aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qlcnic
diff options
context:
space:
mode:
authorRajesh Borundia <rajesh.borundia@qlogic.com>2013-03-29 01:46:34 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-29 15:48:07 -0400
commitf8468331645ea6d9bed057673378ccd580465b8c (patch)
tree2defefc6ac22b74faea275046a70e9e3d746ed5b /drivers/net/ethernet/qlogic/qlcnic
parent02feda1758755f2b5dbed060bdffda5e5b0244ba (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.h35
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c20
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h3
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c30
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c134
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 *);
1523void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, 1523void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int,
1524 __le16); 1524 __le16);
1525int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); 1525int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
1526int qlcnic_read_mac_addr(struct qlcnic_adapter *);
1527int 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,
1647static inline int qlcnic_issue_cmd(struct qlcnic_adapter *adapter, 1650static 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
1653static inline void qlcnic_get_func_no(struct qlcnic_adapter *adapter) 1659static 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
1668static inline void qlcnic_add_sysfs(struct qlcnic_adapter *adapter) 1674static 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
1673static inline void qlcnic_remove_sysfs(struct qlcnic_adapter *adapter) 1680static 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
1678static inline void 1686static inline void
@@ -1790,12 +1798,14 @@ static inline int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
1790static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter, 1798static 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
1796static inline void qlcnic_cancel_idc_work(struct qlcnic_adapter *adapter) 1805static 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
1801static inline irqreturn_t 1811static 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
1846static inline bool qlcnic_82xx_check(struct qlcnic_adapter *adapter) 1858static 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)
1852static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter) 1864static 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
1858static inline bool qlcnic_sriov_pf_check(struct qlcnic_adapter *adapter) 1875static 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
1880static 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
215static const u32 qlcnic_83xx_ext_reg_tbl[] = { 216const 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
261static const u32 qlcnic_83xx_reg_tbl[] = { 262const 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)
649void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter) 653void 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
655int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter) 659int 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 *);
419int qlcnic_83xx_flash_read32(struct qlcnic_adapter *, u32, u8 *, int); 419int qlcnic_83xx_flash_read32(struct qlcnic_adapter *, u32, u8 *, int);
420int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *, 420int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *,
421 u32, u8 *, int); 421 u32, u8 *, int);
422int qlcnic_83xx_init(struct qlcnic_adapter *); 422int qlcnic_83xx_init(struct qlcnic_adapter *, int);
423int qlcnic_83xx_idc_ready_state_entry(struct qlcnic_adapter *); 423int qlcnic_83xx_idc_ready_state_entry(struct qlcnic_adapter *);
424int qlcnic_83xx_check_hw_status(struct qlcnic_adapter *p_dev); 424int qlcnic_83xx_check_hw_status(struct qlcnic_adapter *p_dev);
425void qlcnic_83xx_idc_poll_dev_state(struct work_struct *); 425void 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
2048int qlcnic_83xx_init(struct qlcnic_adapter *adapter) 2049int 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
721enum { 722enum {
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)
110static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { 110static 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
202static int 203int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
203qlcnic_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
1681static int 1682int
1682qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, 1683qlcnic_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
15extern const u32 qlcnic_83xx_reg_tbl[];
16extern const u32 qlcnic_83xx_ext_reg_tbl[];
17
15struct qlcnic_resources { 18struct 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 {
40int qlcnic_sriov_init(struct qlcnic_adapter *, int); 43int qlcnic_sriov_init(struct qlcnic_adapter *, int);
41void qlcnic_sriov_cleanup(struct qlcnic_adapter *); 44void qlcnic_sriov_cleanup(struct qlcnic_adapter *);
42void __qlcnic_sriov_cleanup(struct qlcnic_adapter *); 45void __qlcnic_sriov_cleanup(struct qlcnic_adapter *);
46void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *);
47int qlcnic_sriov_vf_init(struct qlcnic_adapter *, int);
48void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *);
43 49
44static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter) 50static 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
13static 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
42static 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
12int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) 52int 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
76static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter)
77{
78 __qlcnic_sriov_cleanup(adapter);
79}
80
36void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) 81void 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
90static 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
122err_out_cleanup_sriov:
123 __qlcnic_sriov_cleanup(adapter);
124
125err_out_disable_mbx_intr:
126 qlcnic_83xx_free_mbx_intr(adapter);
127
128err_out_disable_msi:
129 qlcnic_teardown_intr(adapter);
130 return err;
131}
132
133int 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
156void 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
169void 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}