Commit 62c02788 authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2020-05-27

This series contains updates to the ice driver only.

Jesse fixes a number of issues, starting with fixing the remaining
signed versus unsigned comparison issues.  Cleaned up an unused code
define.  Fixed the implementation of the manage MAC write command, to
simplify it by using a simple array to represent the MAC address when
writing it.

Paul fixes the setting of the VF default LAN address, by removing a
check that assumed that the address had been deleted and zeroed.

Surabhi prevents a memory leak on filter management initialization
failures and during queue initialization and buffer allocation failures.

Brett adds additional receive error counters that are reported by
ethtool.  Fixed the enabling and disabling of VLAN stripping when the
PVID has been set.

Evan fixes a race condition between the firmware and software, which can
occur between the admin queue setup and the first command sent.

Marta fixes the driver when XDP transmit rings are destroyed, also make
sure the XDP transmit queues are also destroyed.  Update the statistics
when XDP transmit programs are loaded and packets are sent.  Changed the
number of XDP transmit queues to match the number of receive queues,
instead of matching the number of transmit queues.

Bruce avoids undefined behavior by not writing the 8-bit element
init_q_state with the associated internal-to-hardware field which is
122-bits.

Anirudh (Ani) refactors the receive checksum checks.

Krzysztof notifies the user if the fill queue is not long enough to
prepare all buffers before packet processing starts and allocates the
buffers during the NAPI poll.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1e372dbd 3f0d97cd
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -156,13 +156,11 @@ struct ice_aqc_manage_mac_write {
#define ICE_AQC_MAN_MAC_WR_MC_MAG_EN		BIT(0)
#define ICE_AQC_MAN_MAC_WR_WOL_LAA_PFR_KEEP	BIT(1)
#define ICE_AQC_MAN_MAC_WR_S		6
#define ICE_AQC_MAN_MAC_WR_M		(3 << ICE_AQC_MAN_MAC_WR_S)
#define ICE_AQC_MAN_MAC_WR_M		ICE_M(3, ICE_AQC_MAN_MAC_WR_S)
#define ICE_AQC_MAN_MAC_UPDATE_LAA	0
#define ICE_AQC_MAN_MAC_UPDATE_LAA_WOL	(BIT(0) << ICE_AQC_MAN_MAC_WR_S)
	/* High 16 bits of MAC address in big endian order */
	__be16 sah;
	/* Low 32 bits of MAC address in big endian order */
	__be32 sal;
#define ICE_AQC_MAN_MAC_UPDATE_LAA_WOL	BIT(ICE_AQC_MAN_MAC_WR_S)
	/* byte stream in network order */
	u8 mac_addr[ETH_ALEN];
	__le32 addr_high;
	__le32 addr_low;
};
+26 −13
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
 */
