--- zzzz-none-000/linux-3.10.107/drivers/net/ethernet/smsc/smc91x.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/net/ethernet/smsc/smc91x.c 2021-02-04 17:41:59.000000000 +0000 @@ -19,8 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . * * Arguments: * io = for the base address @@ -58,7 +57,7 @@ * 22/09/04 Nicolas Pitre big update (see commit log for details) */ static const char version[] = - "smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre \n"; + "smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre "; /* Debugging level */ #ifndef SMC_DEBUG @@ -66,7 +65,6 @@ #endif -#include #include #include #include @@ -82,6 +80,8 @@ #include #include #include +#include +#include #include #include @@ -91,6 +91,11 @@ #include "smc91x.h" +#if defined(CONFIG_ASSABET_NEPONSET) +#include +#include +#endif + #ifndef SMC_NOWAIT # define SMC_NOWAIT 0 #endif @@ -148,18 +153,19 @@ */ #define MII_DELAY 1 -#if SMC_DEBUG > 0 -#define DBG(n, args...) \ - do { \ - if (SMC_DEBUG >= (n)) \ - printk(args); \ +#define DBG(n, dev, fmt, ...) \ + do { \ + if (SMC_DEBUG >= (n)) \ + netdev_dbg(dev, fmt, ##__VA_ARGS__); \ } while (0) -#define PRINTK(args...) printk(args) -#else -#define DBG(n, args...) do { } while(0) -#define PRINTK(args...) printk(KERN_DEBUG args) -#endif +#define PRINTK(dev, fmt, ...) \ + do { \ + if (SMC_DEBUG > 0) \ + netdev_info(dev, fmt, ##__VA_ARGS__); \ + else \ + netdev_dbg(dev, fmt, ##__VA_ARGS__); \ + } while (0) #if SMC_DEBUG > 3 static void PRINT_PKT(u_char *buf, int length) @@ -173,24 +179,26 @@ for (i = 0; i < lines ; i ++) { int cur; + printk(KERN_DEBUG); for (cur = 0; cur < 8; cur++) { u_char a, b; a = *buf++; b = *buf++; - printk("%02x%02x ", a, b); + pr_cont("%02x%02x ", a, b); } - printk("\n"); + pr_cont("\n"); } + printk(KERN_DEBUG); for (i = 0; i < remainder/2 ; i++) { u_char a, b; a = *buf++; b = *buf++; - printk("%02x%02x ", a, b); + pr_cont("%02x%02x ", a, b); } - printk("\n"); + pr_cont("\n"); } #else -#define PRINT_PKT(x...) do { } while(0) +static inline void PRINT_PKT(u_char *buf, int length) { } #endif @@ -226,8 +234,8 @@ unsigned long timeout = jiffies + 2; \ while (SMC_GET_MMU_CMD(lp) & MC_BUSY) { \ if (time_after(jiffies, timeout)) { \ - printk("%s: timeout %s line %d\n", \ - dev->name, __FILE__, __LINE__); \ + netdev_dbg(dev, "timeout %s line %d\n", \ + __FILE__, __LINE__); \ break; \ } \ cpu_relax(); \ @@ -246,7 +254,7 @@ unsigned int ctl, cfg; struct sk_buff *pending_skb; - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); /* Disable all interrupts, block TX tasklet */ spin_lock_irq(&lp->lock); @@ -339,7 +347,7 @@ void __iomem *ioaddr = lp->base; int mask; - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); /* see the header file for options in TCR/RCR DEFAULT */ SMC_SELECT_BANK(lp, 0); @@ -373,7 +381,7 @@ void __iomem *ioaddr = lp->base; struct sk_buff *pending_skb; - DBG(2, "%s: %s\n", CARDNAME, __func__); + DBG(2, dev, "%s: %s\n", CARDNAME, __func__); /* no more interrupts for me */ spin_lock_irq(&lp->lock); @@ -406,11 +414,11 @@ void __iomem *ioaddr = lp->base; unsigned int packet_number, status, packet_len; - DBG(3, "%s: %s\n", dev->name, __func__); + DBG(3, dev, "%s\n", __func__); packet_number = SMC_GET_RXFIFO(lp); if (unlikely(packet_number & RXFIFO_REMPTY)) { - PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name); + PRINTK(dev, "smc_rcv with nothing on FIFO.\n"); return; } @@ -420,9 +428,8 @@ /* First two words are status and packet length */ SMC_GET_PKT_HDR(lp, status, packet_len); packet_len &= 0x07ff; /* mask off top bits */ - DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", - dev->name, packet_number, status, - packet_len, packet_len); + DBG(2, dev, "RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", + packet_number, status, packet_len, packet_len); back: if (unlikely(packet_len < 6 || status & RS_ERRORS)) { @@ -433,8 +440,8 @@ } if (packet_len < 6) { /* bloody hardware */ - printk(KERN_ERR "%s: fubar (rxlen %u status %x\n", - dev->name, packet_len, status); + netdev_err(dev, "fubar (rxlen %u status %x\n", + packet_len, status); status |= RS_TOOSHORT; } SMC_WAIT_MMU_BUSY(lp); @@ -533,7 +540,7 @@ #define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags) #define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) #else -#define smc_special_trylock(lock, flags) (flags == flags) +#define smc_special_trylock(lock, flags) ((void)flags, true) #define smc_special_lock(lock, flags) do { flags = 0; } while (0) #define smc_special_unlock(lock, flags) do { flags = 0; } while (0) #endif @@ -551,7 +558,7 @@ unsigned char *buf; unsigned long flags; - DBG(3, "%s: %s\n", dev->name, __func__); + DBG(3, dev, "%s\n", __func__); if (!smc_special_trylock(&lp->lock, flags)) { netif_stop_queue(dev); @@ -568,7 +575,7 @@ packet_no = SMC_GET_AR(lp); if (unlikely(packet_no & AR_FAILED)) { - printk("%s: Memory allocation failed.\n", dev->name); + netdev_err(dev, "Memory allocation failed.\n"); dev->stats.tx_errors++; dev->stats.tx_fifo_errors++; smc_special_unlock(&lp->lock, flags); @@ -581,8 +588,8 @@ buf = skb->data; len = skb->len; - DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n", - dev->name, packet_no, len, len, buf); + DBG(2, dev, "TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n", + packet_no, len, len, buf); PRINT_PKT(buf, len); /* @@ -621,7 +628,7 @@ done: if (!THROTTLE_TX_PKTS) netif_wake_queue(dev); - dev_kfree_skb(skb); + dev_consume_skb_any(skb); } /* @@ -637,7 +644,7 @@ unsigned int numPages, poll_count, status; unsigned long flags; - DBG(3, "%s: %s\n", dev->name, __func__); + DBG(3, dev, "%s\n", __func__); BUG_ON(lp->pending_tx_skb != NULL); @@ -654,10 +661,10 @@ */ numPages = ((skb->len & ~1) + (6 - 1)) >> 8; if (unlikely(numPages > 7)) { - printk("%s: Far too big packet error.\n", dev->name); + netdev_warn(dev, "Far too big packet error.\n"); dev->stats.tx_errors++; dev->stats.tx_dropped++; - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } @@ -685,7 +692,7 @@ if (!poll_count) { /* oh well, wait until the chip finds memory later */ netif_stop_queue(dev); - DBG(2, "%s: TX memory allocation deferred.\n", dev->name); + DBG(2, dev, "TX memory allocation deferred.\n"); SMC_ENABLE_INT(lp, IM_ALLOC_INT); } else { /* @@ -709,12 +716,12 @@ void __iomem *ioaddr = lp->base; unsigned int saved_packet, packet_no, tx_status, pkt_len; - DBG(3, "%s: %s\n", dev->name, __func__); + DBG(3, dev, "%s\n", __func__); /* If the TX FIFO is empty then nothing to do */ packet_no = SMC_GET_TXFIFO(lp); if (unlikely(packet_no & TXFIFO_TEMPTY)) { - PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name); + PRINTK(dev, "smc_tx with nothing on FIFO.\n"); return; } @@ -725,8 +732,8 @@ /* read the first word (status word) from this packet */ SMC_SET_PTR(lp, PTR_AUTOINC | PTR_READ); SMC_GET_PKT_HDR(lp, tx_status, pkt_len); - DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n", - dev->name, tx_status, packet_no); + DBG(2, dev, "TX STATUS 0x%04x PNR 0x%02x\n", + tx_status, packet_no); if (!(tx_status & ES_TX_SUC)) dev->stats.tx_errors++; @@ -735,14 +742,12 @@ dev->stats.tx_carrier_errors++; if (tx_status & (ES_LATCOL | ES_16COL)) { - PRINTK("%s: %s occurred on last xmit\n", dev->name, + PRINTK(dev, "%s occurred on last xmit\n", (tx_status & ES_LATCOL) ? "late collision" : "too many collisions"); dev->stats.tx_window_errors++; if (!(dev->stats.tx_window_errors & 63) && net_ratelimit()) { - printk(KERN_INFO "%s: unexpectedly large number of " - "bad collisions. Please check duplex " - "setting.\n", dev->name); + netdev_info(dev, "unexpectedly large number of bad collisions. Please check duplex setting.\n"); } } @@ -830,8 +835,8 @@ /* Return to idle state */ SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); - DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", - __func__, phyaddr, phyreg, phydata); + DBG(3, dev, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", + __func__, phyaddr, phyreg, phydata); SMC_SELECT_BANK(lp, 2); return phydata; @@ -857,8 +862,8 @@ /* Return to idle state */ SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); - DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", - __func__, phyaddr, phyreg, phydata); + DBG(3, dev, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", + __func__, phyaddr, phyreg, phydata); SMC_SELECT_BANK(lp, 2); } @@ -871,7 +876,7 @@ struct smc_local *lp = netdev_priv(dev); int phyaddr; - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); lp->phy_type = 0; @@ -886,8 +891,8 @@ id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1); id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2); - DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", - dev->name, id1, id2); + DBG(3, dev, "phy_id1=0x%x, phy_id2=0x%x\n", + id1, id2); /* Make sure it is a valid identifier */ if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 && @@ -910,7 +915,7 @@ int phyaddr = lp->mii.phy_id; int bmcr, cfg1; - DBG(3, "%s: %s\n", dev->name, __func__); + DBG(3, dev, "%s\n", __func__); /* Enter Link Disable state */ cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG); @@ -1044,7 +1049,7 @@ int my_ad_caps; /* My Advertised capabilities */ int status; - DBG(3, "%s:smc_program_phy()\n", dev->name); + DBG(3, dev, "smc_program_phy()\n"); spin_lock_irq(&lp->lock); @@ -1055,7 +1060,7 @@ goto smc_phy_configure_exit; if (smc_phy_reset(dev, phyaddr)) { - printk("%s: PHY reset timed out\n", dev->name); + netdev_info(dev, "PHY reset timed out\n"); goto smc_phy_configure_exit; } @@ -1082,7 +1087,7 @@ my_phy_caps = smc_phy_read(dev, phyaddr, MII_BMSR); if (!(my_phy_caps & BMSR_ANEGCAPABLE)) { - printk(KERN_INFO "Auto negotiation NOT supported\n"); + netdev_info(dev, "Auto negotiation NOT supported\n"); smc_phy_fixed(dev); goto smc_phy_configure_exit; } @@ -1118,8 +1123,8 @@ */ status = smc_phy_read(dev, phyaddr, MII_ADVERTISE); - DBG(2, "%s: phy caps=%x\n", dev->name, my_phy_caps); - DBG(2, "%s: phy advertised caps=%x\n", dev->name, my_ad_caps); + DBG(2, dev, "phy caps=%x\n", my_phy_caps); + DBG(2, dev, "phy advertised caps=%x\n", my_ad_caps); /* Restart auto-negotiation process in order to advertise my caps */ smc_phy_write(dev, phyaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); @@ -1143,7 +1148,7 @@ int phyaddr = lp->mii.phy_id; int phy18; - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); if (lp->phy_type == 0) return; @@ -1179,8 +1184,8 @@ netif_carrier_on(dev); } if (netif_msg_link(lp)) - printk(KERN_INFO "%s: link %s\n", dev->name, - new_carrier ? "up" : "down"); + netdev_info(dev, "link %s\n", + new_carrier ? "up" : "down"); } } @@ -1211,7 +1216,7 @@ int status, mask, timeout, card_stats; int saved_pointer; - DBG(3, "%s: %s\n", dev->name, __func__); + DBG(3, dev, "%s\n", __func__); spin_lock(&lp->lock); @@ -1230,12 +1235,12 @@ do { status = SMC_GET_INT(lp); - DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", - dev->name, status, mask, - ({ int meminfo; SMC_SELECT_BANK(lp, 0); - meminfo = SMC_GET_MIR(lp); - SMC_SELECT_BANK(lp, 2); meminfo; }), - SMC_GET_FIFO(lp)); + DBG(2, dev, "INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", + status, mask, + ({ int meminfo; SMC_SELECT_BANK(lp, 0); + meminfo = SMC_GET_MIR(lp); + SMC_SELECT_BANK(lp, 2); meminfo; }), + SMC_GET_FIFO(lp)); status &= mask; if (!status) @@ -1243,20 +1248,20 @@ if (status & IM_TX_INT) { /* do this before RX as it will free memory quickly */ - DBG(3, "%s: TX int\n", dev->name); + DBG(3, dev, "TX int\n"); smc_tx(dev); SMC_ACK_INT(lp, IM_TX_INT); if (THROTTLE_TX_PKTS) netif_wake_queue(dev); } else if (status & IM_RCV_INT) { - DBG(3, "%s: RX irq\n", dev->name); + DBG(3, dev, "RX irq\n"); smc_rcv(dev); } else if (status & IM_ALLOC_INT) { - DBG(3, "%s: Allocation irq\n", dev->name); + DBG(3, dev, "Allocation irq\n"); tasklet_hi_schedule(&lp->tx_task); mask &= ~IM_ALLOC_INT; } else if (status & IM_TX_EMPTY_INT) { - DBG(3, "%s: TX empty\n", dev->name); + DBG(3, dev, "TX empty\n"); mask &= ~IM_TX_EMPTY_INT; /* update stats */ @@ -1271,10 +1276,10 @@ /* multiple collisions */ dev->stats.collisions += card_stats & 0xF; } else if (status & IM_RX_OVRN_INT) { - DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, - ({ int eph_st; SMC_SELECT_BANK(lp, 0); - eph_st = SMC_GET_EPH_STATUS(lp); - SMC_SELECT_BANK(lp, 2); eph_st; })); + DBG(1, dev, "RX overrun (EPH_ST 0x%04x)\n", + ({ int eph_st; SMC_SELECT_BANK(lp, 0); + eph_st = SMC_GET_EPH_STATUS(lp); + SMC_SELECT_BANK(lp, 2); eph_st; })); SMC_ACK_INT(lp, IM_RX_OVRN_INT); dev->stats.rx_errors++; dev->stats.rx_fifo_errors++; @@ -1285,7 +1290,7 @@ smc_phy_interrupt(dev); } else if (status & IM_ERCV_INT) { SMC_ACK_INT(lp, IM_ERCV_INT); - PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT\n", dev->name); + PRINTK(dev, "UNSUPPORTED: ERCV INTERRUPT\n"); } } while (--timeout); @@ -1296,11 +1301,11 @@ #ifndef CONFIG_NET_POLL_CONTROLLER if (timeout == MAX_IRQ_LOOPS) - PRINTK("%s: spurious interrupt (mask = 0x%02x)\n", - dev->name, mask); + PRINTK(dev, "spurious interrupt (mask = 0x%02x)\n", + mask); #endif - DBG(3, "%s: Interrupt done (%d loops)\n", - dev->name, MAX_IRQ_LOOPS - timeout); + DBG(3, dev, "Interrupt done (%d loops)\n", + MAX_IRQ_LOOPS - timeout); /* * We return IRQ_HANDLED unconditionally here even if there was @@ -1333,7 +1338,7 @@ void __iomem *ioaddr = lp->base; int status, mask, eph_st, meminfo, fifo; - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); spin_lock_irq(&lp->lock); status = SMC_GET_INT(lp); @@ -1344,9 +1349,8 @@ meminfo = SMC_GET_MIR(lp); SMC_SELECT_BANK(lp, 2); spin_unlock_irq(&lp->lock); - PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x " - "MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n", - dev->name, status, mask, meminfo, fifo, eph_st ); + PRINTK(dev, "TX timeout (INT 0x%02x INTMASK 0x%02x MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n", + status, mask, meminfo, fifo, eph_st); smc_reset(dev); smc_enable(dev); @@ -1377,10 +1381,10 @@ unsigned char multicast_table[8]; int update_multicast = 0; - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); if (dev->flags & IFF_PROMISC) { - DBG(2, "%s: RCR_PRMS\n", dev->name); + DBG(2, dev, "RCR_PRMS\n"); lp->rcr_cur_mode |= RCR_PRMS; } @@ -1395,7 +1399,7 @@ * checked before the table is */ else if (dev->flags & IFF_ALLMULTI || netdev_mc_count(dev) > 16) { - DBG(2, "%s: RCR_ALMUL\n", dev->name); + DBG(2, dev, "RCR_ALMUL\n"); lp->rcr_cur_mode |= RCR_ALMUL; } @@ -1437,7 +1441,7 @@ /* now, the table can be loaded into the chipset */ update_multicast = 1; } else { - DBG(2, "%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name); + DBG(2, dev, "~(RCR_PRMS|RCR_ALMUL)\n"); lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); /* @@ -1470,7 +1474,7 @@ { struct smc_local *lp = netdev_priv(dev); - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); /* Setup the default Register Modes */ lp->tcr_cur_mode = TCR_DEFAULT; @@ -1514,7 +1518,7 @@ { struct smc_local *lp = netdev_priv(dev); - DBG(2, "%s: %s\n", dev->name, __func__); + DBG(2, dev, "%s\n", __func__); netif_stop_queue(dev); netif_carrier_off(dev); @@ -1694,7 +1698,7 @@ int i; int imax; - DBG(1, "Reading %d bytes at %d(0x%x)\n", + DBG(1, dev, "Reading %d bytes at %d(0x%x)\n", eeprom->len, eeprom->offset, eeprom->offset); imax = smc_ethtool_geteeprom_len(dev); for (i = 0; i < eeprom->len; i += 2) { @@ -1706,7 +1710,7 @@ ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf); if (ret != 0) return ret; - DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1); + DBG(2, dev, "Read 0x%x from 0x%x\n", wbuf, offset >> 1); data[i] = (wbuf >> 8) & 0xff; data[i+1] = wbuf & 0xff; } @@ -1719,8 +1723,8 @@ int i; int imax; - DBG(1, "Writing %d bytes to %d(0x%x)\n", - eeprom->len, eeprom->offset, eeprom->offset); + DBG(1, dev, "Writing %d bytes to %d(0x%x)\n", + eeprom->len, eeprom->offset, eeprom->offset); imax = smc_ethtool_geteeprom_len(dev); for (i = 0; i < eeprom->len; i += 2) { int ret; @@ -1729,7 +1733,7 @@ if (offset > imax) break; wbuf = (data[i] << 8) | data[i + 1]; - DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1); + DBG(2, dev, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1); ret = smc_write_eeprom_word(dev, offset >> 1, wbuf); if (ret != 0) return ret; @@ -1784,7 +1788,7 @@ int timeout = 20; unsigned long cookie; - DBG(2, "%s: %s\n", CARDNAME, __func__); + DBG(2, lp->dev, "%s: %s\n", CARDNAME, __func__); cookie = probe_irq_on(); @@ -1856,21 +1860,21 @@ unsigned long irq_flags) { struct smc_local *lp = netdev_priv(dev); - static int version_printed = 0; int retval; unsigned int val, revision_register; const char *version_string; - DBG(2, "%s: %s\n", CARDNAME, __func__); + DBG(2, dev, "%s: %s\n", CARDNAME, __func__); /* First, see if the high byte is 0x33 */ val = SMC_CURRENT_BANK(lp); - DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val); + DBG(2, dev, "%s: bank signature probe returned 0x%04x\n", + CARDNAME, val); if ((val & 0xFF00) != 0x3300) { if ((val & 0xFF) == 0x33) { - printk(KERN_WARNING - "%s: Detected possible byte-swapped interface" - " at IOADDR %p\n", CARDNAME, ioaddr); + netdev_warn(dev, + "%s: Detected possible byte-swapped interface at IOADDR %p\n", + CARDNAME, ioaddr); } retval = -ENODEV; goto err_out; @@ -1896,9 +1900,9 @@ SMC_SELECT_BANK(lp, 1); val = SMC_GET_BASE(lp); val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; - if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { - printk("%s: IOADDR %p doesn't match configuration (%x).\n", - CARDNAME, ioaddr, val); + if (((unsigned long)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { + netdev_warn(dev, "%s: IOADDR %p doesn't match configuration (%x).\n", + CARDNAME, ioaddr, val); } /* @@ -1908,21 +1912,19 @@ */ SMC_SELECT_BANK(lp, 3); revision_register = SMC_GET_REV(lp); - DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register); + DBG(2, dev, "%s: revision = 0x%04x\n", CARDNAME, revision_register); version_string = chip_ids[ (revision_register >> 4) & 0xF]; if (!version_string || (revision_register & 0xff00) != 0x3300) { /* I don't recognize this chip, so... */ - printk("%s: IO %p: Unrecognized revision register 0x%04x" - ", Contact author.\n", CARDNAME, - ioaddr, revision_register); + netdev_warn(dev, "%s: IO %p: Unrecognized revision register 0x%04x, Contact author.\n", + CARDNAME, ioaddr, revision_register); retval = -ENODEV; goto err_out; } /* At this point I'll assume that the chip is an SMC91x. */ - if (version_printed++ == 0) - printk("%s", version); + pr_info_once("%s\n", version); /* fill in some of the fields */ dev->base_addr = (unsigned long)ioaddr; @@ -1940,7 +1942,7 @@ /* * If dev->irq is 0, then the device has to be banged on to see * what the IRQ is. - * + * * This banging doesn't always detect the IRQ, for unknown reasons. * a workaround is to reset the chip and try again. * @@ -1965,16 +1967,12 @@ } } if (dev->irq == 0) { - printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n", - dev->name); + netdev_warn(dev, "Couldn't autodetect your IRQ. Use irq=xx.\n"); retval = -ENODEV; goto err_out; } dev->irq = irq_canonicalize(dev->irq); - /* Fill in the fields of the device structure with ethernet values. */ - ether_setup(dev); - dev->watchdog_timeo = msecs_to_jiffies(watchdog); dev->netdev_ops = &smc_netdev_ops; dev->ethtool_ops = &smc_ethtool_ops; @@ -2020,49 +2018,56 @@ lp->cfg.flags |= SMC91X_USE_DMA; # endif if (lp->cfg.flags & SMC91X_USE_DMA) { - int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, - smc_pxa_dma_irq, NULL); - if (dma >= 0) - dev->dma = dma; + dma_cap_mask_t mask; + struct pxad_param param; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + param.prio = PXAD_PRIO_LOWEST; + param.drcmr = -1UL; + + lp->dma_chan = + dma_request_slave_channel_compat(mask, pxad_filter_fn, + ¶m, &dev->dev, + "data"); } #endif retval = register_netdev(dev); if (retval == 0) { /* now, print out the card info, in a short format.. */ - printk("%s: %s (rev %d) at %p IRQ %d", - dev->name, version_string, revision_register & 0x0f, - lp->base, dev->irq); + netdev_info(dev, "%s (rev %d) at %p IRQ %d", + version_string, revision_register & 0x0f, + lp->base, dev->irq); - if (dev->dma != (unsigned char)-1) - printk(" DMA %d", dev->dma); + if (lp->dma_chan) + pr_cont(" DMA %p", lp->dma_chan); - printk("%s%s\n", + pr_cont("%s%s\n", lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "", THROTTLE_TX_PKTS ? " [throttle_tx]" : ""); if (!is_valid_ether_addr(dev->dev_addr)) { - printk("%s: Invalid ethernet MAC address. Please " - "set using ifconfig\n", dev->name); + netdev_warn(dev, "Invalid ethernet MAC address. Please set using ifconfig\n"); } else { /* Print the Ethernet address */ - printk("%s: Ethernet addr: %pM\n", - dev->name, dev->dev_addr); + netdev_info(dev, "Ethernet addr: %pM\n", + dev->dev_addr); } if (lp->phy_type == 0) { - PRINTK("%s: No PHY found\n", dev->name); + PRINTK(dev, "No PHY found\n"); } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) { - PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name); + PRINTK(dev, "PHY LAN83C183 (LAN91C111 Internal)\n"); } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) { - PRINTK("%s: PHY LAN83C180\n", dev->name); + PRINTK(dev, "PHY LAN83C180\n"); } } err_out: #ifdef CONFIG_ARCH_PXA - if (retval && dev->dma != (unsigned char)-1) - pxa_free_dma(dev->dma); + if (retval && lp->dma_chan) + dma_release_channel(lp->dma_chan); #endif return retval; } @@ -2165,7 +2170,8 @@ return; if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { - printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); + netdev_info(ndev, "%s: failed to request datacs memory region.\n", + CARDNAME); return; } @@ -2189,6 +2195,40 @@ } } +#if IS_BUILTIN(CONFIG_OF) +static const struct of_device_id smc91x_match[] = { + { .compatible = "smsc,lan91c94", }, + { .compatible = "smsc,lan91c111", }, + {}, +}; +MODULE_DEVICE_TABLE(of, smc91x_match); + +/** + * of_try_set_control_gpio - configure a gpio if it exists + */ +static int try_toggle_control_gpio(struct device *dev, + struct gpio_desc **desc, + const char *name, int index, + int value, unsigned int nsdelay) +{ + struct gpio_desc *gpio = *desc; + enum gpiod_flags flags = value ? GPIOD_OUT_LOW : GPIOD_OUT_HIGH; + + gpio = devm_gpiod_get_index_optional(dev, name, index, flags); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + + if (gpio) { + if (nsdelay) + usleep_range(nsdelay, 2 * nsdelay); + gpiod_set_value_cansleep(gpio, value); + } + *desc = gpio; + + return 0; +} +#endif + /* * smc_init(void) * Input parameters: @@ -2202,12 +2242,14 @@ */ static int smc_drv_probe(struct platform_device *pdev) { - struct smc91x_platdata *pd = pdev->dev.platform_data; + struct smc91x_platdata *pd = dev_get_platdata(&pdev->dev); + const struct of_device_id *match = NULL; struct smc_local *lp; struct net_device *ndev; - struct resource *res, *ires; + struct resource *res; unsigned int __iomem *addr; unsigned long irq_flags = SMC_IRQ_FLAGS; + unsigned long irq_resflags; int ret; ndev = alloc_etherdev(sizeof(struct smc_local)); @@ -2222,11 +2264,63 @@ */ lp = netdev_priv(ndev); + lp->cfg.flags = 0; if (pd) { memcpy(&lp->cfg, pd, sizeof(lp->cfg)); lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); - } else { + + if (!SMC_8BIT(lp) && !SMC_16BIT(lp)) { + dev_err(&pdev->dev, + "at least one of 8-bit or 16-bit access support is required.\n"); + ret = -ENXIO; + goto out_free_netdev; + } + } + +#if IS_BUILTIN(CONFIG_OF) + match = of_match_device(of_match_ptr(smc91x_match), &pdev->dev); + if (match) { + struct device_node *np = pdev->dev.of_node; + u32 val; + + /* Optional pwrdwn GPIO configured? */ + ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio, + "power", 0, 0, 100); + if (ret) + return ret; + + /* + * Optional reset GPIO configured? Minimum 100 ns reset needed + * according to LAN91C96 datasheet page 14. + */ + ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio, + "reset", 0, 0, 100); + if (ret) + return ret; + + /* + * Need to wait for optional EEPROM to load, max 750 us according + * to LAN91C96 datasheet page 55. + */ + if (lp->reset_gpio) + usleep_range(750, 1000); + + /* Combination of IO widths supported, default to 16-bit */ + if (!of_property_read_u32(np, "reg-io-width", &val)) { + if (val & 1) + lp->cfg.flags |= SMC91X_USE_8BIT; + if ((val == 0) || (val & 2)) + lp->cfg.flags |= SMC91X_USE_16BIT; + if (val & 4) + lp->cfg.flags |= SMC91X_USE_32BIT; + } else { + lp->cfg.flags |= SMC91X_USE_16BIT; + } + } +#endif + + if (!pd && !match) { lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; @@ -2254,22 +2348,26 @@ goto out_free_netdev; } - ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!ires) { + ndev->irq = platform_get_irq(pdev, 0); + if (ndev->irq <= 0) { ret = -ENODEV; goto out_release_io; } - - ndev->irq = ires->start; - - if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) - irq_flags = ires->flags & IRQF_TRIGGER_MASK; + /* + * If this platform does not specify any special irqflags, or if + * the resource supplies a trigger, override the irqflags with + * the trigger flags from the resource. + */ + irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq)); + if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK) + irq_flags = irq_resflags & IRQF_TRIGGER_MASK; ret = smc_request_attrib(pdev, ndev); if (ret) goto out_release_io; -#if defined(CONFIG_SA1100_ASSABET) - neponset_ncr_set(NCR_ENET_OSC_EN); +#if defined(CONFIG_ASSABET_NEPONSET) + if (machine_is_assabet() && machine_has_neponset()) + neponset_ncr_set(NCR_ENET_OSC_EN); #endif platform_set_drvdata(pdev, ndev); ret = smc_enable_device(pdev); @@ -2287,6 +2385,7 @@ struct smc_local *lp = netdev_priv(ndev); lp->device = &pdev->dev; lp->physaddr = res->start; + } #endif @@ -2299,7 +2398,6 @@ return 0; out_iounmap: - platform_set_drvdata(pdev, NULL); iounmap(addr); out_release_attrib: smc_release_attrib(pdev, ndev); @@ -2308,7 +2406,7 @@ out_free_netdev: free_netdev(ndev); out: - printk("%s: not found (%d).\n", CARDNAME, ret); + pr_info("%s: not found (%d).\n", CARDNAME, ret); return ret; } @@ -2319,15 +2417,13 @@ struct smc_local *lp = netdev_priv(ndev); struct resource *res; - platform_set_drvdata(pdev, NULL); - unregister_netdev(ndev); free_irq(ndev->irq, ndev); #ifdef CONFIG_ARCH_PXA - if (ndev->dma != (unsigned char)-1) - pxa_free_dma(ndev->dma); + if (lp->dma_chan) + dma_release_channel(lp->dma_chan); #endif iounmap(lp->base); @@ -2378,15 +2474,6 @@ return 0; } -#ifdef CONFIG_OF -static const struct of_device_id smc91x_match[] = { - { .compatible = "smsc,lan91c94", }, - { .compatible = "smsc,lan91c111", }, - {}, -}; -MODULE_DEVICE_TABLE(of, smc91x_match); -#endif - static struct dev_pm_ops smc_drv_pm_ops = { .suspend = smc_drv_suspend, .resume = smc_drv_resume, @@ -2397,7 +2484,6 @@ .remove = smc_drv_remove, .driver = { .name = CARDNAME, - .owner = THIS_MODULE, .pm = &smc_drv_pm_ops, .of_match_table = of_match_ptr(smc91x_match), },