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

Commit 648d4feb authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to i40e and i40evf.

Kevin updates the i40e and i40evf driver i40e_check_asq_alive() to ensure
the length register offset is non-zero which indicates that the software
has initialized the admin queue.  Also removes PCTYPE definitions which are
now reserved.

Mitch enables descriptor prefetch for rings belonging to the virtual function.
Also configures the VF minimum transmit rate to 50 Mbps rather than 0 which was
be interpreted as no limit at all.  Mitch found in order for the VF to achieve
its programmed transmit rate, we need to set the max credit value to 4.
Lastly fixes a Tx hang and firmware crash that happens after setting the MTU
on a VF by not using the RESETTING state during reinit, this is because
the RESETTING state means that a catastrophic hardware bad thing is happening
and the driver needs to tiptoe around and not use the admin queue or registers.
A reinit is no big deal and we can use the admin queue (and we should) so
do not set the state to RESETTING during reinit to resolve the bug.

Akeem changes the declaration of the transmit and receive rings inside
several loops to eliminate declaring the same ring every time for the
duration of the loop and declares them just once before the loop.  Also fixes
the driver to clear the recovery pending bit if pf_reset fails instead of
falling through the setup process.

Anjali makes a change based on feedback from Ben Hutchings that cmd->data
needs to be reported in ETHTOOL_GRXCLSRLCNT and use a helper function to
calculate the total filter count.

Jesse removes storm control since the storm control features are not apart
of the hardware and were mistakenly left in the code.

Greg changes tx_lpi_status and rx_lpi_status from bool to u32 to avoid
sparse errors.

Shannon adds the clear_pxe AdminQ API call to tell the firmware that the
driver is taking over from PXE.  In addition, relaxes the firmware API
check to allow more flexibility in handling newer NICs and NVMs in the field.

Vasu ensures that FCoE is disabled for MFP modes since it is not supported
by overriding the hardware FCoE capability.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 47162c0b 7e612411
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -534,6 +534,15 @@ static inline bool i40e_rx_is_programming_status(u64 qw)
		(qw >> I40E_RX_PROG_STATUS_DESC_LENGTH_SHIFT);
}

/**
 * i40e_get_fd_cnt_all - get the total FD filter space available
 * @pf: pointer to the pf struct
 **/
static inline int i40e_get_fd_cnt_all(struct i40e_pf *pf)
{
	return pf->hw.fdir_shared_filter_count + pf->fdir_pf_filter_count;
}

/* needed by i40e_ethtool.c */
int i40e_up(struct i40e_vsi *vsi);
void i40e_down(struct i40e_vsi *vsi);
+1 −2
Original line number Diff line number Diff line
@@ -587,8 +587,7 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
	i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
	hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;

	if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
	    hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR) {
	if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
		ret_code = I40E_ERR_FIRMWARE_API_VERSION;
		goto init_adminq_free_arq;
	}
+41 −1
Original line number Diff line number Diff line
@@ -133,7 +133,11 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
 **/
bool i40e_check_asq_alive(struct i40e_hw *hw)
{
	return !!(rd32(hw, hw->aq.asq.len) & I40E_PF_ATQLEN_ATQENABLE_MASK);
	if (hw->aq.asq.len)
		return !!(rd32(hw, hw->aq.asq.len) &
			  I40E_PF_ATQLEN_ATQENABLE_MASK);
	else
		return false;
}

/**
@@ -789,6 +793,9 @@ void i40e_clear_pxe_mode(struct i40e_hw *hw)
{
	u32 reg;

	if (i40e_check_asq_alive(hw))
		i40e_aq_clear_pxe_mode(hw, NULL);

	/* Clear single descriptor fetch/write-back mode */
	reg = rd32(hw, I40E_GLLAN_RCTL_0);

@@ -906,6 +913,33 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)

/* Admin command wrappers */

/**
 * i40e_aq_clear_pxe_mode
 * @hw: pointer to the hw struct
 * @cmd_details: pointer to command details structure or NULL
 *
 * Tell the firmware that the driver is taking over from PXE
 **/
i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
				struct i40e_asq_cmd_details *cmd_details)
{
	i40e_status status;
	struct i40e_aq_desc desc;
	struct i40e_aqc_clear_pxe *cmd =
		(struct i40e_aqc_clear_pxe *)&desc.params.raw;

	i40e_fill_default_direct_cmd_desc(&desc,
					  i40e_aqc_opc_clear_pxe_mode);

	cmd->rx_cnt = 0x2;

	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

	wr32(hw, I40E_GLLAN_RCTL_0, 0x1);

	return status;
}

/**
 * i40e_aq_set_link_restart_an
 * @hw: pointer to the hw struct
@@ -1915,6 +1949,12 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
		}
	}

	/* Software override ensuring FCoE is disabled if npar or mfp
	 * mode because it is not supported in these modes.
	 */
	if (p->npar_enable || p->mfp_mode_1)
		p->fcoe = false;

	/* additional HW specific goodies that might
	 * someday be HW version specific
	 */
+13 −24
Original line number Diff line number Diff line
@@ -633,6 +633,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
				   struct ethtool_stats *stats, u64 *data)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_ring *tx_ring, *rx_ring;
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	int i = 0;
@@ -650,8 +651,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
	}
	rcu_read_lock();
	for (j = 0; j < vsi->num_queue_pairs; j++) {
		struct i40e_ring *tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
		struct i40e_ring *rx_ring;
		tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);

		if (!tx_ring)
			continue;