static int __ice_vsi_get_qs_contig(struct ice_qs_cfg *qs_cfg)
{
	int offset, i;
	unsigned int offset, i;

	mutex_lock(qs_cfg->qs_mutex);
	offset = bitmap_find_next_zero_area(qs_cfg->pf_map, qs_cfg->pf_map_size,
@@ -39,7 +39,7 @@ static int __ice_vsi_get_qs_contig(struct ice_qs_cfg *qs_cfg)
 */
static int __ice_vsi_get_qs_sc(struct ice_qs_cfg *qs_cfg)
{
	int i, index = 0;
	unsigned int i, index = 0;

	mutex_lock(qs_cfg->qs_mutex);
	for (i = 0; i < qs_cfg->q_count; i++) {
@@ -281,7 +281,9 @@ ice_setup_tx_ctx(struct ice_ring *ring, struct ice_tlan_ctx *tlan_ctx, u16 pf_q)
 */
int ice_setup_rx_ctx(struct ice_ring *ring)
{
	struct device *dev = ice_pf_to_dev(ring->vsi->back);
	int chain_len = ICE_MAX_CHAINED_RX_BUFS;
	u16 num_bufs = ICE_DESC_UNUSED(ring);
	struct ice_vsi *vsi = ring->vsi;
	u32 rxdid = ICE_RXDID_FLEX_NIC;
	struct ice_rlan_ctx rlan_ctx;
@@ -324,7 +326,7 @@ int ice_setup_rx_ctx(struct ice_ring *ring)
				return err;
			xsk_buff_set_rxq_info(ring->xsk_umem, &ring->xdp_rxq);

			dev_info(ice_pf_to_dev(vsi->back), "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n",
			dev_info(dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n",
				 ring->q_index);
		} else {
			if (!xdp_rxq_info_is_reg(&ring->xdp_rxq))
@@ -408,7 +410,7 @@ int ice_setup_rx_ctx(struct ice_ring *ring)
	/* Absolute queue number out of 2K needs to be passed */
	err = ice_write_rxq_ctx(hw, &rlan_ctx, pf_q);
	if (err) {
		dev_err(ice_pf_to_dev(vsi->back), "Failed to set LAN Rx queue context for absolute Rx queue %d error: %d\n",
		dev_err(dev, "Failed to set LAN Rx queue context for absolute Rx queue %d error: %d\n",
			pf_q, err);
		return -EIO;
	}
@@ -426,13 +428,23 @@ int ice_setup_rx_ctx(struct ice_ring *ring)
	ring->tail = hw->hw_addr + QRX_TAIL(pf_q);
	writel(0, ring->tail);

	err = ring->xsk_umem ?
	      ice_alloc_rx_bufs_zc(ring, ICE_DESC_UNUSED(ring)) :
	      ice_alloc_rx_bufs(ring, ICE_DESC_UNUSED(ring));
	if (ring->xsk_umem) {
		if (!xsk_buff_can_alloc(ring->xsk_umem, num_bufs)) {
			dev_warn(dev, "UMEM does not provide enough addresses to fill %d buffers on Rx ring %d\n",
				 num_bufs, ring->q_index);
			dev_warn(dev, "Change Rx ring/fill queue size to avoid performance issues\n");

			return 0;
		}

		err = ice_alloc_rx_bufs_zc(ring, num_bufs);
		if (err)
		dev_info(ice_pf_to_dev(vsi->back), "Failed allocate some buffers on %sRx ring %d (pf_q %d)\n",
			 ring->xsk_umem ? "UMEM enabled " : "",
			dev_info(dev, "Failed to allocate some buffers on UMEM enabled Rx ring %d (pf_q %d)\n",
				 ring->q_index, pf_q);
		return 0;
	}

	ice_alloc_rx_bufs(ring, num_bufs);

	return 0;
}
@@ -638,6 +650,7 @@ ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_ring *ring,
	struct ice_aqc_add_txqs_perq *txq;
	struct ice_pf *pf = vsi->back;
	u8 buf_len = sizeof(*qg_buf);
	struct ice_hw *hw = &pf->hw;
	enum ice_status status;
	u16 pf_q;
	u8 tc;
@@ -646,13 +659,13 @@ ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_ring *ring,
	ice_setup_tx_ctx(ring, &tlan_ctx, pf_q);
	/* copy context contents into the qg_buf */
	qg_buf->txqs[0].txq_id = cpu_to_le16(pf_q);
	ice_set_ctx((u8 *)&tlan_ctx, qg_buf->txqs[0].txq_ctx,
	ice_set_ctx(hw, (u8 *)&tlan_ctx, qg_buf->txqs[0].txq_ctx,
		    ice_tlan_ctx_info);

	/* init queue specific tail reg. It is referred as
	 * transmit comm scheduler queue doorbell.
	 */
	ring->tail = pf->hw.hw_addr + QTX_COMM_DBELL(pf_q);
	ring->tail = hw->hw_addr + QTX_COMM_DBELL(pf_q);

	if (IS_ENABLED(CONFIG_DCB))
		tc = ring->dcb_tc;
+18 −7
Original line number Diff line number Diff line
@@ -387,6 +387,7 @@ ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, struct ice_sq_cd *cd)
static enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw)
{
	struct ice_switch_info *sw;
	enum ice_status status;

	hw->switch_info = devm_kzalloc(ice_hw_to_dev(hw),
				       sizeof(*hw->switch_info), GFP_KERNEL);
@@ -397,7 +398,12 @@ static enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw)

	INIT_LIST_HEAD(&sw->vsi_list_map_head);

	return ice_init_def_sw_recp(hw);
	status = ice_init_def_sw_recp(hw);
	if (status) {
		devm_kfree(ice_hw_to_dev(hw), hw->switch_info);
		return status;
	}
	return 0;
}

/**
@@ -1092,7 +1098,7 @@ ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,

	rlan_ctx->prefena = 1;

	ice_set_ctx((u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info);
	ice_set_ctx(hw, (u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info);
	return ice_copy_rxq_ctx_to_hw(hw, ctx_buf, rxq_index);
}

@@ -1994,10 +2000,7 @@ ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags,
	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_write);

	cmd->flags = flags;

	/* Prep values for flags, sah, sal */
	cmd->sah = htons(*((const u16 *)mac_addr));
	cmd->sal = htonl(*((const u32 *)(mac_addr + 2)));
	ether_addr_copy(cmd->mac_addr, mac_addr);

	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}
@@ -3196,12 +3199,14 @@ ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)

/**
 * ice_set_ctx - set context bits in packed structure
 * @hw: pointer to the hardware structure
 * @src_ctx:  pointer to a generic non-packed context structure
 * @dest_ctx: pointer to memory for the packed structure
 * @ce_info:  a description of the structure to be transformed
 */
enum ice_status
ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
	    const struct ice_ctx_ele *ce_info)
{
	int f;

@@ -3210,6 +3215,12 @@ ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
		 * using the correct size so that we are correct regardless
		 * of the endianness of the machine.
		 */
		if (ce_info[f].width > (ce_info[f].size_of * BITS_PER_BYTE)) {
			ice_debug(hw, ICE_DBG_QCTX,
				  "Field %d width of %d bits larger than size of %d byte(s) ... skipping write\n",
				  f, ce_info[f].width, ce_info[f].size_of);
			continue;
		}
		switch (ce_info[f].size_of) {
		case sizeof(u8):
			ice_write_byte(src_ctx, dest_ctx, &ce_info[f]);
+2 −1
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading);
void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode);
extern const struct ice_ctx_ele ice_tlan_ctx_info[];
enum ice_status
ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info);
ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
	    const struct ice_ctx_ele *ce_info);

