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