diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 656 |
1 files changed, 2 insertions, 654 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 67159d6e9a35..1d334e99169c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -66,8 +66,6 @@ static void qlcnic_fw_poll_work(struct work_struct *work); static void qlcnic_schedule_work(struct qlcnic_adapter *adapter, work_func_t func, int delay); static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); -static int qlcnic_poll(struct napi_struct *napi, int budget); -static int qlcnic_rx_poll(struct napi_struct *napi, int budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void qlcnic_poll_controller(struct net_device *netdev); #endif @@ -130,23 +128,7 @@ static const u32 msi_tgt_status[8] = { static const struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG; -static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring) -{ - writel(0, sds_ring->crb_intr_mask); -} - -static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring) -{ - struct qlcnic_adapter *adapter = sds_ring->adapter; - - writel(0x1, sds_ring->crb_intr_mask); - - if (!QLCNIC_IS_MSI_FAMILY(adapter)) - writel(0xfbff, adapter->tgt_mask_reg); -} - -static int -qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) +int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) { int size = sizeof(struct qlcnic_host_sds_ring) * count; @@ -155,8 +137,7 @@ qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) return recv_ctx->sds_rings == NULL; } -static void -qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) +void qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) { if (recv_ctx->sds_rings != NULL) kfree(recv_ctx->sds_rings); @@ -164,80 +145,6 @@ qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) recv_ctx->sds_rings = NULL; } -static int -qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev) -{ - int ring; - struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; - - if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings)) - return -ENOMEM; - - for (ring = 0; ring < adapter->max_sds_rings; ring++) { - sds_ring = &recv_ctx->sds_rings[ring]; - - if (ring == adapter->max_sds_rings - 1) - netif_napi_add(netdev, &sds_ring->napi, qlcnic_poll, - QLCNIC_NETDEV_WEIGHT/adapter->max_sds_rings); - else - netif_napi_add(netdev, &sds_ring->napi, - qlcnic_rx_poll, QLCNIC_NETDEV_WEIGHT*2); - } - - return 0; -} - -static void -qlcnic_napi_del(struct qlcnic_adapter *adapter) -{ - int ring; - struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; - - for (ring = 0; ring < adapter->max_sds_rings; ring++) { - sds_ring = &recv_ctx->sds_rings[ring]; - netif_napi_del(&sds_ring->napi); - } - - qlcnic_free_sds_rings(adapter->recv_ctx); -} - -static void -qlcnic_napi_enable(struct qlcnic_adapter *adapter) -{ - int ring; - struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; - - if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) - return; - - for (ring = 0; ring < adapter->max_sds_rings; ring++) { - sds_ring = &recv_ctx->sds_rings[ring]; - napi_enable(&sds_ring->napi); - qlcnic_enable_int(sds_ring); - } -} - -static void -qlcnic_napi_disable(struct qlcnic_adapter *adapter) -{ - int ring; - struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; - - if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) - return; - - for (ring = 0; ring < adapter->max_sds_rings; ring++) { - sds_ring = &recv_ctx->sds_rings[ring]; - qlcnic_disable_int(sds_ring); - napi_synchronize(&sds_ring->napi); - napi_disable(&sds_ring->napi); - } -} - static void qlcnic_clear_stats(struct qlcnic_adapter *adapter) { memset(&adapter->stats, 0, sizeof(adapter->stats)); @@ -1924,428 +1831,6 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) adapter->fhash.fmax = 0; } -static void qlcnic_change_filter(struct qlcnic_adapter *adapter, - u64 uaddr, __le16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) -{ - struct cmd_desc_type0 *hwdesc; - struct qlcnic_nic_req *req; - struct qlcnic_mac_req *mac_req; - struct qlcnic_vlan_req *vlan_req; - u32 producer; - u64 word; - - producer = tx_ring->producer; - hwdesc = &tx_ring->desc_head[tx_ring->producer]; - - req = (struct qlcnic_nic_req *)hwdesc; - memset(req, 0, sizeof(struct qlcnic_nic_req)); - req->qhdr = cpu_to_le64(QLCNIC_REQUEST << 23); - - word = QLCNIC_MAC_EVENT | ((u64)(adapter->portnum) << 16); - req->req_hdr = cpu_to_le64(word); - - mac_req = (struct qlcnic_mac_req *)&(req->words[0]); - mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; - memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); - - vlan_req = (struct qlcnic_vlan_req *)&req->words[1]; - vlan_req->vlan_id = vlan_id; - - tx_ring->producer = get_next_index(producer, tx_ring->num_desc); - smp_mb(); -} - -#define QLCNIC_MAC_HASH(MAC)\ - ((((MAC) & 0x70000) >> 0x10) | (((MAC) & 0x70000000000ULL) >> 0x25)) - -static void -qlcnic_send_filter(struct qlcnic_adapter *adapter, - struct qlcnic_host_tx_ring *tx_ring, - struct cmd_desc_type0 *first_desc, - struct sk_buff *skb) -{ - struct ethhdr *phdr = (struct ethhdr *)(skb->data); - struct qlcnic_filter *fil, *tmp_fil; - struct hlist_node *tmp_hnode, *n; - struct hlist_head *head; - u64 src_addr = 0; - __le16 vlan_id = 0; - u8 hindex; - - if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) - return; - - if (adapter->fhash.fnum >= adapter->fhash.fmax) - return; - - /* Only NPAR capable devices support vlan based learning*/ - if (adapter->flags & QLCNIC_ESWITCH_ENABLED) - vlan_id = first_desc->vlan_TCI; - memcpy(&src_addr, phdr->h_source, ETH_ALEN); - hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1); - head = &(adapter->fhash.fhead[hindex]); - - hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { - if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && - tmp_fil->vlan_id == vlan_id) { - - if (jiffies > - (QLCNIC_READD_AGE * HZ + tmp_fil->ftime)) - qlcnic_change_filter(adapter, src_addr, vlan_id, - tx_ring); - tmp_fil->ftime = jiffies; - return; - } - } - - fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); - if (!fil) - return; - - qlcnic_change_filter(adapter, src_addr, vlan_id, tx_ring); - - fil->ftime = jiffies; - fil->vlan_id = vlan_id; - memcpy(fil->faddr, &src_addr, ETH_ALEN); - spin_lock(&adapter->mac_learn_lock); - hlist_add_head(&(fil->fnode), head); - adapter->fhash.fnum++; - spin_unlock(&adapter->mac_learn_lock); -} - -static int -qlcnic_tx_pkt(struct qlcnic_adapter *adapter, - struct cmd_desc_type0 *first_desc, - struct sk_buff *skb) -{ - u8 opcode = 0, hdr_len = 0; - u16 flags = 0, vlan_tci = 0; - int copied, offset, copy_len; - struct cmd_desc_type0 *hwdesc; - struct vlan_ethhdr *vh; - struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; - u16 protocol = ntohs(skb->protocol); - u32 producer = tx_ring->producer; - - if (protocol == ETH_P_8021Q) { - vh = (struct vlan_ethhdr *)skb->data; - flags = FLAGS_VLAN_TAGGED; - vlan_tci = ntohs(vh->h_vlan_TCI); - protocol = ntohs(vh->h_vlan_encapsulated_proto); - } else if (vlan_tx_tag_present(skb)) { - flags = FLAGS_VLAN_OOB; - vlan_tci = vlan_tx_tag_get(skb); - } - if (unlikely(adapter->pvid)) { - if (vlan_tci && !(adapter->flags & QLCNIC_TAGGING_ENABLED)) - return -EIO; - if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED)) - goto set_flags; - - flags = FLAGS_VLAN_OOB; - vlan_tci = adapter->pvid; - } -set_flags: - qlcnic_set_tx_vlan_tci(first_desc, vlan_tci); - qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); - - if (*(skb->data) & BIT_0) { - flags |= BIT_0; - memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); - } - opcode = TX_ETHER_PKT; - if ((adapter->netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && - skb_shinfo(skb)->gso_size > 0) { - - hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - - first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - first_desc->total_hdr_length = hdr_len; - - opcode = (protocol == ETH_P_IPV6) ? TX_TCP_LSO6 : TX_TCP_LSO; - - /* For LSO, we need to copy the MAC/IP/TCP headers into - * the descriptor ring */ - copied = 0; - offset = 2; - - if (flags & FLAGS_VLAN_OOB) { - first_desc->total_hdr_length += VLAN_HLEN; - first_desc->tcp_hdr_offset = VLAN_HLEN; - first_desc->ip_hdr_offset = VLAN_HLEN; - /* Only in case of TSO on vlan device */ - flags |= FLAGS_VLAN_TAGGED; - - /* Create a TSO vlan header template for firmware */ - - hwdesc = &tx_ring->desc_head[producer]; - tx_ring->cmd_buf_arr[producer].skb = NULL; - - copy_len = min((int)sizeof(struct cmd_desc_type0) - - offset, hdr_len + VLAN_HLEN); - - vh = (struct vlan_ethhdr *)((char *) hwdesc + 2); - skb_copy_from_linear_data(skb, vh, 12); - vh->h_vlan_proto = htons(ETH_P_8021Q); - vh->h_vlan_TCI = htons(vlan_tci); - - skb_copy_from_linear_data_offset(skb, 12, - (char *)vh + 16, copy_len - 16); - - copied = copy_len - VLAN_HLEN; - offset = 0; - - producer = get_next_index(producer, tx_ring->num_desc); - } - - while (copied < hdr_len) { - - copy_len = min((int)sizeof(struct cmd_desc_type0) - - offset, (hdr_len - copied)); - - hwdesc = &tx_ring->desc_head[producer]; - tx_ring->cmd_buf_arr[producer].skb = NULL; - - skb_copy_from_linear_data_offset(skb, copied, - (char *) hwdesc + offset, copy_len); - - copied += copy_len; - offset = 0; - - producer = get_next_index(producer, tx_ring->num_desc); - } - - tx_ring->producer = producer; - smp_mb(); - adapter->stats.lso_frames++; - - } else if (skb->ip_summed == CHECKSUM_PARTIAL) { - u8 l4proto; - - if (protocol == ETH_P_IP) { - l4proto = ip_hdr(skb)->protocol; - - if (l4proto == IPPROTO_TCP) - opcode = TX_TCP_PKT; - else if (l4proto == IPPROTO_UDP) - opcode = TX_UDP_PKT; - } else if (protocol == ETH_P_IPV6) { - l4proto = ipv6_hdr(skb)->nexthdr; - - if (l4proto == IPPROTO_TCP) - opcode = TX_TCPV6_PKT; - else if (l4proto == IPPROTO_UDP) - opcode = TX_UDPV6_PKT; - } - } - first_desc->tcp_hdr_offset += skb_transport_offset(skb); - first_desc->ip_hdr_offset += skb_network_offset(skb); - qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); - - return 0; -} - -static int -qlcnic_map_tx_skb(struct pci_dev *pdev, - struct sk_buff *skb, struct qlcnic_cmd_buffer *pbuf) -{ - struct qlcnic_skb_frag *nf; - struct skb_frag_struct *frag; - int i, nr_frags; - dma_addr_t map; - - nr_frags = skb_shinfo(skb)->nr_frags; - nf = &pbuf->frag_array[0]; - - map = pci_map_single(pdev, skb->data, - skb_headlen(skb), PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(pdev, map)) - goto out_err; - - nf->dma = map; - nf->length = skb_headlen(skb); - - for (i = 0; i < nr_frags; i++) { - frag = &skb_shinfo(skb)->frags[i]; - nf = &pbuf->frag_array[i+1]; - - map = skb_frag_dma_map(&pdev->dev, frag, 0, skb_frag_size(frag), - DMA_TO_DEVICE); - if (dma_mapping_error(&pdev->dev, map)) - goto unwind; - - nf->dma = map; - nf->length = skb_frag_size(frag); - } - - return 0; - -unwind: - while (--i >= 0) { - nf = &pbuf->frag_array[i+1]; - pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); - } - - nf = &pbuf->frag_array[0]; - pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); - -out_err: - return -ENOMEM; -} - -static void -qlcnic_unmap_buffers(struct pci_dev *pdev, struct sk_buff *skb, - struct qlcnic_cmd_buffer *pbuf) -{ - struct qlcnic_skb_frag *nf = &pbuf->frag_array[0]; - int nr_frags = skb_shinfo(skb)->nr_frags; - int i; - - for (i = 0; i < nr_frags; i++) { - nf = &pbuf->frag_array[i+1]; - pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); - } - - nf = &pbuf->frag_array[0]; - pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); - pbuf->skb = NULL; -} - -static inline void -qlcnic_clear_cmddesc(u64 *desc) -{ - desc[0] = 0ULL; - desc[2] = 0ULL; - desc[7] = 0ULL; -} - -netdev_tx_t -qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - struct qlcnic_adapter *adapter = netdev_priv(netdev); - struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; - struct qlcnic_cmd_buffer *pbuf; - struct qlcnic_skb_frag *buffrag; - struct cmd_desc_type0 *hwdesc, *first_desc; - struct pci_dev *pdev; - struct ethhdr *phdr; - int delta = 0; - int i, k; - - u32 producer; - int frag_count; - u32 num_txd = tx_ring->num_desc; - - if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { - netif_stop_queue(netdev); - return NETDEV_TX_BUSY; - } - - if (adapter->flags & QLCNIC_MACSPOOF) { - phdr = (struct ethhdr *)skb->data; - if (!ether_addr_equal(phdr->h_source, adapter->mac_addr)) - goto drop_packet; - } - - frag_count = skb_shinfo(skb)->nr_frags + 1; - /* 14 frags supported for normal packet and - * 32 frags supported for TSO packet - */ - if (!skb_is_gso(skb) && frag_count > QLCNIC_MAX_FRAGS_PER_TX) { - - for (i = 0; i < (frag_count - QLCNIC_MAX_FRAGS_PER_TX); i++) - delta += skb_frag_size(&skb_shinfo(skb)->frags[i]); - - if (!__pskb_pull_tail(skb, delta)) - goto drop_packet; - - frag_count = 1 + skb_shinfo(skb)->nr_frags; - } - - if (unlikely(qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH)) { - netif_stop_queue(netdev); - if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) - netif_start_queue(netdev); - else { - adapter->stats.xmit_off++; - return NETDEV_TX_BUSY; - } - } - - producer = tx_ring->producer; - pbuf = &tx_ring->cmd_buf_arr[producer]; - - pdev = adapter->pdev; - - first_desc = hwdesc = &tx_ring->desc_head[producer]; - qlcnic_clear_cmddesc((u64 *)hwdesc); - - if (qlcnic_map_tx_skb(pdev, skb, pbuf)) { - adapter->stats.tx_dma_map_error++; - goto drop_packet; - } - - pbuf->skb = skb; - pbuf->frag_count = frag_count; - - qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len); - qlcnic_set_tx_port(first_desc, adapter->portnum); - - for (i = 0; i < frag_count; i++) { - - k = i % 4; - - if ((k == 0) && (i > 0)) { - /* move to next desc.*/ - producer = get_next_index(producer, num_txd); - hwdesc = &tx_ring->desc_head[producer]; - qlcnic_clear_cmddesc((u64 *)hwdesc); - tx_ring->cmd_buf_arr[producer].skb = NULL; - } - - buffrag = &pbuf->frag_array[i]; - - hwdesc->buffer_length[k] = cpu_to_le16(buffrag->length); - switch (k) { - case 0: - hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); - break; - case 1: - hwdesc->addr_buffer2 = cpu_to_le64(buffrag->dma); - break; - case 2: - hwdesc->addr_buffer3 = cpu_to_le64(buffrag->dma); - break; - case 3: - hwdesc->addr_buffer4 = cpu_to_le64(buffrag->dma); - break; - } - } - - tx_ring->producer = get_next_index(producer, num_txd); - smp_mb(); - - if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb))) - goto unwind_buff; - - if (adapter->mac_learn) - qlcnic_send_filter(adapter, tx_ring, first_desc, skb); - - adapter->stats.txbytes += skb->len; - adapter->stats.xmitcalled++; - - qlcnic_update_cmd_producer(tx_ring); - - return NETDEV_TX_OK; - -unwind_buff: - qlcnic_unmap_buffers(pdev, skb, pbuf); -drop_packet: - adapter->stats.txdropped++; - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; -} - static int qlcnic_check_temp(struct qlcnic_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -2382,27 +1867,6 @@ static int qlcnic_check_temp(struct qlcnic_adapter *adapter) return rv; } -void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) -{ - struct net_device *netdev = adapter->netdev; - - if (adapter->ahw->linkup && !linkup) { - netdev_info(netdev, "NIC Link is down\n"); - adapter->ahw->linkup = 0; - if (netif_running(netdev)) { - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - } else if (!adapter->ahw->linkup && linkup) { - netdev_info(netdev, "NIC Link is up\n"); - adapter->ahw->linkup = 1; - if (netif_running(netdev)) { - netif_carrier_on(netdev); - netif_wake_queue(netdev); - } - } -} - static void qlcnic_tx_timeout(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); @@ -2509,122 +1973,6 @@ static irqreturn_t qlcnic_msix_intr(int irq, void *data) return IRQ_HANDLED; } -static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter) -{ - u32 sw_consumer, hw_consumer; - int count = 0, i; - struct qlcnic_cmd_buffer *buffer; - struct pci_dev *pdev = adapter->pdev; - struct net_device *netdev = adapter->netdev; - struct qlcnic_skb_frag *frag; - int done; - struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; - - if (!spin_trylock(&adapter->tx_clean_lock)) - return 1; - - sw_consumer = tx_ring->sw_consumer; - hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); - - while (sw_consumer != hw_consumer) { - buffer = &tx_ring->cmd_buf_arr[sw_consumer]; - if (buffer->skb) { - frag = &buffer->frag_array[0]; - pci_unmap_single(pdev, frag->dma, frag->length, - PCI_DMA_TODEVICE); - frag->dma = 0ULL; - for (i = 1; i < buffer->frag_count; i++) { - frag++; - pci_unmap_page(pdev, frag->dma, frag->length, - PCI_DMA_TODEVICE); - frag->dma = 0ULL; - } - - adapter->stats.xmitfinished++; - dev_kfree_skb_any(buffer->skb); - buffer->skb = NULL; - } - - sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc); - if (++count >= MAX_STATUS_HANDLE) - break; - } - - if (count && netif_running(netdev)) { - tx_ring->sw_consumer = sw_consumer; - - smp_mb(); - - if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { - if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { - netif_wake_queue(netdev); - adapter->stats.xmit_on++; - } - } - adapter->tx_timeo_cnt = 0; - } - /* - * If everything is freed up to consumer then check if the ring is full - * If the ring is full then check if more needs to be freed and - * schedule the call back again. - * - * This happens when there are 2 CPUs. One could be freeing and the - * other filling it. If the ring is full when we get out of here and - * the card has already interrupted the host then the host can miss the - * interrupt. - * - * There is still a possible race condition and the host could miss an - * interrupt. The card has to take care of this. - */ - hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); - done = (sw_consumer == hw_consumer); - spin_unlock(&adapter->tx_clean_lock); - - return done; -} - -static int qlcnic_poll(struct napi_struct *napi, int budget) -{ - struct qlcnic_host_sds_ring *sds_ring = - container_of(napi, struct qlcnic_host_sds_ring, napi); - - struct qlcnic_adapter *adapter = sds_ring->adapter; - - int tx_complete; - int work_done; - - tx_complete = qlcnic_process_cmd_ring(adapter); - - work_done = qlcnic_process_rcv_ring(sds_ring, budget); - - if ((work_done < budget) && tx_complete) { - napi_complete(&sds_ring->napi); - if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) - qlcnic_enable_int(sds_ring); - } - - return work_done; -} - -static int qlcnic_rx_poll(struct napi_struct *napi, int budget) -{ - struct qlcnic_host_sds_ring *sds_ring = - container_of(napi, struct qlcnic_host_sds_ring, napi); - - struct qlcnic_adapter *adapter = sds_ring->adapter; - int work_done; - - work_done = qlcnic_process_rcv_ring(sds_ring, budget); - - if (work_done < budget) { - napi_complete(&sds_ring->napi); - if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) - qlcnic_enable_int(sds_ring); - } - - return work_done; -} - #ifdef CONFIG_NET_POLL_CONTROLLER static void qlcnic_poll_controller(struct net_device *netdev) { |