X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fipg.c;h=150415e83f61e21e3cdc25f85a9d892b849c7016;hb=92bc3648e6027384479852b770a542722fadee7c;hp=57395b9587dc8efe068fd8f0a35895269f666318;hpb=da02b23192e8c1dc6830fc38840ea1c5e416a43c;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 57395b9..150415e 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -42,7 +42,6 @@ #define ipg_r16(reg) ioread16(ioaddr + (reg)) #define ipg_r8(reg) ioread8(ioaddr + (reg)) -#define JUMBO_FRAME_4k_ONLY enum { netdev_io_size = 128 }; @@ -55,6 +54,14 @@ MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver"); MODULE_LICENSE("GPL"); /* + * Defaults + */ +#define IPG_MAX_RXFRAME_SIZE 0x0600 +#define IPG_RXFRAG_SIZE 0x0600 +#define IPG_RXSUPPORT_SIZE 0x0600 +#define IPG_IS_JUMBO false + +/* * Variable record -- index by leading revision/length * Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN */ @@ -81,17 +88,15 @@ static const char *ipg_brand_name[] = { "Sundance Technology ST2021 based NIC", "Tamarack Microelectronics TC9020/9021 based NIC", "Tamarack Microelectronics TC9020/9021 based NIC", - "D-Link NIC", "D-Link NIC IP1000A" }; -static struct pci_device_id ipg_pci_tbl[] __devinitdata = { +static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = { { PCI_VDEVICE(SUNDANCE, 0x1023), 0 }, { PCI_VDEVICE(SUNDANCE, 0x2021), 1 }, { PCI_VDEVICE(SUNDANCE, 0x1021), 2 }, { PCI_VDEVICE(DLINK, 0x9021), 3 }, - { PCI_VDEVICE(DLINK, 0x4000), 4 }, - { PCI_VDEVICE(DLINK, 0x4020), 5 }, + { PCI_VDEVICE(DLINK, 0x4020), 4 }, { 0, } }; @@ -578,11 +583,11 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) receivemode = IPG_RM_RECEIVEALLFRAMES; } else if ((dev->flags & IFF_ALLMULTI) || ((dev->flags & IFF_MULTICAST) && - (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { + (netdev_mc_count(dev) > IPG_MULTICAST_HASHTABLE_SIZE))) { /* NIC to be configured to receive all multicast * frames. */ receivemode |= IPG_RM_RECEIVEMULTICAST; - } else if ((dev->flags & IFF_MULTICAST) && (dev->mc_count > 0)) { + } else if ((dev->flags & IFF_MULTICAST) && !netdev_mc_empty(dev)) { /* NIC to be configured to receive selected * multicast addresses. */ receivemode |= IPG_RM_RECEIVEMULTICASTHASH; @@ -603,8 +608,7 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) hashtable[1] = 0x00000000; /* Cycle through all multicast addresses to filter. */ - for (mc_list_ptr = dev->mc_list; - mc_list_ptr != NULL; mc_list_ptr = mc_list_ptr->next) { + netdev_for_each_mc_addr(mc_list_ptr, dev) { /* Calculate CRC result for each multicast address. */ hashindex = crc32_le(0xffffffff, mc_list_ptr->dmi_addr, ETH_ALEN); @@ -731,17 +735,12 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry) IPG_DEBUG_MSG("_get_rxbuff\n"); - skb = netdev_alloc_skb(dev, sp->rxsupport_size + NET_IP_ALIGN); + skb = netdev_alloc_skb_ip_align(dev, sp->rxsupport_size); if (!skb) { sp->rx_buff[entry] = NULL; return -ENOMEM; } - /* Adjust the data start location within the buffer to - * align IP address field to a 16 byte boundary. - */ - skb_reserve(skb, NET_IP_ALIGN); - /* Associate the receive buffer with the IPG NIC. */ skb->dev = dev; @@ -1105,7 +1104,7 @@ static void ipg_nic_rx_free_skb(struct net_device *dev) struct ipg_rx *rxfd = sp->rxd + entry; pci_unmap_single(sp->pdev, - le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, sp->rx_buf_sz, PCI_DMA_FROMDEVICE); dev_kfree_skb_irq(sp->rx_buff[entry]); sp->rx_buff[entry] = NULL; @@ -1172,7 +1171,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev) */ if (sp->rx_buff[entry]) { pci_unmap_single(sp->pdev, - le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, sp->rx_buf_sz, PCI_DMA_FROMDEVICE); dev_kfree_skb_irq(sp->rx_buff[entry]); @@ -1215,7 +1214,6 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev, skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_NONE; netif_rx(skb); - dev->last_rx = jiffies; sp->rx_buff[entry] = NULL; } @@ -1239,7 +1237,7 @@ static void ipg_nic_rx_with_start(struct net_device *dev, if (jumbo->found_start) dev_kfree_skb_irq(jumbo->skb); - pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, sp->rx_buf_sz, PCI_DMA_FROMDEVICE); skb_put(skb, sp->rxfrag_size); @@ -1249,7 +1247,6 @@ static void ipg_nic_rx_with_start(struct net_device *dev, jumbo->skb = skb; sp->rx_buff[entry] = NULL; - dev->last_rx = jiffies; } static void ipg_nic_rx_with_end(struct net_device *dev, @@ -1285,7 +1282,6 @@ static void ipg_nic_rx_with_end(struct net_device *dev, } } - dev->last_rx = jiffies; jumbo->found_start = 0; jumbo->current_size = 0; jumbo->skb = NULL; @@ -1318,7 +1314,6 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev, skb->data, sp->rxfrag_size); } } - dev->last_rx = jiffies; ipg_nic_rx_free_skb(dev); } } else { @@ -1342,7 +1337,7 @@ static int ipg_nic_rx_jumbo(struct net_device *dev) unsigned int entry = curr % IPG_RFDLIST_LENGTH; struct ipg_rx *rxfd = sp->rxd + entry; - if (!(rxfd->rfs & le64_to_cpu(IPG_RFS_RFDDONE))) + if (!(rxfd->rfs & cpu_to_le64(IPG_RFS_RFDDONE))) break; switch (ipg_nic_rx_check_frame_type(dev)) { @@ -1487,11 +1482,6 @@ static int ipg_nic_rx(struct net_device *dev) * when processing completes. */ netif_rx(skb); - - /* Record frame receive time (jiffies = Linux - * kernel current time stamp). - */ - dev->last_rx = jiffies; } /* Assure RX buffer is not reused by IPG. */ @@ -1758,7 +1748,7 @@ static int ipg_nic_open(struct net_device *dev) /* Register the interrupt line to be used by the IPG within * the Linux system. */ - rc = request_irq(pdev->irq, &ipg_interrupt_handler, IRQF_SHARED, + rc = request_irq(pdev->irq, ipg_interrupt_handler, IRQF_SHARED, dev->name, dev); if (rc < 0) { printk(KERN_INFO "%s: Error when requesting interrupt.\n", @@ -1805,9 +1795,6 @@ static int ipg_nic_open(struct net_device *dev) sp->jumbo.current_size = 0; sp->jumbo.skb = NULL; - if (IPG_TXFRAG_SIZE) - dev->mtu = IPG_TXFRAG_SIZE; - /* Enable transmit and receive operation of the IPG. */ ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_RX_ENABLE | IPG_MC_TX_ENABLE) & IPG_MC_RSVD_MASK, MAC_CTRL); @@ -1863,7 +1850,8 @@ static int ipg_nic_stop(struct net_device *dev) return 0; } -static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t ipg_nic_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) { struct ipg_nic_private *sp = netdev_priv(dev); void __iomem *ioaddr = sp->ioaddr; @@ -2116,6 +2104,7 @@ static int ipg_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) { struct ipg_nic_private *sp = netdev_priv(dev); + int err; /* Function to accomodate changes to Maximum Transfer Unit * (or MTU) of IPG NIC. Cannot use default function since @@ -2124,16 +2113,33 @@ static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) IPG_DEBUG_MSG("_nic_change_mtu\n"); - /* Check that the new MTU value is between 68 (14 byte header, 46 - * byte payload, 4 byte FCS) and IPG_MAX_RXFRAME_SIZE, which - * corresponds to the MAXFRAMESIZE register in the IPG. + /* + * Check that the new MTU value is between 68 (14 byte header, 46 byte + * payload, 4 byte FCS) and 10 KB, which is the largest supported MTU. */ - if ((new_mtu < 68) || (new_mtu > sp->max_rxframe_size)) + if (new_mtu < 68 || new_mtu > 10240) return -EINVAL; + err = ipg_nic_stop(dev); + if (err) + return err; + dev->mtu = new_mtu; - return 0; + sp->max_rxframe_size = new_mtu; + + sp->rxfrag_size = new_mtu; + if (sp->rxfrag_size > 4088) + sp->rxfrag_size = 4088; + + sp->rxsupport_size = sp->max_rxframe_size; + + if (new_mtu > 0x0600) + sp->is_jumbo = true; + else + sp->is_jumbo = false; + + return ipg_nic_open(dev); } static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) @@ -2172,7 +2178,7 @@ static int ipg_nway_reset(struct net_device *dev) return rc; } -static struct ethtool_ops ipg_ethtool_ops = { +static const struct ethtool_ops ipg_ethtool_ops = { .get_settings = ipg_get_settings, .set_settings = ipg_set_settings, .nway_reset = ipg_nway_reset, @@ -2197,6 +2203,19 @@ static void __devexit ipg_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +static const struct net_device_ops ipg_netdev_ops = { + .ndo_open = ipg_nic_open, + .ndo_stop = ipg_nic_stop, + .ndo_start_xmit = ipg_nic_hard_start_xmit, + .ndo_get_stats = ipg_nic_get_stats, + .ndo_set_multicast_list = ipg_nic_set_multicast_list, + .ndo_do_ioctl = ipg_ioctl, + .ndo_tx_timeout = ipg_tx_timeout, + .ndo_change_mtu = ipg_nic_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit ipg_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -2214,9 +2233,9 @@ static int __devinit ipg_probe(struct pci_dev *pdev, pci_set_master(pdev); - rc = pci_set_dma_mask(pdev, DMA_40BIT_MASK); + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(40)); if (rc < 0) { - rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc < 0) { printk(KERN_ERR "%s: DMA config failed.\n", pci_name(pdev)); @@ -2238,22 +2257,14 @@ static int __devinit ipg_probe(struct pci_dev *pdev, spin_lock_init(&sp->lock); mutex_init(&sp->mii_mutex); - sp->is_jumbo = IPG_JUMBO; + sp->is_jumbo = IPG_IS_JUMBO; sp->rxfrag_size = IPG_RXFRAG_SIZE; sp->rxsupport_size = IPG_RXSUPPORT_SIZE; sp->max_rxframe_size = IPG_MAX_RXFRAME_SIZE; /* Declare IPG NIC functions for Ethernet device methods. */ - dev->open = &ipg_nic_open; - dev->stop = &ipg_nic_stop; - dev->hard_start_xmit = &ipg_nic_hard_start_xmit; - dev->get_stats = &ipg_nic_get_stats; - dev->set_multicast_list = &ipg_nic_set_multicast_list; - dev->do_ioctl = ipg_ioctl; - dev->tx_timeout = ipg_tx_timeout; - dev->change_mtu = &ipg_nic_change_mtu; - + dev->netdev_ops = &ipg_netdev_ops; SET_NETDEV_DEV(dev, &pdev->dev); SET_ETHTOOL_OPS(dev, &ipg_ethtool_ops);