extern struct mutex ice_global_cfg_lock_sw;

+100 −75
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ do { \
	(qinfo)->sq.bal = prefix##_ATQBAL;			\
	(qinfo)->sq.len_mask = prefix##_ATQLEN_ATQLEN_M;	\
	(qinfo)->sq.len_ena_mask = prefix##_ATQLEN_ATQENABLE_M;	\
	(qinfo)->sq.len_crit_mask = prefix##_ATQLEN_ATQCRIT_M;	\
	(qinfo)->sq.head_mask = prefix##_ATQH_ATQH_M;		\
	(qinfo)->rq.head = prefix##_ARQH;			\
	(qinfo)->rq.tail = prefix##_ARQT;			\
@@ -20,6 +21,7 @@ do { \
	(qinfo)->rq.bal = prefix##_ARQBAL;			\
	(qinfo)->rq.len_mask = prefix##_ARQLEN_ARQLEN_M;	\
	(qinfo)->rq.len_ena_mask = prefix##_ARQLEN_ARQENABLE_M;	\
	(qinfo)->rq.len_crit_mask = prefix##_ARQLEN_ARQCRIT_M;	\
	(qinfo)->rq.head_mask = prefix##_ARQH_ARQH_M;		\
} while (0)

@@ -199,7 +201,9 @@ unwind_alloc_rq_bufs:
		cq->rq.r.rq_bi[i].pa = 0;
		cq->rq.r.rq_bi[i].size = 0;
	}
	cq->rq.r.rq_bi = NULL;
	devm_kfree(ice_hw_to_dev(hw), cq->rq.dma_head);
	cq->rq.dma_head = NULL;

	return ICE_ERR_NO_MEMORY;
}
@@ -245,7 +249,9 @@ unwind_alloc_sq_bufs:
		cq->sq.r.sq_bi[i].pa = 0;
		cq->sq.r.sq_bi[i].size = 0;
	}
	cq->sq.r.sq_bi = NULL;
	devm_kfree(ice_hw_to_dev(hw), cq->sq.dma_head);
	cq->sq.dma_head = NULL;

	return ICE_ERR_NO_MEMORY;
}
@@ -304,6 +310,28 @@ ice_cfg_rq_regs(struct ice_hw *hw, struct ice_ctl_q_info *cq)
	return 0;
}

