Commit 09436296 authored by David S. Miller's avatar David S. Miller

Merge branch 'be2net-next'

Sathya Perla says:

====================
be2net: patch set

Patch 1 fixes some minor issues with log messages in be2net.

Patch 2 replaces strcpy() calls with strlcpy() to avoid possible buffer
overflow.

Patch 3 improves the RX buffer posting scheme for jumbo frames.

Patch 4 replaces the use of v0 of SET_FLOW_CONTROL cmd with v1 to receive
a definitive completion status from FW.

Patch 5 adds support for ethtool "-m" ethtool option.

Patch 6 fixes port-type reporting via ethtool get_settings for QSFP/SFP+
interfaces.

Patch 7 fixes the usage of MODIFY_EQD FW cmd to target a max of 8 EQs on
Lancer chip.

Patch 8 enables PCIe error reporting even for VFs.

Pls consider applying this patch set to net-next. Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 233577a2 2f951a9a
...@@ -407,9 +407,9 @@ struct phy_info { ...@@ -407,9 +407,9 @@ struct phy_info {
u16 auto_speeds_supported; u16 auto_speeds_supported;
u16 fixed_speeds_supported; u16 fixed_speeds_supported;
int link_speed; int link_speed;
u32 dac_cable_len;
u32 advertising; u32 advertising;
u32 supported; u32 supported;
u8 cable_type;
}; };
struct be_resources { struct be_resources {
......
...@@ -309,8 +309,6 @@ static void be_async_grp5_evt_process(struct be_adapter *adapter, ...@@ -309,8 +309,6 @@ static void be_async_grp5_evt_process(struct be_adapter *adapter,
be_async_grp5_pvid_state_process(adapter, compl); be_async_grp5_pvid_state_process(adapter, compl);
break; break;
default: default:
dev_warn(&adapter->pdev->dev, "Unknown grp5 event 0x%x!\n",
event_type);
break; break;
} }
} }
...@@ -1772,8 +1770,10 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter) ...@@ -1772,8 +1770,10 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter)
if (!status) { if (!status) {
struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb); struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
strcpy(adapter->fw_ver, resp->firmware_version_string); strlcpy(adapter->fw_ver, resp->firmware_version_string,
strcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string); sizeof(adapter->fw_ver));
strlcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string,
sizeof(adapter->fw_on_flash));
} }
err: err:
spin_unlock_bh(&adapter->mcc_lock); spin_unlock_bh(&adapter->mcc_lock);
...@@ -1783,8 +1783,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter) ...@@ -1783,8 +1783,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter)
/* set the EQ delay interval of an EQ to specified value /* set the EQ delay interval of an EQ to specified value
* Uses async mcc * Uses async mcc
*/ */
int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd, int __be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd,
int num) int num)
{ {
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_cmd_req_modify_eq_delay *req; struct be_cmd_req_modify_eq_delay *req;
...@@ -1817,6 +1817,25 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd, ...@@ -1817,6 +1817,25 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd,
return status; return status;
} }
int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *set_eqd,
int num)
{
int num_eqs, i = 0;
if (lancer_chip(adapter) && num > 8) {
while (num) {
num_eqs = min(num, 8);
__be_cmd_modify_eqd(adapter, &set_eqd[i], num_eqs);
i += num_eqs;
num -= num_eqs;
}
} else {
__be_cmd_modify_eqd(adapter, set_eqd, num);
}
return 0;
}
/* Uses sycnhronous mcc */ /* Uses sycnhronous mcc */
int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
u32 num) u32 num)
...@@ -1948,6 +1967,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) ...@@ -1948,6 +1967,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req), OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req),
wrb, NULL); wrb, NULL);
req->hdr.version = 1;
req->tx_flow_control = cpu_to_le16((u16)tx_fc); req->tx_flow_control = cpu_to_le16((u16)tx_fc);
req->rx_flow_control = cpu_to_le16((u16)rx_fc); req->rx_flow_control = cpu_to_le16((u16)rx_fc);
...@@ -1955,6 +1975,10 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) ...@@ -1955,6 +1975,10 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
err: err:
spin_unlock_bh(&adapter->mcc_lock); spin_unlock_bh(&adapter->mcc_lock);
if (base_status(status) == MCC_STATUS_FEATURE_NOT_SUPPORTED)
return -EOPNOTSUPP;
return status; return status;
} }
...@@ -2171,6 +2195,53 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) ...@@ -2171,6 +2195,53 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
return status; return status;
} }
/* Uses sync mcc */
int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
u8 page_num, u8 *data)
{
struct be_dma_mem cmd;
struct be_mcc_wrb *wrb;
struct be_cmd_req_port_type *req;
int status;
if (page_num > TR_PAGE_A2)
return -EINVAL;
cmd.size = sizeof(struct be_cmd_resp_port_type);
cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
if (!cmd.va) {
dev_err(&adapter->pdev->dev, "Memory allocation failed\n");
return -ENOMEM;
}
memset(cmd.va, 0, cmd.size);
spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
goto err;
}
req = cmd.va;
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_READ_TRANSRECV_DATA,
cmd.size, wrb, &cmd);
req->port = cpu_to_le32(adapter->hba_port_num);
req->page_num = cpu_to_le32(page_num);
status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_port_type *resp = cmd.va;
memcpy(data, resp->page_data, PAGE_DATA_LEN);
}
err:
spin_unlock_bh(&adapter->mcc_lock);
pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
return status;
}
int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, u32 data_size, u32 data_offset,
const char *obj_name, u32 *data_written, const char *obj_name, u32 *data_written,
...@@ -2211,7 +2282,7 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, ...@@ -2211,7 +2282,7 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_dws_cpu_to_le(ctxt, sizeof(req->context));
req->write_offset = cpu_to_le32(data_offset); req->write_offset = cpu_to_le32(data_offset);
strcpy(req->object_name, obj_name); strlcpy(req->object_name, obj_name, sizeof(req->object_name));
req->descriptor_count = cpu_to_le32(1); req->descriptor_count = cpu_to_le32(1);
req->buf_len = cpu_to_le32(data_size); req->buf_len = cpu_to_le32(data_size);
req->addr_low = cpu_to_le32((cmd->dma + req->addr_low = cpu_to_le32((cmd->dma +
...@@ -2244,6 +2315,31 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, ...@@ -2244,6 +2315,31 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
return status; return status;
} }
int be_cmd_query_cable_type(struct be_adapter *adapter)
{
u8 page_data[PAGE_DATA_LEN];
int status;
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
page_data);
if (!status) {
switch (adapter->phy.interface_type) {
case PHY_TYPE_QSFP:
adapter->phy.cable_type =
page_data[QSFP_PLUS_CABLE_TYPE_OFFSET];
break;
case PHY_TYPE_SFP_PLUS_10GB:
adapter->phy.cable_type =
page_data[SFP_PLUS_CABLE_TYPE_OFFSET];
break;
default:
adapter->phy.cable_type = 0;
break;
}
}
return status;
}
int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name) int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
{ {
struct lancer_cmd_req_delete_object *req; struct lancer_cmd_req_delete_object *req;
...@@ -2264,7 +2360,7 @@ int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name) ...@@ -2264,7 +2360,7 @@ int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
OPCODE_COMMON_DELETE_OBJECT, OPCODE_COMMON_DELETE_OBJECT,
sizeof(*req), wrb, NULL); sizeof(*req), wrb, NULL);
strcpy(req->object_name, obj_name); strlcpy(req->object_name, obj_name, sizeof(req->object_name));
status = be_mcc_notify_wait(adapter); status = be_mcc_notify_wait(adapter);
err: err:
......
...@@ -57,7 +57,8 @@ enum mcc_base_status { ...@@ -57,7 +57,8 @@ enum mcc_base_status {
MCC_STATUS_ILLEGAL_FIELD = 3, MCC_STATUS_ILLEGAL_FIELD = 3,
MCC_STATUS_INSUFFICIENT_BUFFER = 4, MCC_STATUS_INSUFFICIENT_BUFFER = 4,
MCC_STATUS_UNAUTHORIZED_REQUEST = 5, MCC_STATUS_UNAUTHORIZED_REQUEST = 5,
MCC_STATUS_NOT_SUPPORTED = 66 MCC_STATUS_NOT_SUPPORTED = 66,
MCC_STATUS_FEATURE_NOT_SUPPORTED = 68
}; };
/* Additional status */ /* Additional status */
...@@ -1013,28 +1014,23 @@ enum { ...@@ -1013,28 +1014,23 @@ enum {
TR_PAGE_A2 = 0xa2 TR_PAGE_A2 = 0xa2
}; };
/* From SFF-8436 QSFP+ spec */
#define QSFP_PLUS_CABLE_TYPE_OFFSET 0x83
#define QSFP_PLUS_CR4_CABLE 0x8
#define QSFP_PLUS_SR4_CABLE 0x4
#define QSFP_PLUS_LR4_CABLE 0x2
/* From SFF-8472 spec */
#define SFP_PLUS_SFF_8472_COMP 0x5E
#define SFP_PLUS_CABLE_TYPE_OFFSET 0x8
#define SFP_PLUS_COPPER_CABLE 0x4
#define PAGE_DATA_LEN 256
struct be_cmd_resp_port_type { struct be_cmd_resp_port_type {
struct be_cmd_resp_hdr hdr; struct be_cmd_resp_hdr hdr;
u32 page_num; u32 page_num;
u32 port; u32 port;
struct data { u8 page_data[PAGE_DATA_LEN];
u8 identifier;
u8 identifier_ext;
u8 connector;
u8 transceiver[8];
u8 rsvd0[3];
u8 length_km;
u8 length_hm;
u8 length_om1;
u8 length_om2;
u8 length_cu;
u8 length_cu_m;
u8 vendor_name[16];
u8 rsvd;
u8 vendor_oui[3];
u8 vendor_pn[16];
u8 vendor_rev[4];
} data;
}; };
/******************** Get FW Version *******************/ /******************** Get FW Version *******************/
...@@ -1367,6 +1363,9 @@ enum { ...@@ -1367,6 +1363,9 @@ enum {
PHY_TYPE_BASET_1GB, PHY_TYPE_BASET_1GB,
PHY_TYPE_BASEX_1GB, PHY_TYPE_BASEX_1GB,
PHY_TYPE_SGMII, PHY_TYPE_SGMII,
PHY_TYPE_QSFP,
PHY_TYPE_KR4_40GB,
PHY_TYPE_KR2_20GB,
PHY_TYPE_DISABLED = 255 PHY_TYPE_DISABLED = 255
}; };
...@@ -1375,6 +1374,7 @@ enum { ...@@ -1375,6 +1374,7 @@ enum {
#define BE_SUPPORTED_SPEED_100MBPS 2 #define BE_SUPPORTED_SPEED_100MBPS 2
#define BE_SUPPORTED_SPEED_1GBPS 4 #define BE_SUPPORTED_SPEED_1GBPS 4
#define BE_SUPPORTED_SPEED_10GBPS 8 #define BE_SUPPORTED_SPEED_10GBPS 8
#define BE_SUPPORTED_SPEED_40GBPS 0x20
#define BE_AN_EN 0x2 #define BE_AN_EN 0x2
#define BE_PAUSE_SYM_EN 0x80 #define BE_PAUSE_SYM_EN 0x80
...@@ -2066,6 +2066,9 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon, ...@@ -2066,6 +2066,9 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon,
u8 status, u8 state); u8 status, u8 state);
int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num,
u32 *state); u32 *state);
int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
u8 page_num, u8 *data);
int be_cmd_query_cable_type(struct be_adapter *adapter);
int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 flash_oper, u32 flash_opcode, u32 buf_size); u32 flash_oper, u32 flash_opcode, u32 buf_size);
int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
......
...@@ -475,18 +475,27 @@ static int be_get_sset_count(struct net_device *netdev, int stringset) ...@@ -475,18 +475,27 @@ static int be_get_sset_count(struct net_device *netdev, int stringset)
} }
} }
static u32 be_get_port_type(u32 phy_type, u32 dac_cable_len) static u32 be_get_port_type(struct be_adapter *adapter)
{ {
u32 port; u32 port;
switch (phy_type) { switch (adapter->phy.interface_type) {
case PHY_TYPE_BASET_1GB: case PHY_TYPE_BASET_1GB:
case PHY_TYPE_BASEX_1GB: case PHY_TYPE_BASEX_1GB:
case PHY_TYPE_SGMII: case PHY_TYPE_SGMII:
port = PORT_TP; port = PORT_TP;
break; break;
case PHY_TYPE_SFP_PLUS_10GB: case PHY_TYPE_SFP_PLUS_10GB:
port = dac_cable_len ? PORT_DA : PORT_FIBRE; if (adapter->phy.cable_type & SFP_PLUS_COPPER_CABLE)
port = PORT_DA;
else
port = PORT_FIBRE;
break;
case PHY_TYPE_QSFP:
if (adapter->phy.cable_type & QSFP_PLUS_CR4_CABLE)
port = PORT_DA;
else
port = PORT_FIBRE;
break; break;
case PHY_TYPE_XFP_10GB: case PHY_TYPE_XFP_10GB:
case PHY_TYPE_SFP_1GB: case PHY_TYPE_SFP_1GB:
...@@ -502,11 +511,11 @@ static u32 be_get_port_type(u32 phy_type, u32 dac_cable_len) ...@@ -502,11 +511,11 @@ static u32 be_get_port_type(u32 phy_type, u32 dac_cable_len)
return port; return port;
} }
static u32 convert_to_et_setting(u32 if_type, u32 if_speeds) static u32 convert_to_et_setting(struct be_adapter *adapter, u32 if_speeds)
{ {
u32 val = 0; u32 val = 0;
switch (if_type) { switch (adapter->phy.interface_type) {
case PHY_TYPE_BASET_1GB: case PHY_TYPE_BASET_1GB:
case PHY_TYPE_BASEX_1GB: case PHY_TYPE_BASEX_1GB:
case PHY_TYPE_SGMII: case PHY_TYPE_SGMII:
...@@ -529,6 +538,20 @@ static u32 convert_to_et_setting(u32 if_type, u32 if_speeds) ...@@ -529,6 +538,20 @@ static u32 convert_to_et_setting(u32 if_type, u32 if_speeds)
val |= SUPPORTED_Backplane | val |= SUPPORTED_Backplane |
SUPPORTED_10000baseKR_Full; SUPPORTED_10000baseKR_Full;
break; break;
case PHY_TYPE_QSFP:
if (if_speeds & BE_SUPPORTED_SPEED_40GBPS) {
switch (adapter->phy.cable_type) {
case QSFP_PLUS_CR4_CABLE:
val |= SUPPORTED_40000baseCR4_Full;
break;
case QSFP_PLUS_LR4_CABLE:
val |= SUPPORTED_40000baseLR4_Full;
break;
default:
val |= SUPPORTED_40000baseSR4_Full;
break;
}
}
case PHY_TYPE_SFP_PLUS_10GB: case PHY_TYPE_SFP_PLUS_10GB:
case PHY_TYPE_XFP_10GB: case PHY_TYPE_XFP_10GB:
case PHY_TYPE_SFP_1GB: case PHY_TYPE_SFP_1GB:
...@@ -569,8 +592,6 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -569,8 +592,6 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
int status; int status;
u32 auto_speeds; u32 auto_speeds;
u32 fixed_speeds; u32 fixed_speeds;
u32 dac_cable_len;
u16 interface_type;
if (adapter->phy.link_speed < 0) { if (adapter->phy.link_speed < 0) {
status = be_cmd_link_status_query(adapter, &link_speed, status = be_cmd_link_status_query(adapter, &link_speed,
...@@ -581,21 +602,19 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -581,21 +602,19 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
status = be_cmd_get_phy_info(adapter); status = be_cmd_get_phy_info(adapter);
if (!status) { if (!status) {
interface_type = adapter->phy.interface_type;
auto_speeds = adapter->phy.auto_speeds_supported; auto_speeds = adapter->phy.auto_speeds_supported;
fixed_speeds = adapter->phy.fixed_speeds_supported; fixed_speeds = adapter->phy.fixed_speeds_supported;
dac_cable_len = adapter->phy.dac_cable_len;
be_cmd_query_cable_type(adapter);
ecmd->supported = ecmd->supported =
convert_to_et_setting(interface_type, convert_to_et_setting(adapter,
auto_speeds | auto_speeds |
fixed_speeds); fixed_speeds);
ecmd->advertising = ecmd->advertising =
convert_to_et_setting(interface_type, convert_to_et_setting(adapter, auto_speeds);
auto_speeds);
ecmd->port = be_get_port_type(interface_type, ecmd->port = be_get_port_type(adapter);
dac_cable_len);
if (adapter->phy.auto_speeds_supported) { if (adapter->phy.auto_speeds_supported) {
ecmd->supported |= SUPPORTED_Autoneg; ecmd->supported |= SUPPORTED_Autoneg;
...@@ -676,7 +695,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) ...@@ -676,7 +695,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
status = be_cmd_set_flow_control(adapter, status = be_cmd_set_flow_control(adapter,
adapter->tx_fc, adapter->rx_fc); adapter->tx_fc, adapter->rx_fc);
if (status) if (status)
dev_warn(&adapter->pdev->dev, "Pause param set failed.\n"); dev_warn(&adapter->pdev->dev, "Pause param set failed\n");
return be_cmd_status(status); return be_cmd_status(status);
} }
...@@ -1189,6 +1208,58 @@ static int be_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -1189,6 +1208,58 @@ static int be_set_rxfh(struct net_device *netdev, const u32 *indir,
return 0; return 0;
} }
static int be_get_module_info(struct net_device *netdev,
struct ethtool_modinfo *modinfo)
{
struct be_adapter *adapter = netdev_priv(netdev);
u8 page_data[PAGE_DATA_LEN];
int status;
if (!check_privilege(adapter, MAX_PRIVILEGES))
return -EOPNOTSUPP;
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
page_data);
if (!status) {
if (!page_data[SFP_PLUS_SFF_8472_COMP]) {
modinfo->type = ETH_MODULE_SFF_8079;
modinfo->eeprom_len = PAGE_DATA_LEN;
} else {
modinfo->type = ETH_MODULE_SFF_8472;
modinfo->eeprom_len = 2 * PAGE_DATA_LEN;
}
}
return be_cmd_status(status);
}
static int be_get_module_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *data)
{
struct be_adapter *adapter = netdev_priv(netdev);
int status;
if (!check_privilege(adapter, MAX_PRIVILEGES))
return -EOPNOTSUPP;
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
data);
if (status)
goto err;
if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) {
status = be_cmd_read_port_transceiver_data(adapter,
TR_PAGE_A2,
data +
PAGE_DATA_LEN);
if (status)
goto err;
}
if (eeprom->offset)
memcpy(data, data + eeprom->offset, eeprom->len);
err:
return be_cmd_status(status);
}
const struct ethtool_ops be_ethtool_ops = { const struct ethtool_ops be_ethtool_ops = {
.get_settings = be_get_settings, .get_settings = be_get_settings,
.get_drvinfo = be_get_drvinfo, .get_drvinfo = be_get_drvinfo,
...@@ -1220,5 +1291,7 @@ const struct ethtool_ops be_ethtool_ops = { ...@@ -1220,5 +1291,7 @@ const struct ethtool_ops be_ethtool_ops = {
.get_rxfh = be_get_rxfh, .get_rxfh = be_get_rxfh,
.set_rxfh = be_set_rxfh, .set_rxfh = be_set_rxfh,
.get_channels = be_get_channels, .get_channels = be_get_channels,
.set_channels = be_set_channels .set_channels = be_set_channels,
.get_module_info = be_get_module_info,
.get_module_eeprom = be_get_module_eeprom
}; };
...@@ -1093,6 +1093,7 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -1093,6 +1093,7 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
*/ */
static int be_vid_config(struct be_adapter *adapter) static int be_vid_config(struct be_adapter *adapter)
{ {
struct device *dev = &adapter->pdev->dev;
u16 vids[BE_NUM_VLANS_SUPPORTED]; u16 vids[BE_NUM_VLANS_SUPPORTED];
u16 num = 0, i = 0; u16 num = 0, i = 0;
int status = 0; int status = 0;
...@@ -1114,16 +1115,15 @@ static int be_vid_config(struct be_adapter *adapter) ...@@ -1114,16 +1115,15 @@ static int be_vid_config(struct be_adapter *adapter)
if (addl_status(status) == if (addl_status(status) ==
MCC_ADDL_STATUS_INSUFFICIENT_RESOURCES) MCC_ADDL_STATUS_INSUFFICIENT_RESOURCES)
goto set_vlan_promisc; goto set_vlan_promisc;
dev_err(&adapter->pdev->dev, dev_err(dev, "Setting HW VLAN filtering failed\n");
"Setting HW VLAN filtering failed.\n");
} else { } else {
if (adapter->flags & BE_FLAGS_VLAN_PROMISC) { if (adapter->flags & BE_FLAGS_VLAN_PROMISC) {
/* hw VLAN filtering re-enabled. */ /* hw VLAN filtering re-enabled. */
status = be_cmd_rx_filter(adapter, status = be_cmd_rx_filter(adapter,
BE_FLAGS_VLAN_PROMISC, OFF); BE_FLAGS_VLAN_PROMISC, OFF);
if (!status) { if (!status) {
dev_info(&adapter->pdev->dev, dev_info(dev,
"Disabling VLAN Promiscuous mode.\n"); "Disabling VLAN Promiscuous mode\n");
adapter->flags &= ~BE_FLAGS_VLAN_PROMISC; adapter->flags &= ~BE_FLAGS_VLAN_PROMISC;
} }
} }
...@@ -1137,11 +1137,10 @@ static int be_vid_config(struct be_adapter *adapter) ...@@ -1137,11 +1137,10 @@ static int be_vid_config(struct be_adapter *adapter)
status = be_cmd_rx_filter(adapter, BE_FLAGS_VLAN_PROMISC, ON); status = be_cmd_rx_filter(adapter, BE_FLAGS_VLAN_PROMISC, ON);
if (!status) { if (!status) {
dev_info(&adapter->pdev->dev, "Enable VLAN Promiscuous mode\n"); dev_info(dev, "Enable VLAN Promiscuous mode\n");
adapter->flags |= BE_FLAGS_VLAN_PROMISC; adapter->flags |= BE_FLAGS_VLAN_PROMISC;
} else } else
dev_err(&adapter->pdev->dev, dev_err(dev, "Failed to enable VLAN Promiscuous mode\n");
"Failed to enable VLAN Promiscuous mode.\n");
return status; return status;
} }
...@@ -1853,7 +1852,7 @@ static inline struct page *be_alloc_pages(u32 size, gfp_t gfp) ...@@ -1853,7 +1852,7 @@ static inline struct page *be_alloc_pages(u32 size, gfp_t gfp)
* Allocate a page, split it to fragments of size rx_frag_size and post as * Allocate a page, split it to fragments of size rx_frag_size and post as
* receive buffers to BE * receive buffers to BE
*/ */
static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp) static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp, u32 frags_needed)
{ {
struct be_adapter *adapter = rxo->adapter; struct be_adapter *adapter = rxo->adapter;
struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL; struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL;
...@@ -1862,10 +1861,10 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp) ...@@ -1862,10 +1861,10 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
struct be_eth_rx_d *rxd; struct be_eth_rx_d *rxd;
u64 page_dmaaddr = 0, frag_dmaaddr; u64 page_dmaaddr = 0, frag_dmaaddr;
u32 posted, page_offset = 0; u32 posted, page_offset = 0, notify = 0;
page_info = &rxo->page_info_tbl[rxq->head]; page_info = &rxo->page_info_tbl[rxq->head];
for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { for (posted = 0; posted < frags_needed && !page_info->page; posted++) {
if (!pagep) { if (!pagep) {
pagep = be_alloc_pages(adapter->big_page_size, gfp); pagep = be_alloc_pages(adapter->big_page_size, gfp);
if (unlikely(!pagep)) { if (unlikely(!pagep)) {
...@@ -1921,7 +1920,11 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp) ...@@ -1921,7 +1920,11 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
atomic_add(posted, &rxq->used); atomic_add(posted, &rxq->used);
if (rxo->rx_post_starved) if (rxo->rx_post_starved)
rxo->rx_post_starved = false; rxo->rx_post_starved = false;
be_rxq_notify(adapter, rxq->id, posted); do {
notify = min(256u, posted);
be_rxq_notify(adapter, rxq->id, notify);
posted -= notify;
} while (posted);
} else if (atomic_read(&rxq->used) == 0) { } else if (atomic_read(&rxq->used) == 0) {
/* Let be_worker replenish when memory is available */ /* Let be_worker replenish when memory is available */
rxo->rx_post_starved = true; rxo->rx_post_starved = true;
...@@ -2372,6 +2375,7 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, ...@@ -2372,6 +2375,7 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
struct be_queue_info *rx_cq = &rxo->cq; struct be_queue_info *rx_cq = &rxo->cq;
struct be_rx_compl_info *rxcp; struct be_rx_compl_info *rxcp;
u32 work_done; u32 work_done;
u32 frags_consumed = 0;
for (work_done = 0; work_done < budget; work_done++) { for (work_done = 0; work_done < budget; work_done++) {
rxcp = be_rx_compl_get(rxo); rxcp = be_rx_compl_get(rxo);
...@@ -2404,6 +2408,7 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, ...@@ -2404,6 +2408,7 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
be_rx_compl_process(rxo, napi, rxcp); be_rx_compl_process(rxo, napi, rxcp);
loop_continue: loop_continue:
frags_consumed += rxcp->num_rcvd;
be_rx_stats_update(rxo, rxcp); be_rx_stats_update(rxo, rxcp);
} }
...@@ -2415,7 +2420,9 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, ...@@ -2415,7 +2420,9 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
*/ */
if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM && if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM &&
!rxo->rx_post_starved) !rxo->rx_post_starved)
be_post_rx_frags(rxo, GFP_ATOMIC); be_post_rx_frags(rxo, GFP_ATOMIC,
max_t(u32, MAX_RX_POST,
frags_consumed));
} }
return work_done; return work_done;
...@@ -2897,7 +2904,7 @@ static int be_rx_qs_create(struct be_adapter *adapter) ...@@ -2897,7 +2904,7 @@ static int be_rx_qs_create(struct be_adapter *adapter)
/* First time posting */ /* First time posting */
for_all_rx_queues(adapter, rxo, i) for_all_rx_queues(adapter, rxo, i)
be_post_rx_frags(rxo, GFP_KERNEL); be_post_rx_frags(rxo, GFP_KERNEL, MAX_RX_POST);
return 0; return 0;
} }
...@@ -3387,7 +3394,7 @@ static int be_get_sriov_config(struct be_adapter *adapter) ...@@ -3387,7 +3394,7 @@ static int be_get_sriov_config(struct be_adapter *adapter)
if (!be_max_vfs(adapter)) { if (!be_max_vfs(adapter)) {
if (num_vfs) if (num_vfs)
dev_warn(dev, "device doesn't support SRIOV\n"); dev_warn(dev, "SRIOV is disabled. Ignoring num_vfs\n");
adapter->num_vfs = 0; adapter->num_vfs = 0;
return 0; return 0;
} }
...@@ -3661,7 +3668,7 @@ static int be_setup(struct be_adapter *adapter) ...@@ -3661,7 +3668,7 @@ static int be_setup(struct be_adapter *adapter)
dev_info(dev, "FW version is %s\n", adapter->fw_ver); dev_info(dev, "FW version is %s\n", adapter->fw_ver);
if (BE2_chip(adapter) && fw_major_num(adapter->fw_ver) < 4) { if (BE2_chip(adapter) && fw_major_num(adapter->fw_ver) < 4) {
dev_err(dev, "Firmware on card is old(%s), IRQs may not work.", dev_err(dev, "Firmware on card is old(%s), IRQs may not work",
adapter->fw_ver); adapter->fw_ver);
dev_err(dev, "Please upgrade firmware to version >= 4.0\n"); dev_err(dev, "Please upgrade firmware to version >= 4.0\n");
} }
...@@ -4779,7 +4786,7 @@ static void be_worker(struct work_struct *work) ...@@ -4779,7 +4786,7 @@ static void be_worker(struct work_struct *work)
* allocation failures. * allocation failures.
*/ */
if (rxo->rx_post_starved) if (rxo->rx_post_starved)
be_post_rx_frags(rxo, GFP_KERNEL); be_post_rx_frags(rxo, GFP_KERNEL, MAX_RX_POST);
} }
be_eqd_update(adapter); be_eqd_update(adapter);
...@@ -4870,11 +4877,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) ...@@ -4870,11 +4877,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
} }
} }
if (be_physfn(adapter)) { status = pci_enable_pcie_error_reporting(pdev);
status = pci_enable_pcie_error_reporting(pdev); if (!status)
if (!status) dev_info(&pdev->dev, "PCIe error reporting enabled\n");
dev_info(&pdev->dev, "PCIe error reporting enabled\n");
}
status = be_ctrl_init(adapter); status = be_ctrl_init(adapter);
if (status) if (status)
......
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