diff options
author | Rajesh Borundia <rajesh.borundia@qlogic.com> | 2013-03-29 01:46:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-29 15:48:07 -0400 |
commit | f8468331645ea6d9bed057673378ccd580465b8c (patch) | |
tree | 2defefc6ac22b74faea275046a70e9e3d746ed5b /drivers/net/ethernet/qlogic/qlcnic | |
parent | 02feda1758755f2b5dbed060bdffda5e5b0244ba (diff) |
qlcnic: SR-IOV VF probe
o Add PCI device entry for VF.
o Add HW operations for VF.
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 35 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 134 |
8 files changed, 214 insertions, 22 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 2ecf845ca1b7..2332d2e4a5e9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -1523,6 +1523,9 @@ int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); | |||
1523 | void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, | 1523 | void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, |
1524 | __le16); | 1524 | __le16); |
1525 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); | 1525 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); |
1526 | int qlcnic_read_mac_addr(struct qlcnic_adapter *); | ||
1527 | int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); | ||
1528 | |||
1526 | /* | 1529 | /* |
1527 | * QLOGIC Board information | 1530 | * QLOGIC Board information |
1528 | */ | 1531 | */ |
@@ -1647,7 +1650,10 @@ static inline int qlcnic_alloc_mbx_args(struct qlcnic_cmd_args *mbx, | |||
1647 | static inline int qlcnic_issue_cmd(struct qlcnic_adapter *adapter, | 1650 | static inline int qlcnic_issue_cmd(struct qlcnic_adapter *adapter, |
1648 | struct qlcnic_cmd_args *cmd) | 1651 | struct qlcnic_cmd_args *cmd) |
1649 | { | 1652 | { |
1650 | return adapter->ahw->hw_ops->mbx_cmd(adapter, cmd); | 1653 | if (adapter->ahw->hw_ops->mbx_cmd) |
1654 | return adapter->ahw->hw_ops->mbx_cmd(adapter, cmd); | ||
1655 | |||
1656 | return -EIO; | ||
1651 | } | 1657 | } |
1652 | 1658 | ||
1653 | static inline void qlcnic_get_func_no(struct qlcnic_adapter *adapter) | 1659 | static inline void qlcnic_get_func_no(struct qlcnic_adapter *adapter) |
@@ -1667,12 +1673,14 @@ static inline void qlcnic_api_unlock(struct qlcnic_adapter *adapter) | |||
1667 | 1673 | ||
1668 | static inline void qlcnic_add_sysfs(struct qlcnic_adapter *adapter) | 1674 | static inline void qlcnic_add_sysfs(struct qlcnic_adapter *adapter) |
1669 | { | 1675 | { |
1670 | adapter->ahw->hw_ops->add_sysfs(adapter); | 1676 | if (adapter->ahw->hw_ops->add_sysfs) |
1677 | adapter->ahw->hw_ops->add_sysfs(adapter); | ||
1671 | } | 1678 | } |
1672 | 1679 | ||
1673 | static inline void qlcnic_remove_sysfs(struct qlcnic_adapter *adapter) | 1680 | static inline void qlcnic_remove_sysfs(struct qlcnic_adapter *adapter) |
1674 | { | 1681 | { |
1675 | adapter->ahw->hw_ops->remove_sysfs(adapter); | 1682 | if (adapter->ahw->hw_ops->remove_sysfs) |
1683 | adapter->ahw->hw_ops->remove_sysfs(adapter); | ||
1676 | } | 1684 | } |
1677 | 1685 | ||
1678 | static inline void | 1686 | static inline void |
@@ -1790,12 +1798,14 @@ static inline int qlcnic_get_board_info(struct qlcnic_adapter *adapter) | |||
1790 | static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter, | 1798 | static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter, |
1791 | u32 key) | 1799 | u32 key) |
1792 | { | 1800 | { |
1793 | adapter->nic_ops->request_reset(adapter, key); | 1801 | if (adapter->nic_ops->request_reset) |
1802 | adapter->nic_ops->request_reset(adapter, key); | ||
1794 | } | 1803 | } |
1795 | 1804 | ||
1796 | static inline void qlcnic_cancel_idc_work(struct qlcnic_adapter *adapter) | 1805 | static inline void qlcnic_cancel_idc_work(struct qlcnic_adapter *adapter) |
1797 | { | 1806 | { |
1798 | adapter->nic_ops->cancel_idc_work(adapter); | 1807 | if (adapter->nic_ops->cancel_idc_work) |
1808 | adapter->nic_ops->cancel_idc_work(adapter); | ||
1799 | } | 1809 | } |
1800 | 1810 | ||
1801 | static inline irqreturn_t | 1811 | static inline irqreturn_t |
@@ -1842,7 +1852,9 @@ extern const struct ethtool_ops qlcnic_ethtool_failed_ops; | |||
1842 | } while (0) | 1852 | } while (0) |
1843 | 1853 | ||
1844 | #define PCI_DEVICE_ID_QLOGIC_QLE834X 0x8030 | 1854 | #define PCI_DEVICE_ID_QLOGIC_QLE834X 0x8030 |
1855 | #define PCI_DEVICE_ID_QLOGIC_VF_QLE834X 0x8430 | ||
1845 | #define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020 | 1856 | #define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020 |
1857 | |||
1846 | static inline bool qlcnic_82xx_check(struct qlcnic_adapter *adapter) | 1858 | static inline bool qlcnic_82xx_check(struct qlcnic_adapter *adapter) |
1847 | { | 1859 | { |
1848 | unsigned short device = adapter->pdev->device; | 1860 | unsigned short device = adapter->pdev->device; |
@@ -1852,7 +1864,12 @@ static inline bool qlcnic_82xx_check(struct qlcnic_adapter *adapter) | |||
1852 | static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter) | 1864 | static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter) |
1853 | { | 1865 | { |
1854 | unsigned short device = adapter->pdev->device; | 1866 | unsigned short device = adapter->pdev->device; |
1855 | return (device == PCI_DEVICE_ID_QLOGIC_QLE834X) ? true : false; | 1867 | bool status; |
1868 | |||
1869 | status = ((device == PCI_DEVICE_ID_QLOGIC_QLE834X) || | ||
1870 | (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X)) ? true : false; | ||
1871 | |||
1872 | return status; | ||
1856 | } | 1873 | } |
1857 | 1874 | ||
1858 | static inline bool qlcnic_sriov_pf_check(struct qlcnic_adapter *adapter) | 1875 | static inline bool qlcnic_sriov_pf_check(struct qlcnic_adapter *adapter) |
@@ -1860,4 +1877,10 @@ static inline bool qlcnic_sriov_pf_check(struct qlcnic_adapter *adapter) | |||
1860 | return (adapter->ahw->op_mode == QLCNIC_SRIOV_PF_FUNC) ? true : false; | 1877 | return (adapter->ahw->op_mode == QLCNIC_SRIOV_PF_FUNC) ? true : false; |
1861 | } | 1878 | } |
1862 | 1879 | ||
1880 | static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter) | ||
1881 | { | ||
1882 | unsigned short device = adapter->pdev->device; | ||
1883 | |||
1884 | return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false; | ||
1885 | } | ||
1863 | #endif /* __QLCNIC_H_ */ | 1886 | #endif /* __QLCNIC_H_ */ |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 0e1283dc16f5..433456b14306 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "qlcnic.h" | 8 | #include "qlcnic.h" |
9 | #include "qlcnic_sriov.h" | ||
9 | #include <linux/if_vlan.h> | 10 | #include <linux/if_vlan.h> |
10 | #include <linux/ipv6.h> | 11 | #include <linux/ipv6.h> |
11 | #include <linux/ethtool.h> | 12 | #include <linux/ethtool.h> |
@@ -212,7 +213,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | |||
212 | {QLCNIC_CMD_CONFIG_VPORT, 4, 4}, | 213 | {QLCNIC_CMD_CONFIG_VPORT, 4, 4}, |
213 | }; | 214 | }; |
214 | 215 | ||
215 | static const u32 qlcnic_83xx_ext_reg_tbl[] = { | 216 | const u32 qlcnic_83xx_ext_reg_tbl[] = { |
216 | 0x38CC, /* Global Reset */ | 217 | 0x38CC, /* Global Reset */ |
217 | 0x38F0, /* Wildcard */ | 218 | 0x38F0, /* Wildcard */ |
218 | 0x38FC, /* Informant */ | 219 | 0x38FC, /* Informant */ |
@@ -258,7 +259,7 @@ static const u32 qlcnic_83xx_ext_reg_tbl[] = { | |||
258 | 0x34A4, /* QLC_83XX_ASIC_TEMP */ | 259 | 0x34A4, /* QLC_83XX_ASIC_TEMP */ |
259 | }; | 260 | }; |
260 | 261 | ||
261 | static const u32 qlcnic_83xx_reg_tbl[] = { | 262 | const u32 qlcnic_83xx_reg_tbl[] = { |
262 | 0x34A8, /* PEG_HALT_STAT1 */ | 263 | 0x34A8, /* PEG_HALT_STAT1 */ |
263 | 0x34AC, /* PEG_HALT_STAT2 */ | 264 | 0x34AC, /* PEG_HALT_STAT2 */ |
264 | 0x34B0, /* FW_HEARTBEAT */ | 265 | 0x34B0, /* FW_HEARTBEAT */ |
@@ -415,8 +416,11 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) | |||
415 | return err; | 416 | return err; |
416 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | 417 | if (adapter->flags & QLCNIC_MSIX_ENABLED) |
417 | num_msix = adapter->ahw->num_msix; | 418 | num_msix = adapter->ahw->num_msix; |
418 | else | 419 | else { |
420 | if (qlcnic_sriov_vf_check(adapter)) | ||
421 | return -EINVAL; | ||
419 | num_msix = 1; | 422 | num_msix = 1; |
423 | } | ||
420 | /* setup interrupt mapping table for fw */ | 424 | /* setup interrupt mapping table for fw */ |
421 | ahw->intr_tbl = vzalloc(num_msix * | 425 | ahw->intr_tbl = vzalloc(num_msix * |
422 | sizeof(struct qlcnic_intrpt_config)); | 426 | sizeof(struct qlcnic_intrpt_config)); |
@@ -649,7 +653,7 @@ int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter) | |||
649 | void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter) | 653 | void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter) |
650 | { | 654 | { |
651 | u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT); | 655 | u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT); |
652 | adapter->ahw->pci_func = val & 0xf; | 656 | adapter->ahw->pci_func = (val >> 24) & 0xff; |
653 | } | 657 | } |
654 | 658 | ||
655 | int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter) | 659 | int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter) |
@@ -761,6 +765,11 @@ void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter, | |||
761 | ahw->fw_hal_version = 2; | 765 | ahw->fw_hal_version = 2; |
762 | qlcnic_get_func_no(adapter); | 766 | qlcnic_get_func_no(adapter); |
763 | 767 | ||
768 | if (qlcnic_sriov_vf_check(adapter)) { | ||
769 | qlcnic_sriov_vf_set_ops(adapter); | ||
770 | return; | ||
771 | } | ||
772 | |||
764 | /* Determine function privilege level */ | 773 | /* Determine function privilege level */ |
765 | op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); | 774 | op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); |
766 | if (op_mode == QLC_83XX_DEFAULT_OPMODE) | 775 | if (op_mode == QLC_83XX_DEFAULT_OPMODE) |
@@ -1487,6 +1496,9 @@ void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter, | |||
1487 | struct qlcnic_cmd_args cmd; | 1496 | struct qlcnic_cmd_args cmd; |
1488 | int status; | 1497 | int status; |
1489 | 1498 | ||
1499 | if (qlcnic_sriov_vf_check(adapter)) | ||
1500 | return; | ||
1501 | |||
1490 | if (enable) { | 1502 | if (enable) { |
1491 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INIT_NIC_FUNC); | 1503 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INIT_NIC_FUNC); |
1492 | cmd.req.arg[1] = BIT_0 | BIT_31; | 1504 | cmd.req.arg[1] = BIT_0 | BIT_31; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 2a05c232d23d..da0fcc78407b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -419,7 +419,7 @@ int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *); | |||
419 | int qlcnic_83xx_flash_read32(struct qlcnic_adapter *, u32, u8 *, int); | 419 | int qlcnic_83xx_flash_read32(struct qlcnic_adapter *, u32, u8 *, int); |
420 | int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *, | 420 | int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *, |
421 | u32, u8 *, int); | 421 | u32, u8 *, int); |
422 | int qlcnic_83xx_init(struct qlcnic_adapter *); | 422 | int qlcnic_83xx_init(struct qlcnic_adapter *, int); |
423 | int qlcnic_83xx_idc_ready_state_entry(struct qlcnic_adapter *); | 423 | int qlcnic_83xx_idc_ready_state_entry(struct qlcnic_adapter *); |
424 | int qlcnic_83xx_check_hw_status(struct qlcnic_adapter *p_dev); | 424 | int qlcnic_83xx_check_hw_status(struct qlcnic_adapter *p_dev); |
425 | void qlcnic_83xx_idc_poll_dev_state(struct work_struct *); | 425 | void qlcnic_83xx_idc_poll_dev_state(struct work_struct *); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 51dd81c85217..c302d118a0d0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * See LICENSE.qlcnic for copyright and licensing details. | 5 | * See LICENSE.qlcnic for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "qlcnic_sriov.h" | ||
8 | #include "qlcnic.h" | 9 | #include "qlcnic.h" |
9 | #include "qlcnic_hw.h" | 10 | #include "qlcnic_hw.h" |
10 | 11 | ||
@@ -2045,10 +2046,13 @@ static void qlcnic_83xx_clear_function_resources(struct qlcnic_adapter *adapter) | |||
2045 | } | 2046 | } |
2046 | } | 2047 | } |
2047 | 2048 | ||
2048 | int qlcnic_83xx_init(struct qlcnic_adapter *adapter) | 2049 | int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) |
2049 | { | 2050 | { |
2050 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 2051 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
2051 | 2052 | ||
2053 | if (qlcnic_sriov_vf_check(adapter)) | ||
2054 | return qlcnic_sriov_vf_init(adapter, pci_using_dac); | ||
2055 | |||
2052 | if (qlcnic_83xx_check_hw_status(adapter)) | 2056 | if (qlcnic_83xx_check_hw_status(adapter)) |
2053 | return -EIO; | 2057 | return -EIO; |
2054 | 2058 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h index 39dffde62412..1cebd8900cf9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | |||
@@ -715,7 +715,8 @@ enum { | |||
715 | QLCNIC_PRIV_FUNC = 1, | 715 | QLCNIC_PRIV_FUNC = 1, |
716 | QLCNIC_NON_PRIV_FUNC = 2, | 716 | QLCNIC_NON_PRIV_FUNC = 2, |
717 | QLCNIC_SRIOV_PF_FUNC = 3, | 717 | QLCNIC_SRIOV_PF_FUNC = 3, |
718 | QLCNIC_UNKNOWN_FUNC_MODE = 4 | 718 | QLCNIC_SRIOV_VF_FUNC = 4, |
719 | QLCNIC_UNKNOWN_FUNC_MODE = 5 | ||
719 | }; | 720 | }; |
720 | 721 | ||
721 | enum { | 722 | enum { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 80a4faa1331c..2f3001c6c6c6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -110,6 +110,7 @@ static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) | |||
110 | static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { | 110 | static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { |
111 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), | 111 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), |
112 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X), | 112 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X), |
113 | ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE834X), | ||
113 | {0,} | 114 | {0,} |
114 | }; | 115 | }; |
115 | 116 | ||
@@ -199,8 +200,7 @@ void qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) | |||
199 | recv_ctx->sds_rings = NULL; | 200 | recv_ctx->sds_rings = NULL; |
200 | } | 201 | } |
201 | 202 | ||
202 | static int | 203 | int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) |
203 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) | ||
204 | { | 204 | { |
205 | u8 mac_addr[ETH_ALEN]; | 205 | u8 mac_addr[ETH_ALEN]; |
206 | struct net_device *netdev = adapter->netdev; | 206 | struct net_device *netdev = adapter->netdev; |
@@ -713,6 +713,7 @@ static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) | |||
713 | *bar = QLCNIC_82XX_BAR0_LENGTH; | 713 | *bar = QLCNIC_82XX_BAR0_LENGTH; |
714 | break; | 714 | break; |
715 | case PCI_DEVICE_ID_QLOGIC_QLE834X: | 715 | case PCI_DEVICE_ID_QLOGIC_QLE834X: |
716 | case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: | ||
716 | *bar = QLCNIC_83XX_BAR0_LENGTH; | 717 | *bar = QLCNIC_83XX_BAR0_LENGTH; |
717 | break; | 718 | break; |
718 | default: | 719 | default: |
@@ -743,7 +744,7 @@ static int qlcnic_setup_pci_map(struct pci_dev *pdev, | |||
743 | return -EIO; | 744 | return -EIO; |
744 | } | 745 | } |
745 | 746 | ||
746 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); | 747 | dev_info(&pdev->dev, "%dKB memory map\n", (int)(mem_len >> 10)); |
747 | 748 | ||
748 | ahw->pci_base0 = mem_ptr0; | 749 | ahw->pci_base0 = mem_ptr0; |
749 | ahw->pci_len0 = pci_len0; | 750 | ahw->pci_len0 = pci_len0; |
@@ -1678,7 +1679,7 @@ qlcnic_reset_context(struct qlcnic_adapter *adapter) | |||
1678 | return err; | 1679 | return err; |
1679 | } | 1680 | } |
1680 | 1681 | ||
1681 | static int | 1682 | int |
1682 | qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, | 1683 | qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, |
1683 | int pci_using_dac) | 1684 | int pci_using_dac) |
1684 | { | 1685 | { |
@@ -1813,6 +1814,9 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1813 | u32 capab2; | 1814 | u32 capab2; |
1814 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ | 1815 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ |
1815 | 1816 | ||
1817 | if (pdev->is_virtfn) | ||
1818 | return -ENODEV; | ||
1819 | |||
1816 | err = pci_enable_device(pdev); | 1820 | err = pci_enable_device(pdev); |
1817 | if (err) | 1821 | if (err) |
1818 | return err; | 1822 | return err; |
@@ -1837,12 +1841,18 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1837 | if (!ahw) | 1841 | if (!ahw) |
1838 | goto err_out_free_res; | 1842 | goto err_out_free_res; |
1839 | 1843 | ||
1840 | if (ent->device == PCI_DEVICE_ID_QLOGIC_QLE824X) { | 1844 | switch (ent->device) { |
1845 | case PCI_DEVICE_ID_QLOGIC_QLE824X: | ||
1841 | ahw->hw_ops = &qlcnic_hw_ops; | 1846 | ahw->hw_ops = &qlcnic_hw_ops; |
1842 | ahw->reg_tbl = (u32 *)qlcnic_reg_tbl; | 1847 | ahw->reg_tbl = (u32 *) qlcnic_reg_tbl; |
1843 | } else if (ent->device == PCI_DEVICE_ID_QLOGIC_QLE834X) { | 1848 | break; |
1849 | case PCI_DEVICE_ID_QLOGIC_QLE834X: | ||
1844 | qlcnic_83xx_register_map(ahw); | 1850 | qlcnic_83xx_register_map(ahw); |
1845 | } else { | 1851 | break; |
1852 | case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: | ||
1853 | qlcnic_sriov_vf_register_map(ahw); | ||
1854 | break; | ||
1855 | default: | ||
1846 | goto err_out_free_hw_res; | 1856 | goto err_out_free_hw_res; |
1847 | } | 1857 | } |
1848 | 1858 | ||
@@ -1904,11 +1914,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1904 | } else if (qlcnic_83xx_check(adapter)) { | 1914 | } else if (qlcnic_83xx_check(adapter)) { |
1905 | qlcnic_83xx_check_vf(adapter, ent); | 1915 | qlcnic_83xx_check_vf(adapter, ent); |
1906 | adapter->portnum = adapter->ahw->pci_func; | 1916 | adapter->portnum = adapter->ahw->pci_func; |
1907 | err = qlcnic_83xx_init(adapter); | 1917 | err = qlcnic_83xx_init(adapter, pci_using_dac); |
1908 | if (err) { | 1918 | if (err) { |
1909 | dev_err(&pdev->dev, "%s: failed\n", __func__); | 1919 | dev_err(&pdev->dev, "%s: failed\n", __func__); |
1910 | goto err_out_free_hw; | 1920 | goto err_out_free_hw; |
1911 | } | 1921 | } |
1922 | if (qlcnic_sriov_vf_check(adapter)) | ||
1923 | return 0; | ||
1912 | } else { | 1924 | } else { |
1913 | dev_err(&pdev->dev, | 1925 | dev_err(&pdev->dev, |
1914 | "%s: failed. Please Reboot\n", __func__); | 1926 | "%s: failed. Please Reboot\n", __func__); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h index bb53307edfd9..e849939bbe5e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | |||
@@ -12,6 +12,9 @@ | |||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | 14 | ||
15 | extern const u32 qlcnic_83xx_reg_tbl[]; | ||
16 | extern const u32 qlcnic_83xx_ext_reg_tbl[]; | ||
17 | |||
15 | struct qlcnic_resources { | 18 | struct qlcnic_resources { |
16 | u16 num_tx_mac_filters; | 19 | u16 num_tx_mac_filters; |
17 | u16 num_rx_ucast_mac_filters; | 20 | u16 num_rx_ucast_mac_filters; |
@@ -40,6 +43,9 @@ struct qlcnic_sriov { | |||
40 | int qlcnic_sriov_init(struct qlcnic_adapter *, int); | 43 | int qlcnic_sriov_init(struct qlcnic_adapter *, int); |
41 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *); | 44 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *); |
42 | void __qlcnic_sriov_cleanup(struct qlcnic_adapter *); | 45 | void __qlcnic_sriov_cleanup(struct qlcnic_adapter *); |
46 | void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *); | ||
47 | int qlcnic_sriov_vf_init(struct qlcnic_adapter *, int); | ||
48 | void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *); | ||
43 | 49 | ||
44 | static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter) | 50 | static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter) |
45 | { | 51 | { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index fb08ad02f7df..0c04e886cdc8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | |||
@@ -7,8 +7,48 @@ | |||
7 | 7 | ||
8 | #include "qlcnic_sriov.h" | 8 | #include "qlcnic_sriov.h" |
9 | #include "qlcnic.h" | 9 | #include "qlcnic.h" |
10 | #include "qlcnic_83xx_hw.h" | ||
10 | #include <linux/types.h> | 11 | #include <linux/types.h> |
11 | 12 | ||
13 | static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = { | ||
14 | .read_crb = qlcnic_83xx_read_crb, | ||
15 | .write_crb = qlcnic_83xx_write_crb, | ||
16 | .read_reg = qlcnic_83xx_rd_reg_indirect, | ||
17 | .write_reg = qlcnic_83xx_wrt_reg_indirect, | ||
18 | .get_mac_address = qlcnic_83xx_get_mac_address, | ||
19 | .setup_intr = qlcnic_83xx_setup_intr, | ||
20 | .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args, | ||
21 | .get_func_no = qlcnic_83xx_get_func_no, | ||
22 | .api_lock = qlcnic_83xx_cam_lock, | ||
23 | .api_unlock = qlcnic_83xx_cam_unlock, | ||
24 | .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag, | ||
25 | .create_rx_ctx = qlcnic_83xx_create_rx_ctx, | ||
26 | .create_tx_ctx = qlcnic_83xx_create_tx_ctx, | ||
27 | .setup_link_event = qlcnic_83xx_setup_link_event, | ||
28 | .get_nic_info = qlcnic_83xx_get_nic_info, | ||
29 | .get_pci_info = qlcnic_83xx_get_pci_info, | ||
30 | .set_nic_info = qlcnic_83xx_set_nic_info, | ||
31 | .change_macvlan = qlcnic_83xx_sre_macaddr_change, | ||
32 | .napi_enable = qlcnic_83xx_napi_enable, | ||
33 | .napi_disable = qlcnic_83xx_napi_disable, | ||
34 | .config_intr_coal = qlcnic_83xx_config_intr_coal, | ||
35 | .config_rss = qlcnic_83xx_config_rss, | ||
36 | .config_hw_lro = qlcnic_83xx_config_hw_lro, | ||
37 | .config_promisc_mode = qlcnic_83xx_nic_set_promisc, | ||
38 | .change_l2_filter = qlcnic_83xx_change_l2_filter, | ||
39 | .get_board_info = qlcnic_83xx_get_port_info, | ||
40 | }; | ||
41 | |||
42 | static struct qlcnic_nic_template qlcnic_sriov_vf_ops = { | ||
43 | .config_bridged_mode = qlcnic_config_bridged_mode, | ||
44 | .config_led = qlcnic_config_led, | ||
45 | .cancel_idc_work = qlcnic_83xx_idc_exit, | ||
46 | .napi_add = qlcnic_83xx_napi_add, | ||
47 | .napi_del = qlcnic_83xx_napi_del, | ||
48 | .config_ipaddr = qlcnic_83xx_config_ipaddr, | ||
49 | .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr, | ||
50 | }; | ||
51 | |||
12 | int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) | 52 | int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) |
13 | { | 53 | { |
14 | struct qlcnic_sriov *sriov; | 54 | struct qlcnic_sriov *sriov; |
@@ -33,8 +73,102 @@ void __qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) | |||
33 | kfree(adapter->ahw->sriov); | 73 | kfree(adapter->ahw->sriov); |
34 | } | 74 | } |
35 | 75 | ||
76 | static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter) | ||
77 | { | ||
78 | __qlcnic_sriov_cleanup(adapter); | ||
79 | } | ||
80 | |||
36 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) | 81 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) |
37 | { | 82 | { |
38 | if (qlcnic_sriov_pf_check(adapter)) | 83 | if (qlcnic_sriov_pf_check(adapter)) |
39 | qlcnic_sriov_pf_cleanup(adapter); | 84 | qlcnic_sriov_pf_cleanup(adapter); |
85 | |||
86 | if (qlcnic_sriov_vf_check(adapter)) | ||
87 | qlcnic_sriov_vf_cleanup(adapter); | ||
88 | } | ||
89 | |||
90 | static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, | ||
91 | int pci_using_dac) | ||
92 | { | ||
93 | int err; | ||
94 | |||
95 | if (!qlcnic_use_msi_x && !!qlcnic_use_msi) | ||
96 | dev_warn(&adapter->pdev->dev, | ||
97 | "83xx adapter do not support MSI interrupts\n"); | ||
98 | |||
99 | err = qlcnic_setup_intr(adapter, 1); | ||
100 | if (err) { | ||
101 | dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n"); | ||
102 | goto err_out_disable_msi; | ||
103 | } | ||
104 | |||
105 | err = qlcnic_83xx_setup_mbx_intr(adapter); | ||
106 | if (err) | ||
107 | goto err_out_disable_msi; | ||
108 | |||
109 | err = qlcnic_sriov_init(adapter, 1); | ||
110 | if (err) | ||
111 | goto err_out_disable_mbx_intr; | ||
112 | |||
113 | err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac); | ||
114 | if (err) | ||
115 | goto err_out_cleanup_sriov; | ||
116 | |||
117 | pci_set_drvdata(adapter->pdev, adapter); | ||
118 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", | ||
119 | adapter->netdev->name); | ||
120 | return 0; | ||
121 | |||
122 | err_out_cleanup_sriov: | ||
123 | __qlcnic_sriov_cleanup(adapter); | ||
124 | |||
125 | err_out_disable_mbx_intr: | ||
126 | qlcnic_83xx_free_mbx_intr(adapter); | ||
127 | |||
128 | err_out_disable_msi: | ||
129 | qlcnic_teardown_intr(adapter); | ||
130 | return err; | ||
131 | } | ||
132 | |||
133 | int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac) | ||
134 | { | ||
135 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
136 | |||
137 | spin_lock_init(&ahw->mbx_lock); | ||
138 | set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); | ||
139 | ahw->msix_supported = 1; | ||
140 | |||
141 | if (qlcnic_sriov_setup_vf(adapter, pci_using_dac)) | ||
142 | return -EIO; | ||
143 | |||
144 | if (qlcnic_read_mac_addr(adapter)) | ||
145 | dev_warn(&adapter->pdev->dev, "failed to read mac addr\n"); | ||
146 | |||
147 | set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); | ||
148 | adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; | ||
149 | adapter->ahw->reset_context = 0; | ||
150 | adapter->fw_fail_cnt = 0; | ||
151 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
152 | adapter->need_fw_reset = 0; | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *adapter) | ||
157 | { | ||
158 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
159 | |||
160 | ahw->op_mode = QLCNIC_SRIOV_VF_FUNC; | ||
161 | dev_info(&adapter->pdev->dev, | ||
162 | "HAL Version: %d Non Privileged SRIOV function\n", | ||
163 | ahw->fw_hal_version); | ||
164 | adapter->nic_ops = &qlcnic_sriov_vf_ops; | ||
165 | set_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state); | ||
166 | return; | ||
167 | } | ||
168 | |||
169 | void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *ahw) | ||
170 | { | ||
171 | ahw->hw_ops = &qlcnic_sriov_vf_hw_ops; | ||
172 | ahw->reg_tbl = (u32 *)qlcnic_83xx_reg_tbl; | ||
173 | ahw->ext_reg_tbl = (u32 *)qlcnic_83xx_ext_reg_tbl; | ||
40 | } | 174 | } |