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

Commit 9073989a authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2019-05-04

This series contains updates to the ice driver only.

Jesse updated the driver to make more functions consistent in their use
of a local variable for vsi->back.  Updates the driver to use bit fields
when possible to avoid wasting lots of storage space to store single bit
values.  Optimized the driver to be more memory efficient by moving
structure members around that are not in are hot path.

Michal updates the driver to disable the VF if malicious device driver
(MDD) event is detected by the hardware.  Adds checks to validate the
messages coming from the VF driver.  Tightens up the sniffing of the
driver so that transmit traffic so that VF's cannot see what is on other
VSIs.

Tony fixed the driver so that receive stripping state won't change every
time transmit insertion is changed.  Cleanup the __always_unused
attribute, now that the variable is being used.  Fixed the function
which evaluates setting of features to ensure that can evaluate and set
multiple features in a single function call.

Akeem fixes the driver so that we do not attempt to remove a VLAN filter
that does not exist.  Adds support for adding a ethertype based filter
rule on VSI and describe it in a very long run-on sentence. :-)

Bruce cleans up static analysis warnings by removing a local variable
initialization that is not needed.

Brett makes the allocate/deallocate more consistent in all the driver
flows for VSI q_vectors.  In addition, makes setting/getting coalesce
settings more consistent throughout the driver.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ba6223fc 64439f8f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@ extern const char ice_drv_ver[];
#define ICE_MAX_QS_PER_VF		256
#define ICE_MIN_QS_PER_VF		1
#define ICE_DFLT_QS_PER_VF		4
#define ICE_NONQ_VECS_VF		1
#define ICE_MAX_SCATTER_QS_PER_VF	16
#define ICE_MAX_BASE_QS_PER_VF		16
#define ICE_MAX_INTR_PER_VF		65
#define ICE_MIN_INTR_PER_VF		(ICE_MIN_QS_PER_VF + 1)
@@ -253,6 +255,8 @@ struct ice_vsi {

	s16 vf_id;			/* VF ID for SR-IOV VSIs */

	u16 ethtype;			/* Ethernet protocol for pause frame */

	/* RSS config */
	u16 rss_table_size;	/* HW RSS table size */
	u16 rss_size;		/* Allocated RSS queues */
+1 −1
Original line number Diff line number Diff line
@@ -1880,10 +1880,10 @@ void
ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
		    u16 link_speeds_bitmap)
{
	u16 speed = ICE_AQ_LINK_SPEED_UNKNOWN;
	u64 pt_high;
	u64 pt_low;
	int index;
	u16 speed;

	/* We first check with low part of phy_type */
	for (index = 0; index <= ICE_PHY_TYPE_LOW_MAX_INDEX; index++) {
+2 −2
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ struct ice_rq_event_info {
/* Control Queue information */
struct ice_ctl_q_info {
	enum ice_ctl_q qtype;
	enum ice_aq_err rq_last_status;	/* last status on receive queue */
	struct ice_ctl_q_ring rq;	/* receive queue */
	struct ice_ctl_q_ring sq;	/* send queue */
	u32 sq_cmd_timeout;		/* send queue cmd write back timeout */
@@ -86,10 +87,9 @@ struct ice_ctl_q_info {
	u16 num_sq_entries;		/* send queue depth */
	u16 rq_buf_size;		/* receive queue buffer size */
	u16 sq_buf_size;		/* send queue buffer size */
	enum ice_aq_err sq_last_status;	/* last status on send queue */
	struct mutex sq_lock;		/* Send queue lock */
	struct mutex rq_lock;		/* Receive queue lock */
	enum ice_aq_err sq_last_status;	/* last status on send queue */
	enum ice_aq_err rq_last_status;	/* last status on receive queue */
};

#endif /* _ICE_CONTROLQ_H_ */
+94 −60
Original line number Diff line number Diff line
@@ -1251,7 +1251,7 @@ ice_get_settings_link_up(struct ethtool_link_ksettings *ks,
 */
static void
ice_get_settings_link_down(struct ethtool_link_ksettings *ks,
			   struct net_device __always_unused *netdev)
			   struct net_device *netdev)
{
	/* link is down and the driver needs to fall back on
	 * supported PHY types to figure out what info to display
@@ -2254,50 +2254,61 @@ ice_get_rc_coalesce(struct ethtool_coalesce *ec, enum ice_container_type c_type,
	return 0;
}

/**
 * ice_get_q_coalesce - get a queue's ITR/INTRL (coalesce) settings
 * @vsi: VSI associated to the queue for getting ITR/INTRL (coalesce) settings
 * @ec: coalesce settings to program the device with
 * @q_num: update ITR/INTRL (coalesce) settings for this queue number/index
 *
 * Return 0 on success, and negative under the following conditions:
 * 1. Getting Tx or Rx ITR/INTRL (coalesce) settings failed.
 * 2. The q_num passed in is not a valid number/index for Tx and Rx rings.
 */
static int
ice_get_q_coalesce(struct ice_vsi *vsi, struct ethtool_coalesce *ec, int q_num)
{
	if (q_num < vsi->num_rxq && q_num < vsi->num_txq) {
		if (ice_get_rc_coalesce(ec, ICE_RX_CONTAINER,
					&vsi->rx_rings[q_num]->q_vector->rx))
			return -EINVAL;
		if (ice_get_rc_coalesce(ec, ICE_TX_CONTAINER,
					&vsi->tx_rings[q_num]->q_vector->tx))
			return -EINVAL;
	} else if (q_num < vsi->num_rxq) {
		if (ice_get_rc_coalesce(ec, ICE_RX_CONTAINER,
					&vsi->rx_rings[q_num]->q_vector->rx))
			return -EINVAL;
	} else if (q_num < vsi->num_txq) {
		if (ice_get_rc_coalesce(ec, ICE_TX_CONTAINER,
					&vsi->tx_rings[q_num]->q_vector->tx))
			return -EINVAL;
	} else {
		return -EINVAL;
	}

	return 0;
}

/**
 * __ice_get_coalesce - get ITR/INTRL values for the device
 * @netdev: pointer to the netdev associated with this query
 * @ec: ethtool structure to fill with driver's coalesce settings
 * @q_num: queue number to get the coalesce settings for
 *
 * If the caller passes in a negative q_num then we return coalesce settings
 * based on queue number 0, else use the actual q_num passed in.
 */
static int
__ice_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec,
		   int q_num)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	int tx = -EINVAL, rx = -EINVAL;
	struct ice_vsi *vsi = np->vsi;

	if (q_num < 0) {
		rx = ice_get_rc_coalesce(ec, ICE_RX_CONTAINER,
					 &vsi->rx_rings[0]->q_vector->rx);
		tx = ice_get_rc_coalesce(ec, ICE_TX_CONTAINER,
					 &vsi->tx_rings[0]->q_vector->tx);
	if (q_num < 0)
		q_num = 0;

		goto update_coalesced_frames;
	}

	if (q_num < vsi->num_rxq && q_num < vsi->num_txq) {
		rx = ice_get_rc_coalesce(ec, ICE_RX_CONTAINER,
					 &vsi->rx_rings[q_num]->q_vector->rx);
		tx = ice_get_rc_coalesce(ec, ICE_TX_CONTAINER,
					 &vsi->tx_rings[q_num]->q_vector->tx);
	} else if (q_num < vsi->num_rxq) {
		rx = ice_get_rc_coalesce(ec, ICE_RX_CONTAINER,
					 &vsi->rx_rings[q_num]->q_vector->rx);
	} else if (q_num < vsi->num_txq) {
		tx = ice_get_rc_coalesce(ec, ICE_TX_CONTAINER,
					 &vsi->tx_rings[q_num]->q_vector->tx);
	} else {
		/* q_num is invalid for both Rx and Tx queues */
		return -EINVAL;
	}

update_coalesced_frames:
	/* either q_num is invalid for both Rx and Tx queues or setting coalesce
	 * failed completely
	 */
	if (tx && rx)
	if (ice_get_q_coalesce(vsi, ec, q_num))
		return -EINVAL;

	if (q_num < vsi->num_txq)
@@ -2423,54 +2434,77 @@ ice_set_rc_coalesce(enum ice_container_type c_type, struct ethtool_coalesce *ec,
	return 0;
}

/**
 * ice_set_q_coalesce - set a queue's ITR/INTRL (coalesce) settings
 * @vsi: VSI associated to the queue that need updating
 * @ec: coalesce settings to program the device with
 * @q_num: update ITR/INTRL (coalesce) settings for this queue number/index
 *
 * Return 0 on success, and negative under the following conditions:
 * 1. Setting Tx or Rx ITR/INTRL (coalesce) settings failed.
 * 2. The q_num passed in is not a valid number/index for Tx and Rx rings.
 */
static int
ice_set_q_coalesce(struct ice_vsi *vsi, struct ethtool_coalesce *ec, int q_num)
{
	if (q_num < vsi->num_rxq && q_num < vsi->num_txq) {
		if (ice_set_rc_coalesce(ICE_RX_CONTAINER, ec,
					&vsi->rx_rings[q_num]->q_vector->rx,
					vsi))
			return -EINVAL;

		if (ice_set_rc_coalesce(ICE_TX_CONTAINER, ec,
					&vsi->tx_rings[q_num]->q_vector->tx,
					vsi))
			return -EINVAL;
	} else if (q_num < vsi->num_rxq) {
		if (ice_set_rc_coalesce(ICE_RX_CONTAINER, ec,
					&vsi->rx_rings[q_num]->q_vector->rx,
					vsi))
			return -EINVAL;
	} else if (q_num < vsi->num_txq) {
		if (ice_set_rc_coalesce(ICE_TX_CONTAINER, ec,
					&vsi->tx_rings[q_num]->q_vector->tx,
					vsi))
			return -EINVAL;
	} else {
		return -EINVAL;
	}

	return 0;
}

/**
 * __ice_set_coalesce - set ITR/INTRL values for the device
 * @netdev: pointer to the netdev associated with this query
 * @ec: ethtool structure to fill with driver's coalesce settings
 * @q_num: queue number to get the coalesce settings for
 *
 * If the caller passes in a negative q_num then we set the coalesce settings
 * for all Tx/Rx queues, else use the actual q_num passed in.
 */
static int
__ice_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec,
		   int q_num)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	int rx = -EINVAL, tx = -EINVAL;
	struct ice_vsi *vsi = np->vsi;

	if (q_num < 0) {
		int i;

		ice_for_each_q_vector(vsi, i) {
			struct ice_q_vector *q_vector = vsi->q_vectors[i];

			if (ice_set_rc_coalesce(ICE_RX_CONTAINER, ec,
						&q_vector->rx, vsi) ||
			    ice_set_rc_coalesce(ICE_TX_CONTAINER, ec,
						&q_vector->tx, vsi))
			if (ice_set_q_coalesce(vsi, ec, i))
				return -EINVAL;
		}

		goto set_work_lmt;
	}

	if (q_num < vsi->num_rxq && q_num < vsi->num_txq) {
		rx = ice_set_rc_coalesce(ICE_RX_CONTAINER, ec,
					 &vsi->rx_rings[q_num]->q_vector->rx,
					 vsi);
		tx = ice_set_rc_coalesce(ICE_TX_CONTAINER, ec,
					 &vsi->tx_rings[q_num]->q_vector->tx,
					 vsi);
	} else if (q_num < vsi->num_rxq) {
		rx = ice_set_rc_coalesce(ICE_RX_CONTAINER, ec,
					 &vsi->rx_rings[q_num]->q_vector->rx,
					 vsi);
	} else if (q_num < vsi->num_txq) {
		tx  = ice_set_rc_coalesce(ICE_TX_CONTAINER, ec,
					  &vsi->tx_rings[q_num]->q_vector->tx,
					  vsi);
	}

	/* either q_num is invalid for both Rx and Tx queues or setting coalesce
	 * failed completely
	 */
	if (rx && tx)
	if (ice_set_q_coalesce(vsi, ec, q_num))
		return -EINVAL;

set_work_lmt:

	if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
		vsi->work_lmt = max(ec->tx_max_coalesced_frames_irq,
				    ec->rx_max_coalesced_frames_irq);
+4 −0
Original line number Diff line number Diff line
@@ -163,11 +163,15 @@
#define PFINT_OICR_ENA				0x0016C900
#define QINT_RQCTL(_QRX)			(0x00150000 + ((_QRX) * 4))
#define QINT_RQCTL_MSIX_INDX_S			0
#define QINT_RQCTL_MSIX_INDX_M			ICE_M(0x7FF, 0)
#define QINT_RQCTL_ITR_INDX_S			11
#define QINT_RQCTL_ITR_INDX_M			ICE_M(0x3, 11)
#define QINT_RQCTL_CAUSE_ENA_M			BIT(30)
#define QINT_TQCTL(_DBQM)			(0x00140000 + ((_DBQM) * 4))
#define QINT_TQCTL_MSIX_INDX_S			0
#define QINT_TQCTL_MSIX_INDX_M			ICE_M(0x7FF, 0)
#define QINT_TQCTL_ITR_INDX_S			11
#define QINT_TQCTL_ITR_INDX_M			ICE_M(0x3, 11)
#define QINT_TQCTL_CAUSE_ENA_M			BIT(30)
#define VPINT_ALLOC(_VF)			(0x001D1000 + ((_VF) * 4))
#define VPINT_ALLOC_FIRST_S			0
Loading