#define ICE_FREE_CQ_BUFS(hw, qi, ring)					\
do {									\
	int i;								\
	/* free descriptors */						\
	if ((qi)->ring.r.ring##_bi)					\
		for (i = 0; i < (qi)->num_##ring##_entries; i++)	\
			if ((qi)->ring.r.ring##_bi[i].pa) {		\
				dmam_free_coherent(ice_hw_to_dev(hw),	\
					(qi)->ring.r.ring##_bi[i].size,	\
					(qi)->ring.r.ring##_bi[i].va,	\
					(qi)->ring.r.ring##_bi[i].pa);	\
					(qi)->ring.r.ring##_bi[i].va = NULL;\
					(qi)->ring.r.ring##_bi[i].pa = 0;\
					(qi)->ring.r.ring##_bi[i].size = 0;\
		}							\
	/* free the buffer info list */					\
	if ((qi)->ring.cmd_buf)						\
		devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf);	\
	/* free DMA head */						\
	devm_kfree(ice_hw_to_dev(hw), (qi)->ring.dma_head);		\
} while (0)

/**
 * ice_init_sq - main initialization routine for Control ATQ
 * @hw: pointer to the hardware structure
@@ -357,6 +385,7 @@ static enum ice_status ice_init_sq(struct ice_hw *hw, struct ice_ctl_q_info *cq)
	goto init_ctrlq_exit;

init_ctrlq_free_rings:
	ICE_FREE_CQ_BUFS(hw, cq, sq);
	ice_free_cq_ring(hw, &cq->sq);

init_ctrlq_exit:
@@ -416,33 +445,13 @@ static enum ice_status ice_init_rq(struct ice_hw *hw, struct ice_ctl_q_info *cq)
	goto init_ctrlq_exit;

init_ctrlq_free_rings:
	ICE_FREE_CQ_BUFS(hw, cq, rq);
	ice_free_cq_ring(hw, &cq->rq);

init_ctrlq_exit:
	return ret_code;
}

#define ICE_FREE_CQ_BUFS(hw, qi, ring)					\
do {									\
	int i;								\
	/* free descriptors */						\
	for (i = 0; i < (qi)->num_##ring##_entries; i++)		\
		if ((qi)->ring.r.ring##_bi[i].pa) {			\
			dmam_free_coherent(ice_hw_to_dev(hw),		\
					   (qi)->ring.r.ring##_bi[i].size,\
					   (qi)->ring.r.ring##_bi[i].va,\
					   (qi)->ring.r.ring##_bi[i].pa);\
			(qi)->ring.r.ring##_bi[i].va = NULL;		\
			(qi)->ring.r.ring##_bi[i].pa = 0;		\
			(qi)->ring.r.ring##_bi[i].size = 0;		\
		}							\
	/* free the buffer info list */					\
	if ((qi)->ring.cmd_buf)						\
		devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf);	\
	/* free DMA head */						\
	devm_kfree(ice_hw_to_dev(hw), (qi)->ring.dma_head);		\
} while (0)

/**
 * ice_shutdown_sq - shutdown the Control ATQ
 * @hw: pointer to the hardware structure
@@ -634,6 +643,50 @@ init_ctrlq_free_sq:
	return ret_code;
}

/**
 * ice_shutdown_ctrlq - shutdown routine for any control queue
 * @hw: pointer to the hardware structure
 * @q_type: specific Control queue type
 *
 * NOTE: this function does not destroy the control queue locks.
 */
static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
{
	struct ice_ctl_q_info *cq;

	switch (q_type) {
	case ICE_CTL_Q_ADMIN:
		cq = &hw->adminq;
		if (ice_check_sq_alive(hw, cq))
			ice_aq_q_shutdown(hw, true);
		break;
	case ICE_CTL_Q_MAILBOX:
		cq = &hw->mailboxq;
		break;
	default:
		return;
	}

	ice_shutdown_sq(hw, cq);
	ice_shutdown_rq(hw, cq);
}

/**
 * ice_shutdown_all_ctrlq - shutdown routine for all control queues
 * @hw: pointer to the hardware structure
 *
 * NOTE: this function does not destroy the control queue locks. The driver
 * may call this at runtime to shutdown and later restart control queues, such
 * as in response to a reset event.
 */
void ice_shutdown_all_ctrlq(struct ice_hw *hw)
{
	/* Shutdown FW admin queue */
	ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);
	/* Shutdown PF-VF Mailbox */
	ice_shutdown_ctrlq(hw, ICE_CTL_Q_MAILBOX);
}

/**
 * ice_init_all_ctrlq - main initialization routine for all control queues
 * @hw: pointer to the hardware structure
@@ -649,17 +702,27 @@ init_ctrlq_free_sq:
 */
enum ice_status ice_init_all_ctrlq(struct ice_hw *hw)
{
	enum ice_status ret_code;
	enum ice_status status;
	u32 retry = 0;

	/* Init FW admin queue */
	ret_code = ice_init_ctrlq(hw, ICE_CTL_Q_ADMIN);
	if (ret_code)
		return ret_code;
	do {
		status = ice_init_ctrlq(hw, ICE_CTL_Q_ADMIN);
		if (status)
			return status;

	ret_code = ice_init_check_adminq(hw);
	if (ret_code)
		return ret_code;
		status = ice_init_check_adminq(hw);
		if (status != ICE_ERR_AQ_FW_CRITICAL)
			break;

		ice_debug(hw, ICE_DBG_AQ_MSG,
			  "Retry Admin Queue init due to FW critical error\n");
		ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);
		msleep(ICE_CTL_Q_ADMIN_INIT_MSEC);
	} while (retry++ < ICE_CTL_Q_ADMIN_INIT_TIMEOUT);

	if (status)
		return status;
	/* Init Mailbox queue */
	return ice_init_ctrlq(hw, ICE_CTL_Q_MAILBOX);
}
@@ -700,50 +763,6 @@ enum ice_status ice_create_all_ctrlq(struct ice_hw *hw)
	return ice_init_all_ctrlq(hw);
}

