Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Add fs_enet ethernet network driver, for several embedded platforms.

authored by

Pantelis Antoniou and committed by
Jeff Garzik
48257c4f d8840ac9

+4400
+1
drivers/net/Kconfig
··· 1775 1775 controller on the Renesas H8/300 processor. 1776 1776 1777 1777 source "drivers/net/fec_8xx/Kconfig" 1778 + source "drivers/net/fs_enet/Kconfig" 1778 1779 1779 1780 endmenu 1780 1781
+3
drivers/net/Makefile
··· 203 203 obj-$(CONFIG_ETRAX_ETHERNET) += cris/ 204 204 205 205 obj-$(CONFIG_NETCONSOLE) += netconsole.o 206 + 207 + obj-$(CONFIG_FS_ENET) += fs_enet/ 208 +
+20
drivers/net/fs_enet/Kconfig
··· 1 + config FS_ENET 2 + tristate "Freescale Ethernet Driver" 3 + depends on NET_ETHERNET && (CPM1 || CPM2) 4 + select MII 5 + 6 + config FS_ENET_HAS_SCC 7 + bool "Chip has an SCC usable for ethernet" 8 + depends on FS_ENET && (CPM1 || CPM2) 9 + default y 10 + 11 + config FS_ENET_HAS_FCC 12 + bool "Chip has an FCC usable for ethernet" 13 + depends on FS_ENET && CPM2 14 + default y 15 + 16 + config FS_ENET_HAS_FEC 17 + bool "Chip has an FEC usable for ethernet" 18 + depends on FS_ENET && CPM1 19 + default y 20 +
+10
drivers/net/fs_enet/Makefile
··· 1 + # 2 + # Makefile for the Freescale Ethernet controllers 3 + # 4 + 5 + obj-$(CONFIG_FS_ENET) += fs_enet.o 6 + 7 + obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o 8 + obj-$(CONFIG_8260) += mac-fcc.o 9 + 10 + fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o
+1226
drivers/net/fs_enet/fs_enet-main.c
··· 1 + /* 2 + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. 3 + * 4 + * Copyright (c) 2003 Intracom S.A. 5 + * by Pantelis Antoniou <panto@intracom.gr> 6 + * 7 + * 2005 (c) MontaVista Software, Inc. 8 + * Vitaly Bordug <vbordug@ru.mvista.com> 9 + * 10 + * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com> 11 + * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se> 12 + * 13 + * This file is licensed under the terms of the GNU General Public License 14 + * version 2. This program is licensed "as is" without any warranty of any 15 + * kind, whether express or implied. 16 + */ 17 + 18 + #include <linux/config.h> 19 + #include <linux/module.h> 20 + #include <linux/kernel.h> 21 + #include <linux/types.h> 22 + #include <linux/sched.h> 23 + #include <linux/string.h> 24 + #include <linux/ptrace.h> 25 + #include <linux/errno.h> 26 + #include <linux/ioport.h> 27 + #include <linux/slab.h> 28 + #include <linux/interrupt.h> 29 + #include <linux/pci.h> 30 + #include <linux/init.h> 31 + #include <linux/delay.h> 32 + #include <linux/netdevice.h> 33 + #include <linux/etherdevice.h> 34 + #include <linux/skbuff.h> 35 + #include <linux/spinlock.h> 36 + #include <linux/mii.h> 37 + #include <linux/ethtool.h> 38 + #include <linux/bitops.h> 39 + #include <linux/fs.h> 40 + 41 + #include <linux/vmalloc.h> 42 + #include <asm/pgtable.h> 43 + 44 + #include <asm/pgtable.h> 45 + #include <asm/irq.h> 46 + #include <asm/uaccess.h> 47 + 48 + #include "fs_enet.h" 49 + 50 + /*************************************************/ 51 + 52 + static char version[] __devinitdata = 53 + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; 54 + 55 + MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); 56 + MODULE_DESCRIPTION("Freescale Ethernet Driver"); 57 + MODULE_LICENSE("GPL"); 58 + MODULE_VERSION(DRV_MODULE_VERSION); 59 + 60 + MODULE_PARM(fs_enet_debug, "i"); 61 + MODULE_PARM_DESC(fs_enet_debug, 62 + "Freescale bitmapped debugging message enable value"); 63 + 64 + int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */ 65 + 66 + static void fs_set_multicast_list(struct net_device *dev) 67 + { 68 + struct fs_enet_private *fep = netdev_priv(dev); 69 + 70 + (*fep->ops->set_multicast_list)(dev); 71 + } 72 + 73 + /* NAPI receive function */ 74 + static int fs_enet_rx_napi(struct net_device *dev, int *budget) 75 + { 76 + struct fs_enet_private *fep = netdev_priv(dev); 77 + const struct fs_platform_info *fpi = fep->fpi; 78 + cbd_t *bdp; 79 + struct sk_buff *skb, *skbn, *skbt; 80 + int received = 0; 81 + u16 pkt_len, sc; 82 + int curidx; 83 + int rx_work_limit = 0; /* pacify gcc */ 84 + 85 + rx_work_limit = min(dev->quota, *budget); 86 + 87 + if (!netif_running(dev)) 88 + return 0; 89 + 90 + /* 91 + * First, grab all of the stats for the incoming packet. 92 + * These get messed up if we get called due to a busy condition. 93 + */ 94 + bdp = fep->cur_rx; 95 + 96 + /* clear RX status bits for napi*/ 97 + (*fep->ops->napi_clear_rx_event)(dev); 98 + 99 + while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { 100 + 101 + curidx = bdp - fep->rx_bd_base; 102 + 103 + /* 104 + * Since we have allocated space to hold a complete frame, 105 + * the last indicator should be set. 106 + */ 107 + if ((sc & BD_ENET_RX_LAST) == 0) 108 + printk(KERN_WARNING DRV_MODULE_NAME 109 + ": %s rcv is not +last\n", 110 + dev->name); 111 + 112 + /* 113 + * Check for errors. 114 + */ 115 + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | 116 + BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { 117 + fep->stats.rx_errors++; 118 + /* Frame too long or too short. */ 119 + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) 120 + fep->stats.rx_length_errors++; 121 + /* Frame alignment */ 122 + if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) 123 + fep->stats.rx_frame_errors++; 124 + /* CRC Error */ 125 + if (sc & BD_ENET_RX_CR) 126 + fep->stats.rx_crc_errors++; 127 + /* FIFO overrun */ 128 + if (sc & BD_ENET_RX_OV) 129 + fep->stats.rx_crc_errors++; 130 + 131 + skb = fep->rx_skbuff[curidx]; 132 + 133 + dma_unmap_single(fep->dev, skb->data, 134 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 135 + DMA_FROM_DEVICE); 136 + 137 + skbn = skb; 138 + 139 + } else { 140 + 141 + /* napi, got packet but no quota */ 142 + if (--rx_work_limit < 0) 143 + break; 144 + 145 + skb = fep->rx_skbuff[curidx]; 146 + 147 + dma_unmap_single(fep->dev, skb->data, 148 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 149 + DMA_FROM_DEVICE); 150 + 151 + /* 152 + * Process the incoming frame. 153 + */ 154 + fep->stats.rx_packets++; 155 + pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ 156 + fep->stats.rx_bytes += pkt_len + 4; 157 + 158 + if (pkt_len <= fpi->rx_copybreak) { 159 + /* +2 to make IP header L1 cache aligned */ 160 + skbn = dev_alloc_skb(pkt_len + 2); 161 + if (skbn != NULL) { 162 + skb_reserve(skbn, 2); /* align IP header */ 163 + memcpy(skbn->data, skb->data, pkt_len); 164 + /* swap */ 165 + skbt = skb; 166 + skb = skbn; 167 + skbn = skbt; 168 + } 169 + } else 170 + skbn = dev_alloc_skb(ENET_RX_FRSIZE); 171 + 172 + if (skbn != NULL) { 173 + skb->dev = dev; 174 + skb_put(skb, pkt_len); /* Make room */ 175 + skb->protocol = eth_type_trans(skb, dev); 176 + received++; 177 + netif_receive_skb(skb); 178 + } else { 179 + printk(KERN_WARNING DRV_MODULE_NAME 180 + ": %s Memory squeeze, dropping packet.\n", 181 + dev->name); 182 + fep->stats.rx_dropped++; 183 + skbn = skb; 184 + } 185 + } 186 + 187 + fep->rx_skbuff[curidx] = skbn; 188 + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data, 189 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 190 + DMA_FROM_DEVICE)); 191 + CBDW_DATLEN(bdp, 0); 192 + CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); 193 + 194 + /* 195 + * Update BD pointer to next entry. 196 + */ 197 + if ((sc & BD_ENET_RX_WRAP) == 0) 198 + bdp++; 199 + else 200 + bdp = fep->rx_bd_base; 201 + 202 + (*fep->ops->rx_bd_done)(dev); 203 + } 204 + 205 + fep->cur_rx = bdp; 206 + 207 + dev->quota -= received; 208 + *budget -= received; 209 + 210 + if (rx_work_limit < 0) 211 + return 1; /* not done */ 212 + 213 + /* done */ 214 + netif_rx_complete(dev); 215 + 216 + (*fep->ops->napi_enable_rx)(dev); 217 + 218 + return 0; 219 + } 220 + 221 + /* non NAPI receive function */ 222 + static int fs_enet_rx_non_napi(struct net_device *dev) 223 + { 224 + struct fs_enet_private *fep = netdev_priv(dev); 225 + const struct fs_platform_info *fpi = fep->fpi; 226 + cbd_t *bdp; 227 + struct sk_buff *skb, *skbn, *skbt; 228 + int received = 0; 229 + u16 pkt_len, sc; 230 + int curidx; 231 + /* 232 + * First, grab all of the stats for the incoming packet. 233 + * These get messed up if we get called due to a busy condition. 234 + */ 235 + bdp = fep->cur_rx; 236 + 237 + while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { 238 + 239 + curidx = bdp - fep->rx_bd_base; 240 + 241 + /* 242 + * Since we have allocated space to hold a complete frame, 243 + * the last indicator should be set. 244 + */ 245 + if ((sc & BD_ENET_RX_LAST) == 0) 246 + printk(KERN_WARNING DRV_MODULE_NAME 247 + ": %s rcv is not +last\n", 248 + dev->name); 249 + 250 + /* 251 + * Check for errors. 252 + */ 253 + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | 254 + BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { 255 + fep->stats.rx_errors++; 256 + /* Frame too long or too short. */ 257 + if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) 258 + fep->stats.rx_length_errors++; 259 + /* Frame alignment */ 260 + if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) 261 + fep->stats.rx_frame_errors++; 262 + /* CRC Error */ 263 + if (sc & BD_ENET_RX_CR) 264 + fep->stats.rx_crc_errors++; 265 + /* FIFO overrun */ 266 + if (sc & BD_ENET_RX_OV) 267 + fep->stats.rx_crc_errors++; 268 + 269 + skb = fep->rx_skbuff[curidx]; 270 + 271 + dma_unmap_single(fep->dev, skb->data, 272 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 273 + DMA_FROM_DEVICE); 274 + 275 + skbn = skb; 276 + 277 + } else { 278 + 279 + skb = fep->rx_skbuff[curidx]; 280 + 281 + dma_unmap_single(fep->dev, skb->data, 282 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 283 + DMA_FROM_DEVICE); 284 + 285 + /* 286 + * Process the incoming frame. 287 + */ 288 + fep->stats.rx_packets++; 289 + pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ 290 + fep->stats.rx_bytes += pkt_len + 4; 291 + 292 + if (pkt_len <= fpi->rx_copybreak) { 293 + /* +2 to make IP header L1 cache aligned */ 294 + skbn = dev_alloc_skb(pkt_len + 2); 295 + if (skbn != NULL) { 296 + skb_reserve(skbn, 2); /* align IP header */ 297 + memcpy(skbn->data, skb->data, pkt_len); 298 + /* swap */ 299 + skbt = skb; 300 + skb = skbn; 301 + skbn = skbt; 302 + } 303 + } else 304 + skbn = dev_alloc_skb(ENET_RX_FRSIZE); 305 + 306 + if (skbn != NULL) { 307 + skb->dev = dev; 308 + skb_put(skb, pkt_len); /* Make room */ 309 + skb->protocol = eth_type_trans(skb, dev); 310 + received++; 311 + netif_rx(skb); 312 + } else { 313 + printk(KERN_WARNING DRV_MODULE_NAME 314 + ": %s Memory squeeze, dropping packet.\n", 315 + dev->name); 316 + fep->stats.rx_dropped++; 317 + skbn = skb; 318 + } 319 + } 320 + 321 + fep->rx_skbuff[curidx] = skbn; 322 + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data, 323 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 324 + DMA_FROM_DEVICE)); 325 + CBDW_DATLEN(bdp, 0); 326 + CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); 327 + 328 + /* 329 + * Update BD pointer to next entry. 330 + */ 331 + if ((sc & BD_ENET_RX_WRAP) == 0) 332 + bdp++; 333 + else 334 + bdp = fep->rx_bd_base; 335 + 336 + (*fep->ops->rx_bd_done)(dev); 337 + } 338 + 339 + fep->cur_rx = bdp; 340 + 341 + return 0; 342 + } 343 + 344 + static void fs_enet_tx(struct net_device *dev) 345 + { 346 + struct fs_enet_private *fep = netdev_priv(dev); 347 + cbd_t *bdp; 348 + struct sk_buff *skb; 349 + int dirtyidx, do_wake, do_restart; 350 + u16 sc; 351 + 352 + spin_lock(&fep->lock); 353 + bdp = fep->dirty_tx; 354 + 355 + do_wake = do_restart = 0; 356 + while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) { 357 + 358 + dirtyidx = bdp - fep->tx_bd_base; 359 + 360 + if (fep->tx_free == fep->tx_ring) 361 + break; 362 + 363 + skb = fep->tx_skbuff[dirtyidx]; 364 + 365 + /* 366 + * Check for errors. 367 + */ 368 + if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | 369 + BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { 370 + 371 + if (sc & BD_ENET_TX_HB) /* No heartbeat */ 372 + fep->stats.tx_heartbeat_errors++; 373 + if (sc & BD_ENET_TX_LC) /* Late collision */ 374 + fep->stats.tx_window_errors++; 375 + if (sc & BD_ENET_TX_RL) /* Retrans limit */ 376 + fep->stats.tx_aborted_errors++; 377 + if (sc & BD_ENET_TX_UN) /* Underrun */ 378 + fep->stats.tx_fifo_errors++; 379 + if (sc & BD_ENET_TX_CSL) /* Carrier lost */ 380 + fep->stats.tx_carrier_errors++; 381 + 382 + if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) { 383 + fep->stats.tx_errors++; 384 + do_restart = 1; 385 + } 386 + } else 387 + fep->stats.tx_packets++; 388 + 389 + if (sc & BD_ENET_TX_READY) 390 + printk(KERN_WARNING DRV_MODULE_NAME 391 + ": %s HEY! Enet xmit interrupt and TX_READY.\n", 392 + dev->name); 393 + 394 + /* 395 + * Deferred means some collisions occurred during transmit, 396 + * but we eventually sent the packet OK. 397 + */ 398 + if (sc & BD_ENET_TX_DEF) 399 + fep->stats.collisions++; 400 + 401 + /* unmap */ 402 + dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE); 403 + 404 + /* 405 + * Free the sk buffer associated with this last transmit. 406 + */ 407 + dev_kfree_skb_irq(skb); 408 + fep->tx_skbuff[dirtyidx] = NULL; 409 + 410 + /* 411 + * Update pointer to next buffer descriptor to be transmitted. 412 + */ 413 + if ((sc & BD_ENET_TX_WRAP) == 0) 414 + bdp++; 415 + else 416 + bdp = fep->tx_bd_base; 417 + 418 + /* 419 + * Since we have freed up a buffer, the ring is no longer 420 + * full. 421 + */ 422 + if (!fep->tx_free++) 423 + do_wake = 1; 424 + } 425 + 426 + fep->dirty_tx = bdp; 427 + 428 + if (do_restart) 429 + (*fep->ops->tx_restart)(dev); 430 + 431 + spin_unlock(&fep->lock); 432 + 433 + if (do_wake) 434 + netif_wake_queue(dev); 435 + } 436 + 437 + /* 438 + * The interrupt handler. 439 + * This is called from the MPC core interrupt. 440 + */ 441 + static irqreturn_t 442 + fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs) 443 + { 444 + struct net_device *dev = dev_id; 445 + struct fs_enet_private *fep; 446 + const struct fs_platform_info *fpi; 447 + u32 int_events; 448 + u32 int_clr_events; 449 + int nr, napi_ok; 450 + int handled; 451 + 452 + fep = netdev_priv(dev); 453 + fpi = fep->fpi; 454 + 455 + nr = 0; 456 + while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) { 457 + 458 + nr++; 459 + 460 + int_clr_events = int_events; 461 + if (fpi->use_napi) 462 + int_clr_events &= ~fep->ev_napi_rx; 463 + 464 + (*fep->ops->clear_int_events)(dev, int_clr_events); 465 + 466 + if (int_events & fep->ev_err) 467 + (*fep->ops->ev_error)(dev, int_events); 468 + 469 + if (int_events & fep->ev_rx) { 470 + if (!fpi->use_napi) 471 + fs_enet_rx_non_napi(dev); 472 + else { 473 + napi_ok = netif_rx_schedule_prep(dev); 474 + 475 + (*fep->ops->napi_disable_rx)(dev); 476 + (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx); 477 + 478 + /* NOTE: it is possible for FCCs in NAPI mode */ 479 + /* to submit a spurious interrupt while in poll */ 480 + if (napi_ok) 481 + __netif_rx_schedule(dev); 482 + } 483 + } 484 + 485 + if (int_events & fep->ev_tx) 486 + fs_enet_tx(dev); 487 + } 488 + 489 + handled = nr > 0; 490 + return IRQ_RETVAL(handled); 491 + } 492 + 493 + void fs_init_bds(struct net_device *dev) 494 + { 495 + struct fs_enet_private *fep = netdev_priv(dev); 496 + cbd_t *bdp; 497 + struct sk_buff *skb; 498 + int i; 499 + 500 + fs_cleanup_bds(dev); 501 + 502 + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; 503 + fep->tx_free = fep->tx_ring; 504 + fep->cur_rx = fep->rx_bd_base; 505 + 506 + /* 507 + * Initialize the receive buffer descriptors. 508 + */ 509 + for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { 510 + skb = dev_alloc_skb(ENET_RX_FRSIZE); 511 + if (skb == NULL) { 512 + printk(KERN_WARNING DRV_MODULE_NAME 513 + ": %s Memory squeeze, unable to allocate skb\n", 514 + dev->name); 515 + break; 516 + } 517 + fep->rx_skbuff[i] = skb; 518 + skb->dev = dev; 519 + CBDW_BUFADDR(bdp, 520 + dma_map_single(fep->dev, skb->data, 521 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 522 + DMA_FROM_DEVICE)); 523 + CBDW_DATLEN(bdp, 0); /* zero */ 524 + CBDW_SC(bdp, BD_ENET_RX_EMPTY | 525 + ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP)); 526 + } 527 + /* 528 + * if we failed, fillup remainder 529 + */ 530 + for (; i < fep->rx_ring; i++, bdp++) { 531 + fep->rx_skbuff[i] = NULL; 532 + CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP); 533 + } 534 + 535 + /* 536 + * ...and the same for transmit. 537 + */ 538 + for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) { 539 + fep->tx_skbuff[i] = NULL; 540 + CBDW_BUFADDR(bdp, 0); 541 + CBDW_DATLEN(bdp, 0); 542 + CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP); 543 + } 544 + } 545 + 546 + void fs_cleanup_bds(struct net_device *dev) 547 + { 548 + struct fs_enet_private *fep = netdev_priv(dev); 549 + struct sk_buff *skb; 550 + int i; 551 + 552 + /* 553 + * Reset SKB transmit buffers. 554 + */ 555 + for (i = 0; i < fep->tx_ring; i++) { 556 + if ((skb = fep->tx_skbuff[i]) == NULL) 557 + continue; 558 + 559 + /* unmap */ 560 + dma_unmap_single(fep->dev, skb->data, skb->len, DMA_TO_DEVICE); 561 + 562 + fep->tx_skbuff[i] = NULL; 563 + dev_kfree_skb(skb); 564 + } 565 + 566 + /* 567 + * Reset SKB receive buffers 568 + */ 569 + for (i = 0; i < fep->rx_ring; i++) { 570 + if ((skb = fep->rx_skbuff[i]) == NULL) 571 + continue; 572 + 573 + /* unmap */ 574 + dma_unmap_single(fep->dev, skb->data, 575 + L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), 576 + DMA_FROM_DEVICE); 577 + 578 + fep->rx_skbuff[i] = NULL; 579 + 580 + dev_kfree_skb(skb); 581 + } 582 + } 583 + 584 + /**********************************************************************************/ 585 + 586 + static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) 587 + { 588 + struct fs_enet_private *fep = netdev_priv(dev); 589 + cbd_t *bdp; 590 + int curidx; 591 + u16 sc; 592 + unsigned long flags; 593 + 594 + spin_lock_irqsave(&fep->tx_lock, flags); 595 + 596 + /* 597 + * Fill in a Tx ring entry 598 + */ 599 + bdp = fep->cur_tx; 600 + 601 + if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) { 602 + netif_stop_queue(dev); 603 + spin_unlock_irqrestore(&fep->tx_lock, flags); 604 + 605 + /* 606 + * Ooops. All transmit buffers are full. Bail out. 607 + * This should not happen, since the tx queue should be stopped. 608 + */ 609 + printk(KERN_WARNING DRV_MODULE_NAME 610 + ": %s tx queue full!.\n", dev->name); 611 + return NETDEV_TX_BUSY; 612 + } 613 + 614 + curidx = bdp - fep->tx_bd_base; 615 + /* 616 + * Clear all of the status flags. 617 + */ 618 + CBDC_SC(bdp, BD_ENET_TX_STATS); 619 + 620 + /* 621 + * Save skb pointer. 622 + */ 623 + fep->tx_skbuff[curidx] = skb; 624 + 625 + fep->stats.tx_bytes += skb->len; 626 + 627 + /* 628 + * Push the data cache so the CPM does not get stale memory data. 629 + */ 630 + CBDW_BUFADDR(bdp, dma_map_single(fep->dev, 631 + skb->data, skb->len, DMA_TO_DEVICE)); 632 + CBDW_DATLEN(bdp, skb->len); 633 + 634 + dev->trans_start = jiffies; 635 + 636 + /* 637 + * If this was the last BD in the ring, start at the beginning again. 638 + */ 639 + if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0) 640 + fep->cur_tx++; 641 + else 642 + fep->cur_tx = fep->tx_bd_base; 643 + 644 + if (!--fep->tx_free) 645 + netif_stop_queue(dev); 646 + 647 + /* Trigger transmission start */ 648 + sc = BD_ENET_TX_READY | BD_ENET_TX_INTR | 649 + BD_ENET_TX_LAST | BD_ENET_TX_TC; 650 + 651 + /* note that while FEC does not have this bit 652 + * it marks it as available for software use 653 + * yay for hw reuse :) */ 654 + if (skb->len <= 60) 655 + sc |= BD_ENET_TX_PAD; 656 + CBDS_SC(bdp, sc); 657 + 658 + (*fep->ops->tx_kickstart)(dev); 659 + 660 + spin_unlock_irqrestore(&fep->tx_lock, flags); 661 + 662 + return NETDEV_TX_OK; 663 + } 664 + 665 + static int fs_request_irq(struct net_device *dev, int irq, const char *name, 666 + irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs)) 667 + { 668 + struct fs_enet_private *fep = netdev_priv(dev); 669 + 670 + (*fep->ops->pre_request_irq)(dev, irq); 671 + return request_irq(irq, irqf, SA_SHIRQ, name, dev); 672 + } 673 + 674 + static void fs_free_irq(struct net_device *dev, int irq) 675 + { 676 + struct fs_enet_private *fep = netdev_priv(dev); 677 + 678 + free_irq(irq, dev); 679 + (*fep->ops->post_free_irq)(dev, irq); 680 + } 681 + 682 + /**********************************************************************************/ 683 + 684 + /* This interrupt occurs when the PHY detects a link change. */ 685 + static irqreturn_t 686 + fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs) 687 + { 688 + struct net_device *dev = dev_id; 689 + struct fs_enet_private *fep; 690 + const struct fs_platform_info *fpi; 691 + 692 + fep = netdev_priv(dev); 693 + fpi = fep->fpi; 694 + 695 + /* 696 + * Acknowledge the interrupt if possible. If we have not 697 + * found the PHY yet we can't process or acknowledge the 698 + * interrupt now. Instead we ignore this interrupt for now, 699 + * which we can do since it is edge triggered. It will be 700 + * acknowledged later by fs_enet_open(). 701 + */ 702 + if (!fep->phy) 703 + return IRQ_NONE; 704 + 705 + fs_mii_ack_int(dev); 706 + fs_mii_link_status_change_check(dev, 0); 707 + 708 + return IRQ_HANDLED; 709 + } 710 + 711 + static void fs_timeout(struct net_device *dev) 712 + { 713 + struct fs_enet_private *fep = netdev_priv(dev); 714 + unsigned long flags; 715 + int wake = 0; 716 + 717 + fep->stats.tx_errors++; 718 + 719 + spin_lock_irqsave(&fep->lock, flags); 720 + 721 + if (dev->flags & IFF_UP) { 722 + (*fep->ops->stop)(dev); 723 + (*fep->ops->restart)(dev); 724 + } 725 + 726 + wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY); 727 + spin_unlock_irqrestore(&fep->lock, flags); 728 + 729 + if (wake) 730 + netif_wake_queue(dev); 731 + } 732 + 733 + static int fs_enet_open(struct net_device *dev) 734 + { 735 + struct fs_enet_private *fep = netdev_priv(dev); 736 + const struct fs_platform_info *fpi = fep->fpi; 737 + int r; 738 + 739 + /* Install our interrupt handler. */ 740 + r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); 741 + if (r != 0) { 742 + printk(KERN_ERR DRV_MODULE_NAME 743 + ": %s Could not allocate FEC IRQ!", dev->name); 744 + return -EINVAL; 745 + } 746 + 747 + /* Install our phy interrupt handler */ 748 + if (fpi->phy_irq != -1) { 749 + 750 + r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt); 751 + if (r != 0) { 752 + printk(KERN_ERR DRV_MODULE_NAME 753 + ": %s Could not allocate PHY IRQ!", dev->name); 754 + fs_free_irq(dev, fep->interrupt); 755 + return -EINVAL; 756 + } 757 + } 758 + 759 + fs_mii_startup(dev); 760 + netif_carrier_off(dev); 761 + fs_mii_link_status_change_check(dev, 1); 762 + 763 + return 0; 764 + } 765 + 766 + static int fs_enet_close(struct net_device *dev) 767 + { 768 + struct fs_enet_private *fep = netdev_priv(dev); 769 + const struct fs_platform_info *fpi = fep->fpi; 770 + unsigned long flags; 771 + 772 + netif_stop_queue(dev); 773 + netif_carrier_off(dev); 774 + fs_mii_shutdown(dev); 775 + 776 + spin_lock_irqsave(&fep->lock, flags); 777 + (*fep->ops->stop)(dev); 778 + spin_unlock_irqrestore(&fep->lock, flags); 779 + 780 + /* release any irqs */ 781 + if (fpi->phy_irq != -1) 782 + fs_free_irq(dev, fpi->phy_irq); 783 + fs_free_irq(dev, fep->interrupt); 784 + 785 + return 0; 786 + } 787 + 788 + static struct net_device_stats *fs_enet_get_stats(struct net_device *dev) 789 + { 790 + struct fs_enet_private *fep = netdev_priv(dev); 791 + return &fep->stats; 792 + } 793 + 794 + /*************************************************************************/ 795 + 796 + static void fs_get_drvinfo(struct net_device *dev, 797 + struct ethtool_drvinfo *info) 798 + { 799 + strcpy(info->driver, DRV_MODULE_NAME); 800 + strcpy(info->version, DRV_MODULE_VERSION); 801 + } 802 + 803 + static int fs_get_regs_len(struct net_device *dev) 804 + { 805 + struct fs_enet_private *fep = netdev_priv(dev); 806 + 807 + return (*fep->ops->get_regs_len)(dev); 808 + } 809 + 810 + static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs, 811 + void *p) 812 + { 813 + struct fs_enet_private *fep = netdev_priv(dev); 814 + unsigned long flags; 815 + int r, len; 816 + 817 + len = regs->len; 818 + 819 + spin_lock_irqsave(&fep->lock, flags); 820 + r = (*fep->ops->get_regs)(dev, p, &len); 821 + spin_unlock_irqrestore(&fep->lock, flags); 822 + 823 + if (r == 0) 824 + regs->version = 0; 825 + } 826 + 827 + static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 828 + { 829 + struct fs_enet_private *fep = netdev_priv(dev); 830 + unsigned long flags; 831 + int rc; 832 + 833 + spin_lock_irqsave(&fep->lock, flags); 834 + rc = mii_ethtool_gset(&fep->mii_if, cmd); 835 + spin_unlock_irqrestore(&fep->lock, flags); 836 + 837 + return rc; 838 + } 839 + 840 + static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 841 + { 842 + struct fs_enet_private *fep = netdev_priv(dev); 843 + unsigned long flags; 844 + int rc; 845 + 846 + spin_lock_irqsave(&fep->lock, flags); 847 + rc = mii_ethtool_sset(&fep->mii_if, cmd); 848 + spin_unlock_irqrestore(&fep->lock, flags); 849 + 850 + return rc; 851 + } 852 + 853 + static int fs_nway_reset(struct net_device *dev) 854 + { 855 + struct fs_enet_private *fep = netdev_priv(dev); 856 + return mii_nway_restart(&fep->mii_if); 857 + } 858 + 859 + static u32 fs_get_msglevel(struct net_device *dev) 860 + { 861 + struct fs_enet_private *fep = netdev_priv(dev); 862 + return fep->msg_enable; 863 + } 864 + 865 + static void fs_set_msglevel(struct net_device *dev, u32 value) 866 + { 867 + struct fs_enet_private *fep = netdev_priv(dev); 868 + fep->msg_enable = value; 869 + } 870 + 871 + static struct ethtool_ops fs_ethtool_ops = { 872 + .get_drvinfo = fs_get_drvinfo, 873 + .get_regs_len = fs_get_regs_len, 874 + .get_settings = fs_get_settings, 875 + .set_settings = fs_set_settings, 876 + .nway_reset = fs_nway_reset, 877 + .get_link = ethtool_op_get_link, 878 + .get_msglevel = fs_get_msglevel, 879 + .set_msglevel = fs_set_msglevel, 880 + .get_tx_csum = ethtool_op_get_tx_csum, 881 + .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ 882 + .get_sg = ethtool_op_get_sg, 883 + .set_sg = ethtool_op_set_sg, 884 + .get_regs = fs_get_regs, 885 + }; 886 + 887 + static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 888 + { 889 + struct fs_enet_private *fep = netdev_priv(dev); 890 + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; 891 + unsigned long flags; 892 + int rc; 893 + 894 + if (!netif_running(dev)) 895 + return -EINVAL; 896 + 897 + spin_lock_irqsave(&fep->lock, flags); 898 + rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); 899 + spin_unlock_irqrestore(&fep->lock, flags); 900 + return rc; 901 + } 902 + 903 + extern int fs_mii_connect(struct net_device *dev); 904 + extern void fs_mii_disconnect(struct net_device *dev); 905 + 906 + static struct net_device *fs_init_instance(struct device *dev, 907 + const struct fs_platform_info *fpi) 908 + { 909 + struct net_device *ndev = NULL; 910 + struct fs_enet_private *fep = NULL; 911 + int privsize, i, r, err = 0, registered = 0; 912 + 913 + /* guard */ 914 + if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX) 915 + return ERR_PTR(-EINVAL); 916 + 917 + privsize = sizeof(*fep) + (sizeof(struct sk_buff **) * 918 + (fpi->rx_ring + fpi->tx_ring)); 919 + 920 + ndev = alloc_etherdev(privsize); 921 + if (!ndev) { 922 + err = -ENOMEM; 923 + goto err; 924 + } 925 + SET_MODULE_OWNER(ndev); 926 + 927 + fep = netdev_priv(ndev); 928 + memset(fep, 0, privsize); /* clear everything */ 929 + 930 + fep->dev = dev; 931 + dev_set_drvdata(dev, ndev); 932 + fep->fpi = fpi; 933 + if (fpi->init_ioports) 934 + fpi->init_ioports(); 935 + 936 + #ifdef CONFIG_FS_ENET_HAS_FEC 937 + if (fs_get_fec_index(fpi->fs_no) >= 0) 938 + fep->ops = &fs_fec_ops; 939 + #endif 940 + 941 + #ifdef CONFIG_FS_ENET_HAS_SCC 942 + if (fs_get_scc_index(fpi->fs_no) >=0 ) 943 + fep->ops = &fs_scc_ops; 944 + #endif 945 + 946 + #ifdef CONFIG_FS_ENET_HAS_FCC 947 + if (fs_get_fcc_index(fpi->fs_no) >= 0) 948 + fep->ops = &fs_fcc_ops; 949 + #endif 950 + 951 + if (fep->ops == NULL) { 952 + printk(KERN_ERR DRV_MODULE_NAME 953 + ": %s No matching ops found (%d).\n", 954 + ndev->name, fpi->fs_no); 955 + err = -EINVAL; 956 + goto err; 957 + } 958 + 959 + r = (*fep->ops->setup_data)(ndev); 960 + if (r != 0) { 961 + printk(KERN_ERR DRV_MODULE_NAME 962 + ": %s setup_data failed\n", 963 + ndev->name); 964 + err = r; 965 + goto err; 966 + } 967 + 968 + /* point rx_skbuff, tx_skbuff */ 969 + fep->rx_skbuff = (struct sk_buff **)&fep[1]; 970 + fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; 971 + 972 + /* init locks */ 973 + spin_lock_init(&fep->lock); 974 + spin_lock_init(&fep->tx_lock); 975 + 976 + /* 977 + * Set the Ethernet address. 978 + */ 979 + for (i = 0; i < 6; i++) 980 + ndev->dev_addr[i] = fpi->macaddr[i]; 981 + 982 + r = (*fep->ops->allocate_bd)(ndev); 983 + 984 + if (fep->ring_base == NULL) { 985 + printk(KERN_ERR DRV_MODULE_NAME 986 + ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r); 987 + err = r; 988 + goto err; 989 + } 990 + 991 + /* 992 + * Set receive and transmit descriptor base. 993 + */ 994 + fep->rx_bd_base = fep->ring_base; 995 + fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; 996 + 997 + /* initialize ring size variables */ 998 + fep->tx_ring = fpi->tx_ring; 999 + fep->rx_ring = fpi->rx_ring; 1000 + 1001 + /* 1002 + * The FEC Ethernet specific entries in the device structure. 1003 + */ 1004 + ndev->open = fs_enet_open; 1005 + ndev->hard_start_xmit = fs_enet_start_xmit; 1006 + ndev->tx_timeout = fs_timeout; 1007 + ndev->watchdog_timeo = 2 * HZ; 1008 + ndev->stop = fs_enet_close; 1009 + ndev->get_stats = fs_enet_get_stats; 1010 + ndev->set_multicast_list = fs_set_multicast_list; 1011 + if (fpi->use_napi) { 1012 + ndev->poll = fs_enet_rx_napi; 1013 + ndev->weight = fpi->napi_weight; 1014 + } 1015 + ndev->ethtool_ops = &fs_ethtool_ops; 1016 + ndev->do_ioctl = fs_ioctl; 1017 + 1018 + init_timer(&fep->phy_timer_list); 1019 + 1020 + netif_carrier_off(ndev); 1021 + 1022 + err = register_netdev(ndev); 1023 + if (err != 0) { 1024 + printk(KERN_ERR DRV_MODULE_NAME 1025 + ": %s register_netdev failed.\n", ndev->name); 1026 + goto err; 1027 + } 1028 + registered = 1; 1029 + 1030 + err = fs_mii_connect(ndev); 1031 + if (err != 0) { 1032 + printk(KERN_ERR DRV_MODULE_NAME 1033 + ": %s fs_mii_connect failed.\n", ndev->name); 1034 + goto err; 1035 + } 1036 + 1037 + return ndev; 1038 + 1039 + err: 1040 + if (ndev != NULL) { 1041 + 1042 + if (registered) 1043 + unregister_netdev(ndev); 1044 + 1045 + if (fep != NULL) { 1046 + (*fep->ops->free_bd)(ndev); 1047 + (*fep->ops->cleanup_data)(ndev); 1048 + } 1049 + 1050 + free_netdev(ndev); 1051 + } 1052 + 1053 + dev_set_drvdata(dev, NULL); 1054 + 1055 + return ERR_PTR(err); 1056 + } 1057 + 1058 + static int fs_cleanup_instance(struct net_device *ndev) 1059 + { 1060 + struct fs_enet_private *fep; 1061 + const struct fs_platform_info *fpi; 1062 + struct device *dev; 1063 + 1064 + if (ndev == NULL) 1065 + return -EINVAL; 1066 + 1067 + fep = netdev_priv(ndev); 1068 + if (fep == NULL) 1069 + return -EINVAL; 1070 + 1071 + fpi = fep->fpi; 1072 + 1073 + fs_mii_disconnect(ndev); 1074 + 1075 + unregister_netdev(ndev); 1076 + 1077 + dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), 1078 + fep->ring_base, fep->ring_mem_addr); 1079 + 1080 + /* reset it */ 1081 + (*fep->ops->cleanup_data)(ndev); 1082 + 1083 + dev = fep->dev; 1084 + if (dev != NULL) { 1085 + dev_set_drvdata(dev, NULL); 1086 + fep->dev = NULL; 1087 + } 1088 + 1089 + free_netdev(ndev); 1090 + 1091 + return 0; 1092 + } 1093 + 1094 + /**************************************************************************************/ 1095 + 1096 + /* handy pointer to the immap */ 1097 + void *fs_enet_immap = NULL; 1098 + 1099 + static int setup_immap(void) 1100 + { 1101 + phys_addr_t paddr = 0; 1102 + unsigned long size = 0; 1103 + 1104 + #ifdef CONFIG_CPM1 1105 + paddr = IMAP_ADDR; 1106 + size = 0x10000; /* map 64K */ 1107 + #endif 1108 + 1109 + #ifdef CONFIG_CPM2 1110 + paddr = CPM_MAP_ADDR; 1111 + size = 0x40000; /* map 256 K */ 1112 + #endif 1113 + fs_enet_immap = ioremap(paddr, size); 1114 + if (fs_enet_immap == NULL) 1115 + return -EBADF; /* XXX ahem; maybe just BUG_ON? */ 1116 + 1117 + return 0; 1118 + } 1119 + 1120 + static void cleanup_immap(void) 1121 + { 1122 + if (fs_enet_immap != NULL) { 1123 + iounmap(fs_enet_immap); 1124 + fs_enet_immap = NULL; 1125 + } 1126 + } 1127 + 1128 + /**************************************************************************************/ 1129 + 1130 + static int __devinit fs_enet_probe(struct device *dev) 1131 + { 1132 + struct net_device *ndev; 1133 + 1134 + /* no fixup - no device */ 1135 + if (dev->platform_data == NULL) { 1136 + printk(KERN_INFO "fs_enet: " 1137 + "probe called with no platform data; " 1138 + "remove unused devices\n"); 1139 + return -ENODEV; 1140 + } 1141 + 1142 + ndev = fs_init_instance(dev, dev->platform_data); 1143 + if (IS_ERR(ndev)) 1144 + return PTR_ERR(ndev); 1145 + return 0; 1146 + } 1147 + 1148 + static int fs_enet_remove(struct device *dev) 1149 + { 1150 + return fs_cleanup_instance(dev_get_drvdata(dev)); 1151 + } 1152 + 1153 + static struct device_driver fs_enet_fec_driver = { 1154 + .name = "fsl-cpm-fec", 1155 + .bus = &platform_bus_type, 1156 + .probe = fs_enet_probe, 1157 + .remove = fs_enet_remove, 1158 + #ifdef CONFIG_PM 1159 + /* .suspend = fs_enet_suspend, TODO */ 1160 + /* .resume = fs_enet_resume, TODO */ 1161 + #endif 1162 + }; 1163 + 1164 + static struct device_driver fs_enet_scc_driver = { 1165 + .name = "fsl-cpm-scc", 1166 + .bus = &platform_bus_type, 1167 + .probe = fs_enet_probe, 1168 + .remove = fs_enet_remove, 1169 + #ifdef CONFIG_PM 1170 + /* .suspend = fs_enet_suspend, TODO */ 1171 + /* .resume = fs_enet_resume, TODO */ 1172 + #endif 1173 + }; 1174 + 1175 + static struct device_driver fs_enet_fcc_driver = { 1176 + .name = "fsl-cpm-fcc", 1177 + .bus = &platform_bus_type, 1178 + .probe = fs_enet_probe, 1179 + .remove = fs_enet_remove, 1180 + #ifdef CONFIG_PM 1181 + /* .suspend = fs_enet_suspend, TODO */ 1182 + /* .resume = fs_enet_resume, TODO */ 1183 + #endif 1184 + }; 1185 + 1186 + static int __init fs_init(void) 1187 + { 1188 + int r; 1189 + 1190 + printk(KERN_INFO 1191 + "%s", version); 1192 + 1193 + r = setup_immap(); 1194 + if (r != 0) 1195 + return r; 1196 + r = driver_register(&fs_enet_fec_driver); 1197 + if (r != 0) 1198 + goto err; 1199 + 1200 + r = driver_register(&fs_enet_fcc_driver); 1201 + if (r != 0) 1202 + goto err; 1203 + 1204 + r = driver_register(&fs_enet_scc_driver); 1205 + if (r != 0) 1206 + goto err; 1207 + 1208 + return 0; 1209 + err: 1210 + cleanup_immap(); 1211 + return r; 1212 + 1213 + } 1214 + 1215 + static void __exit fs_cleanup(void) 1216 + { 1217 + driver_unregister(&fs_enet_fec_driver); 1218 + driver_unregister(&fs_enet_fcc_driver); 1219 + driver_unregister(&fs_enet_scc_driver); 1220 + cleanup_immap(); 1221 + } 1222 + 1223 + /**************************************************************************************/ 1224 + 1225 + module_init(fs_init); 1226 + module_exit(fs_cleanup);
+507
drivers/net/fs_enet/fs_enet-mii.c
··· 1 + /* 2 + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. 3 + * 4 + * Copyright (c) 2003 Intracom S.A. 5 + * by Pantelis Antoniou <panto@intracom.gr> 6 + * 7 + * 2005 (c) MontaVista Software, Inc. 8 + * Vitaly Bordug <vbordug@ru.mvista.com> 9 + * 10 + * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com> 11 + * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se> 12 + * 13 + * This file is licensed under the terms of the GNU General Public License 14 + * version 2. This program is licensed "as is" without any warranty of any 15 + * kind, whether express or implied. 16 + */ 17 + 18 + 19 + #include <linux/config.h> 20 + #include <linux/module.h> 21 + #include <linux/types.h> 22 + #include <linux/kernel.h> 23 + #include <linux/sched.h> 24 + #include <linux/string.h> 25 + #include <linux/ptrace.h> 26 + #include <linux/errno.h> 27 + #include <linux/ioport.h> 28 + #include <linux/slab.h> 29 + #include <linux/interrupt.h> 30 + #include <linux/pci.h> 31 + #include <linux/init.h> 32 + #include <linux/delay.h> 33 + #include <linux/netdevice.h> 34 + #include <linux/etherdevice.h> 35 + #include <linux/skbuff.h> 36 + #include <linux/spinlock.h> 37 + #include <linux/mii.h> 38 + #include <linux/ethtool.h> 39 + #include <linux/bitops.h> 40 + 41 + #include <asm/pgtable.h> 42 + #include <asm/irq.h> 43 + #include <asm/uaccess.h> 44 + 45 + #include "fs_enet.h" 46 + 47 + /*************************************************/ 48 + 49 + /* 50 + * Generic PHY support. 51 + * Should work for all PHYs, but link change is detected by polling 52 + */ 53 + 54 + static void generic_timer_callback(unsigned long data) 55 + { 56 + struct net_device *dev = (struct net_device *)data; 57 + struct fs_enet_private *fep = netdev_priv(dev); 58 + 59 + fep->phy_timer_list.expires = jiffies + HZ / 2; 60 + 61 + add_timer(&fep->phy_timer_list); 62 + 63 + fs_mii_link_status_change_check(dev, 0); 64 + } 65 + 66 + static void generic_startup(struct net_device *dev) 67 + { 68 + struct fs_enet_private *fep = netdev_priv(dev); 69 + 70 + fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */ 71 + fep->phy_timer_list.data = (unsigned long)dev; 72 + fep->phy_timer_list.function = generic_timer_callback; 73 + add_timer(&fep->phy_timer_list); 74 + } 75 + 76 + static void generic_shutdown(struct net_device *dev) 77 + { 78 + struct fs_enet_private *fep = netdev_priv(dev); 79 + 80 + del_timer_sync(&fep->phy_timer_list); 81 + } 82 + 83 + /* ------------------------------------------------------------------------- */ 84 + /* The Davicom DM9161 is used on the NETTA board */ 85 + 86 + /* register definitions */ 87 + 88 + #define MII_DM9161_ANAR 4 /* Aux. Config Register */ 89 + #define MII_DM9161_ACR 16 /* Aux. Config Register */ 90 + #define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */ 91 + #define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */ 92 + #define MII_DM9161_INTR 21 /* Interrupt Register */ 93 + #define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */ 94 + #define MII_DM9161_DISCR 23 /* Disconnect Counter Register */ 95 + 96 + static void dm9161_startup(struct net_device *dev) 97 + { 98 + struct fs_enet_private *fep = netdev_priv(dev); 99 + 100 + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000); 101 + /* Start autonegotiation */ 102 + fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200); 103 + 104 + set_current_state(TASK_UNINTERRUPTIBLE); 105 + schedule_timeout(HZ*8); 106 + } 107 + 108 + static void dm9161_ack_int(struct net_device *dev) 109 + { 110 + struct fs_enet_private *fep = netdev_priv(dev); 111 + 112 + fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR); 113 + } 114 + 115 + static void dm9161_shutdown(struct net_device *dev) 116 + { 117 + struct fs_enet_private *fep = netdev_priv(dev); 118 + 119 + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00); 120 + } 121 + 122 + /**********************************************************************************/ 123 + 124 + static const struct phy_info phy_info[] = { 125 + { 126 + .id = 0x00181b88, 127 + .name = "DM9161", 128 + .startup = dm9161_startup, 129 + .ack_int = dm9161_ack_int, 130 + .shutdown = dm9161_shutdown, 131 + }, { 132 + .id = 0, 133 + .name = "GENERIC", 134 + .startup = generic_startup, 135 + .shutdown = generic_shutdown, 136 + }, 137 + }; 138 + 139 + /**********************************************************************************/ 140 + 141 + static int phy_id_detect(struct net_device *dev) 142 + { 143 + struct fs_enet_private *fep = netdev_priv(dev); 144 + const struct fs_platform_info *fpi = fep->fpi; 145 + struct fs_enet_mii_bus *bus = fep->mii_bus; 146 + int i, r, start, end, phytype, physubtype; 147 + const struct phy_info *phy; 148 + int phy_hwid, phy_id; 149 + 150 + phy_hwid = -1; 151 + fep->phy = NULL; 152 + 153 + /* auto-detect? */ 154 + if (fpi->phy_addr == -1) { 155 + start = 1; 156 + end = 32; 157 + } else { /* direct */ 158 + start = fpi->phy_addr; 159 + end = start + 1; 160 + } 161 + 162 + for (phy_id = start; phy_id < end; phy_id++) { 163 + /* skip already used phy addresses on this bus */ 164 + if (bus->usage_map & (1 << phy_id)) 165 + continue; 166 + r = fs_mii_read(dev, phy_id, MII_PHYSID1); 167 + if (r == -1 || (phytype = (r & 0xffff)) == 0xffff) 168 + continue; 169 + r = fs_mii_read(dev, phy_id, MII_PHYSID2); 170 + if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff) 171 + continue; 172 + phy_hwid = (phytype << 16) | physubtype; 173 + if (phy_hwid != -1) 174 + break; 175 + } 176 + 177 + if (phy_hwid == -1) { 178 + printk(KERN_ERR DRV_MODULE_NAME 179 + ": %s No PHY detected! range=0x%02x-0x%02x\n", 180 + dev->name, start, end); 181 + return -1; 182 + } 183 + 184 + for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++) 185 + if (phy->id == (phy_hwid >> 4) || phy->id == 0) 186 + break; 187 + 188 + if (i >= ARRAY_SIZE(phy_info)) { 189 + printk(KERN_ERR DRV_MODULE_NAME 190 + ": %s PHY id 0x%08x is not supported!\n", 191 + dev->name, phy_hwid); 192 + return -1; 193 + } 194 + 195 + fep->phy = phy; 196 + 197 + /* mark this address as used */ 198 + bus->usage_map |= (1 << phy_id); 199 + 200 + printk(KERN_INFO DRV_MODULE_NAME 201 + ": %s Phy @ 0x%x, type %s (0x%08x)%s\n", 202 + dev->name, phy_id, fep->phy->name, phy_hwid, 203 + fpi->phy_addr == -1 ? " (auto-detected)" : ""); 204 + 205 + return phy_id; 206 + } 207 + 208 + void fs_mii_startup(struct net_device *dev) 209 + { 210 + struct fs_enet_private *fep = netdev_priv(dev); 211 + 212 + if (fep->phy->startup) 213 + (*fep->phy->startup) (dev); 214 + } 215 + 216 + void fs_mii_shutdown(struct net_device *dev) 217 + { 218 + struct fs_enet_private *fep = netdev_priv(dev); 219 + 220 + if (fep->phy->shutdown) 221 + (*fep->phy->shutdown) (dev); 222 + } 223 + 224 + void fs_mii_ack_int(struct net_device *dev) 225 + { 226 + struct fs_enet_private *fep = netdev_priv(dev); 227 + 228 + if (fep->phy->ack_int) 229 + (*fep->phy->ack_int) (dev); 230 + } 231 + 232 + #define MII_LINK 0x0001 233 + #define MII_HALF 0x0002 234 + #define MII_FULL 0x0004 235 + #define MII_BASE4 0x0008 236 + #define MII_10M 0x0010 237 + #define MII_100M 0x0020 238 + #define MII_1G 0x0040 239 + #define MII_10G 0x0080 240 + 241 + /* return full mii info at one gulp, with a usable form */ 242 + static unsigned int mii_full_status(struct mii_if_info *mii) 243 + { 244 + unsigned int status; 245 + int bmsr, adv, lpa, neg; 246 + struct fs_enet_private* fep = netdev_priv(mii->dev); 247 + 248 + /* first, a dummy read, needed to latch some MII phys */ 249 + (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); 250 + bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); 251 + 252 + /* no link */ 253 + if ((bmsr & BMSR_LSTATUS) == 0) 254 + return 0; 255 + 256 + status = MII_LINK; 257 + 258 + /* Lets look what ANEG says if it's supported - otherwize we shall 259 + take the right values from the platform info*/ 260 + if(!mii->force_media) { 261 + /* autoneg not completed; don't bother */ 262 + if ((bmsr & BMSR_ANEGCOMPLETE) == 0) 263 + return 0; 264 + 265 + adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE); 266 + lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA); 267 + 268 + neg = lpa & adv; 269 + } else { 270 + neg = fep->fpi->bus_info->lpa; 271 + } 272 + 273 + if (neg & LPA_100FULL) 274 + status |= MII_FULL | MII_100M; 275 + else if (neg & LPA_100BASE4) 276 + status |= MII_FULL | MII_BASE4 | MII_100M; 277 + else if (neg & LPA_100HALF) 278 + status |= MII_HALF | MII_100M; 279 + else if (neg & LPA_10FULL) 280 + status |= MII_FULL | MII_10M; 281 + else 282 + status |= MII_HALF | MII_10M; 283 + 284 + return status; 285 + } 286 + 287 + void fs_mii_link_status_change_check(struct net_device *dev, int init_media) 288 + { 289 + struct fs_enet_private *fep = netdev_priv(dev); 290 + struct mii_if_info *mii = &fep->mii_if; 291 + unsigned int mii_status; 292 + int ok_to_print, link, duplex, speed; 293 + unsigned long flags; 294 + 295 + ok_to_print = netif_msg_link(fep); 296 + 297 + mii_status = mii_full_status(mii); 298 + 299 + if (!init_media && mii_status == fep->last_mii_status) 300 + return; 301 + 302 + fep->last_mii_status = mii_status; 303 + 304 + link = !!(mii_status & MII_LINK); 305 + duplex = !!(mii_status & MII_FULL); 306 + speed = (mii_status & MII_100M) ? 100 : 10; 307 + 308 + if (link == 0) { 309 + netif_carrier_off(mii->dev); 310 + netif_stop_queue(dev); 311 + if (!init_media) { 312 + spin_lock_irqsave(&fep->lock, flags); 313 + (*fep->ops->stop)(dev); 314 + spin_unlock_irqrestore(&fep->lock, flags); 315 + } 316 + 317 + if (ok_to_print) 318 + printk(KERN_INFO "%s: link down\n", mii->dev->name); 319 + 320 + } else { 321 + 322 + mii->full_duplex = duplex; 323 + 324 + netif_carrier_on(mii->dev); 325 + 326 + spin_lock_irqsave(&fep->lock, flags); 327 + fep->duplex = duplex; 328 + fep->speed = speed; 329 + (*fep->ops->restart)(dev); 330 + spin_unlock_irqrestore(&fep->lock, flags); 331 + 332 + netif_start_queue(dev); 333 + 334 + if (ok_to_print) 335 + printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n", 336 + dev->name, speed, duplex ? "full" : "half"); 337 + } 338 + } 339 + 340 + /**********************************************************************************/ 341 + 342 + int fs_mii_read(struct net_device *dev, int phy_id, int location) 343 + { 344 + struct fs_enet_private *fep = netdev_priv(dev); 345 + struct fs_enet_mii_bus *bus = fep->mii_bus; 346 + 347 + unsigned long flags; 348 + int ret; 349 + 350 + spin_lock_irqsave(&bus->mii_lock, flags); 351 + ret = (*bus->mii_read)(bus, phy_id, location); 352 + spin_unlock_irqrestore(&bus->mii_lock, flags); 353 + 354 + return ret; 355 + } 356 + 357 + void fs_mii_write(struct net_device *dev, int phy_id, int location, int value) 358 + { 359 + struct fs_enet_private *fep = netdev_priv(dev); 360 + struct fs_enet_mii_bus *bus = fep->mii_bus; 361 + unsigned long flags; 362 + 363 + spin_lock_irqsave(&bus->mii_lock, flags); 364 + (*bus->mii_write)(bus, phy_id, location, value); 365 + spin_unlock_irqrestore(&bus->mii_lock, flags); 366 + } 367 + 368 + /*****************************************************************************/ 369 + 370 + /* list of all registered mii buses */ 371 + static LIST_HEAD(fs_mii_bus_list); 372 + 373 + static struct fs_enet_mii_bus *lookup_bus(int method, int id) 374 + { 375 + struct list_head *ptr; 376 + struct fs_enet_mii_bus *bus; 377 + 378 + list_for_each(ptr, &fs_mii_bus_list) { 379 + bus = list_entry(ptr, struct fs_enet_mii_bus, list); 380 + if (bus->bus_info->method == method && 381 + bus->bus_info->id == id) 382 + return bus; 383 + } 384 + return NULL; 385 + } 386 + 387 + static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) 388 + { 389 + struct fs_enet_mii_bus *bus; 390 + int ret = 0; 391 + 392 + bus = kmalloc(sizeof(*bus), GFP_KERNEL); 393 + if (bus == NULL) { 394 + ret = -ENOMEM; 395 + goto err; 396 + } 397 + memset(bus, 0, sizeof(*bus)); 398 + spin_lock_init(&bus->mii_lock); 399 + bus->bus_info = bi; 400 + bus->refs = 0; 401 + bus->usage_map = 0; 402 + 403 + /* perform initialization */ 404 + switch (bi->method) { 405 + 406 + case fsmii_fixed: 407 + ret = fs_mii_fixed_init(bus); 408 + if (ret != 0) 409 + goto err; 410 + break; 411 + 412 + case fsmii_bitbang: 413 + ret = fs_mii_bitbang_init(bus); 414 + if (ret != 0) 415 + goto err; 416 + break; 417 + #ifdef CONFIG_FS_ENET_HAS_FEC 418 + case fsmii_fec: 419 + ret = fs_mii_fec_init(bus); 420 + if (ret != 0) 421 + goto err; 422 + break; 423 + #endif 424 + default: 425 + ret = -EINVAL; 426 + goto err; 427 + } 428 + 429 + list_add(&bus->list, &fs_mii_bus_list); 430 + 431 + return bus; 432 + 433 + err: 434 + if (bus) 435 + kfree(bus); 436 + return ERR_PTR(ret); 437 + } 438 + 439 + static void destroy_bus(struct fs_enet_mii_bus *bus) 440 + { 441 + /* remove from bus list */ 442 + list_del(&bus->list); 443 + 444 + /* nothing more needed */ 445 + kfree(bus); 446 + } 447 + 448 + int fs_mii_connect(struct net_device *dev) 449 + { 450 + struct fs_enet_private *fep = netdev_priv(dev); 451 + const struct fs_platform_info *fpi = fep->fpi; 452 + struct fs_enet_mii_bus *bus = NULL; 453 + 454 + /* check method validity */ 455 + switch (fpi->bus_info->method) { 456 + case fsmii_fixed: 457 + case fsmii_bitbang: 458 + break; 459 + #ifdef CONFIG_FS_ENET_HAS_FEC 460 + case fsmii_fec: 461 + break; 462 + #endif 463 + default: 464 + printk(KERN_ERR DRV_MODULE_NAME 465 + ": %s Unknown MII bus method (%d)!\n", 466 + dev->name, fpi->bus_info->method); 467 + return -EINVAL; 468 + } 469 + 470 + bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id); 471 + 472 + /* if not found create new bus */ 473 + if (bus == NULL) { 474 + bus = create_bus(fpi->bus_info); 475 + if (IS_ERR(bus)) { 476 + printk(KERN_ERR DRV_MODULE_NAME 477 + ": %s MII bus creation failure!\n", dev->name); 478 + return PTR_ERR(bus); 479 + } 480 + } 481 + 482 + bus->refs++; 483 + 484 + fep->mii_bus = bus; 485 + 486 + fep->mii_if.dev = dev; 487 + fep->mii_if.phy_id_mask = 0x1f; 488 + fep->mii_if.reg_num_mask = 0x1f; 489 + fep->mii_if.mdio_read = fs_mii_read; 490 + fep->mii_if.mdio_write = fs_mii_write; 491 + fep->mii_if.force_media = fpi->bus_info->disable_aneg; 492 + fep->mii_if.phy_id = phy_id_detect(dev); 493 + 494 + return 0; 495 + } 496 + 497 + void fs_mii_disconnect(struct net_device *dev) 498 + { 499 + struct fs_enet_private *fep = netdev_priv(dev); 500 + struct fs_enet_mii_bus *bus = NULL; 501 + 502 + bus = fep->mii_bus; 503 + fep->mii_bus = NULL; 504 + 505 + if (--bus->refs <= 0) 506 + destroy_bus(bus); 507 + }
+245
drivers/net/fs_enet/fs_enet.h
··· 1 + #ifndef FS_ENET_H 2 + #define FS_ENET_H 3 + 4 + #include <linux/mii.h> 5 + #include <linux/netdevice.h> 6 + #include <linux/types.h> 7 + #include <linux/version.h> 8 + #include <linux/list.h> 9 + 10 + #include <linux/fs_enet_pd.h> 11 + 12 + #include <asm/dma-mapping.h> 13 + 14 + #ifdef CONFIG_CPM1 15 + #include <asm/commproc.h> 16 + #endif 17 + 18 + #ifdef CONFIG_CPM2 19 + #include <asm/cpm2.h> 20 + #endif 21 + 22 + /* hw driver ops */ 23 + struct fs_ops { 24 + int (*setup_data)(struct net_device *dev); 25 + int (*allocate_bd)(struct net_device *dev); 26 + void (*free_bd)(struct net_device *dev); 27 + void (*cleanup_data)(struct net_device *dev); 28 + void (*set_multicast_list)(struct net_device *dev); 29 + void (*restart)(struct net_device *dev); 30 + void (*stop)(struct net_device *dev); 31 + void (*pre_request_irq)(struct net_device *dev, int irq); 32 + void (*post_free_irq)(struct net_device *dev, int irq); 33 + void (*napi_clear_rx_event)(struct net_device *dev); 34 + void (*napi_enable_rx)(struct net_device *dev); 35 + void (*napi_disable_rx)(struct net_device *dev); 36 + void (*rx_bd_done)(struct net_device *dev); 37 + void (*tx_kickstart)(struct net_device *dev); 38 + u32 (*get_int_events)(struct net_device *dev); 39 + void (*clear_int_events)(struct net_device *dev, u32 int_events); 40 + void (*ev_error)(struct net_device *dev, u32 int_events); 41 + int (*get_regs)(struct net_device *dev, void *p, int *sizep); 42 + int (*get_regs_len)(struct net_device *dev); 43 + void (*tx_restart)(struct net_device *dev); 44 + }; 45 + 46 + struct phy_info { 47 + unsigned int id; 48 + const char *name; 49 + void (*startup) (struct net_device * dev); 50 + void (*shutdown) (struct net_device * dev); 51 + void (*ack_int) (struct net_device * dev); 52 + }; 53 + 54 + /* The FEC stores dest/src/type, data, and checksum for receive packets. 55 + */ 56 + #define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */ 57 + #define MIN_MTU 46 /* this is data size */ 58 + #define CRC_LEN 4 59 + 60 + #define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN) 61 + #define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN) 62 + 63 + /* Must be a multiple of 32 (to cover both FEC & FCC) */ 64 + #define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE + 31) & ~31) 65 + /* This is needed so that invalidate_xxx wont invalidate too much */ 66 + #define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE) 67 + 68 + struct fs_enet_mii_bus { 69 + struct list_head list; 70 + spinlock_t mii_lock; 71 + const struct fs_mii_bus_info *bus_info; 72 + int refs; 73 + u32 usage_map; 74 + 75 + int (*mii_read)(struct fs_enet_mii_bus *bus, 76 + int phy_id, int location); 77 + 78 + void (*mii_write)(struct fs_enet_mii_bus *bus, 79 + int phy_id, int location, int value); 80 + 81 + union { 82 + struct { 83 + unsigned int mii_speed; 84 + void *fecp; 85 + } fec; 86 + 87 + struct { 88 + /* note that the actual port size may */ 89 + /* be different; cpm(s) handle it OK */ 90 + u8 mdio_msk; 91 + u8 *mdio_dir; 92 + u8 *mdio_dat; 93 + u8 mdc_msk; 94 + u8 *mdc_dir; 95 + u8 *mdc_dat; 96 + } bitbang; 97 + 98 + struct { 99 + u16 lpa; 100 + } fixed; 101 + }; 102 + }; 103 + 104 + int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus); 105 + int fs_mii_fixed_init(struct fs_enet_mii_bus *bus); 106 + int fs_mii_fec_init(struct fs_enet_mii_bus *bus); 107 + 108 + struct fs_enet_private { 109 + struct device *dev; /* pointer back to the device (must be initialized first) */ 110 + spinlock_t lock; /* during all ops except TX pckt processing */ 111 + spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */ 112 + const struct fs_platform_info *fpi; 113 + const struct fs_ops *ops; 114 + int rx_ring, tx_ring; 115 + dma_addr_t ring_mem_addr; 116 + void *ring_base; 117 + struct sk_buff **rx_skbuff; 118 + struct sk_buff **tx_skbuff; 119 + cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ 120 + cbd_t *tx_bd_base; 121 + cbd_t *dirty_tx; /* ring entries to be free()ed. */ 122 + cbd_t *cur_rx; 123 + cbd_t *cur_tx; 124 + int tx_free; 125 + struct net_device_stats stats; 126 + struct timer_list phy_timer_list; 127 + const struct phy_info *phy; 128 + u32 msg_enable; 129 + struct mii_if_info mii_if; 130 + unsigned int last_mii_status; 131 + struct fs_enet_mii_bus *mii_bus; 132 + int interrupt; 133 + 134 + int duplex, speed; /* current settings */ 135 + 136 + /* event masks */ 137 + u32 ev_napi_rx; /* mask of NAPI rx events */ 138 + u32 ev_rx; /* rx event mask */ 139 + u32 ev_tx; /* tx event mask */ 140 + u32 ev_err; /* error event mask */ 141 + 142 + u16 bd_rx_empty; /* mask of BD rx empty */ 143 + u16 bd_rx_err; /* mask of BD rx errors */ 144 + 145 + union { 146 + struct { 147 + int idx; /* FEC1 = 0, FEC2 = 1 */ 148 + void *fecp; /* hw registers */ 149 + u32 hthi, htlo; /* state for multicast */ 150 + } fec; 151 + 152 + struct { 153 + int idx; /* FCC1-3 = 0-2 */ 154 + void *fccp; /* hw registers */ 155 + void *ep; /* parameter ram */ 156 + void *fcccp; /* hw registers cont. */ 157 + void *mem; /* FCC DPRAM */ 158 + u32 gaddrh, gaddrl; /* group address */ 159 + } fcc; 160 + 161 + struct { 162 + int idx; /* FEC1 = 0, FEC2 = 1 */ 163 + void *sccp; /* hw registers */ 164 + void *ep; /* parameter ram */ 165 + u32 hthi, htlo; /* state for multicast */ 166 + } scc; 167 + 168 + }; 169 + }; 170 + 171 + /***************************************************************************/ 172 + 173 + int fs_mii_read(struct net_device *dev, int phy_id, int location); 174 + void fs_mii_write(struct net_device *dev, int phy_id, int location, int value); 175 + 176 + void fs_mii_startup(struct net_device *dev); 177 + void fs_mii_shutdown(struct net_device *dev); 178 + void fs_mii_ack_int(struct net_device *dev); 179 + 180 + void fs_mii_link_status_change_check(struct net_device *dev, int init_media); 181 + 182 + void fs_init_bds(struct net_device *dev); 183 + void fs_cleanup_bds(struct net_device *dev); 184 + 185 + /***************************************************************************/ 186 + 187 + #define DRV_MODULE_NAME "fs_enet" 188 + #define PFX DRV_MODULE_NAME ": " 189 + #define DRV_MODULE_VERSION "1.0" 190 + #define DRV_MODULE_RELDATE "Aug 8, 2005" 191 + 192 + /***************************************************************************/ 193 + 194 + int fs_enet_platform_init(void); 195 + void fs_enet_platform_cleanup(void); 196 + 197 + /***************************************************************************/ 198 + 199 + /* buffer descriptor access macros */ 200 + 201 + /* access macros */ 202 + #if defined(CONFIG_CPM1) 203 + /* for a a CPM1 __raw_xxx's are sufficient */ 204 + #define __cbd_out32(addr, x) __raw_writel(x, addr) 205 + #define __cbd_out16(addr, x) __raw_writew(x, addr) 206 + #define __cbd_in32(addr) __raw_readl(addr) 207 + #define __cbd_in16(addr) __raw_readw(addr) 208 + #else 209 + /* for others play it safe */ 210 + #define __cbd_out32(addr, x) out_be32(addr, x) 211 + #define __cbd_out16(addr, x) out_be16(addr, x) 212 + #define __cbd_in32(addr) in_be32(addr) 213 + #define __cbd_in16(addr) in_be16(addr) 214 + #endif 215 + 216 + /* write */ 217 + #define CBDW_SC(_cbd, _sc) __cbd_out16(&(_cbd)->cbd_sc, (_sc)) 218 + #define CBDW_DATLEN(_cbd, _datlen) __cbd_out16(&(_cbd)->cbd_datlen, (_datlen)) 219 + #define CBDW_BUFADDR(_cbd, _bufaddr) __cbd_out32(&(_cbd)->cbd_bufaddr, (_bufaddr)) 220 + 221 + /* read */ 222 + #define CBDR_SC(_cbd) __cbd_in16(&(_cbd)->cbd_sc) 223 + #define CBDR_DATLEN(_cbd) __cbd_in16(&(_cbd)->cbd_datlen) 224 + #define CBDR_BUFADDR(_cbd) __cbd_in32(&(_cbd)->cbd_bufaddr) 225 + 226 + /* set bits */ 227 + #define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc)) 228 + 229 + /* clear bits */ 230 + #define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc)) 231 + 232 + /*******************************************************************/ 233 + 234 + extern const struct fs_ops fs_fec_ops; 235 + extern const struct fs_ops fs_fcc_ops; 236 + extern const struct fs_ops fs_scc_ops; 237 + 238 + /*******************************************************************/ 239 + 240 + /* handy pointer to the immap */ 241 + extern void *fs_enet_immap; 242 + 243 + /*******************************************************************/ 244 + 245 + #endif
+578
drivers/net/fs_enet/mac-fcc.c
··· 1 + /* 2 + * FCC driver for Motorola MPC82xx (PQ2). 3 + * 4 + * Copyright (c) 2003 Intracom S.A. 5 + * by Pantelis Antoniou <panto@intracom.gr> 6 + * 7 + * 2005 (c) MontaVista Software, Inc. 8 + * Vitaly Bordug <vbordug@ru.mvista.com> 9 + * 10 + * This file is licensed under the terms of the GNU General Public License 11 + * version 2. This program is licensed "as is" without any warranty of any 12 + * kind, whether express or implied. 13 + */ 14 + 15 + #include <linux/config.h> 16 + #include <linux/module.h> 17 + #include <linux/kernel.h> 18 + #include <linux/types.h> 19 + #include <linux/sched.h> 20 + #include <linux/string.h> 21 + #include <linux/ptrace.h> 22 + #include <linux/errno.h> 23 + #include <linux/ioport.h> 24 + #include <linux/slab.h> 25 + #include <linux/interrupt.h> 26 + #include <linux/pci.h> 27 + #include <linux/init.h> 28 + #include <linux/delay.h> 29 + #include <linux/netdevice.h> 30 + #include <linux/etherdevice.h> 31 + #include <linux/skbuff.h> 32 + #include <linux/spinlock.h> 33 + #include <linux/mii.h> 34 + #include <linux/ethtool.h> 35 + #include <linux/bitops.h> 36 + #include <linux/fs.h> 37 + 38 + #include <asm/immap_cpm2.h> 39 + #include <asm/mpc8260.h> 40 + #include <asm/cpm2.h> 41 + 42 + #include <asm/pgtable.h> 43 + #include <asm/irq.h> 44 + #include <asm/uaccess.h> 45 + 46 + #include "fs_enet.h" 47 + 48 + /*************************************************/ 49 + 50 + /* FCC access macros */ 51 + 52 + #define __fcc_out32(addr, x) out_be32((unsigned *)addr, x) 53 + #define __fcc_out16(addr, x) out_be16((unsigned short *)addr, x) 54 + #define __fcc_out8(addr, x) out_8((unsigned char *)addr, x) 55 + #define __fcc_in32(addr) in_be32((unsigned *)addr) 56 + #define __fcc_in16(addr) in_be16((unsigned short *)addr) 57 + #define __fcc_in8(addr) in_8((unsigned char *)addr) 58 + 59 + /* parameter space */ 60 + 61 + /* write, read, set bits, clear bits */ 62 + #define W32(_p, _m, _v) __fcc_out32(&(_p)->_m, (_v)) 63 + #define R32(_p, _m) __fcc_in32(&(_p)->_m) 64 + #define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v)) 65 + #define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v)) 66 + 67 + #define W16(_p, _m, _v) __fcc_out16(&(_p)->_m, (_v)) 68 + #define R16(_p, _m) __fcc_in16(&(_p)->_m) 69 + #define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v)) 70 + #define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v)) 71 + 72 + #define W8(_p, _m, _v) __fcc_out8(&(_p)->_m, (_v)) 73 + #define R8(_p, _m) __fcc_in8(&(_p)->_m) 74 + #define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v)) 75 + #define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v)) 76 + 77 + /*************************************************/ 78 + 79 + #define FCC_MAX_MULTICAST_ADDRS 64 80 + 81 + #define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) 82 + #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) 83 + #define mk_mii_end 0 84 + 85 + #define MAX_CR_CMD_LOOPS 10000 86 + 87 + static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) 88 + { 89 + const struct fs_platform_info *fpi = fep->fpi; 90 + 91 + cpm2_map_t *immap = fs_enet_immap; 92 + cpm_cpm2_t *cpmp = &immap->im_cpm; 93 + u32 v; 94 + int i; 95 + 96 + /* Currently I don't know what feature call will look like. But 97 + I guess there'd be something like do_cpm_cmd() which will require page & sblock */ 98 + v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op); 99 + W32(cpmp, cp_cpcr, v | CPM_CR_FLG); 100 + for (i = 0; i < MAX_CR_CMD_LOOPS; i++) 101 + if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) 102 + break; 103 + 104 + if (i >= MAX_CR_CMD_LOOPS) { 105 + printk(KERN_ERR "%s(): Not able to issue CPM command\n", 106 + __FUNCTION__); 107 + return 1; 108 + } 109 + 110 + return 0; 111 + } 112 + 113 + static int do_pd_setup(struct fs_enet_private *fep) 114 + { 115 + struct platform_device *pdev = to_platform_device(fep->dev); 116 + struct resource *r; 117 + 118 + /* Fill out IRQ field */ 119 + fep->interrupt = platform_get_irq(pdev, 0); 120 + 121 + /* Attach the memory for the FCC Parameter RAM */ 122 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); 123 + fep->fcc.ep = (void *)r->start; 124 + 125 + if (fep->fcc.ep == NULL) 126 + return -EINVAL; 127 + 128 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs"); 129 + fep->fcc.fccp = (void *)r->start; 130 + 131 + if (fep->fcc.fccp == NULL) 132 + return -EINVAL; 133 + 134 + fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c; 135 + 136 + if (fep->fcc.fcccp == NULL) 137 + return -EINVAL; 138 + 139 + return 0; 140 + } 141 + 142 + #define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) 143 + #define FCC_RX_EVENT (FCC_ENET_RXF) 144 + #define FCC_TX_EVENT (FCC_ENET_TXB) 145 + #define FCC_ERR_EVENT_MSK (FCC_ENET_TXE | FCC_ENET_BSY) 146 + 147 + static int setup_data(struct net_device *dev) 148 + { 149 + struct fs_enet_private *fep = netdev_priv(dev); 150 + const struct fs_platform_info *fpi = fep->fpi; 151 + 152 + fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); 153 + if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ 154 + return -EINVAL; 155 + 156 + fep->fcc.mem = (void *)fpi->mem_offset; 157 + 158 + if (do_pd_setup(fep) != 0) 159 + return -EINVAL; 160 + 161 + fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK; 162 + fep->ev_rx = FCC_RX_EVENT; 163 + fep->ev_tx = FCC_TX_EVENT; 164 + fep->ev_err = FCC_ERR_EVENT_MSK; 165 + 166 + return 0; 167 + } 168 + 169 + static int allocate_bd(struct net_device *dev) 170 + { 171 + struct fs_enet_private *fep = netdev_priv(dev); 172 + const struct fs_platform_info *fpi = fep->fpi; 173 + 174 + fep->ring_base = dma_alloc_coherent(fep->dev, 175 + (fpi->tx_ring + fpi->rx_ring) * 176 + sizeof(cbd_t), &fep->ring_mem_addr, 177 + GFP_KERNEL); 178 + if (fep->ring_base == NULL) 179 + return -ENOMEM; 180 + 181 + return 0; 182 + } 183 + 184 + static void free_bd(struct net_device *dev) 185 + { 186 + struct fs_enet_private *fep = netdev_priv(dev); 187 + const struct fs_platform_info *fpi = fep->fpi; 188 + 189 + if (fep->ring_base) 190 + dma_free_coherent(fep->dev, 191 + (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), 192 + fep->ring_base, fep->ring_mem_addr); 193 + } 194 + 195 + static void cleanup_data(struct net_device *dev) 196 + { 197 + /* nothing */ 198 + } 199 + 200 + static void set_promiscuous_mode(struct net_device *dev) 201 + { 202 + struct fs_enet_private *fep = netdev_priv(dev); 203 + fcc_t *fccp = fep->fcc.fccp; 204 + 205 + S32(fccp, fcc_fpsmr, FCC_PSMR_PRO); 206 + } 207 + 208 + static void set_multicast_start(struct net_device *dev) 209 + { 210 + struct fs_enet_private *fep = netdev_priv(dev); 211 + fcc_enet_t *ep = fep->fcc.ep; 212 + 213 + W32(ep, fen_gaddrh, 0); 214 + W32(ep, fen_gaddrl, 0); 215 + } 216 + 217 + static void set_multicast_one(struct net_device *dev, const u8 *mac) 218 + { 219 + struct fs_enet_private *fep = netdev_priv(dev); 220 + fcc_enet_t *ep = fep->fcc.ep; 221 + u16 taddrh, taddrm, taddrl; 222 + 223 + taddrh = ((u16)mac[5] << 8) | mac[4]; 224 + taddrm = ((u16)mac[3] << 8) | mac[2]; 225 + taddrl = ((u16)mac[1] << 8) | mac[0]; 226 + 227 + W16(ep, fen_taddrh, taddrh); 228 + W16(ep, fen_taddrm, taddrm); 229 + W16(ep, fen_taddrl, taddrl); 230 + fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR); 231 + } 232 + 233 + static void set_multicast_finish(struct net_device *dev) 234 + { 235 + struct fs_enet_private *fep = netdev_priv(dev); 236 + fcc_t *fccp = fep->fcc.fccp; 237 + fcc_enet_t *ep = fep->fcc.ep; 238 + 239 + /* clear promiscuous always */ 240 + C32(fccp, fcc_fpsmr, FCC_PSMR_PRO); 241 + 242 + /* if all multi or too many multicasts; just enable all */ 243 + if ((dev->flags & IFF_ALLMULTI) != 0 || 244 + dev->mc_count > FCC_MAX_MULTICAST_ADDRS) { 245 + 246 + W32(ep, fen_gaddrh, 0xffffffff); 247 + W32(ep, fen_gaddrl, 0xffffffff); 248 + } 249 + 250 + /* read back */ 251 + fep->fcc.gaddrh = R32(ep, fen_gaddrh); 252 + fep->fcc.gaddrl = R32(ep, fen_gaddrl); 253 + } 254 + 255 + static void set_multicast_list(struct net_device *dev) 256 + { 257 + struct dev_mc_list *pmc; 258 + 259 + if ((dev->flags & IFF_PROMISC) == 0) { 260 + set_multicast_start(dev); 261 + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) 262 + set_multicast_one(dev, pmc->dmi_addr); 263 + set_multicast_finish(dev); 264 + } else 265 + set_promiscuous_mode(dev); 266 + } 267 + 268 + static void restart(struct net_device *dev) 269 + { 270 + struct fs_enet_private *fep = netdev_priv(dev); 271 + const struct fs_platform_info *fpi = fep->fpi; 272 + fcc_t *fccp = fep->fcc.fccp; 273 + fcc_c_t *fcccp = fep->fcc.fcccp; 274 + fcc_enet_t *ep = fep->fcc.ep; 275 + dma_addr_t rx_bd_base_phys, tx_bd_base_phys; 276 + u16 paddrh, paddrm, paddrl; 277 + u16 mem_addr; 278 + const unsigned char *mac; 279 + int i; 280 + 281 + C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); 282 + 283 + /* clear everything (slow & steady does it) */ 284 + for (i = 0; i < sizeof(*ep); i++) 285 + __fcc_out8((char *)ep + i, 0); 286 + 287 + /* get physical address */ 288 + rx_bd_base_phys = fep->ring_mem_addr; 289 + tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring; 290 + 291 + /* point to bds */ 292 + W32(ep, fen_genfcc.fcc_rbase, rx_bd_base_phys); 293 + W32(ep, fen_genfcc.fcc_tbase, tx_bd_base_phys); 294 + 295 + /* Set maximum bytes per receive buffer. 296 + * It must be a multiple of 32. 297 + */ 298 + W16(ep, fen_genfcc.fcc_mrblr, PKT_MAXBLR_SIZE); 299 + 300 + W32(ep, fen_genfcc.fcc_rstate, (CPMFCR_GBL | CPMFCR_EB) << 24); 301 + W32(ep, fen_genfcc.fcc_tstate, (CPMFCR_GBL | CPMFCR_EB) << 24); 302 + 303 + /* Allocate space in the reserved FCC area of DPRAM for the 304 + * internal buffers. No one uses this space (yet), so we 305 + * can do this. Later, we will add resource management for 306 + * this area. 307 + */ 308 + 309 + mem_addr = (u32) fep->fcc.mem; /* de-fixup dpram offset */ 310 + 311 + W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff)); 312 + W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff)); 313 + W16(ep, fen_padptr, mem_addr + 64); 314 + 315 + /* fill with special symbol... */ 316 + memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32); 317 + 318 + W32(ep, fen_genfcc.fcc_rbptr, 0); 319 + W32(ep, fen_genfcc.fcc_tbptr, 0); 320 + W32(ep, fen_genfcc.fcc_rcrc, 0); 321 + W32(ep, fen_genfcc.fcc_tcrc, 0); 322 + W16(ep, fen_genfcc.fcc_res1, 0); 323 + W32(ep, fen_genfcc.fcc_res2, 0); 324 + 325 + /* no CAM */ 326 + W32(ep, fen_camptr, 0); 327 + 328 + /* Set CRC preset and mask */ 329 + W32(ep, fen_cmask, 0xdebb20e3); 330 + W32(ep, fen_cpres, 0xffffffff); 331 + 332 + W32(ep, fen_crcec, 0); /* CRC Error counter */ 333 + W32(ep, fen_alec, 0); /* alignment error counter */ 334 + W32(ep, fen_disfc, 0); /* discard frame counter */ 335 + W16(ep, fen_retlim, 15); /* Retry limit threshold */ 336 + W16(ep, fen_pper, 0); /* Normal persistence */ 337 + 338 + /* set group address */ 339 + W32(ep, fen_gaddrh, fep->fcc.gaddrh); 340 + W32(ep, fen_gaddrl, fep->fcc.gaddrh); 341 + 342 + /* Clear hash filter tables */ 343 + W32(ep, fen_iaddrh, 0); 344 + W32(ep, fen_iaddrl, 0); 345 + 346 + /* Clear the Out-of-sequence TxBD */ 347 + W16(ep, fen_tfcstat, 0); 348 + W16(ep, fen_tfclen, 0); 349 + W32(ep, fen_tfcptr, 0); 350 + 351 + W16(ep, fen_mflr, PKT_MAXBUF_SIZE); /* maximum frame length register */ 352 + W16(ep, fen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */ 353 + 354 + /* set address */ 355 + mac = dev->dev_addr; 356 + paddrh = ((u16)mac[5] << 8) | mac[4]; 357 + paddrm = ((u16)mac[3] << 8) | mac[2]; 358 + paddrl = ((u16)mac[1] << 8) | mac[0]; 359 + 360 + W16(ep, fen_paddrh, paddrh); 361 + W16(ep, fen_paddrm, paddrm); 362 + W16(ep, fen_paddrl, paddrl); 363 + 364 + W16(ep, fen_taddrh, 0); 365 + W16(ep, fen_taddrm, 0); 366 + W16(ep, fen_taddrl, 0); 367 + 368 + W16(ep, fen_maxd1, 1520); /* maximum DMA1 length */ 369 + W16(ep, fen_maxd2, 1520); /* maximum DMA2 length */ 370 + 371 + /* Clear stat counters, in case we ever enable RMON */ 372 + W32(ep, fen_octc, 0); 373 + W32(ep, fen_colc, 0); 374 + W32(ep, fen_broc, 0); 375 + W32(ep, fen_mulc, 0); 376 + W32(ep, fen_uspc, 0); 377 + W32(ep, fen_frgc, 0); 378 + W32(ep, fen_ospc, 0); 379 + W32(ep, fen_jbrc, 0); 380 + W32(ep, fen_p64c, 0); 381 + W32(ep, fen_p65c, 0); 382 + W32(ep, fen_p128c, 0); 383 + W32(ep, fen_p256c, 0); 384 + W32(ep, fen_p512c, 0); 385 + W32(ep, fen_p1024c, 0); 386 + 387 + W16(ep, fen_rfthr, 0); /* Suggested by manual */ 388 + W16(ep, fen_rfcnt, 0); 389 + W16(ep, fen_cftype, 0); 390 + 391 + fs_init_bds(dev); 392 + 393 + /* adjust to speed (for RMII mode) */ 394 + if (fpi->use_rmii) { 395 + if (fep->speed == 100) 396 + C8(fcccp, fcc_gfemr, 0x20); 397 + else 398 + S8(fcccp, fcc_gfemr, 0x20); 399 + } 400 + 401 + fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX); 402 + 403 + /* clear events */ 404 + W16(fccp, fcc_fcce, 0xffff); 405 + 406 + /* Enable interrupts we wish to service */ 407 + W16(fccp, fcc_fccm, FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB); 408 + 409 + /* Set GFMR to enable Ethernet operating mode */ 410 + W32(fccp, fcc_gfmr, FCC_GFMR_TCI | FCC_GFMR_MODE_ENET); 411 + 412 + /* set sync/delimiters */ 413 + W16(fccp, fcc_fdsr, 0xd555); 414 + 415 + W32(fccp, fcc_fpsmr, FCC_PSMR_ENCRC); 416 + 417 + if (fpi->use_rmii) 418 + S32(fccp, fcc_fpsmr, FCC_PSMR_RMII); 419 + 420 + /* adjust to duplex mode */ 421 + if (fep->duplex) 422 + S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); 423 + else 424 + C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); 425 + 426 + S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); 427 + } 428 + 429 + static void stop(struct net_device *dev) 430 + { 431 + struct fs_enet_private *fep = netdev_priv(dev); 432 + fcc_t *fccp = fep->fcc.fccp; 433 + 434 + /* stop ethernet */ 435 + C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); 436 + 437 + /* clear events */ 438 + W16(fccp, fcc_fcce, 0xffff); 439 + 440 + /* clear interrupt mask */ 441 + W16(fccp, fcc_fccm, 0); 442 + 443 + fs_cleanup_bds(dev); 444 + } 445 + 446 + static void pre_request_irq(struct net_device *dev, int irq) 447 + { 448 + /* nothing */ 449 + } 450 + 451 + static void post_free_irq(struct net_device *dev, int irq) 452 + { 453 + /* nothing */ 454 + } 455 + 456 + static void napi_clear_rx_event(struct net_device *dev) 457 + { 458 + struct fs_enet_private *fep = netdev_priv(dev); 459 + fcc_t *fccp = fep->fcc.fccp; 460 + 461 + W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK); 462 + } 463 + 464 + static void napi_enable_rx(struct net_device *dev) 465 + { 466 + struct fs_enet_private *fep = netdev_priv(dev); 467 + fcc_t *fccp = fep->fcc.fccp; 468 + 469 + S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK); 470 + } 471 + 472 + static void napi_disable_rx(struct net_device *dev) 473 + { 474 + struct fs_enet_private *fep = netdev_priv(dev); 475 + fcc_t *fccp = fep->fcc.fccp; 476 + 477 + C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK); 478 + } 479 + 480 + static void rx_bd_done(struct net_device *dev) 481 + { 482 + /* nothing */ 483 + } 484 + 485 + static void tx_kickstart(struct net_device *dev) 486 + { 487 + /* nothing */ 488 + } 489 + 490 + static u32 get_int_events(struct net_device *dev) 491 + { 492 + struct fs_enet_private *fep = netdev_priv(dev); 493 + fcc_t *fccp = fep->fcc.fccp; 494 + 495 + return (u32)R16(fccp, fcc_fcce); 496 + } 497 + 498 + static void clear_int_events(struct net_device *dev, u32 int_events) 499 + { 500 + struct fs_enet_private *fep = netdev_priv(dev); 501 + fcc_t *fccp = fep->fcc.fccp; 502 + 503 + W16(fccp, fcc_fcce, int_events & 0xffff); 504 + } 505 + 506 + static void ev_error(struct net_device *dev, u32 int_events) 507 + { 508 + printk(KERN_WARNING DRV_MODULE_NAME 509 + ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events); 510 + } 511 + 512 + int get_regs(struct net_device *dev, void *p, int *sizep) 513 + { 514 + struct fs_enet_private *fep = netdev_priv(dev); 515 + 516 + if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t)) 517 + return -EINVAL; 518 + 519 + memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); 520 + p = (char *)p + sizeof(fcc_t); 521 + 522 + memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t)); 523 + p = (char *)p + sizeof(fcc_c_t); 524 + 525 + memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); 526 + 527 + return 0; 528 + } 529 + 530 + int get_regs_len(struct net_device *dev) 531 + { 532 + return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t); 533 + } 534 + 535 + /* Some transmit errors cause the transmitter to shut 536 + * down. We now issue a restart transmit. Since the 537 + * errors close the BD and update the pointers, the restart 538 + * _should_ pick up without having to reset any of our 539 + * pointers either. Also, To workaround 8260 device erratum 540 + * CPM37, we must disable and then re-enable the transmitter 541 + * following a Late Collision, Underrun, or Retry Limit error. 542 + */ 543 + void tx_restart(struct net_device *dev) 544 + { 545 + struct fs_enet_private *fep = netdev_priv(dev); 546 + fcc_t *fccp = fep->fcc.fccp; 547 + 548 + C32(fccp, fcc_gfmr, FCC_GFMR_ENT); 549 + udelay(10); 550 + S32(fccp, fcc_gfmr, FCC_GFMR_ENT); 551 + 552 + fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX); 553 + } 554 + 555 + /*************************************************************************/ 556 + 557 + const struct fs_ops fs_fcc_ops = { 558 + .setup_data = setup_data, 559 + .cleanup_data = cleanup_data, 560 + .set_multicast_list = set_multicast_list, 561 + .restart = restart, 562 + .stop = stop, 563 + .pre_request_irq = pre_request_irq, 564 + .post_free_irq = post_free_irq, 565 + .napi_clear_rx_event = napi_clear_rx_event, 566 + .napi_enable_rx = napi_enable_rx, 567 + .napi_disable_rx = napi_disable_rx, 568 + .rx_bd_done = rx_bd_done, 569 + .tx_kickstart = tx_kickstart, 570 + .get_int_events = get_int_events, 571 + .clear_int_events = clear_int_events, 572 + .ev_error = ev_error, 573 + .get_regs = get_regs, 574 + .get_regs_len = get_regs_len, 575 + .tx_restart = tx_restart, 576 + .allocate_bd = allocate_bd, 577 + .free_bd = free_bd, 578 + };
+653
drivers/net/fs_enet/mac-fec.c
··· 1 + /* 2 + * Freescale Ethernet controllers 3 + * 4 + * Copyright (c) 2005 Intracom S.A. 5 + * by Pantelis Antoniou <panto@intracom.gr> 6 + * 7 + * 2005 (c) MontaVista Software, Inc. 8 + * Vitaly Bordug <vbordug@ru.mvista.com> 9 + * 10 + * This file is licensed under the terms of the GNU General Public License 11 + * version 2. This program is licensed "as is" without any warranty of any 12 + * kind, whether express or implied. 13 + */ 14 + 15 + #include <linux/config.h> 16 + #include <linux/module.h> 17 + #include <linux/kernel.h> 18 + #include <linux/types.h> 19 + #include <linux/sched.h> 20 + #include <linux/string.h> 21 + #include <linux/ptrace.h> 22 + #include <linux/errno.h> 23 + #include <linux/ioport.h> 24 + #include <linux/slab.h> 25 + #include <linux/interrupt.h> 26 + #include <linux/pci.h> 27 + #include <linux/init.h> 28 + #include <linux/delay.h> 29 + #include <linux/netdevice.h> 30 + #include <linux/etherdevice.h> 31 + #include <linux/skbuff.h> 32 + #include <linux/spinlock.h> 33 + #include <linux/mii.h> 34 + #include <linux/ethtool.h> 35 + #include <linux/bitops.h> 36 + #include <linux/fs.h> 37 + 38 + #include <asm/irq.h> 39 + #include <asm/uaccess.h> 40 + 41 + #ifdef CONFIG_8xx 42 + #include <asm/8xx_immap.h> 43 + #include <asm/pgtable.h> 44 + #include <asm/mpc8xx.h> 45 + #include <asm/commproc.h> 46 + #endif 47 + 48 + #include "fs_enet.h" 49 + 50 + /*************************************************/ 51 + 52 + #if defined(CONFIG_CPM1) 53 + /* for a CPM1 __raw_xxx's are sufficient */ 54 + #define __fs_out32(addr, x) __raw_writel(x, addr) 55 + #define __fs_out16(addr, x) __raw_writew(x, addr) 56 + #define __fs_in32(addr) __raw_readl(addr) 57 + #define __fs_in16(addr) __raw_readw(addr) 58 + #else 59 + /* for others play it safe */ 60 + #define __fs_out32(addr, x) out_be32(addr, x) 61 + #define __fs_out16(addr, x) out_be16(addr, x) 62 + #define __fs_in32(addr) in_be32(addr) 63 + #define __fs_in16(addr) in_be16(addr) 64 + #endif 65 + 66 + /* write */ 67 + #define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v)) 68 + 69 + /* read */ 70 + #define FR(_fecp, _reg) __fs_in32(&(_fecp)->fec_ ## _reg) 71 + 72 + /* set bits */ 73 + #define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v)) 74 + 75 + /* clear bits */ 76 + #define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) 77 + 78 + 79 + /* CRC polynomium used by the FEC for the multicast group filtering */ 80 + #define FEC_CRC_POLY 0x04C11DB7 81 + 82 + #define FEC_MAX_MULTICAST_ADDRS 64 83 + 84 + /* Interrupt events/masks. 85 + */ 86 + #define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ 87 + #define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ 88 + #define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ 89 + #define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ 90 + #define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ 91 + #define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ 92 + #define FEC_ENET_RXF 0x02000000U /* Full frame received */ 93 + #define FEC_ENET_RXB 0x01000000U /* A buffer was received */ 94 + #define FEC_ENET_MII 0x00800000U /* MII interrupt */ 95 + #define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ 96 + 97 + #define FEC_ECNTRL_PINMUX 0x00000004 98 + #define FEC_ECNTRL_ETHER_EN 0x00000002 99 + #define FEC_ECNTRL_RESET 0x00000001 100 + 101 + #define FEC_RCNTRL_BC_REJ 0x00000010 102 + #define FEC_RCNTRL_PROM 0x00000008 103 + #define FEC_RCNTRL_MII_MODE 0x00000004 104 + #define FEC_RCNTRL_DRT 0x00000002 105 + #define FEC_RCNTRL_LOOP 0x00000001 106 + 107 + #define FEC_TCNTRL_FDEN 0x00000004 108 + #define FEC_TCNTRL_HBC 0x00000002 109 + #define FEC_TCNTRL_GTS 0x00000001 110 + 111 + 112 + /* Make MII read/write commands for the FEC. 113 + */ 114 + #define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) 115 + #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) 116 + #define mk_mii_end 0 117 + 118 + #define FEC_MII_LOOPS 10000 119 + 120 + /* 121 + * Delay to wait for FEC reset command to complete (in us) 122 + */ 123 + #define FEC_RESET_DELAY 50 124 + 125 + static int whack_reset(fec_t * fecp) 126 + { 127 + int i; 128 + 129 + FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET); 130 + for (i = 0; i < FEC_RESET_DELAY; i++) { 131 + if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0) 132 + return 0; /* OK */ 133 + udelay(1); 134 + } 135 + 136 + return -1; 137 + } 138 + 139 + static int do_pd_setup(struct fs_enet_private *fep) 140 + { 141 + struct platform_device *pdev = to_platform_device(fep->dev); 142 + struct resource *r; 143 + 144 + /* Fill out IRQ field */ 145 + fep->interrupt = platform_get_irq_byname(pdev,"interrupt"); 146 + 147 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 148 + fep->fec.fecp =(void*)r->start; 149 + 150 + if(fep->fec.fecp == NULL) 151 + return -EINVAL; 152 + 153 + return 0; 154 + 155 + } 156 + 157 + #define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB) 158 + #define FEC_RX_EVENT (FEC_ENET_RXF) 159 + #define FEC_TX_EVENT (FEC_ENET_TXF) 160 + #define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \ 161 + FEC_ENET_BABT | FEC_ENET_EBERR) 162 + 163 + static int setup_data(struct net_device *dev) 164 + { 165 + struct fs_enet_private *fep = netdev_priv(dev); 166 + 167 + if (do_pd_setup(fep) != 0) 168 + return -EINVAL; 169 + 170 + fep->fec.hthi = 0; 171 + fep->fec.htlo = 0; 172 + 173 + fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK; 174 + fep->ev_rx = FEC_RX_EVENT; 175 + fep->ev_tx = FEC_TX_EVENT; 176 + fep->ev_err = FEC_ERR_EVENT_MSK; 177 + 178 + return 0; 179 + } 180 + 181 + static int allocate_bd(struct net_device *dev) 182 + { 183 + struct fs_enet_private *fep = netdev_priv(dev); 184 + const struct fs_platform_info *fpi = fep->fpi; 185 + 186 + fep->ring_base = dma_alloc_coherent(fep->dev, 187 + (fpi->tx_ring + fpi->rx_ring) * 188 + sizeof(cbd_t), &fep->ring_mem_addr, 189 + GFP_KERNEL); 190 + if (fep->ring_base == NULL) 191 + return -ENOMEM; 192 + 193 + return 0; 194 + } 195 + 196 + static void free_bd(struct net_device *dev) 197 + { 198 + struct fs_enet_private *fep = netdev_priv(dev); 199 + const struct fs_platform_info *fpi = fep->fpi; 200 + 201 + if(fep->ring_base) 202 + dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) 203 + * sizeof(cbd_t), 204 + fep->ring_base, 205 + fep->ring_mem_addr); 206 + } 207 + 208 + static void cleanup_data(struct net_device *dev) 209 + { 210 + /* nothing */ 211 + } 212 + 213 + static void set_promiscuous_mode(struct net_device *dev) 214 + { 215 + struct fs_enet_private *fep = netdev_priv(dev); 216 + fec_t *fecp = fep->fec.fecp; 217 + 218 + FS(fecp, r_cntrl, FEC_RCNTRL_PROM); 219 + } 220 + 221 + static void set_multicast_start(struct net_device *dev) 222 + { 223 + struct fs_enet_private *fep = netdev_priv(dev); 224 + 225 + fep->fec.hthi = 0; 226 + fep->fec.htlo = 0; 227 + } 228 + 229 + static void set_multicast_one(struct net_device *dev, const u8 *mac) 230 + { 231 + struct fs_enet_private *fep = netdev_priv(dev); 232 + int temp, hash_index, i, j; 233 + u32 crc, csrVal; 234 + u8 byte, msb; 235 + 236 + crc = 0xffffffff; 237 + for (i = 0; i < 6; i++) { 238 + byte = mac[i]; 239 + for (j = 0; j < 8; j++) { 240 + msb = crc >> 31; 241 + crc <<= 1; 242 + if (msb ^ (byte & 0x1)) 243 + crc ^= FEC_CRC_POLY; 244 + byte >>= 1; 245 + } 246 + } 247 + 248 + temp = (crc & 0x3f) >> 1; 249 + hash_index = ((temp & 0x01) << 4) | 250 + ((temp & 0x02) << 2) | 251 + ((temp & 0x04)) | 252 + ((temp & 0x08) >> 2) | 253 + ((temp & 0x10) >> 4); 254 + csrVal = 1 << hash_index; 255 + if (crc & 1) 256 + fep->fec.hthi |= csrVal; 257 + else 258 + fep->fec.htlo |= csrVal; 259 + } 260 + 261 + static void set_multicast_finish(struct net_device *dev) 262 + { 263 + struct fs_enet_private *fep = netdev_priv(dev); 264 + fec_t *fecp = fep->fec.fecp; 265 + 266 + /* if all multi or too many multicasts; just enable all */ 267 + if ((dev->flags & IFF_ALLMULTI) != 0 || 268 + dev->mc_count > FEC_MAX_MULTICAST_ADDRS) { 269 + fep->fec.hthi = 0xffffffffU; 270 + fep->fec.htlo = 0xffffffffU; 271 + } 272 + 273 + FC(fecp, r_cntrl, FEC_RCNTRL_PROM); 274 + FW(fecp, hash_table_high, fep->fec.hthi); 275 + FW(fecp, hash_table_low, fep->fec.htlo); 276 + } 277 + 278 + static void set_multicast_list(struct net_device *dev) 279 + { 280 + struct dev_mc_list *pmc; 281 + 282 + if ((dev->flags & IFF_PROMISC) == 0) { 283 + set_multicast_start(dev); 284 + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) 285 + set_multicast_one(dev, pmc->dmi_addr); 286 + set_multicast_finish(dev); 287 + } else 288 + set_promiscuous_mode(dev); 289 + } 290 + 291 + static void restart(struct net_device *dev) 292 + { 293 + #ifdef CONFIG_DUET 294 + immap_t *immap = fs_enet_immap; 295 + u32 cptr; 296 + #endif 297 + struct fs_enet_private *fep = netdev_priv(dev); 298 + fec_t *fecp = fep->fec.fecp; 299 + const struct fs_platform_info *fpi = fep->fpi; 300 + dma_addr_t rx_bd_base_phys, tx_bd_base_phys; 301 + int r; 302 + u32 addrhi, addrlo; 303 + 304 + r = whack_reset(fep->fec.fecp); 305 + if (r != 0) 306 + printk(KERN_ERR DRV_MODULE_NAME 307 + ": %s FEC Reset FAILED!\n", dev->name); 308 + 309 + /* 310 + * Set station address. 311 + */ 312 + addrhi = ((u32) dev->dev_addr[0] << 24) | 313 + ((u32) dev->dev_addr[1] << 16) | 314 + ((u32) dev->dev_addr[2] << 8) | 315 + (u32) dev->dev_addr[3]; 316 + addrlo = ((u32) dev->dev_addr[4] << 24) | 317 + ((u32) dev->dev_addr[5] << 16); 318 + FW(fecp, addr_low, addrhi); 319 + FW(fecp, addr_high, addrlo); 320 + 321 + /* 322 + * Reset all multicast. 323 + */ 324 + FW(fecp, hash_table_high, fep->fec.hthi); 325 + FW(fecp, hash_table_low, fep->fec.htlo); 326 + 327 + /* 328 + * Set maximum receive buffer size. 329 + */ 330 + FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); 331 + FW(fecp, r_hash, PKT_MAXBUF_SIZE); 332 + 333 + /* get physical address */ 334 + rx_bd_base_phys = fep->ring_mem_addr; 335 + tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring; 336 + 337 + /* 338 + * Set receive and transmit descriptor base. 339 + */ 340 + FW(fecp, r_des_start, rx_bd_base_phys); 341 + FW(fecp, x_des_start, tx_bd_base_phys); 342 + 343 + fs_init_bds(dev); 344 + 345 + /* 346 + * Enable big endian and don't care about SDMA FC. 347 + */ 348 + FW(fecp, fun_code, 0x78000000); 349 + 350 + /* 351 + * Set MII speed. 352 + */ 353 + FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed); 354 + 355 + /* 356 + * Clear any outstanding interrupt. 357 + */ 358 + FW(fecp, ievent, 0xffc0); 359 + FW(fecp, ivec, (fep->interrupt / 2) << 29); 360 + 361 + 362 + /* 363 + * adjust to speed (only for DUET & RMII) 364 + */ 365 + #ifdef CONFIG_DUET 366 + if (fpi->use_rmii) { 367 + cptr = in_be32(&immap->im_cpm.cp_cptr); 368 + switch (fs_get_fec_index(fpi->fs_no)) { 369 + case 0: 370 + cptr |= 0x100; 371 + if (fep->speed == 10) 372 + cptr |= 0x0000010; 373 + else if (fep->speed == 100) 374 + cptr &= ~0x0000010; 375 + break; 376 + case 1: 377 + cptr |= 0x80; 378 + if (fep->speed == 10) 379 + cptr |= 0x0000008; 380 + else if (fep->speed == 100) 381 + cptr &= ~0x0000008; 382 + break; 383 + default: 384 + BUG(); /* should never happen */ 385 + break; 386 + } 387 + out_be32(&immap->im_cpm.cp_cptr, cptr); 388 + } 389 + #endif 390 + 391 + FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 392 + /* 393 + * adjust to duplex mode 394 + */ 395 + if (fep->duplex) { 396 + FC(fecp, r_cntrl, FEC_RCNTRL_DRT); 397 + FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ 398 + } else { 399 + FS(fecp, r_cntrl, FEC_RCNTRL_DRT); 400 + FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ 401 + } 402 + 403 + /* 404 + * Enable interrupts we wish to service. 405 + */ 406 + FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB | 407 + FEC_ENET_RXF | FEC_ENET_RXB); 408 + 409 + /* 410 + * And last, enable the transmit and receive processing. 411 + */ 412 + FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); 413 + FW(fecp, r_des_active, 0x01000000); 414 + } 415 + 416 + static void stop(struct net_device *dev) 417 + { 418 + struct fs_enet_private *fep = netdev_priv(dev); 419 + fec_t *fecp = fep->fec.fecp; 420 + struct fs_enet_mii_bus *bus = fep->mii_bus; 421 + const struct fs_mii_bus_info *bi = bus->bus_info; 422 + int i; 423 + 424 + if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) 425 + return; /* already down */ 426 + 427 + FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */ 428 + for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) && 429 + i < FEC_RESET_DELAY; i++) 430 + udelay(1); 431 + 432 + if (i == FEC_RESET_DELAY) 433 + printk(KERN_WARNING DRV_MODULE_NAME 434 + ": %s FEC timeout on graceful transmit stop\n", 435 + dev->name); 436 + /* 437 + * Disable FEC. Let only MII interrupts. 438 + */ 439 + FW(fecp, imask, 0); 440 + FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN); 441 + 442 + fs_cleanup_bds(dev); 443 + 444 + /* shut down FEC1? that's where the mii bus is */ 445 + if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) { 446 + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 447 + FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); 448 + FW(fecp, ievent, FEC_ENET_MII); 449 + FW(fecp, mii_speed, bus->fec.mii_speed); 450 + } 451 + } 452 + 453 + static void pre_request_irq(struct net_device *dev, int irq) 454 + { 455 + immap_t *immap = fs_enet_immap; 456 + u32 siel; 457 + 458 + /* SIU interrupt */ 459 + if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { 460 + 461 + siel = in_be32(&immap->im_siu_conf.sc_siel); 462 + if ((irq & 1) == 0) 463 + siel |= (0x80000000 >> irq); 464 + else 465 + siel &= ~(0x80000000 >> (irq & ~1)); 466 + out_be32(&immap->im_siu_conf.sc_siel, siel); 467 + } 468 + } 469 + 470 + static void post_free_irq(struct net_device *dev, int irq) 471 + { 472 + /* nothing */ 473 + } 474 + 475 + static void napi_clear_rx_event(struct net_device *dev) 476 + { 477 + struct fs_enet_private *fep = netdev_priv(dev); 478 + fec_t *fecp = fep->fec.fecp; 479 + 480 + FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK); 481 + } 482 + 483 + static void napi_enable_rx(struct net_device *dev) 484 + { 485 + struct fs_enet_private *fep = netdev_priv(dev); 486 + fec_t *fecp = fep->fec.fecp; 487 + 488 + FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 489 + } 490 + 491 + static void napi_disable_rx(struct net_device *dev) 492 + { 493 + struct fs_enet_private *fep = netdev_priv(dev); 494 + fec_t *fecp = fep->fec.fecp; 495 + 496 + FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 497 + } 498 + 499 + static void rx_bd_done(struct net_device *dev) 500 + { 501 + struct fs_enet_private *fep = netdev_priv(dev); 502 + fec_t *fecp = fep->fec.fecp; 503 + 504 + FW(fecp, r_des_active, 0x01000000); 505 + } 506 + 507 + static void tx_kickstart(struct net_device *dev) 508 + { 509 + struct fs_enet_private *fep = netdev_priv(dev); 510 + fec_t *fecp = fep->fec.fecp; 511 + 512 + FW(fecp, x_des_active, 0x01000000); 513 + } 514 + 515 + static u32 get_int_events(struct net_device *dev) 516 + { 517 + struct fs_enet_private *fep = netdev_priv(dev); 518 + fec_t *fecp = fep->fec.fecp; 519 + 520 + return FR(fecp, ievent) & FR(fecp, imask); 521 + } 522 + 523 + static void clear_int_events(struct net_device *dev, u32 int_events) 524 + { 525 + struct fs_enet_private *fep = netdev_priv(dev); 526 + fec_t *fecp = fep->fec.fecp; 527 + 528 + FW(fecp, ievent, int_events); 529 + } 530 + 531 + static void ev_error(struct net_device *dev, u32 int_events) 532 + { 533 + printk(KERN_WARNING DRV_MODULE_NAME 534 + ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events); 535 + } 536 + 537 + int get_regs(struct net_device *dev, void *p, int *sizep) 538 + { 539 + struct fs_enet_private *fep = netdev_priv(dev); 540 + 541 + if (*sizep < sizeof(fec_t)) 542 + return -EINVAL; 543 + 544 + memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t)); 545 + 546 + return 0; 547 + } 548 + 549 + int get_regs_len(struct net_device *dev) 550 + { 551 + return sizeof(fec_t); 552 + } 553 + 554 + void tx_restart(struct net_device *dev) 555 + { 556 + /* nothing */ 557 + } 558 + 559 + /*************************************************************************/ 560 + 561 + const struct fs_ops fs_fec_ops = { 562 + .setup_data = setup_data, 563 + .cleanup_data = cleanup_data, 564 + .set_multicast_list = set_multicast_list, 565 + .restart = restart, 566 + .stop = stop, 567 + .pre_request_irq = pre_request_irq, 568 + .post_free_irq = post_free_irq, 569 + .napi_clear_rx_event = napi_clear_rx_event, 570 + .napi_enable_rx = napi_enable_rx, 571 + .napi_disable_rx = napi_disable_rx, 572 + .rx_bd_done = rx_bd_done, 573 + .tx_kickstart = tx_kickstart, 574 + .get_int_events = get_int_events, 575 + .clear_int_events = clear_int_events, 576 + .ev_error = ev_error, 577 + .get_regs = get_regs, 578 + .get_regs_len = get_regs_len, 579 + .tx_restart = tx_restart, 580 + .allocate_bd = allocate_bd, 581 + .free_bd = free_bd, 582 + }; 583 + 584 + /***********************************************************************/ 585 + 586 + static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) 587 + { 588 + fec_t *fecp = bus->fec.fecp; 589 + int i, ret = -1; 590 + 591 + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) 592 + BUG(); 593 + 594 + /* Add PHY address to register command. */ 595 + FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location)); 596 + 597 + for (i = 0; i < FEC_MII_LOOPS; i++) 598 + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) 599 + break; 600 + 601 + if (i < FEC_MII_LOOPS) { 602 + FW(fecp, ievent, FEC_ENET_MII); 603 + ret = FR(fecp, mii_data) & 0xffff; 604 + } 605 + 606 + return ret; 607 + } 608 + 609 + static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value) 610 + { 611 + fec_t *fecp = bus->fec.fecp; 612 + int i; 613 + 614 + /* this must never happen */ 615 + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) 616 + BUG(); 617 + 618 + /* Add PHY address to register command. */ 619 + FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value)); 620 + 621 + for (i = 0; i < FEC_MII_LOOPS; i++) 622 + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) 623 + break; 624 + 625 + if (i < FEC_MII_LOOPS) 626 + FW(fecp, ievent, FEC_ENET_MII); 627 + } 628 + 629 + int fs_mii_fec_init(struct fs_enet_mii_bus *bus) 630 + { 631 + bd_t *bd = (bd_t *)__res; 632 + const struct fs_mii_bus_info *bi = bus->bus_info; 633 + fec_t *fecp; 634 + 635 + if (bi->id != 0) 636 + return -1; 637 + 638 + bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec; 639 + bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) 640 + & 0x3F) << 1; 641 + 642 + fecp = bus->fec.fecp; 643 + 644 + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 645 + FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); 646 + FW(fecp, ievent, FEC_ENET_MII); 647 + FW(fecp, mii_speed, bus->fec.mii_speed); 648 + 649 + bus->mii_read = mii_read; 650 + bus->mii_write = mii_write; 651 + 652 + return 0; 653 + }
+524
drivers/net/fs_enet/mac-scc.c
··· 1 + /* 2 + * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx. 3 + * 4 + * Copyright (c) 2003 Intracom S.A. 5 + * by Pantelis Antoniou <panto@intracom.gr> 6 + * 7 + * 2005 (c) MontaVista Software, Inc. 8 + * Vitaly Bordug <vbordug@ru.mvista.com> 9 + * 10 + * This file is licensed under the terms of the GNU General Public License 11 + * version 2. This program is licensed "as is" without any warranty of any 12 + * kind, whether express or implied. 13 + */ 14 + 15 + #include <linux/config.h> 16 + #include <linux/module.h> 17 + #include <linux/kernel.h> 18 + #include <linux/types.h> 19 + #include <linux/sched.h> 20 + #include <linux/string.h> 21 + #include <linux/ptrace.h> 22 + #include <linux/errno.h> 23 + #include <linux/ioport.h> 24 + #include <linux/slab.h> 25 + #include <linux/interrupt.h> 26 + #include <linux/pci.h> 27 + #include <linux/init.h> 28 + #include <linux/delay.h> 29 + #include <linux/netdevice.h> 30 + #include <linux/etherdevice.h> 31 + #include <linux/skbuff.h> 32 + #include <linux/spinlock.h> 33 + #include <linux/mii.h> 34 + #include <linux/ethtool.h> 35 + #include <linux/bitops.h> 36 + #include <linux/fs.h> 37 + 38 + #include <asm/irq.h> 39 + #include <asm/uaccess.h> 40 + 41 + #ifdef CONFIG_8xx 42 + #include <asm/8xx_immap.h> 43 + #include <asm/pgtable.h> 44 + #include <asm/mpc8xx.h> 45 + #include <asm/commproc.h> 46 + #endif 47 + 48 + #include "fs_enet.h" 49 + 50 + /*************************************************/ 51 + 52 + #if defined(CONFIG_CPM1) 53 + /* for a 8xx __raw_xxx's are sufficient */ 54 + #define __fs_out32(addr, x) __raw_writel(x, addr) 55 + #define __fs_out16(addr, x) __raw_writew(x, addr) 56 + #define __fs_out8(addr, x) __raw_writeb(x, addr) 57 + #define __fs_in32(addr) __raw_readl(addr) 58 + #define __fs_in16(addr) __raw_readw(addr) 59 + #define __fs_in8(addr) __raw_readb(addr) 60 + #else 61 + /* for others play it safe */ 62 + #define __fs_out32(addr, x) out_be32(addr, x) 63 + #define __fs_out16(addr, x) out_be16(addr, x) 64 + #define __fs_in32(addr) in_be32(addr) 65 + #define __fs_in16(addr) in_be16(addr) 66 + #endif 67 + 68 + /* write, read, set bits, clear bits */ 69 + #define W32(_p, _m, _v) __fs_out32(&(_p)->_m, (_v)) 70 + #define R32(_p, _m) __fs_in32(&(_p)->_m) 71 + #define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v)) 72 + #define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v)) 73 + 74 + #define W16(_p, _m, _v) __fs_out16(&(_p)->_m, (_v)) 75 + #define R16(_p, _m) __fs_in16(&(_p)->_m) 76 + #define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v)) 77 + #define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v)) 78 + 79 + #define W8(_p, _m, _v) __fs_out8(&(_p)->_m, (_v)) 80 + #define R8(_p, _m) __fs_in8(&(_p)->_m) 81 + #define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v)) 82 + #define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v)) 83 + 84 + #define SCC_MAX_MULTICAST_ADDRS 64 85 + 86 + /* 87 + * Delay to wait for SCC reset command to complete (in us) 88 + */ 89 + #define SCC_RESET_DELAY 50 90 + #define MAX_CR_CMD_LOOPS 10000 91 + 92 + static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) 93 + { 94 + cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm; 95 + u32 v, ch; 96 + int i = 0; 97 + 98 + ch = fep->scc.idx << 2; 99 + v = mk_cr_cmd(ch, op); 100 + W16(cpmp, cp_cpcr, v | CPM_CR_FLG); 101 + for (i = 0; i < MAX_CR_CMD_LOOPS; i++) 102 + if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) 103 + break; 104 + 105 + if (i >= MAX_CR_CMD_LOOPS) { 106 + printk(KERN_ERR "%s(): Not able to issue CPM command\n", 107 + __FUNCTION__); 108 + return 1; 109 + } 110 + return 0; 111 + } 112 + 113 + static int do_pd_setup(struct fs_enet_private *fep) 114 + { 115 + struct platform_device *pdev = to_platform_device(fep->dev); 116 + struct resource *r; 117 + 118 + /* Fill out IRQ field */ 119 + fep->interrupt = platform_get_irq_byname(pdev, "interrupt"); 120 + 121 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 122 + fep->scc.sccp = (void *)r->start; 123 + 124 + if (fep->scc.sccp == NULL) 125 + return -EINVAL; 126 + 127 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"); 128 + fep->scc.ep = (void *)r->start; 129 + 130 + if (fep->scc.ep == NULL) 131 + return -EINVAL; 132 + 133 + return 0; 134 + } 135 + 136 + #define SCC_NAPI_RX_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB) 137 + #define SCC_RX_EVENT (SCCE_ENET_RXF) 138 + #define SCC_TX_EVENT (SCCE_ENET_TXB) 139 + #define SCC_ERR_EVENT_MSK (SCCE_ENET_TXE | SCCE_ENET_BSY) 140 + 141 + static int setup_data(struct net_device *dev) 142 + { 143 + struct fs_enet_private *fep = netdev_priv(dev); 144 + const struct fs_platform_info *fpi = fep->fpi; 145 + 146 + fep->scc.idx = fs_get_scc_index(fpi->fs_no); 147 + if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */ 148 + return -EINVAL; 149 + 150 + do_pd_setup(fep); 151 + 152 + fep->scc.hthi = 0; 153 + fep->scc.htlo = 0; 154 + 155 + fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK; 156 + fep->ev_rx = SCC_RX_EVENT; 157 + fep->ev_tx = SCC_TX_EVENT; 158 + fep->ev_err = SCC_ERR_EVENT_MSK; 159 + 160 + return 0; 161 + } 162 + 163 + static int allocate_bd(struct net_device *dev) 164 + { 165 + struct fs_enet_private *fep = netdev_priv(dev); 166 + const struct fs_platform_info *fpi = fep->fpi; 167 + 168 + fep->ring_mem_addr = cpm_dpalloc((fpi->tx_ring + fpi->rx_ring) * 169 + sizeof(cbd_t), 8); 170 + if (IS_DPERR(fep->ring_mem_addr)) 171 + return -ENOMEM; 172 + 173 + fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr); 174 + 175 + return 0; 176 + } 177 + 178 + static void free_bd(struct net_device *dev) 179 + { 180 + struct fs_enet_private *fep = netdev_priv(dev); 181 + 182 + if (fep->ring_base) 183 + cpm_dpfree(fep->ring_mem_addr); 184 + } 185 + 186 + static void cleanup_data(struct net_device *dev) 187 + { 188 + /* nothing */ 189 + } 190 + 191 + static void set_promiscuous_mode(struct net_device *dev) 192 + { 193 + struct fs_enet_private *fep = netdev_priv(dev); 194 + scc_t *sccp = fep->scc.sccp; 195 + 196 + S16(sccp, scc_psmr, SCC_PSMR_PRO); 197 + } 198 + 199 + static void set_multicast_start(struct net_device *dev) 200 + { 201 + struct fs_enet_private *fep = netdev_priv(dev); 202 + scc_enet_t *ep = fep->scc.ep; 203 + 204 + W16(ep, sen_gaddr1, 0); 205 + W16(ep, sen_gaddr2, 0); 206 + W16(ep, sen_gaddr3, 0); 207 + W16(ep, sen_gaddr4, 0); 208 + } 209 + 210 + static void set_multicast_one(struct net_device *dev, const u8 * mac) 211 + { 212 + struct fs_enet_private *fep = netdev_priv(dev); 213 + scc_enet_t *ep = fep->scc.ep; 214 + u16 taddrh, taddrm, taddrl; 215 + 216 + taddrh = ((u16) mac[5] << 8) | mac[4]; 217 + taddrm = ((u16) mac[3] << 8) | mac[2]; 218 + taddrl = ((u16) mac[1] << 8) | mac[0]; 219 + 220 + W16(ep, sen_taddrh, taddrh); 221 + W16(ep, sen_taddrm, taddrm); 222 + W16(ep, sen_taddrl, taddrl); 223 + scc_cr_cmd(fep, CPM_CR_SET_GADDR); 224 + } 225 + 226 + static void set_multicast_finish(struct net_device *dev) 227 + { 228 + struct fs_enet_private *fep = netdev_priv(dev); 229 + scc_t *sccp = fep->scc.sccp; 230 + scc_enet_t *ep = fep->scc.ep; 231 + 232 + /* clear promiscuous always */ 233 + C16(sccp, scc_psmr, SCC_PSMR_PRO); 234 + 235 + /* if all multi or too many multicasts; just enable all */ 236 + if ((dev->flags & IFF_ALLMULTI) != 0 || 237 + dev->mc_count > SCC_MAX_MULTICAST_ADDRS) { 238 + 239 + W16(ep, sen_gaddr1, 0xffff); 240 + W16(ep, sen_gaddr2, 0xffff); 241 + W16(ep, sen_gaddr3, 0xffff); 242 + W16(ep, sen_gaddr4, 0xffff); 243 + } 244 + } 245 + 246 + static void set_multicast_list(struct net_device *dev) 247 + { 248 + struct dev_mc_list *pmc; 249 + 250 + if ((dev->flags & IFF_PROMISC) == 0) { 251 + set_multicast_start(dev); 252 + for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) 253 + set_multicast_one(dev, pmc->dmi_addr); 254 + set_multicast_finish(dev); 255 + } else 256 + set_promiscuous_mode(dev); 257 + } 258 + 259 + /* 260 + * This function is called to start or restart the FEC during a link 261 + * change. This only happens when switching between half and full 262 + * duplex. 263 + */ 264 + static void restart(struct net_device *dev) 265 + { 266 + struct fs_enet_private *fep = netdev_priv(dev); 267 + scc_t *sccp = fep->scc.sccp; 268 + scc_enet_t *ep = fep->scc.ep; 269 + const struct fs_platform_info *fpi = fep->fpi; 270 + u16 paddrh, paddrm, paddrl; 271 + const unsigned char *mac; 272 + int i; 273 + 274 + C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); 275 + 276 + /* clear everything (slow & steady does it) */ 277 + for (i = 0; i < sizeof(*ep); i++) 278 + __fs_out8((char *)ep + i, 0); 279 + 280 + /* point to bds */ 281 + W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr); 282 + W16(ep, sen_genscc.scc_tbase, 283 + fep->ring_mem_addr + sizeof(cbd_t) * fpi->rx_ring); 284 + 285 + /* Initialize function code registers for big-endian. 286 + */ 287 + W8(ep, sen_genscc.scc_rfcr, SCC_EB); 288 + W8(ep, sen_genscc.scc_tfcr, SCC_EB); 289 + 290 + /* Set maximum bytes per receive buffer. 291 + * This appears to be an Ethernet frame size, not the buffer 292 + * fragment size. It must be a multiple of four. 293 + */ 294 + W16(ep, sen_genscc.scc_mrblr, 0x5f0); 295 + 296 + /* Set CRC preset and mask. 297 + */ 298 + W32(ep, sen_cpres, 0xffffffff); 299 + W32(ep, sen_cmask, 0xdebb20e3); 300 + 301 + W32(ep, sen_crcec, 0); /* CRC Error counter */ 302 + W32(ep, sen_alec, 0); /* alignment error counter */ 303 + W32(ep, sen_disfc, 0); /* discard frame counter */ 304 + 305 + W16(ep, sen_pads, 0x8888); /* Tx short frame pad character */ 306 + W16(ep, sen_retlim, 15); /* Retry limit threshold */ 307 + 308 + W16(ep, sen_maxflr, 0x5ee); /* maximum frame length register */ 309 + 310 + W16(ep, sen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */ 311 + 312 + W16(ep, sen_maxd1, 0x000005f0); /* maximum DMA1 length */ 313 + W16(ep, sen_maxd2, 0x000005f0); /* maximum DMA2 length */ 314 + 315 + /* Clear hash tables. 316 + */ 317 + W16(ep, sen_gaddr1, 0); 318 + W16(ep, sen_gaddr2, 0); 319 + W16(ep, sen_gaddr3, 0); 320 + W16(ep, sen_gaddr4, 0); 321 + W16(ep, sen_iaddr1, 0); 322 + W16(ep, sen_iaddr2, 0); 323 + W16(ep, sen_iaddr3, 0); 324 + W16(ep, sen_iaddr4, 0); 325 + 326 + /* set address 327 + */ 328 + mac = dev->dev_addr; 329 + paddrh = ((u16) mac[5] << 8) | mac[4]; 330 + paddrm = ((u16) mac[3] << 8) | mac[2]; 331 + paddrl = ((u16) mac[1] << 8) | mac[0]; 332 + 333 + W16(ep, sen_paddrh, paddrh); 334 + W16(ep, sen_paddrm, paddrm); 335 + W16(ep, sen_paddrl, paddrl); 336 + 337 + W16(ep, sen_pper, 0); 338 + W16(ep, sen_taddrl, 0); 339 + W16(ep, sen_taddrm, 0); 340 + W16(ep, sen_taddrh, 0); 341 + 342 + fs_init_bds(dev); 343 + 344 + scc_cr_cmd(fep, CPM_CR_INIT_TRX); 345 + 346 + W16(sccp, scc_scce, 0xffff); 347 + 348 + /* Enable interrupts we wish to service. 349 + */ 350 + W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB); 351 + 352 + /* Set GSMR_H to enable all normal operating modes. 353 + * Set GSMR_L to enable Ethernet to MC68160. 354 + */ 355 + W32(sccp, scc_gsmrh, 0); 356 + W32(sccp, scc_gsmrl, 357 + SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | 358 + SCC_GSMRL_MODE_ENET); 359 + 360 + /* Set sync/delimiters. 361 + */ 362 + W16(sccp, scc_dsr, 0xd555); 363 + 364 + /* Set processing mode. Use Ethernet CRC, catch broadcast, and 365 + * start frame search 22 bit times after RENA. 366 + */ 367 + W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22); 368 + 369 + /* Set full duplex mode if needed */ 370 + if (fep->duplex) 371 + S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE); 372 + 373 + S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); 374 + } 375 + 376 + static void stop(struct net_device *dev) 377 + { 378 + struct fs_enet_private *fep = netdev_priv(dev); 379 + scc_t *sccp = fep->scc.sccp; 380 + int i; 381 + 382 + for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++) 383 + udelay(1); 384 + 385 + if (i == SCC_RESET_DELAY) 386 + printk(KERN_WARNING DRV_MODULE_NAME 387 + ": %s SCC timeout on graceful transmit stop\n", 388 + dev->name); 389 + 390 + W16(sccp, scc_sccm, 0); 391 + C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); 392 + 393 + fs_cleanup_bds(dev); 394 + } 395 + 396 + static void pre_request_irq(struct net_device *dev, int irq) 397 + { 398 + immap_t *immap = fs_enet_immap; 399 + u32 siel; 400 + 401 + /* SIU interrupt */ 402 + if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { 403 + 404 + siel = in_be32(&immap->im_siu_conf.sc_siel); 405 + if ((irq & 1) == 0) 406 + siel |= (0x80000000 >> irq); 407 + else 408 + siel &= ~(0x80000000 >> (irq & ~1)); 409 + out_be32(&immap->im_siu_conf.sc_siel, siel); 410 + } 411 + } 412 + 413 + static void post_free_irq(struct net_device *dev, int irq) 414 + { 415 + /* nothing */ 416 + } 417 + 418 + static void napi_clear_rx_event(struct net_device *dev) 419 + { 420 + struct fs_enet_private *fep = netdev_priv(dev); 421 + scc_t *sccp = fep->scc.sccp; 422 + 423 + W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK); 424 + } 425 + 426 + static void napi_enable_rx(struct net_device *dev) 427 + { 428 + struct fs_enet_private *fep = netdev_priv(dev); 429 + scc_t *sccp = fep->scc.sccp; 430 + 431 + S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); 432 + } 433 + 434 + static void napi_disable_rx(struct net_device *dev) 435 + { 436 + struct fs_enet_private *fep = netdev_priv(dev); 437 + scc_t *sccp = fep->scc.sccp; 438 + 439 + C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK); 440 + } 441 + 442 + static void rx_bd_done(struct net_device *dev) 443 + { 444 + /* nothing */ 445 + } 446 + 447 + static void tx_kickstart(struct net_device *dev) 448 + { 449 + /* nothing */ 450 + } 451 + 452 + static u32 get_int_events(struct net_device *dev) 453 + { 454 + struct fs_enet_private *fep = netdev_priv(dev); 455 + scc_t *sccp = fep->scc.sccp; 456 + 457 + return (u32) R16(sccp, scc_scce); 458 + } 459 + 460 + static void clear_int_events(struct net_device *dev, u32 int_events) 461 + { 462 + struct fs_enet_private *fep = netdev_priv(dev); 463 + scc_t *sccp = fep->scc.sccp; 464 + 465 + W16(sccp, scc_scce, int_events & 0xffff); 466 + } 467 + 468 + static void ev_error(struct net_device *dev, u32 int_events) 469 + { 470 + printk(KERN_WARNING DRV_MODULE_NAME 471 + ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events); 472 + } 473 + 474 + static int get_regs(struct net_device *dev, void *p, int *sizep) 475 + { 476 + struct fs_enet_private *fep = netdev_priv(dev); 477 + 478 + if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t)) 479 + return -EINVAL; 480 + 481 + memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t)); 482 + p = (char *)p + sizeof(scc_t); 483 + 484 + memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t)); 485 + 486 + return 0; 487 + } 488 + 489 + static int get_regs_len(struct net_device *dev) 490 + { 491 + return sizeof(scc_t) + sizeof(scc_enet_t); 492 + } 493 + 494 + static void tx_restart(struct net_device *dev) 495 + { 496 + struct fs_enet_private *fep = netdev_priv(dev); 497 + 498 + scc_cr_cmd(fep, CPM_CR_RESTART_TX); 499 + } 500 + 501 + /*************************************************************************/ 502 + 503 + const struct fs_ops fs_scc_ops = { 504 + .setup_data = setup_data, 505 + .cleanup_data = cleanup_data, 506 + .set_multicast_list = set_multicast_list, 507 + .restart = restart, 508 + .stop = stop, 509 + .pre_request_irq = pre_request_irq, 510 + .post_free_irq = post_free_irq, 511 + .napi_clear_rx_event = napi_clear_rx_event, 512 + .napi_enable_rx = napi_enable_rx, 513 + .napi_disable_rx = napi_disable_rx, 514 + .rx_bd_done = rx_bd_done, 515 + .tx_kickstart = tx_kickstart, 516 + .get_int_events = get_int_events, 517 + .clear_int_events = clear_int_events, 518 + .ev_error = ev_error, 519 + .get_regs = get_regs, 520 + .get_regs_len = get_regs_len, 521 + .tx_restart = tx_restart, 522 + .allocate_bd = allocate_bd, 523 + .free_bd = free_bd, 524 + };
+405
drivers/net/fs_enet/mii-bitbang.c
··· 1 + /* 2 + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. 3 + * 4 + * Copyright (c) 2003 Intracom S.A. 5 + * by Pantelis Antoniou <panto@intracom.gr> 6 + * 7 + * 2005 (c) MontaVista Software, Inc. 8 + * Vitaly Bordug <vbordug@ru.mvista.com> 9 + * 10 + * This file is licensed under the terms of the GNU General Public License 11 + * version 2. This program is licensed "as is" without any warranty of any 12 + * kind, whether express or implied. 13 + */ 14 + 15 + 16 + #include <linux/config.h> 17 + #include <linux/module.h> 18 + #include <linux/types.h> 19 + #include <linux/kernel.h> 20 + #include <linux/sched.h> 21 + #include <linux/string.h> 22 + #include <linux/ptrace.h> 23 + #include <linux/errno.h> 24 + #include <linux/ioport.h> 25 + #include <linux/slab.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/pci.h> 28 + #include <linux/init.h> 29 + #include <linux/delay.h> 30 + #include <linux/netdevice.h> 31 + #include <linux/etherdevice.h> 32 + #include <linux/skbuff.h> 33 + #include <linux/spinlock.h> 34 + #include <linux/mii.h> 35 + #include <linux/ethtool.h> 36 + #include <linux/bitops.h> 37 + 38 + #include <asm/pgtable.h> 39 + #include <asm/irq.h> 40 + #include <asm/uaccess.h> 41 + 42 + #include "fs_enet.h" 43 + 44 + #ifdef CONFIG_8xx 45 + static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) 46 + { 47 + immap_t *im = (immap_t *)fs_enet_immap; 48 + void *dir, *dat, *ppar; 49 + int adv; 50 + u8 msk; 51 + 52 + switch (port) { 53 + case fsiop_porta: 54 + dir = &im->im_ioport.iop_padir; 55 + dat = &im->im_ioport.iop_padat; 56 + ppar = &im->im_ioport.iop_papar; 57 + break; 58 + 59 + case fsiop_portb: 60 + dir = &im->im_cpm.cp_pbdir; 61 + dat = &im->im_cpm.cp_pbdat; 62 + ppar = &im->im_cpm.cp_pbpar; 63 + break; 64 + 65 + case fsiop_portc: 66 + dir = &im->im_ioport.iop_pcdir; 67 + dat = &im->im_ioport.iop_pcdat; 68 + ppar = &im->im_ioport.iop_pcpar; 69 + break; 70 + 71 + case fsiop_portd: 72 + dir = &im->im_ioport.iop_pddir; 73 + dat = &im->im_ioport.iop_pddat; 74 + ppar = &im->im_ioport.iop_pdpar; 75 + break; 76 + 77 + case fsiop_porte: 78 + dir = &im->im_cpm.cp_pedir; 79 + dat = &im->im_cpm.cp_pedat; 80 + ppar = &im->im_cpm.cp_pepar; 81 + break; 82 + 83 + default: 84 + printk(KERN_ERR DRV_MODULE_NAME 85 + "Illegal port value %d!\n", port); 86 + return -EINVAL; 87 + } 88 + 89 + adv = bit >> 3; 90 + dir = (char *)dir + adv; 91 + dat = (char *)dat + adv; 92 + ppar = (char *)ppar + adv; 93 + 94 + msk = 1 << (7 - (bit & 7)); 95 + if ((in_8(ppar) & msk) != 0) { 96 + printk(KERN_ERR DRV_MODULE_NAME 97 + "pin %d on port %d is not general purpose!\n", bit, port); 98 + return -EINVAL; 99 + } 100 + 101 + *dirp = dir; 102 + *datp = dat; 103 + *mskp = msk; 104 + 105 + return 0; 106 + } 107 + #endif 108 + 109 + #ifdef CONFIG_8260 110 + static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) 111 + { 112 + iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport; 113 + void *dir, *dat, *ppar; 114 + int adv; 115 + u8 msk; 116 + 117 + switch (port) { 118 + case fsiop_porta: 119 + dir = &io->iop_pdira; 120 + dat = &io->iop_pdata; 121 + ppar = &io->iop_ppara; 122 + break; 123 + 124 + case fsiop_portb: 125 + dir = &io->iop_pdirb; 126 + dat = &io->iop_pdatb; 127 + ppar = &io->iop_pparb; 128 + break; 129 + 130 + case fsiop_portc: 131 + dir = &io->iop_pdirc; 132 + dat = &io->iop_pdatc; 133 + ppar = &io->iop_pparc; 134 + break; 135 + 136 + case fsiop_portd: 137 + dir = &io->iop_pdird; 138 + dat = &io->iop_pdatd; 139 + ppar = &io->iop_ppard; 140 + break; 141 + 142 + default: 143 + printk(KERN_ERR DRV_MODULE_NAME 144 + "Illegal port value %d!\n", port); 145 + return -EINVAL; 146 + } 147 + 148 + adv = bit >> 3; 149 + dir = (char *)dir + adv; 150 + dat = (char *)dat + adv; 151 + ppar = (char *)ppar + adv; 152 + 153 + msk = 1 << (7 - (bit & 7)); 154 + if ((in_8(ppar) & msk) != 0) { 155 + printk(KERN_ERR DRV_MODULE_NAME 156 + "pin %d on port %d is not general purpose!\n", bit, port); 157 + return -EINVAL; 158 + } 159 + 160 + *dirp = dir; 161 + *datp = dat; 162 + *mskp = msk; 163 + 164 + return 0; 165 + } 166 + #endif 167 + 168 + static inline void bb_set(u8 *p, u8 m) 169 + { 170 + out_8(p, in_8(p) | m); 171 + } 172 + 173 + static inline void bb_clr(u8 *p, u8 m) 174 + { 175 + out_8(p, in_8(p) & ~m); 176 + } 177 + 178 + static inline int bb_read(u8 *p, u8 m) 179 + { 180 + return (in_8(p) & m) != 0; 181 + } 182 + 183 + static inline void mdio_active(struct fs_enet_mii_bus *bus) 184 + { 185 + bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); 186 + } 187 + 188 + static inline void mdio_tristate(struct fs_enet_mii_bus *bus) 189 + { 190 + bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); 191 + } 192 + 193 + static inline int mdio_read(struct fs_enet_mii_bus *bus) 194 + { 195 + return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); 196 + } 197 + 198 + static inline void mdio(struct fs_enet_mii_bus *bus, int what) 199 + { 200 + if (what) 201 + bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); 202 + else 203 + bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); 204 + } 205 + 206 + static inline void mdc(struct fs_enet_mii_bus *bus, int what) 207 + { 208 + if (what) 209 + bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); 210 + else 211 + bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); 212 + } 213 + 214 + static inline void mii_delay(struct fs_enet_mii_bus *bus) 215 + { 216 + udelay(bus->bus_info->i.bitbang.delay); 217 + } 218 + 219 + /* Utility to send the preamble, address, and register (common to read and write). */ 220 + static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg) 221 + { 222 + int j; 223 + 224 + /* 225 + * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure. 226 + * The IEEE spec says this is a PHY optional requirement. The AMD 227 + * 79C874 requires one after power up and one after a MII communications 228 + * error. This means that we are doing more preambles than we need, 229 + * but it is safer and will be much more robust. 230 + */ 231 + 232 + mdio_active(bus); 233 + mdio(bus, 1); 234 + for (j = 0; j < 32; j++) { 235 + mdc(bus, 0); 236 + mii_delay(bus); 237 + mdc(bus, 1); 238 + mii_delay(bus); 239 + } 240 + 241 + /* send the start bit (01) and the read opcode (10) or write (10) */ 242 + mdc(bus, 0); 243 + mdio(bus, 0); 244 + mii_delay(bus); 245 + mdc(bus, 1); 246 + mii_delay(bus); 247 + mdc(bus, 0); 248 + mdio(bus, 1); 249 + mii_delay(bus); 250 + mdc(bus, 1); 251 + mii_delay(bus); 252 + mdc(bus, 0); 253 + mdio(bus, read); 254 + mii_delay(bus); 255 + mdc(bus, 1); 256 + mii_delay(bus); 257 + mdc(bus, 0); 258 + mdio(bus, !read); 259 + mii_delay(bus); 260 + mdc(bus, 1); 261 + mii_delay(bus); 262 + 263 + /* send the PHY address */ 264 + for (j = 0; j < 5; j++) { 265 + mdc(bus, 0); 266 + mdio(bus, (addr & 0x10) != 0); 267 + mii_delay(bus); 268 + mdc(bus, 1); 269 + mii_delay(bus); 270 + addr <<= 1; 271 + } 272 + 273 + /* send the register address */ 274 + for (j = 0; j < 5; j++) { 275 + mdc(bus, 0); 276 + mdio(bus, (reg & 0x10) != 0); 277 + mii_delay(bus); 278 + mdc(bus, 1); 279 + mii_delay(bus); 280 + reg <<= 1; 281 + } 282 + } 283 + 284 + static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) 285 + { 286 + u16 rdreg; 287 + int ret, j; 288 + u8 addr = phy_id & 0xff; 289 + u8 reg = location & 0xff; 290 + 291 + bitbang_pre(bus, 1, addr, reg); 292 + 293 + /* tri-state our MDIO I/O pin so we can read */ 294 + mdc(bus, 0); 295 + mdio_tristate(bus); 296 + mii_delay(bus); 297 + mdc(bus, 1); 298 + mii_delay(bus); 299 + 300 + /* check the turnaround bit: the PHY should be driving it to zero */ 301 + if (mdio_read(bus) != 0) { 302 + /* PHY didn't drive TA low */ 303 + for (j = 0; j < 32; j++) { 304 + mdc(bus, 0); 305 + mii_delay(bus); 306 + mdc(bus, 1); 307 + mii_delay(bus); 308 + } 309 + ret = -1; 310 + goto out; 311 + } 312 + 313 + mdc(bus, 0); 314 + mii_delay(bus); 315 + 316 + /* read 16 bits of register data, MSB first */ 317 + rdreg = 0; 318 + for (j = 0; j < 16; j++) { 319 + mdc(bus, 1); 320 + mii_delay(bus); 321 + rdreg <<= 1; 322 + rdreg |= mdio_read(bus); 323 + mdc(bus, 0); 324 + mii_delay(bus); 325 + } 326 + 327 + mdc(bus, 1); 328 + mii_delay(bus); 329 + mdc(bus, 0); 330 + mii_delay(bus); 331 + mdc(bus, 1); 332 + mii_delay(bus); 333 + 334 + ret = rdreg; 335 + out: 336 + return ret; 337 + } 338 + 339 + static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) 340 + { 341 + int j; 342 + u8 addr = phy_id & 0xff; 343 + u8 reg = location & 0xff; 344 + u16 value = val & 0xffff; 345 + 346 + bitbang_pre(bus, 0, addr, reg); 347 + 348 + /* send the turnaround (10) */ 349 + mdc(bus, 0); 350 + mdio(bus, 1); 351 + mii_delay(bus); 352 + mdc(bus, 1); 353 + mii_delay(bus); 354 + mdc(bus, 0); 355 + mdio(bus, 0); 356 + mii_delay(bus); 357 + mdc(bus, 1); 358 + mii_delay(bus); 359 + 360 + /* write 16 bits of register data, MSB first */ 361 + for (j = 0; j < 16; j++) { 362 + mdc(bus, 0); 363 + mdio(bus, (value & 0x8000) != 0); 364 + mii_delay(bus); 365 + mdc(bus, 1); 366 + mii_delay(bus); 367 + value <<= 1; 368 + } 369 + 370 + /* 371 + * Tri-state the MDIO line. 372 + */ 373 + mdio_tristate(bus); 374 + mdc(bus, 0); 375 + mii_delay(bus); 376 + mdc(bus, 1); 377 + mii_delay(bus); 378 + } 379 + 380 + int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus) 381 + { 382 + const struct fs_mii_bus_info *bi = bus->bus_info; 383 + int r; 384 + 385 + r = bitbang_prep_bit(&bus->bitbang.mdio_dir, 386 + &bus->bitbang.mdio_dat, 387 + &bus->bitbang.mdio_msk, 388 + bi->i.bitbang.mdio_port, 389 + bi->i.bitbang.mdio_bit); 390 + if (r != 0) 391 + return r; 392 + 393 + r = bitbang_prep_bit(&bus->bitbang.mdc_dir, 394 + &bus->bitbang.mdc_dat, 395 + &bus->bitbang.mdc_msk, 396 + bi->i.bitbang.mdc_port, 397 + bi->i.bitbang.mdc_bit); 398 + if (r != 0) 399 + return r; 400 + 401 + bus->mii_read = mii_read; 402 + bus->mii_write = mii_write; 403 + 404 + return 0; 405 + }
+92
drivers/net/fs_enet/mii-fixed.c
··· 1 + /* 2 + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. 3 + * 4 + * Copyright (c) 2003 Intracom S.A. 5 + * by Pantelis Antoniou <panto@intracom.gr> 6 + * 7 + * 2005 (c) MontaVista Software, Inc. 8 + * Vitaly Bordug <vbordug@ru.mvista.com> 9 + * 10 + * This file is licensed under the terms of the GNU General Public License 11 + * version 2. This program is licensed "as is" without any warranty of any 12 + * kind, whether express or implied. 13 + */ 14 + 15 + 16 + #include <linux/config.h> 17 + #include <linux/module.h> 18 + #include <linux/types.h> 19 + #include <linux/kernel.h> 20 + #include <linux/sched.h> 21 + #include <linux/string.h> 22 + #include <linux/ptrace.h> 23 + #include <linux/errno.h> 24 + #include <linux/ioport.h> 25 + #include <linux/slab.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/pci.h> 28 + #include <linux/init.h> 29 + #include <linux/delay.h> 30 + #include <linux/netdevice.h> 31 + #include <linux/etherdevice.h> 32 + #include <linux/skbuff.h> 33 + #include <linux/spinlock.h> 34 + #include <linux/mii.h> 35 + #include <linux/ethtool.h> 36 + #include <linux/bitops.h> 37 + 38 + #include <asm/pgtable.h> 39 + #include <asm/irq.h> 40 + #include <asm/uaccess.h> 41 + 42 + #include "fs_enet.h" 43 + 44 + static const u16 mii_regs[7] = { 45 + 0x3100, 46 + 0x786d, 47 + 0x0fff, 48 + 0x0fff, 49 + 0x01e1, 50 + 0x45e1, 51 + 0x0003, 52 + }; 53 + 54 + static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) 55 + { 56 + int ret = 0; 57 + 58 + if ((unsigned int)location >= ARRAY_SIZE(mii_regs)) 59 + return -1; 60 + 61 + if (location != 5) 62 + ret = mii_regs[location]; 63 + else 64 + ret = bus->fixed.lpa; 65 + 66 + return ret; 67 + } 68 + 69 + static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) 70 + { 71 + /* do nothing */ 72 + } 73 + 74 + int fs_mii_fixed_init(struct fs_enet_mii_bus *bus) 75 + { 76 + const struct fs_mii_bus_info *bi = bus->bus_info; 77 + 78 + bus->fixed.lpa = 0x45e1; /* default 100Mb, full duplex */ 79 + 80 + /* if speed is fixed at 10Mb, remove 100Mb modes */ 81 + if (bi->i.fixed.speed == 10) 82 + bus->fixed.lpa &= ~LPA_100; 83 + 84 + /* if duplex is half, remove full duplex modes */ 85 + if (bi->i.fixed.duplex == 0) 86 + bus->fixed.lpa &= ~LPA_DUPLEX; 87 + 88 + bus->mii_read = mii_read; 89 + bus->mii_write = mii_write; 90 + 91 + return 0; 92 + }
+136
include/linux/fs_enet_pd.h
··· 1 + /* 2 + * Platform information definitions for the 3 + * universal Freescale Ethernet driver. 4 + * 5 + * Copyright (c) 2003 Intracom S.A. 6 + * by Pantelis Antoniou <panto@intracom.gr> 7 + * 8 + * 2005 (c) MontaVista Software, Inc. 9 + * Vitaly Bordug <vbordug@ru.mvista.com> 10 + * 11 + * This file is licensed under the terms of the GNU General Public License 12 + * version 2. This program is licensed "as is" without any warranty of any 13 + * kind, whether express or implied. 14 + */ 15 + 16 + #ifndef FS_ENET_PD_H 17 + #define FS_ENET_PD_H 18 + 19 + #include <linux/version.h> 20 + #include <asm/types.h> 21 + 22 + #define FS_ENET_NAME "fs_enet" 23 + 24 + enum fs_id { 25 + fsid_fec1, 26 + fsid_fec2, 27 + fsid_fcc1, 28 + fsid_fcc2, 29 + fsid_fcc3, 30 + fsid_scc1, 31 + fsid_scc2, 32 + fsid_scc3, 33 + fsid_scc4, 34 + }; 35 + 36 + #define FS_MAX_INDEX 9 37 + 38 + static inline int fs_get_fec_index(enum fs_id id) 39 + { 40 + if (id >= fsid_fec1 && id <= fsid_fec2) 41 + return id - fsid_fec1; 42 + return -1; 43 + } 44 + 45 + static inline int fs_get_fcc_index(enum fs_id id) 46 + { 47 + if (id >= fsid_fcc1 && id <= fsid_fcc3) 48 + return id - fsid_fcc1; 49 + return -1; 50 + } 51 + 52 + static inline int fs_get_scc_index(enum fs_id id) 53 + { 54 + if (id >= fsid_scc1 && id <= fsid_scc4) 55 + return id - fsid_scc1; 56 + return -1; 57 + } 58 + 59 + enum fs_mii_method { 60 + fsmii_fixed, 61 + fsmii_fec, 62 + fsmii_bitbang, 63 + }; 64 + 65 + enum fs_ioport { 66 + fsiop_porta, 67 + fsiop_portb, 68 + fsiop_portc, 69 + fsiop_portd, 70 + fsiop_porte, 71 + }; 72 + 73 + struct fs_mii_bus_info { 74 + int method; /* mii method */ 75 + int id; /* the id of the mii_bus */ 76 + int disable_aneg; /* if the controller needs to negothiate speed & duplex */ 77 + int lpa; /* the default board-specific vallues will be applied otherwise */ 78 + 79 + union { 80 + struct { 81 + int duplex; 82 + int speed; 83 + } fixed; 84 + 85 + struct { 86 + /* nothing */ 87 + } fec; 88 + 89 + struct { 90 + /* nothing */ 91 + } scc; 92 + 93 + struct { 94 + int mdio_port; /* port & bit for MDIO */ 95 + int mdio_bit; 96 + int mdc_port; /* port & bit for MDC */ 97 + int mdc_bit; 98 + int delay; /* delay in us */ 99 + } bitbang; 100 + } i; 101 + }; 102 + 103 + struct fs_platform_info { 104 + 105 + void(*init_ioports)(void); 106 + /* device specific information */ 107 + int fs_no; /* controller index */ 108 + 109 + u32 cp_page; /* CPM page */ 110 + u32 cp_block; /* CPM sblock */ 111 + 112 + u32 clk_trx; /* some stuff for pins & mux configuration*/ 113 + u32 clk_route; 114 + u32 clk_mask; 115 + 116 + u32 mem_offset; 117 + u32 dpram_offset; 118 + u32 fcc_regs_c; 119 + 120 + u32 device_flags; 121 + 122 + int phy_addr; /* the phy address (-1 no phy) */ 123 + int phy_irq; /* the phy irq (if it exists) */ 124 + 125 + const struct fs_mii_bus_info *bus_info; 126 + 127 + int rx_ring, tx_ring; /* number of buffers on rx */ 128 + __u8 macaddr[6]; /* mac address */ 129 + int rx_copybreak; /* limit we copy small frames */ 130 + int use_napi; /* use NAPI */ 131 + int napi_weight; /* NAPI weight */ 132 + 133 + int use_rmii; /* use RMII mode */ 134 + }; 135 + 136 + #endif