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