Skip to content

Commit

Permalink
qlcnic: update NIC partition interface routines
Browse files Browse the repository at this point in the history
Refactor 82xx driver to support new adapter
Update routines to support variable number of NIC partitions

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sony Chacko authored and David S. Miller committed Dec 4, 2012
1 parent 2299979 commit bff57d8
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 48 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,7 @@ struct qlcnic_npar_info {
u8 mac_anti_spoof;
u8 promisc_mode;
u8 offload_flags;
u8 pci_func;
};

struct qlcnic_eswitch {
Expand Down
39 changes: 32 additions & 7 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@

#include "qlcnic.h"

static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
{
int i;

for (i = 0; i < adapter->ahw->act_pci_func; i++) {
if (adapter->npars[i].pci_func == pci_func)
return i;
}

return -1;
}

static u32
qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
{
Expand Down Expand Up @@ -817,11 +829,14 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
qlcnic_issue_cmd(adapter, &cmd);
err = cmd.rsp.cmd;

adapter->ahw->act_pci_func = 0;
if (err == QLCNIC_RCODE_SUCCESS) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) {
pci_info->id = le16_to_cpu(npar->id);
pci_info->active = le16_to_cpu(npar->active);
pci_info->type = le16_to_cpu(npar->type);
if (pci_info->type == QLCNIC_TYPE_NIC)
adapter->ahw->act_pci_func++;
pci_info->default_port =
le16_to_cpu(npar->default_port);
pci_info->tx_min_bw =
Expand Down Expand Up @@ -1016,12 +1031,13 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL;
esw_stats->context_id = eswitch;

for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
for (i = 0; i < adapter->ahw->act_pci_func; i++) {
if (adapter->npars[i].phy_port != eswitch)
continue;

memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats))
if (qlcnic_get_port_stats(adapter, adapter->npars[i].pci_func,
rx_tx, &port_stats))
continue;

esw_stats->size = port_stats.size;
Expand Down Expand Up @@ -1120,15 +1136,18 @@ op_type = 1 for port vlan_id
int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg)
{
int err = -EIO;
int err = -EIO, index;
u32 arg1, arg2 = 0;
struct qlcnic_cmd_args cmd;
u8 pci_func;

if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
return err;
pci_func = esw_cfg->pci_func;
arg1 = (adapter->npars[pci_func].phy_port & BIT_0);
index = qlcnic_is_valid_nic_func(adapter, pci_func);
if (index < 0)
return err;
arg1 = (adapter->npars[index].phy_port & BIT_0);
arg1 |= (pci_func << 8);

if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
Expand Down Expand Up @@ -1192,11 +1211,17 @@ qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg)
{
u32 arg1, arg2;
int index;
u8 phy_port;
if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
phy_port = adapter->npars[esw_cfg->pci_func].phy_port;
else

if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) {
index = qlcnic_is_valid_nic_func(adapter, esw_cfg->pci_func);
if (index < 0)
return -EIO;
phy_port = adapter->npars[index].phy_port;
} else {
phy_port = adapter->ahw->physical_port;
}
arg1 = phy_port;
arg1 |= (esw_cfg->pci_func << 8);
if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
Expand Down
97 changes: 56 additions & 41 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
static int qlcnic_vlan_rx_add(struct net_device *, u16);
static int qlcnic_vlan_rx_del(struct net_device *, u16);

#define QLCNIC_IS_TSO_CAPABLE(adapter) \
((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)

/* PCI Device ID Table */
#define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
Expand Down Expand Up @@ -369,19 +372,25 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
iounmap(adapter->ahw->pci_base0);
}

static int
qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{
struct qlcnic_pci_info *pci_info;
int i, ret = 0;
int i, ret = 0, j = 0;
u16 act_pci_func;
u8 pfn;

pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
if (!pci_info)
return -ENOMEM;

ret = qlcnic_get_pci_info(adapter, pci_info);
if (ret)
goto err_pci_info;

act_pci_func = adapter->ahw->act_pci_func;

adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) *
QLCNIC_MAX_PCI_FUNC, GFP_KERNEL);
act_pci_func, GFP_KERNEL);
if (!adapter->npars) {
ret = -ENOMEM;
goto err_pci_info;
Expand All @@ -394,21 +403,25 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
goto err_npars;
}

ret = qlcnic_get_pci_info(adapter, pci_info);
if (ret)
goto err_eswitch;

for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
pfn = pci_info[i].id;

if (pfn >= QLCNIC_MAX_PCI_FUNC) {
ret = QL_STATUS_INVALID_PARAM;
goto err_eswitch;
}
adapter->npars[pfn].active = (u8)pci_info[i].active;
adapter->npars[pfn].type = (u8)pci_info[i].type;
adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port;
adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;

