diff options
author | Sarveshwar Bandi <sarveshwarb@serverengines.com> | 2010-03-30 22:56:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-01 22:53:14 -0400 |
commit | ba343c7736b36d62d276e20383588bcf9403d6c6 (patch) | |
tree | 3b157ff000be3ef3ead1a07d038e5afd23d03e53 | |
parent | f64e96973a1fa885ce6e4f7e3fdbae83de98fcab (diff) |
be2net: Adding PCI SRIOV support
- Patch adds support to enable PCI SRIOV in the driver and changes to handle initialization of PCI virtual functions.
- Function handler to change mac addresses for VF from its corresponding PF.
Signed-off-by: Sarveshwar Bandi <sarveshwarb@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/benet/be.h | 9 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 4 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 2 | ||||
-rw-r--r-- | drivers/net/benet/be_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 222 |
5 files changed, 191 insertions, 49 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 8f0752553681..20842c5fd8fb 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -83,6 +83,8 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
83 | 83 | ||
84 | #define FW_VER_LEN 32 | 84 | #define FW_VER_LEN 32 |
85 | 85 | ||
86 | #define BE_MAX_VF 32 | ||
87 | |||
86 | struct be_dma_mem { | 88 | struct be_dma_mem { |
87 | void *va; | 89 | void *va; |
88 | dma_addr_t dma; | 90 | dma_addr_t dma; |
@@ -280,8 +282,15 @@ struct be_adapter { | |||
280 | u8 port_type; | 282 | u8 port_type; |
281 | u8 transceiver; | 283 | u8 transceiver; |
282 | u8 generation; /* BladeEngine ASIC generation */ | 284 | u8 generation; /* BladeEngine ASIC generation */ |
285 | |||
286 | bool sriov_enabled; | ||
287 | u32 vf_if_handle[BE_MAX_VF]; | ||
288 | u32 vf_pmac_id[BE_MAX_VF]; | ||
289 | u8 base_eq_id; | ||
283 | }; | 290 | }; |
284 | 291 | ||
292 | #define be_physfn(adapter) (!adapter->pdev->is_virtfn) | ||
293 | |||
285 | /* BladeEngine Generation numbers */ | 294 | /* BladeEngine Generation numbers */ |
286 | #define BE_GEN2 2 | 295 | #define BE_GEN2 2 |
287 | #define BE_GEN3 3 | 296 | #define BE_GEN3 3 |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 50e6259b50e4..9f53d9e86e2b 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -843,7 +843,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
843 | * Uses mbox | 843 | * Uses mbox |
844 | */ | 844 | */ |
845 | int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | 845 | int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, |
846 | u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id) | 846 | u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id, |
847 | u32 domain) | ||
847 | { | 848 | { |
848 | struct be_mcc_wrb *wrb; | 849 | struct be_mcc_wrb *wrb; |
849 | struct be_cmd_req_if_create *req; | 850 | struct be_cmd_req_if_create *req; |
@@ -860,6 +861,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | |||
860 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 861 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
861 | OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req)); | 862 | OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req)); |
862 | 863 | ||
864 | req->hdr.domain = domain; | ||
863 | req->capability_flags = cpu_to_le32(cap_flags); | 865 | req->capability_flags = cpu_to_le32(cap_flags); |
864 | req->enable_flags = cpu_to_le32(en_flags); | 866 | req->enable_flags = cpu_to_le32(en_flags); |
865 | req->pmac_invalid = pmac_invalid; | 867 | req->pmac_invalid = pmac_invalid; |
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index cce61f9a3714..763dc199e337 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -878,7 +878,7 @@ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | |||
878 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); | 878 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); |
879 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, | 879 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, |
880 | u32 en_flags, u8 *mac, bool pmac_invalid, | 880 | u32 en_flags, u8 *mac, bool pmac_invalid, |
881 | u32 *if_handle, u32 *pmac_id); | 881 | u32 *if_handle, u32 *pmac_id, u32 domain); |
882 | extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle); | 882 | extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle); |
883 | extern int be_cmd_eq_create(struct be_adapter *adapter, | 883 | extern int be_cmd_eq_create(struct be_adapter *adapter, |
884 | struct be_queue_info *eq, int eq_delay); | 884 | struct be_queue_info *eq, int eq_delay); |
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 2d4a4b827637..063026de4957 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -99,6 +99,9 @@ | |||
99 | /* Number of entries posted */ | 99 | /* Number of entries posted */ |
100 | #define DB_MCCQ_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */ | 100 | #define DB_MCCQ_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */ |
101 | 101 | ||
102 | /********** SRIOV VF PCICFG OFFSET ********/ | ||
103 | #define SRIOV_VF_PCICFG_OFFSET (4096) | ||
104 | |||
102 | /* Flashrom related descriptors */ | 105 | /* Flashrom related descriptors */ |
103 | #define IMAGE_TYPE_FIRMWARE 160 | 106 | #define IMAGE_TYPE_FIRMWARE 160 |
104 | #define IMAGE_TYPE_BOOTCODE 224 | 107 | #define IMAGE_TYPE_BOOTCODE 224 |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 17282df6e202..cb0a4a6d5dea 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -26,8 +26,11 @@ MODULE_AUTHOR("ServerEngines Corporation"); | |||
26 | MODULE_LICENSE("GPL"); | 26 | MODULE_LICENSE("GPL"); |
27 | 27 | ||
28 | static unsigned int rx_frag_size = 2048; | 28 | static unsigned int rx_frag_size = 2048; |
29 | static unsigned int num_vfs; | ||
29 | module_param(rx_frag_size, uint, S_IRUGO); | 30 | module_param(rx_frag_size, uint, S_IRUGO); |
31 | module_param(num_vfs, uint, S_IRUGO); | ||
30 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); | 32 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); |
33 | MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); | ||
31 | 34 | ||
32 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { | 35 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { |
33 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, | 36 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, |
@@ -138,12 +141,19 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) | |||
138 | if (!is_valid_ether_addr(addr->sa_data)) | 141 | if (!is_valid_ether_addr(addr->sa_data)) |
139 | return -EADDRNOTAVAIL; | 142 | return -EADDRNOTAVAIL; |
140 | 143 | ||
144 | /* MAC addr configuration will be done in hardware for VFs | ||
145 | * by their corresponding PFs. Just copy to netdev addr here | ||
146 | */ | ||
147 | if (!be_physfn(adapter)) | ||
148 | goto netdev_addr; | ||
149 | |||
141 | status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id); | 150 | status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id); |
142 | if (status) | 151 | if (status) |
143 | return status; | 152 | return status; |
144 | 153 | ||
145 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, | 154 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, |
146 | adapter->if_handle, &adapter->pmac_id); | 155 | adapter->if_handle, &adapter->pmac_id); |
156 | netdev_addr: | ||
147 | if (!status) | 157 | if (!status) |
148 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 158 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
149 | 159 | ||
@@ -576,6 +586,9 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid) | |||
576 | { | 586 | { |
577 | struct be_adapter *adapter = netdev_priv(netdev); | 587 | struct be_adapter *adapter = netdev_priv(netdev); |
578 | 588 | ||
589 | if (!be_physfn(adapter)) | ||
590 | return; | ||
591 | |||
579 | adapter->vlan_tag[vid] = 1; | 592 | adapter->vlan_tag[vid] = 1; |
580 | adapter->vlans_added++; | 593 | adapter->vlans_added++; |
581 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) | 594 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) |
@@ -586,6 +599,9 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) | |||
586 | { | 599 | { |
587 | struct be_adapter *adapter = netdev_priv(netdev); | 600 | struct be_adapter *adapter = netdev_priv(netdev); |
588 | 601 | ||
602 | if (!be_physfn(adapter)) | ||
603 | return; | ||
604 | |||
589 | adapter->vlan_tag[vid] = 0; | 605 | adapter->vlan_tag[vid] = 0; |
590 | vlan_group_set_device(adapter->vlan_grp, vid, NULL); | 606 | vlan_group_set_device(adapter->vlan_grp, vid, NULL); |
591 | adapter->vlans_added--; | 607 | adapter->vlans_added--; |
@@ -623,6 +639,28 @@ done: | |||
623 | return; | 639 | return; |
624 | } | 640 | } |
625 | 641 | ||
642 | static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | ||
643 | { | ||
644 | struct be_adapter *adapter = netdev_priv(netdev); | ||
645 | int status; | ||
646 | |||
647 | if (!adapter->sriov_enabled) | ||
648 | return -EPERM; | ||
649 | |||
650 | if (!is_valid_ether_addr(mac) || (vf >= num_vfs)) | ||
651 | return -EINVAL; | ||
652 | |||
653 | status = be_cmd_pmac_del(adapter, adapter->vf_if_handle[vf], | ||
654 | adapter->vf_pmac_id[vf]); | ||
655 | |||
656 | status = be_cmd_pmac_add(adapter, mac, adapter->vf_if_handle[vf], | ||
657 | &adapter->vf_pmac_id[vf]); | ||
658 | if (!status) | ||
659 | dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", | ||
660 | mac, vf); | ||
661 | return status; | ||
662 | } | ||
663 | |||
626 | static void be_rx_rate_update(struct be_adapter *adapter) | 664 | static void be_rx_rate_update(struct be_adapter *adapter) |
627 | { | 665 | { |
628 | struct be_drvr_stats *stats = drvr_stats(adapter); | 666 | struct be_drvr_stats *stats = drvr_stats(adapter); |
@@ -1280,6 +1318,8 @@ static int be_tx_queues_create(struct be_adapter *adapter) | |||
1280 | /* Ask BE to create Tx Event queue */ | 1318 | /* Ask BE to create Tx Event queue */ |
1281 | if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) | 1319 | if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) |
1282 | goto tx_eq_free; | 1320 | goto tx_eq_free; |
1321 | adapter->base_eq_id = adapter->tx_eq.q.id; | ||
1322 | |||
1283 | /* Alloc TX eth compl queue */ | 1323 | /* Alloc TX eth compl queue */ |
1284 | cq = &adapter->tx_obj.cq; | 1324 | cq = &adapter->tx_obj.cq; |
1285 | if (be_queue_alloc(adapter, cq, TX_CQ_LEN, | 1325 | if (be_queue_alloc(adapter, cq, TX_CQ_LEN, |
@@ -1407,7 +1447,7 @@ rx_eq_free: | |||
1407 | /* There are 8 evt ids per func. Retruns the evt id's bit number */ | 1447 | /* There are 8 evt ids per func. Retruns the evt id's bit number */ |
1408 | static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) | 1448 | static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) |
1409 | { | 1449 | { |
1410 | return eq_id % 8; | 1450 | return eq_id - adapter->base_eq_id; |
1411 | } | 1451 | } |
1412 | 1452 | ||
1413 | static irqreturn_t be_intx(int irq, void *dev) | 1453 | static irqreturn_t be_intx(int irq, void *dev) |
@@ -1585,6 +1625,28 @@ static void be_msix_enable(struct be_adapter *adapter) | |||
1585 | return; | 1625 | return; |
1586 | } | 1626 | } |
1587 | 1627 | ||
1628 | static void be_sriov_enable(struct be_adapter *adapter) | ||
1629 | { | ||
1630 | #ifdef CONFIG_PCI_IOV | ||
1631 | int status; | ||
1632 | if (be_physfn(adapter) && num_vfs) { | ||
1633 | status = pci_enable_sriov(adapter->pdev, num_vfs); | ||
1634 | adapter->sriov_enabled = status ? false : true; | ||
1635 | } | ||
1636 | #endif | ||
1637 | return; | ||
1638 | } | ||
1639 | |||
1640 | static void be_sriov_disable(struct be_adapter *adapter) | ||
1641 | { | ||
1642 | #ifdef CONFIG_PCI_IOV | ||
1643 | if (adapter->sriov_enabled) { | ||
1644 | pci_disable_sriov(adapter->pdev); | ||
1645 | adapter->sriov_enabled = false; | ||
1646 | } | ||
1647 | #endif | ||
1648 | } | ||
1649 | |||
1588 | static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) | 1650 | static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) |
1589 | { | 1651 | { |
1590 | return adapter->msix_entries[ | 1652 | return adapter->msix_entries[ |
@@ -1642,6 +1704,9 @@ static int be_irq_register(struct be_adapter *adapter) | |||
1642 | status = be_msix_register(adapter); | 1704 | status = be_msix_register(adapter); |
1643 | if (status == 0) | 1705 | if (status == 0) |
1644 | goto done; | 1706 | goto done; |
1707 | /* INTx is not supported for VF */ | ||
1708 | if (!be_physfn(adapter)) | ||
1709 | return status; | ||
1645 | } | 1710 | } |
1646 | 1711 | ||
1647 | /* INTx */ | 1712 | /* INTx */ |
@@ -1715,14 +1780,17 @@ static int be_open(struct net_device *netdev) | |||
1715 | goto ret_sts; | 1780 | goto ret_sts; |
1716 | be_link_status_update(adapter, link_up); | 1781 | be_link_status_update(adapter, link_up); |
1717 | 1782 | ||
1718 | status = be_vid_config(adapter); | 1783 | if (be_physfn(adapter)) |
1784 | status = be_vid_config(adapter); | ||
1719 | if (status) | 1785 | if (status) |
1720 | goto ret_sts; | 1786 | goto ret_sts; |
1721 | 1787 | ||
1722 | status = be_cmd_set_flow_control(adapter, | 1788 | if (be_physfn(adapter)) { |
1723 | adapter->tx_fc, adapter->rx_fc); | 1789 | status = be_cmd_set_flow_control(adapter, |
1724 | if (status) | 1790 | adapter->tx_fc, adapter->rx_fc); |
1725 | goto ret_sts; | 1791 | if (status) |
1792 | goto ret_sts; | ||
1793 | } | ||
1726 | 1794 | ||
1727 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | 1795 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); |
1728 | ret_sts: | 1796 | ret_sts: |
@@ -1770,22 +1838,48 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) | |||
1770 | static int be_setup(struct be_adapter *adapter) | 1838 | static int be_setup(struct be_adapter *adapter) |
1771 | { | 1839 | { |
1772 | struct net_device *netdev = adapter->netdev; | 1840 | struct net_device *netdev = adapter->netdev; |
1773 | u32 cap_flags, en_flags; | 1841 | u32 cap_flags, en_flags, vf = 0; |
1774 | int status; | 1842 | int status; |
1843 | u8 mac[ETH_ALEN]; | ||
1844 | |||
1845 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; | ||
1775 | 1846 | ||
1776 | cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 1847 | if (be_physfn(adapter)) { |
1777 | BE_IF_FLAGS_MCAST_PROMISCUOUS | | 1848 | cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS | |
1778 | BE_IF_FLAGS_PROMISCUOUS | | 1849 | BE_IF_FLAGS_PROMISCUOUS | |
1779 | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 1850 | BE_IF_FLAGS_PASS_L3L4_ERRORS; |
1780 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 1851 | en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; |
1781 | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 1852 | } |
1782 | 1853 | ||
1783 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 1854 | status = be_cmd_if_create(adapter, cap_flags, en_flags, |
1784 | netdev->dev_addr, false/* pmac_invalid */, | 1855 | netdev->dev_addr, false/* pmac_invalid */, |
1785 | &adapter->if_handle, &adapter->pmac_id); | 1856 | &adapter->if_handle, &adapter->pmac_id, 0); |
1786 | if (status != 0) | 1857 | if (status != 0) |
1787 | goto do_none; | 1858 | goto do_none; |
1788 | 1859 | ||
1860 | if (be_physfn(adapter)) { | ||
1861 | while (vf < num_vfs) { | ||
1862 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | ||
1863 | | BE_IF_FLAGS_BROADCAST; | ||
1864 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | ||
1865 | mac, true, &adapter->vf_if_handle[vf], | ||
1866 | NULL, vf+1); | ||
1867 | if (status) { | ||
1868 | dev_err(&adapter->pdev->dev, | ||
1869 | "Interface Create failed for VF %d\n", vf); | ||
1870 | goto if_destroy; | ||
1871 | } | ||
1872 | vf++; | ||
1873 | } while (vf < num_vfs); | ||
1874 | } else if (!be_physfn(adapter)) { | ||
1875 | status = be_cmd_mac_addr_query(adapter, mac, | ||
1876 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); | ||
1877 | if (!status) { | ||
1878 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
1879 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
1880 | } | ||
1881 | } | ||
1882 | |||
1789 | status = be_tx_queues_create(adapter); | 1883 | status = be_tx_queues_create(adapter); |
1790 | if (status != 0) | 1884 | if (status != 0) |
1791 | goto if_destroy; | 1885 | goto if_destroy; |
@@ -1807,6 +1901,9 @@ rx_qs_destroy: | |||
1807 | tx_qs_destroy: | 1901 | tx_qs_destroy: |
1808 | be_tx_queues_destroy(adapter); | 1902 | be_tx_queues_destroy(adapter); |
1809 | if_destroy: | 1903 | if_destroy: |
1904 | for (vf = 0; vf < num_vfs; vf++) | ||
1905 | if (adapter->vf_if_handle[vf]) | ||
1906 | be_cmd_if_destroy(adapter, adapter->vf_if_handle[vf]); | ||
1810 | be_cmd_if_destroy(adapter, adapter->if_handle); | 1907 | be_cmd_if_destroy(adapter, adapter->if_handle); |
1811 | do_none: | 1908 | do_none: |
1812 | return status; | 1909 | return status; |
@@ -2087,6 +2184,7 @@ static struct net_device_ops be_netdev_ops = { | |||
2087 | .ndo_vlan_rx_register = be_vlan_register, | 2184 | .ndo_vlan_rx_register = be_vlan_register, |
2088 | .ndo_vlan_rx_add_vid = be_vlan_add_vid, | 2185 | .ndo_vlan_rx_add_vid = be_vlan_add_vid, |
2089 | .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, | 2186 | .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, |
2187 | .ndo_set_vf_mac = be_set_vf_mac | ||
2090 | }; | 2188 | }; |
2091 | 2189 | ||
2092 | static void be_netdev_init(struct net_device *netdev) | 2190 | static void be_netdev_init(struct net_device *netdev) |
@@ -2128,37 +2226,48 @@ static void be_unmap_pci_bars(struct be_adapter *adapter) | |||
2128 | iounmap(adapter->csr); | 2226 | iounmap(adapter->csr); |
2129 | if (adapter->db) | 2227 | if (adapter->db) |
2130 | iounmap(adapter->db); | 2228 | iounmap(adapter->db); |
2131 | if (adapter->pcicfg) | 2229 | if (adapter->pcicfg && be_physfn(adapter)) |
2132 | iounmap(adapter->pcicfg); | 2230 | iounmap(adapter->pcicfg); |
2133 | } | 2231 | } |
2134 | 2232 | ||
2135 | static int be_map_pci_bars(struct be_adapter *adapter) | 2233 | static int be_map_pci_bars(struct be_adapter *adapter) |
2136 | { | 2234 | { |
2137 | u8 __iomem *addr; | 2235 | u8 __iomem *addr; |
2138 | int pcicfg_reg; | 2236 | int pcicfg_reg, db_reg; |
2139 | 2237 | ||
2140 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), | 2238 | if (be_physfn(adapter)) { |
2141 | pci_resource_len(adapter->pdev, 2)); | 2239 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), |
2142 | if (addr == NULL) | 2240 | pci_resource_len(adapter->pdev, 2)); |
2143 | return -ENOMEM; | 2241 | if (addr == NULL) |
2144 | adapter->csr = addr; | 2242 | return -ENOMEM; |
2145 | 2243 | adapter->csr = addr; | |
2146 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4), | 2244 | } |
2147 | 128 * 1024); | ||
2148 | if (addr == NULL) | ||
2149 | goto pci_map_err; | ||
2150 | adapter->db = addr; | ||
2151 | 2245 | ||
2152 | if (adapter->generation == BE_GEN2) | 2246 | if (adapter->generation == BE_GEN2) { |
2153 | pcicfg_reg = 1; | 2247 | pcicfg_reg = 1; |
2154 | else | 2248 | db_reg = 4; |
2249 | } else { | ||
2155 | pcicfg_reg = 0; | 2250 | pcicfg_reg = 0; |
2156 | 2251 | if (be_physfn(adapter)) | |
2157 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg), | 2252 | db_reg = 4; |
2158 | pci_resource_len(adapter->pdev, pcicfg_reg)); | 2253 | else |
2254 | db_reg = 0; | ||
2255 | } | ||
2256 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, db_reg), | ||
2257 | pci_resource_len(adapter->pdev, db_reg)); | ||
2159 | if (addr == NULL) | 2258 | if (addr == NULL) |
2160 | goto pci_map_err; | 2259 | goto pci_map_err; |
2161 | adapter->pcicfg = addr; | 2260 | adapter->db = addr; |
2261 | |||
2262 | if (be_physfn(adapter)) { | ||
2263 | addr = ioremap_nocache( | ||
2264 | pci_resource_start(adapter->pdev, pcicfg_reg), | ||
2265 | pci_resource_len(adapter->pdev, pcicfg_reg)); | ||
2266 | if (addr == NULL) | ||
2267 | goto pci_map_err; | ||
2268 | adapter->pcicfg = addr; | ||
2269 | } else | ||
2270 | adapter->pcicfg = adapter->db + SRIOV_VF_PCICFG_OFFSET; | ||
2162 | 2271 | ||
2163 | return 0; | 2272 | return 0; |
2164 | pci_map_err: | 2273 | pci_map_err: |
@@ -2272,6 +2381,8 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
2272 | 2381 | ||
2273 | be_ctrl_cleanup(adapter); | 2382 | be_ctrl_cleanup(adapter); |
2274 | 2383 | ||
2384 | be_sriov_disable(adapter); | ||
2385 | |||
2275 | be_msix_disable(adapter); | 2386 | be_msix_disable(adapter); |
2276 | 2387 | ||
2277 | pci_set_drvdata(pdev, NULL); | 2388 | pci_set_drvdata(pdev, NULL); |
@@ -2296,16 +2407,20 @@ static int be_get_config(struct be_adapter *adapter) | |||
2296 | return status; | 2407 | return status; |
2297 | 2408 | ||
2298 | memset(mac, 0, ETH_ALEN); | 2409 | memset(mac, 0, ETH_ALEN); |
2299 | status = be_cmd_mac_addr_query(adapter, mac, | 2410 | |
2411 | if (be_physfn(adapter)) { | ||
2412 | status = be_cmd_mac_addr_query(adapter, mac, | ||
2300 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); | 2413 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); |
2301 | if (status) | ||
2302 | return status; | ||
2303 | 2414 | ||
2304 | if (!is_valid_ether_addr(mac)) | 2415 | if (status) |
2305 | return -EADDRNOTAVAIL; | 2416 | return status; |
2306 | 2417 | ||
2307 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | 2418 | if (!is_valid_ether_addr(mac)) |
2308 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | 2419 | return -EADDRNOTAVAIL; |
2420 | |||
2421 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
2422 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
2423 | } | ||
2309 | 2424 | ||
2310 | if (adapter->cap & 0x400) | 2425 | if (adapter->cap & 0x400) |
2311 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; | 2426 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; |
@@ -2322,6 +2437,7 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2322 | struct be_adapter *adapter; | 2437 | struct be_adapter *adapter; |
2323 | struct net_device *netdev; | 2438 | struct net_device *netdev; |
2324 | 2439 | ||
2440 | |||
2325 | status = pci_enable_device(pdev); | 2441 | status = pci_enable_device(pdev); |
2326 | if (status) | 2442 | if (status) |
2327 | goto do_none; | 2443 | goto do_none; |
@@ -2370,24 +2486,28 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2370 | } | 2486 | } |
2371 | } | 2487 | } |
2372 | 2488 | ||
2489 | be_sriov_enable(adapter); | ||
2490 | |||
2373 | status = be_ctrl_init(adapter); | 2491 | status = be_ctrl_init(adapter); |
2374 | if (status) | 2492 | if (status) |
2375 | goto free_netdev; | 2493 | goto free_netdev; |
2376 | 2494 | ||
2377 | /* sync up with fw's ready state */ | 2495 | /* sync up with fw's ready state */ |
2378 | status = be_cmd_POST(adapter); | 2496 | if (be_physfn(adapter)) { |
2379 | if (status) | 2497 | status = be_cmd_POST(adapter); |
2380 | goto ctrl_clean; | 2498 | if (status) |
2499 | goto ctrl_clean; | ||
2500 | |||
2501 | status = be_cmd_reset_function(adapter); | ||
2502 | if (status) | ||
2503 | goto ctrl_clean; | ||
2504 | } | ||
2381 | 2505 | ||
2382 | /* tell fw we're ready to fire cmds */ | 2506 | /* tell fw we're ready to fire cmds */ |
2383 | status = be_cmd_fw_init(adapter); | 2507 | status = be_cmd_fw_init(adapter); |
2384 | if (status) | 2508 | if (status) |
2385 | goto ctrl_clean; | 2509 | goto ctrl_clean; |
2386 | 2510 | ||
2387 | status = be_cmd_reset_function(adapter); | ||
2388 | if (status) | ||
2389 | goto ctrl_clean; | ||
2390 | |||
2391 | status = be_stats_init(adapter); | 2511 | status = be_stats_init(adapter); |
2392 | if (status) | 2512 | if (status) |
2393 | goto ctrl_clean; | 2513 | goto ctrl_clean; |
@@ -2417,6 +2537,7 @@ ctrl_clean: | |||
2417 | be_ctrl_cleanup(adapter); | 2537 | be_ctrl_cleanup(adapter); |
2418 | free_netdev: | 2538 | free_netdev: |
2419 | be_msix_disable(adapter); | 2539 | be_msix_disable(adapter); |
2540 | be_sriov_disable(adapter); | ||
2420 | free_netdev(adapter->netdev); | 2541 | free_netdev(adapter->netdev); |
2421 | pci_set_drvdata(pdev, NULL); | 2542 | pci_set_drvdata(pdev, NULL); |
2422 | rel_reg: | 2543 | rel_reg: |
@@ -2613,6 +2734,13 @@ static int __init be_init_module(void) | |||
2613 | rx_frag_size = 2048; | 2734 | rx_frag_size = 2048; |
2614 | } | 2735 | } |
2615 | 2736 | ||
2737 | if (num_vfs > 32) { | ||
2738 | printk(KERN_WARNING DRV_NAME | ||
2739 | " : Module param num_vfs must not be greater than 32." | ||
2740 | "Using 32\n"); | ||
2741 | num_vfs = 32; | ||
2742 | } | ||
2743 | |||
2616 | return pci_register_driver(&be_driver); | 2744 | return pci_register_driver(&be_driver); |
2617 | } | 2745 | } |
2618 | module_init(be_init_module); | 2746 | module_init(be_init_module); |