@@ -1131,8 +1131,7 @@ static int i40e_get_ethtool_fdir_all(struct i40e_pf *pf,
	int cnt = 0;

	/* report total rule count */
	cmd->data = pf->hw.fdir_shared_filter_count +
		    pf->fdir_pf_filter_count;
	cmd->data = i40e_get_fd_cnt_all(pf);

	hlist_for_each_entry_safe(rule, node2,
				  &pf->fdir_filter_list, fdir_node) {
@@ -1166,10 +1165,6 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
	struct i40e_fdir_filter *rule = NULL;
	struct hlist_node *node2;

	/* report total rule count */
	cmd->data = pf->hw.fdir_shared_filter_count +
		    pf->fdir_pf_filter_count;

	hlist_for_each_entry_safe(rule, node2,
				  &pf->fdir_filter_list, fdir_node) {
		if (fsp->location <= rule->fd_id)
@@ -1220,6 +1215,8 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
		break;
	case ETHTOOL_GRXCLSRLCNT:
		cmd->rule_cnt = pf->fdir_pf_active_filters;
		/* report total rule count */
		cmd->data = i40e_get_fd_cnt_all(pf);
		ret = 0;
		break;
	case ETHTOOL_GRXCLSRULE:
@@ -1288,15 +1285,11 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
	case UDP_V4_FLOW:
		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
		case 0:
			hena &=
			~(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
			((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) |
			hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
				  ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
			break;
		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
			hena |=
			(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP)  |
			((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) |
			hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
				  ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
			break;
		default:
@@ -1306,15 +1299,11 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
	case UDP_V6_FLOW:
		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
		case 0:
			hena &=
			~(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
			((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) |
			hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
				  ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
			break;
		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
			hena |=
			(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP)  |
			((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) |
			hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
				 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
			break;
		default:
+9 −10
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
					     struct rtnl_link_stats64 *stats)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_ring *tx_ring, *rx_ring;
	struct i40e_vsi *vsi = np->vsi;
	struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi);
	int i;
@@ -368,7 +369,6 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(

	rcu_read_lock();
	for (i = 0; i < vsi->num_queue_pairs; i++) {
		struct i40e_ring *tx_ring, *rx_ring;
		u64 bytes, packets;
		unsigned int start;

@@ -2415,6 +2415,7 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi)
 **/
static void i40e_vsi_config_dcb_rings(struct i40e_vsi *vsi)
{
	struct i40e_ring *tx_ring, *rx_ring;
	u16 qoffset, qcount;
	int i, n;

@@ -2428,8 +2429,8 @@ static void i40e_vsi_config_dcb_rings(struct i40e_vsi *vsi)
		qoffset = vsi->tc_config.tc_info[n].qoffset;
		qcount = vsi->tc_config.tc_info[n].qcount;
		for (i = qoffset; i < (qoffset + qcount); i++) {
			struct i40e_ring *rx_ring = vsi->rx_rings[i];
			struct i40e_ring *tx_ring = vsi->tx_rings[i];
			rx_ring = vsi->rx_rings[i];
			tx_ring = vsi->tx_rings[i];
			rx_ring->dcb_tc = n;
			tx_ring->dcb_tc = n;
		}
@@ -2567,7 +2568,6 @@ static void i40e_enable_misc_int_causes(struct i40e_hw *hw)
	      I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK |
	      I40E_PFINT_ICR0_ENA_GPIO_MASK          |
	      I40E_PFINT_ICR0_ENA_TIMESYNC_MASK      |
	      I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK  |
	      I40E_PFINT_ICR0_ENA_HMC_ERR_MASK       |
	      I40E_PFINT_ICR0_ENA_VFLR_MASK          |
	      I40E_PFINT_ICR0_ENA_ADMINQ_MASK;
@@ -4711,8 +4711,7 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
	    (pf->flags & I40E_FLAG_FD_SB_ENABLED))
		return;
	fcnt_prog = i40e_get_current_fd_count(pf);
	fcnt_avail = pf->hw.fdir_shared_filter_count +
					       pf->fdir_pf_filter_count;
	fcnt_avail = i40e_get_fd_cnt_all(pf);
	if (fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) {
		if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
		    (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) {
@@ -5368,8 +5367,10 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
	 * because the reset will make them disappear.
	 */
	ret = i40e_pf_reset(hw);
	if (ret)
	if (ret) {
		dev_info(&pf->pdev->dev, "PF reset failed, %d\n", ret);
		goto end_core_reset;
	}
	pf->pfr_count++;

	if (test_bit(__I40E_DOWN, &pf->state))
@@ -5948,14 +5949,12 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi)
 **/
static int i40e_alloc_rings(struct i40e_vsi *vsi)
{
	struct i40e_ring *tx_ring, *rx_ring;
	struct i40e_pf *pf = vsi->back;
	int i;

	/* Set basic values in the rings to be used later during open() */
	for (i = 0; i < vsi->alloc_queue_pairs; i++) {
		struct i40e_ring *tx_ring;
		struct i40e_ring *rx_ring;

		/* allocate space for both Tx and Rx in one shot */
		tx_ring = kzalloc(sizeof(struct i40e_ring) * 2, GFP_KERNEL);
		if (!tx_ring)
Loading