aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_main.c
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 /drivers/net/qlcnic/qlcnic_main.c
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>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c124
1 files changed, 115 insertions, 9 deletions
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};