/**
 * ice_shutdown_ctrlq - shutdown routine for any control queue
 * @hw: pointer to the hardware structure
 * @q_type: specific Control queue type
 *
 * NOTE: this function does not destroy the control queue locks.
 */
static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
{
	struct ice_ctl_q_info *cq;

	switch (q_type) {
	case ICE_CTL_Q_ADMIN:
		cq = &hw->adminq;
		if (ice_check_sq_alive(hw, cq))
			ice_aq_q_shutdown(hw, true);
		break;
	case ICE_CTL_Q_MAILBOX:
		cq = &hw->mailboxq;
		break;
	default:
		return;
	}

	ice_shutdown_sq(hw, cq);
	ice_shutdown_rq(hw, cq);
}

/**
 * ice_shutdown_all_ctrlq - shutdown routine for all control queues
 * @hw: pointer to the hardware structure
 *
 * NOTE: this function does not destroy the control queue locks. The driver
 * may call this at runtime to shutdown and later restart control queues, such
 * as in response to a reset event.
 */
void ice_shutdown_all_ctrlq(struct ice_hw *hw)
{
	/* Shutdown FW admin queue */
	ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);
	/* Shutdown PF-VF Mailbox */
	ice_shutdown_ctrlq(hw, ICE_CTL_Q_MAILBOX);
}

/**
 * ice_destroy_ctrlq_locks - Destroy locks for a control queue
 * @cq: pointer to the control queue
@@ -1042,10 +1061,16 @@ ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,

	/* update the error if time out occurred */
	if (!cmd_completed) {
		if (rd32(hw, cq->rq.len) & cq->rq.len_crit_mask ||
		    rd32(hw, cq->sq.len) & cq->sq.len_crit_mask) {
			ice_debug(hw, ICE_DBG_AQ_MSG, "Critical FW error.\n");
			status = ICE_ERR_AQ_FW_CRITICAL;
		} else {
			ice_debug(hw, ICE_DBG_AQ_MSG,
				  "Control Send Queue Writeback timeout.\n");
			status = ICE_ERR_AQ_TIMEOUT;
		}
	}

sq_send_command_error:
	mutex_unlock(&cq->sq_lock);
Loading