diff options
author | Sony Chacko <sony.chacko@qlogic.com> | 2012-12-03 22:33:56 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-04 13:00:12 -0500 |
commit | bff57d8e1de3510bb8845f639631b6fced211801 (patch) | |
tree | 23eee74bbc38e185faccdede63f0ec2b68a2ec19 /drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |
parent | 229997989bdb7742cf5d21cdc6754017dab1e2db (diff) |
qlcnic: update NIC partition interface routines
Refactor 82xx driver to support new adapter
Update routines to support variable number of NIC partitions
Signed-off-by: Rajesh Borundia <rajesh.borundia@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_main.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 97 |
1 files changed, 56 insertions, 41 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 85adf0def3bd..88084a3bec34 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -91,6 +91,9 @@ static void qlcnic_set_netdev_features(struct qlcnic_adapter *, | |||
91 | static int qlcnic_vlan_rx_add(struct net_device *, u16); | 91 | static int qlcnic_vlan_rx_add(struct net_device *, u16); |
92 | static int qlcnic_vlan_rx_del(struct net_device *, u16); | 92 | static int qlcnic_vlan_rx_del(struct net_device *, u16); |
93 | 93 | ||
94 | #define QLCNIC_IS_TSO_CAPABLE(adapter) \ | ||
95 | ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) | ||
96 | |||
94 | /* PCI Device ID Table */ | 97 | /* PCI Device ID Table */ |
95 | #define ENTRY(device) \ | 98 | #define ENTRY(device) \ |
96 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ | 99 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ |
@@ -369,19 +372,25 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | |||
369 | iounmap(adapter->ahw->pci_base0); | 372 | iounmap(adapter->ahw->pci_base0); |
370 | } | 373 | } |
371 | 374 | ||
372 | static int | 375 | static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) |
373 | qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | ||
374 | { | 376 | { |
375 | struct qlcnic_pci_info *pci_info; | 377 | struct qlcnic_pci_info *pci_info; |
376 | int i, ret = 0; | 378 | int i, ret = 0, j = 0; |
379 | u16 act_pci_func; | ||
377 | u8 pfn; | 380 | u8 pfn; |
378 | 381 | ||
379 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); | 382 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); |
380 | if (!pci_info) | 383 | if (!pci_info) |
381 | return -ENOMEM; | 384 | return -ENOMEM; |
382 | 385 | ||
386 | ret = qlcnic_get_pci_info(adapter, pci_info); | ||
387 | if (ret) | ||
388 | goto err_pci_info; | ||
389 | |||
390 | act_pci_func = adapter->ahw->act_pci_func; | ||
391 | |||
383 | adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * | 392 | adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * |
384 | QLCNIC_MAX_PCI_FUNC, GFP_KERNEL); | 393 | act_pci_func, GFP_KERNEL); |
385 | if (!adapter->npars) { | 394 | if (!adapter->npars) { |
386 | ret = -ENOMEM; | 395 | ret = -ENOMEM; |
387 | goto err_pci_info; | 396 | goto err_pci_info; |
@@ -394,21 +403,25 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | |||
394 | goto err_npars; | 403 | goto err_npars; |
395 | } | 404 | } |
396 | 405 | ||
397 | ret = qlcnic_get_pci_info(adapter, pci_info); | ||
398 | if (ret) | ||
399 | goto err_eswitch; | ||
400 | |||
401 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 406 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { |
402 | pfn = pci_info[i].id; | 407 | pfn = pci_info[i].id; |
408 | |||
403 | if (pfn >= QLCNIC_MAX_PCI_FUNC) { | 409 | if (pfn >= QLCNIC_MAX_PCI_FUNC) { |
404 | ret = QL_STATUS_INVALID_PARAM; | 410 | ret = QL_STATUS_INVALID_PARAM; |
405 | goto err_eswitch; | 411 | goto err_eswitch; |
406 | } | 412 | } |
407 | adapter->npars[pfn].active = (u8)pci_info[i].active; | 413 | |
408 | adapter->npars[pfn].type = (u8)pci_info[i].type; | 414 | if (!pci_info[i].active || |
409 | adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port; | 415 | (pci_info[i].type != QLCNIC_TYPE_NIC)) |
410 | adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; | 416 | continue; |
411 | adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; | 417 | |
418 | adapter->npars[j].pci_func = pfn; | ||
419 | adapter->npars[j].active = (u8)pci_info[i].active; | ||
420 | adapter->npars[j].type = (u8)pci_info[i].type; | ||
421 | adapter->npars[j].phy_port = (u8)pci_info[i].default_port; | ||
422 | adapter->npars[j].min_bw = pci_info[i].tx_min_bw; | ||
423 | adapter->npars[j].max_bw = pci_info[i].tx_max_bw; | ||
424 | j++; | ||
412 | } | 425 | } |
413 | 426 | ||
414 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) | 427 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) |
@@ -436,7 +449,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) | |||
436 | u32 ref_count; | 449 | u32 ref_count; |
437 | int i, ret = 1; | 450 | int i, ret = 1; |
438 | u32 data = QLCNIC_MGMT_FUNC; | 451 | u32 data = QLCNIC_MGMT_FUNC; |
439 | void __iomem *priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE; | 452 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
440 | 453 | ||
441 | /* If other drivers are not in use set their privilege level */ | 454 | /* If other drivers are not in use set their privilege level */ |
442 | ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); | 455 | ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); |
@@ -445,21 +458,20 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) | |||
445 | goto err_lock; | 458 | goto err_lock; |
446 | 459 | ||
447 | if (qlcnic_config_npars) { | 460 | if (qlcnic_config_npars) { |
448 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 461 | for (i = 0; i < ahw->act_pci_func; i++) { |
449 | id = i; | 462 | id = adapter->npars[i].pci_func; |
450 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC || | 463 | if (id == ahw->pci_func) |
451 | id == adapter->ahw->pci_func) | ||
452 | continue; | 464 | continue; |
453 | data |= (qlcnic_config_npars & | 465 | data |= (qlcnic_config_npars & |
454 | QLC_DEV_SET_DRV(0xf, id)); | 466 | QLC_DEV_SET_DRV(0xf, id)); |
455 | } | 467 | } |
456 | } else { | 468 | } else { |
457 | data = readl(priv_op); | 469 | data = QLCRD32(adapter, QLCNIC_DRV_OP_MODE); |
458 | data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) | | 470 | data = (data & ~QLC_DEV_SET_DRV(0xf, ahw->pci_func)) | |
459 | (QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, | 471 | (QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, |
460 | adapter->ahw->pci_func)); | 472 | ahw->pci_func)); |
461 | } | 473 | } |
462 | writel(data, priv_op); | 474 | QLCWR32(adapter, QLCNIC_DRV_OP_MODE, data); |
463 | qlcnic_api_unlock(adapter); | 475 | qlcnic_api_unlock(adapter); |
464 | err_lock: | 476 | err_lock: |
465 | return ret; | 477 | return ret; |
@@ -632,6 +644,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter) | |||
632 | int err; | 644 | int err; |
633 | struct qlcnic_info nic_info; | 645 | struct qlcnic_info nic_info; |
634 | 646 | ||
647 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | ||
635 | err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func); | 648 | err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func); |
636 | if (err) | 649 | if (err) |
637 | return err; | 650 | return err; |
@@ -798,8 +811,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) | |||
798 | return err; | 811 | return err; |
799 | } | 812 | } |
800 | 813 | ||
801 | static int | 814 | static int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) |
802 | qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) | ||
803 | { | 815 | { |
804 | struct qlcnic_esw_func_cfg esw_cfg; | 816 | struct qlcnic_esw_func_cfg esw_cfg; |
805 | struct qlcnic_npar_info *npar; | 817 | struct qlcnic_npar_info *npar; |
@@ -808,16 +820,16 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) | |||
808 | if (adapter->need_fw_reset) | 820 | if (adapter->need_fw_reset) |
809 | return 0; | 821 | return 0; |
810 | 822 | ||
811 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 823 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { |
812 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | ||
813 | continue; | ||
814 | memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); | 824 | memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); |
815 | esw_cfg.pci_func = i; | 825 | esw_cfg.pci_func = adapter->npars[i].pci_func; |
816 | esw_cfg.offload_flags = BIT_0; | ||
817 | esw_cfg.mac_override = BIT_0; | 826 | esw_cfg.mac_override = BIT_0; |
818 | esw_cfg.promisc_mode = BIT_0; | 827 | esw_cfg.promisc_mode = BIT_0; |
819 | if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) | 828 | if (qlcnic_82xx_check(adapter)) { |
820 | esw_cfg.offload_flags |= (BIT_1 | BIT_2); | 829 | esw_cfg.offload_flags = BIT_0; |
830 | if (QLCNIC_IS_TSO_CAPABLE(adapter)) | ||
831 | esw_cfg.offload_flags |= (BIT_1 | BIT_2); | ||
832 | } | ||
821 | if (qlcnic_config_switch_port(adapter, &esw_cfg)) | 833 | if (qlcnic_config_switch_port(adapter, &esw_cfg)) |
822 | return -EIO; | 834 | return -EIO; |
823 | npar = &adapter->npars[i]; | 835 | npar = &adapter->npars[i]; |
@@ -855,22 +867,24 @@ qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, | |||
855 | return 0; | 867 | return 0; |
856 | } | 868 | } |
857 | 869 | ||
858 | static int | 870 | static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) |
859 | qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) | ||
860 | { | 871 | { |
861 | int i, err; | 872 | int i, err; |
862 | struct qlcnic_npar_info *npar; | 873 | struct qlcnic_npar_info *npar; |
863 | struct qlcnic_info nic_info; | 874 | struct qlcnic_info nic_info; |
875 | u8 pci_func; | ||
864 | 876 | ||
865 | if (!adapter->need_fw_reset) | 877 | if (qlcnic_82xx_check(adapter)) |
866 | return 0; | 878 | if (!adapter->need_fw_reset) |
879 | return 0; | ||
867 | 880 | ||
868 | /* Set the NPAR config data after FW reset */ | 881 | /* Set the NPAR config data after FW reset */ |
869 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 882 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { |
870 | npar = &adapter->npars[i]; | 883 | npar = &adapter->npars[i]; |
871 | if (npar->type != QLCNIC_TYPE_NIC) | 884 | pci_func = npar->pci_func; |
872 | continue; | 885 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); |
873 | err = qlcnic_get_nic_info(adapter, &nic_info, i); | 886 | err = qlcnic_get_nic_info(adapter, |
887 | &nic_info, pci_func); | ||
874 | if (err) | 888 | if (err) |
875 | return err; | 889 | return err; |
876 | nic_info.min_tx_bw = npar->min_bw; | 890 | nic_info.min_tx_bw = npar->min_bw; |
@@ -881,11 +895,12 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) | |||
881 | 895 | ||
882 | if (npar->enable_pm) { | 896 | if (npar->enable_pm) { |
883 | err = qlcnic_config_port_mirroring(adapter, | 897 | err = qlcnic_config_port_mirroring(adapter, |
884 | npar->dest_npar, 1, i); | 898 | npar->dest_npar, 1, |
899 | pci_func); | ||
885 | if (err) | 900 | if (err) |
886 | return err; | 901 | return err; |
887 | } | 902 | } |
888 | err = qlcnic_reset_eswitch_config(adapter, npar, i); | 903 | err = qlcnic_reset_eswitch_config(adapter, npar, pci_func); |
889 | if (err) | 904 | if (err) |
890 | return err; | 905 | return err; |
891 | } | 906 | } |