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_memac.h"
37 uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
39 return ioread32be(®s->ievent) & ev_mask;
42 uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
44 return ioread32be(®s->imask);
47 void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
49 iowrite32be(ev_mask, ®s->ievent);
52 void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
56 tmp = ioread32be(®s->command_config);
59 tmp |= CMD_CFG_PROMIS_EN;
61 tmp &= ~CMD_CFG_PROMIS_EN;
63 iowrite32be(tmp, ®s->command_config);
66 void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
70 iowrite32be(0, ®s->mac_addr0.mac_addr_l);
71 iowrite32be(0, ®s->mac_addr0.mac_addr_u);
73 iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_l);
74 iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_u);
78 void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
84 tmp0 = (uint32_t)(adr[0] |
88 tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
91 iowrite32be(tmp0, ®s->mac_addr0.mac_addr_l);
92 iowrite32be(tmp1, ®s->mac_addr0.mac_addr_u);
94 iowrite32be(tmp0, ®s->mac_addr[paddr_num-1].mac_addr_l);
95 iowrite32be(tmp1, ®s->mac_addr[paddr_num-1].mac_addr_u);
99 void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
103 tmp = ioread32be(®s->command_config);
106 tmp |= CMD_CFG_RX_EN;
109 tmp |= CMD_CFG_TX_EN;
111 iowrite32be(tmp, ®s->command_config);
114 void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
118 tmp = ioread32be(®s->command_config);
121 tmp &= ~CMD_CFG_RX_EN;
124 tmp &= ~CMD_CFG_TX_EN;
126 iowrite32be(tmp, ®s->command_config);
129 void fman_memac_reset_stat(struct memac_regs *regs)
133 tmp = ioread32be(®s->statn_config);
135 tmp |= STATS_CFG_CLR;
137 iowrite32be(tmp, ®s->statn_config);
139 while (ioread32be(®s->statn_config) & STATS_CFG_CLR);
142 void fman_memac_reset(struct memac_regs *regs)
146 tmp = ioread32be(®s->command_config);
148 tmp |= CMD_CFG_SW_RESET;
150 iowrite32be(tmp, ®s->command_config);
152 while (ioread32be(®s->command_config) & CMD_CFG_SW_RESET);
155 int fman_memac_init(struct memac_regs *regs,
156 struct memac_cfg *cfg,
157 enum enet_interface enet_interface,
158 enum enet_speed enet_speed,
166 if (cfg->wan_mode_enable)
167 tmp |= CMD_CFG_WAN_MODE;
168 if (cfg->promiscuous_mode_enable)
169 tmp |= CMD_CFG_PROMIS_EN;
170 if (cfg->pause_forward_enable)
171 tmp |= CMD_CFG_PAUSE_FWD;
172 if (cfg->pause_ignore)
173 tmp |= CMD_CFG_PAUSE_IGNORE;
174 if (cfg->tx_addr_ins_enable)
175 tmp |= CMD_CFG_TX_ADDR_INS;
176 if (cfg->loopback_enable)
177 tmp |= CMD_CFG_LOOPBACK_EN;
178 if (cfg->cmd_frame_enable)
179 tmp |= CMD_CFG_CNT_FRM_EN;
180 if (cfg->send_idle_enable)
181 tmp |= CMD_CFG_SEND_IDLE;
182 if (cfg->no_length_check_enable)
183 tmp |= CMD_CFG_NO_LEN_CHK;
185 tmp |= CMD_CFG_SFD_ANY;
187 tmp |= CMD_CFG_TX_PAD_EN;
188 if (cfg->wake_on_lan)
191 tmp |= CMD_CFG_CRC_FWD;
193 iowrite32be(tmp, ®s->command_config);
195 /* Max Frame Length */
196 iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm);
199 iowrite32be((uint32_t)cfg->pause_quanta, ®s->pause_quanta[0]);
200 iowrite32be((uint32_t)0, ®s->pause_thresh[0]);
204 switch (enet_interface) {
205 case E_ENET_IF_XGMII:
207 tmp |= IF_MODE_XGMII;
211 if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
212 tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
214 iowrite32be(tmp, ®s->if_mode);
216 /* TX_FIFO_SECTIONS */
218 if (enet_interface == E_ENET_IF_XGMII ||
219 enet_interface == E_ENET_IF_XFI) {
221 tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
222 TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
224 tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
225 TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
228 tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
229 TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
231 iowrite32be(tmp, ®s->tx_fifo_sections);
233 /* clear all pending events and set-up interrupts */
234 fman_memac_ack_event(regs, 0xffffffff);
235 fman_memac_set_exception(regs, exceptions, TRUE);
240 void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
244 tmp = ioread32be(®s->imask);
250 iowrite32be(tmp, ®s->imask);
253 void fman_memac_reset_filter_table(struct memac_regs *regs)
256 for (i = 0; i < 64; i++)
257 iowrite32be(i & ~HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl);
260 void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
262 iowrite32be(crc | HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl);
265 void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
267 iowrite32be(val, ®s->hashtable_ctrl);
270 uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
274 tmp = ioread32be(®s->maxfrm);
280 void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
283 uint16_t thresh_time)
287 tmp = ioread32be(®s->tx_fifo_sections);
289 if (priority == 0xff) {
290 GET_TX_EMPTY_DEFAULT_VALUE(tmp);
291 iowrite32be(tmp, ®s->tx_fifo_sections);
293 tmp = ioread32be(®s->command_config);
294 tmp &= ~CMD_CFG_PFC_MODE;
297 GET_TX_EMPTY_PFC_VALUE(tmp);
298 iowrite32be(tmp, ®s->tx_fifo_sections);
300 tmp = ioread32be(®s->command_config);
301 tmp |= CMD_CFG_PFC_MODE;
304 iowrite32be(tmp, ®s->command_config);
306 tmp = ioread32be(®s->pause_quanta[priority / 2]);
311 tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
312 iowrite32be(tmp, ®s->pause_quanta[priority / 2]);
314 tmp = ioread32be(®s->pause_thresh[priority / 2]);
319 tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
320 iowrite32be(tmp, ®s->pause_thresh[priority / 2]);
323 void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
327 tmp = ioread32be(®s->command_config);
329 tmp |= CMD_CFG_PAUSE_IGNORE;
331 tmp &= ~CMD_CFG_PAUSE_IGNORE;
333 iowrite32be(tmp, ®s->command_config);
336 void fman_memac_set_wol(struct memac_regs *regs, bool enable)
340 tmp = ioread32be(®s->command_config);
347 iowrite32be(tmp, ®s->command_config);
350 #define GET_MEMAC_CNTR_64(bn) \
351 (ioread32be(®s->bn ## _l) | \
352 ((uint64_t)ioread32be(®s->bn ## _u) << 32))
354 uint64_t fman_memac_get_counter(struct memac_regs *regs,
355 enum memac_counters reg_name)
360 case E_MEMAC_COUNTER_R64:
361 ret_val = GET_MEMAC_CNTR_64(r64);
363 case E_MEMAC_COUNTER_R127:
364 ret_val = GET_MEMAC_CNTR_64(r127);
366 case E_MEMAC_COUNTER_R255:
367 ret_val = GET_MEMAC_CNTR_64(r255);
369 case E_MEMAC_COUNTER_R511:
370 ret_val = GET_MEMAC_CNTR_64(r511);
372 case E_MEMAC_COUNTER_R1023:
373 ret_val = GET_MEMAC_CNTR_64(r1023);
375 case E_MEMAC_COUNTER_R1518:
376 ret_val = GET_MEMAC_CNTR_64(r1518);
378 case E_MEMAC_COUNTER_R1519X:
379 ret_val = GET_MEMAC_CNTR_64(r1519x);
381 case E_MEMAC_COUNTER_RFRG:
382 ret_val = GET_MEMAC_CNTR_64(rfrg);
384 case E_MEMAC_COUNTER_RJBR:
385 ret_val = GET_MEMAC_CNTR_64(rjbr);
387 case E_MEMAC_COUNTER_RDRP:
388 ret_val = GET_MEMAC_CNTR_64(rdrp);
390 case E_MEMAC_COUNTER_RALN:
391 ret_val = GET_MEMAC_CNTR_64(raln);
393 case E_MEMAC_COUNTER_TUND:
394 ret_val = GET_MEMAC_CNTR_64(tund);
396 case E_MEMAC_COUNTER_ROVR:
397 ret_val = GET_MEMAC_CNTR_64(rovr);
399 case E_MEMAC_COUNTER_RXPF:
400 ret_val = GET_MEMAC_CNTR_64(rxpf);
402 case E_MEMAC_COUNTER_TXPF:
403 ret_val = GET_MEMAC_CNTR_64(txpf);
405 case E_MEMAC_COUNTER_ROCT:
406 ret_val = GET_MEMAC_CNTR_64(roct);
408 case E_MEMAC_COUNTER_RMCA:
409 ret_val = GET_MEMAC_CNTR_64(rmca);
411 case E_MEMAC_COUNTER_RBCA:
412 ret_val = GET_MEMAC_CNTR_64(rbca);
414 case E_MEMAC_COUNTER_RPKT:
415 ret_val = GET_MEMAC_CNTR_64(rpkt);
417 case E_MEMAC_COUNTER_RUCA:
418 ret_val = GET_MEMAC_CNTR_64(ruca);
420 case E_MEMAC_COUNTER_RERR:
421 ret_val = GET_MEMAC_CNTR_64(rerr);
423 case E_MEMAC_COUNTER_TOCT:
424 ret_val = GET_MEMAC_CNTR_64(toct);
426 case E_MEMAC_COUNTER_TMCA:
427 ret_val = GET_MEMAC_CNTR_64(tmca);
429 case E_MEMAC_COUNTER_TBCA:
430 ret_val = GET_MEMAC_CNTR_64(tbca);
432 case E_MEMAC_COUNTER_TUCA:
433 ret_val = GET_MEMAC_CNTR_64(tuca);
435 case E_MEMAC_COUNTER_TERR:
436 ret_val = GET_MEMAC_CNTR_64(terr);
445 void fman_memac_adjust_link(struct memac_regs *regs,
446 enum enet_interface iface_mode,
447 enum enet_speed speed, bool full_dx)
451 tmp = ioread32be(®s->if_mode);
458 if (iface_mode == E_ENET_IF_RGMII) {
459 /* Configure RGMII in manual mode */
460 tmp &= ~IF_MODE_RGMII_AUTO;
461 tmp &= ~IF_MODE_RGMII_SP_MASK;
464 tmp |= IF_MODE_RGMII_FD;
466 tmp &= ~IF_MODE_RGMII_FD;
469 case E_ENET_SPEED_1000:
470 tmp |= IF_MODE_RGMII_1000;
472 case E_ENET_SPEED_100:
473 tmp |= IF_MODE_RGMII_100;
475 case E_ENET_SPEED_10:
476 tmp |= IF_MODE_RGMII_10;
483 iowrite32be(tmp, ®s->if_mode);
486 void fman_memac_defconfig(struct memac_cfg *cfg)
488 cfg->reset_on_init = FALSE;
489 cfg->wan_mode_enable = FALSE;
490 cfg->promiscuous_mode_enable = FALSE;
491 cfg->pause_forward_enable = FALSE;
492 cfg->pause_ignore = FALSE;
493 cfg->tx_addr_ins_enable = FALSE;
494 cfg->loopback_enable = FALSE;
495 cfg->cmd_frame_enable = FALSE;
496 cfg->rx_error_discard = FALSE;
497 cfg->send_idle_enable = FALSE;
498 cfg->no_length_check_enable = TRUE;
499 cfg->lgth_check_nostdr = FALSE;
500 cfg->time_stamp_enable = FALSE;
501 cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
502 cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
503 cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
504 cfg->pad_enable = TRUE;
505 cfg->phy_tx_ena_on = FALSE;
506 cfg->rx_sfd_any = FALSE;
507 cfg->rx_pbl_fwd = FALSE;
508 cfg->tx_pbl_fwd = FALSE;
509 cfg->debug_mode = FALSE;
510 cfg->wake_on_lan = FALSE;