Commit 015777be authored by David S. Miller's avatar David S. Miller

Merge branch 'be2net-error-recovery-and-bug-fixes'

Sriharsha Basavapatna says:

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

The following patch set contains an error recovery feature and a few
bug fixes. Please consider applying this to the net-next tree. Thanks.

Patch-1 Supports HW error recovery in Skyhawk/BEx adapters
Patch-2 Fixes driver unload to issue function reset FW command
Patch-3 Avoids issuing GET_EXT_FAT_CAPABILITIES command for VFs
Patch-4 Avoids redundant addition of mac address in HW
Patch-5 Fixes mac address collision in some configurations
Patch-6 Updates driver version
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dd0cb7db 368f2f13
......@@ -37,7 +37,7 @@
#include "be_hw.h"
#include "be_roce.h"
#define DRV_VER "11.0.0.0"
#define DRV_VER "11.1.0.0"
#define DRV_NAME "be2net"
#define BE_NAME "Emulex BladeEngine2"
#define BE3_NAME "Emulex BladeEngine3"
......@@ -399,13 +399,13 @@ enum vf_state {
#define BE_FLAGS_PHY_MISCONFIGURED BIT(10)
#define BE_FLAGS_ERR_DETECTION_SCHEDULED BIT(11)
#define BE_FLAGS_OS2BMC BIT(12)
#define BE_FLAGS_TRY_RECOVERY BIT(13)
#define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2
#define MAX_ERR_RECOVERY_RETRY_COUNT 3
#define ERR_DETECTION_DELAY 1000
#define ERR_RECOVERY_RETRY_DELAY 30000
/* Ethtool set_dump flags */
#define LANCER_INITIATE_FW_DUMP 0x1
......@@ -512,6 +512,66 @@ struct be_eth_addr {
unsigned char mac[ETH_ALEN];
};
#define BE_SEC 1000 /* in msec */
#define BE_MIN (60 * BE_SEC) /* in msec */
#define BE_HOUR (60 * BE_MIN) /* in msec */
#define ERR_RECOVERY_MAX_RETRY_COUNT 3
#define ERR_RECOVERY_DETECTION_DELAY BE_SEC
#define ERR_RECOVERY_RETRY_DELAY (30 * BE_SEC)
/* UE-detection-duration in BEx/Skyhawk:
* All PFs must wait for this duration after they detect UE before reading
* SLIPORT_SEMAPHORE register. At the end of this duration, the Firmware
* guarantees that the SLIPORT_SEMAPHORE register is updated to indicate
* if the UE is recoverable.
*/
#define ERR_RECOVERY_UE_DETECT_DURATION BE_SEC
/* Initial idle time (in msec) to elapse after driver load,
* before UE recovery is allowed.
*/
#define ERR_IDLE_HR 24
#define ERR_RECOVERY_IDLE_TIME (ERR_IDLE_HR * BE_HOUR)
/* Time interval (in msec) after which UE recovery can be repeated */
#define ERR_INTERVAL_HR 72
#define ERR_RECOVERY_INTERVAL (ERR_INTERVAL_HR * BE_HOUR)
/* BEx/SH UE recovery state machine */
enum {
ERR_RECOVERY_ST_NONE = 0, /* No Recovery */
ERR_RECOVERY_ST_DETECT = 1, /* UE detection duration */
ERR_RECOVERY_ST_RESET = 2, /* Reset Phase (PF0 only) */
ERR_RECOVERY_ST_PRE_POLL = 3, /* Pre-Poll Phase (all PFs) */
ERR_RECOVERY_ST_REINIT = 4 /* Re-initialize Phase */
};
struct be_error_recovery {
/* Lancer error recovery variables */
u8 recovery_retries;
/* BEx/Skyhawk error recovery variables */
u8 recovery_state;
u16 ue_to_reset_time; /* Time after UE, to soft reset
* the chip - PF0 only
*/
u16 ue_to_poll_time; /* Time after UE, to Restart Polling
* of SLIPORT_SEMAPHORE reg
*/
u16 last_err_code;
bool recovery_supported;
unsigned long probe_time;
unsigned long last_recovery_time;
/* Common to both Lancer & BEx/SH error recovery */
u32 resched_delay;
struct delayed_work err_detection_work;
};
/* Ethtool priv_flags */
#define BE_DISABLE_TPE_RECOVERY 0x1
struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;
......@@ -560,7 +620,6 @@ struct be_adapter {
struct delayed_work work;
u16 work_counter;
struct delayed_work be_err_detection_work;
u8 recovery_retries;
u8 err_flags;
bool pcicfg_mapped; /* pcicfg obtained via pci_iomap() */
......@@ -634,6 +693,9 @@ struct be_adapter {
u32 fat_dump_len;
u16 serial_num[CNTL_SERIAL_NUM_WORDS];
u8 phy_state; /* state of sfp optics (functional, faulted, etc.,) */
u8 dev_mac[ETH_ALEN];
u32 priv_flags; /* ethtool get/set_priv_flags() */
struct be_error_recovery error_recovery;
};
/* Used for defered FW config cmds. Add fields to this struct as reqd */
......@@ -867,6 +929,9 @@ static inline bool is_ipv4_pkt(struct sk_buff *skb)
return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
}
#define be_error_recovering(adapter) \
(adapter->flags & BE_FLAGS_TRY_RECOVERY)
#define BE_ERROR_EEH 1
#define BE_ERROR_UE BIT(1)
#define BE_ERROR_FW BIT(2)
......
......@@ -92,6 +92,11 @@ static struct be_cmd_priv_map cmd_priv_map[] = {
CMD_SUBSYSTEM_COMMON,
BE_PRIV_DEVCFG | BE_PRIV_VHADM
},
{
OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
CMD_SUBSYSTEM_COMMON,
BE_PRIV_DEVCFG
}
};
static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem)
......@@ -705,7 +710,7 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
return 0;
}
static u16 be_POST_stage_get(struct be_adapter *adapter)
u16 be_POST_stage_get(struct be_adapter *adapter)
{
u32 sem;
......@@ -4127,6 +4132,10 @@ int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
struct be_cmd_req_get_ext_fat_caps *req;
int status;
if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
CMD_SUBSYSTEM_COMMON))
return -EPERM;
if (mutex_lock_interruptible(&adapter->mbox_lock))
return -1;
......@@ -4138,7 +4147,7 @@ int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
req = cmd->va;
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_GET_EXT_FAT_CAPABILITES,
OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
cmd->size, wrb, cmd);
req->parameter_type = cpu_to_le32(1);
......@@ -4167,7 +4176,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
req = cmd->va;
memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_SET_EXT_FAT_CAPABILITES,
OPCODE_COMMON_SET_EXT_FAT_CAPABILITIES,
cmd->size, wrb, cmd);
status = be_mcc_notify_wait(adapter);
......@@ -4954,6 +4963,57 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter,
1, domain);
return status;
}
int be_cmd_set_features(struct be_adapter *adapter)
{
struct be_cmd_resp_set_features *resp;
struct be_cmd_req_set_features *req;
struct be_mcc_wrb *wrb;
int status;
if (mutex_lock_interruptible(&adapter->mcc_lock))
return -1;
wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
goto err;
}
req = embedded_payload(wrb);
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_SET_FEATURES,
sizeof(*req), wrb, NULL);
req->features = cpu_to_le32(BE_FEATURE_UE_RECOVERY);
req->parameter_len = cpu_to_le32(sizeof(struct be_req_ue_recovery));
req->parameter.req.uer = cpu_to_le32(BE_UE_RECOVERY_UER_MASK);
status = be_mcc_notify_wait(adapter);
if (status)
goto err;
resp = embedded_payload(wrb);
adapter->error_recovery.ue_to_poll_time =
le16_to_cpu(resp->parameter.resp.ue2rp);
adapter->error_recovery.ue_to_reset_time =
le16_to_cpu(resp->parameter.resp.ue2sr);
adapter->error_recovery.recovery_supported = true;
err:
/* Checking "MCC_STATUS_INVALID_LENGTH" for SKH as FW
* returns this error in older firmware versions
*/
if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST ||
base_status(status) == MCC_STATUS_INVALID_LENGTH)
dev_info(&adapter->pdev->dev,
"Adapter does not support HW error recovery\n");
mutex_unlock(&adapter->mcc_lock);
return status;
}
int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
{
......
......@@ -58,7 +58,8 @@ enum mcc_base_status {
MCC_STATUS_INSUFFICIENT_BUFFER = 4,
MCC_STATUS_UNAUTHORIZED_REQUEST = 5,
MCC_STATUS_NOT_SUPPORTED = 66,
MCC_STATUS_FEATURE_NOT_SUPPORTED = 68
MCC_STATUS_FEATURE_NOT_SUPPORTED = 68,
MCC_STATUS_INVALID_LENGTH = 116
};
/* Additional status */
......@@ -294,8 +295,8 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_PHY_DETAILS 102
#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
#define OPCODE_COMMON_GET_EXT_FAT_CAPABILITES 125
#define OPCODE_COMMON_SET_EXT_FAT_CAPABILITES 126
#define OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES 125
#define OPCODE_COMMON_SET_EXT_FAT_CAPABILITIES 126
#define OPCODE_COMMON_GET_MAC_LIST 147
#define OPCODE_COMMON_SET_MAC_LIST 148
#define OPCODE_COMMON_GET_HSW_CONFIG 152
......@@ -308,6 +309,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_READ_OBJECT 171
#define OPCODE_COMMON_WRITE_OBJECT 172
#define OPCODE_COMMON_DELETE_OBJECT 174
#define OPCODE_COMMON_SET_FEATURES 191
#define OPCODE_COMMON_MANAGE_IFACE_FILTERS 193
#define OPCODE_COMMON_GET_IFACE_LIST 194
#define OPCODE_COMMON_ENABLE_DISABLE_VF 196
......@@ -2315,6 +2317,41 @@ struct be_cmd_resp_get_iface_list {
struct be_if_desc if_desc;
};
/************** Set Features *******************/
#define BE_FEATURE_UE_RECOVERY 0x10
#define BE_UE_RECOVERY_UER_MASK 0x1
struct be_req_ue_recovery {
u32 uer;
u32 rsvd;
};
struct be_cmd_req_set_features {
struct be_cmd_req_hdr hdr;
u32 features;
u32 parameter_len;
union {
struct be_req_ue_recovery req;
u32 rsvd[2];
} parameter;
};
struct be_resp_ue_recovery {
u32 uer;
u16 ue2rp;
u16 ue2sr;
};
struct be_cmd_resp_set_features {
struct be_cmd_resp_hdr hdr;
u32 features;
u32 parameter_len;
union {
struct be_resp_ue_recovery resp;
u32 rsvd[2];
} parameter;
};
/*************** Set logical link ********************/
#define PLINK_ENABLE BIT(0)
#define PLINK_TRACK BIT(8)
......@@ -2343,6 +2380,7 @@ struct be_cmd_req_manage_iface_filters {
u32 cap_control_flags;
} __packed;
u16 be_POST_stage_get(struct be_adapter *adapter);
int be_pci_fnum_get(struct be_adapter *adapter);
int be_fw_wait_ready(struct be_adapter *adapter);
int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
......@@ -2470,3 +2508,4 @@ int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op);
int be_cmd_set_sriov_config(struct be_adapter *adapter,
struct be_resources res, u16 num_vfs,
struct be_resources *vft_res);
int be_cmd_set_features(struct be_adapter *adapter);
......@@ -421,6 +421,10 @@ static void be_get_ethtool_stats(struct net_device *netdev,
}
}
static const char be_priv_flags[][ETH_GSTRING_LEN] = {
"disable-tpe-recovery"
};
static void be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
uint8_t *data)
{
......@@ -454,6 +458,10 @@ static void be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
data += ETH_GSTRING_LEN;
}
break;
case ETH_SS_PRIV_FLAGS:
for (i = 0; i < ARRAY_SIZE(be_priv_flags); i++)
strcpy(data + i * ETH_GSTRING_LEN, be_priv_flags[i]);
break;
}
}
......@@ -468,6 +476,8 @@ static int be_get_sset_count(struct net_device *netdev, int stringset)
return ETHTOOL_STATS_NUM +
adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM +
adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM;
case ETH_SS_PRIV_FLAGS:
return ARRAY_SIZE(be_priv_flags);
default:
return -EINVAL;
}
......@@ -1360,6 +1370,34 @@ static int be_get_module_eeprom(struct net_device *netdev,
return be_cmd_status(status);
}
static u32 be_get_priv_flags(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
return adapter->priv_flags;
}
static int be_set_priv_flags(struct net_device *netdev, u32 flags)
{
struct be_adapter *adapter = netdev_priv(netdev);
bool tpe_old = !!(adapter->priv_flags & BE_DISABLE_TPE_RECOVERY);
bool tpe_new = !!(flags & BE_DISABLE_TPE_RECOVERY);
if (tpe_old != tpe_new) {
if (tpe_new) {
adapter->priv_flags |= BE_DISABLE_TPE_RECOVERY;
dev_info(&adapter->pdev->dev,
"HW error recovery is disabled\n");
} else {
adapter->priv_flags &= ~BE_DISABLE_TPE_RECOVERY;
dev_info(&adapter->pdev->dev,
"HW error recovery is enabled\n");
}
}
return 0;
}
const struct ethtool_ops be_ethtool_ops = {
.get_settings = be_get_settings,
.get_drvinfo = be_get_drvinfo,
......@@ -1373,6 +1411,8 @@ const struct ethtool_ops be_ethtool_ops = {
.get_ringparam = be_get_ringparam,
.get_pauseparam = be_get_pauseparam,
.set_pauseparam = be_set_pauseparam,
.set_priv_flags = be_set_priv_flags,
.get_priv_flags = be_get_priv_flags,
.get_strings = be_get_stat_strings,
.set_phys_id = be_set_phys_id,
.set_dump = be_set_dump,
......
......@@ -32,18 +32,23 @@
#define MPU_EP_CONTROL 0
/********** MPU semphore: used for SH & BE *************/
#define SLIPORT_SOFTRESET_OFFSET 0x5c /* CSR BAR offset */
#define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */
#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */
#define POST_STAGE_MASK 0x0000FFFF
#define POST_ERR_MASK 0x1
#define POST_ERR_SHIFT 31
#define POST_ERR_RECOVERY_CODE_MASK 0xFFF
/* Soft Reset register masks */
#define SLIPORT_SOFTRESET_SR_MASK 0x00000080 /* SR bit */
/* MPU semphore POST stage values */
#define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */
#define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */
#define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */
#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */
#define POST_STAGE_RECOVERABLE_ERR 0xE000 /* Recoverable err detected */
/* Lancer SLIPORT registers */
#define SLIPORT_STATUS_OFFSET 0x404
......
This diff is collapsed.
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