Commit 7a9d645e authored by David S. Miller's avatar David S. Miller

Merge branch 'bnx2x'

Yuval Mintz says:

====================
This series contain several small enhancements - chief among those are
the implementation of ethtool's private flags callback to share information
about the storage offload capabilities of its network interfaces,
and the prevention of a link flap when booting from storage area networks.

Changes from V1:
  - Patch 1, removed trailing whitespaces from private flag strings.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 340611ab 84b6f745
......@@ -1937,6 +1937,8 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
void bnx2x_update_coalesce(struct bnx2x *bp);
int bnx2x_get_cur_phy_idx(struct bnx2x *bp);
bool bnx2x_port_after_undi(struct bnx2x *bp);
static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
int wait)
{
......@@ -2137,6 +2139,8 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
#define ATTN_HARD_WIRED_MASK 0xff00
#define ATTENTION_ID 4
#define IS_MF_STORAGE_ONLY(bp) (IS_MF_STORAGE_SD(bp) || \
IS_MF_FCOE_AFEX(bp))
/* stuff added to make the code fit 80Col */
......
......@@ -2183,6 +2183,8 @@ static int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp)
/* send load request to mcp and analyze response */
static int bnx2x_nic_load_request(struct bnx2x *bp, u32 *load_code)
{
u32 param;
/* init fw_seq */
bp->fw_seq =
(SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
......@@ -2195,9 +2197,13 @@ static int bnx2x_nic_load_request(struct bnx2x *bp, u32 *load_code)
DRV_PULSE_SEQ_MASK);
BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq);
param = DRV_MSG_CODE_LOAD_REQ_WITH_LFA;
if (IS_MF_SD(bp) && bnx2x_port_after_undi(bp))
param |= DRV_MSG_CODE_LOAD_REQ_FORCE_LFA;
/* load request */
(*load_code) = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ,
DRV_MSG_CODE_LOAD_REQ_WITH_LFA);
(*load_code) = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, param);
/* if mcp fails to respond we must abort */
if (!(*load_code)) {
......
......@@ -1921,6 +1921,19 @@ static const char bnx2x_tests_str_arr[BNX2X_NUM_TESTS_SF][ETH_GSTRING_LEN] = {
"link_test (online) "
};
enum {
BNX2X_PRI_FLAG_ISCSI,
BNX2X_PRI_FLAG_FCOE,
BNX2X_PRI_FLAG_STORAGE,
BNX2X_PRI_FLAG_LEN,
};
static const char bnx2x_private_arr[BNX2X_PRI_FLAG_LEN][ETH_GSTRING_LEN] = {
"iSCSI offload support",
"FCoE offload support",
"Storage only interface"
};
static u32 bnx2x_eee_to_adv(u32 eee_adv)
{
u32 modes = 0;
......@@ -2978,32 +2991,47 @@ static int bnx2x_num_stat_queues(struct bnx2x *bp)
static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
{
struct bnx2x *bp = netdev_priv(dev);
int i, num_stats;
int i, num_strings = 0;
switch (stringset) {
case ETH_SS_STATS:
if (is_multi(bp)) {
num_stats = bnx2x_num_stat_queues(bp) *
num_strings = bnx2x_num_stat_queues(bp) *
BNX2X_NUM_Q_STATS;
} else
num_stats = 0;
num_strings = 0;
if (IS_MF_MODE_STAT(bp)) {
for (i = 0; i < BNX2X_NUM_STATS; i++)
if (IS_FUNC_STAT(i))
num_stats++;
num_strings++;
} else
num_stats += BNX2X_NUM_STATS;
num_strings += BNX2X_NUM_STATS;
return num_stats;
return num_strings;
case ETH_SS_TEST:
return BNX2X_NUM_TESTS(bp);
case ETH_SS_PRIV_FLAGS:
return BNX2X_PRI_FLAG_LEN;
default:
return -EINVAL;
}
}
static u32 bnx2x_get_private_flags(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
u32 flags = 0;
flags |= (!(bp->flags & NO_ISCSI_FLAG) ? 1 : 0) << BNX2X_PRI_FLAG_ISCSI;
flags |= (!(bp->flags & NO_FCOE_FLAG) ? 1 : 0) << BNX2X_PRI_FLAG_FCOE;
flags |= (!!IS_MF_STORAGE_ONLY(bp)) << BNX2X_PRI_FLAG_STORAGE;
return flags;
}
static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
......@@ -3045,6 +3073,12 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
start = 4;
memcpy(buf, bnx2x_tests_str_arr + start,
ETH_GSTRING_LEN * BNX2X_NUM_TESTS(bp));
break;
case ETH_SS_PRIV_FLAGS:
memcpy(buf, bnx2x_private_arr,
ETH_GSTRING_LEN * BNX2X_PRI_FLAG_LEN);
break;
}
}
......@@ -3112,11 +3146,6 @@ static int bnx2x_set_phys_id(struct net_device *dev,
return -EAGAIN;
}
if (!bp->port.pmf) {
DP(BNX2X_MSG_ETHTOOL, "Interface is not pmf\n");
return -EOPNOTSUPP;
}
switch (state) {
case ETHTOOL_ID_ACTIVE:
return 1; /* cycle on/off once per second */
......@@ -3445,6 +3474,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
.set_pauseparam = bnx2x_set_pauseparam,
.self_test = bnx2x_self_test,
.get_sset_count = bnx2x_get_sset_count,
.get_priv_flags = bnx2x_get_private_flags,
.get_strings = bnx2x_get_strings,
.set_phys_id = bnx2x_set_phys_id,
.get_ethtool_stats = bnx2x_get_ethtool_stats,
......
......@@ -1323,6 +1323,8 @@ struct drv_func_mb {
#define DRV_MSG_CODE_UNLOAD_SKIP_LINK_RESET 0x00000002
#define DRV_MSG_CODE_LOAD_REQ_WITH_LFA 0x0000100a
#define DRV_MSG_CODE_LOAD_REQ_FORCE_LFA 0x00002000
u32 fw_mb_header;
#define FW_MSG_CODE_MASK 0xffff0000
#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000
......
......@@ -9780,6 +9780,21 @@ static bool bnx2x_prev_is_path_marked(struct bnx2x *bp)
return rc;
}
bool bnx2x_port_after_undi(struct bnx2x *bp)
{
struct bnx2x_prev_path_list *entry;
bool val;
down(&bnx2x_prev_sem);
entry = bnx2x_prev_path_get_entry(bp);
val = !!(entry && (entry->undi & (1 << BP_PORT(bp))));
up(&bnx2x_prev_sem);
return val;
}
static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi)
{
struct bnx2x_prev_path_list *tmp_list;
......@@ -10036,7 +10051,6 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
{
int time_counter = 10;
u32 rc, fw, hw_lock_reg, hw_lock_val;
struct bnx2x_prev_path_list *prev_list;
BNX2X_DEV_INFO("Entering Previous Unload Flow\n");
/* clear hw from errors which may have resulted from an interrupted
......@@ -10107,8 +10121,7 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
}
/* Mark function if its port was used to boot from SAN */
prev_list = bnx2x_prev_path_get_entry(bp);
if (prev_list && (prev_list->undi & (1 << BP_PORT(bp))))
if (bnx2x_port_after_undi(bp))
bp->link_params.feature_config_flags |=
FEATURE_CONFIG_BOOT_FROM_SAN;
......@@ -12747,19 +12760,6 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
return 0;
}
static void bnx2x_eeh_recover(struct bnx2x *bp)
{
u32 val;
mutex_init(&bp->port.phy_mutex);
val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
BNX2X_ERR("BAD MCP validity signature\n");
}
/**
* bnx2x_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
......@@ -12828,6 +12828,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
if (netif_running(dev)) {
BNX2X_ERR("IO slot reset --> driver unload\n");
/* MCP should have been reset; Need to wait for validity */
bnx2x_init_shmem(bp);
if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
u32 v;
......@@ -12886,8 +12890,6 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
rtnl_lock();
bnx2x_eeh_recover(bp);
bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK;
......
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