X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fsunhme.c;h=3d9650b8d38fab26fce127f52d7a09ad1170ff6d;hb=HEAD;hp=ec51f397e1ed526ab8c00c0c6db0fa6b1c7b8fec;hpb=050bbb196392b9c178f82b1205a23dd2f915ee93;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index ec51f39..3d9650b 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3,7 +3,7 @@ * "Happy Meal Ethernet" found on SunSwift SBUS cards. * * Copyright (C) 1996, 1998, 1999, 2002, 2003, - 2006 David S. Miller (davem@davemloft.net) + * 2006, 2008 David S. Miller (davem@davemloft.net) * * Changes : * 2000/11/11 Willy Tarreau @@ -13,7 +13,6 @@ * argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50 */ -#include #include #include #include @@ -33,7 +32,9 @@ #include #include #include +#include #include +#include #include #include @@ -41,8 +42,9 @@ #include #ifdef CONFIG_SPARC +#include +#include #include -#include #include #include #include @@ -55,16 +57,13 @@ #ifdef CONFIG_PCI #include -#ifdef CONFIG_SPARC -#include -#endif #endif #include "sunhme.h" #define DRV_NAME "sunhme" -#define DRV_VERSION "3.00" -#define DRV_RELDATE "June 23, 2006" +#define DRV_VERSION "3.10" +#define DRV_RELDATE "August 26, 2008" #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" static char version[] = @@ -114,7 +113,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne struct hme_tx_logent *tlp; unsigned long flags; - save_and_cli(flags); + local_irq_save(flags); tlp = &tx_log[txlog_cur_entry]; tlp->tstamp = (unsigned int)jiffies; tlp->tx_new = hp->tx_new; @@ -122,7 +121,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne tlp->action = a; tlp->status = s; txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1); - restore_flags(flags); + local_irq_restore(flags); } static __inline__ void tx_dump_log(void) { @@ -197,21 +196,21 @@ static u32 sbus_hme_read32(void __iomem *reg) static void sbus_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) { - rxd->rx_addr = addr; + rxd->rx_addr = (__force hme32)addr; wmb(); - rxd->rx_flags = flags; + rxd->rx_flags = (__force hme32)flags; } static void sbus_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) { - txd->tx_addr = addr; + txd->tx_addr = (__force hme32)addr; wmb(); - txd->tx_flags = flags; + txd->tx_flags = (__force hme32)flags; } -static u32 sbus_hme_read_desc32(u32 *p) +static u32 sbus_hme_read_desc32(hme32 *p) { - return *p; + return (__force u32)*p; } static void pci_hme_write32(void __iomem *reg, u32 val) @@ -226,21 +225,21 @@ static u32 pci_hme_read32(void __iomem *reg) static void pci_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) { - rxd->rx_addr = cpu_to_le32(addr); + rxd->rx_addr = (__force hme32)cpu_to_le32(addr); wmb(); - rxd->rx_flags = cpu_to_le32(flags); + rxd->rx_flags = (__force hme32)cpu_to_le32(flags); } static void pci_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) { - txd->tx_addr = cpu_to_le32(addr); + txd->tx_addr = (__force hme32)cpu_to_le32(addr); wmb(); - txd->tx_flags = cpu_to_le32(flags); + txd->tx_flags = (__force hme32)cpu_to_le32(flags); } -static u32 pci_hme_read_desc32(u32 *p) +static u32 pci_hme_read_desc32(hme32 *p) { - return cpu_to_le32p(p); + return le32_to_cpup((__le32 *)p); } #define hme_write32(__hp, __reg, __val) \ @@ -254,13 +253,13 @@ static u32 pci_hme_read_desc32(u32 *p) #define hme_read_desc32(__hp, __p) \ ((__hp)->read_desc32(__p)) #define hme_dma_map(__hp, __ptr, __size, __dir) \ - ((__hp)->dma_map((__hp)->happy_dev, (__ptr), (__size), (__dir))) + ((__hp)->dma_map((__hp)->dma_dev, (__ptr), (__size), (__dir))) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ - ((__hp)->dma_unmap((__hp)->happy_dev, (__addr), (__size), (__dir))) + ((__hp)->dma_unmap((__hp)->dma_dev, (__addr), (__size), (__dir))) #define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \ - ((__hp)->dma_sync_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir))) + ((__hp)->dma_sync_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir))) #define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \ - ((__hp)->dma_sync_for_device((__hp)->happy_dev, (__addr), (__size), (__dir))) + ((__hp)->dma_sync_for_device((__hp)->dma_dev, (__addr), (__size), (__dir))) #else #ifdef CONFIG_SBUS /* SBUS only compilation */ @@ -269,24 +268,24 @@ static u32 pci_hme_read_desc32(u32 *p) #define hme_read32(__hp, __reg) \ sbus_readl(__reg) #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ -do { (__rxd)->rx_addr = (__addr); \ +do { (__rxd)->rx_addr = (__force hme32)(u32)(__addr); \ wmb(); \ - (__rxd)->rx_flags = (__flags); \ + (__rxd)->rx_flags = (__force hme32)(u32)(__flags); \ } while(0) #define hme_write_txd(__hp, __txd, __flags, __addr) \ -do { (__txd)->tx_addr = (__addr); \ +do { (__txd)->tx_addr = (__force hme32)(u32)(__addr); \ wmb(); \ - (__txd)->tx_flags = (__flags); \ + (__txd)->tx_flags = (__force hme32)(u32)(__flags); \ } while(0) -#define hme_read_desc32(__hp, __p) (*(__p)) +#define hme_read_desc32(__hp, __p) ((__force u32)(hme32)*(__p)) #define hme_dma_map(__hp, __ptr, __size, __dir) \ - sbus_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) + dma_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir)) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ - sbus_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir)) + dma_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir)) #define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \ - sbus_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir)) + dma_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir)) #define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \ - sbus_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir)) + dma_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir)) #else /* PCI only compilation */ #define hme_write32(__hp, __reg, __val) \ @@ -294,47 +293,31 @@ do { (__txd)->tx_addr = (__addr); \ #define hme_read32(__hp, __reg) \ readl(__reg) #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ -do { (__rxd)->rx_addr = cpu_to_le32(__addr); \ +do { (__rxd)->rx_addr = (__force hme32)cpu_to_le32(__addr); \ wmb(); \ - (__rxd)->rx_flags = cpu_to_le32(__flags); \ + (__rxd)->rx_flags = (__force hme32)cpu_to_le32(__flags); \ } while(0) #define hme_write_txd(__hp, __txd, __flags, __addr) \ -do { (__txd)->tx_addr = cpu_to_le32(__addr); \ +do { (__txd)->tx_addr = (__force hme32)cpu_to_le32(__addr); \ wmb(); \ - (__txd)->tx_flags = cpu_to_le32(__flags); \ + (__txd)->tx_flags = (__force hme32)cpu_to_le32(__flags); \ } while(0) -#define hme_read_desc32(__hp, __p) cpu_to_le32p(__p) +static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p) +{ + return le32_to_cpup((__le32 *)p); +} #define hme_dma_map(__hp, __ptr, __size, __dir) \ - pci_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) + pci_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir)) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ - pci_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir)) + pci_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir)) #define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \ - pci_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir)) + pci_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir)) #define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \ - pci_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir)) + pci_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir)) #endif #endif -#ifdef SBUS_DMA_BIDIRECTIONAL -# define DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL -#else -# define DMA_BIDIRECTIONAL 0 -#endif - -#ifdef SBUS_DMA_FROMDEVICE -# define DMA_FROMDEVICE SBUS_DMA_FROMDEVICE -#else -# define DMA_TODEVICE 1 -#endif - -#ifdef SBUS_DMA_TODEVICE -# define DMA_TODEVICE SBUS_DMA_TODEVICE -#else -# define DMA_FROMDEVICE 2 -#endif - - /* Oh yes, the MIF BitBang is mighty fun to program. BitBucket is more like it. */ static void BB_PUT_BIT(struct happy_meal *hp, void __iomem *tregs, int bit) { @@ -506,7 +489,7 @@ static void happy_meal_tcvr_write(struct happy_meal *hp, unsigned short value) { int tries = TCVR_WRITE_TRIES; - + ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value)); /* Welcome to Sun Microsystems, can I take your order please? */ @@ -872,7 +855,7 @@ static void happy_meal_timer(unsigned long data) hp->timer_ticks = 0; hp->timer_state = asleep; /* foo on you */ break; - }; + } if (restart_timer) { hp->happy_timer.expires = jiffies + ((12 * HZ)/10); /* 1.2 sec. */ @@ -1208,7 +1191,7 @@ static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tr * flags, thus: * * skb->csum = rxd->rx_flags & 0xffff; - * skb->ip_summed = CHECKSUM_HW; + * skb->ip_summed = CHECKSUM_COMPLETE; * * before sending off the skb to the protocols, and we are good as gold. */ @@ -1224,7 +1207,8 @@ static void happy_meal_clean_rings(struct happy_meal *hp) rxd = &hp->happy_block->happy_meal_rxd[i]; dma_addr = hme_read_desc32(hp, &rxd->rx_addr); - hme_dma_unmap(hp, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE); + dma_unmap_single(hp->dma_dev, dma_addr, + RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE); dev_kfree_skb_any(skb); hp->rx_skbs[i] = NULL; } @@ -1242,10 +1226,16 @@ static void happy_meal_clean_rings(struct happy_meal *hp) for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) { txd = &hp->happy_block->happy_meal_txd[i]; dma_addr = hme_read_desc32(hp, &txd->tx_addr); - hme_dma_unmap(hp, dma_addr, - (hme_read_desc32(hp, &txd->tx_flags) - & TXFLAG_SIZE), - DMA_TODEVICE); + if (!frag) + dma_unmap_single(hp->dma_dev, dma_addr, + (hme_read_desc32(hp, &txd->tx_flags) + & TXFLAG_SIZE), + DMA_TO_DEVICE); + else + dma_unmap_page(hp->dma_dev, dma_addr, + (hme_read_desc32(hp, &txd->tx_flags) + & TXFLAG_SIZE), + DMA_TO_DEVICE); if (frag != skb_shinfo(skb)->nr_frags) i++; @@ -1284,10 +1274,11 @@ static void happy_meal_init_rings(struct happy_meal *hp) skb->dev = dev; /* Because we reserve afterwards. */ - skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET)); + skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET + 4)); hme_write_rxd(hp, &hb->happy_meal_rxd[i], (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16)), - hme_dma_map(hp, skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE)); + dma_map_single(hp->dma_dev, skb->data, RX_BUF_ALLOC_SIZE, + DMA_FROM_DEVICE)); skb_reserve(skb, RX_OFFSET); } @@ -1497,7 +1488,7 @@ static int happy_meal_init(struct happy_meal *hp) HMD(("external, disable MII, ")); hme_write32(hp, bregs + BMAC_XIFCFG, BIGMAC_XCFG_MIIDISAB); break; - }; + } if (happy_meal_tcvr_reset(hp, tregs)) return -EAGAIN; @@ -1525,24 +1516,20 @@ static int happy_meal_init(struct happy_meal *hp) HMD(("htable, ")); if ((hp->dev->flags & IFF_ALLMULTI) || - (hp->dev->mc_count > 64)) { + (netdev_mc_count(hp->dev) > 64)) { hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff); hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff); hme_write32(hp, bregs + BMAC_HTABLE2, 0xffff); hme_write32(hp, bregs + BMAC_HTABLE3, 0xffff); } else if ((hp->dev->flags & IFF_PROMISC) == 0) { u16 hash_table[4]; - struct dev_mc_list *dmi = hp->dev->mc_list; + struct netdev_hw_addr *ha; char *addrs; - int i; u32 crc; - for (i = 0; i < 4; i++) - hash_table[i] = 0; - - for (i = 0; i < hp->dev->mc_count; i++) { - addrs = dmi->dmi_addr; - dmi = dmi->next; + memset(hash_table, 0, sizeof(hash_table)); + netdev_for_each_mc_addr(ha, hp->dev) { + addrs = ha->addr; if (!(*addrs & 1)) continue; @@ -1593,7 +1580,7 @@ static int happy_meal_init(struct happy_meal *hp) if ((hp->happy_bursts & DMA_BURST64) && ((hp->happy_flags & HFLAG_PCI) != 0 #ifdef CONFIG_SBUS - || sbus_can_burst64(hp->happy_dev) + || sbus_can_burst64() #endif || 0)) { u32 gcfg = GREG_CFG_BURST64; @@ -1603,11 +1590,13 @@ static int happy_meal_init(struct happy_meal *hp) * do not. -DaveM */ #ifdef CONFIG_SBUS - if ((hp->happy_flags & HFLAG_PCI) == 0 && - sbus_can_dma_64bit(hp->happy_dev)) { - sbus_set_sbus64(hp->happy_dev, - hp->happy_bursts); - gcfg |= GREG_CFG_64BIT; + if ((hp->happy_flags & HFLAG_PCI) == 0) { + struct of_device *op = hp->happy_dev; + if (sbus_can_dma_64bit()) { + sbus_set_sbus64(&op->dev, + hp->happy_bursts); + gcfg |= GREG_CFG_64BIT; + } } #endif @@ -1703,6 +1692,11 @@ static int happy_meal_init(struct happy_meal *hp) HMD(("tx old[%08x] and rx [%08x] ON!\n", hme_read32(hp, bregs + BMAC_TXCFG), hme_read32(hp, bregs + BMAC_RXCFG))); + + /* Set larger TX/RX size to allow for 802.1q */ + hme_write32(hp, bregs + BMAC_TXMAX, ETH_FRAME_LEN + 8); + hme_write32(hp, bregs + BMAC_RXMAX, ETH_FRAME_LEN + 8); + hme_write32(hp, bregs + BMAC_TXCFG, hme_read32(hp, bregs + BMAC_TXCFG) | BIGMAC_TXCFG_ENABLE); hme_write32(hp, bregs + BMAC_RXCFG, @@ -1740,7 +1734,7 @@ static void happy_meal_set_initial_advertisement(struct happy_meal *hp) case external: hme_write32(hp, bregs + BMAC_XIFCFG, BIGMAC_XCFG_MIIDISAB); break; - }; + } if (happy_meal_tcvr_reset(hp, tregs)) return; @@ -1779,7 +1773,7 @@ static void happy_meal_set_initial_advertisement(struct happy_meal *hp) static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status) { int reset = 0; - + /* Only print messages for non-counter related interrupts. */ if (status & (GREG_STAT_STSTERR | GREG_STAT_TFIFO_UND | GREG_STAT_MAXPKTERR | GREG_STAT_RXERR | @@ -1961,7 +1955,10 @@ static void happy_meal_tx(struct happy_meal *hp) dma_len = hme_read_desc32(hp, &this->tx_flags); dma_len &= TXFLAG_SIZE; - hme_dma_unmap(hp, dma_addr, dma_len, DMA_TODEVICE); + if (!frag) + dma_unmap_single(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE); + else + dma_unmap_page(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE); elem = NEXT_TX(elem); this = &txbase[elem]; @@ -2039,13 +2036,14 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) drops++; goto drop_it; } - hme_dma_unmap(hp, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE); + dma_unmap_single(hp->dma_dev, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE); hp->rx_skbs[elem] = new_skb; new_skb->dev = dev; - skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET)); + skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4)); hme_write_rxd(hp, this, (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)), - hme_dma_map(hp, new_skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE)); + dma_map_single(hp->dma_dev, new_skb->data, RX_BUF_ALLOC_SIZE, + DMA_FROM_DEVICE)); skb_reserve(new_skb, RX_OFFSET); /* Trim the original skb for the netif. */ @@ -2058,13 +2056,11 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) goto drop_it; } - copy_skb->dev = dev; skb_reserve(copy_skb, 2); skb_put(copy_skb, len); - hme_dma_sync_for_cpu(hp, dma_addr, len, DMA_FROMDEVICE); - memcpy(copy_skb->data, skb->data, len); - hme_dma_sync_for_device(hp, dma_addr, len, DMA_FROMDEVICE); - + dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); + skb_copy_from_linear_data(skb, copy_skb->data, len); + dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); /* Reuse original ring buffer. */ hme_write_rxd(hp, this, (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)), @@ -2074,14 +2070,13 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) } /* This card is _fucking_ hot... */ - skb->csum = ntohs(csum ^ 0xffff); - skb->ip_summed = CHECKSUM_HW; + skb->csum = csum_unfold(~(__force __sum16)htons(csum)); + skb->ip_summed = CHECKSUM_COMPLETE; RXD(("len=%d csum=%4x]", len, csum)); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - dev->last_rx = jiffies; hp->net_stats.rx_packets++; hp->net_stats.rx_bytes += len; next: @@ -2094,10 +2089,10 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) RXD((">")); } -static irqreturn_t happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t happy_meal_interrupt(int irq, void *dev_id) { - struct net_device *dev = (struct net_device *) dev_id; - struct happy_meal *hp = dev->priv; + struct net_device *dev = dev_id; + struct happy_meal *hp = netdev_priv(dev); u32 happy_status = hme_read32(hp, hp->gregs + GREG_STAT); HMD(("happy_meal_interrupt: status=%08x ", happy_status)); @@ -2133,14 +2128,14 @@ out: } #ifdef CONFIG_SBUS -static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie, struct pt_regs *ptregs) +static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie) { struct quattro *qp = (struct quattro *) cookie; int i; for (i = 0; i < 4; i++) { struct net_device *dev = qp->happy_meals[i]; - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); u32 happy_status = hme_read32(hp, hp->gregs + GREG_STAT); HMD(("quattro_interrupt: status=%08x ", happy_status)); @@ -2185,7 +2180,7 @@ static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie, struct pt_regs static int happy_meal_open(struct net_device *dev) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); int res; HMD(("happy_meal_open: ")); @@ -2194,8 +2189,8 @@ static int happy_meal_open(struct net_device *dev) * into a single source which we register handling at probe time. */ if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) { - if (request_irq(dev->irq, &happy_meal_interrupt, - SA_SHIRQ, dev->name, (void *)dev)) { + if (request_irq(dev->irq, happy_meal_interrupt, + IRQF_SHARED, dev->name, (void *)dev)) { HMD(("EAGAIN\n")); printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n", dev->irq); @@ -2217,7 +2212,7 @@ static int happy_meal_open(struct net_device *dev) static int happy_meal_close(struct net_device *dev) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); spin_lock_irq(&hp->happy_lock); happy_meal_stop(hp, hp->gregs); @@ -2246,7 +2241,7 @@ static int happy_meal_close(struct net_device *dev) static void happy_meal_tx_timeout(struct net_device *dev) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); printk (KERN_ERR "%s: transmit timed out, resetting\n", dev->name); tx_dump_log(); @@ -2262,18 +2257,17 @@ static void happy_meal_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } -static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb, + struct net_device *dev) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); int entry; u32 tx_flags; tx_flags = TXFLAG_OWN; - if (skb->ip_summed == CHECKSUM_HW) { - u32 csum_start_off, csum_stuff_off; - - csum_start_off = (u32) (skb->h.raw - skb->data); - csum_stuff_off = (u32) ((skb->h.raw + skb->csum) - skb->data); + if (skb->ip_summed == CHECKSUM_PARTIAL) { + const u32 csum_start_off = skb_transport_offset(skb); + const u32 csum_stuff_off = csum_start_off + skb->csum_offset; tx_flags = (TXFLAG_OWN | TXFLAG_CSENABLE | ((csum_start_off << 14) & TXFLAG_CSBUFBEGIN) | @@ -2287,7 +2281,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irq(&hp->happy_lock); printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n", dev->name); - return 1; + return NETDEV_TX_BUSY; } entry = hp->tx_new; @@ -2298,7 +2292,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 mapping, len; len = skb->len; - mapping = hme_dma_map(hp, skb->data, len, DMA_TODEVICE); + mapping = dma_map_single(hp->dma_dev, skb->data, len, DMA_TO_DEVICE); tx_flags |= (TXFLAG_SOP | TXFLAG_EOP); hme_write_txd(hp, &hp->happy_block->happy_meal_txd[entry], (tx_flags | (len & TXFLAG_SIZE)), @@ -2312,7 +2306,8 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) * Otherwise we could race with the device. */ first_len = skb_headlen(skb); - first_mapping = hme_dma_map(hp, skb->data, first_len, DMA_TODEVICE); + first_mapping = dma_map_single(hp->dma_dev, skb->data, first_len, + DMA_TO_DEVICE); entry = NEXT_TX(entry); for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { @@ -2320,10 +2315,9 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 len, mapping, this_txflags; len = this_frag->size; - mapping = hme_dma_map(hp, - ((void *) page_address(this_frag->page) + - this_frag->page_offset), - len, DMA_TODEVICE); + mapping = dma_map_page(hp->dma_dev, this_frag->page, + this_frag->page_offset, len, + DMA_TO_DEVICE); this_txflags = tx_flags; if (frag == skb_shinfo(skb)->nr_frags - 1) this_txflags |= TXFLAG_EOP; @@ -2347,15 +2341,13 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irq(&hp->happy_lock); - dev->trans_start = jiffies; - tx_add_log(hp, TXLOG_ACTION_TXMIT, 0); - return 0; + return NETDEV_TX_OK; } static struct net_device_stats *happy_meal_get_stats(struct net_device *dev) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); spin_lock_irq(&hp->happy_lock); happy_meal_get_counters(hp, hp->bigmacregs); @@ -2366,18 +2358,15 @@ static struct net_device_stats *happy_meal_get_stats(struct net_device *dev) static void happy_meal_set_multicast(struct net_device *dev) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); void __iomem *bregs = hp->bigmacregs; - struct dev_mc_list *dmi = dev->mc_list; + struct netdev_hw_addr *ha; char *addrs; - int i; u32 crc; spin_lock_irq(&hp->happy_lock); - netif_stop_queue(dev); - - if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) { + if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) { hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff); hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff); hme_write32(hp, bregs + BMAC_HTABLE2, 0xffff); @@ -2388,12 +2377,9 @@ static void happy_meal_set_multicast(struct net_device *dev) } else { u16 hash_table[4]; - for (i = 0; i < 4; i++) - hash_table[i] = 0; - - for (i = 0; i < dev->mc_count; i++) { - addrs = dmi->dmi_addr; - dmi = dmi->next; + memset(hash_table, 0, sizeof(hash_table)); + netdev_for_each_mc_addr(ha, dev) { + addrs = ha->addr; if (!(*addrs & 1)) continue; @@ -2408,15 +2394,13 @@ static void happy_meal_set_multicast(struct net_device *dev) hme_write32(hp, bregs + BMAC_HTABLE3, hash_table[3]); } - netif_wake_queue(dev); - spin_unlock_irq(&hp->happy_lock); } /* Ethtool support... */ static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); cmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | @@ -2461,7 +2445,7 @@ static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); /* Verify the settings we care about. */ if (cmd->autoneg != AUTONEG_ENABLE && @@ -2485,7 +2469,7 @@ static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); strcpy(info->driver, "sunhme"); strcpy(info->version, "2.02"); @@ -2495,16 +2479,19 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info } #ifdef CONFIG_SBUS else { - struct sbus_dev *sdev = hp->happy_dev; - sprintf(info->bus_info, "SBUS:%d", - sdev->slot); + const struct linux_prom_registers *regs; + struct of_device *op = hp->happy_dev; + regs = of_get_property(op->dev.of_node, "regs", NULL); + if (regs) + sprintf(info->bus_info, "SBUS:%d", + regs->which_io); } #endif } static u32 hme_get_link(struct net_device *dev) { - struct happy_meal *hp = dev->priv; + struct happy_meal *hp = netdev_priv(dev); spin_lock_irq(&hp->happy_lock); hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR); @@ -2513,7 +2500,7 @@ static u32 hme_get_link(struct net_device *dev) return (hp->sw_bmsr & BMSR_LSTATUS); } -static struct ethtool_ops hme_ethtool_ops = { +static const struct ethtool_ops hme_ethtool_ops = { .get_settings = hme_get_settings, .set_settings = hme_set_settings, .get_drvinfo = hme_get_drvinfo, @@ -2523,78 +2510,22 @@ static struct ethtool_ops hme_ethtool_ops = { static int hme_version_printed; #ifdef CONFIG_SBUS -void __init quattro_get_ranges(struct quattro *qp) -{ - struct sbus_dev *sdev = qp->quattro_dev; - int err; - - err = prom_getproperty(sdev->prom_node, - "ranges", - (char *)&qp->ranges[0], - sizeof(qp->ranges)); - if (err == 0 || err == -1) { - qp->nranges = 0; - return; - } - qp->nranges = (err / sizeof(struct linux_prom_ranges)); -} - -static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp) -{ - struct sbus_dev *sdev = hp->happy_dev; - int rng; - - for (rng = 0; rng < qp->nranges; rng++) { - struct linux_prom_ranges *rngp = &qp->ranges[rng]; - int reg; - - for (reg = 0; reg < 5; reg++) { - if (sdev->reg_addrs[reg].which_io == - rngp->ot_child_space) - break; - } - if (reg == 5) - continue; - - sdev->reg_addrs[reg].which_io = rngp->ot_parent_space; - sdev->reg_addrs[reg].phys_addr += rngp->ot_parent_base; - } -} - /* Given a happy meal sbus device, find it's quattro parent. * If none exist, allocate and return a new one. * * Return NULL on failure. */ -static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) +static struct quattro * __devinit quattro_sbus_find(struct of_device *child) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct device *parent = child->dev.parent; + struct of_device *op; struct quattro *qp; - int i; - - if (qfe_sbus_list == NULL) - goto found; - - for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { - for (i = 0, sdev = qp->quattro_dev; - (sdev != NULL) && (i < 4); - sdev = sdev->next, i++) { - if (sdev == goal_sdev) - return qp; - } - } - for_each_sbus(sbus) { - for_each_sbusdev(sdev, sbus) { - if (sdev == goal_sdev) - goto found; - } - } - /* Cannot find quattro parent, fail. */ - return NULL; + op = to_of_device(parent); + qp = dev_get_drvdata(&op->dev); + if (qp) + return qp; -found: qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); if (qp != NULL) { int i; @@ -2602,50 +2533,70 @@ found: for (i = 0; i < 4; i++) qp->happy_meals[i] = NULL; - qp->quattro_dev = goal_sdev; + qp->quattro_dev = child; qp->next = qfe_sbus_list; qfe_sbus_list = qp; - quattro_get_ranges(qp); + + dev_set_drvdata(&op->dev, qp); } return qp; } /* After all quattro cards have been probed, we call these functions - * to register the IRQ handlers. + * to register the IRQ handlers for the cards that have been + * successfully probed and skip the cards that failed to initialize */ -static void __init quattro_sbus_register_irqs(void) +static int __init quattro_sbus_register_irqs(void) { struct quattro *qp; for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { - struct sbus_dev *sdev = qp->quattro_dev; - int err; + struct of_device *op = qp->quattro_dev; + int err, qfe_slot, skip = 0; + + for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) { + if (!qp->happy_meals[qfe_slot]) + skip = 1; + } + if (skip) + continue; - err = request_irq(sdev->irqs[0], + err = request_irq(op->irqs[0], quattro_sbus_interrupt, - SA_SHIRQ, "Quattro", + IRQF_SHARED, "Quattro", qp); if (err != 0) { - printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err); - panic("QFE request irq"); + printk(KERN_ERR "Quattro HME: IRQ registration " + "error %d.\n", err); + return err; } } + + return 0; } -static void __devexit quattro_sbus_free_irqs(void) +static void quattro_sbus_free_irqs(void) { struct quattro *qp; for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { - struct sbus_dev *sdev = qp->quattro_dev; + struct of_device *op = qp->quattro_dev; + int qfe_slot, skip = 0; - free_irq(sdev->irqs[0], qp); + for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) { + if (!qp->happy_meals[qfe_slot]) + skip = 1; + } + if (skip) + continue; + + free_irq(op->irqs[0], qp); } } #endif /* CONFIG_SBUS */ #ifdef CONFIG_PCI -static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) +static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev) { struct pci_dev *bdev = pdev->bus->self; struct quattro *qp; @@ -2675,18 +2626,36 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) } #endif /* CONFIG_PCI */ +static const struct net_device_ops hme_netdev_ops = { + .ndo_open = happy_meal_open, + .ndo_stop = happy_meal_close, + .ndo_start_xmit = happy_meal_start_xmit, + .ndo_tx_timeout = happy_meal_tx_timeout, + .ndo_get_stats = happy_meal_get_stats, + .ndo_set_multicast_list = happy_meal_set_multicast, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + #ifdef CONFIG_SBUS -static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) +static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) { - struct device_node *dp = sdev->ofdev.node; + struct device_node *dp = op->dev.of_node, *sbus_dp; struct quattro *qp = NULL; struct happy_meal *hp; struct net_device *dev; int i, qfe_slot = -1; int err = -ENODEV; + sbus_dp = to_of_device(op->dev.parent)->dev.of_node; + + /* We can match PCI devices too, do not accept those here. */ + if (strcmp(sbus_dp->name, "sbus")) + return err; + if (is_qfe) { - qp = quattro_sbus_find(sdev); + qp = quattro_sbus_find(op); if (qp == NULL) goto err_out; for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) @@ -2700,8 +2669,7 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) dev = alloc_etherdev(sizeof(struct happy_meal)); if (!dev) goto err_out; - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &sdev->ofdev.dev); + SET_NETDEV_DEV(dev, &op->dev); if (hme_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -2718,7 +2686,7 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) dev->dev_addr[i] = macaddr[i]; macaddr[5]++; } else { - unsigned char *addr; + const unsigned char *addr; int len; addr = of_get_property(dp, "local-mac-address", &len); @@ -2729,56 +2697,50 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) memcpy(dev->dev_addr, idprom->id_ethaddr, 6); } - hp = dev->priv; + hp = netdev_priv(dev); - hp->happy_dev = sdev; + hp->happy_dev = op; + hp->dma_dev = &op->dev; spin_lock_init(&hp->happy_lock); err = -ENODEV; - if (sdev->num_registers != 5) { - printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n", - sdev->num_registers); - goto err_out_free_netdev; - } - if (qp != NULL) { hp->qfe_parent = qp; hp->qfe_ent = qfe_slot; qp->happy_meals[qfe_slot] = dev; - quattro_apply_ranges(qp, hp); } - hp->gregs = sbus_ioremap(&sdev->resource[0], 0, - GREG_REG_SIZE, "HME Global Regs"); + hp->gregs = of_ioremap(&op->resource[0], 0, + GREG_REG_SIZE, "HME Global Regs"); if (!hp->gregs) { printk(KERN_ERR "happymeal: Cannot map global registers.\n"); goto err_out_free_netdev; } - hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, - ETX_REG_SIZE, "HME TX Regs"); + hp->etxregs = of_ioremap(&op->resource[1], 0, + ETX_REG_SIZE, "HME TX Regs"); if (!hp->etxregs) { printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n"); goto err_out_iounmap; } - hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, - ERX_REG_SIZE, "HME RX Regs"); + hp->erxregs = of_ioremap(&op->resource[2], 0, + ERX_REG_SIZE, "HME RX Regs"); if (!hp->erxregs) { printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n"); goto err_out_iounmap; } - hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, - BMAC_REG_SIZE, "HME BIGMAC Regs"); + hp->bigmacregs = of_ioremap(&op->resource[3], 0, + BMAC_REG_SIZE, "HME BIGMAC Regs"); if (!hp->bigmacregs) { printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n"); goto err_out_iounmap; } - hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, - TCVR_REG_SIZE, "HME Tranceiver Regs"); + hp->tcvregs = of_ioremap(&op->resource[4], 0, + TCVR_REG_SIZE, "HME Tranceiver Regs"); if (!hp->tcvregs) { printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n"); goto err_out_iounmap; @@ -2798,12 +2760,13 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) hp->happy_flags |= HFLAG_QUATTRO; /* Get the supported DVMA burst sizes from our Happy SBUS. */ - hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node, + hp->happy_bursts = of_getintprop_default(sbus_dp, "burst-sizes", 0x00); - hp->happy_block = sbus_alloc_consistent(hp->happy_dev, - PAGE_SIZE, - &hp->hblock_dvma); + hp->happy_block = dma_alloc_coherent(hp->dma_dev, + PAGE_SIZE, + &hp->hblock_dvma, + GFP_ATOMIC); err = -ENOMEM; if (!hp->happy_block) { printk(KERN_ERR "happymeal: Cannot allocate descriptors.\n"); @@ -2820,31 +2783,20 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) init_timer(&hp->happy_timer); hp->dev = dev; - dev->open = &happy_meal_open; - dev->stop = &happy_meal_close; - dev->hard_start_xmit = &happy_meal_start_xmit; - dev->get_stats = &happy_meal_get_stats; - dev->set_multicast_list = &happy_meal_set_multicast; - dev->tx_timeout = &happy_meal_tx_timeout; + dev->netdev_ops = &hme_netdev_ops; dev->watchdog_timeo = 5*HZ; dev->ethtool_ops = &hme_ethtool_ops; - /* Happy Meal can do it all... except VLAN. */ - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_VLAN_CHALLENGED; + /* Happy Meal can do it all... */ + dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; - dev->irq = sdev->irqs[0]; + dev->irq = op->irqs[0]; #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) - /* Hook up PCI register/dma accessors. */ + /* Hook up SBUS register/descriptor accessors. */ hp->read_desc32 = sbus_hme_read_desc32; hp->write_txd = sbus_hme_write_txd; hp->write_rxd = sbus_hme_write_rxd; - hp->dma_map = (u32 (*)(void *, void *, long, int))sbus_map_single; - hp->dma_unmap = (void (*)(void *, u32, long, int))sbus_unmap_single; - hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int)) - sbus_dma_sync_single_for_cpu; - hp->dma_sync_for_device = (void (*)(void *, u32, long, int)) - sbus_dma_sync_single_for_device; hp->read32 = sbus_hme_read32; hp->write32 = sbus_hme_write32; #endif @@ -2859,10 +2811,10 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) if (register_netdev(hp->dev)) { printk(KERN_ERR "happymeal: Cannot register net device, " "aborting.\n"); - goto err_out_free_consistent; + goto err_out_free_coherent; } - dev_set_drvdata(&sdev->ofdev.dev, hp); + dev_set_drvdata(&op->dev, hp); if (qfe_slot != -1) printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", @@ -2871,30 +2823,30 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) printk(KERN_INFO "%s: HAPPY MEAL (SBUS) 10/100baseT Ethernet ", dev->name); - for (i = 0; i < 6; i++) - printk("%2.2x%c", - dev->dev_addr[i], i == 5 ? ' ' : ':'); - printk("\n"); + printk("%pM\n", dev->dev_addr); return 0; -err_out_free_consistent: - sbus_free_consistent(hp->happy_dev, - PAGE_SIZE, - hp->happy_block, - hp->hblock_dvma); +err_out_free_coherent: + dma_free_coherent(hp->dma_dev, + PAGE_SIZE, + hp->happy_block, + hp->hblock_dvma); err_out_iounmap: if (hp->gregs) - sbus_iounmap(hp->gregs, GREG_REG_SIZE); + of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE); if (hp->etxregs) - sbus_iounmap(hp->etxregs, ETX_REG_SIZE); + of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE); if (hp->erxregs) - sbus_iounmap(hp->erxregs, ERX_REG_SIZE); + of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE); if (hp->bigmacregs) - sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); + of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE); if (hp->tcvregs) - sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); + of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE); + + if (qp) + qp->happy_meals[qfe_slot] = NULL; err_out_free_netdev: free_netdev(dev); @@ -2991,7 +2943,6 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr) dev_addr[1] = 0x00; dev_addr[2] = 0x20; get_random_bytes(&dev_addr[3], 3); - return; } #endif /* !(CONFIG_SPARC) */ @@ -3000,7 +2951,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, { struct quattro *qp = NULL; #ifdef CONFIG_SPARC - struct pcidev_cookie *pcp; + struct device_node *dp; #endif struct happy_meal *hp; struct net_device *dev; @@ -3012,13 +2963,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, /* Now make sure pci_dev cookie is there. */ #ifdef CONFIG_SPARC - pcp = pdev->sysdata; - if (pcp == NULL) { - printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); - return -ENODEV; - } - - strcpy(prom_name, pcp->prom_node->name); + dp = pci_device_to_OF_node(pdev); + strcpy(prom_name, dp->name); #else if (is_quattro_p(pdev)) strcpy(prom_name, "SUNW,qfe"); @@ -3027,6 +2973,11 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, #endif err = -ENODEV; + + if (pci_enable_device(pdev)) + goto err_out; + pci_set_master(pdev); + if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) { qp = quattro_pci_find(pdev); if (qp == NULL) @@ -3042,7 +2993,6 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, err = -ENOMEM; if (!dev) goto err_out; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (hme_version_printed++ == 0) @@ -3050,10 +3000,10 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, dev->base_addr = (long) pdev; - hp = (struct happy_meal *)dev->priv; - memset(hp, 0, sizeof(*hp)); + hp = netdev_priv(dev); hp->happy_dev = pdev; + hp->dma_dev = &pdev->dev; spin_lock_init(&hp->happy_lock); @@ -3061,7 +3011,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, hp->qfe_parent = qp; hp->qfe_ent = qfe_slot; qp->happy_meals[qfe_slot] = dev; - } + } hpreg_res = pci_resource_start(pdev, 0); err = -ENODEV; @@ -3075,7 +3025,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, goto err_out_clear_quattro; } - if ((hpreg_base = ioremap(hpreg_res, 0x8000)) == 0) { + if ((hpreg_base = ioremap(hpreg_res, 0x8000)) == NULL) { printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n"); goto err_out_free_res; } @@ -3090,13 +3040,13 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, macaddr[5]++; } else { #ifdef CONFIG_SPARC - unsigned char *addr; + const unsigned char *addr; int len; if (qfe_slot != -1 && - (addr = of_get_property(pcp->prom_node, - "local-mac-address", &len)) != NULL - && len == 6) { + (addr = of_get_property(dp, "local-mac-address", &len)) + != NULL && + len == 6) { memcpy(dev->dev_addr, addr, 6); } else { memcpy(dev->dev_addr, idprom->id_ethaddr, 6); @@ -3105,7 +3055,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]); #endif } - + /* Layout registers. */ hp->gregs = (hpreg_base + 0x0000UL); hp->etxregs = (hpreg_base + 0x2000UL); @@ -3114,13 +3064,9 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, hp->tcvregs = (hpreg_base + 0x7000UL); #ifdef CONFIG_SPARC - hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff); - if (hp->hm_revision == 0xff) { - unsigned char prev; - - pci_read_config_byte(pdev, PCI_REVISION_ID, &prev); - hp->hm_revision = 0xc0 | (prev & 0x0f); - } + hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff); + if (hp->hm_revision == 0xff) + hp->hm_revision = 0xc0 | (pdev->revision & 0x0f); #else /* works with this on non-sparc hosts */ hp->hm_revision = 0x20; @@ -3144,7 +3090,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, #endif hp->happy_block = (struct hmeal_init_block *) - pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma); + dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &hp->hblock_dvma, GFP_KERNEL); err = -ENODEV; if (!hp->happy_block) { @@ -3159,12 +3105,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, init_timer(&hp->happy_timer); hp->dev = dev; - dev->open = &happy_meal_open; - dev->stop = &happy_meal_close; - dev->hard_start_xmit = &happy_meal_start_xmit; - dev->get_stats = &happy_meal_get_stats; - dev->set_multicast_list = &happy_meal_set_multicast; - dev->tx_timeout = &happy_meal_tx_timeout; + dev->netdev_ops = &hme_netdev_ops; dev->watchdog_timeo = 5*HZ; dev->ethtool_ops = &hme_ethtool_ops; dev->irq = pdev->irq; @@ -3174,16 +3115,10 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) - /* Hook up PCI register/dma accessors. */ + /* Hook up PCI register/descriptor accessors. */ hp->read_desc32 = pci_hme_read_desc32; hp->write_txd = pci_hme_write_txd; hp->write_rxd = pci_hme_write_rxd; - hp->dma_map = (u32 (*)(void *, void *, long, int))pci_map_single; - hp->dma_unmap = (void (*)(void *, u32, long, int))pci_unmap_single; - hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int)) - pci_dma_sync_single_for_cpu; - hp->dma_sync_for_device = (void (*)(void *, u32, long, int)) - pci_dma_sync_single_for_device; hp->read32 = pci_hme_read32; hp->write32 = pci_hme_write32; #endif @@ -3216,7 +3151,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, qpdev->device == PCI_DEVICE_ID_DEC_21153) printk("DEC 21153 PCI Bridge\n"); else - printk("unknown bridge %04x.%04x\n", + printk("unknown bridge %04x.%04x\n", qpdev->vendor, qpdev->device); } @@ -3227,10 +3162,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, printk(KERN_INFO "%s: HAPPY MEAL (PCI/CheerIO) 10/100BaseT Ethernet ", dev->name); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], i == 5 ? ' ' : ':'); - - printk("\n"); + printk("%pM\n", dev->dev_addr); return 0; @@ -3257,10 +3189,8 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) unregister_netdev(net_dev); - pci_free_consistent(hp->happy_dev, - PAGE_SIZE, - hp->happy_block, - hp->hblock_dvma); + dma_free_coherent(hp->dma_dev, PAGE_SIZE, + hp->happy_block, hp->hblock_dvma); iounmap(hp->gregs); pci_release_regions(hp->happy_dev); @@ -3269,13 +3199,8 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) dev_set_drvdata(&pdev->dev, NULL); } -static struct pci_device_id happymeal_pci_ids[] = { - { - .vendor = PCI_VENDOR_ID_SUN, - .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, +static DEFINE_PCI_DEVICE_TABLE(happymeal_pci_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) }, { } /* Terminating entry */ }; @@ -3290,7 +3215,7 @@ static struct pci_driver hme_pci_driver = { static int __init happy_meal_pci_init(void) { - return pci_module_init(&hme_pci_driver); + return pci_register_driver(&hme_pci_driver); } static void happy_meal_pci_exit(void) @@ -3310,46 +3235,45 @@ static void happy_meal_pci_exit(void) #endif #ifdef CONFIG_SBUS -static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match) +static int __devinit hme_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; - char *model = of_get_property(dp, "model", NULL); + struct device_node *dp = op->dev.of_node; + const char *model = of_get_property(dp, "model", NULL); int is_qfe = (match->data != NULL); if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) is_qfe = 1; - return happy_meal_sbus_probe_one(sdev, is_qfe); + return happy_meal_sbus_probe_one(op, is_qfe); } -static int __devexit hme_sbus_remove(struct of_device *dev) +static int __devexit hme_sbus_remove(struct of_device *op) { - struct happy_meal *hp = dev_get_drvdata(&dev->dev); + struct happy_meal *hp = dev_get_drvdata(&op->dev); struct net_device *net_dev = hp->dev; - unregister_netdevice(net_dev); + unregister_netdev(net_dev); /* XXX qfe parent interrupt... */ - sbus_iounmap(hp->gregs, GREG_REG_SIZE); - sbus_iounmap(hp->etxregs, ETX_REG_SIZE); - sbus_iounmap(hp->erxregs, ERX_REG_SIZE); - sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); - sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); - sbus_free_consistent(hp->happy_dev, - PAGE_SIZE, - hp->happy_block, - hp->hblock_dvma); + of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE); + of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE); + of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE); + of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE); + of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE); + dma_free_coherent(hp->dma_dev, + PAGE_SIZE, + hp->happy_block, + hp->hblock_dvma); free_netdev(net_dev); - dev_set_drvdata(&dev->dev, NULL); + dev_set_drvdata(&op->dev, NULL); return 0; } -static struct of_device_id hme_sbus_match[] = { +static const struct of_device_id hme_sbus_match[] = { { .name = "SUNW,hme", }, @@ -3367,8 +3291,11 @@ static struct of_device_id hme_sbus_match[] = { MODULE_DEVICE_TABLE(of, hme_sbus_match); static struct of_platform_driver hme_sbus_driver = { - .name = "hme", - .match_table = hme_sbus_match, + .driver = { + .name = "hme", + .owner = THIS_MODULE, + .of_match_table = hme_sbus_match, + }, .probe = hme_sbus_probe, .remove = __devexit_p(hme_sbus_remove), }; @@ -3377,9 +3304,9 @@ static int __init happy_meal_sbus_init(void) { int err; - err = of_register_driver(&hme_sbus_driver, &sbus_bus_type); + err = of_register_driver(&hme_sbus_driver, &of_bus_type); if (!err) - quattro_sbus_register_irqs(); + err = quattro_sbus_register_irqs(); return err; }