diff options
Diffstat (limited to 'drivers/net/ethernet/micrel/ksz884x.c')
| -rw-r--r-- | drivers/net/ethernet/micrel/ksz884x.c | 166 |
1 files changed, 71 insertions, 95 deletions
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 7ece990381c..064a48d0c36 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -1,5 +1,5 @@ /** - * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver + * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver * * Copyright (c) 2009-2010 Micrel, Inc. * Tristram Ha <Tristram.Ha@micrel.com> @@ -743,11 +743,10 @@ /* Change default LED mode. */ #define SET_DEFAULT_LED LED_SPEED_DUPLEX_ACT -#define MAC_ADDR_LEN 6 -#define MAC_ADDR_ORDER(i) (MAC_ADDR_LEN - 1 - (i)) +#define MAC_ADDR_ORDER(i) (ETH_ALEN - 1 - (i)) #define MAX_ETHERNET_BODY_SIZE 1500 -#define ETHERNET_HEADER_SIZE 14 +#define ETHERNET_HEADER_SIZE (14 + VLAN_HLEN) #define MAX_ETHERNET_PACKET_SIZE \ (MAX_ETHERNET_BODY_SIZE + ETHERNET_HEADER_SIZE) @@ -1043,7 +1042,7 @@ enum { * @valid: Valid setting indicating the entry is being used. */ struct ksz_mac_table { - u8 mac_addr[MAC_ADDR_LEN]; + u8 mac_addr[ETH_ALEN]; u16 vid; u8 fid; u8 ports; @@ -1187,8 +1186,8 @@ struct ksz_switch { u8 diffserv[DIFFSERV_ENTRIES]; u8 p_802_1p[PRIO_802_1P_ENTRIES]; - u8 br_addr[MAC_ADDR_LEN]; - u8 other_addr[MAC_ADDR_LEN]; + u8 br_addr[ETH_ALEN]; + u8 other_addr[ETH_ALEN]; u8 broad_per; u8 member; @@ -1292,14 +1291,14 @@ struct ksz_hw { int tx_int_mask; int tx_size; - u8 perm_addr[MAC_ADDR_LEN]; - u8 override_addr[MAC_ADDR_LEN]; - u8 address[ADDITIONAL_ENTRIES][MAC_ADDR_LEN]; + u8 perm_addr[ETH_ALEN]; + u8 override_addr[ETH_ALEN]; + u8 address[ADDITIONAL_ENTRIES][ETH_ALEN]; u8 addr_list_size; u8 mac_override; u8 promiscuous; u8 all_multi; - u8 multi_list[MAX_MULTICAST_LIST][MAC_ADDR_LEN]; + u8 multi_list[MAX_MULTICAST_LIST][ETH_ALEN]; u8 multi_bits[HW_MULTICAST_SIZE]; u8 multi_list_size; @@ -1488,7 +1487,7 @@ struct dev_priv { #define DRV_VERSION "1.0.0" #define DRV_RELDATE "Feb 8, 2010" -static char version[] __devinitdata = +static char version[] = "Micrel " DEVICE_NAME " " DRV_VERSION " (" DRV_RELDATE ")"; static u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x88, 0x42, 0x01 }; @@ -3654,7 +3653,7 @@ static void hw_add_wol_bcast(struct ksz_hw *hw) static const u8 mask[] = { 0x3F }; static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern); + hw_set_wol_frame(hw, 2, 1, mask, ETH_ALEN, pattern); } /** @@ -3689,7 +3688,7 @@ static void hw_add_wol_ucast(struct ksz_hw *hw) { static const u8 mask[] = { 0x3F }; - hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr); + hw_set_wol_frame(hw, 0, 1, mask, ETH_ALEN, hw->override_addr); } /** @@ -3914,7 +3913,7 @@ static void hw_start_rx(struct ksz_hw *hw) hw->rx_stop = 2; } -/* +/** * hw_stop_rx - stop receiving * @hw: The hardware instance. * @@ -4055,7 +4054,7 @@ static void hw_set_addr(struct ksz_hw *hw) { int i; - for (i = 0; i < MAC_ADDR_LEN; i++) + for (i = 0; i < ETH_ALEN; i++) writeb(hw->override_addr[MAC_ADDR_ORDER(i)], hw->io + KS884X_ADDR_0_OFFSET + i); @@ -4072,17 +4071,16 @@ static void hw_read_addr(struct ksz_hw *hw) { int i; - for (i = 0; i < MAC_ADDR_LEN; i++) + for (i = 0; i < ETH_ALEN; i++) hw->perm_addr[MAC_ADDR_ORDER(i)] = readb(hw->io + KS884X_ADDR_0_OFFSET + i); if (!hw->mac_override) { - memcpy(hw->override_addr, hw->perm_addr, MAC_ADDR_LEN); + memcpy(hw->override_addr, hw->perm_addr, ETH_ALEN); if (empty_addr(hw->override_addr)) { - memcpy(hw->perm_addr, DEFAULT_MAC_ADDRESS, - MAC_ADDR_LEN); + memcpy(hw->perm_addr, DEFAULT_MAC_ADDRESS, ETH_ALEN); memcpy(hw->override_addr, DEFAULT_MAC_ADDRESS, - MAC_ADDR_LEN); + ETH_ALEN); hw->override_addr[5] += hw->id; hw_set_addr(hw); } @@ -4130,16 +4128,16 @@ static int hw_add_addr(struct ksz_hw *hw, u8 *mac_addr) int i; int j = ADDITIONAL_ENTRIES; - if (!memcmp(hw->override_addr, mac_addr, MAC_ADDR_LEN)) + if (ether_addr_equal(hw->override_addr, mac_addr)) return 0; for (i = 0; i < hw->addr_list_size; i++) { - if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN)) + if (ether_addr_equal(hw->address[i], mac_addr)) return 0; if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i])) j = i; } if (j < ADDITIONAL_ENTRIES) { - memcpy(hw->address[j], mac_addr, MAC_ADDR_LEN); + memcpy(hw->address[j], mac_addr, ETH_ALEN); hw_ena_add_addr(hw, j, hw->address[j]); return 0; } @@ -4151,8 +4149,8 @@ static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr) int i; for (i = 0; i < hw->addr_list_size; i++) { - if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN)) { - memset(hw->address[i], 0, MAC_ADDR_LEN); + if (ether_addr_equal(hw->address[i], mac_addr)) { + memset(hw->address[i], 0, ETH_ALEN); writel(0, hw->io + ADD_ADDR_INCR * i + KS_ADD_ADDR_0_HI); return 0; @@ -4382,12 +4380,10 @@ static void ksz_update_timer(struct ksz_timer_info *info) */ static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit) { - desc_info->ring = kmalloc(sizeof(struct ksz_desc) * desc_info->alloc, - GFP_KERNEL); + desc_info->ring = kzalloc(sizeof(struct ksz_desc) * desc_info->alloc, + GFP_KERNEL); if (!desc_info->ring) return 1; - memset((void *) desc_info->ring, 0, - sizeof(struct ksz_desc) * desc_info->alloc); hw_init_desc(desc_info, transmit); return 0; } @@ -4484,14 +4480,12 @@ static void ksz_init_rx_buffers(struct dev_info *adapter) dma_buf->len = adapter->mtu; if (!dma_buf->skb) dma_buf->skb = alloc_skb(dma_buf->len, GFP_ATOMIC); - if (dma_buf->skb && !dma_buf->dma) { - dma_buf->skb->dev = adapter->dev; + if (dma_buf->skb && !dma_buf->dma) dma_buf->dma = pci_map_single( adapter->pdev, skb_tail_pointer(dma_buf->skb), dma_buf->len, PCI_DMA_FROMDEVICE); - } /* Set descriptor. */ set_rx_buf(desc, dma_buf->dma); @@ -4767,7 +4761,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal) struct ksz_dma_buf *dma_buf; struct net_device *dev = NULL; - spin_lock(&hw_priv->hwlock); + spin_lock_irq(&hw_priv->hwlock); last = info->last; while (info->avail < info->alloc) { @@ -4801,7 +4795,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal) info->avail++; } info->last = last; - spin_unlock(&hw_priv->hwlock); + spin_unlock_irq(&hw_priv->hwlock); /* Notify the network subsystem that the packet has been sent. */ if (dev) @@ -4838,7 +4832,7 @@ static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb) skb->csum = old->csum; skb_set_network_header(skb, ETH_HLEN); - dev_kfree_skb(old); + dev_consume_skb_any(old); } /** @@ -4867,7 +4861,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) memset(&skb->data[skb->len], 0, 50 - skb->len); skb->len = 50; } else { - skb = dev_alloc_skb(50); + skb = netdev_alloc_skb(dev, 50); if (!skb) return NETDEV_TX_BUSY; memcpy(skb->data, org_skb->data, org_skb->len); @@ -4885,11 +4879,11 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) left = hw_alloc_pkt(hw, skb->len, num); if (left) { if (left < num || - ((CHECKSUM_PARTIAL == skb->ip_summed) && - (ETH_P_IPV6 == htons(skb->protocol)))) { + (CHECKSUM_PARTIAL == skb->ip_summed && + skb->protocol == htons(ETH_P_IPV6))) { struct sk_buff *org_skb = skb; - skb = dev_alloc_skb(org_skb->len); + skb = netdev_alloc_skb(dev, org_skb->len); if (!skb) { rc = NETDEV_TX_BUSY; goto unlock; @@ -4936,7 +4930,7 @@ static void netdev_tx_timeout(struct net_device *dev) * Only reset the hardware if time between calls is long * enough. */ - if (jiffies - last_reset <= dev->watchdog_timeo) + if (time_before_eq(jiffies, last_reset + dev->watchdog_timeo)) hw_priv = NULL; } @@ -5023,7 +5017,7 @@ static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw, do { /* skb->data != skb->head */ - skb = dev_alloc_skb(packet_len + 2); + skb = netdev_alloc_skb(dev, packet_len + 2); if (!skb) { dev->stats.rx_dropped++; return -ENOMEM; @@ -5265,11 +5259,15 @@ static irqreturn_t netdev_intr(int irq, void *dev_id) struct dev_info *hw_priv = priv->adapter; struct ksz_hw *hw = &hw_priv->hw; + spin_lock(&hw_priv->hwlock); + hw_read_intr(hw, &int_enable); /* Not our interrupt! */ - if (!int_enable) + if (!int_enable) { + spin_unlock(&hw_priv->hwlock); return IRQ_NONE; + } do { hw_ack_intr(hw, int_enable); @@ -5316,6 +5314,8 @@ static irqreturn_t netdev_intr(int irq, void *dev_id) hw_ena_intr(hw); + spin_unlock(&hw_priv->hwlock); + return IRQ_HANDLED; } @@ -5413,8 +5413,8 @@ static int netdev_close(struct net_device *dev) /* Delay for receive task to stop scheduling itself. */ msleep(2000 / HZ); - tasklet_disable(&hw_priv->rx_tasklet); - tasklet_disable(&hw_priv->tx_tasklet); + tasklet_kill(&hw_priv->rx_tasklet); + tasklet_kill(&hw_priv->tx_tasklet); free_irq(dev->irq, hw_priv->dev); transmit_cleanup(hw_priv, 0); @@ -5465,8 +5465,10 @@ static int prepare_hardware(struct net_device *dev) rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); if (rc) return rc; - tasklet_enable(&hw_priv->rx_tasklet); - tasklet_enable(&hw_priv->tx_tasklet); + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, + (unsigned long) hw_priv); + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, + (unsigned long) hw_priv); hw->promiscuous = 0; hw->all_multi = 0; @@ -5676,10 +5678,10 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr) hw_del_addr(hw, dev->dev_addr); else { hw->mac_override = 1; - memcpy(hw->override_addr, mac->sa_data, MAC_ADDR_LEN); + memcpy(hw->override_addr, mac->sa_data, ETH_ALEN); } - memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); + memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN); interrupt = hw_block_intr(hw); @@ -5786,7 +5788,7 @@ static void netdev_set_rx_mode(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { if (i >= MAX_MULTICAST_LIST) break; - memcpy(hw->multi_list[i++], ha->addr, MAC_ADDR_LEN); + memcpy(hw->multi_list[i++], ha->addr, ETH_ALEN); } hw->multi_list_size = (u8) i; hw_set_grp_addr(hw); @@ -5851,15 +5853,12 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct dev_info *hw_priv = priv->adapter; struct ksz_hw *hw = &hw_priv->hw; struct ksz_port *port = &priv->port; - int rc; int result = 0; struct mii_ioctl_data *data = if_mii(ifr); if (down_interruptible(&priv->proc_sem)) return -ERESTARTSYS; - /* assume success */ - rc = 0; switch (cmd) { /* Get address of MII PHY in use. */ case SIOCGMIIPHY: @@ -6093,9 +6092,10 @@ static void netdev_get_drvinfo(struct net_device *dev, struct dev_priv *priv = netdev_priv(dev); struct dev_info *hw_priv = priv->adapter; - strcpy(info->driver, DRV_NAME); - strcpy(info->version, DRV_VERSION); - strcpy(info->bus_info, pci_name(hw_priv->pdev)); + strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); + strlcpy(info->version, DRV_VERSION, sizeof(info->version)); + strlcpy(info->bus_info, pci_name(hw_priv->pdev), + sizeof(info->bus_info)); } /** @@ -6587,7 +6587,8 @@ static void netdev_get_ethtool_stats(struct net_device *dev, * * Return 0 if successful; otherwise an error code. */ -static int netdev_set_features(struct net_device *dev, u32 features) +static int netdev_set_features(struct net_device *dev, + netdev_features_t features) { struct dev_priv *priv = netdev_priv(dev); struct dev_info *hw_priv = priv->adapter; @@ -6609,7 +6610,7 @@ static int netdev_set_features(struct net_device *dev, u32 features) return 0; } -static struct ethtool_ops netdev_ethtool_ops = { +static const struct ethtool_ops netdev_ethtool_ops = { .get_settings = netdev_get_settings, .set_settings = netdev_set_settings, .nway_reset = netdev_nway_reset, @@ -6771,7 +6772,7 @@ static int stp; /* * This enables fast aging in the KSZ8842 switch. Not sure what situation * needs that. However, fast aging is used to flush the dynamic MAC table when - * STP suport is enabled. + * STP support is enabled. */ static int fast_aging; @@ -6860,7 +6861,7 @@ static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port) int num; i = j = num = got_num = 0; - while (j < MAC_ADDR_LEN) { + while (j < ETH_ALEN) { if (macaddr[i]) { int digit; @@ -6891,7 +6892,7 @@ static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port) } i++; } - if (MAC_ADDR_LEN == j) { + if (ETH_ALEN == j) { if (MAIN_PORT == port) hw_priv->hw.mac_override = 1; } @@ -6921,8 +6922,7 @@ static void read_other_addr(struct ksz_hw *hw) #define PCI_VENDOR_ID_MICREL_KS 0x16c6 #endif -static int __devinit pcidev_init(struct pci_dev *pdev, - const struct pci_device_id *id) +static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *dev; struct dev_priv *priv; @@ -7037,16 +7037,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev, spin_lock_init(&hw_priv->hwlock); mutex_init(&hw_priv->lock); - /* tasklet is enabled. */ - tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, - (unsigned long) hw_priv); - tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, - (unsigned long) hw_priv); - - /* tasklet_enable will decrement the atomic counter. */ - tasklet_disable(&hw_priv->rx_tasklet); - tasklet_disable(&hw_priv->tx_tasklet); - for (i = 0; i < TOTAL_PORT_NUM; i++) init_waitqueue_head(&hw_priv->counter[i].counter); @@ -7058,7 +7048,7 @@ static int __devinit pcidev_init(struct pci_dev *pdev, /* Multiple device interfaces mode requires a second MAC address. */ if (hw->dev_count > 1) { - memcpy(sw->other_addr, hw->override_addr, MAC_ADDR_LEN); + memcpy(sw->other_addr, hw->override_addr, ETH_ALEN); read_other_addr(hw); if (mac1addr[0] != ':') get_mac_addr(hw_priv, mac1addr, OTHER_PORT); @@ -7082,6 +7072,7 @@ static int __devinit pcidev_init(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct dev_priv)); if (!dev) goto pcidev_init_reg_err; + SET_NETDEV_DEV(dev, &pdev->dev); info->netdev[i] = dev; priv = netdev_priv(dev); @@ -7108,17 +7099,15 @@ static int __devinit pcidev_init(struct pci_dev *pdev, dev->irq = pdev->irq; if (MAIN_PORT == i) memcpy(dev->dev_addr, hw_priv->hw.override_addr, - MAC_ADDR_LEN); + ETH_ALEN); else { - memcpy(dev->dev_addr, sw->other_addr, - MAC_ADDR_LEN); - if (!memcmp(sw->other_addr, hw->override_addr, - MAC_ADDR_LEN)) + memcpy(dev->dev_addr, sw->other_addr, ETH_ALEN); + if (ether_addr_equal(sw->other_addr, hw->override_addr)) dev->dev_addr[5] += port->first_port; } dev->netdev_ops = &netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); + dev->ethtool_ops = &netdev_ethtool_ops; if (register_netdev(dev)) goto pcidev_init_reg_err; port_set_power_saving(port, true); @@ -7158,8 +7147,6 @@ static void pcidev_exit(struct pci_dev *pdev) struct platform_info *info = pci_get_drvdata(pdev); struct dev_info *hw_priv = &info->dev_info; - pci_set_drvdata(pdev, NULL); - release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); for (i = 0; i < hw_priv->hw.dev_count; i++) { @@ -7235,7 +7222,7 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state) static char pcidev_name[] = "ksz884xp"; -static struct pci_device_id pcidev_table[] = { +static DEFINE_PCI_DEVICE_TABLE(pcidev_table) = { { PCI_VENDOR_ID_MICREL_KS, 0x8841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_MICREL_KS, 0x8842, @@ -7256,18 +7243,7 @@ static struct pci_driver pci_device_driver = { .remove = pcidev_exit }; -static int __init ksz884x_init_module(void) -{ - return pci_register_driver(&pci_device_driver); -} - -static void __exit ksz884x_cleanup_module(void) -{ - pci_unregister_driver(&pci_device_driver); -} - -module_init(ksz884x_init_module); -module_exit(ksz884x_cleanup_module); +module_pci_driver(pci_device_driver); MODULE_DESCRIPTION("KSZ8841/2 PCI network driver"); MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>"); |
