1 /* 2 * Copyright 2008-2012 Freescale Semiconductor Inc. 3 * 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. 14 * 15 * 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 19 * later version. 20 * 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. 31 */ 32 33 34 #include "fsl_fman_memac.h" 35 36 37 uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask) 38 { 39 return ioread32be(®s->ievent) & ev_mask; 40 } 41 42 uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs) 43 { 44 return ioread32be(®s->imask); 45 } 46 47 void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask) 48 { 49 iowrite32be(ev_mask, ®s->ievent); 50 } 51 52 void fman_memac_set_promiscuous(struct memac_regs *regs, bool val) 53 { 54 uint32_t tmp; 55 56 tmp = ioread32be(®s->command_config); 57 58 if (val) 59 tmp |= CMD_CFG_PROMIS_EN; 60 else 61 tmp &= ~CMD_CFG_PROMIS_EN; 62 63 iowrite32be(tmp, ®s->command_config); 64 } 65 66 void fman_memac_clear_addr_in_paddr(struct memac_regs *regs, 67 uint8_t paddr_num) 68 { 69 if (paddr_num == 0) { 70 iowrite32be(0, ®s->mac_addr0.mac_addr_l); 71 iowrite32be(0, ®s->mac_addr0.mac_addr_u); 72 } else { 73 iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_l); 74 iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_u); 75 } 76 } 77 78 void fman_memac_add_addr_in_paddr(struct memac_regs *regs, 79 uint8_t *adr, 80 uint8_t paddr_num) 81 { 82 uint32_t tmp0, tmp1; 83 84 tmp0 = (uint32_t)(adr[0] | 85 adr[1] << 8 | 86 adr[2] << 16 | 87 adr[3] << 24); 88 tmp1 = (uint32_t)(adr[4] | adr[5] << 8); 89 90 if (paddr_num == 0) { 91 iowrite32be(tmp0, ®s->mac_addr0.mac_addr_l); 92 iowrite32be(tmp1, ®s->mac_addr0.mac_addr_u); 93 } else { 94 iowrite32be(tmp0, ®s->mac_addr[paddr_num-1].mac_addr_l); 95 iowrite32be(tmp1, ®s->mac_addr[paddr_num-1].mac_addr_u); 96 } 97 } 98 99 void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx) 100 { 101 uint32_t tmp; 102 103 tmp = ioread32be(®s->command_config); 104 105 if (apply_rx) 106 tmp |= CMD_CFG_RX_EN; 107 108 if (apply_tx) 109 tmp |= CMD_CFG_TX_EN; 110 111 iowrite32be(tmp, ®s->command_config); 112 } 113 114 void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx) 115 { 116 uint32_t tmp; 117 118 tmp = ioread32be(®s->command_config); 119 120 if (apply_rx) 121 tmp &= ~CMD_CFG_RX_EN; 122 123 if (apply_tx) 124 tmp &= ~CMD_CFG_TX_EN; 125 126 iowrite32be(tmp, ®s->command_config); 127 } 128 129 void fman_memac_reset_stat(struct memac_regs *regs) 130 { 131 uint32_t tmp; 132 133 tmp = ioread32be(®s->statn_config); 134 135 tmp |= STATS_CFG_CLR; 136 137 iowrite32be(tmp, ®s->statn_config); 138 139 while (ioread32be(®s->statn_config) & STATS_CFG_CLR); 140 } 141 142 void fman_memac_reset(struct memac_regs *regs) 143 { 144 uint32_t tmp; 145 146 tmp = ioread32be(®s->command_config); 147 148 tmp |= CMD_CFG_SW_RESET; 149 150 iowrite32be(tmp, ®s->command_config); 151 152 while (ioread32be(®s->command_config) & CMD_CFG_SW_RESET); 153 } 154 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, 159 bool slow_10g_if, 160 uint32_t exceptions) 161 { 162 uint32_t tmp; 163 164 /* Config */ 165 tmp = 0; 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; 184 if (cfg->rx_sfd_any) 185 tmp |= CMD_CFG_SFD_ANY; 186 if (cfg->pad_enable) 187 tmp |= CMD_CFG_TX_PAD_EN; 188 if (cfg->wake_on_lan) 189 tmp |= CMD_CFG_MG; 190 191 tmp |= CMD_CFG_CRC_FWD; 192 193 iowrite32be(tmp, ®s->command_config); 194 195 /* Max Frame Length */ 196 iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm); 197 198 /* Pause Time */ 199 iowrite32be((uint32_t)cfg->pause_quanta, ®s->pause_quanta[0]); 200 iowrite32be((uint32_t)0, ®s->pause_thresh[0]); 201 202 /* IF_MODE */ 203 tmp = 0; 204 switch (enet_interface) { 205 case E_ENET_IF_XGMII: 206 case E_ENET_IF_XFI: 207 tmp |= IF_MODE_XGMII; 208 break; 209 default: 210 tmp |= IF_MODE_GMII; 211 if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable) 212 tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO; 213 } 214 iowrite32be(tmp, ®s->if_mode); 215 216 /* TX_FIFO_SECTIONS */ 217 tmp = 0; 218 if (enet_interface == E_ENET_IF_XGMII || 219 enet_interface == E_ENET_IF_XFI) { 220 if(slow_10g_if) { 221 tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G | 222 TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); 223 } else { 224 tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G | 225 TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); 226 } 227 } else { 228 tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G | 229 TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G); 230 } 231 iowrite32be(tmp, ®s->tx_fifo_sections); 232 233 /* clear all pending events and set-up interrupts */ 234 fman_memac_ack_event(regs, 0xffffffff); 235 fman_memac_set_exception(regs, exceptions, TRUE); 236 237 return 0; 238 } 239 240 void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable) 241 { 242 uint32_t tmp; 243 244 tmp = ioread32be(®s->imask); 245 if (enable) 246 tmp |= val; 247 else 248 tmp &= ~val; 249 250 iowrite32be(tmp, ®s->imask); 251 } 252 253 void fman_memac_reset_filter_table(struct memac_regs *regs) 254 { 255 uint32_t i; 256 for (i = 0; i < 64; i++) 257 iowrite32be(i & ~HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); 258 } 259 260 void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc) 261 { 262 iowrite32be(crc | HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); 263 } 264 265 void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val) 266 { 267 iowrite32be(val, ®s->hashtable_ctrl); 268 } 269 270 uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs) 271 { 272 uint32_t tmp; 273 274 tmp = ioread32be(®s->maxfrm); 275 276 return(uint16_t)tmp; 277 } 278 279 280 void fman_memac_set_tx_pause_frames(struct memac_regs *regs, 281 uint8_t priority, 282 uint16_t pause_time, 283 uint16_t thresh_time) 284 { 285 uint32_t tmp; 286 287 tmp = ioread32be(®s->tx_fifo_sections); 288 289 if (priority == 0xff) { 290 GET_TX_EMPTY_DEFAULT_VALUE(tmp); 291 iowrite32be(tmp, ®s->tx_fifo_sections); 292 293 tmp = ioread32be(®s->command_config); 294 tmp &= ~CMD_CFG_PFC_MODE; 295 priority = 0; 296 } else { 297 GET_TX_EMPTY_PFC_VALUE(tmp); 298 iowrite32be(tmp, ®s->tx_fifo_sections); 299 300 tmp = ioread32be(®s->command_config); 301 tmp |= CMD_CFG_PFC_MODE; 302 } 303 304 iowrite32be(tmp, ®s->command_config); 305 306 tmp = ioread32be(®s->pause_quanta[priority / 2]); 307 if (priority % 2) 308 tmp &= 0x0000FFFF; 309 else 310 tmp &= 0xFFFF0000; 311 tmp |= ((uint32_t)pause_time << (16 * (priority % 2))); 312 iowrite32be(tmp, ®s->pause_quanta[priority / 2]); 313 314 tmp = ioread32be(®s->pause_thresh[priority / 2]); 315 if (priority % 2) 316 tmp &= 0x0000FFFF; 317 else 318 tmp &= 0xFFFF0000; 319 tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2))); 320 iowrite32be(tmp, ®s->pause_thresh[priority / 2]); 321 } 322 323 void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable) 324 { 325 uint32_t tmp; 326 327 tmp = ioread32be(®s->command_config); 328 if (enable) 329 tmp |= CMD_CFG_PAUSE_IGNORE; 330 else 331 tmp &= ~CMD_CFG_PAUSE_IGNORE; 332 333 iowrite32be(tmp, ®s->command_config); 334 } 335 336 void fman_memac_set_wol(struct memac_regs *regs, bool enable) 337 { 338 uint32_t tmp; 339 340 tmp = ioread32be(®s->command_config); 341 342 if (enable) 343 tmp |= CMD_CFG_MG; 344 else 345 tmp &= ~CMD_CFG_MG; 346 347 iowrite32be(tmp, ®s->command_config); 348 } 349 350 #define GET_MEMAC_CNTR_64(bn) \ 351 (ioread32be(®s->bn ## _l) | \ 352 ((uint64_t)ioread32be(®s->bn ## _u) << 32)) 353 354 uint64_t fman_memac_get_counter(struct memac_regs *regs, 355 enum memac_counters reg_name) 356 { 357 uint64_t ret_val; 358 359 switch (reg_name) { 360 case E_MEMAC_COUNTER_R64: 361 ret_val = GET_MEMAC_CNTR_64(r64); 362 break; 363 case E_MEMAC_COUNTER_R127: 364 ret_val = GET_MEMAC_CNTR_64(r127); 365 break; 366 case E_MEMAC_COUNTER_R255: 367 ret_val = GET_MEMAC_CNTR_64(r255); 368 break; 369 case E_MEMAC_COUNTER_R511: 370 ret_val = GET_MEMAC_CNTR_64(r511); 371 break; 372 case E_MEMAC_COUNTER_R1023: 373 ret_val = GET_MEMAC_CNTR_64(r1023); 374 break; 375 case E_MEMAC_COUNTER_R1518: 376 ret_val = GET_MEMAC_CNTR_64(r1518); 377 break; 378 case E_MEMAC_COUNTER_R1519X: 379 ret_val = GET_MEMAC_CNTR_64(r1519x); 380 break; 381 case E_MEMAC_COUNTER_RFRG: 382 ret_val = GET_MEMAC_CNTR_64(rfrg); 383 break; 384 case E_MEMAC_COUNTER_RJBR: 385 ret_val = GET_MEMAC_CNTR_64(rjbr); 386 break; 387 case E_MEMAC_COUNTER_RDRP: 388 ret_val = GET_MEMAC_CNTR_64(rdrp); 389 break; 390 case E_MEMAC_COUNTER_RALN: 391 ret_val = GET_MEMAC_CNTR_64(raln); 392 break; 393 case E_MEMAC_COUNTER_TUND: 394 ret_val = GET_MEMAC_CNTR_64(tund); 395 break; 396 case E_MEMAC_COUNTER_ROVR: 397 ret_val = GET_MEMAC_CNTR_64(rovr); 398 break; 399 case E_MEMAC_COUNTER_RXPF: 400 ret_val = GET_MEMAC_CNTR_64(rxpf); 401 break; 402 case E_MEMAC_COUNTER_TXPF: 403 ret_val = GET_MEMAC_CNTR_64(txpf); 404 break; 405 case E_MEMAC_COUNTER_ROCT: 406 ret_val = GET_MEMAC_CNTR_64(roct); 407 break; 408 case E_MEMAC_COUNTER_RMCA: 409 ret_val = GET_MEMAC_CNTR_64(rmca); 410 break; 411 case E_MEMAC_COUNTER_RBCA: 412 ret_val = GET_MEMAC_CNTR_64(rbca); 413 break; 414 case E_MEMAC_COUNTER_RPKT: 415 ret_val = GET_MEMAC_CNTR_64(rpkt); 416 break; 417 case E_MEMAC_COUNTER_RUCA: 418 ret_val = GET_MEMAC_CNTR_64(ruca); 419 break; 420 case E_MEMAC_COUNTER_RERR: 421 ret_val = GET_MEMAC_CNTR_64(rerr); 422 break; 423 case E_MEMAC_COUNTER_TOCT: 424 ret_val = GET_MEMAC_CNTR_64(toct); 425 break; 426 case E_MEMAC_COUNTER_TMCA: 427 ret_val = GET_MEMAC_CNTR_64(tmca); 428 break; 429 case E_MEMAC_COUNTER_TBCA: 430 ret_val = GET_MEMAC_CNTR_64(tbca); 431 break; 432 case E_MEMAC_COUNTER_TUCA: 433 ret_val = GET_MEMAC_CNTR_64(tuca); 434 break; 435 case E_MEMAC_COUNTER_TERR: 436 ret_val = GET_MEMAC_CNTR_64(terr); 437 break; 438 default: 439 ret_val = 0; 440 } 441 442 return ret_val; 443 } 444 445 void fman_memac_adjust_link(struct memac_regs *regs, 446 enum enet_interface iface_mode, 447 enum enet_speed speed, bool full_dx) 448 { 449 uint32_t tmp; 450 451 tmp = ioread32be(®s->if_mode); 452 453 if (full_dx) 454 tmp &= ~IF_MODE_HD; 455 else 456 tmp |= IF_MODE_HD; 457 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; 462 463 if (full_dx) 464 tmp |= IF_MODE_RGMII_FD; 465 else 466 tmp &= ~IF_MODE_RGMII_FD; 467 468 switch (speed) { 469 case E_ENET_SPEED_1000: 470 tmp |= IF_MODE_RGMII_1000; 471 break; 472 case E_ENET_SPEED_100: 473 tmp |= IF_MODE_RGMII_100; 474 break; 475 case E_ENET_SPEED_10: 476 tmp |= IF_MODE_RGMII_10; 477 break; 478 default: 479 break; 480 } 481 } 482 483 iowrite32be(tmp, ®s->if_mode); 484 } 485 486 void fman_memac_defconfig(struct memac_cfg *cfg) 487 { 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; 511 } 512