if (!pci_info[i].active ||
(pci_info[i].type != QLCNIC_TYPE_NIC))
continue;

adapter->npars[j].pci_func = pfn;
adapter->npars[j].active = (u8)pci_info[i].active;
adapter->npars[j].type = (u8)pci_info[i].type;
adapter->npars[j].phy_port = (u8)pci_info[i].default_port;
adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
j++;
}

for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
Expand Down Expand Up @@ -436,7 +449,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
u32 ref_count;
int i, ret = 1;
u32 data = QLCNIC_MGMT_FUNC;
void __iomem *priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
struct qlcnic_hardware_context *ahw = adapter->ahw;

/* If other drivers are not in use set their privilege level */
ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
Expand All @@ -445,21 +458,20 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
goto err_lock;

if (qlcnic_config_npars) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
id = i;
if (adapter->npars[i].type != QLCNIC_TYPE_NIC ||
id == adapter->ahw->pci_func)
for (i = 0; i < ahw->act_pci_func; i++) {
id = adapter->npars[i].pci_func;
if (id == ahw->pci_func)
continue;
data |= (qlcnic_config_npars &
QLC_DEV_SET_DRV(0xf, id));
}
} else {
data = readl(priv_op);
data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) |
data = QLCRD32(adapter, QLCNIC_DRV_OP_MODE);
data = (data & ~QLC_DEV_SET_DRV(0xf, ahw->pci_func)) |
(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC,
adapter->ahw->pci_func));
ahw->pci_func));
}
writel(data, priv_op);
QLCWR32(adapter, QLCNIC_DRV_OP_MODE, data);
qlcnic_api_unlock(adapter);
err_lock:
return ret;
Expand Down Expand Up @@ -632,6 +644,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
int err;
struct qlcnic_info nic_info;

memset(&nic_info, 0, sizeof(struct qlcnic_info));
err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func);
if (err)
return err;
Expand Down Expand Up @@ -798,8 +811,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
return err;
}

static int
qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
static int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
{
struct qlcnic_esw_func_cfg esw_cfg;
struct qlcnic_npar_info *npar;
Expand All @@ -808,16 +820,16 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
if (adapter->need_fw_reset)
return 0;

for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
continue;
for (i = 0; i < adapter->ahw->act_pci_func; i++) {
memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg));
esw_cfg.pci_func = i;
esw_cfg.offload_flags = BIT_0;
esw_cfg.pci_func = adapter->npars[i].pci_func;
esw_cfg.mac_override = BIT_0;
esw_cfg.promisc_mode = BIT_0;
if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
esw_cfg.offload_flags |= (BIT_1 | BIT_2);
if (qlcnic_82xx_check(adapter)) {
esw_cfg.offload_flags = BIT_0;
if (QLCNIC_IS_TSO_CAPABLE(adapter))
esw_cfg.offload_flags |= (BIT_1 | BIT_2);
}
if (qlcnic_config_switch_port(adapter, &esw_cfg))
return -EIO;
npar = &adapter->npars[i];
Expand Down Expand Up @@ -855,22 +867,24 @@ qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
return 0;
}

static int
qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
{
int i, err;
struct qlcnic_npar_info *npar;
struct qlcnic_info nic_info;
u8 pci_func;

if (!adapter->need_fw_reset)
return 0;
if (qlcnic_82xx_check(adapter))
if (!adapter->need_fw_reset)
return 0;

/* Set the NPAR config data after FW reset */
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
for (i = 0; i < adapter->ahw->act_pci_func; i++) {
npar = &adapter->npars[i];
if (npar->type != QLCNIC_TYPE_NIC)
continue;
err = qlcnic_get_nic_info(adapter, &nic_info, i);
pci_func = npar->pci_func;
memset(&nic_info, 0, sizeof(struct qlcnic_info));
err = qlcnic_get_nic_info(adapter,
&nic_info, pci_func);
if (err)
return err;
nic_info.min_tx_bw = npar->min_bw;
Expand All @@ -881,11 +895,12 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)

if (npar->enable_pm) {
err = qlcnic_config_port_mirroring(adapter,
npar->dest_npar, 1, i);
npar->dest_npar, 1,
pci_func);
if (err)
return err;
}
err = qlcnic_reset_eswitch_config(adapter, npar, i);
err = qlcnic_reset_eswitch_config(adapter, npar, pci_func);
if (err)
return err;
}
Expand Down

0 comments on commit bff57d8

Please sign in to comment.