|
@@ -254,8 +254,8 @@ static int i40e_put_lump(struct i40e_lump_tracking *pile, u16 index, u16 id)
|
|
|
|
|
|
/**
|
|
|
* i40e_find_vsi_from_id - searches for the vsi with the given id
|
|
|
- * @pf - the pf structure to search for the vsi
|
|
|
- * @id - id of the vsi it is searching for
|
|
|
+ * @pf: the pf structure to search for the vsi
|
|
|
+ * @id: id of the vsi it is searching for
|
|
|
**/
|
|
|
struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id)
|
|
|
{
|
|
@@ -411,6 +411,7 @@ static void i40e_get_netdev_stats_struct_tx(struct i40e_ring *ring,
|
|
|
/**
|
|
|
* i40e_get_netdev_stats_struct - Get statistics for netdev interface
|
|
|
* @netdev: network interface device structure
|
|
|
+ * @stats: data structure to store statistics
|
|
|
*
|
|
|
* Returns the address of the device statistics structure.
|
|
|
* The statistics are actually updated from the service task.
|
|
@@ -2003,7 +2004,7 @@ struct i40e_new_mac_filter *i40e_next_filter(struct i40e_new_mac_filter *next)
|
|
|
* from firmware
|
|
|
* @count: Number of filters added
|
|
|
* @add_list: return data from fw
|
|
|
- * @head: pointer to first filter in current batch
|
|
|
+ * @add_head: pointer to first filter in current batch
|
|
|
*
|
|
|
* MAC filter entries from list were slated to be added to device. Returns
|
|
|
* number of successful filters. Note that 0 does NOT mean success!
|
|
@@ -2110,6 +2111,7 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
|
|
|
/**
|
|
|
* i40e_aqc_broadcast_filter - Set promiscuous broadcast flags
|
|
|
* @vsi: pointer to the VSI
|
|
|
+ * @vsi_name: the VSI name
|
|
|
* @f: filter data
|
|
|
*
|
|
|
* This function sets or clears the promiscuous broadcast flags for VLAN
|
|
@@ -2816,6 +2818,7 @@ void i40e_vsi_kill_vlan(struct i40e_vsi *vsi, u16 vid)
|
|
|
/**
|
|
|
* i40e_vlan_rx_add_vid - Add a vlan id filter to HW offload
|
|
|
* @netdev: network interface to be adjusted
|
|
|
+ * @proto: unused protocol value
|
|
|
* @vid: vlan id to be added
|
|
|
*
|
|
|
* net_device_ops implementation for adding vlan ids
|
|
@@ -2840,6 +2843,7 @@ static int i40e_vlan_rx_add_vid(struct net_device *netdev,
|
|
|
/**
|
|
|
* i40e_vlan_rx_kill_vid - Remove a vlan id filter from HW offload
|
|
|
* @netdev: network interface to be adjusted
|
|
|
+ * @proto: unused protocol value
|
|
|
* @vid: vlan id to be removed
|
|
|
*
|
|
|
* net_device_ops implementation for removing vlan ids
|
|
@@ -3461,7 +3465,7 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
|
|
|
|
|
|
/**
|
|
|
* i40e_enable_misc_int_causes - enable the non-queue interrupts
|
|
|
- * @hw: ptr to the hardware info
|
|
|
+ * @pf: pointer to private device data structure
|
|
|
**/
|
|
|
static void i40e_enable_misc_int_causes(struct i40e_pf *pf)
|
|
|
{
|
|
@@ -4231,8 +4235,8 @@ static void i40e_control_tx_q(struct i40e_pf *pf, int pf_q, bool enable)
|
|
|
* @is_xdp: true if the queue is used for XDP
|
|
|
* @enable: start or stop the queue
|
|
|
**/
|
|
|
-static int i40e_control_wait_tx_q(int seid, struct i40e_pf *pf, int pf_q,
|
|
|
- bool is_xdp, bool enable)
|
|
|
+int i40e_control_wait_tx_q(int seid, struct i40e_pf *pf, int pf_q,
|
|
|
+ bool is_xdp, bool enable)
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
@@ -4277,7 +4281,6 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
|
|
|
if (ret)
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -4316,9 +4319,9 @@ static int i40e_pf_rxq_wait(struct i40e_pf *pf, int pf_q, bool enable)
|
|
|
* @pf_q: the PF queue to configure
|
|
|
* @enable: start or stop the queue
|
|
|
*
|
|
|
- * This function enables or disables a single queue. Note that any delay
|
|
|
- * required after the operation is expected to be handled by the caller of
|
|
|
- * this function.
|
|
|
+ * This function enables or disables a single queue. Note that
|
|
|
+ * any delay required after the operation is expected to be
|
|
|
+ * handled by the caller of this function.
|
|
|
**/
|
|
|
static void i40e_control_rx_q(struct i40e_pf *pf, int pf_q, bool enable)
|
|
|
{
|
|
@@ -4347,6 +4350,30 @@ static void i40e_control_rx_q(struct i40e_pf *pf, int pf_q, bool enable)
|
|
|
wr32(hw, I40E_QRX_ENA(pf_q), rx_reg);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i40e_control_wait_rx_q
|
|
|
+ * @pf: the PF structure
|
|
|
+ * @pf_q: queue being configured
|
|
|
+ * @enable: start or stop the rings
|
|
|
+ *
|
|
|
+ * This function enables or disables a single queue along with waiting
|
|
|
+ * for the change to finish. The caller of this function should handle
|
|
|
+ * the delays needed in the case of disabling queues.
|
|
|
+ **/
|
|
|
+int i40e_control_wait_rx_q(struct i40e_pf *pf, int pf_q, bool enable)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ i40e_control_rx_q(pf, pf_q, enable);
|
|
|
+
|
|
|
+ /* wait for the change to finish */
|
|
|
+ ret = i40e_pf_rxq_wait(pf, pf_q, enable);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40e_vsi_control_rx - Start or stop a VSI's rings
|
|
|
* @vsi: the VSI being configured
|
|
@@ -4359,10 +4386,7 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
|
|
|
|
|
|
pf_q = vsi->base_queue;
|
|
|
for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
|
|
|
- i40e_control_rx_q(pf, pf_q, enable);
|
|
|
-
|
|
|
- /* wait for the change to finish */
|
|
|
- ret = i40e_pf_rxq_wait(pf, pf_q, enable);
|
|
|
+ ret = i40e_control_wait_rx_q(pf, pf_q, enable);
|
|
|
if (ret) {
|
|
|
dev_info(&pf->pdev->dev,
|
|
|
"VSI seid %d Rx ring %d %sable timeout\n",
|
|
@@ -5072,7 +5096,7 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi)
|
|
|
* i40e_vsi_configure_bw_alloc - Configure VSI BW allocation per TC
|
|
|
* @vsi: the VSI being configured
|
|
|
* @enabled_tc: TC bitmap
|
|
|
- * @bw_credits: BW shared credits per TC
|
|
|
+ * @bw_share: BW shared credits per TC
|
|
|
*
|
|
|
* Returns 0 on success, negative value on failure
|
|
|
**/
|
|
@@ -6329,6 +6353,7 @@ out:
|
|
|
/**
|
|
|
* i40e_print_link_message - print link up or down
|
|
|
* @vsi: the VSI for which link needs a message
|
|
|
+ * @isup: true of link is up, false otherwise
|
|
|
*/
|
|
|
void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
|
|
|
{
|
|
@@ -7188,8 +7213,7 @@ static int i40e_parse_cls_flower(struct i40e_vsi *vsi,
|
|
|
if (mask->dst == cpu_to_be32(0xffffffff)) {
|
|
|
field_flags |= I40E_CLOUD_FIELD_IIP;
|
|
|
} else {
|
|
|
- mask->dst = be32_to_cpu(mask->dst);
|
|
|
- dev_err(&pf->pdev->dev, "Bad ip dst mask %pI4\n",
|
|
|
+ dev_err(&pf->pdev->dev, "Bad ip dst mask %pI4b\n",
|
|
|
&mask->dst);
|
|
|
return I40E_ERR_CONFIG;
|
|
|
}
|
|
@@ -7199,8 +7223,7 @@ static int i40e_parse_cls_flower(struct i40e_vsi *vsi,
|
|
|
if (mask->src == cpu_to_be32(0xffffffff)) {
|
|
|
field_flags |= I40E_CLOUD_FIELD_IIP;
|
|
|
} else {
|
|
|
- mask->src = be32_to_cpu(mask->src);
|
|
|
- dev_err(&pf->pdev->dev, "Bad ip src mask %pI4\n",
|
|
|
+ dev_err(&pf->pdev->dev, "Bad ip src mask %pI4b\n",
|
|
|
&mask->src);
|
|
|
return I40E_ERR_CONFIG;
|
|
|
}
|
|
@@ -9667,9 +9690,9 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
|
|
|
i40e_flush(hw);
|
|
|
}
|
|
|
|
|
|
-static const char *i40e_tunnel_name(struct i40e_udp_port_config *port)
|
|
|
+static const char *i40e_tunnel_name(u8 type)
|
|
|
{
|
|
|
- switch (port->type) {
|
|
|
+ switch (type) {
|
|
|
case UDP_TUNNEL_TYPE_VXLAN:
|
|
|
return "vxlan";
|
|
|
case UDP_TUNNEL_TYPE_GENEVE:
|
|
@@ -9703,37 +9726,68 @@ static void i40e_sync_udp_filters(struct i40e_pf *pf)
|
|
|
static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf)
|
|
|
{
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
|
- i40e_status ret;
|
|
|
+ u8 filter_index, type;
|
|
|
u16 port;
|
|
|
int i;
|
|
|
|
|
|
if (!test_and_clear_bit(__I40E_UDP_FILTER_SYNC_PENDING, pf->state))
|
|
|
return;
|
|
|
|
|
|
+ /* acquire RTNL to maintain state of flags and port requests */
|
|
|
+ rtnl_lock();
|
|
|
+
|
|
|
for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) {
|
|
|
if (pf->pending_udp_bitmap & BIT_ULL(i)) {
|
|
|
+ struct i40e_udp_port_config *udp_port;
|
|
|
+ i40e_status ret = 0;
|
|
|
+
|
|
|
+ udp_port = &pf->udp_ports[i];
|
|
|
pf->pending_udp_bitmap &= ~BIT_ULL(i);
|
|
|
- port = pf->udp_ports[i].port;
|
|
|
+
|
|
|
+ port = READ_ONCE(udp_port->port);
|
|
|
+ type = READ_ONCE(udp_port->type);
|
|
|
+ filter_index = READ_ONCE(udp_port->filter_index);
|
|
|
+
|
|
|
+ /* release RTNL while we wait on AQ command */
|
|
|
+ rtnl_unlock();
|
|
|
+
|
|
|
if (port)
|
|
|
ret = i40e_aq_add_udp_tunnel(hw, port,
|
|
|
- pf->udp_ports[i].type,
|
|
|
- NULL, NULL);
|
|
|
- else
|
|
|
- ret = i40e_aq_del_udp_tunnel(hw, i, NULL);
|
|
|
+ type,
|
|
|
+ &filter_index,
|
|
|
+ NULL);
|
|
|
+ else if (filter_index != I40E_UDP_PORT_INDEX_UNUSED)
|
|
|
+ ret = i40e_aq_del_udp_tunnel(hw, filter_index,
|
|
|
+ NULL);
|
|
|
+
|
|
|
+ /* reacquire RTNL so we can update filter_index */
|
|
|
+ rtnl_lock();
|
|
|
|
|
|
if (ret) {
|
|
|
dev_info(&pf->pdev->dev,
|
|
|
"%s %s port %d, index %d failed, err %s aq_err %s\n",
|
|
|
- i40e_tunnel_name(&pf->udp_ports[i]),
|
|
|
+ i40e_tunnel_name(type),
|
|
|
port ? "add" : "delete",
|
|
|
- port, i,
|
|
|
+ port,
|
|
|
+ filter_index,
|
|
|
i40e_stat_str(&pf->hw, ret),
|
|
|
i40e_aq_str(&pf->hw,
|
|
|
pf->hw.aq.asq_last_status));
|
|
|
- pf->udp_ports[i].port = 0;
|
|
|
+ if (port) {
|
|
|
+ /* failed to add, just reset port,
|
|
|
+ * drop pending bit for any deletion
|
|
|
+ */
|
|
|
+ udp_port->port = 0;
|
|
|
+ pf->pending_udp_bitmap &= ~BIT_ULL(i);
|
|
|
+ }
|
|
|
+ } else if (port) {
|
|
|
+ /* record filter index on success */
|
|
|
+ udp_port->filter_index = filter_index;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ rtnl_unlock();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -9980,7 +10034,7 @@ unlock_pf:
|
|
|
|
|
|
/**
|
|
|
* i40e_vsi_free_arrays - Free queue and vector pointer arrays for the VSI
|
|
|
- * @type: VSI pointer
|
|
|
+ * @vsi: VSI pointer
|
|
|
* @free_qvectors: a bool to specify if q_vectors need to be freed.
|
|
|
*
|
|
|
* On error: returns error code (negative)
|
|
@@ -10776,7 +10830,7 @@ int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
|
|
|
* @vsi: Pointer to VSI structure
|
|
|
* @seed: Buffer to store the keys
|
|
|
* @lut: Buffer to store the lookup table entries
|
|
|
- * lut_size: Size of buffer to store the lookup table entries
|
|
|
+ * @lut_size: Size of buffer to store the lookup table entries
|
|
|
*
|
|
|
* Returns 0 on success, negative on failure
|
|
|
*/
|
|
@@ -11350,6 +11404,11 @@ static u8 i40e_get_udp_port_idx(struct i40e_pf *pf, u16 port)
|
|
|
u8 i;
|
|
|
|
|
|
for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) {
|
|
|
+ /* Do not report ports with pending deletions as
|
|
|
+ * being available.
|
|
|
+ */
|
|
|
+ if (!port && (pf->pending_udp_bitmap & BIT_ULL(i)))
|
|
|
+ continue;
|
|
|
if (pf->udp_ports[i].port == port)
|
|
|
return i;
|
|
|
}
|
|
@@ -11404,6 +11463,7 @@ static void i40e_udp_tunnel_add(struct net_device *netdev,
|
|
|
|
|
|
/* New port: add it and mark its index in the bitmap */
|
|
|
pf->udp_ports[next_idx].port = port;
|
|
|
+ pf->udp_ports[next_idx].filter_index = I40E_UDP_PORT_INDEX_UNUSED;
|
|
|
pf->pending_udp_bitmap |= BIT_ULL(next_idx);
|
|
|
set_bit(__I40E_UDP_FILTER_SYNC_PENDING, pf->state);
|
|
|
}
|
|
@@ -11445,7 +11505,12 @@ static void i40e_udp_tunnel_del(struct net_device *netdev,
|
|
|
* and make it pending
|
|
|
*/
|
|
|
pf->udp_ports[idx].port = 0;
|
|
|
- pf->pending_udp_bitmap |= BIT_ULL(idx);
|
|
|
+
|
|
|
+ /* Toggle pending bit instead of setting it. This way if we are
|
|
|
+ * deleting a port that has yet to be added we just clear the pending
|
|
|
+ * bit and don't have to worry about it.
|
|
|
+ */
|
|
|
+ pf->pending_udp_bitmap ^= BIT_ULL(idx);
|
|
|
set_bit(__I40E_UDP_FILTER_SYNC_PENDING, pf->state);
|
|
|
|
|
|
return;
|
|
@@ -11476,6 +11541,7 @@ static int i40e_get_phys_port_id(struct net_device *netdev,
|
|
|
* @tb: pointer to array of nladdr (unused)
|
|
|
* @dev: the net device pointer
|
|
|
* @addr: the MAC address entry being added
|
|
|
+ * @vid: VLAN ID
|
|
|
* @flags: instructions from stack about fdb operation
|
|
|
*/
|
|
|
static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
|
@@ -11521,6 +11587,7 @@ static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
|
|
* i40e_ndo_bridge_setlink - Set the hardware bridge mode
|
|
|
* @dev: the netdev being configured
|
|
|
* @nlh: RTNL message
|
|
|
+ * @flags: bridge flags
|
|
|
*
|
|
|
* Inserts a new hardware bridge if not already created and
|
|
|
* enables the bridging mode requested (VEB or VEPA). If the
|
|
@@ -14094,6 +14161,7 @@ static void i40e_remove(struct pci_dev *pdev)
|
|
|
/**
|
|
|
* i40e_pci_error_detected - warning that something funky happened in PCI land
|
|
|
* @pdev: PCI device information struct
|
|
|
+ * @error: the type of PCI error
|
|
|
*
|
|
|
* Called to warn that something happened and the error handling steps
|
|
|
* are in progress. Allows the driver to quiesce things, be ready for
|