X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fnet%2Fqla3xxx.c;h=bf9f8f64ba67f1b43cb3643ddb5d1ef718fcf3d9;hb=d4dc4ec9d84e0578b9bfbe56a11fafdb7cbac771;hp=d8766c0e825585c230171dcb57cc0a627a791c5f;hpb=9b6a51746ffe8d619f1097675d2dc5e303470024;p=linux-2.6-omap-h63xx.git diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index d8766c0e825..bf9f8f64ba6 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -1904,7 +1904,6 @@ static void ql_get_pauseparam(struct net_device *ndev, static const struct ethtool_ops ql3xxx_ethtool_ops = { .get_settings = ql_get_settings, .get_drvinfo = ql_get_drvinfo, - .get_perm_addr = ethtool_op_get_perm_addr, .get_link = ethtool_op_get_link, .get_msglevel = ql_get_msglevel, .set_msglevel = ql_set_msglevel, @@ -2249,6 +2248,13 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev, qdev->rsp_consumer_index) && (work_done < work_to_do)) { net_rsp = qdev->rsp_current; + rmb(); + /* + * Fix 4032 chipe undocumented "feature" where bit-8 is set if the + * inbound completion is for a VLAN. + */ + if (qdev->device_id == QL3032_DEVICE_ID) + net_rsp->opcode &= 0x7f; switch (net_rsp->opcode) { case OPCODE_OB_MAC_IOCB_FN0: @@ -2304,10 +2310,10 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev, return work_done; } -static int ql_poll(struct net_device *ndev, int *budget) +static int ql_poll(struct napi_struct *napi, int budget) { - struct ql3_adapter *qdev = netdev_priv(ndev); - int work_to_do = min(*budget, ndev->quota); + struct ql3_adapter *qdev = container_of(napi, struct ql3_adapter, napi); + struct net_device *ndev = qdev->ndev; int rx_cleaned = 0, tx_cleaned = 0; unsigned long hw_flags; struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; @@ -2315,16 +2321,13 @@ static int ql_poll(struct net_device *ndev, int *budget) if (!netif_carrier_ok(ndev)) goto quit_polling; - ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, work_to_do); - *budget -= rx_cleaned; - ndev->quota -= rx_cleaned; + ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, budget); - if( tx_cleaned + rx_cleaned != work_to_do || + if (tx_cleaned + rx_cleaned != budget || !netif_running(ndev)) { quit_polling: - netif_rx_complete(ndev); - spin_lock_irqsave(&qdev->hw_lock, hw_flags); + __netif_rx_complete(ndev, napi); ql_update_small_bufq_prod_index(qdev); ql_update_lrg_bufq_prod_index(qdev); writel(qdev->rsp_consumer_index, @@ -2332,9 +2335,8 @@ quit_polling: spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); ql_enable_interrupts(qdev); - return 0; } - return 1; + return tx_cleaned + rx_cleaned; } static irqreturn_t ql3xxx_isr(int irq, void *dev_id) @@ -2384,8 +2386,8 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) spin_unlock(&qdev->adapter_lock); } else if (value & ISP_IMR_DISABLE_CMPL_INT) { ql_disable_interrupts(qdev); - if (likely(netif_rx_schedule_prep(ndev))) { - __netif_rx_schedule(ndev); + if (likely(netif_rx_schedule_prep(ndev, &qdev->napi))) { + __netif_rx_schedule(ndev, &qdev->napi); } } else { return IRQ_NONE; @@ -2433,37 +2435,22 @@ static int ql_get_seg_count(struct ql3_adapter *qdev, return -1; } -static void ql_hw_csum_setup(struct sk_buff *skb, +static void ql_hw_csum_setup(const struct sk_buff *skb, struct ob_mac_iocb_req *mac_iocb_ptr) { - struct ethhdr *eth; - struct iphdr *ip = NULL; - u8 offset = ETH_HLEN; + const struct iphdr *ip = ip_hdr(skb); - eth = (struct ethhdr *)(skb->data); + mac_iocb_ptr->ip_hdr_off = skb_network_offset(skb); + mac_iocb_ptr->ip_hdr_len = ip->ihl; - if (eth->h_proto == __constant_htons(ETH_P_IP)) { - ip = (struct iphdr *)&skb->data[ETH_HLEN]; - } else if (eth->h_proto == htons(ETH_P_8021Q) && - ((struct vlan_ethhdr *)skb->data)-> - h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP)) { - ip = (struct iphdr *)&skb->data[VLAN_ETH_HLEN]; - offset = VLAN_ETH_HLEN; - } - - if (ip) { - if (ip->protocol == IPPROTO_TCP) { - mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC | + if (ip->protocol == IPPROTO_TCP) { + mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC | OB_3032MAC_IOCB_REQ_IC; - mac_iocb_ptr->ip_hdr_off = offset; - mac_iocb_ptr->ip_hdr_len = ip->ihl; - } else if (ip->protocol == IPPROTO_UDP) { - mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC | + } else { + mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC | OB_3032MAC_IOCB_REQ_IC; - mac_iocb_ptr->ip_hdr_off = offset; - mac_iocb_ptr->ip_hdr_len = ip->ihl; - } } + } /* @@ -3626,7 +3613,7 @@ static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) del_timer_sync(&qdev->adapter_timer); - netif_poll_disable(ndev); + napi_disable(&qdev->napi); if (do_reset) { int soft_reset; @@ -3714,7 +3701,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev) mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); - netif_poll_enable(ndev); + napi_enable(&qdev->napi); ql_enable_interrupts(qdev); return 0; @@ -4044,7 +4031,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, if (pci_using_dac) ndev->features |= NETIF_F_HIGHDMA; if (qdev->device_id == QL3032_DEVICE_ID) - ndev->features |= (NETIF_F_HW_CSUM | NETIF_F_SG); + ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; qdev->mem_map_registers = ioremap_nocache(pci_resource_start(pdev, 1), @@ -4070,8 +4057,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, ndev->tx_timeout = ql3xxx_tx_timeout; ndev->watchdog_timeo = 5 * HZ; - ndev->poll = &ql_poll; - ndev->weight = 64; + netif_napi_add(ndev, &qdev->napi, ql_poll, 64); ndev->irq = pdev->irq;