aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>2010-06-01 07:33:09 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-02 05:24:03 -0400
commit9f26f547a587ce9015ffe495d2af604580b4b784 (patch)
treeddf274a263389e6cebb28f5e881d9bc69ec6f49e
parent2e9d722db6617ed10204bfa9cd60552620592a43 (diff)
qlcnic: NIC Partitioning - Add non privileged mode support
Added support for NIC functions that work in non privileged mode where these functions are privileged to do IO only, the control operations are handled via privileged functions. Bumped up version number to 5.0.3. Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/qlcnic/qlcnic.h13
-rw-r--r--drivers/net/qlcnic/qlcnic_hdr.h14
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c124
3 files changed, 128 insertions, 23 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 31a0b430a9d7..02db363f20cd 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 2 54#define _QLCNIC_LINUX_SUBVERSION 3
55#define QLCNIC_LINUX_VERSIONID "5.0.2" 55#define QLCNIC_LINUX_VERSIONID "5.0.3"
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))
@@ -891,6 +891,7 @@ struct qlcnic_mac_req {
891#define QLCNIC_LRO_ENABLED 0x08 891#define QLCNIC_LRO_ENABLED 0x08
892#define QLCNIC_BRIDGE_ENABLED 0X10 892#define QLCNIC_BRIDGE_ENABLED 0X10
893#define QLCNIC_DIAG_ENABLED 0x20 893#define QLCNIC_DIAG_ENABLED 0x20
894#define QLCNIC_NPAR_ENABLED 0x40
894#define QLCNIC_IS_MSI_FAMILY(adapter) \ 895#define QLCNIC_IS_MSI_FAMILY(adapter) \
895 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) 896 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
896 897
@@ -1159,13 +1160,6 @@ int qlcnic_check_loopback_buff(unsigned char *data);
1159netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); 1160netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
1160void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); 1161void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
1161 1162
1162/* Functions from qlcnic_vf.c */
1163int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
1164int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
1165int qlcnicvf_set_ilb_mode(struct qlcnic_adapter *adapter);
1166void qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *adapter);
1167void qlcnicvf_set_port_mode(struct qlcnic_adapter *adapter);
1168
1169/* Management functions */ 1163/* Management functions */
1170int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*); 1164int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*);
1171int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); 1165int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
@@ -1234,6 +1228,7 @@ struct qlcnic_nic_template {
1234 int (*config_led) (struct qlcnic_adapter *, u32, u32); 1228 int (*config_led) (struct qlcnic_adapter *, u32, u32);
1235 int (*set_ilb_mode) (struct qlcnic_adapter *); 1229 int (*set_ilb_mode) (struct qlcnic_adapter *);
1236 void (*clear_ilb_mode) (struct qlcnic_adapter *); 1230 void (*clear_ilb_mode) (struct qlcnic_adapter *);
1231 int (*start_firmware) (struct qlcnic_adapter *);
1237}; 1232};
1238 1233
1239#define QLCDB(adapter, lvl, _fmt, _args...) do { \ 1234#define QLCDB(adapter, lvl, _fmt, _args...) do { \
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 1bcfb121a895..7b81cab27002 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -701,10 +701,11 @@ enum {
701#define QLCNIC_CRB_DEV_REF_COUNT (QLCNIC_CAM_RAM(0x138)) 701#define QLCNIC_CRB_DEV_REF_COUNT (QLCNIC_CAM_RAM(0x138))
702#define QLCNIC_CRB_DEV_STATE (QLCNIC_CAM_RAM(0x140)) 702#define QLCNIC_CRB_DEV_STATE (QLCNIC_CAM_RAM(0x140))
703 703
704#define QLCNIC_CRB_DRV_STATE (QLCNIC_CAM_RAM(0x144)) 704#define QLCNIC_CRB_DRV_STATE (QLCNIC_CAM_RAM(0x144))
705#define QLCNIC_CRB_DRV_SCRATCH (QLCNIC_CAM_RAM(0x148)) 705#define QLCNIC_CRB_DRV_SCRATCH (QLCNIC_CAM_RAM(0x148))
706#define QLCNIC_CRB_DEV_PARTITION_INFO (QLCNIC_CAM_RAM(0x14c)) 706#define QLCNIC_CRB_DEV_PARTITION_INFO (QLCNIC_CAM_RAM(0x14c))
707#define QLCNIC_CRB_DRV_IDC_VER (QLCNIC_CAM_RAM(0x174)) 707#define QLCNIC_CRB_DRV_IDC_VER (QLCNIC_CAM_RAM(0x174))
708#define QLCNIC_CRB_DEV_NPAR_STATE (QLCNIC_CAM_RAM(0x19c))
708#define QLCNIC_ROM_DEV_INIT_TIMEOUT (0x3e885c) 709#define QLCNIC_ROM_DEV_INIT_TIMEOUT (0x3e885c)
709#define QLCNIC_ROM_DRV_RESET_TIMEOUT (0x3e8860) 710#define QLCNIC_ROM_DRV_RESET_TIMEOUT (0x3e8860)
710 711
@@ -717,6 +718,9 @@ enum {
717#define QLCNIC_DEV_FAILED 0x6 718#define QLCNIC_DEV_FAILED 0x6
718#define QLCNIC_DEV_QUISCENT 0x7 719#define QLCNIC_DEV_QUISCENT 0x7
719 720
721#define QLCNIC_DEV_NPAR_NOT_RDY 0
722#define QLCNIC_DEV_NPAR_RDY 1
723
720#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) 724#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4)))
721#define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) 725#define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4)))
722#define QLC_DEV_CLR_REF_CNT(VAL, FN) ((VAL) &= ~(1 << (FN * 4))) 726#define QLC_DEV_CLR_REF_CNT(VAL, FN) ((VAL) &= ~(1 << (FN * 4)))
@@ -732,8 +736,8 @@ enum {
732#define QLCNIC_TYPE_ISCSI 3 736#define QLCNIC_TYPE_ISCSI 3
733 737
734#define QLCNIC_RCODE_DRIVER_INFO 0x20000000 738#define QLCNIC_RCODE_DRIVER_INFO 0x20000000
735#define QLCNIC_RCODE_DRIVER_CAN_RELOAD 0x40000000 739#define QLCNIC_RCODE_DRIVER_CAN_RELOAD BIT_30
736#define QLCNIC_RCODE_FATAL_ERROR 0x80000000 740#define QLCNIC_RCODE_FATAL_ERROR BIT_31
737#define QLCNIC_FWERROR_PEGNUM(code) ((code) & 0xff) 741#define QLCNIC_FWERROR_PEGNUM(code) ((code) & 0xff)
738#define QLCNIC_FWERROR_CODE(code) ((code >> 8) & 0xfffff) 742#define QLCNIC_FWERROR_CODE(code) ((code >> 8) & 0xfffff)
739 743
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 1e5e66facabd..119bcae5e74b 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -103,7 +103,14 @@ static irqreturn_t qlcnic_msix_intr(int irq, void *data);
103 103
104static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); 104static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev);
105static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); 105static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long);
106 106static int qlcnic_start_firmware(struct qlcnic_adapter *);
107
108static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
109static void qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *);
110static int qlcnicvf_set_ilb_mode(struct qlcnic_adapter *);
111static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
112static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
113static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
107/* PCI Device ID Table */ 114/* PCI Device ID Table */
108#define ENTRY(device) \ 115#define ENTRY(device) \
109 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ 116 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
@@ -375,7 +382,8 @@ static struct qlcnic_nic_template qlcnic_ops = {
375 .config_bridged_mode = qlcnic_config_bridged_mode, 382 .config_bridged_mode = qlcnic_config_bridged_mode,
376 .config_led = qlcnic_config_led, 383 .config_led = qlcnic_config_led,
377 .set_ilb_mode = qlcnic_set_ilb_mode, 384 .set_ilb_mode = qlcnic_set_ilb_mode,
378 .clear_ilb_mode = qlcnic_clear_ilb_mode 385 .clear_ilb_mode = qlcnic_clear_ilb_mode,
386 .start_firmware = qlcnic_start_firmware
379}; 387};
380 388
381static struct qlcnic_nic_template qlcnic_pf_ops = { 389static struct qlcnic_nic_template qlcnic_pf_ops = {
@@ -383,7 +391,17 @@ static struct qlcnic_nic_template qlcnic_pf_ops = {
383 .config_bridged_mode = qlcnic_config_bridged_mode, 391 .config_bridged_mode = qlcnic_config_bridged_mode,
384 .config_led = qlcnic_config_led, 392 .config_led = qlcnic_config_led,
385 .set_ilb_mode = qlcnic_set_ilb_mode, 393 .set_ilb_mode = qlcnic_set_ilb_mode,
386 .clear_ilb_mode = qlcnic_clear_ilb_mode 394 .clear_ilb_mode = qlcnic_clear_ilb_mode,
395 .start_firmware = qlcnic_start_firmware
396};
397
398static struct qlcnic_nic_template qlcnic_vf_ops = {
399 .get_mac_addr = qlcnic_get_mac_address,
400 .config_bridged_mode = qlcnicvf_config_bridged_mode,
401 .config_led = qlcnicvf_config_led,
402 .set_ilb_mode = qlcnicvf_set_ilb_mode,
403 .clear_ilb_mode = qlcnicvf_clear_ilb_mode,
404 .start_firmware = qlcnicvf_start_firmware
387}; 405};
388 406
389static void 407static void
@@ -467,7 +485,6 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
467 iounmap(adapter->ahw.pci_base0); 485 iounmap(adapter->ahw.pci_base0);
468} 486}
469 487
470/* Use api lock to access this function */
471static int 488static int
472qlcnic_set_function_modes(struct qlcnic_adapter *adapter) 489qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
473{ 490{
@@ -567,6 +584,7 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
567 /* Set privilege level for other functions */ 584 /* Set privilege level for other functions */
568 if (qlcnic_config_npars) 585 if (qlcnic_config_npars)
569 qlcnic_set_function_modes(adapter); 586 qlcnic_set_function_modes(adapter);
587 qlcnic_dev_set_npar_ready(adapter);
570 dev_info(&adapter->pdev->dev, 588 dev_info(&adapter->pdev->dev,
571 "HAL Version: %d, Management function\n", 589 "HAL Version: %d, Management function\n",
572 adapter->fw_hal_version); 590 adapter->fw_hal_version);
@@ -578,6 +596,13 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
578 adapter->fw_hal_version); 596 adapter->fw_hal_version);
579 adapter->nic_ops = &qlcnic_pf_ops; 597 adapter->nic_ops = &qlcnic_pf_ops;
580 break; 598 break;
599 case QLCNIC_NON_PRIV_FUNC:
600 adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
601 dev_info(&adapter->pdev->dev,
602 "HAL Version: %d Non Privileged function\n",
603 adapter->fw_hal_version);
604 adapter->nic_ops = &qlcnic_vf_ops;
605 break;
581 default: 606 default:
582 dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n", 607 dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n",
583 priv_level); 608 priv_level);
@@ -772,6 +797,8 @@ wait_init:
772 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 797 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
773 qlcnic_idc_debug_info(adapter, 1); 798 qlcnic_idc_debug_info(adapter, 1);
774 799
800 qlcnic_dev_set_npar_ready(adapter);
801
775 qlcnic_check_options(adapter); 802 qlcnic_check_options(adapter);
776 803
777 if (adapter->fw_hal_version != QLCNIC_FW_BASE && 804 if (adapter->fw_hal_version != QLCNIC_FW_BASE &&
@@ -1244,7 +1271,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1244 if (qlcnic_setup_idc_param(adapter)) 1271 if (qlcnic_setup_idc_param(adapter))
1245 goto err_out_iounmap; 1272 goto err_out_iounmap;
1246 1273
1247 err = qlcnic_start_firmware(adapter); 1274 err = adapter->nic_ops->start_firmware(adapter);
1248 if (err) { 1275 if (err) {
1249 dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); 1276 dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n");
1250 goto err_out_decr_ref; 1277 goto err_out_decr_ref;
@@ -1410,7 +1437,7 @@ qlcnic_resume(struct pci_dev *pdev)
1410 pci_set_master(pdev); 1437 pci_set_master(pdev);
1411 pci_restore_state(pdev); 1438 pci_restore_state(pdev);
1412 1439
1413 err = qlcnic_start_firmware(adapter); 1440 err = adapter->nic_ops->start_firmware(adapter);
1414 if (err) { 1441 if (err) {
1415 dev_err(&pdev->dev, "failed to start firmware\n"); 1442 dev_err(&pdev->dev, "failed to start firmware\n");
1416 return err; 1443 return err;
@@ -2260,7 +2287,7 @@ qlcnic_fwinit_work(struct work_struct *work)
2260{ 2287{
2261 struct qlcnic_adapter *adapter = container_of(work, 2288 struct qlcnic_adapter *adapter = container_of(work,
2262 struct qlcnic_adapter, fw_work.work); 2289 struct qlcnic_adapter, fw_work.work);
2263 u32 dev_state = 0xf; 2290 u32 dev_state = 0xf, npar_state;
2264 2291
2265 if (qlcnic_api_lock(adapter)) 2292 if (qlcnic_api_lock(adapter))
2266 goto err_ret; 2293 goto err_ret;
@@ -2273,6 +2300,19 @@ qlcnic_fwinit_work(struct work_struct *work)
2273 return; 2300 return;
2274 } 2301 }
2275 2302
2303 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
2304 npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
2305 if (npar_state == QLCNIC_DEV_NPAR_RDY) {
2306 qlcnic_api_unlock(adapter);
2307 goto wait_npar;
2308 } else {
2309 qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
2310 FW_POLL_DELAY);
2311 qlcnic_api_unlock(adapter);
2312 return;
2313 }
2314 }
2315
2276 if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { 2316 if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
2277 dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", 2317 dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n",
2278 adapter->reset_ack_timeo); 2318 adapter->reset_ack_timeo);
@@ -2305,7 +2345,7 @@ skip_ack_check:
2305 2345
2306 qlcnic_api_unlock(adapter); 2346 qlcnic_api_unlock(adapter);
2307 2347
2308 if (!qlcnic_start_firmware(adapter)) { 2348 if (!adapter->nic_ops->start_firmware(adapter)) {
2309 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 2349 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
2310 return; 2350 return;
2311 } 2351 }
@@ -2314,6 +2354,7 @@ skip_ack_check:
2314 2354
2315 qlcnic_api_unlock(adapter); 2355 qlcnic_api_unlock(adapter);
2316 2356
2357wait_npar:
2317 dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); 2358 dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2318 QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); 2359 QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
2319 2360
@@ -2328,7 +2369,7 @@ skip_ack_check:
2328 break; 2369 break;
2329 2370
2330 default: 2371 default:
2331 if (!qlcnic_start_firmware(adapter)) { 2372 if (!adapter->nic_ops->start_firmware(adapter)) {
2332 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 2373 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
2333 return; 2374 return;
2334 } 2375 }
@@ -2402,6 +2443,30 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
2402 qlcnic_api_unlock(adapter); 2443 qlcnic_api_unlock(adapter);
2403} 2444}
2404 2445
2446/* Transit to NPAR READY state from NPAR NOT READY state */
2447static void
2448qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
2449{
2450 u32 state;
2451
2452 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC ||
2453 adapter->fw_hal_version == QLCNIC_FW_BASE)
2454 return;
2455
2456 if (qlcnic_api_lock(adapter))
2457 return;
2458
2459 state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
2460
2461 if (state != QLCNIC_DEV_NPAR_RDY) {
2462 QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE,
2463 QLCNIC_DEV_NPAR_RDY);
2464 QLCDB(adapter, DRV, "NPAR READY state set\n");
2465 }
2466
2467 qlcnic_api_unlock(adapter);
2468}
2469
2405static void 2470static void
2406qlcnic_schedule_work(struct qlcnic_adapter *adapter, 2471qlcnic_schedule_work(struct qlcnic_adapter *adapter,
2407 work_func_t func, int delay) 2472 work_func_t func, int delay)
@@ -2889,6 +2954,47 @@ done:
2889 return NOTIFY_DONE; 2954 return NOTIFY_DONE;
2890} 2955}
2891 2956
2957static int
2958qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
2959{
2960 int err;
2961
2962 err = qlcnic_can_start_firmware(adapter);
2963 if (err)
2964 return err;
2965
2966 qlcnic_check_options(adapter);
2967
2968 adapter->need_fw_reset = 0;
2969
2970 return err;
2971}
2972
2973static int
2974qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
2975{
2976 return -EOPNOTSUPP;
2977}
2978
2979static int
2980qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
2981{
2982 return -EOPNOTSUPP;
2983}
2984
2985static int
2986qlcnicvf_set_ilb_mode(struct qlcnic_adapter *adapter)
2987{
2988 return -EOPNOTSUPP;
2989}
2990
2991static void
2992qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *adapter)
2993{
2994 return;
2995}
2996
2997
2892static struct notifier_block qlcnic_netdev_cb = { 2998static struct notifier_block qlcnic_netdev_cb = {
2893 .notifier_call = qlcnic_netdev_event, 2999 .notifier_call = qlcnic_netdev_event,
2894}; 3000};