diff options
author | Ganesh Goudar <ganeshgr@chelsio.com> | 2018-01-16 05:47:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-17 16:04:48 -0500 |
commit | baf5086840ab1815003e6ece5a51c1a803f81f47 (patch) | |
tree | 5d40d9a13e532d74ecc35c0531cfca405ee6f849 | |
parent | 42157277af17d5c05946c700eb03877d60760d3c (diff) |
cxgb4: restructure VF mgmt code
restructure the code which adds support for configuring
PCIe VF via mgmt netdevice. which was added by
commit 7829451c695e ("cxgb4: Add control net_device for
configuring PCIe VF")
Original work by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 393 |
2 files changed, 190 insertions, 204 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index baa67d362051..f05b58f74c7a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -312,6 +312,7 @@ struct vpd_params { | |||
312 | }; | 312 | }; |
313 | 313 | ||
314 | struct pci_params { | 314 | struct pci_params { |
315 | unsigned int vpd_cap_addr; | ||
315 | unsigned char speed; | 316 | unsigned char speed; |
316 | unsigned char width; | 317 | unsigned char width; |
317 | }; | 318 | }; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 3293980ce6e0..11fe5961040a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -102,7 +102,9 @@ const char cxgb4_driver_version[] = DRV_VERSION; | |||
102 | */ | 102 | */ |
103 | #define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \ | 103 | #define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \ |
104 | static const struct pci_device_id cxgb4_pci_tbl[] = { | 104 | static const struct pci_device_id cxgb4_pci_tbl[] = { |
105 | #define CH_PCI_DEVICE_ID_FUNCTION 0x4 | 105 | #define CXGB4_UNIFIED_PF 0x4 |
106 | |||
107 | #define CH_PCI_DEVICE_ID_FUNCTION CXGB4_UNIFIED_PF | ||
106 | 108 | ||
107 | /* Include PCI Device IDs for both PF4 and PF0-3 so our PCI probe() routine is | 109 | /* Include PCI Device IDs for both PF4 and PF0-3 so our PCI probe() routine is |
108 | * called for both. | 110 | * called for both. |
@@ -110,7 +112,7 @@ const char cxgb4_driver_version[] = DRV_VERSION; | |||
110 | #define CH_PCI_DEVICE_ID_FUNCTION2 0x0 | 112 | #define CH_PCI_DEVICE_ID_FUNCTION2 0x0 |
111 | 113 | ||
112 | #define CH_PCI_ID_TABLE_ENTRY(devid) \ | 114 | #define CH_PCI_ID_TABLE_ENTRY(devid) \ |
113 | {PCI_VDEVICE(CHELSIO, (devid)), 4} | 115 | {PCI_VDEVICE(CHELSIO, (devid)), CXGB4_UNIFIED_PF} |
114 | 116 | ||
115 | #define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \ | 117 | #define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \ |
116 | { 0, } \ | 118 | { 0, } \ |
@@ -2605,7 +2607,7 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu) | |||
2605 | } | 2607 | } |
2606 | 2608 | ||
2607 | #ifdef CONFIG_PCI_IOV | 2609 | #ifdef CONFIG_PCI_IOV |
2608 | static int dummy_open(struct net_device *dev) | 2610 | static int cxgb4_mgmt_open(struct net_device *dev) |
2609 | { | 2611 | { |
2610 | /* Turn carrier off since we don't have to transmit anything on this | 2612 | /* Turn carrier off since we don't have to transmit anything on this |
2611 | * interface. | 2613 | * interface. |
@@ -2615,39 +2617,44 @@ static int dummy_open(struct net_device *dev) | |||
2615 | } | 2617 | } |
2616 | 2618 | ||
2617 | /* Fill MAC address that will be assigned by the FW */ | 2619 | /* Fill MAC address that will be assigned by the FW */ |
2618 | static void fill_vf_station_mac_addr(struct adapter *adap) | 2620 | static void cxgb4_mgmt_fill_vf_station_mac_addr(struct adapter *adap) |
2619 | { | 2621 | { |
2620 | unsigned int i; | ||
2621 | u8 hw_addr[ETH_ALEN], macaddr[ETH_ALEN]; | 2622 | u8 hw_addr[ETH_ALEN], macaddr[ETH_ALEN]; |
2623 | unsigned int i, vf, nvfs; | ||
2624 | u16 a, b; | ||
2622 | int err; | 2625 | int err; |
2623 | u8 *na; | 2626 | u8 *na; |
2624 | u16 a, b; | ||
2625 | 2627 | ||
2628 | adap->params.pci.vpd_cap_addr = pci_find_capability(adap->pdev, | ||
2629 | PCI_CAP_ID_VPD); | ||
2626 | err = t4_get_raw_vpd_params(adap, &adap->params.vpd); | 2630 | err = t4_get_raw_vpd_params(adap, &adap->params.vpd); |
2627 | if (!err) { | 2631 | if (err) |
2628 | na = adap->params.vpd.na; | 2632 | return; |
2629 | for (i = 0; i < ETH_ALEN; i++) | 2633 | |
2630 | hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 + | 2634 | na = adap->params.vpd.na; |
2631 | hex2val(na[2 * i + 1])); | 2635 | for (i = 0; i < ETH_ALEN; i++) |
2632 | a = (hw_addr[0] << 8) | hw_addr[1]; | 2636 | hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 + |
2633 | b = (hw_addr[1] << 8) | hw_addr[2]; | 2637 | hex2val(na[2 * i + 1])); |
2634 | a ^= b; | 2638 | |
2635 | a |= 0x0200; /* locally assigned Ethernet MAC address */ | 2639 | a = (hw_addr[0] << 8) | hw_addr[1]; |
2636 | a &= ~0x0100; /* not a multicast Ethernet MAC address */ | 2640 | b = (hw_addr[1] << 8) | hw_addr[2]; |
2637 | macaddr[0] = a >> 8; | 2641 | a ^= b; |
2638 | macaddr[1] = a & 0xff; | 2642 | a |= 0x0200; /* locally assigned Ethernet MAC address */ |
2639 | 2643 | a &= ~0x0100; /* not a multicast Ethernet MAC address */ | |
2640 | for (i = 2; i < 5; i++) | 2644 | macaddr[0] = a >> 8; |
2641 | macaddr[i] = hw_addr[i + 1]; | 2645 | macaddr[1] = a & 0xff; |
2642 | 2646 | ||
2643 | for (i = 0; i < adap->num_vfs; i++) { | 2647 | for (i = 2; i < 5; i++) |
2644 | macaddr[5] = adap->pf * 16 + i; | 2648 | macaddr[i] = hw_addr[i + 1]; |
2645 | ether_addr_copy(adap->vfinfo[i].vf_mac_addr, macaddr); | 2649 | |
2646 | } | 2650 | for (vf = 0, nvfs = pci_sriov_get_totalvfs(adap->pdev); |
2651 | vf < nvfs; vf++) { | ||
2652 | macaddr[5] = adap->pf * 16 + vf; | ||
2653 | ether_addr_copy(adap->vfinfo[vf].vf_mac_addr, macaddr); | ||
2647 | } | 2654 | } |
2648 | } | 2655 | } |
2649 | 2656 | ||
2650 | static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) | 2657 | static int cxgb4_mgmt_set_vf_mac(struct net_device *dev, int vf, u8 *mac) |
2651 | { | 2658 | { |
2652 | struct port_info *pi = netdev_priv(dev); | 2659 | struct port_info *pi = netdev_priv(dev); |
2653 | struct adapter *adap = pi->adapter; | 2660 | struct adapter *adap = pi->adapter; |
@@ -2669,8 +2676,8 @@ static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac) | |||
2669 | return ret; | 2676 | return ret; |
2670 | } | 2677 | } |
2671 | 2678 | ||
2672 | static int cxgb_get_vf_config(struct net_device *dev, | 2679 | static int cxgb4_mgmt_get_vf_config(struct net_device *dev, |
2673 | int vf, struct ifla_vf_info *ivi) | 2680 | int vf, struct ifla_vf_info *ivi) |
2674 | { | 2681 | { |
2675 | struct port_info *pi = netdev_priv(dev); | 2682 | struct port_info *pi = netdev_priv(dev); |
2676 | struct adapter *adap = pi->adapter; | 2683 | struct adapter *adap = pi->adapter; |
@@ -2684,8 +2691,8 @@ static int cxgb_get_vf_config(struct net_device *dev, | |||
2684 | return 0; | 2691 | return 0; |
2685 | } | 2692 | } |
2686 | 2693 | ||
2687 | static int cxgb_get_phys_port_id(struct net_device *dev, | 2694 | static int cxgb4_mgmt_get_phys_port_id(struct net_device *dev, |
2688 | struct netdev_phys_item_id *ppid) | 2695 | struct netdev_phys_item_id *ppid) |
2689 | { | 2696 | { |
2690 | struct port_info *pi = netdev_priv(dev); | 2697 | struct port_info *pi = netdev_priv(dev); |
2691 | unsigned int phy_port_id; | 2698 | unsigned int phy_port_id; |
@@ -2696,8 +2703,8 @@ static int cxgb_get_phys_port_id(struct net_device *dev, | |||
2696 | return 0; | 2703 | return 0; |
2697 | } | 2704 | } |
2698 | 2705 | ||
2699 | static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, | 2706 | static int cxgb4_mgmt_set_vf_rate(struct net_device *dev, int vf, |
2700 | int max_tx_rate) | 2707 | int min_tx_rate, int max_tx_rate) |
2701 | { | 2708 | { |
2702 | struct port_info *pi = netdev_priv(dev); | 2709 | struct port_info *pi = netdev_priv(dev); |
2703 | struct adapter *adap = pi->adapter; | 2710 | struct adapter *adap = pi->adapter; |
@@ -3172,15 +3179,16 @@ static const struct net_device_ops cxgb4_netdev_ops = { | |||
3172 | 3179 | ||
3173 | #ifdef CONFIG_PCI_IOV | 3180 | #ifdef CONFIG_PCI_IOV |
3174 | static const struct net_device_ops cxgb4_mgmt_netdev_ops = { | 3181 | static const struct net_device_ops cxgb4_mgmt_netdev_ops = { |
3175 | .ndo_open = dummy_open, | 3182 | .ndo_open = cxgb4_mgmt_open, |
3176 | .ndo_set_vf_mac = cxgb_set_vf_mac, | 3183 | .ndo_set_vf_mac = cxgb4_mgmt_set_vf_mac, |
3177 | .ndo_get_vf_config = cxgb_get_vf_config, | 3184 | .ndo_get_vf_config = cxgb4_mgmt_get_vf_config, |
3178 | .ndo_set_vf_rate = cxgb_set_vf_rate, | 3185 | .ndo_set_vf_rate = cxgb4_mgmt_set_vf_rate, |
3179 | .ndo_get_phys_port_id = cxgb_get_phys_port_id, | 3186 | .ndo_get_phys_port_id = cxgb4_mgmt_get_phys_port_id, |
3180 | }; | 3187 | }; |
3181 | #endif | 3188 | #endif |
3182 | 3189 | ||
3183 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 3190 | static void cxgb4_mgmt_get_drvinfo(struct net_device *dev, |
3191 | struct ethtool_drvinfo *info) | ||
3184 | { | 3192 | { |
3185 | struct adapter *adapter = netdev2adap(dev); | 3193 | struct adapter *adapter = netdev2adap(dev); |
3186 | 3194 | ||
@@ -3192,7 +3200,7 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
3192 | } | 3200 | } |
3193 | 3201 | ||
3194 | static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = { | 3202 | static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = { |
3195 | .get_drvinfo = get_drvinfo, | 3203 | .get_drvinfo = cxgb4_mgmt_get_drvinfo, |
3196 | }; | 3204 | }; |
3197 | 3205 | ||
3198 | void t4_fatal_err(struct adapter *adap) | 3206 | void t4_fatal_err(struct adapter *adap) |
@@ -4908,7 +4916,7 @@ static int get_chip_type(struct pci_dev *pdev, u32 pl_rev) | |||
4908 | } | 4916 | } |
4909 | 4917 | ||
4910 | #ifdef CONFIG_PCI_IOV | 4918 | #ifdef CONFIG_PCI_IOV |
4911 | static void dummy_setup(struct net_device *dev) | 4919 | static void cxgb4_mgmt_setup(struct net_device *dev) |
4912 | { | 4920 | { |
4913 | dev->type = ARPHRD_NONE; | 4921 | dev->type = ARPHRD_NONE; |
4914 | dev->mtu = 0; | 4922 | dev->mtu = 0; |
@@ -4924,38 +4932,6 @@ static void dummy_setup(struct net_device *dev) | |||
4924 | dev->needs_free_netdev = true; | 4932 | dev->needs_free_netdev = true; |
4925 | } | 4933 | } |
4926 | 4934 | ||
4927 | static int config_mgmt_dev(struct pci_dev *pdev) | ||
4928 | { | ||
4929 | struct adapter *adap = pci_get_drvdata(pdev); | ||
4930 | struct net_device *netdev; | ||
4931 | struct port_info *pi; | ||
4932 | char name[IFNAMSIZ]; | ||
4933 | int err; | ||
4934 | |||
4935 | snprintf(name, IFNAMSIZ, "mgmtpf%d%d", adap->adap_idx, adap->pf); | ||
4936 | netdev = alloc_netdev(sizeof(struct port_info), name, NET_NAME_UNKNOWN, | ||
4937 | dummy_setup); | ||
4938 | if (!netdev) | ||
4939 | return -ENOMEM; | ||
4940 | |||
4941 | pi = netdev_priv(netdev); | ||
4942 | pi->adapter = adap; | ||
4943 | pi->tx_chan = adap->pf % adap->params.nports; | ||
4944 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
4945 | |||
4946 | adap->port[0] = netdev; | ||
4947 | pi->port_id = 0; | ||
4948 | |||
4949 | err = register_netdev(adap->port[0]); | ||
4950 | if (err) { | ||
4951 | pr_info("Unable to register VF mgmt netdev %s\n", name); | ||
4952 | free_netdev(adap->port[0]); | ||
4953 | adap->port[0] = NULL; | ||
4954 | return err; | ||
4955 | } | ||
4956 | return 0; | ||
4957 | } | ||
4958 | |||
4959 | static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) | 4935 | static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) |
4960 | { | 4936 | { |
4961 | struct adapter *adap = pci_get_drvdata(pdev); | 4937 | struct adapter *adap = pci_get_drvdata(pdev); |
@@ -4967,7 +4943,7 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) | |||
4967 | /* Check if cxgb4 is the MASTER and fw is initialized */ | 4943 | /* Check if cxgb4 is the MASTER and fw is initialized */ |
4968 | if (!(pcie_fw & PCIE_FW_INIT_F) || | 4944 | if (!(pcie_fw & PCIE_FW_INIT_F) || |
4969 | !(pcie_fw & PCIE_FW_MASTER_VLD_F) || | 4945 | !(pcie_fw & PCIE_FW_MASTER_VLD_F) || |
4970 | PCIE_FW_MASTER_G(pcie_fw) != 4) { | 4946 | PCIE_FW_MASTER_G(pcie_fw) != CXGB4_UNIFIED_PF) { |
4971 | dev_warn(&pdev->dev, | 4947 | dev_warn(&pdev->dev, |
4972 | "cxgb4 driver needs to be MASTER to support SRIOV\n"); | 4948 | "cxgb4 driver needs to be MASTER to support SRIOV\n"); |
4973 | return -EOPNOTSUPP; | 4949 | return -EOPNOTSUPP; |
@@ -4979,46 +4955,132 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) | |||
4979 | if (current_vfs && pci_vfs_assigned(pdev)) { | 4955 | if (current_vfs && pci_vfs_assigned(pdev)) { |
4980 | dev_err(&pdev->dev, | 4956 | dev_err(&pdev->dev, |
4981 | "Cannot modify SR-IOV while VFs are assigned\n"); | 4957 | "Cannot modify SR-IOV while VFs are assigned\n"); |
4982 | num_vfs = current_vfs; | 4958 | return current_vfs; |
4983 | return num_vfs; | ||
4984 | } | 4959 | } |
4985 | 4960 | /* Note that the upper-level code ensures that we're never called with | |
4986 | /* Disable SRIOV when zero is passed. | 4961 | * a non-zero "num_vfs" when we already have VFs instantiated. But |
4987 | * One needs to disable SRIOV before modifying it, else | 4962 | * it never hurts to code defensively. |
4988 | * stack throws the below warning: | ||
4989 | * " 'n' VFs already enabled. Disable before enabling 'm' VFs." | ||
4990 | */ | 4963 | */ |
4964 | if (num_vfs != 0 && current_vfs != 0) | ||
4965 | return -EBUSY; | ||
4966 | |||
4967 | /* Nothing to do for no change. */ | ||
4968 | if (num_vfs == current_vfs) | ||
4969 | return num_vfs; | ||
4970 | |||
4971 | /* Disable SRIOV when zero is passed. */ | ||
4991 | if (!num_vfs) { | 4972 | if (!num_vfs) { |
4992 | pci_disable_sriov(pdev); | 4973 | pci_disable_sriov(pdev); |
4993 | if (adap->port[0]) { | 4974 | /* free VF Management Interface */ |
4994 | unregister_netdev(adap->port[0]); | 4975 | unregister_netdev(adap->port[0]); |
4995 | adap->port[0] = NULL; | 4976 | free_netdev(adap->port[0]); |
4996 | } | 4977 | adap->port[0] = NULL; |
4978 | |||
4997 | /* free VF resources */ | 4979 | /* free VF resources */ |
4980 | adap->num_vfs = 0; | ||
4998 | kfree(adap->vfinfo); | 4981 | kfree(adap->vfinfo); |
4999 | adap->vfinfo = NULL; | 4982 | adap->vfinfo = NULL; |
5000 | adap->num_vfs = 0; | 4983 | return 0; |
5001 | return num_vfs; | ||
5002 | } | 4984 | } |
5003 | 4985 | ||
5004 | if (num_vfs != current_vfs) { | 4986 | if (!current_vfs) { |
5005 | err = pci_enable_sriov(pdev, num_vfs); | 4987 | struct fw_pfvf_cmd port_cmd, port_rpl; |
4988 | struct net_device *netdev; | ||
4989 | unsigned int pmask, port; | ||
4990 | struct pci_dev *pbridge; | ||
4991 | struct port_info *pi; | ||
4992 | char name[IFNAMSIZ]; | ||
4993 | u32 devcap2; | ||
4994 | u16 flags; | ||
4995 | int pos; | ||
4996 | |||
4997 | /* If we want to instantiate Virtual Functions, then our | ||
4998 | * parent bridge's PCI-E needs to support Alternative Routing | ||
4999 | * ID (ARI) because our VFs will show up at function offset 8 | ||
5000 | * and above. | ||
5001 | */ | ||
5002 | pbridge = pdev->bus->self; | ||
5003 | pos = pci_find_capability(pbridge, PCI_CAP_ID_EXP); | ||
5004 | pci_read_config_word(pbridge, pos + PCI_EXP_FLAGS, &flags); | ||
5005 | pci_read_config_dword(pbridge, pos + PCI_EXP_DEVCAP2, &devcap2); | ||
5006 | |||
5007 | if ((flags & PCI_EXP_FLAGS_VERS) < 2 || | ||
5008 | !(devcap2 & PCI_EXP_DEVCAP2_ARI)) { | ||
5009 | /* Our parent bridge does not support ARI so issue a | ||
5010 | * warning and skip instantiating the VFs. They | ||
5011 | * won't be reachable. | ||
5012 | */ | ||
5013 | dev_warn(&pdev->dev, "Parent bridge %02x:%02x.%x doesn't support ARI; can't instantiate Virtual Functions\n", | ||
5014 | pbridge->bus->number, PCI_SLOT(pbridge->devfn), | ||
5015 | PCI_FUNC(pbridge->devfn)); | ||
5016 | return -ENOTSUPP; | ||
5017 | } | ||
5018 | memset(&port_cmd, 0, sizeof(port_cmd)); | ||
5019 | port_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PFVF_CMD) | | ||
5020 | FW_CMD_REQUEST_F | | ||
5021 | FW_CMD_READ_F | | ||
5022 | FW_PFVF_CMD_PFN_V(adap->pf) | | ||
5023 | FW_PFVF_CMD_VFN_V(0)); | ||
5024 | port_cmd.retval_len16 = cpu_to_be32(FW_LEN16(port_cmd)); | ||
5025 | err = t4_wr_mbox(adap, adap->mbox, &port_cmd, sizeof(port_cmd), | ||
5026 | &port_rpl); | ||
5006 | if (err) | 5027 | if (err) |
5007 | return err; | 5028 | return err; |
5029 | pmask = FW_PFVF_CMD_PMASK_G(be32_to_cpu(port_rpl.type_to_neq)); | ||
5030 | port = ffs(pmask) - 1; | ||
5031 | /* Allocate VF Management Interface. */ | ||
5032 | snprintf(name, IFNAMSIZ, "mgmtpf%d,%d", adap->adap_idx, | ||
5033 | adap->pf); | ||
5034 | netdev = alloc_netdev(sizeof(struct port_info), | ||
5035 | name, NET_NAME_UNKNOWN, cxgb4_mgmt_setup); | ||
5036 | if (!netdev) | ||
5037 | return -ENOMEM; | ||
5008 | 5038 | ||
5009 | adap->num_vfs = num_vfs; | 5039 | pi = netdev_priv(netdev); |
5010 | err = config_mgmt_dev(pdev); | 5040 | pi->adapter = adap; |
5011 | if (err) | 5041 | pi->lport = port; |
5042 | pi->tx_chan = port; | ||
5043 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
5044 | |||
5045 | adap->port[0] = netdev; | ||
5046 | pi->port_id = 0; | ||
5047 | |||
5048 | err = register_netdev(adap->port[0]); | ||
5049 | if (err) { | ||
5050 | pr_info("Unable to register VF mgmt netdev %s\n", name); | ||
5051 | free_netdev(adap->port[0]); | ||
5052 | adap->port[0] = NULL; | ||
5012 | return err; | 5053 | return err; |
5054 | } | ||
5055 | /* Allocate and set up VF Information. */ | ||
5056 | adap->vfinfo = kcalloc(pci_sriov_get_totalvfs(pdev), | ||
5057 | sizeof(struct vf_info), GFP_KERNEL); | ||
5058 | if (!adap->vfinfo) { | ||
5059 | unregister_netdev(adap->port[0]); | ||
5060 | free_netdev(adap->port[0]); | ||
5061 | adap->port[0] = NULL; | ||
5062 | return -ENOMEM; | ||
5063 | } | ||
5064 | cxgb4_mgmt_fill_vf_station_mac_addr(adap); | ||
5065 | } | ||
5066 | /* Instantiate the requested number of VFs. */ | ||
5067 | err = pci_enable_sriov(pdev, num_vfs); | ||
5068 | if (err) { | ||
5069 | pr_info("Unable to instantiate %d VFs\n", num_vfs); | ||
5070 | if (!current_vfs) { | ||
5071 | unregister_netdev(adap->port[0]); | ||
5072 | free_netdev(adap->port[0]); | ||
5073 | adap->port[0] = NULL; | ||
5074 | kfree(adap->vfinfo); | ||
5075 | adap->vfinfo = NULL; | ||
5076 | } | ||
5077 | return err; | ||
5013 | } | 5078 | } |
5014 | 5079 | ||
5015 | adap->vfinfo = kcalloc(adap->num_vfs, | 5080 | adap->num_vfs = num_vfs; |
5016 | sizeof(struct vf_info), GFP_KERNEL); | ||
5017 | if (adap->vfinfo) | ||
5018 | fill_vf_station_mac_addr(adap); | ||
5019 | return num_vfs; | 5081 | return num_vfs; |
5020 | } | 5082 | } |
5021 | #endif | 5083 | #endif /* CONFIG_PCI_IOV */ |
5022 | 5084 | ||
5023 | static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 5085 | static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
5024 | { | 5086 | { |
@@ -5031,9 +5093,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5031 | u32 whoami, pl_rev; | 5093 | u32 whoami, pl_rev; |
5032 | enum chip_type chip; | 5094 | enum chip_type chip; |
5033 | static int adap_idx = 1; | 5095 | static int adap_idx = 1; |
5034 | #ifdef CONFIG_PCI_IOV | ||
5035 | u32 v, port_vec; | ||
5036 | #endif | ||
5037 | 5096 | ||
5038 | printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); | 5097 | printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); |
5039 | 5098 | ||
@@ -5057,6 +5116,13 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5057 | goto out_disable_device; | 5116 | goto out_disable_device; |
5058 | } | 5117 | } |
5059 | 5118 | ||
5119 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | ||
5120 | if (!adapter) { | ||
5121 | err = -ENOMEM; | ||
5122 | goto out_unmap_bar0; | ||
5123 | } | ||
5124 | |||
5125 | adapter->regs = regs; | ||
5060 | err = t4_wait_dev_ready(regs); | 5126 | err = t4_wait_dev_ready(regs); |
5061 | if (err < 0) | 5127 | if (err < 0) |
5062 | goto out_unmap_bar0; | 5128 | goto out_unmap_bar0; |
@@ -5067,13 +5133,29 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5067 | chip = get_chip_type(pdev, pl_rev); | 5133 | chip = get_chip_type(pdev, pl_rev); |
5068 | func = CHELSIO_CHIP_VERSION(chip) <= CHELSIO_T5 ? | 5134 | func = CHELSIO_CHIP_VERSION(chip) <= CHELSIO_T5 ? |
5069 | SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); | 5135 | SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); |
5136 | |||
5137 | adapter->pdev = pdev; | ||
5138 | adapter->pdev_dev = &pdev->dev; | ||
5139 | adapter->name = pci_name(pdev); | ||
5140 | adapter->mbox = func; | ||
5141 | adapter->pf = func; | ||
5142 | adapter->msg_enable = DFLT_MSG_ENABLE; | ||
5143 | adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) + | ||
5144 | (sizeof(struct mbox_cmd) * | ||
5145 | T4_OS_LOG_MBOX_CMDS), | ||
5146 | GFP_KERNEL); | ||
5147 | if (!adapter->mbox_log) { | ||
5148 | err = -ENOMEM; | ||
5149 | goto out_free_adapter; | ||
5150 | } | ||
5151 | spin_lock_init(&adapter->mbox_lock); | ||
5152 | INIT_LIST_HEAD(&adapter->mlist.list); | ||
5153 | pci_set_drvdata(pdev, adapter); | ||
5154 | |||
5070 | if (func != ent->driver_data) { | 5155 | if (func != ent->driver_data) { |
5071 | #ifndef CONFIG_PCI_IOV | ||
5072 | iounmap(regs); | ||
5073 | #endif | ||
5074 | pci_disable_device(pdev); | 5156 | pci_disable_device(pdev); |
5075 | pci_save_state(pdev); /* to restore SR-IOV later */ | 5157 | pci_save_state(pdev); /* to restore SR-IOV later */ |
5076 | goto sriov; | 5158 | return 0; |
5077 | } | 5159 | } |
5078 | 5160 | ||
5079 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | 5161 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
@@ -5082,53 +5164,30 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5082 | if (err) { | 5164 | if (err) { |
5083 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " | 5165 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " |
5084 | "coherent allocations\n"); | 5166 | "coherent allocations\n"); |
5085 | goto out_unmap_bar0; | 5167 | goto out_free_adapter; |
5086 | } | 5168 | } |
5087 | } else { | 5169 | } else { |
5088 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 5170 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
5089 | if (err) { | 5171 | if (err) { |
5090 | dev_err(&pdev->dev, "no usable DMA configuration\n"); | 5172 | dev_err(&pdev->dev, "no usable DMA configuration\n"); |
5091 | goto out_unmap_bar0; | 5173 | goto out_free_adapter; |
5092 | } | 5174 | } |
5093 | } | 5175 | } |
5094 | 5176 | ||
5095 | pci_enable_pcie_error_reporting(pdev); | 5177 | pci_enable_pcie_error_reporting(pdev); |
5096 | pci_set_master(pdev); | 5178 | pci_set_master(pdev); |
5097 | pci_save_state(pdev); | 5179 | pci_save_state(pdev); |
5098 | |||
5099 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | ||
5100 | if (!adapter) { | ||
5101 | err = -ENOMEM; | ||
5102 | goto out_unmap_bar0; | ||
5103 | } | ||
5104 | adap_idx++; | 5180 | adap_idx++; |
5105 | |||
5106 | adapter->workq = create_singlethread_workqueue("cxgb4"); | 5181 | adapter->workq = create_singlethread_workqueue("cxgb4"); |
5107 | if (!adapter->workq) { | 5182 | if (!adapter->workq) { |
5108 | err = -ENOMEM; | 5183 | err = -ENOMEM; |
5109 | goto out_free_adapter; | 5184 | goto out_free_adapter; |
5110 | } | 5185 | } |
5111 | 5186 | ||
5112 | adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) + | ||
5113 | (sizeof(struct mbox_cmd) * | ||
5114 | T4_OS_LOG_MBOX_CMDS), | ||
5115 | GFP_KERNEL); | ||
5116 | if (!adapter->mbox_log) { | ||
5117 | err = -ENOMEM; | ||
5118 | goto out_free_adapter; | ||
5119 | } | ||
5120 | adapter->mbox_log->size = T4_OS_LOG_MBOX_CMDS; | 5187 | adapter->mbox_log->size = T4_OS_LOG_MBOX_CMDS; |
5121 | 5188 | ||
5122 | /* PCI device has been enabled */ | 5189 | /* PCI device has been enabled */ |
5123 | adapter->flags |= DEV_ENABLED; | 5190 | adapter->flags |= DEV_ENABLED; |
5124 | |||
5125 | adapter->regs = regs; | ||
5126 | adapter->pdev = pdev; | ||
5127 | adapter->pdev_dev = &pdev->dev; | ||
5128 | adapter->name = pci_name(pdev); | ||
5129 | adapter->mbox = func; | ||
5130 | adapter->pf = func; | ||
5131 | adapter->msg_enable = DFLT_MSG_ENABLE; | ||
5132 | memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); | 5191 | memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); |
5133 | 5192 | ||
5134 | /* If possible, we use PCIe Relaxed Ordering Attribute to deliver | 5193 | /* If possible, we use PCIe Relaxed Ordering Attribute to deliver |
@@ -5151,9 +5210,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5151 | spin_lock_init(&adapter->stats_lock); | 5210 | spin_lock_init(&adapter->stats_lock); |
5152 | spin_lock_init(&adapter->tid_release_lock); | 5211 | spin_lock_init(&adapter->tid_release_lock); |
5153 | spin_lock_init(&adapter->win0_lock); | 5212 | spin_lock_init(&adapter->win0_lock); |
5154 | spin_lock_init(&adapter->mbox_lock); | ||
5155 | |||
5156 | INIT_LIST_HEAD(&adapter->mlist.list); | ||
5157 | 5213 | ||
5158 | INIT_WORK(&adapter->tid_release_task, process_tid_release_list); | 5214 | INIT_WORK(&adapter->tid_release_task, process_tid_release_list); |
5159 | INIT_WORK(&adapter->db_full_task, process_db_full); | 5215 | INIT_WORK(&adapter->db_full_task, process_db_full); |
@@ -5426,58 +5482,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5426 | setup_fw_sge_queues(adapter); | 5482 | setup_fw_sge_queues(adapter); |
5427 | return 0; | 5483 | return 0; |
5428 | 5484 | ||
5429 | sriov: | ||
5430 | #ifdef CONFIG_PCI_IOV | ||
5431 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | ||
5432 | if (!adapter) { | ||
5433 | err = -ENOMEM; | ||
5434 | goto free_pci_region; | ||
5435 | } | ||
5436 | |||
5437 | adapter->pdev = pdev; | ||
5438 | adapter->pdev_dev = &pdev->dev; | ||
5439 | adapter->name = pci_name(pdev); | ||
5440 | adapter->mbox = func; | ||
5441 | adapter->pf = func; | ||
5442 | adapter->regs = regs; | ||
5443 | adapter->adap_idx = adap_idx; | ||
5444 | adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) + | ||
5445 | (sizeof(struct mbox_cmd) * | ||
5446 | T4_OS_LOG_MBOX_CMDS), | ||
5447 | GFP_KERNEL); | ||
5448 | if (!adapter->mbox_log) { | ||
5449 | err = -ENOMEM; | ||
5450 | goto free_adapter; | ||
5451 | } | ||
5452 | spin_lock_init(&adapter->mbox_lock); | ||
5453 | INIT_LIST_HEAD(&adapter->mlist.list); | ||
5454 | |||
5455 | v = FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | | ||
5456 | FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_PORTVEC); | ||
5457 | err = t4_query_params(adapter, adapter->mbox, adapter->pf, 0, 1, | ||
5458 | &v, &port_vec); | ||
5459 | if (err < 0) { | ||
5460 | dev_err(adapter->pdev_dev, "Could not fetch port params\n"); | ||
5461 | goto free_mbox_log; | ||
5462 | } | ||
5463 | |||
5464 | adapter->params.nports = hweight32(port_vec); | ||
5465 | pci_set_drvdata(pdev, adapter); | ||
5466 | return 0; | ||
5467 | |||
5468 | free_mbox_log: | ||
5469 | kfree(adapter->mbox_log); | ||
5470 | free_adapter: | ||
5471 | kfree(adapter); | ||
5472 | free_pci_region: | ||
5473 | iounmap(regs); | ||
5474 | pci_disable_sriov(pdev); | ||
5475 | pci_release_regions(pdev); | ||
5476 | return err; | ||
5477 | #else | ||
5478 | return 0; | ||
5479 | #endif | ||
5480 | |||
5481 | out_free_dev: | 5485 | out_free_dev: |
5482 | free_some_resources(adapter); | 5486 | free_some_resources(adapter); |
5483 | if (adapter->flags & USING_MSIX) | 5487 | if (adapter->flags & USING_MSIX) |
@@ -5569,14 +5573,7 @@ static void remove_one(struct pci_dev *pdev) | |||
5569 | } | 5573 | } |
5570 | #ifdef CONFIG_PCI_IOV | 5574 | #ifdef CONFIG_PCI_IOV |
5571 | else { | 5575 | else { |
5572 | if (adapter->port[0]) | 5576 | cxgb4_iov_configure(adapter->pdev, 0); |
5573 | unregister_netdev(adapter->port[0]); | ||
5574 | iounmap(adapter->regs); | ||
5575 | kfree(adapter->vfinfo); | ||
5576 | kfree(adapter->mbox_log); | ||
5577 | kfree(adapter); | ||
5578 | pci_disable_sriov(pdev); | ||
5579 | pci_release_regions(pdev); | ||
5580 | } | 5577 | } |
5581 | #endif | 5578 | #endif |
5582 | } | 5579 | } |
@@ -5620,18 +5617,6 @@ static void shutdown_one(struct pci_dev *pdev) | |||
5620 | if (adapter->flags & FW_OK) | 5617 | if (adapter->flags & FW_OK) |
5621 | t4_fw_bye(adapter, adapter->mbox); | 5618 | t4_fw_bye(adapter, adapter->mbox); |
5622 | } | 5619 | } |
5623 | #ifdef CONFIG_PCI_IOV | ||
5624 | else { | ||
5625 | if (adapter->port[0]) | ||
5626 | unregister_netdev(adapter->port[0]); | ||
5627 | iounmap(adapter->regs); | ||
5628 | kfree(adapter->vfinfo); | ||
5629 | kfree(adapter->mbox_log); | ||
5630 | kfree(adapter); | ||
5631 | pci_disable_sriov(pdev); | ||
5632 | pci_release_regions(pdev); | ||
5633 | } | ||
5634 | #endif | ||
5635 | } | 5620 | } |
5636 | 5621 | ||
5637 | static struct pci_driver cxgb4_driver = { | 5622 | static struct pci_driver cxgb4_driver = { |