aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
diff options
context:
space:
mode:
authorSony Chacko <sony.chacko@qlogic.com>2012-12-31 22:20:20 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 05:43:26 -0500
commit4be41e92f7c613d6c08686374ad0fdeaaa2a7280 (patch)
treeee5a37cf0fb67dacaf9d741c3cf47e16f6e55268 /drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
parent7f9664525f9cb507de9198a395a111371413f230 (diff)
qlcnic: 83xx data path routines
Add 83xx adapter data path routines Update few 82xx adapter data path routines Modify datapath resource allocation routines Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com> Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com> Signed-off-by: Sony Chacko <sony.chacko@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c592
1 files changed, 542 insertions, 50 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index d678e6d763e1..383ecd20d9b5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -5,9 +5,6 @@
5 5
6#include "qlcnic.h" 6#include "qlcnic.h"
7 7
8#define QLCNIC_MAC_HASH(MAC)\
9 ((((MAC) & 0x70000) >> 0x10) | (((MAC) & 0x70000000000ULL) >> 0x25))
10
11#define TX_ETHER_PKT 0x01 8#define TX_ETHER_PKT 0x01
12#define TX_TCP_PKT 0x02 9#define TX_TCP_PKT 0x02
13#define TX_UDP_PKT 0x03 10#define TX_UDP_PKT 0x03
@@ -91,10 +88,61 @@
91#define QLCNIC_RESPONSE_DESC 0x05 88#define QLCNIC_RESPONSE_DESC 0x05
92#define QLCNIC_LRO_DESC 0x12 89#define QLCNIC_LRO_DESC 0x12
93 90
91#define QLCNIC_TX_POLL_BUDGET 128
92#define QLCNIC_TCP_HDR_SIZE 20
93#define QLCNIC_TCP_TS_OPTION_SIZE 12
94#define QLCNIC_FETCH_RING_ID(handle) ((handle) >> 63)
95#define QLCNIC_DESC_OWNER_FW cpu_to_le64(STATUS_OWNER_PHANTOM)
96
97#define QLCNIC_TCP_TS_HDR_SIZE (QLCNIC_TCP_HDR_SIZE + QLCNIC_TCP_TS_OPTION_SIZE)
98
94/* for status field in status_desc */ 99/* for status field in status_desc */
95#define STATUS_CKSUM_LOOP 0 100#define STATUS_CKSUM_LOOP 0
96#define STATUS_CKSUM_OK 2 101#define STATUS_CKSUM_OK 2
97 102
103#define qlcnic_83xx_pktln(sts) ((sts >> 32) & 0x3FFF)
104#define qlcnic_83xx_hndl(sts) ((sts >> 48) & 0x7FFF)
105#define qlcnic_83xx_csum_status(sts) ((sts >> 39) & 7)
106#define qlcnic_83xx_opcode(sts) ((sts >> 42) & 0xF)
107#define qlcnic_83xx_vlan_tag(sts) (((sts) >> 48) & 0xFFFF)
108#define qlcnic_83xx_lro_pktln(sts) (((sts) >> 32) & 0x3FFF)
109#define qlcnic_83xx_l2_hdr_off(sts) (((sts) >> 16) & 0xFF)
110#define qlcnic_83xx_l4_hdr_off(sts) (((sts) >> 24) & 0xFF)
111#define qlcnic_83xx_pkt_cnt(sts) (((sts) >> 16) & 0x7)
112#define qlcnic_83xx_is_tstamp(sts) (((sts) >> 40) & 1)
113#define qlcnic_83xx_is_psh_bit(sts) (((sts) >> 41) & 1)
114#define qlcnic_83xx_is_ip_align(sts) (((sts) >> 46) & 1)
115#define qlcnic_83xx_has_vlan_tag(sts) (((sts) >> 47) & 1)
116
117struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *,
118 struct qlcnic_host_rds_ring *, u16, u16);
119
120inline void qlcnic_83xx_enable_tx_intr(struct qlcnic_adapter *adapter,
121 struct qlcnic_host_tx_ring *tx_ring)
122{
123 writel(0, tx_ring->crb_intr_mask);
124}
125
126inline void qlcnic_83xx_disable_tx_intr(struct qlcnic_adapter *adapter,
127 struct qlcnic_host_tx_ring *tx_ring)
128{
129 writel(1, tx_ring->crb_intr_mask);
130}
131
132static inline u8 qlcnic_mac_hash(u64 mac)
133{
134 return (u8)((mac & 0xff) ^ ((mac >> 40) & 0xff));
135}
136
137static inline u32 qlcnic_get_ref_handle(struct qlcnic_adapter *adapter,
138 u16 handle, u8 ring_id)
139{
140 if (adapter->pdev->device == PCI_DEVICE_ID_QLOGIC_QLE834X)
141 return handle | (ring_id << 15);
142 else
143 return handle;
144}
145
98void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr, 146void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr,
99 __le16 vlan_id) 147 __le16 vlan_id)
100{ 148{
@@ -128,29 +176,33 @@ void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr,
128} 176}
129 177
130static void qlcnic_send_filter(struct qlcnic_adapter *adapter, 178static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
131 struct qlcnic_host_tx_ring *tx_ring,
132 struct cmd_desc_type0 *first_desc, 179 struct cmd_desc_type0 *first_desc,
133 struct sk_buff *skb) 180 struct sk_buff *skb)
134{ 181{
135 struct qlcnic_filter *fil, *tmp_fil; 182 struct qlcnic_filter *fil, *tmp_fil;
136 struct hlist_node *tmp_hnode, *n; 183 struct hlist_node *tmp_hnode, *n;
137 struct hlist_head *head; 184 struct hlist_head *head;
185 struct net_device *netdev = adapter->netdev;
138 struct ethhdr *phdr = (struct ethhdr *)(skb->data); 186 struct ethhdr *phdr = (struct ethhdr *)(skb->data);
139 u64 src_addr = 0; 187 u64 src_addr = 0;
140 __le16 vlan_id = 0; 188 __le16 vlan_id = 0;
141 u8 hindex; 189 u8 hindex;
142 190
143 if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) 191 if (ether_addr_equal(phdr->h_source, adapter->mac_addr))
144 return; 192 return;
145 193
146 if (adapter->fhash.fnum >= adapter->fhash.fmax) 194 if (adapter->fhash.fnum >= adapter->fhash.fmax) {
195 adapter->stats.mac_filter_limit_overrun++;
196 netdev_info(netdev, "Can not add more than %d mac addresses\n",
197 adapter->fhash.fmax);
147 return; 198 return;
199 }
148 200
149 /* Only NPAR capable devices support vlan based learning */ 201 /* Only NPAR capable devices support vlan based learning */
150 if (adapter->flags & QLCNIC_ESWITCH_ENABLED) 202 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
151 vlan_id = first_desc->vlan_TCI; 203 vlan_id = first_desc->vlan_TCI;
152 memcpy(&src_addr, phdr->h_source, ETH_ALEN); 204 memcpy(&src_addr, phdr->h_source, ETH_ALEN);
153 hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1); 205 hindex = qlcnic_mac_hash(src_addr) & (adapter->fhash.fbucket_size - 1);
154 head = &(adapter->fhash.fhead[hindex]); 206 head = &(adapter->fhash.fhead[hindex]);
155 207
156 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { 208 hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
@@ -470,7 +522,7 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
470 goto unwind_buff; 522 goto unwind_buff;
471 523
472 if (adapter->mac_learn) 524 if (adapter->mac_learn)
473 qlcnic_send_filter(adapter, tx_ring, first_desc, skb); 525 qlcnic_send_filter(adapter, first_desc, skb);
474 526
475 adapter->stats.txbytes += skb->len; 527 adapter->stats.txbytes += skb->len;
476 adapter->stats.xmitcalled++; 528 adapter->stats.xmitcalled++;
@@ -523,8 +575,8 @@ static int qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
523 } 575 }
524 576
525 skb_reserve(skb, NET_IP_ALIGN); 577 skb_reserve(skb, NET_IP_ALIGN);
526 dma = pci_map_single(pdev, skb->data, rds_ring->dma_size, 578 dma = pci_map_single(pdev, skb->data,
527 PCI_DMA_FROMDEVICE); 579 rds_ring->dma_size, PCI_DMA_FROMDEVICE);
528 580
529 if (pci_dma_mapping_error(pdev, dma)) { 581 if (pci_dma_mapping_error(pdev, dma)) {
530 adapter->stats.rx_dma_map_error++; 582 adapter->stats.rx_dma_map_error++;
@@ -539,12 +591,13 @@ static int qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
539} 591}
540 592
541static void qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, 593static void qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
542 struct qlcnic_host_rds_ring *rds_ring) 594 struct qlcnic_host_rds_ring *rds_ring,
595 u8 ring_id)
543{ 596{
544 struct rcv_desc *pdesc; 597 struct rcv_desc *pdesc;
545 struct qlcnic_rx_buffer *buffer; 598 struct qlcnic_rx_buffer *buffer;
546 int count = 0; 599 int count = 0;
547 uint32_t producer; 600 uint32_t producer, handle;
548 struct list_head *head; 601 struct list_head *head;
549 602
550 if (!spin_trylock(&rds_ring->lock)) 603 if (!spin_trylock(&rds_ring->lock))
@@ -552,7 +605,6 @@ static void qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
552 605
553 producer = rds_ring->producer; 606 producer = rds_ring->producer;
554 head = &rds_ring->free_list; 607 head = &rds_ring->free_list;
555
556 while (!list_empty(head)) { 608 while (!list_empty(head)) {
557 buffer = list_entry(head->next, struct qlcnic_rx_buffer, list); 609 buffer = list_entry(head->next, struct qlcnic_rx_buffer, list);
558 610
@@ -560,28 +612,29 @@ static void qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
560 if (qlcnic_alloc_rx_skb(adapter, rds_ring, buffer)) 612 if (qlcnic_alloc_rx_skb(adapter, rds_ring, buffer))
561 break; 613 break;
562 } 614 }
563
564 count++; 615 count++;
565 list_del(&buffer->list); 616 list_del(&buffer->list);
566 617
567 /* make a rcv descriptor */ 618 /* make a rcv descriptor */
568 pdesc = &rds_ring->desc_head[producer]; 619 pdesc = &rds_ring->desc_head[producer];
569 pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); 620 handle = qlcnic_get_ref_handle(adapter,
621 buffer->ref_handle, ring_id);
622 pdesc->reference_handle = cpu_to_le16(handle);
570 pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); 623 pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
571 pdesc->addr_buffer = cpu_to_le64(buffer->dma); 624 pdesc->addr_buffer = cpu_to_le64(buffer->dma);
572 producer = get_next_index(producer, rds_ring->num_desc); 625 producer = get_next_index(producer, rds_ring->num_desc);
573 } 626 }
574
575 if (count) { 627 if (count) {
576 rds_ring->producer = producer; 628 rds_ring->producer = producer;
577 writel((producer - 1) & (rds_ring->num_desc - 1), 629 writel((producer - 1) & (rds_ring->num_desc - 1),
578 rds_ring->crb_rcv_producer); 630 rds_ring->crb_rcv_producer);
579 } 631 }
580
581 spin_unlock(&rds_ring->lock); 632 spin_unlock(&rds_ring->lock);
582} 633}
583 634
584static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter) 635static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter,
636 struct qlcnic_host_tx_ring *tx_ring,
637 int budget)
585{ 638{
586 u32 sw_consumer, hw_consumer; 639 u32 sw_consumer, hw_consumer;
587 int i, done, count = 0; 640 int i, done, count = 0;
@@ -589,7 +642,6 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
589 struct pci_dev *pdev = adapter->pdev; 642 struct pci_dev *pdev = adapter->pdev;
590 struct net_device *netdev = adapter->netdev; 643 struct net_device *netdev = adapter->netdev;
591 struct qlcnic_skb_frag *frag; 644 struct qlcnic_skb_frag *frag;
592 struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
593 645
594 if (!spin_trylock(&adapter->tx_clean_lock)) 646 if (!spin_trylock(&adapter->tx_clean_lock))
595 return 1; 647 return 1;
@@ -610,22 +662,19 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
610 PCI_DMA_TODEVICE); 662 PCI_DMA_TODEVICE);
611 frag->dma = 0ULL; 663 frag->dma = 0ULL;
612 } 664 }
613
614 adapter->stats.xmitfinished++; 665 adapter->stats.xmitfinished++;
615 dev_kfree_skb_any(buffer->skb); 666 dev_kfree_skb_any(buffer->skb);
616 buffer->skb = NULL; 667 buffer->skb = NULL;
617 } 668 }
618 669
619 sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc); 670 sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc);
620 if (++count >= MAX_STATUS_HANDLE) 671 if (++count >= budget)
621 break; 672 break;
622 } 673 }
623 674
624 if (count && netif_running(netdev)) { 675 if (count && netif_running(netdev)) {
625 tx_ring->sw_consumer = sw_consumer; 676 tx_ring->sw_consumer = sw_consumer;
626
627 smp_mb(); 677 smp_mb();
628
629 if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { 678 if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
630 if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { 679 if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) {
631 netif_wake_queue(netdev); 680 netif_wake_queue(netdev);
@@ -649,7 +698,6 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
649 */ 698 */
650 hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); 699 hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
651 done = (sw_consumer == hw_consumer); 700 done = (sw_consumer == hw_consumer);
652
653 spin_unlock(&adapter->tx_clean_lock); 701 spin_unlock(&adapter->tx_clean_lock);
654 702
655 return done; 703 return done;
@@ -657,16 +705,15 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
657 705
658static int qlcnic_poll(struct napi_struct *napi, int budget) 706static int qlcnic_poll(struct napi_struct *napi, int budget)
659{ 707{
708 int tx_complete, work_done;
660 struct qlcnic_host_sds_ring *sds_ring; 709 struct qlcnic_host_sds_ring *sds_ring;
661 struct qlcnic_adapter *adapter; 710 struct qlcnic_adapter *adapter;
662 int tx_complete, work_done;
663 711
664 sds_ring = container_of(napi, struct qlcnic_host_sds_ring, napi); 712 sds_ring = container_of(napi, struct qlcnic_host_sds_ring, napi);
665 adapter = sds_ring->adapter; 713 adapter = sds_ring->adapter;
666 714 tx_complete = qlcnic_process_cmd_ring(adapter, adapter->tx_ring,
667 tx_complete = qlcnic_process_cmd_ring(adapter); 715 budget);
668 work_done = qlcnic_process_rcv_ring(sds_ring, budget); 716 work_done = qlcnic_process_rcv_ring(sds_ring, budget);
669
670 if ((work_done < budget) && tx_complete) { 717 if ((work_done < budget) && tx_complete) {
671 napi_complete(&sds_ring->napi); 718 napi_complete(&sds_ring->napi);
672 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 719 if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
@@ -799,26 +846,23 @@ static void qlcnic_handle_fw_message(int desc_cnt, int index,
799 } 846 }
800} 847}
801 848
802static struct sk_buff * 849struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
803qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, 850 struct qlcnic_host_rds_ring *ring,
804 struct qlcnic_host_rds_ring *rds_ring, u16 index, 851 u16 index, u16 cksum)
805 u16 cksum)
806{ 852{
807 struct qlcnic_rx_buffer *buffer; 853 struct qlcnic_rx_buffer *buffer;
808 struct sk_buff *skb; 854 struct sk_buff *skb;
809 855
810 buffer = &rds_ring->rx_buf_arr[index]; 856 buffer = &ring->rx_buf_arr[index];
811
812 if (unlikely(buffer->skb == NULL)) { 857 if (unlikely(buffer->skb == NULL)) {
813 WARN_ON(1); 858 WARN_ON(1);
814 return NULL; 859 return NULL;
815 } 860 }
816 861
817 pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size, 862 pci_unmap_single(adapter->pdev, buffer->dma, ring->dma_size,
818 PCI_DMA_FROMDEVICE); 863 PCI_DMA_FROMDEVICE);
819 864
820 skb = buffer->skb; 865 skb = buffer->skb;
821
822 if (likely((adapter->netdev->features & NETIF_F_RXCSUM) && 866 if (likely((adapter->netdev->features & NETIF_F_RXCSUM) &&
823 (cksum == STATUS_CKSUM_OK || cksum == STATUS_CKSUM_LOOP))) { 867 (cksum == STATUS_CKSUM_OK || cksum == STATUS_CKSUM_LOOP))) {
824 adapter->stats.csummed++; 868 adapter->stats.csummed++;
@@ -827,6 +871,7 @@ qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
827 skb_checksum_none_assert(skb); 871 skb_checksum_none_assert(skb);
828 } 872 }
829 873
874
830 buffer->skb = NULL; 875 buffer->skb = NULL;
831 876
832 return skb; 877 return skb;
@@ -1001,9 +1046,9 @@ int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max)
1001 struct list_head *cur; 1046 struct list_head *cur;
1002 struct status_desc *desc; 1047 struct status_desc *desc;
1003 struct qlcnic_rx_buffer *rxbuf; 1048 struct qlcnic_rx_buffer *rxbuf;
1049 int opcode, desc_cnt, count = 0;
1004 u64 sts_data0, sts_data1; 1050 u64 sts_data0, sts_data1;
1005 __le64 owner_phantom = cpu_to_le64(STATUS_OWNER_PHANTOM); 1051 u8 ring;
1006 int opcode, ring, desc_cnt, count = 0;
1007 u32 consumer = sds_ring->consumer; 1052 u32 consumer = sds_ring->consumer;
1008 1053
1009 while (count < max) { 1054 while (count < max) {
@@ -1015,7 +1060,6 @@ int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max)
1015 1060
1016 desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0); 1061 desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
1017 opcode = qlcnic_get_sts_opcode(sts_data0); 1062 opcode = qlcnic_get_sts_opcode(sts_data0);
1018
1019 switch (opcode) { 1063 switch (opcode) {
1020 case QLCNIC_RXPKT_DESC: 1064 case QLCNIC_RXPKT_DESC:
1021 case QLCNIC_OLD_RXPKT_DESC: 1065 case QLCNIC_OLD_RXPKT_DESC:
@@ -1035,18 +1079,16 @@ int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max)
1035 default: 1079 default:
1036 goto skip; 1080 goto skip;
1037 } 1081 }
1038
1039 WARN_ON(desc_cnt > 1); 1082 WARN_ON(desc_cnt > 1);
1040 1083
1041 if (likely(rxbuf)) 1084 if (likely(rxbuf))
1042 list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]); 1085 list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
1043 else 1086 else
1044 adapter->stats.null_rxbuf++; 1087 adapter->stats.null_rxbuf++;
1045
1046skip: 1088skip:
1047 for (; desc_cnt > 0; desc_cnt--) { 1089 for (; desc_cnt > 0; desc_cnt--) {
1048 desc = &sds_ring->desc_head[consumer]; 1090 desc = &sds_ring->desc_head[consumer];
1049 desc->status_desc_data[0] = owner_phantom; 1091 desc->status_desc_data[0] = QLCNIC_DESC_OWNER_FW;
1050 consumer = get_next_index(consumer, sds_ring->num_desc); 1092 consumer = get_next_index(consumer, sds_ring->num_desc);
1051 } 1093 }
1052 count++; 1094 count++;
@@ -1054,7 +1096,6 @@ skip:
1054 1096
1055 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1097 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1056 rds_ring = &adapter->recv_ctx->rds_rings[ring]; 1098 rds_ring = &adapter->recv_ctx->rds_rings[ring];
1057
1058 if (!list_empty(&sds_ring->free_list[ring])) { 1099 if (!list_empty(&sds_ring->free_list[ring])) {
1059 list_for_each(cur, &sds_ring->free_list[ring]) { 1100 list_for_each(cur, &sds_ring->free_list[ring]) {
1060 rxbuf = list_entry(cur, struct qlcnic_rx_buffer, 1101 rxbuf = list_entry(cur, struct qlcnic_rx_buffer,
@@ -1067,7 +1108,7 @@ skip:
1067 spin_unlock(&rds_ring->lock); 1108 spin_unlock(&rds_ring->lock);
1068 } 1109 }
1069 1110
1070 qlcnic_post_rx_buffers_nodb(adapter, rds_ring); 1111 qlcnic_post_rx_buffers_nodb(adapter, rds_ring, ring);
1071 } 1112 }
1072 1113
1073 if (count) { 1114 if (count) {
@@ -1079,12 +1120,12 @@ skip:
1079} 1120}
1080 1121
1081void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, 1122void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
1082 struct qlcnic_host_rds_ring *rds_ring) 1123 struct qlcnic_host_rds_ring *rds_ring, u8 ring_id)
1083{ 1124{
1084 struct rcv_desc *pdesc; 1125 struct rcv_desc *pdesc;
1085 struct qlcnic_rx_buffer *buffer; 1126 struct qlcnic_rx_buffer *buffer;
1086 int count = 0; 1127 int count = 0;
1087 u32 producer; 1128 u32 producer, handle;
1088 struct list_head *head; 1129 struct list_head *head;
1089 1130
1090 producer = rds_ring->producer; 1131 producer = rds_ring->producer;
@@ -1105,7 +1146,9 @@ void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
1105 /* make a rcv descriptor */ 1146 /* make a rcv descriptor */
1106 pdesc = &rds_ring->desc_head[producer]; 1147 pdesc = &rds_ring->desc_head[producer];
1107 pdesc->addr_buffer = cpu_to_le64(buffer->dma); 1148 pdesc->addr_buffer = cpu_to_le64(buffer->dma);
1108 pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); 1149 handle = qlcnic_get_ref_handle(adapter, buffer->ref_handle,
1150 ring_id);
1151 pdesc->reference_handle = cpu_to_le16(handle);
1109 pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); 1152 pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
1110 producer = get_next_index(producer, rds_ring->num_desc); 1153 producer = get_next_index(producer, rds_ring->num_desc);
1111 } 1154 }
@@ -1226,8 +1269,7 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter,
1226 1269
1227 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 1270 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1228 sds_ring = &recv_ctx->sds_rings[ring]; 1271 sds_ring = &recv_ctx->sds_rings[ring];
1229 1272 if (ring == adapter->max_sds_rings - 1)
1230 if (ring == max_sds_rings - 1)
1231 netif_napi_add(netdev, &sds_ring->napi, qlcnic_poll, 1273 netif_napi_add(netdev, &sds_ring->napi, qlcnic_poll,
1232 QLCNIC_NETDEV_WEIGHT / max_sds_rings); 1274 QLCNIC_NETDEV_WEIGHT / max_sds_rings);
1233 else 1275 else
@@ -1235,10 +1277,15 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter,
1235 QLCNIC_NETDEV_WEIGHT*2); 1277 QLCNIC_NETDEV_WEIGHT*2);
1236 } 1278 }
1237 1279
1280 if (qlcnic_alloc_tx_rings(adapter, netdev)) {
1281 qlcnic_free_sds_rings(recv_ctx);
1282 return -ENOMEM;
1283 }
1284
1238 return 0; 1285 return 0;
1239} 1286}
1240 1287
1241void qlcnic_napi_del(struct qlcnic_adapter *adapter) 1288void qlcnic_82xx_napi_del(struct qlcnic_adapter *adapter)
1242{ 1289{
1243 int ring; 1290 int ring;
1244 struct qlcnic_host_sds_ring *sds_ring; 1291 struct qlcnic_host_sds_ring *sds_ring;
@@ -1250,6 +1297,7 @@ void qlcnic_napi_del(struct qlcnic_adapter *adapter)
1250 } 1297 }
1251 1298
1252 qlcnic_free_sds_rings(adapter->recv_ctx); 1299 qlcnic_free_sds_rings(adapter->recv_ctx);
1300 qlcnic_free_tx_rings(adapter);
1253} 1301}
1254 1302
1255void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter) 1303void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter)
@@ -1284,3 +1332,447 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter)
1284 napi_disable(&sds_ring->napi); 1332 napi_disable(&sds_ring->napi);
1285 } 1333 }
1286} 1334}
1335
1336static struct qlcnic_rx_buffer *
1337qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter,
1338 struct qlcnic_host_sds_ring *sds_ring,
1339 u8 ring, u64 sts_data[])
1340{
1341 struct net_device *netdev = adapter->netdev;
1342 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1343 struct qlcnic_rx_buffer *buffer;
1344 struct sk_buff *skb;
1345 struct qlcnic_host_rds_ring *rds_ring;
1346 int index, length, cksum;
1347 u16 vid = 0xffff;
1348
1349 if (unlikely(ring >= adapter->max_rds_rings))
1350 return NULL;
1351
1352 rds_ring = &recv_ctx->rds_rings[ring];
1353
1354 index = qlcnic_83xx_hndl(sts_data[0]);
1355 if (unlikely(index >= rds_ring->num_desc))
1356 return NULL;
1357
1358 buffer = &rds_ring->rx_buf_arr[index];
1359 length = qlcnic_83xx_pktln(sts_data[0]);
1360 cksum = qlcnic_83xx_csum_status(sts_data[1]);
1361 skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
1362 if (!skb)
1363 return buffer;
1364
1365 if (length > rds_ring->skb_size)
1366 skb_put(skb, rds_ring->skb_size);
1367 else
1368 skb_put(skb, length);
1369
1370 if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) {
1371 adapter->stats.rxdropped++;
1372 dev_kfree_skb(skb);
1373 return buffer;
1374 }
1375
1376 skb->protocol = eth_type_trans(skb, netdev);
1377
1378 if (vid != 0xffff)
1379 __vlan_hwaccel_put_tag(skb, vid);
1380
1381 napi_gro_receive(&sds_ring->napi, skb);
1382
1383 adapter->stats.rx_pkts++;
1384 adapter->stats.rxbytes += length;
1385
1386 return buffer;
1387}
1388
1389static struct qlcnic_rx_buffer *
1390qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter,
1391 u8 ring, u64 sts_data[])
1392{
1393 struct net_device *netdev = adapter->netdev;
1394 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1395 struct qlcnic_rx_buffer *buffer;
1396 struct sk_buff *skb;
1397 struct qlcnic_host_rds_ring *rds_ring;
1398 struct iphdr *iph;
1399 struct ipv6hdr *ipv6h;
1400 struct tcphdr *th;
1401 bool push;
1402 int l2_hdr_offset, l4_hdr_offset;
1403 int index;
1404 u16 lro_length, length, data_offset;
1405 u16 vid = 0xffff;
1406
1407 if (unlikely(ring > adapter->max_rds_rings))
1408 return NULL;
1409
1410 rds_ring = &recv_ctx->rds_rings[ring];
1411
1412 index = qlcnic_83xx_hndl(sts_data[0]);
1413 if (unlikely(index > rds_ring->num_desc))
1414 return NULL;
1415
1416 buffer = &rds_ring->rx_buf_arr[index];
1417
1418 lro_length = qlcnic_83xx_lro_pktln(sts_data[0]);
1419 l2_hdr_offset = qlcnic_83xx_l2_hdr_off(sts_data[1]);
1420 l4_hdr_offset = qlcnic_83xx_l4_hdr_off(sts_data[1]);
1421 push = qlcnic_83xx_is_psh_bit(sts_data[1]);
1422
1423 skb = qlcnic_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK);
1424 if (!skb)
1425 return buffer;
1426 if (qlcnic_83xx_is_tstamp(sts_data[1]))
1427 data_offset = l4_hdr_offset + QLCNIC_TCP_TS_HDR_SIZE;
1428 else
1429 data_offset = l4_hdr_offset + QLCNIC_TCP_HDR_SIZE;
1430
1431 skb_put(skb, lro_length + data_offset);
1432 skb_pull(skb, l2_hdr_offset);
1433
1434 if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) {
1435 adapter->stats.rxdropped++;
1436 dev_kfree_skb(skb);
1437 return buffer;
1438 }
1439
1440 skb->protocol = eth_type_trans(skb, netdev);
1441 if (ntohs(skb->protocol) == ETH_P_IPV6) {
1442 ipv6h = (struct ipv6hdr *)skb->data;
1443 th = (struct tcphdr *)(skb->data + sizeof(struct ipv6hdr));
1444
1445 length = (th->doff << 2) + lro_length;
1446 ipv6h->payload_len = htons(length);
1447 } else {
1448 iph = (struct iphdr *)skb->data;
1449 th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
1450 length = (iph->ihl << 2) + (th->doff << 2) + lro_length;
1451 iph->tot_len = htons(length);
1452 iph->check = 0;
1453 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
1454 }
1455
1456 th->psh = push;
1457 length = skb->len;
1458
1459 if (vid != 0xffff)
1460 __vlan_hwaccel_put_tag(skb, vid);
1461
1462 netif_receive_skb(skb);
1463
1464 adapter->stats.lro_pkts++;
1465 adapter->stats.lrobytes += length;
1466 return buffer;
1467}
1468
1469static int qlcnic_83xx_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring,
1470 int max)
1471{
1472 struct qlcnic_host_rds_ring *rds_ring;
1473 struct qlcnic_adapter *adapter = sds_ring->adapter;
1474 struct list_head *cur;
1475 struct status_desc *desc;
1476 struct qlcnic_rx_buffer *rxbuf = NULL;
1477 u8 ring;
1478 u64 sts_data[2];
1479 int count = 0, opcode;
1480 u32 consumer = sds_ring->consumer;
1481
1482 while (count < max) {
1483 desc = &sds_ring->desc_head[consumer];
1484 sts_data[1] = le64_to_cpu(desc->status_desc_data[1]);
1485 opcode = qlcnic_83xx_opcode(sts_data[1]);
1486 if (!opcode)
1487 break;
1488 sts_data[0] = le64_to_cpu(desc->status_desc_data[0]);
1489 ring = QLCNIC_FETCH_RING_ID(sts_data[0]);
1490
1491 switch (opcode) {
1492 case QLC_83XX_REG_DESC:
1493 rxbuf = qlcnic_83xx_process_rcv(adapter, sds_ring,
1494 ring, sts_data);
1495 break;
1496 case QLC_83XX_LRO_DESC:
1497 rxbuf = qlcnic_83xx_process_lro(adapter, ring,
1498 sts_data);
1499 break;
1500 default:
1501 dev_info(&adapter->pdev->dev,
1502 "Unkonwn opcode: 0x%x\n", opcode);
1503 goto skip;
1504 }
1505
1506 if (likely(rxbuf))
1507 list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
1508 else
1509 adapter->stats.null_rxbuf++;
1510skip:
1511 desc = &sds_ring->desc_head[consumer];
1512 /* Reset the descriptor */
1513 desc->status_desc_data[1] = 0;
1514 consumer = get_next_index(consumer, sds_ring->num_desc);
1515 count++;
1516 }
1517 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1518 rds_ring = &adapter->recv_ctx->rds_rings[ring];
1519 if (!list_empty(&sds_ring->free_list[ring])) {
1520 list_for_each(cur, &sds_ring->free_list[ring]) {
1521 rxbuf = list_entry(cur, struct qlcnic_rx_buffer,
1522 list);
1523 qlcnic_alloc_rx_skb(adapter, rds_ring, rxbuf);
1524 }
1525 spin_lock(&rds_ring->lock);
1526 list_splice_tail_init(&sds_ring->free_list[ring],
1527 &rds_ring->free_list);
1528 spin_unlock(&rds_ring->lock);
1529 }
1530 qlcnic_post_rx_buffers_nodb(adapter, rds_ring, ring);
1531 }
1532 if (count) {
1533 sds_ring->consumer = consumer;
1534 writel(consumer, sds_ring->crb_sts_consumer);
1535 }
1536 return count;
1537}
1538
1539static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
1540{
1541 int tx_complete;
1542 int work_done;
1543 struct qlcnic_host_sds_ring *sds_ring;
1544 struct qlcnic_adapter *adapter;
1545 struct qlcnic_host_tx_ring *tx_ring;
1546
1547 sds_ring = container_of(napi, struct qlcnic_host_sds_ring, napi);
1548 adapter = sds_ring->adapter;
1549 /* tx ring count = 1 */
1550 tx_ring = adapter->tx_ring;
1551
1552 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1553 qlcnic_83xx_process_aen(adapter);
1554
1555 tx_complete = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
1556 work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
1557 if ((work_done < budget) && tx_complete) {
1558 napi_complete(&sds_ring->napi);
1559 if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
1560 qlcnic_83xx_enable_intr(adapter, sds_ring);
1561 }
1562
1563 return work_done;
1564}
1565
1566static int qlcnic_83xx_msix_tx_poll(struct napi_struct *napi, int budget)
1567{
1568 int work_done;
1569 struct qlcnic_host_tx_ring *tx_ring;
1570 struct qlcnic_adapter *adapter;
1571
1572 budget = QLCNIC_TX_POLL_BUDGET;
1573 tx_ring = container_of(napi, struct qlcnic_host_tx_ring, napi);
1574 adapter = tx_ring->adapter;
1575 work_done = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
1576 if (work_done) {
1577 napi_complete(&tx_ring->napi);
1578 if (test_bit(__QLCNIC_DEV_UP , &adapter->state))
1579 qlcnic_83xx_enable_tx_intr(adapter, tx_ring);
1580 }
1581
1582 return work_done;
1583}
1584
1585static int qlcnic_83xx_rx_poll(struct napi_struct *napi, int budget)
1586{
1587 int work_done;
1588 struct qlcnic_host_sds_ring *sds_ring;
1589 struct qlcnic_adapter *adapter;
1590
1591 sds_ring = container_of(napi, struct qlcnic_host_sds_ring, napi);
1592 adapter = sds_ring->adapter;
1593 work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
1594 if (work_done < budget) {
1595 napi_complete(&sds_ring->napi);
1596 if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
1597 qlcnic_83xx_enable_intr(adapter, sds_ring);
1598 }
1599
1600 return work_done;
1601}
1602
1603void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter)
1604{
1605 int ring;
1606 struct qlcnic_host_sds_ring *sds_ring;
1607 struct qlcnic_host_tx_ring *tx_ring;
1608 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1609
1610 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1611 return;
1612
1613 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1614 sds_ring = &recv_ctx->sds_rings[ring];
1615 napi_enable(&sds_ring->napi);
1616 qlcnic_83xx_enable_intr(adapter, sds_ring);
1617 }
1618
1619 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1620 for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
1621 tx_ring = &adapter->tx_ring[ring];
1622 napi_enable(&tx_ring->napi);
1623 qlcnic_83xx_enable_tx_intr(adapter, tx_ring);
1624 }
1625 }
1626}
1627
1628void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter)
1629{
1630 int ring;
1631 struct qlcnic_host_sds_ring *sds_ring;
1632 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1633 struct qlcnic_host_tx_ring *tx_ring;
1634
1635 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1636 return;
1637
1638 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1639 sds_ring = &recv_ctx->sds_rings[ring];
1640 writel(1, sds_ring->crb_intr_mask);
1641 napi_synchronize(&sds_ring->napi);
1642 napi_disable(&sds_ring->napi);
1643 }
1644
1645 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1646 for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
1647 tx_ring = &adapter->tx_ring[ring];
1648 qlcnic_83xx_disable_tx_intr(adapter, tx_ring);
1649 napi_synchronize(&tx_ring->napi);
1650 napi_disable(&tx_ring->napi);
1651 }
1652 }
1653}
1654
1655int qlcnic_83xx_napi_add(struct qlcnic_adapter *adapter,
1656 struct net_device *netdev)
1657{
1658 int ring, max_sds_rings;
1659 struct qlcnic_host_sds_ring *sds_ring;
1660 struct qlcnic_host_tx_ring *tx_ring;
1661 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1662
1663 if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
1664 return -ENOMEM;
1665
1666 max_sds_rings = adapter->max_sds_rings;
1667 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1668 sds_ring = &recv_ctx->sds_rings[ring];
1669 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1670 netif_napi_add(netdev, &sds_ring->napi,
1671 qlcnic_83xx_rx_poll,
1672 QLCNIC_NETDEV_WEIGHT * 2);
1673 else
1674 netif_napi_add(netdev, &sds_ring->napi,
1675 qlcnic_83xx_poll,
1676 QLCNIC_NETDEV_WEIGHT / max_sds_rings);
1677 }
1678
1679 if (qlcnic_alloc_tx_rings(adapter, netdev)) {
1680 qlcnic_free_sds_rings(recv_ctx);
1681 return -ENOMEM;
1682 }
1683
1684 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1685 for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
1686 tx_ring = &adapter->tx_ring[ring];
1687 netif_napi_add(netdev, &tx_ring->napi,
1688 qlcnic_83xx_msix_tx_poll,
1689 QLCNIC_NETDEV_WEIGHT);
1690 }
1691 }
1692
1693 return 0;
1694}
1695
1696void qlcnic_83xx_napi_del(struct qlcnic_adapter *adapter)
1697{
1698 int ring;
1699 struct qlcnic_host_sds_ring *sds_ring;
1700 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1701 struct qlcnic_host_tx_ring *tx_ring;
1702
1703 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1704 sds_ring = &recv_ctx->sds_rings[ring];
1705 netif_napi_del(&sds_ring->napi);
1706 }
1707
1708 qlcnic_free_sds_rings(adapter->recv_ctx);
1709
1710 if ((adapter->flags & QLCNIC_MSIX_ENABLED)) {
1711 for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
1712 tx_ring = &adapter->tx_ring[ring];
1713 netif_napi_del(&tx_ring->napi);
1714 }
1715 }
1716
1717 qlcnic_free_tx_rings(adapter);
1718}
1719
1720void qlcnic_83xx_process_rcv_diag(struct qlcnic_adapter *adapter,
1721 int ring, u64 sts_data[])
1722{
1723 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1724 struct sk_buff *skb;
1725 struct qlcnic_host_rds_ring *rds_ring;
1726 int index, length;
1727
1728 if (unlikely(ring >= adapter->max_rds_rings))
1729 return;
1730
1731 rds_ring = &recv_ctx->rds_rings[ring];
1732 index = qlcnic_83xx_hndl(sts_data[0]);
1733 if (unlikely(index >= rds_ring->num_desc))
1734 return;
1735
1736 length = qlcnic_83xx_pktln(sts_data[0]);
1737
1738 skb = qlcnic_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK);
1739 if (!skb)
1740 return;
1741
1742 if (length > rds_ring->skb_size)
1743 skb_put(skb, rds_ring->skb_size);
1744 else
1745 skb_put(skb, length);
1746
1747 if (!qlcnic_check_loopback_buff(skb->data, adapter->mac_addr))
1748 adapter->ahw->diag_cnt++;
1749 else
1750 dump_skb(skb, adapter);
1751
1752 dev_kfree_skb_any(skb);
1753 return;
1754}
1755
1756void qlcnic_83xx_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
1757{
1758 struct qlcnic_adapter *adapter = sds_ring->adapter;
1759 struct status_desc *desc;
1760 u64 sts_data[2];
1761 int ring, opcode;
1762 u32 consumer = sds_ring->consumer;
1763
1764 desc = &sds_ring->desc_head[consumer];
1765 sts_data[0] = le64_to_cpu(desc->status_desc_data[0]);
1766 sts_data[1] = le64_to_cpu(desc->status_desc_data[1]);
1767 opcode = qlcnic_83xx_opcode(sts_data[1]);
1768 if (!opcode)
1769 return;
1770
1771 ring = QLCNIC_FETCH_RING_ID(qlcnic_83xx_hndl(sts_data[0]));
1772 qlcnic_83xx_process_rcv_diag(adapter, ring, sts_data);
1773 desc = &sds_ring->desc_head[consumer];
1774 desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
1775 consumer = get_next_index(consumer, sds_ring->num_desc);
1776 sds_ring->consumer = consumer;
1777 writel(consumer, sds_ring->crb_sts_consumer);
1778}