From 580a690208321ed45addef5ef12e25b87f9f5dec Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:03:44 +0200 Subject: via-velocity: remove the bounce buffers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Executive summary: the bounce buffers are in my way - they use something like a 64 * 1500 bytes area of PCI consistent area - they are not resized when the MTU changes - they are used - to hand-pad undersized packets. skb_pad anyone ? - to linearize fragmented skbs whose fragment count goes beyond the 7 fragments hardware limit in order to claim scatter-gather support Actually the SG code is commented out and I wonder if it could not be implemented (ab-)using the large send feature of the chipset since the latter should support some multi-descriptor packet transmitting. Signed-off-by: Francois Romieu Fixed-by: Séguier Régis Signed-off-by: Jeff Garzik --- drivers/net/via-velocity.c | 72 ++++++++++++---------------------------------- drivers/net/via-velocity.h | 5 ---- 2 files changed, 18 insertions(+), 59 deletions(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index bcbf2fa9b94..fce2dfd0e9e 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1104,7 +1104,6 @@ static int velocity_init_rings(struct velocity_info *vptr) { int i; unsigned int psize; - unsigned int tsize; dma_addr_t pool_dma; u8 *pool; @@ -1133,19 +1132,6 @@ static int velocity_init_rings(struct velocity_info *vptr) vptr->rd_pool_dma = pool_dma; - tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq; - vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize, - &vptr->tx_bufs_dma); - - if (vptr->tx_bufs == NULL) { - printk(KERN_ERR "%s: DMA memory allocation failed.\n", - vptr->dev->name); - pci_free_consistent(vptr->pdev, psize, pool, pool_dma); - return -ENOMEM; - } - - memset(vptr->tx_bufs, 0, vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq); - i = vptr->options.numrx * sizeof(struct rx_desc); pool += i; pool_dma += i; @@ -1169,16 +1155,10 @@ static int velocity_init_rings(struct velocity_info *vptr) static void velocity_free_rings(struct velocity_info *vptr) { - int size; - - size = vptr->options.numrx * sizeof(struct rx_desc) + - vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq; + const int size = vptr->options.numrx * sizeof(struct rx_desc) + + vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq; pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma); - - size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq; - - pci_free_consistent(vptr->pdev, size, vptr->tx_bufs, vptr->tx_bufs_dma); } static inline void velocity_give_many_rx_descs(struct velocity_info *vptr) @@ -1313,10 +1293,8 @@ static void velocity_free_rd_ring(struct velocity_info *vptr) static int velocity_init_td_ring(struct velocity_info *vptr) { - int i, j; dma_addr_t curr; - struct tx_desc *td; - struct velocity_td_info *td_info; + unsigned int j; /* Init the TD ring entries */ for (j = 0; j < vptr->num_txq; j++) { @@ -1331,14 +1309,6 @@ static int velocity_init_td_ring(struct velocity_info *vptr) return -ENOMEM; } - for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) { - td = &(vptr->td_rings[j][i]); - td_info = &(vptr->td_infos[j][i]); - td_info->buf = vptr->tx_bufs + - (j * vptr->options.numtx + i) * PKT_BUF_SZ; - td_info->buf_dma = vptr->tx_bufs_dma + - (j * vptr->options.numtx + i) * PKT_BUF_SZ; - } vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0; } return 0; @@ -1867,7 +1837,7 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_ /* * Don't unmap the pre-allocated tx_bufs */ - if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) { + if (tdinfo->skb_dma) { for (i = 0; i < tdinfo->nskb_dma; i++) { #ifdef VELOCITY_ZERO_COPY_SUPPORT @@ -2063,9 +2033,19 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) struct tx_desc *td_ptr; struct velocity_td_info *tdinfo; unsigned long flags; - int index; int pktlen = skb->len; - __le16 len = cpu_to_le16(pktlen); + __le16 len; + int index; + + + + if (skb->len < ETH_ZLEN) { + if (skb_padto(skb, ETH_ZLEN)) + goto out; + pktlen = ETH_ZLEN; + } + + len = cpu_to_le16(pktlen); #ifdef VELOCITY_ZERO_COPY_SUPPORT if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) { @@ -2083,23 +2063,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) td_ptr->tdesc1.TCR = TCR0_TIC; td_ptr->td_buf[0].size &= ~TD_QUEUE; - /* - * Pad short frames. - */ - if (pktlen < ETH_ZLEN) { - /* Cannot occur until ZC support */ - pktlen = ETH_ZLEN; - len = cpu_to_le16(ETH_ZLEN); - skb_copy_from_linear_data(skb, tdinfo->buf, skb->len); - memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); - tdinfo->skb = skb; - tdinfo->skb_dma[0] = tdinfo->buf_dma; - td_ptr->tdesc0.len = len; - td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); - td_ptr->td_buf[0].pa_high = 0; - td_ptr->td_buf[0].size = len; /* queue is 0 anyway */ - tdinfo->nskb_dma = 1; - } else #ifdef VELOCITY_ZERO_COPY_SUPPORT if (skb_shinfo(skb)->nr_frags > 0) { int nfrags = skb_shinfo(skb)->nr_frags; @@ -2191,7 +2154,8 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) } dev->trans_start = jiffies; spin_unlock_irqrestore(&vptr->lock, flags); - return 0; +out: + return NETDEV_TX_OK; } /** diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index 7387be4f428..86446147284 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -236,10 +236,8 @@ struct velocity_rd_info { struct velocity_td_info { struct sk_buff *skb; - u8 *buf; int nskb_dma; dma_addr_t skb_dma[7]; - dma_addr_t buf_dma; }; enum velocity_owner { @@ -1506,9 +1504,6 @@ struct velocity_info { dma_addr_t rd_pool_dma; dma_addr_t td_pool_dma[TX_QUEUE_NO]; - dma_addr_t tx_bufs_dma; - u8 *tx_bufs; - struct vlan_group *vlgrp; u8 ip_addr[4]; enum chip_type chip_id; -- cgit v1.2.3 From 8ac53afccf7ab383fd97db8910117ae7892c72a7 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:04:33 +0200 Subject: via-velocity: lean and clean velocity_init_rings - PCI consistent areas need no memset - use dev_err instead of plain printk - avoid a few casts Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/via-velocity.c | 48 ++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index fce2dfd0e9e..86b256cbeaf 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1102,47 +1102,41 @@ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pc static int velocity_init_rings(struct velocity_info *vptr) { - int i; - unsigned int psize; + struct velocity_opt *opt = &vptr->options; + const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc); + const unsigned int tx_ring_size = opt->numtx * sizeof(struct tx_desc); + struct pci_dev *pdev = vptr->pdev; dma_addr_t pool_dma; - u8 *pool; - - /* - * Allocate all RD/TD rings a single pool - */ - - psize = vptr->options.numrx * sizeof(struct rx_desc) + - vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq; + void *pool; + unsigned int i; /* + * Allocate all RD/TD rings a single pool. + * * pci_alloc_consistent() fulfills the requirement for 64 bytes * alignment */ - pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma); - - if (pool == NULL) { - printk(KERN_ERR "%s : DMA memory allocation failed.\n", - vptr->dev->name); + pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->num_txq + + rx_ring_size, &pool_dma); + if (!pool) { + dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n", + vptr->dev->name); return -ENOMEM; } - memset(pool, 0, psize); - - vptr->rd_ring = (struct rx_desc *) pool; - + vptr->rd_ring = pool; vptr->rd_pool_dma = pool_dma; - i = vptr->options.numrx * sizeof(struct rx_desc); - pool += i; - pool_dma += i; - for (i = 0; i < vptr->num_txq; i++) { - int offset = vptr->options.numtx * sizeof(struct tx_desc); + pool += rx_ring_size; + pool_dma += rx_ring_size; + for (i = 0; i < vptr->num_txq; i++) { + vptr->td_rings[i] = pool; vptr->td_pool_dma[i] = pool_dma; - vptr->td_rings[i] = (struct tx_desc *) pool; - pool += offset; - pool_dma += offset; + pool += tx_ring_size; + pool_dma += tx_ring_size; } + return 0; } -- cgit v1.2.3 From 28133176082d9bcafb5958b8fac80943e51d5eda Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:05:17 +0200 Subject: via-velocity: move residual free rx descriptors count register update Updates of the RBRDU have two different meanings depending on their context: 1. the receiving process has not started - the value which is written into the RBRDU register is supposed to be the free rx descriptors count (rounded to a multiple of 4) 2. the receiving process is running - the value increments the count above (sic) The update is currently issued deep inside the rx replenish chain (see velocity_give_many_rx_descs). Let's propagate enough information to the caller so that the rx replenish functions do not depend on hardware any more. It is needed to perform the Rx/Tx buffers housekeeping when MTU changes. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/via-velocity.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 86b256cbeaf..086d69c1992 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1155,7 +1155,7 @@ static void velocity_free_rings(struct velocity_info *vptr) pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma); } -static inline void velocity_give_many_rx_descs(struct velocity_info *vptr) +static void velocity_give_many_rx_descs(struct velocity_info *vptr) { struct mac_regs __iomem *regs = vptr->mac_regs; int avail, dirty, unusable; @@ -1182,7 +1182,7 @@ static inline void velocity_give_many_rx_descs(struct velocity_info *vptr) static int velocity_rx_refill(struct velocity_info *vptr) { - int dirty = vptr->rd_dirty, done = 0, ret = 0; + int dirty = vptr->rd_dirty, done = 0; do { struct rx_desc *rd = vptr->rd_ring + dirty; @@ -1192,8 +1192,7 @@ static int velocity_rx_refill(struct velocity_info *vptr) break; if (!vptr->rd_info[dirty].skb) { - ret = velocity_alloc_rx_buf(vptr, dirty); - if (ret < 0) + if (velocity_alloc_rx_buf(vptr, dirty) < 0) break; } done++; @@ -1203,10 +1202,9 @@ static int velocity_rx_refill(struct velocity_info *vptr) if (done) { vptr->rd_dirty = dirty; vptr->rd_filled += done; - velocity_give_many_rx_descs(vptr); } - return ret; + return done; } /** @@ -1219,25 +1217,27 @@ static int velocity_rx_refill(struct velocity_info *vptr) static int velocity_init_rd_ring(struct velocity_info *vptr) { - int ret; int mtu = vptr->dev->mtu; + int ret = -ENOMEM; vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32; vptr->rd_info = kcalloc(vptr->options.numrx, sizeof(struct velocity_rd_info), GFP_KERNEL); if (!vptr->rd_info) - return -ENOMEM; + goto out; vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0; - ret = velocity_rx_refill(vptr); - if (ret < 0) { + if (velocity_rx_refill(vptr) != vptr->options.numrx) { VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: failed to allocate RX buffer.\n", vptr->dev->name); velocity_free_rd_ring(vptr); + goto out; } + ret = 0; +out: return ret; } @@ -1412,10 +1412,8 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status) vptr->rd_curr = rd_curr; - if (works > 0 && velocity_rx_refill(vptr) < 0) { - VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR - "%s: rx buf allocation failure\n", vptr->dev->name); - } + if ((works > 0) && (velocity_rx_refill(vptr) > 0)) + velocity_give_many_rx_descs(vptr); VAR_USED(stats); return works; @@ -1877,6 +1875,8 @@ static int velocity_open(struct net_device *dev) /* Ensure chip is running */ pci_set_power_state(vptr->pdev, PCI_D0); + velocity_give_many_rx_descs(vptr); + velocity_init_registers(vptr, VELOCITY_INIT_COLD); ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED, -- cgit v1.2.3 From 9088d9a4267ff098d5edc3dad8359c92741b7a6a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:05:57 +0200 Subject: via-velocity: add velocity_set_rxbufsize helper It removes a dependancy from velocity_init_rd_ring to dev->mtu. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/via-velocity.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 086d69c1992..370ce30f2f4 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1207,6 +1207,11 @@ static int velocity_rx_refill(struct velocity_info *vptr) return done; } +static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu) +{ + vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32; +} + /** * velocity_init_rd_ring - set up receive ring * @vptr: velocity to configure @@ -1217,11 +1222,8 @@ static int velocity_rx_refill(struct velocity_info *vptr) static int velocity_init_rd_ring(struct velocity_info *vptr) { - int mtu = vptr->dev->mtu; int ret = -ENOMEM; - vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32; - vptr->rd_info = kcalloc(vptr->options.numrx, sizeof(struct velocity_rd_info), GFP_KERNEL); if (!vptr->rd_info) @@ -1860,6 +1862,8 @@ static int velocity_open(struct net_device *dev) struct velocity_info *vptr = netdev_priv(dev); int ret; + velocity_set_rxbufsize(vptr, dev->mtu); + ret = velocity_init_rings(vptr); if (ret < 0) goto out; @@ -1941,6 +1945,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; + velocity_set_rxbufsize(vptr, new_mtu); + ret = velocity_init_rd_ring(vptr); if (ret < 0) goto out_unlock; -- cgit v1.2.3 From 3f78d88575d99e17218a5bb2d79e251a781d16ad Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Wed, 9 Jul 2008 23:47:46 -0400 Subject: S2io: Fix IOMMU overflow checking. - Fix IOMMU overflow checking. As reported by Andi Kleen removed check for zero dma address. Signed-off-by: Santosh Rastapur Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 51a91154125..685030bb1d5 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2501,6 +2501,9 @@ static void stop_nic(struct s2io_nic *nic) /** * fill_rx_buffers - Allocates the Rx side skbs * @ring_info: per ring structure + * @from_card_up: If this is true, we will map the buffer to get + * the dma address for buf0 and buf1 to give it to the card. + * Else we will sync the already mapped buffer to give it to the card. * Description: * The function allocates Rx side skbs and puts the physical * address of these buffers into the RxD buffer pointers, so that the NIC @@ -2518,7 +2521,7 @@ static void stop_nic(struct s2io_nic *nic) * SUCCESS on success or an appropriate -ve value on failure. */ -static int fill_rx_buffers(struct ring_info *ring) +static int fill_rx_buffers(struct ring_info *ring, int from_card_up) { struct sk_buff *skb; struct RxD_t *rxdp; @@ -2637,17 +2640,16 @@ static int fill_rx_buffers(struct ring_info *ring) skb->data = (void *) (unsigned long)tmp; skb_reset_tail_pointer(skb); - /* AK: check is wrong. 0 can be valid dma address */ - if (!(rxdp3->Buffer0_ptr)) + if (from_card_up) { rxdp3->Buffer0_ptr = pci_map_single(ring->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - else + if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) + goto pci_map_failed; + } else pci_dma_sync_single_for_device(ring->pdev, (dma_addr_t) rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) - goto pci_map_failed; rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (ring->rxd_mode == RXD_MODE_3B) { @@ -2664,21 +2666,22 @@ static int fill_rx_buffers(struct ring_info *ring) if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) goto pci_map_failed; - /* AK: check is wrong */ - if (!rxdp3->Buffer1_ptr) + if (from_card_up) { rxdp3->Buffer1_ptr = pci_map_single(ring->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { - pci_unmap_single - (ring->pdev, - (dma_addr_t)(unsigned long) - skb->data, - ring->mtu + 4, - PCI_DMA_FROMDEVICE); - goto pci_map_failed; + if (pci_dma_mapping_error + (rxdp3->Buffer1_ptr)) { + pci_unmap_single + (ring->pdev, + (dma_addr_t)(unsigned long) + skb->data, + ring->mtu + 4, + PCI_DMA_FROMDEVICE); + goto pci_map_failed; + } } rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3 @@ -2813,7 +2816,7 @@ static void free_rx_buffers(struct s2io_nic *sp) static int s2io_chk_rx_buffers(struct ring_info *ring) { - if (fill_rx_buffers(ring) == -ENOMEM) { + if (fill_rx_buffers(ring, 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } @@ -2944,7 +2947,7 @@ static void s2io_netpoll(struct net_device *dev) rx_intr_handler(&mac_control->rings[i], 0); for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { + if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; @@ -7183,7 +7186,7 @@ static int s2io_card_up(struct s2io_nic * sp) for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].mtu = dev->mtu; - ret = fill_rx_buffers(&mac_control->rings[i]); + ret = fill_rx_buffers(&mac_control->rings[i], 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); -- cgit v1.2.3 From 01e16faa0691c57fd8f9bac46b1953ff7692ab8a Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Wed, 9 Jul 2008 23:49:21 -0400 Subject: S2io: Enable msi-x link interrupts. - Enable msi-x link interrupts because the timer based scheduler was getting cancelled causing the link state to be lost with repetitive card up/downs when changing the mtu. - Unmask mac_rmac_link interrupts only for Xframe I and prevent a spurious link interrupt in Xframe II. - Stop the tx queue and indicate link down when card is down Signed-off-by: Santosh Rastapur Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 47 ++++++++++++++++++++++++++++++----------------- drivers/net/s2io.h | 1 + 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 685030bb1d5..7f89b433bfc 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -1891,8 +1891,6 @@ static int init_nic(struct s2io_nic *nic) static int s2io_link_fault_indication(struct s2io_nic *nic) { - if (nic->config.intr_type != INTA) - return MAC_RMAC_ERR_TIMER; if (nic->device_type == XFRAME_II_DEVICE) return LINK_UP_DOWN_INTERRUPT; else @@ -1925,7 +1923,9 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag) { struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 gen_int_mask = 0; + u64 interruptible; + writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask); if (mask & TX_DMA_INTR) { gen_int_mask |= TXDMA_INT_M; @@ -2015,10 +2015,12 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag) gen_int_mask |= RXMAC_INT_M; do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag, &bar0->mac_int_mask); - do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR | + interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR | RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR | - RMAC_DOUBLE_ECC_ERR | - RMAC_LINK_STATE_CHANGE_INT, + RMAC_DOUBLE_ECC_ERR; + if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) + interruptible |= RMAC_LINK_STATE_CHANGE_INT; + do_s2io_write_bits(interruptible, flag, &bar0->mac_rmac_err_mask); } @@ -4376,18 +4378,24 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) /* Nothing much can be done. Get out */ return IRQ_HANDLED; - writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); + if (reason & (GEN_INTR_TXPIC | GEN_INTR_TXTRAFFIC)) { + writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); - if (reason & GEN_INTR_TXTRAFFIC) - writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); + if (reason & GEN_INTR_TXPIC) + s2io_txpic_intr_handle(sp); - for (i = 0; i < config->tx_fifo_num; i++) - tx_intr_handler(&fifos[i]); + if (reason & GEN_INTR_TXTRAFFIC) + writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); - writeq(sp->general_int_mask, &bar0->general_int_mask); - readl(&bar0->general_int_status); + for (i = 0; i < config->tx_fifo_num; i++) + tx_intr_handler(&fifos[i]); - return IRQ_HANDLED; + writeq(sp->general_int_mask, &bar0->general_int_mask); + readl(&bar0->general_int_status); + return IRQ_HANDLED; + } + /* The interrupt was not raised by us */ + return IRQ_NONE; } static void s2io_txpic_intr_handle(struct s2io_nic *sp) @@ -7115,6 +7123,9 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) s2io_rem_isr(sp); + /* stop the tx queue, indicate link down */ + s2io_link(sp, LINK_DOWN); + /* Check if the device is Quiescent and then Reset the NIC */ while(do_io) { /* As per the HW requirement we need to replenish the @@ -7247,17 +7258,19 @@ static int s2io_card_up(struct s2io_nic * sp) S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); + set_bit(__S2IO_STATE_CARD_UP, &sp->state); + /* Enable select interrupts */ en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); - if (sp->config.intr_type != INTA) - en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS); - else { + if (sp->config.intr_type != INTA) { + interruptible = TX_TRAFFIC_INTR | TX_PIC_INTR; + en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); + } else { interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; interruptible |= TX_PIC_INTR; en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); } - set_bit(__S2IO_STATE_CARD_UP, &sp->state); return 0; } diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 483b17c34ae..6722a2f7d09 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -1107,6 +1107,7 @@ static int init_shared_mem(struct s2io_nic *sp); static void free_shared_mem(struct s2io_nic *sp); static int init_nic(struct s2io_nic *nic); static int rx_intr_handler(struct ring_info *ring_data, int budget); +static void s2io_txpic_intr_handle(struct s2io_nic *sp); static void tx_intr_handler(struct fifo_info *fifo_data); static void s2io_handle_errors(void * dev_id); -- cgit v1.2.3 From 29d0a2b0f7b5f53c79095a5539ee3884afb354b6 Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Wed, 9 Jul 2008 23:50:13 -0400 Subject: S2io: Version update for IOMMU overflow checking and enable msi-x link interrupts patches. - Updated version number Signed-off-by: Santosh Rastapur Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 7f89b433bfc..517425dcb77 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -86,7 +86,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.24" +#define DRV_VERSION "2.0.26.25" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; -- cgit v1.2.3 From 4422b00390749f8b877b2838a99ef2948ae08a58 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:29:19 +0200 Subject: cxgb: delete non NAPI code from the driver. Compile-tested only. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 8 ------ drivers/net/chelsio/cxgb2.c | 2 -- drivers/net/chelsio/sge.c | 70 ++++----------------------------------------- 3 files changed, 5 insertions(+), 75 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4675c1bd6fb..50ca1cf1271 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2378,14 +2378,6 @@ config CHELSIO_T1_1G Enables support for Chelsio's gigabit Ethernet PCI cards. If you are using only 10G cards say 'N' here. -config CHELSIO_T1_NAPI - bool "Use Rx Polling (NAPI)" - depends on CHELSIO_T1 - default y - help - NAPI is a driver API designed to reduce CPU and interrupt load - when the driver is receiving lots of packets from the card. - config CHELSIO_T3 tristate "Chelsio Communications T3 10Gb Ethernet support" depends on PCI && INET diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index a509337eab2..638c9a27a7a 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -1153,9 +1153,7 @@ static int __devinit init_one(struct pci_dev *pdev, #ifdef CONFIG_NET_POLL_CONTROLLER netdev->poll_controller = t1_netpoll; #endif -#ifdef CONFIG_CHELSIO_T1_NAPI netif_napi_add(netdev, &adapter->napi, t1_poll, 64); -#endif SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); } diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 8a7efd38e95..d6c7d2aa761 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1396,20 +1396,10 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) if (unlikely(adapter->vlan_grp && p->vlan_valid)) { st->vlan_xtract++; -#ifdef CONFIG_CHELSIO_T1_NAPI - vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, - ntohs(p->vlan)); -#else - vlan_hwaccel_rx(skb, adapter->vlan_grp, - ntohs(p->vlan)); -#endif - } else { -#ifdef CONFIG_CHELSIO_T1_NAPI + vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, + ntohs(p->vlan)); + } else netif_receive_skb(skb); -#else - netif_rx(skb); -#endif - } } /* @@ -1568,7 +1558,6 @@ static inline int responses_pending(const struct adapter *adapter) return (e->GenerationBit == Q->genbit); } -#ifdef CONFIG_CHELSIO_T1_NAPI /* * A simpler version of process_responses() that handles only pure (i.e., * non data-carrying) responses. Such respones are too light-weight to justify @@ -1636,9 +1625,6 @@ int t1_poll(struct napi_struct *napi, int budget) return work_done; } -/* - * NAPI version of the main interrupt handler. - */ irqreturn_t t1_interrupt(int irq, void *data) { struct adapter *adapter = data; @@ -1656,7 +1642,8 @@ irqreturn_t t1_interrupt(int irq, void *data) else { /* no data, no NAPI needed */ writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING); - napi_enable(&adapter->napi); /* undo schedule_prep */ + /* undo schedule_prep */ + napi_enable(&adapter->napi); } } return IRQ_HANDLED; @@ -1672,53 +1659,6 @@ irqreturn_t t1_interrupt(int irq, void *data) return IRQ_RETVAL(handled != 0); } -#else -/* - * Main interrupt handler, optimized assuming that we took a 'DATA' - * interrupt. - * - * 1. Clear the interrupt - * 2. Loop while we find valid descriptors and process them; accumulate - * information that can be processed after the loop - * 3. Tell the SGE at which index we stopped processing descriptors - * 4. Bookkeeping; free TX buffers, ring doorbell if there are any - * outstanding TX buffers waiting, replenish RX buffers, potentially - * reenable upper layers if they were turned off due to lack of TX - * resources which are available again. - * 5. If we took an interrupt, but no valid respQ descriptors was found we - * let the slow_intr_handler run and do error handling. - */ -irqreturn_t t1_interrupt(int irq, void *cookie) -{ - int work_done; - struct adapter *adapter = cookie; - struct respQ *Q = &adapter->sge->respQ; - - spin_lock(&adapter->async_lock); - - writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); - - if (likely(responses_pending(adapter))) - work_done = process_responses(adapter, -1); - else - work_done = t1_slow_intr_handler(adapter); - - /* - * The unconditional clearing of the PL_CAUSE above may have raced - * with DMA completion and the corresponding generation of a response - * to cause us to miss the resulting data interrupt. The next write - * is also unconditional to recover the missed interrupt and render - * this race harmless. - */ - writel(Q->cidx, adapter->regs + A_SG_SLEEPING); - - if (!work_done) - adapter->sge->stats.unhandled_irqs++; - spin_unlock(&adapter->async_lock); - return IRQ_RETVAL(work_done != 0); -} -#endif - /* * Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it. * -- cgit v1.2.3 From 32b0f53e5bc80b87fd20d4d78a0e0cb602c9157a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:30:14 +0200 Subject: via-rhine: delete non NAPI code from the driver. Compile-tested only. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 11 ----------- drivers/net/via-rhine.c | 27 ++------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 50ca1cf1271..fb618b6e88e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1694,17 +1694,6 @@ config VIA_RHINE_MMIO If unsure, say Y. -config VIA_RHINE_NAPI - bool "Use Rx Polling (NAPI)" - depends on VIA_RHINE - help - NAPI is a new driver API designed to reduce CPU and interrupt load - when the driver is receiving lots of packets from the card. - - If your estimated Rx load is 10kpps or more, or if the card will be - deployed on potentially unfriendly networks (e.g. in a firewall), - then say Y here. - config LAN_SAA9730 bool "Philips SAA9730 Ethernet support" depends on NET_PCI && PCI && MIPS_ATLAS diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 8c9d6ae2bb3..96dff04334b 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -73,12 +73,7 @@ static const int multicast_filter_limit = 32; There are no ill effects from too-large receive rings. */ #define TX_RING_SIZE 16 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ -#ifdef CONFIG_VIA_RHINE_NAPI #define RX_RING_SIZE 64 -#else -#define RX_RING_SIZE 16 -#endif - /* Operational parameters that usually are not changed. */ @@ -583,7 +578,6 @@ static void rhine_poll(struct net_device *dev) } #endif -#ifdef CONFIG_VIA_RHINE_NAPI static int rhine_napipoll(struct napi_struct *napi, int budget) { struct rhine_private *rp = container_of(napi, struct rhine_private, napi); @@ -604,7 +598,6 @@ static int rhine_napipoll(struct napi_struct *napi, int budget) } return work_done; } -#endif static void __devinit rhine_hw_init(struct net_device *dev, long pioaddr) { @@ -784,9 +777,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = rhine_poll; #endif -#ifdef CONFIG_VIA_RHINE_NAPI netif_napi_add(dev, &rp->napi, rhine_napipoll, 64); -#endif + if (rp->quirks & rqRhineI) dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; @@ -1056,9 +1048,7 @@ static void init_registers(struct net_device *dev) rhine_set_rx_mode(dev); -#ifdef CONFIG_VIA_RHINE_NAPI napi_enable(&rp->napi); -#endif /* Enable interrupts by setting the interrupt mask. */ iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | @@ -1193,9 +1183,7 @@ static void rhine_tx_timeout(struct net_device *dev) /* protect against concurrent rx interrupts */ disable_irq(rp->pdev->irq); -#ifdef CONFIG_VIA_RHINE_NAPI napi_disable(&rp->napi); -#endif spin_lock(&rp->lock); @@ -1319,16 +1307,12 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance) if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped | IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) { -#ifdef CONFIG_VIA_RHINE_NAPI iowrite16(IntrTxAborted | IntrTxDone | IntrTxError | IntrTxUnderrun | IntrPCIErr | IntrStatsMax | IntrLinkChange, ioaddr + IntrEnable); netif_rx_schedule(dev, &rp->napi); -#else - rhine_rx(dev, RX_RING_SIZE); -#endif } if (intr_status & (IntrTxErrSummary | IntrTxDone)) { @@ -1520,11 +1504,7 @@ static int rhine_rx(struct net_device *dev, int limit) PCI_DMA_FROMDEVICE); } skb->protocol = eth_type_trans(skb, dev); -#ifdef CONFIG_VIA_RHINE_NAPI netif_receive_skb(skb); -#else - netif_rx(skb); -#endif dev->last_rx = jiffies; rp->stats.rx_bytes += pkt_len; rp->stats.rx_packets++; @@ -1836,9 +1816,7 @@ static int rhine_close(struct net_device *dev) spin_lock_irq(&rp->lock); netif_stop_queue(dev); -#ifdef CONFIG_VIA_RHINE_NAPI napi_disable(&rp->napi); -#endif if (debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard, " @@ -1937,9 +1915,8 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state) if (!netif_running(dev)) return 0; -#ifdef CONFIG_VIA_RHINE_NAPI napi_disable(&rp->napi); -#endif + netif_device_detach(dev); pci_save_state(pdev); -- cgit v1.2.3 From 0aa1538f4e4bab366023f4c414555e4ed25994e6 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:33:52 +0200 Subject: gianfar: delete non NAPI code from the driver. Compile-tested only. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 4 --- drivers/net/gianfar.c | 76 ++++----------------------------------------------- drivers/net/gianfar.h | 11 -------- 3 files changed, 6 insertions(+), 85 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index fb618b6e88e..1fe7e0792c1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2262,10 +2262,6 @@ config GIANFAR This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, and MPC86xx family of chips, and the FEC on the 8540. -config GFAR_NAPI - bool "Use Rx Polling (NAPI)" - depends on GIANFAR - config UCC_GETH tristate "Freescale QE Gigabit Ethernet" depends on QUICC_ENGINE diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 393a0f17530..fa78d687012 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -44,8 +44,7 @@ * happen immediately, but will wait until either a set number * of frames or amount of time have passed). In NAPI, the * interrupt handler will signal there is work to be done, and - * exit. Without NAPI, the packet(s) will be handled - * immediately. Both methods will start at the last known empty + * exit. This method will start at the last known empty * descriptor, and process every subsequent descriptor until there * are none left with data (NAPI will stop after a set number of * packets to give time to other tasks, but will eventually @@ -101,12 +100,6 @@ #undef BRIEF_GFAR_ERRORS #undef VERBOSE_GFAR_ERRORS -#ifdef CONFIG_GFAR_NAPI -#define RECEIVE(x) netif_receive_skb(x) -#else -#define RECEIVE(x) netif_rx(x) -#endif - const char gfar_driver_name[] = "Gianfar Ethernet"; const char gfar_driver_version[] = "1.3"; @@ -131,9 +124,7 @@ static void free_skb_resources(struct gfar_private *priv); static void gfar_set_multi(struct net_device *dev); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); static void gfar_configure_serdes(struct net_device *dev); -#ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct napi_struct *napi, int budget); -#endif #ifdef CONFIG_NET_POLL_CONTROLLER static void gfar_netpoll(struct net_device *dev); #endif @@ -260,9 +251,7 @@ static int gfar_probe(struct platform_device *pdev) dev->hard_start_xmit = gfar_start_xmit; dev->tx_timeout = gfar_timeout; dev->watchdog_timeo = TX_TIMEOUT; -#ifdef CONFIG_GFAR_NAPI netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT); -#endif #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = gfar_netpoll; #endif @@ -363,11 +352,7 @@ static int gfar_probe(struct platform_device *pdev) /* Even more device info helps when determining which kernel */ /* provided which set of benchmarks. */ -#ifdef CONFIG_GFAR_NAPI printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name); -#else - printk(KERN_INFO "%s: Running with NAPI disabled\n", dev->name); -#endif printk(KERN_INFO "%s: %d/%d RX/TX BD ring size\n", dev->name, priv->rx_ring_size, priv->tx_ring_size); @@ -945,14 +930,10 @@ tx_skb_fail: /* Returns 0 for success. */ static int gfar_enet_open(struct net_device *dev) { -#ifdef CONFIG_GFAR_NAPI struct gfar_private *priv = netdev_priv(dev); -#endif int err; -#ifdef CONFIG_GFAR_NAPI napi_enable(&priv->napi); -#endif /* Initialize a bunch of registers */ init_registers(dev); @@ -962,17 +943,13 @@ static int gfar_enet_open(struct net_device *dev) err = init_phy(dev); if(err) { -#ifdef CONFIG_GFAR_NAPI napi_disable(&priv->napi); -#endif return err; } err = startup_gfar(dev); if (err) { -#ifdef CONFIG_GFAR_NAPI napi_disable(&priv->napi); -#endif return err; } @@ -1128,9 +1105,7 @@ static int gfar_close(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); -#ifdef CONFIG_GFAR_NAPI napi_disable(&priv->napi); -#endif stop_gfar(dev); @@ -1427,14 +1402,9 @@ irqreturn_t gfar_receive(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; struct gfar_private *priv = netdev_priv(dev); -#ifdef CONFIG_GFAR_NAPI u32 tempval; -#else - unsigned long flags; -#endif /* support NAPI */ -#ifdef CONFIG_GFAR_NAPI /* Clear IEVENT, so interrupts aren't called again * because of the packets that have already arrived */ gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK); @@ -1451,38 +1421,10 @@ irqreturn_t gfar_receive(int irq, void *dev_id) dev->name, gfar_read(&priv->regs->ievent), gfar_read(&priv->regs->imask)); } -#else - /* Clear IEVENT, so rx interrupt isn't called again - * because of this interrupt */ - gfar_write(&priv->regs->ievent, IEVENT_RX_MASK); - - spin_lock_irqsave(&priv->rxlock, flags); - gfar_clean_rx_ring(dev, priv->rx_ring_size); - - /* If we are coalescing interrupts, update the timer */ - /* Otherwise, clear it */ - if (likely(priv->rxcoalescing)) { - gfar_write(&priv->regs->rxic, 0); - gfar_write(&priv->regs->rxic, - mk_ic_value(priv->rxcount, priv->rxtime)); - } - - spin_unlock_irqrestore(&priv->rxlock, flags); -#endif return IRQ_HANDLED; } -static inline int gfar_rx_vlan(struct sk_buff *skb, - struct vlan_group *vlgrp, unsigned short vlctl) -{ -#ifdef CONFIG_GFAR_NAPI - return vlan_hwaccel_receive_skb(skb, vlgrp, vlctl); -#else - return vlan_hwaccel_rx(skb, vlgrp, vlctl); -#endif -} - static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) { /* If valid headers were found, and valid sums @@ -1539,10 +1481,11 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, skb->protocol = eth_type_trans(skb, dev); /* Send the packet up the stack */ - if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN))) - ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl); - else - ret = RECEIVE(skb); + if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN))) { + ret = vlan_hwaccel_receive_skb(skb, priv->vlgrp, + fcb->vlctl); + } else + ret = netif_receive_skb(skb); if (NET_RX_DROP == ret) priv->extra_stats.kernel_dropped++; @@ -1629,7 +1572,6 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) return howmany; } -#ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct napi_struct *napi, int budget) { struct gfar_private *priv = container_of(napi, struct gfar_private, napi); @@ -1664,7 +1606,6 @@ static int gfar_poll(struct napi_struct *napi, int budget) return howmany; } -#endif #ifdef CONFIG_NET_POLL_CONTROLLER /* @@ -2003,11 +1944,6 @@ static irqreturn_t gfar_error(int irq, void *dev_id) gfar_receive(irq, dev_id); -#ifndef CONFIG_GFAR_NAPI - /* Clear the halt bit in RSTAT */ - gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT); -#endif - if (netif_msg_rx_err(priv)) printk(KERN_DEBUG "%s: busy error (rstat: %x)\n", dev->name, gfar_read(&priv->regs->rstat)); diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 27f37c81e52..bead71cb2b1 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -77,13 +77,8 @@ extern const char gfar_driver_name[]; extern const char gfar_driver_version[]; /* These need to be powers of 2 for this driver */ -#ifdef CONFIG_GFAR_NAPI #define DEFAULT_TX_RING_SIZE 256 #define DEFAULT_RX_RING_SIZE 256 -#else -#define DEFAULT_TX_RING_SIZE 64 -#define DEFAULT_RX_RING_SIZE 64 -#endif #define GFAR_RX_MAX_RING_SIZE 256 #define GFAR_TX_MAX_RING_SIZE 256 @@ -128,14 +123,8 @@ extern const char gfar_driver_version[]; #define DEFAULT_RXTIME 21 -/* Non NAPI Case */ -#ifndef CONFIG_GFAR_NAPI -#define DEFAULT_RX_COALESCE 1 -#define DEFAULT_RXCOUNT 16 -#else #define DEFAULT_RX_COALESCE 0 #define DEFAULT_RXCOUNT 0 -#endif /* CONFIG_GFAR_NAPI */ #define MIIMCFG_INIT_VALUE 0x00000007 #define MIIMCFG_RESET 0x80000000 -- cgit v1.2.3 From 1a342d224afb03196e3df28a271f3ddf3787e8f4 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 11 Jul 2008 00:34:40 +0200 Subject: ucc_geth: delete non NAPI code from the driver. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 4 ---- drivers/net/ucc_geth.c | 29 ++--------------------------- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 1fe7e0792c1..9b98714889b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2270,10 +2270,6 @@ config UCC_GETH This driver supports the Gigabit Ethernet mode of the QUICC Engine, which is available on some Freescale SOCs. -config UGETH_NAPI - bool "Use Rx Polling (NAPI)" - depends on UCC_GETH - config UGETH_MAGIC_PACKET bool "Magic Packet detection support" depends on UCC_GETH diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index fb0b918e5cc..07933f71b86 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3500,11 +3500,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit dev->stats.rx_bytes += length; /* Send the packet up the stack */ -#ifdef CONFIG_UGETH_NAPI netif_receive_skb(skb); -#else - netif_rx(skb); -#endif /* CONFIG_UGETH_NAPI */ } ugeth->dev->last_rx = jiffies; @@ -3580,7 +3576,6 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) return 0; } -#ifdef CONFIG_UGETH_NAPI static int ucc_geth_poll(struct napi_struct *napi, int budget) { struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi); @@ -3607,7 +3602,6 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget) return howmany; } -#endif /* CONFIG_UGETH_NAPI */ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) { @@ -3617,9 +3611,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) struct ucc_geth_info *ug_info; register u32 ucce; register u32 uccm; -#ifndef CONFIG_UGETH_NAPI - register u32 rx_mask; -#endif register u32 tx_mask; u8 i; @@ -3636,21 +3627,11 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) /* check for receive events that require processing */ if (ucce & UCCE_RX_EVENTS) { -#ifdef CONFIG_UGETH_NAPI if (netif_rx_schedule_prep(dev, &ugeth->napi)) { uccm &= ~UCCE_RX_EVENTS; out_be32(uccf->p_uccm, uccm); __netif_rx_schedule(dev, &ugeth->napi); } -#else - rx_mask = UCCE_RXBF_SINGLE_MASK; - for (i = 0; i < ug_info->numQueuesRx; i++) { - if (ucce & rx_mask) - ucc_geth_rx(ugeth, i, (int)ugeth->ug_info->bdRingLenRx[i]); - ucce &= ~rx_mask; - rx_mask <<= 1; - } -#endif /* CONFIG_UGETH_NAPI */ } /* Tx event processing */ @@ -3720,9 +3701,8 @@ static int ucc_geth_open(struct net_device *dev) return err; } -#ifdef CONFIG_UGETH_NAPI napi_enable(&ugeth->napi); -#endif + err = ucc_geth_startup(ugeth); if (err) { if (netif_msg_ifup(ugeth)) @@ -3783,9 +3763,8 @@ static int ucc_geth_open(struct net_device *dev) return err; out_err: -#ifdef CONFIG_UGETH_NAPI napi_disable(&ugeth->napi); -#endif + return err; } @@ -3796,9 +3775,7 @@ static int ucc_geth_close(struct net_device *dev) ugeth_vdbg("%s: IN", __FUNCTION__); -#ifdef CONFIG_UGETH_NAPI napi_disable(&ugeth->napi); -#endif ucc_geth_stop(ugeth); @@ -4050,9 +4027,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma dev->hard_start_xmit = ucc_geth_start_xmit; dev->tx_timeout = ucc_geth_timeout; dev->watchdog_timeo = TX_TIMEOUT; -#ifdef CONFIG_UGETH_NAPI netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT); -#endif /* CONFIG_UGETH_NAPI */ #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = ucc_netpoll; #endif -- cgit v1.2.3 From 0f8ecbadae4bd9f085e605c08347ed3077a6146f Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:07 -0700 Subject: ixgb: maybe stop tx port missed a piece back when maybe stop tx was added to the ixgb driver some mistakes were made and the driver a) didn't remove the tx lock, which is now un-necessary b) didn't change the restart code to be compliant with maybe_stop Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 41f3adf5f37..04cac41f7d5 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1855,12 +1855,17 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter) tx_ring->next_to_clean = i; - if (unlikely(netif_queue_stopped(netdev))) { - spin_lock(&adapter->tx_lock); - if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev) && - (IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED)) + if (unlikely(cleaned && netif_carrier_ok(netdev) && + IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED)) { + /* Make sure that anybody stopping the queue after this + * sees the new next_to_clean. */ + smp_mb(); + + if (netif_queue_stopped(netdev) && + !(test_bit(__IXGB_DOWN, &adapter->flags))) { netif_wake_queue(netdev); - spin_unlock(&adapter->tx_lock); + ++adapter->restart_queue; + } } if(adapter->detect_tx_hung) { -- cgit v1.2.3 From e539e4667e3c8125641f5916eb0b7d087d3e0844 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:12 -0700 Subject: ixgb: repeat 32 bit ioremap cleanup this patch has been made to many other drivers in kernel to fix the storage of 64 bit resources in 32 bit variables. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 04cac41f7d5..652c0eab3a4 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -363,8 +363,6 @@ ixgb_probe(struct pci_dev *pdev, struct net_device *netdev = NULL; struct ixgb_adapter *adapter; static int cards_found = 0; - unsigned long mmio_start; - int mmio_len; int pci_using_dac; int i; int err; @@ -405,11 +403,9 @@ ixgb_probe(struct pci_dev *pdev, adapter->hw.back = adapter; adapter->msg_enable = netif_msg_init(debug, DEFAULT_DEBUG_LEVEL_SHIFT); - mmio_start = pci_resource_start(pdev, BAR_0); - mmio_len = pci_resource_len(pdev, BAR_0); - - adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); - if(!adapter->hw.hw_addr) { + adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0), + pci_resource_len(pdev, BAR_0)); + if (!adapter->hw.hw_addr) { err = -EIO; goto err_ioremap; } @@ -444,9 +440,6 @@ ixgb_probe(struct pci_dev *pdev, #endif strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); - netdev->mem_start = mmio_start; - netdev->mem_end = mmio_start + mmio_len; - netdev->base_addr = adapter->hw.io_base; adapter->bd_number = cards_found; adapter->link_speed = 0; -- cgit v1.2.3 From 4360386f7d849f521e8ef042f90dbca73e07509c Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:17 -0700 Subject: ixgb: fix bug in descriptor ring due to prefetch corruption there was one more bug hidden in the prefetch routines in ixgb hardware that force us to remove it completely. Writebacks were being done on descriptors with stale data due to internal hardware fifo corruption. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 652c0eab3a4..ecd5252c4bf 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -146,14 +146,6 @@ static int debug = DEFAULT_DEBUG_LEVEL_SHIFT; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); -/* some defines for controlling descriptor fetches in h/w */ -#define RXDCTL_WTHRESH_DEFAULT 15 /* chip writes back at this many or RXT0 */ -#define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below - * this */ -#define RXDCTL_HTHRESH_DEFAULT 0 /* chip will only prefetch if tail - * is pushed this many descriptors - * from head */ - /** * ixgb_init_module - Driver Registration Routine * @@ -839,7 +831,6 @@ ixgb_configure_rx(struct ixgb_adapter *adapter) struct ixgb_hw *hw = &adapter->hw; u32 rctl; u32 rxcsum; - u32 rxdctl; /* make sure receives are disabled while setting up the descriptors */ @@ -861,18 +852,12 @@ ixgb_configure_rx(struct ixgb_adapter *adapter) IXGB_WRITE_REG(hw, RDH, 0); IXGB_WRITE_REG(hw, RDT, 0); - /* set up pre-fetching of receive buffers so we get some before we - * run out (default hardware behavior is to run out before fetching - * more). This sets up to fetch if HTHRESH rx descriptors are avail - * and the descriptors in hw cache are below PTHRESH. This avoids - * the hardware behavior of fetching <=512 descriptors in a single - * burst that pre-empts all other activity, usually causing fifo - * overflows. */ - /* use WTHRESH to burst write 16 descriptors or burst when RXT0 */ - rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT | - RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT | - RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT; - IXGB_WRITE_REG(hw, RXDCTL, rxdctl); + /* due to the hardware errata with RXDCTL, we are unable to use any of + * the performance enhancing features of it without causing other + * subtle bugs, some of the bugs could include receive length + * corruption at high data rates (WTHRESH > 0) and/or receive + * descriptor ring irregularites (particularly in hardware cache) */ + IXGB_WRITE_REG(hw, RXDCTL, 0); /* Enable Receive Checksum Offload for TCP and UDP */ if (adapter->rx_csum) { -- cgit v1.2.3 From a3dc3da02a7c29237ca4ce3ec17f0e1f87ff0a06 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:22 -0700 Subject: ixgb: leave room for extra hardware memory usage ixgb hardware (not ixgbe) has a problem where it might dma past the end of a buffer in certain cases. leave 8 bytes extra room. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index ecd5252c4bf..ec8bce15436 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -560,7 +560,7 @@ ixgb_sw_init(struct ixgb_adapter *adapter) hw->subsystem_id = pdev->subsystem_device; hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; - adapter->rx_buffer_len = hw->max_frame_size; + adapter->rx_buffer_len = hw->max_frame_size + 8; /* + 8 for errata */ if((hw->device_id == IXGB_DEVICE_ID_82597EX) || (hw->device_id == IXGB_DEVICE_ID_82597EX_CX4) @@ -1573,7 +1573,7 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu) return -EINVAL; } - adapter->rx_buffer_len = max_frame; + adapter->rx_buffer_len = max_frame + 8; /* + 8 for errata */ netdev->mtu = new_mtu; -- cgit v1.2.3 From 72ab51954d108e4999b3c958ae21da731d2d789a Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:27 -0700 Subject: ixgb: check down state before enable irq in order to prevent the case where poll_disable is waiting on our device to permanently, check the flag to make sure we're not down or closing down before re-enabling interrupts. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index ec8bce15436..60cad65dbc2 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1782,7 +1782,8 @@ ixgb_clean(struct napi_struct *napi, int budget) /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { netif_rx_complete(netdev, napi); - ixgb_irq_enable(adapter); + if (!test_bit(__IXGB_DOWN, &adapter->flags)) + ixgb_irq_enable(adapter); } return work_done; -- cgit v1.2.3 From a65a604a01f710defe01f2322e108f4d8c20f6ce Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:32 -0700 Subject: ixgb: don't allow too small MTU Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 60cad65dbc2..0e72dadf8b7 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1566,9 +1566,9 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; - - if((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) - || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) { + /* MTU < 68 is an error for IPv4 traffic, just don't allow it */ + if ((new_mtu < 68) || + (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) { DPRINTK(PROBE, ERR, "Invalid MTU setting %d\n", new_mtu); return -EINVAL; } -- cgit v1.2.3 From 34336635467c5102777ea8acf34fc8bf391f98c0 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:37 -0700 Subject: ixgb: move time stamp set before setting dma pointer a user pointed out that setting variables out of order with respect to the checks we make for tx timeout handling could result in a race where ->dma was set but ->time_stamp was set to the old value. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 0e72dadf8b7..4bf6bbc6582 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1290,12 +1290,12 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, buffer_info->length = size; WARN_ON(buffer_info->dma != 0); + buffer_info->time_stamp = jiffies; buffer_info->dma = pci_map_single(adapter->pdev, skb->data + offset, size, PCI_DMA_TODEVICE); - buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = 0; len -= size; @@ -1322,13 +1322,13 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, size -= 4; buffer_info->length = size; + buffer_info->time_stamp = jiffies; buffer_info->dma = pci_map_page(adapter->pdev, frag->page, frag->page_offset + offset, size, PCI_DMA_TODEVICE); - buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = 0; len -= size; -- cgit v1.2.3 From b5ca88eb335580dc48ef5ebb3b86719bdb5a4113 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:42 -0700 Subject: ixgb: fix race on rx_buffer_len in mtu change some random coverage testing found that when changing mtu under heavy traffic load, NAPI would use the rx_buffer_len variable after it had been changed by change_mtu. Similar to e1000 bugs found long ago. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 4bf6bbc6582..c3234c45104 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1573,14 +1573,18 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu) return -EINVAL; } + if (old_max_frame == max_frame) + return 0; + + if (netif_running(netdev)) + ixgb_down(adapter, true); + adapter->rx_buffer_len = max_frame + 8; /* + 8 for errata */ netdev->mtu = new_mtu; - if ((old_max_frame != max_frame) && netif_running(netdev)) { - ixgb_down(adapter, true); + if (netif_running(netdev)) ixgb_up(adapter); - } return 0; } -- cgit v1.2.3 From 1257969724e7d5f878ac05067388ac5c012eb29b Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:47 -0700 Subject: ixgb: fix unload race with timers ixgb needs to call flush scheduled work to flush any timers before unregistering the netdev. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index c3234c45104..79082eb577c 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -528,6 +528,8 @@ ixgb_remove(struct pci_dev *pdev) struct net_device *netdev = pci_get_drvdata(pdev); struct ixgb_adapter *adapter = netdev_priv(netdev); + flush_scheduled_work(); + unregister_netdev(netdev); iounmap(adapter->hw.hw_addr); -- cgit v1.2.3 From db58294416d5d1446cbf6962a21ad077919d564e Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:52 -0700 Subject: ixgb: remove lltx support and update tx routine a) kernel developers suggest LLTX is broken and unsafe to use, remove it. b) remember to pre-stop the queue if we won't have room c) removing lltx means we can remove our tx lock Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb.h | 1 - drivers/net/ixgb/ixgb_main.c | 32 +------------------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index 16f9c756aa4..3cec7b98d52 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h @@ -157,7 +157,6 @@ struct ixgb_adapter { u32 part_num; u16 link_speed; u16 link_duplex; - spinlock_t tx_lock; struct work_struct tx_timeout_task; struct timer_list blink_timer; diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 79082eb577c..bd08e199214 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -448,9 +448,6 @@ ixgb_probe(struct pci_dev *pdev, NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_TSO; -#ifdef NETIF_F_LLTX - netdev->features |= NETIF_F_LLTX; -#endif if(pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -577,8 +574,6 @@ ixgb_sw_init(struct ixgb_adapter *adapter) /* enable flow control to be programmed */ hw->fc.send_xon = 1; - spin_lock_init(&adapter->tx_lock); - set_bit(__IXGB_DOWN, &adapter->flags); return 0; } @@ -1441,7 +1436,6 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct ixgb_adapter *adapter = netdev_priv(netdev); unsigned int first; unsigned int tx_flags = 0; - unsigned long flags; int vlan_id = 0; int tso; @@ -1455,26 +1449,9 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return 0; } -#ifdef NETIF_F_LLTX - if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) { - /* Collision - tell upper layer to requeue */ - local_irq_restore(flags); - return NETDEV_TX_LOCKED; - } -#else - spin_lock_irqsave(&adapter->tx_lock, flags); -#endif - if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, - DESC_NEEDED))) { - netif_stop_queue(netdev); - spin_unlock_irqrestore(&adapter->tx_lock, flags); + DESC_NEEDED))) return NETDEV_TX_BUSY; - } - -#ifndef NETIF_F_LLTX - spin_unlock_irqrestore(&adapter->tx_lock, flags); -#endif if(adapter->vlgrp && vlan_tx_tag_present(skb)) { tx_flags |= IXGB_TX_FLAGS_VLAN; @@ -1486,9 +1463,6 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tso = ixgb_tso(adapter, skb); if (tso < 0) { dev_kfree_skb_any(skb); -#ifdef NETIF_F_LLTX - spin_unlock_irqrestore(&adapter->tx_lock, flags); -#endif return NETDEV_TX_OK; } @@ -1502,13 +1476,9 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) netdev->trans_start = jiffies; -#ifdef NETIF_F_LLTX /* Make sure there is space in the ring for the next send. */ ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED); - spin_unlock_irqrestore(&adapter->tx_lock, flags); - -#endif return NETDEV_TX_OK; } -- cgit v1.2.3 From 2115a6432911b669bec037686066c7bbc70cc68e Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 8 Jul 2008 15:51:57 -0700 Subject: ixgb: update readme text Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- Documentation/networking/ixgb.txt | 419 +++++++++++++++++++++++++++++--------- 1 file changed, 320 insertions(+), 99 deletions(-) diff --git a/Documentation/networking/ixgb.txt b/Documentation/networking/ixgb.txt index 7c98277777e..a0d0ffb5e58 100644 --- a/Documentation/networking/ixgb.txt +++ b/Documentation/networking/ixgb.txt @@ -1,7 +1,7 @@ -Linux* Base Driver for the Intel(R) PRO/10GbE Family of Adapters -================================================================ +Linux Base Driver for 10 Gigabit Intel(R) Network Connection +============================================================= -November 17, 2004 +October 9, 2007 Contents @@ -9,94 +9,151 @@ Contents - In This Release - Identifying Your Adapter +- Building and Installation - Command Line Parameters - Improving Performance +- Additional Configurations +- Known Issues/Troubleshooting - Support + In This Release =============== -This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family -of Adapters, version 1.0.x. +This file describes the ixgb Linux Base Driver for the 10 Gigabit Intel(R) +Network Connection. This driver includes support for Itanium(R)2-based +systems. + +For questions related to hardware requirements, refer to the documentation +supplied with your 10 Gigabit adapter. All hardware requirements listed apply +to use with Linux. + +The following features are available in this kernel: + - Native VLANs + - Channel Bonding (teaming) + - SNMP + +Channel Bonding documentation can be found in the Linux kernel source: +/Documentation/networking/bonding.txt + +The driver information previously displayed in the /proc filesystem is not +supported in this release. Alternatively, you can use ethtool (version 1.6 +or later), lspci, and ifconfig to obtain the same information. + +Instructions on updating ethtool can be found in the section "Additional +Configurations" later in this document. -For questions related to hardware requirements, refer to the documentation -supplied with your Intel PRO/10GbE adapter. All hardware requirements listed -apply to use with Linux. Identifying Your Adapter ======================== -To verify your Intel adapter is supported, find the board ID number on the -adapter. Look for a label that has a barcode and a number in the format -A12345-001. +The following Intel network adapters are compatible with the drivers in this +release: + +Controller Adapter Name Physical Layer +---------- ------------ -------------- +82597EX Intel(R) PRO/10GbE LR/SR/CX4 10G Base-LR (1310 nm optical fiber) + Server Adapters 10G Base-SR (850 nm optical fiber) + 10G Base-CX4(twin-axial copper cabling) + +For more information on how to identify your adapter, go to the Adapter & +Driver ID Guide at: + + http://support.intel.com/support/network/sb/CS-012904.htm + + +Building and Installation +========================= + +select m for "Intel(R) PRO/10GbE support" located at: + Location: + -> Device Drivers + -> Network device support (NETDEVICES [=y]) + -> Ethernet (10000 Mbit) (NETDEV_10000 [=y]) +1. make modules && make modules_install + +2. Load the module: + +    modprobe ixgb = + + The insmod command can be used if the full + path to the driver module is specified. For example: + + insmod /lib/modules//kernel/drivers/net/ixgb/ixgb.ko + + With 2.6 based kernels also make sure that older ixgb drivers are + removed from the kernel, before loading the new module: -Use the above information and the Adapter & Driver ID Guide at: + rmmod ixgb; modprobe ixgb - http://support.intel.com/support/network/adapter/pro100/21397.htm +3. Assign an IP address to the interface by entering the following, where + x is the interface number: -For the latest Intel network drivers for Linux, go to: + ifconfig ethx + +4. Verify that the interface works. Enter the following, where + is the IP address for another machine on the same subnet as the interface + that is being tested: + + ping - http://downloadfinder.intel.com/scripts-df/support_intel.asp Command Line Parameters ======================= -If the driver is built as a module, the following optional parameters are -used by entering them on the command line with the modprobe or insmod command -using this syntax: +If the driver is built as a module, the following optional parameters are +used by entering them on the command line with the modprobe command using +this syntax: modprobe ixgb [