Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+68 −3
Original line number Diff line number Diff line
@@ -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)
+63 −3
Original line number Diff line number Diff line
@@ -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)
{
+42 −3
Original line number Diff line number Diff line
@@ -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);
+40 −0
Original line number Diff line number Diff line
@@ -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,
+6 −1
Original line number Diff line number Diff line
@@ -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
Loading