Skip to content

Commit

Permalink
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jkirsher/next-queue

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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 6, 2019
2 parents ba6223f + 64439f8 commit 9073989
Show file tree
Hide file tree
Showing 12 changed files with 339 additions and 179 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ice/ice_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/ice/ice_controlq.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,17 @@ 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 */
u16 num_rq_entries; /* receive queue depth */
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_ */
154 changes: 94 additions & 60 deletions drivers/net/ethernet/intel/ice/ice_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);

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;
}
if (q_num < 0)
q_num = 0;

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)
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_hw_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 9073989

Please sign in to comment.