aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic
diff options
context:
space:
mode:
authorschacko <schacko@qlogic.com>2010-06-16 22:56:40 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-17 11:57:55 -0400
commit8f891387aa73b85d2ea8d953e04dac224f687e52 (patch)
treecbf7101c7aa3721cb02298f3f454692bfbd18524 /drivers/net/qlcnic
parent7f9a0c34d26b1ce8a512555ca144e622dea4dc44 (diff)
qlcnic: seperate interrupt for TX
Earlier all poll routine can process rx and tx, But now one poll routine to process rx + tx and other for rx only. Last msix vector will be used for separate tx interrupt. o This is supported from fw version 4.4.2. o Bump version 5.0.5 Signed-off-by: Sony Chacko <schacko@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r--drivers/net/qlcnic/qlcnic.h14
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c7
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c35
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c35
4 files changed, 72 insertions, 19 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 7d31caaf2fa8..9970cff598d1 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -51,8 +51,8 @@
51 51
52#define _QLCNIC_LINUX_MAJOR 5 52#define _QLCNIC_LINUX_MAJOR 5
53#define _QLCNIC_LINUX_MINOR 0 53#define _QLCNIC_LINUX_MINOR 0
54#define _QLCNIC_LINUX_SUBVERSION 4 54#define _QLCNIC_LINUX_SUBVERSION 5
55#define QLCNIC_LINUX_VERSIONID "5.0.4" 55#define QLCNIC_LINUX_VERSIONID "5.0.5"
56#define QLCNIC_DRV_IDC_VER 0x01 56#define QLCNIC_DRV_IDC_VER 0x01
57 57
58#define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) 58#define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
@@ -68,6 +68,7 @@
68#define QLCNIC_DECODE_VERSION(v) \ 68#define QLCNIC_DECODE_VERSION(v) \
69 QLCNIC_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16)) 69 QLCNIC_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16))
70 70
71#define QLCNIC_MIN_FW_VERSION QLCNIC_VERSION_CODE(4, 4, 2)
71#define QLCNIC_NUM_FLASH_SECTORS (64) 72#define QLCNIC_NUM_FLASH_SECTORS (64)
72#define QLCNIC_FLASH_SECTOR_SIZE (64 * 1024) 73#define QLCNIC_FLASH_SECTOR_SIZE (64 * 1024)
73#define QLCNIC_FLASH_TOTAL_SIZE (QLCNIC_NUM_FLASH_SECTORS \ 74#define QLCNIC_FLASH_TOTAL_SIZE (QLCNIC_NUM_FLASH_SECTORS \
@@ -567,6 +568,7 @@ struct qlcnic_recv_context {
567#define QLCNIC_CAP0_LSO (1 << 6) 568#define QLCNIC_CAP0_LSO (1 << 6)
568#define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7) 569#define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7)
569#define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8) 570#define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8)
571#define QLCNIC_CAP0_VALIDOFF (1 << 11)
570 572
571/* 573/*
572 * Context state 574 * Context state
@@ -602,9 +604,10 @@ struct qlcnic_hostrq_rx_ctx {
602 __le32 sds_ring_offset; /* Offset to SDS config */ 604 __le32 sds_ring_offset; /* Offset to SDS config */
603 __le16 num_rds_rings; /* Count of RDS rings */ 605 __le16 num_rds_rings; /* Count of RDS rings */
604 __le16 num_sds_rings; /* Count of SDS rings */ 606 __le16 num_sds_rings; /* Count of SDS rings */
605 __le16 rsvd1; /* Padding */ 607 __le16 valid_field_offset;
606 __le16 rsvd2; /* Padding */ 608 u8 txrx_sds_binding;
607 u8 reserved[128]; /* reserve space for future expansion*/ 609 u8 msix_handler;
610 u8 reserved[128]; /* reserve space for future expansion*/
608 /* MUST BE 64-bit aligned. 611 /* MUST BE 64-bit aligned.
609 The following is packed: 612 The following is packed:
610 - N hostrq_rds_rings 613 - N hostrq_rds_rings
@@ -1109,6 +1112,7 @@ void qlcnic_request_firmware(struct qlcnic_adapter *adapter);
1109void qlcnic_release_firmware(struct qlcnic_adapter *adapter); 1112void qlcnic_release_firmware(struct qlcnic_adapter *adapter);
1110int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter); 1113int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter);
1111int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter); 1114int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter);
1115int qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter);
1112 1116
1113int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp); 1117int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp);
1114int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr, 1118int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 90ed6fbaee34..7c96c8e06c3f 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -152,9 +152,14 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
152 152
153 prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); 153 prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
154 154
155 cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN); 155 cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN
156 | QLCNIC_CAP0_VALIDOFF);
156 cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); 157 cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
157 158
159 prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx,
160 msix_handler);
161 prq->txrx_sds_binding = nsds_rings - 1;
162
158 prq->capabilities[0] = cpu_to_le32(cap); 163 prq->capabilities[0] = cpu_to_le32(cap);
159 prq->host_int_crb_mode = 164 prq->host_int_crb_mode =
160 cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED); 165 cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 317750d67931..2bd00d54dd3f 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -543,16 +543,34 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) {
543 return 0; 543 return 0;
544} 544}
545 545
546int
547qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter)
548{
549 u32 ver = -1, min_ver;
550
551 qlcnic_rom_fast_read(adapter, QLCNIC_FW_VERSION_OFFSET, (int *)&ver);
552
553 ver = QLCNIC_DECODE_VERSION(ver);
554 min_ver = QLCNIC_MIN_FW_VERSION;
555
556 if (ver < min_ver) {
557 dev_err(&adapter->pdev->dev,
558 "firmware version %d.%d.%d unsupported."
559 "Min supported version %d.%d.%d\n",
560 _major(ver), _minor(ver), _build(ver),
561 _major(min_ver), _minor(min_ver), _build(min_ver));
562 return -EINVAL;
563 }
564
565 return 0;
566}
567
546static int 568static int
547qlcnic_has_mn(struct qlcnic_adapter *adapter) 569qlcnic_has_mn(struct qlcnic_adapter *adapter)
548{ 570{
549 u32 capability, flashed_ver; 571 u32 capability;
550 capability = 0; 572 capability = 0;
551 573
552 qlcnic_rom_fast_read(adapter,
553 QLCNIC_FW_VERSION_OFFSET, (int *)&flashed_ver);
554 flashed_ver = QLCNIC_DECODE_VERSION(flashed_ver);
555
556 capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY); 574 capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY);
557 if (capability & QLCNIC_PEG_TUNE_MN_PRESENT) 575 if (capability & QLCNIC_PEG_TUNE_MN_PRESENT)
558 return 1; 576 return 1;
@@ -1006,7 +1024,7 @@ static int
1006qlcnic_validate_firmware(struct qlcnic_adapter *adapter) 1024qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
1007{ 1025{
1008 __le32 val; 1026 __le32 val;
1009 u32 ver, min_ver, bios, min_size; 1027 u32 ver, bios, min_size;
1010 struct pci_dev *pdev = adapter->pdev; 1028 struct pci_dev *pdev = adapter->pdev;
1011 const struct firmware *fw = adapter->fw; 1029 const struct firmware *fw = adapter->fw;
1012 u8 fw_type = adapter->fw_type; 1030 u8 fw_type = adapter->fw_type;
@@ -1028,12 +1046,9 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
1028 return -EINVAL; 1046 return -EINVAL;
1029 1047
1030 val = qlcnic_get_fw_version(adapter); 1048 val = qlcnic_get_fw_version(adapter);
1031
1032 min_ver = QLCNIC_VERSION_CODE(4, 0, 216);
1033
1034 ver = QLCNIC_DECODE_VERSION(val); 1049 ver = QLCNIC_DECODE_VERSION(val);
1035 1050
1036 if ((_major(ver) > _QLCNIC_LINUX_MAJOR) || (ver < min_ver)) { 1051 if (ver < QLCNIC_MIN_FW_VERSION) {
1037 dev_err(&pdev->dev, 1052 dev_err(&pdev->dev,
1038 "%s: firmware version %d.%d.%d unsupported\n", 1053 "%s: firmware version %d.%d.%d unsupported\n",
1039 fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); 1054 fw_name[fw_type], _major(ver), _minor(ver), _build(ver));
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 28ed28c1cbcc..06d2dfd646fe 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -83,6 +83,7 @@ static void qlcnic_schedule_work(struct qlcnic_adapter *adapter,
83 work_func_t func, int delay); 83 work_func_t func, int delay);
84static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); 84static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter);
85static int qlcnic_poll(struct napi_struct *napi, int budget); 85static int qlcnic_poll(struct napi_struct *napi, int budget);
86static int qlcnic_rx_poll(struct napi_struct *napi, int budget);
86#ifdef CONFIG_NET_POLL_CONTROLLER 87#ifdef CONFIG_NET_POLL_CONTROLLER
87static void qlcnic_poll_controller(struct net_device *netdev); 88static void qlcnic_poll_controller(struct net_device *netdev);
88#endif 89#endif
@@ -195,8 +196,13 @@ qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev)
195 196
196 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 197 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
197 sds_ring = &recv_ctx->sds_rings[ring]; 198 sds_ring = &recv_ctx->sds_rings[ring];
198 netif_napi_add(netdev, &sds_ring->napi, 199
199 qlcnic_poll, QLCNIC_NETDEV_WEIGHT); 200 if (ring == adapter->max_sds_rings - 1)
201 netif_napi_add(netdev, &sds_ring->napi, qlcnic_poll,
202 QLCNIC_NETDEV_WEIGHT/adapter->max_sds_rings);
203 else
204 netif_napi_add(netdev, &sds_ring->napi,
205 qlcnic_rx_poll, QLCNIC_NETDEV_WEIGHT*2);
200 } 206 }
201 207
202 return 0; 208 return 0;
@@ -743,8 +749,12 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
743 749
744 if (load_fw_file) 750 if (load_fw_file)
745 qlcnic_request_firmware(adapter); 751 qlcnic_request_firmware(adapter);
746 else 752 else {
753 if (qlcnic_check_flash_fw_ver(adapter))
754 goto err_out;
755
747 adapter->fw_type = QLCNIC_FLASH_ROMIMAGE; 756 adapter->fw_type = QLCNIC_FLASH_ROMIMAGE;
757 }
748 758
749 err = qlcnic_need_fw_reset(adapter); 759 err = qlcnic_need_fw_reset(adapter);
750 if (err < 0) 760 if (err < 0)
@@ -2060,6 +2070,25 @@ static int qlcnic_poll(struct napi_struct *napi, int budget)
2060 return work_done; 2070 return work_done;
2061} 2071}
2062 2072
2073static int qlcnic_rx_poll(struct napi_struct *napi, int budget)
2074{
2075 struct qlcnic_host_sds_ring *sds_ring =
2076 container_of(napi, struct qlcnic_host_sds_ring, napi);
2077
2078 struct qlcnic_adapter *adapter = sds_ring->adapter;
2079 int work_done;
2080
2081 work_done = qlcnic_process_rcv_ring(sds_ring, budget);
2082
2083 if (work_done < budget) {
2084 napi_complete(&sds_ring->napi);
2085 if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
2086 qlcnic_enable_int(sds_ring);
2087 }
2088
2089 return work_done;
2090}
2091
2063#ifdef CONFIG_NET_POLL_CONTROLLER 2092#ifdef CONFIG_NET_POLL_CONTROLLER
2064static void qlcnic_poll_controller(struct net_device *netdev) 2093static void qlcnic_poll_controller(struct net_device *netdev)
2065{ 2094{