Commit 4e8acb01 authored by Rajesh Borundia's avatar Rajesh Borundia Committed by David S. Miller

qlcnic: configure port on eswitch

o Nic partition capable devices has embedded switch, this needs to support
various features like external switch.
Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarAmit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 251b036a
...@@ -556,6 +556,7 @@ struct qlcnic_recv_context { ...@@ -556,6 +556,7 @@ struct qlcnic_recv_context {
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026 #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026
#define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027 #define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027
#define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028
#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a
#define QLCNIC_RCODE_SUCCESS 0 #define QLCNIC_RCODE_SUCCESS 0
...@@ -1044,7 +1045,7 @@ struct qlcnic_pci_info { ...@@ -1044,7 +1045,7 @@ struct qlcnic_pci_info {
}; };
struct qlcnic_npar_info { struct qlcnic_npar_info {
u16 vlan_id; u16 pvid;
u16 min_bw; u16 min_bw;
u16 max_bw; u16 max_bw;
u8 phy_port; u8 phy_port;
...@@ -1052,11 +1053,13 @@ struct qlcnic_npar_info { ...@@ -1052,11 +1053,13 @@ struct qlcnic_npar_info {
u8 active; u8 active;
u8 enable_pm; u8 enable_pm;
u8 dest_npar; u8 dest_npar;
u8 host_vlan_tag;
u8 promisc_mode;
u8 discard_tagged; u8 discard_tagged;
u8 mac_learning; u8 mac_learning;
u8 mac_anti_spoof;
u8 promisc_mode;
u8 offload_flags;
}; };
struct qlcnic_eswitch { struct qlcnic_eswitch {
u8 port; u8 port;
u8 active_vports; u8 active_vports;
...@@ -1088,7 +1091,6 @@ struct qlcnic_eswitch { ...@@ -1088,7 +1091,6 @@ struct qlcnic_eswitch {
#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW) #define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW)
#define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) #define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES)
#define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) #define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES)
#define IS_VALID_MODE(mode) (mode == 0 || mode == 1)
struct qlcnic_pci_func_cfg { struct qlcnic_pci_func_cfg {
u16 func_type; u16 func_type;
...@@ -1120,12 +1122,16 @@ struct qlcnic_pm_func_cfg { ...@@ -1120,12 +1122,16 @@ struct qlcnic_pm_func_cfg {
struct qlcnic_esw_func_cfg { struct qlcnic_esw_func_cfg {
u16 vlan_id; u16 vlan_id;
u8 op_mode;
u8 op_type;
u8 pci_func; u8 pci_func;
u8 host_vlan_tag; u8 host_vlan_tag;
u8 promisc_mode; u8 promisc_mode;
u8 discard_tagged; u8 discard_tagged;
u8 mac_learning; u8 mac_learning;
u8 reserved; u8 mac_anti_spoof;
u8 offload_flags;
u8 reserved[5];
}; };
#define QLCNIC_STATS_VERSION 1 #define QLCNIC_STATS_VERSION 1
...@@ -1276,8 +1282,10 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8, ...@@ -1276,8 +1282,10 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8,
int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8, int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8,
struct qlcnic_eswitch *); struct qlcnic_eswitch *);
int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8); int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8);
int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8, int qlcnic_config_switch_port(struct qlcnic_adapter *,
u8, u8, u16); struct qlcnic_esw_func_cfg *);
int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *);
int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8); int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8, int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8,
struct __qlcnic_esw_statistics *); struct __qlcnic_esw_statistics *);
......
...@@ -813,9 +813,8 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port, ...@@ -813,9 +813,8 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port,
arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
eswitch->port = arg1 & 0xf; eswitch->port = arg1 & 0xf;
eswitch->active_vports = LSB(arg2); eswitch->max_ucast_filters = LSW(arg2);
eswitch->max_ucast_filters = MSB(arg2); eswitch->max_active_vlans = MSW(arg2) & 0xfff;
eswitch->max_active_vlans = LSB(MSW(arg2));
if (arg1 & BIT_6) if (arg1 & BIT_6)
eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING;
if (arg1 & BIT_7) if (arg1 & BIT_7)
...@@ -943,47 +942,6 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, ...@@ -943,47 +942,6 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
return err; return err;
} }
/* Configure eSwitch port */
int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
int vlan_tagging, u8 discard_tagged, u8 promsc_mode,
u8 mac_learn, u8 pci_func, u16 vlan_id)
{
int err = -EIO;
u32 arg1;
struct qlcnic_eswitch *eswitch;
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return err;
eswitch = &adapter->eswitch[id];
if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE))
return err;
arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0);
arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0);
arg1 |= pci_func << 8;
if (vlan_tagging)
arg1 |= BIT_5 | (vlan_id << 16);
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
arg1,
0,
0,
QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH);
if (err != QLCNIC_RCODE_SUCCESS) {
dev_err(&adapter->pdev->dev,
"Failed to configure eswitch port%d\n", eswitch->port);
} else {
dev_info(&adapter->pdev->dev,
"Configured eSwitch for port %d\n", eswitch->port);
}
return err;
}
int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
...@@ -1108,3 +1066,131 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, ...@@ -1108,3 +1066,131 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
"rx_ctx=%d\n", func_esw, port, rx_tx); "rx_ctx=%d\n", func_esw, port, rx_tx);
return -EIO; return -EIO;
} }
static int
__qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
u32 *arg1, u32 *arg2)
{
int err = -EIO;
u8 pci_func;
pci_func = (*arg1 >> 8);
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
*arg1,
0,
0,
QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG);
if (err == QLCNIC_RCODE_SUCCESS) {
*arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
*arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
dev_info(&adapter->pdev->dev,
"eSwitch port config for pci func%d\n", pci_func);
} else {
dev_err(&adapter->pdev->dev,
"Failed to get eswitch port config%d\n", pci_func);
}
return err;
}
/* Configure eSwitch port
op_mode = 0 for setting default port behavior
op_mode = 1 for setting vlan id
op_mode = 2 for deleting vlan id
op_type = 0 for vlan_id
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;
u32 arg1, arg2 = 0;
u8 pci_func;
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return err;
pci_func = esw_cfg->pci_func;
arg1 = (adapter->npars[pci_func].phy_port & BIT_0);
arg1 |= (pci_func << 8);
if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
return err;
arg1 &= ~(0x0ff << 8);
arg1 |= (pci_func << 8);
arg1 &= ~(BIT_2 | BIT_3);
switch (esw_cfg->op_mode) {
case QLCNIC_PORT_DEFAULTS:
arg1 |= (BIT_4 | BIT_6 | BIT_7);
arg2 |= (BIT_0 | BIT_1);
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
arg2 |= (BIT_2 | BIT_3);
if (!(esw_cfg->discard_tagged))
arg1 &= ~BIT_4;
if (!(esw_cfg->promisc_mode))
arg1 &= ~BIT_6;
if (!(esw_cfg->mac_learning))
arg1 &= ~BIT_7;
if (!(esw_cfg->mac_anti_spoof))
arg2 &= ~BIT_0;
if (!(esw_cfg->offload_flags & BIT_0))
arg2 &= ~(BIT_1 | BIT_2 | BIT_3);
if (!(esw_cfg->offload_flags & BIT_1))
arg2 &= ~BIT_2;
if (!(esw_cfg->offload_flags & BIT_2))
arg2 &= ~BIT_3;
break;
case QLCNIC_ADD_VLAN:
arg1 |= (BIT_2 | BIT_5);
arg1 |= (esw_cfg->vlan_id << 16);
break;
case QLCNIC_DEL_VLAN:
arg1 |= (BIT_3 | BIT_5);
arg1 &= ~(0x0ffff << 16);
default:
return err;
}
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
arg1,
arg2,
0,
QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH);
if (err != QLCNIC_RCODE_SUCCESS) {
dev_err(&adapter->pdev->dev,
"Failed to configure eswitch port%d\n", pci_func);
} else {
dev_info(&adapter->pdev->dev,
"Configured eSwitch for port %d\n", pci_func);
}
return err;
}
int
qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg)
{
u32 arg1, arg2;
u8 phy_port;
if (adapter->op_mode == QLCNIC_MGMT_FUNC)
phy_port = adapter->npars[esw_cfg->pci_func].phy_port;
else
phy_port = adapter->physical_port;
arg1 = phy_port;
arg1 |= (esw_cfg->pci_func << 8);
if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
return -EIO;
esw_cfg->discard_tagged = !!(arg1 & BIT_4);
esw_cfg->host_vlan_tag = !!(arg1 & BIT_5);
esw_cfg->promisc_mode = !!(arg1 & BIT_6);
esw_cfg->mac_learning = !!(arg1 & BIT_7);
esw_cfg->vlan_id = LSW(arg1 >> 16);
esw_cfg->mac_anti_spoof = (arg2 & 0x1);
esw_cfg->offload_flags = ((arg2 >> 1) & 0x7);
return 0;
}
...@@ -775,6 +775,7 @@ struct qlcnic_legacy_intr_set { ...@@ -775,6 +775,7 @@ struct qlcnic_legacy_intr_set {
#define QLCNIC_DRV_OP_MODE 0x1b2170 #define QLCNIC_DRV_OP_MODE 0x1b2170
#define QLCNIC_MSIX_BASE 0x132110 #define QLCNIC_MSIX_BASE 0x132110
#define QLCNIC_MAX_PCI_FUNC 8 #define QLCNIC_MAX_PCI_FUNC 8
#define QLCNIC_MAX_VLAN_FILTERS 64
/* PCI function operational mode */ /* PCI function operational mode */
enum { enum {
...@@ -783,6 +784,12 @@ enum { ...@@ -783,6 +784,12 @@ enum {
QLCNIC_NON_PRIV_FUNC = 2 QLCNIC_NON_PRIV_FUNC = 2
}; };
enum {
QLCNIC_PORT_DEFAULTS = 0,
QLCNIC_ADD_VLAN = 1,
QLCNIC_DEL_VLAN = 2
};
#define QLC_DEV_DRV_DEFAULT 0x11111111 #define QLC_DEV_DRV_DEFAULT 0x11111111
#define LSB(x) ((uint8_t)(x)) #define LSB(x) ((uint8_t)(x))
......
...@@ -506,7 +506,6 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) ...@@ -506,7 +506,6 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
adapter->npars[pfn].active = pci_info[i].active; adapter->npars[pfn].active = pci_info[i].active;
adapter->npars[pfn].type = pci_info[i].type; adapter->npars[pfn].type = pci_info[i].type;
adapter->npars[pfn].phy_port = pci_info[i].default_port; adapter->npars[pfn].phy_port = pci_info[i].default_port;
adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN;
adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
} }
...@@ -757,48 +756,65 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) ...@@ -757,48 +756,65 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->max_rds_rings = MAX_RDS_RINGS; adapter->max_rds_rings = MAX_RDS_RINGS;
} }
static int
qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
struct qlcnic_npar_info *npar, int pci_func)
{
struct qlcnic_esw_func_cfg esw_cfg;
esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS;
esw_cfg.pci_func = pci_func;
esw_cfg.vlan_id = npar->pvid;
esw_cfg.mac_learning = npar->mac_learning;
esw_cfg.discard_tagged = npar->discard_tagged;
esw_cfg.mac_anti_spoof = npar->mac_anti_spoof;
esw_cfg.offload_flags = npar->offload_flags;
esw_cfg.promisc_mode = npar->promisc_mode;
if (qlcnic_config_switch_port(adapter, &esw_cfg))
return -EIO;
esw_cfg.op_mode = QLCNIC_ADD_VLAN;
if (qlcnic_config_switch_port(adapter, &esw_cfg))
return -EIO;
return 0;
}
static int static int
qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
{ {
int i, err = 0; int i, err;
struct qlcnic_npar_info *npar; struct qlcnic_npar_info *npar;
struct qlcnic_info nic_info; struct qlcnic_info nic_info;
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
!adapter->need_fw_reset) !adapter->need_fw_reset || adapter->op_mode != QLCNIC_MGMT_FUNC)
return 0; return 0;
if (adapter->op_mode == QLCNIC_MGMT_FUNC) { /* Set the NPAR config data after FW reset */
/* Set the NPAR config data after FW reset */ for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { npar = &adapter->npars[i];
npar = &adapter->npars[i]; if (npar->type != QLCNIC_TYPE_NIC)
if (npar->type != QLCNIC_TYPE_NIC) continue;
continue; err = qlcnic_get_nic_info(adapter, &nic_info, i);
err = qlcnic_get_nic_info(adapter, &nic_info, i); if (err)
if (err) return err;
goto err_out; nic_info.min_tx_bw = npar->min_bw;
nic_info.min_tx_bw = npar->min_bw; nic_info.max_tx_bw = npar->max_bw;
nic_info.max_tx_bw = npar->max_bw; err = qlcnic_set_nic_info(adapter, &nic_info);
err = qlcnic_set_nic_info(adapter, &nic_info); if (err)
if (err) return err;
goto err_out;
if (npar->enable_pm) {
err = qlcnic_config_port_mirroring(adapter,
npar->dest_npar, 1, i);
if (err)
goto err_out;
} if (npar->enable_pm) {
npar->mac_learning = DEFAULT_MAC_LEARN; err = qlcnic_config_port_mirroring(adapter,
npar->host_vlan_tag = 0; npar->dest_npar, 1, i);
npar->promisc_mode = 0; if (err)
npar->discard_tagged = 0; return err;
npar->vlan_id = 0;
} }
err = qlcnic_reset_eswitch_config(adapter, npar, i);
if (err)
return err;
} }
err_out: return 0;
return err;
} }
static int static int
...@@ -863,12 +879,10 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) ...@@ -863,12 +879,10 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
qlcnic_idc_debug_info(adapter, 1); qlcnic_idc_debug_info(adapter, 1);
qlcnic_check_options(adapter);
if (qlcnic_reset_npar_config(adapter)) if (qlcnic_reset_npar_config(adapter))
goto err_out; goto err_out;
qlcnic_dev_set_npar_ready(adapter); qlcnic_dev_set_npar_ready(adapter);
qlcnic_check_options(adapter);
adapter->need_fw_reset = 0; adapter->need_fw_reset = 0;
qlcnic_release_firmware(adapter); qlcnic_release_firmware(adapter);
...@@ -3082,9 +3096,6 @@ validate_pm_config(struct qlcnic_adapter *adapter, ...@@ -3082,9 +3096,6 @@ validate_pm_config(struct qlcnic_adapter *adapter,
if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
if (!IS_VALID_MODE(pm_cfg[i].action))
return QL_STATUS_INVALID_PARAM;
s_esw_id = adapter->npars[src_pci_func].phy_port; s_esw_id = adapter->npars[src_pci_func].phy_port;
d_esw_id = adapter->npars[dest_pci_func].phy_port; d_esw_id = adapter->npars[dest_pci_func].phy_port;
...@@ -3118,7 +3129,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj, ...@@ -3118,7 +3129,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
return ret; return ret;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = pm_cfg[i].pci_func; pci_func = pm_cfg[i].pci_func;
action = pm_cfg[i].action; action = !!pm_cfg[i].action;
id = adapter->npars[pci_func].phy_port; id = adapter->npars[pci_func].phy_port;
ret = qlcnic_config_port_mirroring(adapter, id, ret = qlcnic_config_port_mirroring(adapter, id,
action, pci_func); action, pci_func);
...@@ -3129,7 +3140,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj, ...@@ -3129,7 +3140,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = pm_cfg[i].pci_func; pci_func = pm_cfg[i].pci_func;
id = adapter->npars[pci_func].phy_port; id = adapter->npars[pci_func].phy_port;
adapter->npars[pci_func].enable_pm = pm_cfg[i].action; adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action;
adapter->npars[pci_func].dest_npar = id; adapter->npars[pci_func].dest_npar = id;
} }
return size; return size;
...@@ -3161,30 +3172,38 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj, ...@@ -3161,30 +3172,38 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj,
static int static int
validate_esw_config(struct qlcnic_adapter *adapter, validate_esw_config(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg, int count) struct qlcnic_esw_func_cfg *esw_cfg, int count)
{ {
u8 pci_func; u8 pci_func;
int i; int i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func; pci_func = esw_cfg[i].pci_func;
if (pci_func >= QLCNIC_MAX_PCI_FUNC) if (pci_func >= QLCNIC_MAX_PCI_FUNC)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
if (adapter->npars[i].type != QLCNIC_TYPE_NIC) if (adapter->op_mode == QLCNIC_MGMT_FUNC)
return QL_STATUS_INVALID_PARAM; if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
return QL_STATUS_INVALID_PARAM;
if (esw_cfg->host_vlan_tag == 1) switch (esw_cfg[i].op_mode) {
case QLCNIC_PORT_DEFAULTS:
break;
case QLCNIC_ADD_VLAN:
if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
if (!esw_cfg[i].op_type)
if (!IS_VALID_MODE(esw_cfg[i].promisc_mode) return QL_STATUS_INVALID_PARAM;
|| !IS_VALID_MODE(esw_cfg[i].host_vlan_tag) break;
|| !IS_VALID_MODE(esw_cfg[i].mac_learning) case QLCNIC_DEL_VLAN:
|| !IS_VALID_MODE(esw_cfg[i].discard_tagged)) if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
return QL_STATUS_INVALID_PARAM;
if (!esw_cfg[i].op_type)
return QL_STATUS_INVALID_PARAM;
break;
default:
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
}
} }
return 0; return 0;
} }
...@@ -3195,8 +3214,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, ...@@ -3195,8 +3214,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg *esw_cfg; struct qlcnic_esw_func_cfg *esw_cfg;
struct qlcnic_npar_info *npar;
int count, rem, i, ret; int count, rem, i, ret;
u8 id, pci_func; u8 pci_func;
count = size / sizeof(struct qlcnic_esw_func_cfg); count = size / sizeof(struct qlcnic_esw_func_cfg);
rem = size % sizeof(struct qlcnic_esw_func_cfg); rem = size % sizeof(struct qlcnic_esw_func_cfg);
...@@ -3209,28 +3229,28 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, ...@@ -3209,28 +3229,28 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
return ret; return ret;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func; if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
id = adapter->npars[pci_func].phy_port; return QL_STATUS_INVALID_PARAM;
ret = qlcnic_config_switch_port(adapter, id,
esw_cfg[i].host_vlan_tag,
esw_cfg[i].discard_tagged,
esw_cfg[i].promisc_mode,
esw_cfg[i].mac_learning,
esw_cfg[i].pci_func,
esw_cfg[i].vlan_id);
if (ret)
return ret;
} }
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func; pci_func = esw_cfg[i].pci_func;
adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode; npar = &adapter->npars[pci_func];
adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning; switch (esw_cfg[i].op_mode) {
adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id; case QLCNIC_PORT_DEFAULTS:
adapter->npars[pci_func].discard_tagged = npar->promisc_mode = esw_cfg[i].promisc_mode;
esw_cfg[i].discard_tagged; npar->mac_learning = esw_cfg[i].mac_learning;
adapter->npars[pci_func].host_vlan_tag = npar->offload_flags = esw_cfg[i].offload_flags;
esw_cfg[i].host_vlan_tag; npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
npar->discard_tagged = esw_cfg[i].discard_tagged;
break;
case QLCNIC_ADD_VLAN:
npar->pvid = esw_cfg[i].vlan_id;
break;
case QLCNIC_DEL_VLAN:
npar->pvid = 0;
break;
}
} }
return size; return size;
...@@ -3243,7 +3263,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj, ...@@ -3243,7 +3263,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
int i; u8 i;
if (size != sizeof(esw_cfg)) if (size != sizeof(esw_cfg))
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
...@@ -3251,12 +3271,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj, ...@@ -3251,12 +3271,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
if (adapter->npars[i].type != QLCNIC_TYPE_NIC) if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
continue; continue;
esw_cfg[i].pci_func = i;
esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag; if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]))
esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode; return QL_STATUS_INVALID_PARAM;
esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged;
esw_cfg[i].vlan_id = adapter->npars[i].vlan_id;
esw_cfg[i].mac_learning = adapter->npars[i].mac_learning;
} }
memcpy(buf, &esw_cfg, size); memcpy(buf, &esw_cfg, size);
...@@ -3580,15 +3597,16 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) ...@@ -3580,15 +3597,16 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
dev_info(dev, "failed to create crb sysfs entry\n"); dev_info(dev, "failed to create crb sysfs entry\n");
if (device_create_bin_file(dev, &bin_attr_mem)) if (device_create_bin_file(dev, &bin_attr_mem))
dev_info(dev, "failed to create mem sysfs entry\n"); dev_info(dev, "failed to create mem sysfs entry\n");
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
adapter->op_mode != QLCNIC_MGMT_FUNC) return;
if (device_create_bin_file(dev, &bin_attr_esw_config))
dev_info(dev, "failed to create esw config sysfs entry");
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return; return;
if (device_create_bin_file(dev, &bin_attr_pci_config)) if (device_create_bin_file(dev, &bin_attr_pci_config))
dev_info(dev, "failed to create pci config sysfs entry"); dev_info(dev, "failed to create pci config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_npar_config)) if (device_create_bin_file(dev, &bin_attr_npar_config))
dev_info(dev, "failed to create npar config sysfs entry"); dev_info(dev, "failed to create npar config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_esw_config))
dev_info(dev, "failed to create esw config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_pm_config)) if (device_create_bin_file(dev, &bin_attr_pm_config))
dev_info(dev, "failed to create pm config sysfs entry"); dev_info(dev, "failed to create pm config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_esw_stats)) if (device_create_bin_file(dev, &bin_attr_esw_stats))
...@@ -3607,12 +3625,13 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) ...@@ -3607,12 +3625,13 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
device_remove_file(dev, &dev_attr_diag_mode); device_remove_file(dev, &dev_attr_diag_mode);
device_remove_bin_file(dev, &bin_attr_crb); device_remove_bin_file(dev, &bin_attr_crb);
device_remove_bin_file(dev, &bin_attr_mem); device_remove_bin_file(dev, &bin_attr_mem);
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
adapter->op_mode != QLCNIC_MGMT_FUNC) return;
device_remove_bin_file(dev, &bin_attr_esw_config);
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return; return;
device_remove_bin_file(dev, &bin_attr_pci_config); device_remove_bin_file(dev, &bin_attr_pci_config);
device_remove_bin_file(dev, &bin_attr_npar_config); device_remove_bin_file(dev, &bin_attr_npar_config);
device_remove_bin_file(dev, &bin_attr_esw_config);
device_remove_bin_file(dev, &bin_attr_pm_config); device_remove_bin_file(dev, &bin_attr_pm_config);
device_remove_bin_file(dev, &bin_attr_esw_stats); device_remove_bin_file(dev, &bin_attr_esw_stats);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment