mirror of
https://github.com/torvalds/linux.git
synced 2024-12-03 17:41:22 +00:00
cxgb4: restructure VF mgmt code
restructure the code which adds support for configuring
PCIe VF via mgmt netdevice. which was added by
commit 7829451c69
("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>
This commit is contained in:
parent
42157277af
commit
baf5086840
@ -312,6 +312,7 @@ struct vpd_params {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct pci_params {
|
struct pci_params {
|
||||||
|
unsigned int vpd_cap_addr;
|
||||||
unsigned char speed;
|
unsigned char speed;
|
||||||
unsigned char width;
|
unsigned char width;
|
||||||
};
|
};
|
||||||
|
@ -102,7 +102,9 @@ const char cxgb4_driver_version[] = DRV_VERSION;
|
|||||||
*/
|
*/
|
||||||
#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \
|
#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \
|
||||||
static const struct pci_device_id cxgb4_pci_tbl[] = {
|
static const struct pci_device_id cxgb4_pci_tbl[] = {
|
||||||
#define CH_PCI_DEVICE_ID_FUNCTION 0x4
|
#define CXGB4_UNIFIED_PF 0x4
|
||||||
|
|
||||||
|
#define CH_PCI_DEVICE_ID_FUNCTION CXGB4_UNIFIED_PF
|
||||||
|
|
||||||
/* Include PCI Device IDs for both PF4 and PF0-3 so our PCI probe() routine is
|
/* Include PCI Device IDs for both PF4 and PF0-3 so our PCI probe() routine is
|
||||||
* called for both.
|
* called for both.
|
||||||
@ -110,7 +112,7 @@ const char cxgb4_driver_version[] = DRV_VERSION;
|
|||||||
#define CH_PCI_DEVICE_ID_FUNCTION2 0x0
|
#define CH_PCI_DEVICE_ID_FUNCTION2 0x0
|
||||||
|
|
||||||
#define CH_PCI_ID_TABLE_ENTRY(devid) \
|
#define CH_PCI_ID_TABLE_ENTRY(devid) \
|
||||||
{PCI_VDEVICE(CHELSIO, (devid)), 4}
|
{PCI_VDEVICE(CHELSIO, (devid)), CXGB4_UNIFIED_PF}
|
||||||
|
|
||||||
#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \
|
#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \
|
||||||
{ 0, } \
|
{ 0, } \
|
||||||
@ -2605,7 +2607,7 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
static int dummy_open(struct net_device *dev)
|
static int cxgb4_mgmt_open(struct net_device *dev)
|
||||||
{
|
{
|
||||||
/* Turn carrier off since we don't have to transmit anything on this
|
/* Turn carrier off since we don't have to transmit anything on this
|
||||||
* interface.
|
* interface.
|
||||||
@ -2615,39 +2617,44 @@ static int dummy_open(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fill MAC address that will be assigned by the FW */
|
/* Fill MAC address that will be assigned by the FW */
|
||||||
static void fill_vf_station_mac_addr(struct adapter *adap)
|
static void cxgb4_mgmt_fill_vf_station_mac_addr(struct adapter *adap)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
u8 hw_addr[ETH_ALEN], macaddr[ETH_ALEN];
|
u8 hw_addr[ETH_ALEN], macaddr[ETH_ALEN];
|
||||||
|
unsigned int i, vf, nvfs;
|
||||||
|
u16 a, b;
|
||||||
int err;
|
int err;
|
||||||
u8 *na;
|
u8 *na;
|
||||||
u16 a, b;
|
|
||||||
|
|
||||||
|
adap->params.pci.vpd_cap_addr = pci_find_capability(adap->pdev,
|
||||||
|
PCI_CAP_ID_VPD);
|
||||||
err = t4_get_raw_vpd_params(adap, &adap->params.vpd);
|
err = t4_get_raw_vpd_params(adap, &adap->params.vpd);
|
||||||
if (!err) {
|
if (err)
|
||||||
na = adap->params.vpd.na;
|
return;
|
||||||
for (i = 0; i < ETH_ALEN; i++)
|
|
||||||
hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 +
|
|
||||||
hex2val(na[2 * i + 1]));
|
|
||||||
a = (hw_addr[0] << 8) | hw_addr[1];
|
|
||||||
b = (hw_addr[1] << 8) | hw_addr[2];
|
|
||||||
a ^= b;
|
|
||||||
a |= 0x0200; /* locally assigned Ethernet MAC address */
|
|
||||||
a &= ~0x0100; /* not a multicast Ethernet MAC address */
|
|
||||||
macaddr[0] = a >> 8;
|
|
||||||
macaddr[1] = a & 0xff;
|
|
||||||
|
|
||||||
for (i = 2; i < 5; i++)
|
na = adap->params.vpd.na;
|
||||||
macaddr[i] = hw_addr[i + 1];
|
for (i = 0; i < ETH_ALEN; i++)
|
||||||
|
hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 +
|
||||||
|
hex2val(na[2 * i + 1]));
|
||||||
|
|
||||||
for (i = 0; i < adap->num_vfs; i++) {
|
a = (hw_addr[0] << 8) | hw_addr[1];
|
||||||
macaddr[5] = adap->pf * 16 + i;
|
b = (hw_addr[1] << 8) | hw_addr[2];
|
||||||
ether_addr_copy(adap->vfinfo[i].vf_mac_addr, macaddr);
|
a ^= b;
|
||||||
}
|
a |= 0x0200; /* locally assigned Ethernet MAC address */
|
||||||
|
a &= ~0x0100; /* not a multicast Ethernet MAC address */
|
||||||
|
macaddr[0] = a >> 8;
|
||||||
|
macaddr[1] = a & 0xff;
|
||||||
|
|
||||||
|
for (i = 2; i < 5; i++)
|
||||||
|
macaddr[i] = hw_addr[i + 1];
|
||||||
|
|
||||||
|
for (vf = 0, nvfs = pci_sriov_get_totalvfs(adap->pdev);
|
||||||
|
vf < nvfs; vf++) {
|
||||||
|
macaddr[5] = adap->pf * 16 + vf;
|
||||||
|
ether_addr_copy(adap->vfinfo[vf].vf_mac_addr, macaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
|
static int cxgb4_mgmt_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
|
||||||
{
|
{
|
||||||
struct port_info *pi = netdev_priv(dev);
|
struct port_info *pi = netdev_priv(dev);
|
||||||
struct adapter *adap = pi->adapter;
|
struct adapter *adap = pi->adapter;
|
||||||
@ -2669,8 +2676,8 @@ static int cxgb_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cxgb_get_vf_config(struct net_device *dev,
|
static int cxgb4_mgmt_get_vf_config(struct net_device *dev,
|
||||||
int vf, struct ifla_vf_info *ivi)
|
int vf, struct ifla_vf_info *ivi)
|
||||||
{
|
{
|
||||||
struct port_info *pi = netdev_priv(dev);
|
struct port_info *pi = netdev_priv(dev);
|
||||||
struct adapter *adap = pi->adapter;
|
struct adapter *adap = pi->adapter;
|
||||||
@ -2684,8 +2691,8 @@ static int cxgb_get_vf_config(struct net_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cxgb_get_phys_port_id(struct net_device *dev,
|
static int cxgb4_mgmt_get_phys_port_id(struct net_device *dev,
|
||||||
struct netdev_phys_item_id *ppid)
|
struct netdev_phys_item_id *ppid)
|
||||||
{
|
{
|
||||||
struct port_info *pi = netdev_priv(dev);
|
struct port_info *pi = netdev_priv(dev);
|
||||||
unsigned int phy_port_id;
|
unsigned int phy_port_id;
|
||||||
@ -2696,8 +2703,8 @@ static int cxgb_get_phys_port_id(struct net_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
|
static int cxgb4_mgmt_set_vf_rate(struct net_device *dev, int vf,
|
||||||
int max_tx_rate)
|
int min_tx_rate, int max_tx_rate)
|
||||||
{
|
{
|
||||||
struct port_info *pi = netdev_priv(dev);
|
struct port_info *pi = netdev_priv(dev);
|
||||||
struct adapter *adap = pi->adapter;
|
struct adapter *adap = pi->adapter;
|
||||||
@ -3172,15 +3179,16 @@ static const struct net_device_ops cxgb4_netdev_ops = {
|
|||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
static const struct net_device_ops cxgb4_mgmt_netdev_ops = {
|
static const struct net_device_ops cxgb4_mgmt_netdev_ops = {
|
||||||
.ndo_open = dummy_open,
|
.ndo_open = cxgb4_mgmt_open,
|
||||||
.ndo_set_vf_mac = cxgb_set_vf_mac,
|
.ndo_set_vf_mac = cxgb4_mgmt_set_vf_mac,
|
||||||
.ndo_get_vf_config = cxgb_get_vf_config,
|
.ndo_get_vf_config = cxgb4_mgmt_get_vf_config,
|
||||||
.ndo_set_vf_rate = cxgb_set_vf_rate,
|
.ndo_set_vf_rate = cxgb4_mgmt_set_vf_rate,
|
||||||
.ndo_get_phys_port_id = cxgb_get_phys_port_id,
|
.ndo_get_phys_port_id = cxgb4_mgmt_get_phys_port_id,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
static void cxgb4_mgmt_get_drvinfo(struct net_device *dev,
|
||||||
|
struct ethtool_drvinfo *info)
|
||||||
{
|
{
|
||||||
struct adapter *adapter = netdev2adap(dev);
|
struct adapter *adapter = netdev2adap(dev);
|
||||||
|
|
||||||
@ -3192,7 +3200,7 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = {
|
static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = {
|
||||||
.get_drvinfo = get_drvinfo,
|
.get_drvinfo = cxgb4_mgmt_get_drvinfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
void t4_fatal_err(struct adapter *adap)
|
void t4_fatal_err(struct adapter *adap)
|
||||||
@ -4908,7 +4916,7 @@ static int get_chip_type(struct pci_dev *pdev, u32 pl_rev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
static void dummy_setup(struct net_device *dev)
|
static void cxgb4_mgmt_setup(struct net_device *dev)
|
||||||
{
|
{
|
||||||
dev->type = ARPHRD_NONE;
|
dev->type = ARPHRD_NONE;
|
||||||
dev->mtu = 0;
|
dev->mtu = 0;
|
||||||
@ -4924,38 +4932,6 @@ static void dummy_setup(struct net_device *dev)
|
|||||||
dev->needs_free_netdev = true;
|
dev->needs_free_netdev = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int config_mgmt_dev(struct pci_dev *pdev)
|
|
||||||
{
|
|
||||||
struct adapter *adap = pci_get_drvdata(pdev);
|
|
||||||
struct net_device *netdev;
|
|
||||||
struct port_info *pi;
|
|
||||||
char name[IFNAMSIZ];
|
|
||||||
int err;
|
|
||||||
|
|
||||||
snprintf(name, IFNAMSIZ, "mgmtpf%d%d", adap->adap_idx, adap->pf);
|
|
||||||
netdev = alloc_netdev(sizeof(struct port_info), name, NET_NAME_UNKNOWN,
|
|
||||||
dummy_setup);
|
|
||||||
if (!netdev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
pi = netdev_priv(netdev);
|
|
||||||
pi->adapter = adap;
|
|
||||||
pi->tx_chan = adap->pf % adap->params.nports;
|
|
||||||
SET_NETDEV_DEV(netdev, &pdev->dev);
|
|
||||||
|
|
||||||
adap->port[0] = netdev;
|
|
||||||
pi->port_id = 0;
|
|
||||||
|
|
||||||
err = register_netdev(adap->port[0]);
|
|
||||||
if (err) {
|
|
||||||
pr_info("Unable to register VF mgmt netdev %s\n", name);
|
|
||||||
free_netdev(adap->port[0]);
|
|
||||||
adap->port[0] = NULL;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)
|
static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)
|
||||||
{
|
{
|
||||||
struct adapter *adap = pci_get_drvdata(pdev);
|
struct adapter *adap = pci_get_drvdata(pdev);
|
||||||
@ -4967,7 +4943,7 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)
|
|||||||
/* Check if cxgb4 is the MASTER and fw is initialized */
|
/* Check if cxgb4 is the MASTER and fw is initialized */
|
||||||
if (!(pcie_fw & PCIE_FW_INIT_F) ||
|
if (!(pcie_fw & PCIE_FW_INIT_F) ||
|
||||||
!(pcie_fw & PCIE_FW_MASTER_VLD_F) ||
|
!(pcie_fw & PCIE_FW_MASTER_VLD_F) ||
|
||||||
PCIE_FW_MASTER_G(pcie_fw) != 4) {
|
PCIE_FW_MASTER_G(pcie_fw) != CXGB4_UNIFIED_PF) {
|
||||||
dev_warn(&pdev->dev,
|
dev_warn(&pdev->dev,
|
||||||
"cxgb4 driver needs to be MASTER to support SRIOV\n");
|
"cxgb4 driver needs to be MASTER to support SRIOV\n");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@ -4979,46 +4955,132 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)
|
|||||||
if (current_vfs && pci_vfs_assigned(pdev)) {
|
if (current_vfs && pci_vfs_assigned(pdev)) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"Cannot modify SR-IOV while VFs are assigned\n");
|
"Cannot modify SR-IOV while VFs are assigned\n");
|
||||||
num_vfs = current_vfs;
|
return current_vfs;
|
||||||
return num_vfs;
|
|
||||||
}
|
}
|
||||||
|
/* Note that the upper-level code ensures that we're never called with
|
||||||
/* Disable SRIOV when zero is passed.
|
* a non-zero "num_vfs" when we already have VFs instantiated. But
|
||||||
* One needs to disable SRIOV before modifying it, else
|
* it never hurts to code defensively.
|
||||||
* stack throws the below warning:
|
|
||||||
* " 'n' VFs already enabled. Disable before enabling 'm' VFs."
|
|
||||||
*/
|
*/
|
||||||
|
if (num_vfs != 0 && current_vfs != 0)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
/* Nothing to do for no change. */
|
||||||
|
if (num_vfs == current_vfs)
|
||||||
|
return num_vfs;
|
||||||
|
|
||||||
|
/* Disable SRIOV when zero is passed. */
|
||||||
if (!num_vfs) {
|
if (!num_vfs) {
|
||||||
pci_disable_sriov(pdev);
|
pci_disable_sriov(pdev);
|
||||||
if (adap->port[0]) {
|
/* free VF Management Interface */
|
||||||
unregister_netdev(adap->port[0]);
|
unregister_netdev(adap->port[0]);
|
||||||
adap->port[0] = NULL;
|
free_netdev(adap->port[0]);
|
||||||
}
|
adap->port[0] = NULL;
|
||||||
|
|
||||||
/* free VF resources */
|
/* free VF resources */
|
||||||
|
adap->num_vfs = 0;
|
||||||
kfree(adap->vfinfo);
|
kfree(adap->vfinfo);
|
||||||
adap->vfinfo = NULL;
|
adap->vfinfo = NULL;
|
||||||
adap->num_vfs = 0;
|
return 0;
|
||||||
return num_vfs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_vfs != current_vfs) {
|
if (!current_vfs) {
|
||||||
err = pci_enable_sriov(pdev, num_vfs);
|
struct fw_pfvf_cmd port_cmd, port_rpl;
|
||||||
if (err)
|
struct net_device *netdev;
|
||||||
return err;
|
unsigned int pmask, port;
|
||||||
|
struct pci_dev *pbridge;
|
||||||
|
struct port_info *pi;
|
||||||
|
char name[IFNAMSIZ];
|
||||||
|
u32 devcap2;
|
||||||
|
u16 flags;
|
||||||
|
int pos;
|
||||||
|
|
||||||
adap->num_vfs = num_vfs;
|
/* If we want to instantiate Virtual Functions, then our
|
||||||
err = config_mgmt_dev(pdev);
|
* parent bridge's PCI-E needs to support Alternative Routing
|
||||||
|
* ID (ARI) because our VFs will show up at function offset 8
|
||||||
|
* and above.
|
||||||
|
*/
|
||||||
|
pbridge = pdev->bus->self;
|
||||||
|
pos = pci_find_capability(pbridge, PCI_CAP_ID_EXP);
|
||||||
|
pci_read_config_word(pbridge, pos + PCI_EXP_FLAGS, &flags);
|
||||||
|
pci_read_config_dword(pbridge, pos + PCI_EXP_DEVCAP2, &devcap2);
|
||||||
|
|
||||||
|
if ((flags & PCI_EXP_FLAGS_VERS) < 2 ||
|
||||||
|
!(devcap2 & PCI_EXP_DEVCAP2_ARI)) {
|
||||||
|
/* Our parent bridge does not support ARI so issue a
|
||||||
|
* warning and skip instantiating the VFs. They
|
||||||
|
* won't be reachable.
|
||||||
|
*/
|
||||||
|
dev_warn(&pdev->dev, "Parent bridge %02x:%02x.%x doesn't support ARI; can't instantiate Virtual Functions\n",
|
||||||
|
pbridge->bus->number, PCI_SLOT(pbridge->devfn),
|
||||||
|
PCI_FUNC(pbridge->devfn));
|
||||||
|
return -ENOTSUPP;
|
||||||
|
}
|
||||||
|
memset(&port_cmd, 0, sizeof(port_cmd));
|
||||||
|
port_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PFVF_CMD) |
|
||||||
|
FW_CMD_REQUEST_F |
|
||||||
|
FW_CMD_READ_F |
|
||||||
|
FW_PFVF_CMD_PFN_V(adap->pf) |
|
||||||
|
FW_PFVF_CMD_VFN_V(0));
|
||||||
|
port_cmd.retval_len16 = cpu_to_be32(FW_LEN16(port_cmd));
|
||||||
|
err = t4_wr_mbox(adap, adap->mbox, &port_cmd, sizeof(port_cmd),
|
||||||
|
&port_rpl);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
pmask = FW_PFVF_CMD_PMASK_G(be32_to_cpu(port_rpl.type_to_neq));
|
||||||
|
port = ffs(pmask) - 1;
|
||||||
|
/* Allocate VF Management Interface. */
|
||||||
|
snprintf(name, IFNAMSIZ, "mgmtpf%d,%d", adap->adap_idx,
|
||||||
|
adap->pf);
|
||||||
|
netdev = alloc_netdev(sizeof(struct port_info),
|
||||||
|
name, NET_NAME_UNKNOWN, cxgb4_mgmt_setup);
|
||||||
|
if (!netdev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
pi = netdev_priv(netdev);
|
||||||
|
pi->adapter = adap;
|
||||||
|
pi->lport = port;
|
||||||
|
pi->tx_chan = port;
|
||||||
|
SET_NETDEV_DEV(netdev, &pdev->dev);
|
||||||
|
|
||||||
|
adap->port[0] = netdev;
|
||||||
|
pi->port_id = 0;
|
||||||
|
|
||||||
|
err = register_netdev(adap->port[0]);
|
||||||
|
if (err) {
|
||||||
|
pr_info("Unable to register VF mgmt netdev %s\n", name);
|
||||||
|
free_netdev(adap->port[0]);
|
||||||
|
adap->port[0] = NULL;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
/* Allocate and set up VF Information. */
|
||||||
|
adap->vfinfo = kcalloc(pci_sriov_get_totalvfs(pdev),
|
||||||
|
sizeof(struct vf_info), GFP_KERNEL);
|
||||||
|
if (!adap->vfinfo) {
|
||||||
|
unregister_netdev(adap->port[0]);
|
||||||
|
free_netdev(adap->port[0]);
|
||||||
|
adap->port[0] = NULL;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
cxgb4_mgmt_fill_vf_station_mac_addr(adap);
|
||||||
|
}
|
||||||
|
/* Instantiate the requested number of VFs. */
|
||||||
|
err = pci_enable_sriov(pdev, num_vfs);
|
||||||
|
if (err) {
|
||||||
|
pr_info("Unable to instantiate %d VFs\n", num_vfs);
|
||||||
|
if (!current_vfs) {
|
||||||
|
unregister_netdev(adap->port[0]);
|
||||||
|
free_netdev(adap->port[0]);
|
||||||
|
adap->port[0] = NULL;
|
||||||
|
kfree(adap->vfinfo);
|
||||||
|
adap->vfinfo = NULL;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
adap->vfinfo = kcalloc(adap->num_vfs,
|
adap->num_vfs = num_vfs;
|
||||||
sizeof(struct vf_info), GFP_KERNEL);
|
|
||||||
if (adap->vfinfo)
|
|
||||||
fill_vf_station_mac_addr(adap);
|
|
||||||
return num_vfs;
|
return num_vfs;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* CONFIG_PCI_IOV */
|
||||||
|
|
||||||
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
@ -5031,9 +5093,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
u32 whoami, pl_rev;
|
u32 whoami, pl_rev;
|
||||||
enum chip_type chip;
|
enum chip_type chip;
|
||||||
static int adap_idx = 1;
|
static int adap_idx = 1;
|
||||||
#ifdef CONFIG_PCI_IOV
|
|
||||||
u32 v, port_vec;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
|
printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
|
||||||
|
|
||||||
@ -5057,6 +5116,13 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
goto out_disable_device;
|
goto out_disable_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
|
||||||
|
if (!adapter) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_unmap_bar0;
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter->regs = regs;
|
||||||
err = t4_wait_dev_ready(regs);
|
err = t4_wait_dev_ready(regs);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_unmap_bar0;
|
goto out_unmap_bar0;
|
||||||
@ -5067,48 +5133,13 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
chip = get_chip_type(pdev, pl_rev);
|
chip = get_chip_type(pdev, pl_rev);
|
||||||
func = CHELSIO_CHIP_VERSION(chip) <= CHELSIO_T5 ?
|
func = CHELSIO_CHIP_VERSION(chip) <= CHELSIO_T5 ?
|
||||||
SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami);
|
SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami);
|
||||||
if (func != ent->driver_data) {
|
|
||||||
#ifndef CONFIG_PCI_IOV
|
|
||||||
iounmap(regs);
|
|
||||||
#endif
|
|
||||||
pci_disable_device(pdev);
|
|
||||||
pci_save_state(pdev); /* to restore SR-IOV later */
|
|
||||||
goto sriov;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
|
||||||
highdma = true;
|
|
||||||
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
|
||||||
if (err) {
|
|
||||||
dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
|
|
||||||
"coherent allocations\n");
|
|
||||||
goto out_unmap_bar0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
|
|
||||||
if (err) {
|
|
||||||
dev_err(&pdev->dev, "no usable DMA configuration\n");
|
|
||||||
goto out_unmap_bar0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pci_enable_pcie_error_reporting(pdev);
|
|
||||||
pci_set_master(pdev);
|
|
||||||
pci_save_state(pdev);
|
|
||||||
|
|
||||||
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
|
|
||||||
if (!adapter) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto out_unmap_bar0;
|
|
||||||
}
|
|
||||||
adap_idx++;
|
|
||||||
|
|
||||||
adapter->workq = create_singlethread_workqueue("cxgb4");
|
|
||||||
if (!adapter->workq) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto out_free_adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
adapter->pdev = pdev;
|
||||||
|
adapter->pdev_dev = &pdev->dev;
|
||||||
|
adapter->name = pci_name(pdev);
|
||||||
|
adapter->mbox = func;
|
||||||
|
adapter->pf = func;
|
||||||
|
adapter->msg_enable = DFLT_MSG_ENABLE;
|
||||||
adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) +
|
adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) +
|
||||||
(sizeof(struct mbox_cmd) *
|
(sizeof(struct mbox_cmd) *
|
||||||
T4_OS_LOG_MBOX_CMDS),
|
T4_OS_LOG_MBOX_CMDS),
|
||||||
@ -5117,18 +5148,46 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_free_adapter;
|
goto out_free_adapter;
|
||||||
}
|
}
|
||||||
|
spin_lock_init(&adapter->mbox_lock);
|
||||||
|
INIT_LIST_HEAD(&adapter->mlist.list);
|
||||||
|
pci_set_drvdata(pdev, adapter);
|
||||||
|
|
||||||
|
if (func != ent->driver_data) {
|
||||||
|
pci_disable_device(pdev);
|
||||||
|
pci_save_state(pdev); /* to restore SR-IOV later */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||||
|
highdma = true;
|
||||||
|
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
||||||
|
if (err) {
|
||||||
|
dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
|
||||||
|
"coherent allocations\n");
|
||||||
|
goto out_free_adapter;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||||
|
if (err) {
|
||||||
|
dev_err(&pdev->dev, "no usable DMA configuration\n");
|
||||||
|
goto out_free_adapter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_enable_pcie_error_reporting(pdev);
|
||||||
|
pci_set_master(pdev);
|
||||||
|
pci_save_state(pdev);
|
||||||
|
adap_idx++;
|
||||||
|
adapter->workq = create_singlethread_workqueue("cxgb4");
|
||||||
|
if (!adapter->workq) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_free_adapter;
|
||||||
|
}
|
||||||
|
|
||||||
adapter->mbox_log->size = T4_OS_LOG_MBOX_CMDS;
|
adapter->mbox_log->size = T4_OS_LOG_MBOX_CMDS;
|
||||||
|
|
||||||
/* PCI device has been enabled */
|
/* PCI device has been enabled */
|
||||||
adapter->flags |= DEV_ENABLED;
|
adapter->flags |= DEV_ENABLED;
|
||||||
|
|
||||||
adapter->regs = regs;
|
|
||||||
adapter->pdev = pdev;
|
|
||||||
adapter->pdev_dev = &pdev->dev;
|
|
||||||
adapter->name = pci_name(pdev);
|
|
||||||
adapter->mbox = func;
|
|
||||||
adapter->pf = func;
|
|
||||||
adapter->msg_enable = DFLT_MSG_ENABLE;
|
|
||||||
memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
|
memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
|
||||||
|
|
||||||
/* If possible, we use PCIe Relaxed Ordering Attribute to deliver
|
/* 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)
|
|||||||
spin_lock_init(&adapter->stats_lock);
|
spin_lock_init(&adapter->stats_lock);
|
||||||
spin_lock_init(&adapter->tid_release_lock);
|
spin_lock_init(&adapter->tid_release_lock);
|
||||||
spin_lock_init(&adapter->win0_lock);
|
spin_lock_init(&adapter->win0_lock);
|
||||||
spin_lock_init(&adapter->mbox_lock);
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&adapter->mlist.list);
|
|
||||||
|
|
||||||
INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
|
INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
|
||||||
INIT_WORK(&adapter->db_full_task, process_db_full);
|
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)
|
|||||||
setup_fw_sge_queues(adapter);
|
setup_fw_sge_queues(adapter);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sriov:
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
|
||||||
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
|
|
||||||
if (!adapter) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto free_pci_region;
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter->pdev = pdev;
|
|
||||||
adapter->pdev_dev = &pdev->dev;
|
|
||||||
adapter->name = pci_name(pdev);
|
|
||||||
adapter->mbox = func;
|
|
||||||
adapter->pf = func;
|
|
||||||
adapter->regs = regs;
|
|
||||||
adapter->adap_idx = adap_idx;
|
|
||||||
adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) +
|
|
||||||
(sizeof(struct mbox_cmd) *
|
|
||||||
T4_OS_LOG_MBOX_CMDS),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!adapter->mbox_log) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto free_adapter;
|
|
||||||
}
|
|
||||||
spin_lock_init(&adapter->mbox_lock);
|
|
||||||
INIT_LIST_HEAD(&adapter->mlist.list);
|
|
||||||
|
|
||||||
v = FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
|
|
||||||
FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_PORTVEC);
|
|
||||||
err = t4_query_params(adapter, adapter->mbox, adapter->pf, 0, 1,
|
|
||||||
&v, &port_vec);
|
|
||||||
if (err < 0) {
|
|
||||||
dev_err(adapter->pdev_dev, "Could not fetch port params\n");
|
|
||||||
goto free_mbox_log;
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter->params.nports = hweight32(port_vec);
|
|
||||||
pci_set_drvdata(pdev, adapter);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
free_mbox_log:
|
|
||||||
kfree(adapter->mbox_log);
|
|
||||||
free_adapter:
|
|
||||||
kfree(adapter);
|
|
||||||
free_pci_region:
|
|
||||||
iounmap(regs);
|
|
||||||
pci_disable_sriov(pdev);
|
|
||||||
pci_release_regions(pdev);
|
|
||||||
return err;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
out_free_dev:
|
out_free_dev:
|
||||||
free_some_resources(adapter);
|
free_some_resources(adapter);
|
||||||
if (adapter->flags & USING_MSIX)
|
if (adapter->flags & USING_MSIX)
|
||||||
@ -5569,14 +5573,7 @@ static void remove_one(struct pci_dev *pdev)
|
|||||||
}
|
}
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
else {
|
else {
|
||||||
if (adapter->port[0])
|
cxgb4_iov_configure(adapter->pdev, 0);
|
||||||
unregister_netdev(adapter->port[0]);
|
|
||||||
iounmap(adapter->regs);
|
|
||||||
kfree(adapter->vfinfo);
|
|
||||||
kfree(adapter->mbox_log);
|
|
||||||
kfree(adapter);
|
|
||||||
pci_disable_sriov(pdev);
|
|
||||||
pci_release_regions(pdev);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -5620,18 +5617,6 @@ static void shutdown_one(struct pci_dev *pdev)
|
|||||||
if (adapter->flags & FW_OK)
|
if (adapter->flags & FW_OK)
|
||||||
t4_fw_bye(adapter, adapter->mbox);
|
t4_fw_bye(adapter, adapter->mbox);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_PCI_IOV
|
|
||||||
else {
|
|
||||||
if (adapter->port[0])
|
|
||||||
unregister_netdev(adapter->port[0]);
|
|
||||||
iounmap(adapter->regs);
|
|
||||||
kfree(adapter->vfinfo);
|
|
||||||
kfree(adapter->mbox_log);
|
|
||||||
kfree(adapter);
|
|
||||||
pci_disable_sriov(pdev);
|
|
||||||
pci_release_regions(pdev);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_driver cxgb4_driver = {
|
static struct pci_driver cxgb4_driver = {
|
||||||
|
Loading…
Reference in New Issue
Block a user