2 * Copyright 2008-2012 Freescale Semiconductor Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Freescale Semiconductor nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "fsl_fman_tgec.h"
37 void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
41 tmp0 = (uint32_t)(adr[0] |
45 tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
46 iowrite32be(tmp0, ®s->mac_addr_0);
47 iowrite32be(tmp1, ®s->mac_addr_1);
50 void fman_tgec_reset_stat(struct tgec_regs *regs)
54 tmp = ioread32be(®s->command_config);
56 tmp |= CMD_CFG_STAT_CLR;
58 iowrite32be(tmp, ®s->command_config);
60 while (ioread32be(®s->command_config) & CMD_CFG_STAT_CLR) ;
63 #define GET_TGEC_CNTR_64(bn) \
64 (((uint64_t)ioread32be(®s->bn ## _u) << 32) | \
65 ioread32be(®s->bn ## _l))
67 uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
72 case E_TGEC_COUNTER_R64:
73 ret_val = GET_TGEC_CNTR_64(r64);
75 case E_TGEC_COUNTER_R127:
76 ret_val = GET_TGEC_CNTR_64(r127);
78 case E_TGEC_COUNTER_R255:
79 ret_val = GET_TGEC_CNTR_64(r255);
81 case E_TGEC_COUNTER_R511:
82 ret_val = GET_TGEC_CNTR_64(r511);
84 case E_TGEC_COUNTER_R1023:
85 ret_val = GET_TGEC_CNTR_64(r1023);
87 case E_TGEC_COUNTER_R1518:
88 ret_val = GET_TGEC_CNTR_64(r1518);
90 case E_TGEC_COUNTER_R1519X:
91 ret_val = GET_TGEC_CNTR_64(r1519x);
93 case E_TGEC_COUNTER_TRFRG:
94 ret_val = GET_TGEC_CNTR_64(trfrg);
96 case E_TGEC_COUNTER_TRJBR:
97 ret_val = GET_TGEC_CNTR_64(trjbr);
99 case E_TGEC_COUNTER_RDRP:
100 ret_val = GET_TGEC_CNTR_64(rdrp);
102 case E_TGEC_COUNTER_RALN:
103 ret_val = GET_TGEC_CNTR_64(raln);
105 case E_TGEC_COUNTER_TRUND:
106 ret_val = GET_TGEC_CNTR_64(trund);
108 case E_TGEC_COUNTER_TROVR:
109 ret_val = GET_TGEC_CNTR_64(trovr);
111 case E_TGEC_COUNTER_RXPF:
112 ret_val = GET_TGEC_CNTR_64(rxpf);
114 case E_TGEC_COUNTER_TXPF:
115 ret_val = GET_TGEC_CNTR_64(txpf);
117 case E_TGEC_COUNTER_ROCT:
118 ret_val = GET_TGEC_CNTR_64(roct);
120 case E_TGEC_COUNTER_RMCA:
121 ret_val = GET_TGEC_CNTR_64(rmca);
123 case E_TGEC_COUNTER_RBCA:
124 ret_val = GET_TGEC_CNTR_64(rbca);
126 case E_TGEC_COUNTER_RPKT:
127 ret_val = GET_TGEC_CNTR_64(rpkt);
129 case E_TGEC_COUNTER_RUCA:
130 ret_val = GET_TGEC_CNTR_64(ruca);
132 case E_TGEC_COUNTER_RERR:
133 ret_val = GET_TGEC_CNTR_64(rerr);
135 case E_TGEC_COUNTER_TOCT:
136 ret_val = GET_TGEC_CNTR_64(toct);
138 case E_TGEC_COUNTER_TMCA:
139 ret_val = GET_TGEC_CNTR_64(tmca);
141 case E_TGEC_COUNTER_TBCA:
142 ret_val = GET_TGEC_CNTR_64(tbca);
144 case E_TGEC_COUNTER_TUCA:
145 ret_val = GET_TGEC_CNTR_64(tuca);
147 case E_TGEC_COUNTER_TERR:
148 ret_val = GET_TGEC_CNTR_64(terr);
157 void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
161 tmp = ioread32be(®s->command_config);
163 tmp |= CMD_CFG_RX_EN;
165 tmp |= CMD_CFG_TX_EN;
166 iowrite32be(tmp, ®s->command_config);
169 void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
173 tmp_reg_32 = ioread32be(®s->command_config);
175 tmp_reg_32 &= ~CMD_CFG_RX_EN;
177 tmp_reg_32 &= ~CMD_CFG_TX_EN;
178 iowrite32be(tmp_reg_32, ®s->command_config);
181 void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
185 tmp = ioread32be(®s->command_config);
187 tmp |= CMD_CFG_PROMIS_EN;
189 tmp &= ~CMD_CFG_PROMIS_EN;
190 iowrite32be(tmp, ®s->command_config);
193 void fman_tgec_reset_filter_table(struct tgec_regs *regs)
196 for (i = 0; i < 512; i++)
197 iowrite32be(i & ~TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl);
200 void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
202 uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
203 iowrite32be(hash | TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl);
206 void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
208 iowrite32be(value, ®s->hashtable_ctrl);
211 void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
213 iowrite32be((uint32_t)pause_time, ®s->pause_quant);
216 void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
220 tmp = ioread32be(®s->command_config);
222 tmp |= CMD_CFG_PAUSE_IGNORE;
224 tmp &= ~CMD_CFG_PAUSE_IGNORE;
225 iowrite32be(tmp, ®s->command_config);
228 void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
232 tmp = ioread32be(®s->command_config);
234 tmp |= CMD_CFG_EN_TIMESTAMP;
236 tmp &= ~CMD_CFG_EN_TIMESTAMP;
237 iowrite32be(tmp, ®s->command_config);
240 uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
242 return ioread32be(®s->ievent) & ev_mask;
245 void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
247 iowrite32be(ev_mask, ®s->ievent);
250 uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
252 return ioread32be(®s->imask);
255 void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
259 tmp0 = (uint32_t)(adr[0] |
263 tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
264 iowrite32be(tmp0, ®s->mac_addr_2);
265 iowrite32be(tmp1, ®s->mac_addr_3);
268 void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
270 iowrite32be(0, ®s->mac_addr_2);
271 iowrite32be(0, ®s->mac_addr_3);
274 uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
276 return ioread32be(®s->tgec_id);
279 void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
281 iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask);
284 void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
286 iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask);
289 uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
291 return (uint16_t) ioread32be(®s->maxfrm);
294 void fman_tgec_defconfig(struct tgec_cfg *cfg)
296 cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
297 cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
298 cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
299 cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
300 cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
301 cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
302 cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
303 cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
304 cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
305 cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
306 cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
307 cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
308 cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
309 cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
310 cfg->pause_quant = DEFAULT_PAUSE_QUANT;
311 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
312 cfg->skip_fman11_workaround = FALSE;
313 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
316 int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
317 uint32_t exception_mask)
322 tmp = 0x40; /* CRC forward */
323 if (cfg->wan_mode_enable)
324 tmp |= CMD_CFG_WAN_MODE;
325 if (cfg->promiscuous_mode_enable)
326 tmp |= CMD_CFG_PROMIS_EN;
327 if (cfg->pause_forward_enable)
328 tmp |= CMD_CFG_PAUSE_FWD;
329 if (cfg->pause_ignore)
330 tmp |= CMD_CFG_PAUSE_IGNORE;
331 if (cfg->tx_addr_ins_enable)
332 tmp |= CMD_CFG_TX_ADDR_INS;
333 if (cfg->loopback_enable)
334 tmp |= CMD_CFG_LOOPBACK_EN;
335 if (cfg->cmd_frame_enable)
336 tmp |= CMD_CFG_CMD_FRM_EN;
337 if (cfg->rx_error_discard)
338 tmp |= CMD_CFG_RX_ER_DISC;
339 if (cfg->send_idle_enable)
340 tmp |= CMD_CFG_SEND_IDLE;
341 if (cfg->no_length_check_enable)
342 tmp |= CMD_CFG_NO_LEN_CHK;
343 if (cfg->time_stamp_enable)
344 tmp |= CMD_CFG_EN_TIMESTAMP;
345 iowrite32be(tmp, ®s->command_config);
347 /* Max Frame Length */
348 iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm);
350 iowrite32be(cfg->pause_quant, ®s->pause_quant);
352 /* clear all pending events and set-up interrupts */
353 fman_tgec_ack_event(regs, 0xffffffff);
354 fman_tgec_enable_interrupt(regs, exception_mask);
359 void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
363 /* restore the default tx ipg Length */
364 tmp = (ioread32be(®s->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
366 iowrite32be(tmp, ®s->tx_ipg_len);