1279 lines · c
1// SPDX-License-Identifier: GPL-2.02/* sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters.3 *4 * Copyright (C) 1997, 1998, 1999, 2003, 2008 David S. Miller (davem@davemloft.net)5 */6 7#include <linux/module.h>8#include <linux/pgtable.h>9 10#include <linux/kernel.h>11#include <linux/types.h>12#include <linux/fcntl.h>13#include <linux/interrupt.h>14#include <linux/ioport.h>15#include <linux/in.h>16#include <linux/string.h>17#include <linux/delay.h>18#include <linux/crc32.h>19#include <linux/errno.h>20#include <linux/ethtool.h>21#include <linux/mii.h>22#include <linux/netdevice.h>23#include <linux/etherdevice.h>24#include <linux/skbuff.h>25#include <linux/bitops.h>26#include <linux/dma-mapping.h>27#include <linux/of.h>28#include <linux/platform_device.h>29#include <linux/gfp.h>30 31#include <asm/auxio.h>32#include <asm/byteorder.h>33#include <asm/dma.h>34#include <asm/idprom.h>35#include <asm/io.h>36#include <asm/openprom.h>37#include <asm/oplib.h>38 39#include "sunbmac.h"40 41#define DRV_NAME "sunbmac"42#define DRV_VERSION "2.1"43#define DRV_RELDATE "August 26, 2008"44#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"45 46static char version[] =47 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";48 49MODULE_VERSION(DRV_VERSION);50MODULE_AUTHOR(DRV_AUTHOR);51MODULE_DESCRIPTION("Sun BigMAC 100baseT ethernet driver");52MODULE_LICENSE("GPL");53 54#undef DEBUG_PROBE55#undef DEBUG_TX56#undef DEBUG_IRQ57 58#ifdef DEBUG_PROBE59#define DP(x) printk x60#else61#define DP(x)62#endif63 64#ifdef DEBUG_TX65#define DTX(x) printk x66#else67#define DTX(x)68#endif69 70#ifdef DEBUG_IRQ71#define DIRQ(x) printk x72#else73#define DIRQ(x)74#endif75 76#define DEFAULT_JAMSIZE 4 /* Toe jam */77 78#define QEC_RESET_TRIES 20079 80static int qec_global_reset(void __iomem *gregs)81{82 int tries = QEC_RESET_TRIES;83 84 sbus_writel(GLOB_CTRL_RESET, gregs + GLOB_CTRL);85 while (--tries) {86 if (sbus_readl(gregs + GLOB_CTRL) & GLOB_CTRL_RESET) {87 udelay(20);88 continue;89 }90 break;91 }92 if (tries)93 return 0;94 printk(KERN_ERR "BigMAC: Cannot reset the QEC.\n");95 return -1;96}97 98static void qec_init(struct bigmac *bp)99{100 struct platform_device *qec_op = bp->qec_op;101 void __iomem *gregs = bp->gregs;102 u8 bsizes = bp->bigmac_bursts;103 u32 regval;104 105 /* 64byte bursts do not work at the moment, do106 * not even try to enable them. -DaveM107 */108 if (bsizes & DMA_BURST32)109 regval = GLOB_CTRL_B32;110 else111 regval = GLOB_CTRL_B16;112 sbus_writel(regval | GLOB_CTRL_BMODE, gregs + GLOB_CTRL);113 sbus_writel(GLOB_PSIZE_2048, gregs + GLOB_PSIZE);114 115 /* All of memsize is given to bigmac. */116 sbus_writel(resource_size(&qec_op->resource[1]),117 gregs + GLOB_MSIZE);118 119 /* Half to the transmitter, half to the receiver. */120 sbus_writel(resource_size(&qec_op->resource[1]) >> 1,121 gregs + GLOB_TSIZE);122 sbus_writel(resource_size(&qec_op->resource[1]) >> 1,123 gregs + GLOB_RSIZE);124}125 126#define TX_RESET_TRIES 32127#define RX_RESET_TRIES 32128 129static void bigmac_tx_reset(void __iomem *bregs)130{131 int tries = TX_RESET_TRIES;132 133 sbus_writel(0, bregs + BMAC_TXCFG);134 135 /* The fifo threshold bit is read-only and does136 * not clear. -DaveM137 */138 while ((sbus_readl(bregs + BMAC_TXCFG) & ~(BIGMAC_TXCFG_FIFO)) != 0 &&139 --tries != 0)140 udelay(20);141 142 if (!tries) {143 printk(KERN_ERR "BIGMAC: Transmitter will not reset.\n");144 printk(KERN_ERR "BIGMAC: tx_cfg is %08x\n",145 sbus_readl(bregs + BMAC_TXCFG));146 }147}148 149static void bigmac_rx_reset(void __iomem *bregs)150{151 int tries = RX_RESET_TRIES;152 153 sbus_writel(0, bregs + BMAC_RXCFG);154 while (sbus_readl(bregs + BMAC_RXCFG) && --tries)155 udelay(20);156 157 if (!tries) {158 printk(KERN_ERR "BIGMAC: Receiver will not reset.\n");159 printk(KERN_ERR "BIGMAC: rx_cfg is %08x\n",160 sbus_readl(bregs + BMAC_RXCFG));161 }162}163 164/* Reset the transmitter and receiver. */165static void bigmac_stop(struct bigmac *bp)166{167 bigmac_tx_reset(bp->bregs);168 bigmac_rx_reset(bp->bregs);169}170 171static void bigmac_get_counters(struct bigmac *bp, void __iomem *bregs)172{173 struct net_device_stats *stats = &bp->dev->stats;174 175 stats->rx_crc_errors += sbus_readl(bregs + BMAC_RCRCECTR);176 sbus_writel(0, bregs + BMAC_RCRCECTR);177 178 stats->rx_frame_errors += sbus_readl(bregs + BMAC_UNALECTR);179 sbus_writel(0, bregs + BMAC_UNALECTR);180 181 stats->rx_length_errors += sbus_readl(bregs + BMAC_GLECTR);182 sbus_writel(0, bregs + BMAC_GLECTR);183 184 stats->tx_aborted_errors += sbus_readl(bregs + BMAC_EXCTR);185 186 stats->collisions +=187 (sbus_readl(bregs + BMAC_EXCTR) +188 sbus_readl(bregs + BMAC_LTCTR));189 sbus_writel(0, bregs + BMAC_EXCTR);190 sbus_writel(0, bregs + BMAC_LTCTR);191}192 193static void bigmac_clean_rings(struct bigmac *bp)194{195 int i;196 197 for (i = 0; i < RX_RING_SIZE; i++) {198 if (bp->rx_skbs[i] != NULL) {199 dev_kfree_skb_any(bp->rx_skbs[i]);200 bp->rx_skbs[i] = NULL;201 }202 }203 204 for (i = 0; i < TX_RING_SIZE; i++) {205 if (bp->tx_skbs[i] != NULL) {206 dev_kfree_skb_any(bp->tx_skbs[i]);207 bp->tx_skbs[i] = NULL;208 }209 }210}211 212static void bigmac_init_rings(struct bigmac *bp, bool non_blocking)213{214 struct bmac_init_block *bb = bp->bmac_block;215 int i;216 gfp_t gfp_flags = GFP_KERNEL;217 218 if (non_blocking)219 gfp_flags = GFP_ATOMIC;220 221 bp->rx_new = bp->rx_old = bp->tx_new = bp->tx_old = 0;222 223 /* Free any skippy bufs left around in the rings. */224 bigmac_clean_rings(bp);225 226 /* Now get new skbufs for the receive ring. */227 for (i = 0; i < RX_RING_SIZE; i++) {228 struct sk_buff *skb;229 230 skb = big_mac_alloc_skb(RX_BUF_ALLOC_SIZE, gfp_flags);231 if (!skb)232 continue;233 234 bp->rx_skbs[i] = skb;235 236 /* Because we reserve afterwards. */237 skb_put(skb, ETH_FRAME_LEN);238 skb_reserve(skb, 34);239 240 bb->be_rxd[i].rx_addr =241 dma_map_single(&bp->bigmac_op->dev,242 skb->data,243 RX_BUF_ALLOC_SIZE - 34,244 DMA_FROM_DEVICE);245 bb->be_rxd[i].rx_flags =246 (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));247 }248 249 for (i = 0; i < TX_RING_SIZE; i++)250 bb->be_txd[i].tx_flags = bb->be_txd[i].tx_addr = 0;251}252 253#define MGMT_CLKON (MGMT_PAL_INT_MDIO|MGMT_PAL_EXT_MDIO|MGMT_PAL_OENAB|MGMT_PAL_DCLOCK)254#define MGMT_CLKOFF (MGMT_PAL_INT_MDIO|MGMT_PAL_EXT_MDIO|MGMT_PAL_OENAB)255 256static void idle_transceiver(void __iomem *tregs)257{258 int i = 20;259 260 while (i--) {261 sbus_writel(MGMT_CLKOFF, tregs + TCVR_MPAL);262 sbus_readl(tregs + TCVR_MPAL);263 sbus_writel(MGMT_CLKON, tregs + TCVR_MPAL);264 sbus_readl(tregs + TCVR_MPAL);265 }266}267 268static void write_tcvr_bit(struct bigmac *bp, void __iomem *tregs, int bit)269{270 if (bp->tcvr_type == internal) {271 bit = (bit & 1) << 3;272 sbus_writel(bit | (MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO),273 tregs + TCVR_MPAL);274 sbus_readl(tregs + TCVR_MPAL);275 sbus_writel(bit | MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK,276 tregs + TCVR_MPAL);277 sbus_readl(tregs + TCVR_MPAL);278 } else if (bp->tcvr_type == external) {279 bit = (bit & 1) << 2;280 sbus_writel(bit | MGMT_PAL_INT_MDIO | MGMT_PAL_OENAB,281 tregs + TCVR_MPAL);282 sbus_readl(tregs + TCVR_MPAL);283 sbus_writel(bit | MGMT_PAL_INT_MDIO | MGMT_PAL_OENAB | MGMT_PAL_DCLOCK,284 tregs + TCVR_MPAL);285 sbus_readl(tregs + TCVR_MPAL);286 } else {287 printk(KERN_ERR "write_tcvr_bit: No transceiver type known!\n");288 }289}290 291static int read_tcvr_bit(struct bigmac *bp, void __iomem *tregs)292{293 int retval = 0;294 295 if (bp->tcvr_type == internal) {296 sbus_writel(MGMT_PAL_EXT_MDIO, tregs + TCVR_MPAL);297 sbus_readl(tregs + TCVR_MPAL);298 sbus_writel(MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK,299 tregs + TCVR_MPAL);300 sbus_readl(tregs + TCVR_MPAL);301 retval = (sbus_readl(tregs + TCVR_MPAL) & MGMT_PAL_INT_MDIO) >> 3;302 } else if (bp->tcvr_type == external) {303 sbus_writel(MGMT_PAL_INT_MDIO, tregs + TCVR_MPAL);304 sbus_readl(tregs + TCVR_MPAL);305 sbus_writel(MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK, tregs + TCVR_MPAL);306 sbus_readl(tregs + TCVR_MPAL);307 retval = (sbus_readl(tregs + TCVR_MPAL) & MGMT_PAL_EXT_MDIO) >> 2;308 } else {309 printk(KERN_ERR "read_tcvr_bit: No transceiver type known!\n");310 }311 return retval;312}313 314static int read_tcvr_bit2(struct bigmac *bp, void __iomem *tregs)315{316 int retval = 0;317 318 if (bp->tcvr_type == internal) {319 sbus_writel(MGMT_PAL_EXT_MDIO, tregs + TCVR_MPAL);320 sbus_readl(tregs + TCVR_MPAL);321 retval = (sbus_readl(tregs + TCVR_MPAL) & MGMT_PAL_INT_MDIO) >> 3;322 sbus_writel(MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK, tregs + TCVR_MPAL);323 sbus_readl(tregs + TCVR_MPAL);324 } else if (bp->tcvr_type == external) {325 sbus_writel(MGMT_PAL_INT_MDIO, tregs + TCVR_MPAL);326 sbus_readl(tregs + TCVR_MPAL);327 retval = (sbus_readl(tregs + TCVR_MPAL) & MGMT_PAL_EXT_MDIO) >> 2;328 sbus_writel(MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK, tregs + TCVR_MPAL);329 sbus_readl(tregs + TCVR_MPAL);330 } else {331 printk(KERN_ERR "read_tcvr_bit2: No transceiver type known!\n");332 }333 return retval;334}335 336static void put_tcvr_byte(struct bigmac *bp,337 void __iomem *tregs,338 unsigned int byte)339{340 int shift = 4;341 342 do {343 write_tcvr_bit(bp, tregs, ((byte >> shift) & 1));344 shift -= 1;345 } while (shift >= 0);346}347 348static void bigmac_tcvr_write(struct bigmac *bp, void __iomem *tregs,349 int reg, unsigned short val)350{351 int shift;352 353 reg &= 0xff;354 val &= 0xffff;355 switch(bp->tcvr_type) {356 case internal:357 case external:358 break;359 360 default:361 printk(KERN_ERR "bigmac_tcvr_read: Whoops, no known transceiver type.\n");362 return;363 }364 365 idle_transceiver(tregs);366 write_tcvr_bit(bp, tregs, 0);367 write_tcvr_bit(bp, tregs, 1);368 write_tcvr_bit(bp, tregs, 0);369 write_tcvr_bit(bp, tregs, 1);370 371 put_tcvr_byte(bp, tregs,372 ((bp->tcvr_type == internal) ?373 BIGMAC_PHY_INTERNAL : BIGMAC_PHY_EXTERNAL));374 375 put_tcvr_byte(bp, tregs, reg);376 377 write_tcvr_bit(bp, tregs, 1);378 write_tcvr_bit(bp, tregs, 0);379 380 shift = 15;381 do {382 write_tcvr_bit(bp, tregs, (val >> shift) & 1);383 shift -= 1;384 } while (shift >= 0);385}386 387static unsigned short bigmac_tcvr_read(struct bigmac *bp,388 void __iomem *tregs,389 int reg)390{391 unsigned short retval = 0;392 393 reg &= 0xff;394 switch(bp->tcvr_type) {395 case internal:396 case external:397 break;398 399 default:400 printk(KERN_ERR "bigmac_tcvr_read: Whoops, no known transceiver type.\n");401 return 0xffff;402 }403 404 idle_transceiver(tregs);405 write_tcvr_bit(bp, tregs, 0);406 write_tcvr_bit(bp, tregs, 1);407 write_tcvr_bit(bp, tregs, 1);408 write_tcvr_bit(bp, tregs, 0);409 410 put_tcvr_byte(bp, tregs,411 ((bp->tcvr_type == internal) ?412 BIGMAC_PHY_INTERNAL : BIGMAC_PHY_EXTERNAL));413 414 put_tcvr_byte(bp, tregs, reg);415 416 if (bp->tcvr_type == external) {417 int shift = 15;418 419 (void) read_tcvr_bit2(bp, tregs);420 (void) read_tcvr_bit2(bp, tregs);421 422 do {423 int tmp;424 425 tmp = read_tcvr_bit2(bp, tregs);426 retval |= ((tmp & 1) << shift);427 shift -= 1;428 } while (shift >= 0);429 430 (void) read_tcvr_bit2(bp, tregs);431 (void) read_tcvr_bit2(bp, tregs);432 (void) read_tcvr_bit2(bp, tregs);433 } else {434 int shift = 15;435 436 (void) read_tcvr_bit(bp, tregs);437 (void) read_tcvr_bit(bp, tregs);438 439 do {440 int tmp;441 442 tmp = read_tcvr_bit(bp, tregs);443 retval |= ((tmp & 1) << shift);444 shift -= 1;445 } while (shift >= 0);446 447 (void) read_tcvr_bit(bp, tregs);448 (void) read_tcvr_bit(bp, tregs);449 (void) read_tcvr_bit(bp, tregs);450 }451 return retval;452}453 454static void bigmac_tcvr_init(struct bigmac *bp)455{456 void __iomem *tregs = bp->tregs;457 u32 mpal;458 459 idle_transceiver(tregs);460 sbus_writel(MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK,461 tregs + TCVR_MPAL);462 sbus_readl(tregs + TCVR_MPAL);463 464 /* Only the bit for the present transceiver (internal or465 * external) will stick, set them both and see what stays.466 */467 sbus_writel(MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO, tregs + TCVR_MPAL);468 sbus_readl(tregs + TCVR_MPAL);469 udelay(20);470 471 mpal = sbus_readl(tregs + TCVR_MPAL);472 if (mpal & MGMT_PAL_EXT_MDIO) {473 bp->tcvr_type = external;474 sbus_writel(~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE),475 tregs + TCVR_TPAL);476 sbus_readl(tregs + TCVR_TPAL);477 } else if (mpal & MGMT_PAL_INT_MDIO) {478 bp->tcvr_type = internal;479 sbus_writel(~(TCVR_PAL_SERIAL | TCVR_PAL_EXTLBACK |480 TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE),481 tregs + TCVR_TPAL);482 sbus_readl(tregs + TCVR_TPAL);483 } else {484 printk(KERN_ERR "BIGMAC: AIEEE, neither internal nor "485 "external MDIO available!\n");486 printk(KERN_ERR "BIGMAC: mgmt_pal[%08x] tcvr_pal[%08x]\n",487 sbus_readl(tregs + TCVR_MPAL),488 sbus_readl(tregs + TCVR_TPAL));489 }490}491 492static int bigmac_init_hw(struct bigmac *, bool);493 494static int try_next_permutation(struct bigmac *bp, void __iomem *tregs)495{496 if (bp->sw_bmcr & BMCR_SPEED100) {497 int timeout;498 499 /* Reset the PHY. */500 bp->sw_bmcr = (BMCR_ISOLATE | BMCR_PDOWN | BMCR_LOOPBACK);501 bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr);502 bp->sw_bmcr = (BMCR_RESET);503 bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr);504 505 timeout = 64;506 while (--timeout) {507 bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR);508 if ((bp->sw_bmcr & BMCR_RESET) == 0)509 break;510 udelay(20);511 }512 if (timeout == 0)513 printk(KERN_ERR "%s: PHY reset failed.\n", bp->dev->name);514 515 bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR);516 517 /* Now we try 10baseT. */518 bp->sw_bmcr &= ~(BMCR_SPEED100);519 bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr);520 return 0;521 }522 523 /* We've tried them all. */524 return -1;525}526 527static void bigmac_timer(struct timer_list *t)528{529 struct bigmac *bp = from_timer(bp, t, bigmac_timer);530 void __iomem *tregs = bp->tregs;531 int restart_timer = 0;532 533 bp->timer_ticks++;534 if (bp->timer_state == ltrywait) {535 bp->sw_bmsr = bigmac_tcvr_read(bp, tregs, MII_BMSR);536 bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR);537 if (bp->sw_bmsr & BMSR_LSTATUS) {538 printk(KERN_INFO "%s: Link is now up at %s.\n",539 bp->dev->name,540 (bp->sw_bmcr & BMCR_SPEED100) ?541 "100baseT" : "10baseT");542 bp->timer_state = asleep;543 restart_timer = 0;544 } else {545 if (bp->timer_ticks >= 4) {546 int ret;547 548 ret = try_next_permutation(bp, tregs);549 if (ret == -1) {550 printk(KERN_ERR "%s: Link down, cable problem?\n",551 bp->dev->name);552 ret = bigmac_init_hw(bp, true);553 if (ret) {554 printk(KERN_ERR "%s: Error, cannot re-init the "555 "BigMAC.\n", bp->dev->name);556 }557 return;558 }559 bp->timer_ticks = 0;560 restart_timer = 1;561 } else {562 restart_timer = 1;563 }564 }565 } else {566 /* Can't happens.... */567 printk(KERN_ERR "%s: Aieee, link timer is asleep but we got one anyways!\n",568 bp->dev->name);569 restart_timer = 0;570 bp->timer_ticks = 0;571 bp->timer_state = asleep; /* foo on you */572 }573 574 if (restart_timer != 0) {575 bp->bigmac_timer.expires = jiffies + ((12 * HZ)/10); /* 1.2 sec. */576 add_timer(&bp->bigmac_timer);577 }578}579 580/* Well, really we just force the chip into 100baseT then581 * 10baseT, each time checking for a link status.582 */583static void bigmac_begin_auto_negotiation(struct bigmac *bp)584{585 void __iomem *tregs = bp->tregs;586 int timeout;587 588 /* Grab new software copies of PHY registers. */589 bp->sw_bmsr = bigmac_tcvr_read(bp, tregs, MII_BMSR);590 bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR);591 592 /* Reset the PHY. */593 bp->sw_bmcr = (BMCR_ISOLATE | BMCR_PDOWN | BMCR_LOOPBACK);594 bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr);595 bp->sw_bmcr = (BMCR_RESET);596 bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr);597 598 timeout = 64;599 while (--timeout) {600 bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR);601 if ((bp->sw_bmcr & BMCR_RESET) == 0)602 break;603 udelay(20);604 }605 if (timeout == 0)606 printk(KERN_ERR "%s: PHY reset failed.\n", bp->dev->name);607 608 bp->sw_bmcr = bigmac_tcvr_read(bp, tregs, MII_BMCR);609 610 /* First we try 100baseT. */611 bp->sw_bmcr |= BMCR_SPEED100;612 bigmac_tcvr_write(bp, tregs, MII_BMCR, bp->sw_bmcr);613 614 bp->timer_state = ltrywait;615 bp->timer_ticks = 0;616 bp->bigmac_timer.expires = jiffies + (12 * HZ) / 10;617 add_timer(&bp->bigmac_timer);618}619 620static int bigmac_init_hw(struct bigmac *bp, bool non_blocking)621{622 void __iomem *gregs = bp->gregs;623 void __iomem *cregs = bp->creg;624 void __iomem *bregs = bp->bregs;625 __u32 bblk_dvma = (__u32)bp->bblock_dvma;626 const unsigned char *e = &bp->dev->dev_addr[0];627 628 /* Latch current counters into statistics. */629 bigmac_get_counters(bp, bregs);630 631 /* Reset QEC. */632 qec_global_reset(gregs);633 634 /* Init QEC. */635 qec_init(bp);636 637 /* Alloc and reset the tx/rx descriptor chains. */638 bigmac_init_rings(bp, non_blocking);639 640 /* Initialize the PHY. */641 bigmac_tcvr_init(bp);642 643 /* Stop transmitter and receiver. */644 bigmac_stop(bp);645 646 /* Set hardware ethernet address. */647 sbus_writel(((e[4] << 8) | e[5]), bregs + BMAC_MACADDR2);648 sbus_writel(((e[2] << 8) | e[3]), bregs + BMAC_MACADDR1);649 sbus_writel(((e[0] << 8) | e[1]), bregs + BMAC_MACADDR0);650 651 /* Clear the hash table until mc upload occurs. */652 sbus_writel(0, bregs + BMAC_HTABLE3);653 sbus_writel(0, bregs + BMAC_HTABLE2);654 sbus_writel(0, bregs + BMAC_HTABLE1);655 sbus_writel(0, bregs + BMAC_HTABLE0);656 657 /* Enable Big Mac hash table filter. */658 sbus_writel(BIGMAC_RXCFG_HENABLE | BIGMAC_RXCFG_FIFO,659 bregs + BMAC_RXCFG);660 udelay(20);661 662 /* Ok, configure the Big Mac transmitter. */663 sbus_writel(BIGMAC_TXCFG_FIFO, bregs + BMAC_TXCFG);664 665 /* The HME docs recommend to use the 10LSB of our MAC here. */666 sbus_writel(((e[5] | e[4] << 8) & 0x3ff),667 bregs + BMAC_RSEED);668 669 /* Enable the output drivers no matter what. */670 sbus_writel(BIGMAC_XCFG_ODENABLE | BIGMAC_XCFG_RESV,671 bregs + BMAC_XIFCFG);672 673 /* Tell the QEC where the ring descriptors are. */674 sbus_writel(bblk_dvma + bib_offset(be_rxd, 0),675 cregs + CREG_RXDS);676 sbus_writel(bblk_dvma + bib_offset(be_txd, 0),677 cregs + CREG_TXDS);678 679 /* Setup the FIFO pointers into QEC local memory. */680 sbus_writel(0, cregs + CREG_RXRBUFPTR);681 sbus_writel(0, cregs + CREG_RXWBUFPTR);682 sbus_writel(sbus_readl(gregs + GLOB_RSIZE),683 cregs + CREG_TXRBUFPTR);684 sbus_writel(sbus_readl(gregs + GLOB_RSIZE),685 cregs + CREG_TXWBUFPTR);686 687 /* Tell bigmac what interrupts we don't want to hear about. */688 sbus_writel(BIGMAC_IMASK_GOTFRAME | BIGMAC_IMASK_SENTFRAME,689 bregs + BMAC_IMASK);690 691 /* Enable the various other irq's. */692 sbus_writel(0, cregs + CREG_RIMASK);693 sbus_writel(0, cregs + CREG_TIMASK);694 sbus_writel(0, cregs + CREG_QMASK);695 sbus_writel(0, cregs + CREG_BMASK);696 697 /* Set jam size to a reasonable default. */698 sbus_writel(DEFAULT_JAMSIZE, bregs + BMAC_JSIZE);699 700 /* Clear collision counter. */701 sbus_writel(0, cregs + CREG_CCNT);702 703 /* Enable transmitter and receiver. */704 sbus_writel(sbus_readl(bregs + BMAC_TXCFG) | BIGMAC_TXCFG_ENABLE,705 bregs + BMAC_TXCFG);706 sbus_writel(sbus_readl(bregs + BMAC_RXCFG) | BIGMAC_RXCFG_ENABLE,707 bregs + BMAC_RXCFG);708 709 /* Ok, start detecting link speed/duplex. */710 bigmac_begin_auto_negotiation(bp);711 712 /* Success. */713 return 0;714}715 716/* Error interrupts get sent here. */717static void bigmac_is_medium_rare(struct bigmac *bp, u32 qec_status, u32 bmac_status)718{719 printk(KERN_ERR "bigmac_is_medium_rare: ");720 if (qec_status & (GLOB_STAT_ER | GLOB_STAT_BM)) {721 if (qec_status & GLOB_STAT_ER)722 printk("QEC_ERROR, ");723 if (qec_status & GLOB_STAT_BM)724 printk("QEC_BMAC_ERROR, ");725 }726 if (bmac_status & CREG_STAT_ERRORS) {727 if (bmac_status & CREG_STAT_BERROR)728 printk("BMAC_ERROR, ");729 if (bmac_status & CREG_STAT_TXDERROR)730 printk("TXD_ERROR, ");731 if (bmac_status & CREG_STAT_TXLERR)732 printk("TX_LATE_ERROR, ");733 if (bmac_status & CREG_STAT_TXPERR)734 printk("TX_PARITY_ERROR, ");735 if (bmac_status & CREG_STAT_TXSERR)736 printk("TX_SBUS_ERROR, ");737 738 if (bmac_status & CREG_STAT_RXDROP)739 printk("RX_DROP_ERROR, ");740 741 if (bmac_status & CREG_STAT_RXSMALL)742 printk("RX_SMALL_ERROR, ");743 if (bmac_status & CREG_STAT_RXLERR)744 printk("RX_LATE_ERROR, ");745 if (bmac_status & CREG_STAT_RXPERR)746 printk("RX_PARITY_ERROR, ");747 if (bmac_status & CREG_STAT_RXSERR)748 printk("RX_SBUS_ERROR, ");749 }750 751 printk(" RESET\n");752 bigmac_init_hw(bp, true);753}754 755/* BigMAC transmit complete service routines. */756static void bigmac_tx(struct bigmac *bp)757{758 struct be_txd *txbase = &bp->bmac_block->be_txd[0];759 struct net_device *dev = bp->dev;760 int elem;761 762 spin_lock(&bp->lock);763 764 elem = bp->tx_old;765 DTX(("bigmac_tx: tx_old[%d] ", elem));766 while (elem != bp->tx_new) {767 struct sk_buff *skb;768 struct be_txd *this = &txbase[elem];769 770 DTX(("this(%p) [flags(%08x)addr(%08x)]",771 this, this->tx_flags, this->tx_addr));772 773 if (this->tx_flags & TXD_OWN)774 break;775 skb = bp->tx_skbs[elem];776 dev->stats.tx_packets++;777 dev->stats.tx_bytes += skb->len;778 dma_unmap_single(&bp->bigmac_op->dev,779 this->tx_addr, skb->len,780 DMA_TO_DEVICE);781 782 DTX(("skb(%p) ", skb));783 bp->tx_skbs[elem] = NULL;784 dev_consume_skb_irq(skb);785 786 elem = NEXT_TX(elem);787 }788 DTX((" DONE, tx_old=%d\n", elem));789 bp->tx_old = elem;790 791 if (netif_queue_stopped(dev) &&792 TX_BUFFS_AVAIL(bp) > 0)793 netif_wake_queue(bp->dev);794 795 spin_unlock(&bp->lock);796}797 798/* BigMAC receive complete service routines. */799static void bigmac_rx(struct bigmac *bp)800{801 struct be_rxd *rxbase = &bp->bmac_block->be_rxd[0];802 struct be_rxd *this;803 int elem = bp->rx_new, drops = 0;804 u32 flags;805 806 this = &rxbase[elem];807 while (!((flags = this->rx_flags) & RXD_OWN)) {808 struct sk_buff *skb;809 int len = (flags & RXD_LENGTH); /* FCS not included */810 811 /* Check for errors. */812 if (len < ETH_ZLEN) {813 bp->dev->stats.rx_errors++;814 bp->dev->stats.rx_length_errors++;815 816 drop_it:817 /* Return it to the BigMAC. */818 bp->dev->stats.rx_dropped++;819 this->rx_flags =820 (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));821 goto next;822 }823 skb = bp->rx_skbs[elem];824 if (len > RX_COPY_THRESHOLD) {825 struct sk_buff *new_skb;826 827 /* Now refill the entry, if we can. */828 new_skb = big_mac_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);829 if (new_skb == NULL) {830 drops++;831 goto drop_it;832 }833 dma_unmap_single(&bp->bigmac_op->dev,834 this->rx_addr,835 RX_BUF_ALLOC_SIZE - 34,836 DMA_FROM_DEVICE);837 bp->rx_skbs[elem] = new_skb;838 skb_put(new_skb, ETH_FRAME_LEN);839 skb_reserve(new_skb, 34);840 this->rx_addr =841 dma_map_single(&bp->bigmac_op->dev,842 new_skb->data,843 RX_BUF_ALLOC_SIZE - 34,844 DMA_FROM_DEVICE);845 this->rx_flags =846 (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));847 848 /* Trim the original skb for the netif. */849 skb_trim(skb, len);850 } else {851 struct sk_buff *copy_skb = netdev_alloc_skb(bp->dev, len + 2);852 853 if (copy_skb == NULL) {854 drops++;855 goto drop_it;856 }857 skb_reserve(copy_skb, 2);858 skb_put(copy_skb, len);859 dma_sync_single_for_cpu(&bp->bigmac_op->dev,860 this->rx_addr, len,861 DMA_FROM_DEVICE);862 skb_copy_to_linear_data(copy_skb, (unsigned char *)skb->data, len);863 dma_sync_single_for_device(&bp->bigmac_op->dev,864 this->rx_addr, len,865 DMA_FROM_DEVICE);866 867 /* Reuse original ring buffer. */868 this->rx_flags =869 (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));870 871 skb = copy_skb;872 }873 874 /* No checksums done by the BigMAC ;-( */875 skb->protocol = eth_type_trans(skb, bp->dev);876 netif_rx(skb);877 bp->dev->stats.rx_packets++;878 bp->dev->stats.rx_bytes += len;879 next:880 elem = NEXT_RX(elem);881 this = &rxbase[elem];882 }883 bp->rx_new = elem;884 if (drops)885 printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", bp->dev->name);886}887 888static irqreturn_t bigmac_interrupt(int irq, void *dev_id)889{890 struct bigmac *bp = (struct bigmac *) dev_id;891 u32 qec_status, bmac_status;892 893 DIRQ(("bigmac_interrupt: "));894 895 /* Latch status registers now. */896 bmac_status = sbus_readl(bp->creg + CREG_STAT);897 qec_status = sbus_readl(bp->gregs + GLOB_STAT);898 899 DIRQ(("qec_status=%08x bmac_status=%08x\n", qec_status, bmac_status));900 if ((qec_status & (GLOB_STAT_ER | GLOB_STAT_BM)) ||901 (bmac_status & CREG_STAT_ERRORS))902 bigmac_is_medium_rare(bp, qec_status, bmac_status);903 904 if (bmac_status & CREG_STAT_TXIRQ)905 bigmac_tx(bp);906 907 if (bmac_status & CREG_STAT_RXIRQ)908 bigmac_rx(bp);909 910 return IRQ_HANDLED;911}912 913static int bigmac_open(struct net_device *dev)914{915 struct bigmac *bp = netdev_priv(dev);916 int ret;917 918 ret = request_irq(dev->irq, bigmac_interrupt, IRQF_SHARED, dev->name, bp);919 if (ret) {920 printk(KERN_ERR "BIGMAC: Can't order irq %d to go.\n", dev->irq);921 return ret;922 }923 timer_setup(&bp->bigmac_timer, bigmac_timer, 0);924 ret = bigmac_init_hw(bp, false);925 if (ret)926 free_irq(dev->irq, bp);927 return ret;928}929 930static int bigmac_close(struct net_device *dev)931{932 struct bigmac *bp = netdev_priv(dev);933 934 del_timer(&bp->bigmac_timer);935 bp->timer_state = asleep;936 bp->timer_ticks = 0;937 938 bigmac_stop(bp);939 bigmac_clean_rings(bp);940 free_irq(dev->irq, bp);941 return 0;942}943 944static void bigmac_tx_timeout(struct net_device *dev, unsigned int txqueue)945{946 struct bigmac *bp = netdev_priv(dev);947 948 bigmac_init_hw(bp, true);949 netif_wake_queue(dev);950}951 952/* Put a packet on the wire. */953static netdev_tx_t954bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)955{956 struct bigmac *bp = netdev_priv(dev);957 int len, entry;958 u32 mapping;959 960 len = skb->len;961 mapping = dma_map_single(&bp->bigmac_op->dev, skb->data,962 len, DMA_TO_DEVICE);963 964 /* Avoid a race... */965 spin_lock_irq(&bp->lock);966 entry = bp->tx_new;967 DTX(("bigmac_start_xmit: len(%d) entry(%d)\n", len, entry));968 bp->bmac_block->be_txd[entry].tx_flags = TXD_UPDATE;969 bp->tx_skbs[entry] = skb;970 bp->bmac_block->be_txd[entry].tx_addr = mapping;971 bp->bmac_block->be_txd[entry].tx_flags =972 (TXD_OWN | TXD_SOP | TXD_EOP | (len & TXD_LENGTH));973 bp->tx_new = NEXT_TX(entry);974 if (TX_BUFFS_AVAIL(bp) <= 0)975 netif_stop_queue(dev);976 spin_unlock_irq(&bp->lock);977 978 /* Get it going. */979 sbus_writel(CREG_CTRL_TWAKEUP, bp->creg + CREG_CTRL);980 981 982 return NETDEV_TX_OK;983}984 985static struct net_device_stats *bigmac_get_stats(struct net_device *dev)986{987 struct bigmac *bp = netdev_priv(dev);988 989 bigmac_get_counters(bp, bp->bregs);990 return &dev->stats;991}992 993static void bigmac_set_multicast(struct net_device *dev)994{995 struct bigmac *bp = netdev_priv(dev);996 void __iomem *bregs = bp->bregs;997 struct netdev_hw_addr *ha;998 u32 tmp, crc;999 1000 /* Disable the receiver. The bit self-clears when1001 * the operation is complete.1002 */1003 tmp = sbus_readl(bregs + BMAC_RXCFG);1004 tmp &= ~(BIGMAC_RXCFG_ENABLE);1005 sbus_writel(tmp, bregs + BMAC_RXCFG);1006 while ((sbus_readl(bregs + BMAC_RXCFG) & BIGMAC_RXCFG_ENABLE) != 0)1007 udelay(20);1008 1009 if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {1010 sbus_writel(0xffff, bregs + BMAC_HTABLE0);1011 sbus_writel(0xffff, bregs + BMAC_HTABLE1);1012 sbus_writel(0xffff, bregs + BMAC_HTABLE2);1013 sbus_writel(0xffff, bregs + BMAC_HTABLE3);1014 } else if (dev->flags & IFF_PROMISC) {1015 tmp = sbus_readl(bregs + BMAC_RXCFG);1016 tmp |= BIGMAC_RXCFG_PMISC;1017 sbus_writel(tmp, bregs + BMAC_RXCFG);1018 } else {1019 u16 hash_table[4] = { 0 };1020 1021 netdev_for_each_mc_addr(ha, dev) {1022 crc = ether_crc_le(6, ha->addr);1023 crc >>= 26;1024 hash_table[crc >> 4] |= 1 << (crc & 0xf);1025 }1026 sbus_writel(hash_table[0], bregs + BMAC_HTABLE0);1027 sbus_writel(hash_table[1], bregs + BMAC_HTABLE1);1028 sbus_writel(hash_table[2], bregs + BMAC_HTABLE2);1029 sbus_writel(hash_table[3], bregs + BMAC_HTABLE3);1030 }1031 1032 /* Re-enable the receiver. */1033 tmp = sbus_readl(bregs + BMAC_RXCFG);1034 tmp |= BIGMAC_RXCFG_ENABLE;1035 sbus_writel(tmp, bregs + BMAC_RXCFG);1036}1037 1038/* Ethtool support... */1039static void bigmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)1040{1041 strscpy(info->driver, "sunbmac", sizeof(info->driver));1042 strscpy(info->version, "2.0", sizeof(info->version));1043}1044 1045static u32 bigmac_get_link(struct net_device *dev)1046{1047 struct bigmac *bp = netdev_priv(dev);1048 1049 spin_lock_irq(&bp->lock);1050 bp->sw_bmsr = bigmac_tcvr_read(bp, bp->tregs, MII_BMSR);1051 spin_unlock_irq(&bp->lock);1052 1053 return (bp->sw_bmsr & BMSR_LSTATUS);1054}1055 1056static const struct ethtool_ops bigmac_ethtool_ops = {1057 .get_drvinfo = bigmac_get_drvinfo,1058 .get_link = bigmac_get_link,1059};1060 1061static const struct net_device_ops bigmac_ops = {1062 .ndo_open = bigmac_open,1063 .ndo_stop = bigmac_close,1064 .ndo_start_xmit = bigmac_start_xmit,1065 .ndo_get_stats = bigmac_get_stats,1066 .ndo_set_rx_mode = bigmac_set_multicast,1067 .ndo_tx_timeout = bigmac_tx_timeout,1068 .ndo_set_mac_address = eth_mac_addr,1069 .ndo_validate_addr = eth_validate_addr,1070};1071 1072static int bigmac_ether_init(struct platform_device *op,1073 struct platform_device *qec_op)1074{1075 static int version_printed;1076 struct net_device *dev;1077 u8 bsizes, bsizes_more;1078 struct bigmac *bp;1079 1080 /* Get a new device struct for this interface. */1081 dev = alloc_etherdev(sizeof(struct bigmac));1082 if (!dev)1083 return -ENOMEM;1084 1085 if (version_printed++ == 0)1086 printk(KERN_INFO "%s", version);1087 1088 eth_hw_addr_set(dev, idprom->id_ethaddr);1089 1090 /* Setup softc, with backpointers to QEC and BigMAC SBUS device structs. */1091 bp = netdev_priv(dev);1092 bp->qec_op = qec_op;1093 bp->bigmac_op = op;1094 1095 SET_NETDEV_DEV(dev, &op->dev);1096 1097 spin_lock_init(&bp->lock);1098 1099 /* Map in QEC global control registers. */1100 bp->gregs = of_ioremap(&qec_op->resource[0], 0,1101 GLOB_REG_SIZE, "BigMAC QEC GLobal Regs");1102 if (!bp->gregs) {1103 printk(KERN_ERR "BIGMAC: Cannot map QEC global registers.\n");1104 goto fail_and_cleanup;1105 }1106 1107 /* Make sure QEC is in BigMAC mode. */1108 if ((sbus_readl(bp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_BMODE) {1109 printk(KERN_ERR "BigMAC: AIEEE, QEC is not in BigMAC mode!\n");1110 goto fail_and_cleanup;1111 }1112 1113 /* Reset the QEC. */1114 if (qec_global_reset(bp->gregs))1115 goto fail_and_cleanup;1116 1117 /* Get supported SBUS burst sizes. */1118 bsizes = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff);1119 bsizes_more = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff);1120 1121 bsizes &= 0xff;1122 if (bsizes_more != 0xff)1123 bsizes &= bsizes_more;1124 if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 ||1125 (bsizes & DMA_BURST32) == 0)1126 bsizes = (DMA_BURST32 - 1);1127 bp->bigmac_bursts = bsizes;1128 1129 /* Perform QEC initialization. */1130 qec_init(bp);1131 1132 /* Map in the BigMAC channel registers. */1133 bp->creg = of_ioremap(&op->resource[0], 0,1134 CREG_REG_SIZE, "BigMAC QEC Channel Regs");1135 if (!bp->creg) {1136 printk(KERN_ERR "BIGMAC: Cannot map QEC channel registers.\n");1137 goto fail_and_cleanup;1138 }1139 1140 /* Map in the BigMAC control registers. */1141 bp->bregs = of_ioremap(&op->resource[1], 0,1142 BMAC_REG_SIZE, "BigMAC Primary Regs");1143 if (!bp->bregs) {1144 printk(KERN_ERR "BIGMAC: Cannot map BigMAC primary registers.\n");1145 goto fail_and_cleanup;1146 }1147 1148 /* Map in the BigMAC transceiver registers, this is how you poke at1149 * the BigMAC's PHY.1150 */1151 bp->tregs = of_ioremap(&op->resource[2], 0,1152 TCVR_REG_SIZE, "BigMAC Transceiver Regs");1153 if (!bp->tregs) {1154 printk(KERN_ERR "BIGMAC: Cannot map BigMAC transceiver registers.\n");1155 goto fail_and_cleanup;1156 }1157 1158 /* Stop the BigMAC. */1159 bigmac_stop(bp);1160 1161 /* Allocate transmit/receive descriptor DVMA block. */1162 bp->bmac_block = dma_alloc_coherent(&bp->bigmac_op->dev,1163 PAGE_SIZE,1164 &bp->bblock_dvma, GFP_ATOMIC);1165 if (bp->bmac_block == NULL || bp->bblock_dvma == 0)1166 goto fail_and_cleanup;1167 1168 /* Get the board revision of this BigMAC. */1169 bp->board_rev = of_getintprop_default(bp->bigmac_op->dev.of_node,1170 "board-version", 1);1171 1172 /* Init auto-negotiation timer state. */1173 timer_setup(&bp->bigmac_timer, bigmac_timer, 0);1174 bp->timer_state = asleep;1175 bp->timer_ticks = 0;1176 1177 /* Backlink to generic net device struct. */1178 bp->dev = dev;1179 1180 /* Set links to our BigMAC open and close routines. */1181 dev->ethtool_ops = &bigmac_ethtool_ops;1182 dev->netdev_ops = &bigmac_ops;1183 dev->watchdog_timeo = 5*HZ;1184 1185 /* Finish net device registration. */1186 dev->irq = bp->bigmac_op->archdata.irqs[0];1187 dev->dma = 0;1188 1189 if (register_netdev(dev)) {1190 printk(KERN_ERR "BIGMAC: Cannot register device.\n");1191 goto fail_and_cleanup;1192 }1193 1194 dev_set_drvdata(&bp->bigmac_op->dev, bp);1195 1196 printk(KERN_INFO "%s: BigMAC 100baseT Ethernet %pM\n",1197 dev->name, dev->dev_addr);1198 1199 return 0;1200 1201fail_and_cleanup:1202 /* Something went wrong, undo whatever we did so far. */1203 /* Free register mappings if any. */1204 if (bp->gregs)1205 of_iounmap(&qec_op->resource[0], bp->gregs, GLOB_REG_SIZE);1206 if (bp->creg)1207 of_iounmap(&op->resource[0], bp->creg, CREG_REG_SIZE);1208 if (bp->bregs)1209 of_iounmap(&op->resource[1], bp->bregs, BMAC_REG_SIZE);1210 if (bp->tregs)1211 of_iounmap(&op->resource[2], bp->tregs, TCVR_REG_SIZE);1212 1213 if (bp->bmac_block)1214 dma_free_coherent(&bp->bigmac_op->dev,1215 PAGE_SIZE,1216 bp->bmac_block,1217 bp->bblock_dvma);1218 1219 /* This also frees the co-located private data */1220 free_netdev(dev);1221 return -ENODEV;1222}1223 1224/* QEC can be the parent of either QuadEthernet or a BigMAC. We want1225 * the latter.1226 */1227static int bigmac_sbus_probe(struct platform_device *op)1228{1229 struct device *parent = op->dev.parent;1230 struct platform_device *qec_op;1231 1232 qec_op = to_platform_device(parent);1233 1234 return bigmac_ether_init(op, qec_op);1235}1236 1237static void bigmac_sbus_remove(struct platform_device *op)1238{1239 struct bigmac *bp = platform_get_drvdata(op);1240 struct device *parent = op->dev.parent;1241 struct net_device *net_dev = bp->dev;1242 struct platform_device *qec_op;1243 1244 qec_op = to_platform_device(parent);1245 1246 unregister_netdev(net_dev);1247 1248 of_iounmap(&qec_op->resource[0], bp->gregs, GLOB_REG_SIZE);1249 of_iounmap(&op->resource[0], bp->creg, CREG_REG_SIZE);1250 of_iounmap(&op->resource[1], bp->bregs, BMAC_REG_SIZE);1251 of_iounmap(&op->resource[2], bp->tregs, TCVR_REG_SIZE);1252 dma_free_coherent(&op->dev,1253 PAGE_SIZE,1254 bp->bmac_block,1255 bp->bblock_dvma);1256 1257 free_netdev(net_dev);1258}1259 1260static const struct of_device_id bigmac_sbus_match[] = {1261 {1262 .name = "be",1263 },1264 {},1265};1266 1267MODULE_DEVICE_TABLE(of, bigmac_sbus_match);1268 1269static struct platform_driver bigmac_sbus_driver = {1270 .driver = {1271 .name = "sunbmac",1272 .of_match_table = bigmac_sbus_match,1273 },1274 .probe = bigmac_sbus_probe,1275 .remove_new = bigmac_sbus_remove,1276};1277 1278module_platform_driver(bigmac_sbus_driver);1279