Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next...
authorDavid S. Miller <davem@davemloft.net>
Sat, 24 Sep 2016 12:14:57 +0000 (08:14 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sat, 24 Sep 2016 12:14:57 +0000 (08:14 -0400)
Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-09-22

This series contains updates to i40e and i40evf only.

Sridhar fixes link state event handling by updating the carrier and
starts/stops the Tx queues based on the link state notification from PF.

Brady fixes an issue where a user defined RSS hash key was not being
set because a user defined indirection table is not supplied when changing
the hash key, so if an indirection table is not supplied now, then a
default one is created and the hash key is correctly set.  Also fixed
an issue where when NPAR was enabled, we were still using pf->mac_seid
to perform the dump port query. Instead, go through the VSI to determine
the correct ID to use in either case.

Mitch provides one fix where a conditional return code was reversed, so
he does a "switheroo" to fix the issue.

Carolyn has two fixes, first fixes an issue in the virt channel code,
where a return code was not checked for NULL when applicable.  Second,
fixes an issue where we were byte swapping the port parameter, then
byte swapping it again in function execution.

Colin Ian King fixes a potential NULL pointer dereference.

Bimmy changes up i40evf_up_complete() to be void since it always returns
success anyways, which allows cleaning up of code which checked the
return code from this function.

Alex fixed an issue where the driver was incorrectly assuming that we
would always be pulling no more than 1 descriptor from each fragment.
So to correct this, we just need to make certain to test all the way to
the end of the fragments as it is possible for us to span 2 descriptors
in the block before us so we need to guarantee that even the last 6
descriptors have enough data to fill a full frame.

v2: dropped patches 1-3, 10 and 12 from the original series since Or
    Gerlitz pointed out several areas of improvement in the implementation
    of the VF Port representor netdev.  Sridhar is re-working the series
    for later submission.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/i40e/i40e.h
drivers/net/ethernet/intel/i40e/i40e_debugfs.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40evf/i40e_common.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

index 19103a6..30aaee4 100644 (file)
@@ -701,6 +701,8 @@ void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
 void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags);
 int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
 int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
+void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
+                      u16 rss_table_size, u16 rss_size);
 struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id);
 void i40e_update_stats(struct i40e_vsi *vsi);
 void i40e_update_eth_stats(struct i40e_vsi *vsi);
index 05cf9a7..8555f04 100644 (file)
@@ -1054,6 +1054,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
                        struct i40e_dcbx_config *r_cfg =
                                                &pf->hw.remote_dcbx_config;
                        int i, ret;
+                       u32 switch_id;
 
                        bw_data = kzalloc(sizeof(
                                    struct i40e_aqc_query_port_ets_config_resp),
@@ -1063,8 +1064,12 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
                                goto command_write_done;
                        }
 
+                       vsi = pf->vsi[pf->lan_vsi];
+                       switch_id =
+                               vsi->info.switch_id & I40E_AQ_VSI_SW_ID_MASK;
+
                        ret = i40e_aq_query_port_ets_config(&pf->hw,
-                                                           pf->mac_seid,
+                                                           switch_id,
                                                            bw_data, NULL);
                        if (ret) {
                                dev_info(&pf->pdev->dev,
index 1835186..af28a8c 100644 (file)
@@ -2922,15 +2922,13 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
+       struct i40e_pf *pf = vsi->back;
        u8 *seed = NULL;
        u16 i;
 
        if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
                return -EOPNOTSUPP;
 
-       if (!indir)
-               return 0;
-
        if (key) {
                if (!vsi->rss_hkey_user) {
                        vsi->rss_hkey_user = kzalloc(I40E_HKEY_ARRAY_SIZE,
@@ -2948,8 +2946,12 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
        }
 
        /* Each 32 bits pointed by 'indir' is stored with a lut entry */
-       for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
-               vsi->rss_lut_user[i] = (u8)(indir[i]);
+       if (indir)
+               for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
+                       vsi->rss_lut_user[i] = (u8)(indir[i]);
+       else
+               i40e_fill_rss_lut(pf, vsi->rss_lut_user, I40E_HLUT_ARRAY_SIZE,
+                                 vsi->rss_size);
 
        return i40e_config_rss(vsi, seed, vsi->rss_lut_user,
                               I40E_HLUT_ARRAY_SIZE);
index 61b0fc4..53cde5b 100644 (file)
@@ -57,8 +57,6 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit);
 static int i40e_setup_misc_vector(struct i40e_pf *pf);
 static void i40e_determine_queue_usage(struct i40e_pf *pf);
 static int i40e_setup_pf_filter_control(struct i40e_pf *pf);
-static void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
-                             u16 rss_table_size, u16 rss_size);
 static void i40e_fdir_sb_setup(struct i40e_pf *pf);
 static int i40e_veb_get_bw_info(struct i40e_veb *veb);
 
@@ -7156,9 +7154,9 @@ static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf)
                        pf->pending_udp_bitmap &= ~BIT_ULL(i);
                        port = pf->udp_ports[i].index;
                        if (port)
-                               ret = i40e_aq_add_udp_tunnel(hw, ntohs(port),
-                                                    pf->udp_ports[i].type,
-                                                    NULL, NULL);
+                               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);
 
@@ -8244,8 +8242,8 @@ int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
  * @rss_table_size: Lookup table size
  * @rss_size: Range of queue number for hashing
  */
-static void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
-                             u16 rss_table_size, u16 rss_size)
+void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
+                      u16 rss_table_size, u16 rss_size)
 {
        u16 i;
 
index f8d6623..bf7bb7c 100644 (file)
@@ -2621,9 +2621,7 @@ bool __i40e_chk_linearize(struct sk_buff *skb)
                return false;
 
        /* We need to walk through the list and validate that each group
-        * of 6 fragments totals at least gso_size.  However we don't need
-        * to perform such validation on the last 6 since the last 6 cannot
-        * inherit any data from a descriptor after them.
+        * of 6 fragments totals at least gso_size.
         */
        nr_frags -= I40E_MAX_BUFFER_TXD - 2;
        frag = &skb_shinfo(skb)->frags[0];
@@ -2654,8 +2652,7 @@ bool __i40e_chk_linearize(struct sk_buff *skb)
                if (sum < 0)
                        return true;
 
-               /* use pre-decrement to avoid processing last fragment */
-               if (!--nr_frags)
+               if (!nr_frags--)
                        break;
 
                sum -= skb_frag_size(stale++);
index 724d874..54b8ee2 100644 (file)
@@ -502,8 +502,16 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_id,
        u32 qtx_ctl;
        int ret = 0;
 
+       if (!i40e_vc_isvalid_vsi_id(vf, info->vsi_id)) {
+               ret = -ENOENT;
+               goto error_context;
+       }
        pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id);
        vsi = i40e_find_vsi_from_id(pf, vsi_id);
+       if (!vsi) {
+               ret = -ENOENT;
+               goto error_context;
+       }
 
        /* clear the context structure first */
        memset(&tx_ctx, 0, sizeof(struct i40e_hmc_obj_txq));
@@ -1476,7 +1484,8 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf,
 
        vsi = i40e_find_vsi_from_id(pf, info->vsi_id);
        if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
-           !i40e_vc_isvalid_vsi_id(vf, info->vsi_id)) {
+           !i40e_vc_isvalid_vsi_id(vf, info->vsi_id) ||
+           !vsi) {
                aq_ret = I40E_ERR_PARAM;
                goto error_param;
        }
@@ -2217,8 +2226,8 @@ static int i40e_vc_iwarp_qvmap_msg(struct i40e_vf *vf, u8 *msg, u16 msglen,
 error_param:
        /* send the response to the VF */
        return i40e_vc_send_resp_to_vf(vf,
-                              config ? I40E_VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP :
-                              I40E_VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP,
+                              config ? I40E_VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP :
+                              I40E_VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP,
                               aq_ret);
 }
 
index 4db0c03..7953c13 100644 (file)
@@ -302,7 +302,6 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
                   void *buffer, u16 buf_len)
 {
        struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
-       u16 len = le16_to_cpu(aq_desc->datalen);
        u8 *buf = (u8 *)buffer;
        u16 i = 0;
 
@@ -326,6 +325,8 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
                   le32_to_cpu(aq_desc->params.external.addr_low));
 
        if ((buffer != NULL) && (aq_desc->datalen != 0)) {
+               u16 len = le16_to_cpu(aq_desc->datalen);
+
                i40e_debug(hw, mask, "AQ CMD Buffer:\n");
                if (buf_len < len)
                        len = buf_len;
index 0130458..e3427eb 100644 (file)
@@ -1832,9 +1832,7 @@ bool __i40evf_chk_linearize(struct sk_buff *skb)
                return false;
 
        /* We need to walk through the list and validate that each group
-        * of 6 fragments totals at least gso_size.  However we don't need
-        * to perform such validation on the last 6 since the last 6 cannot
-        * inherit any data from a descriptor after them.
+        * of 6 fragments totals at least gso_size.
         */
        nr_frags -= I40E_MAX_BUFFER_TXD - 2;
        frag = &skb_shinfo(skb)->frags[0];
@@ -1865,8 +1863,7 @@ bool __i40evf_chk_linearize(struct sk_buff *skb)
                if (sum < 0)
                        return true;
 
-               /* use pre-decrement to avoid processing last fragment */
-               if (!--nr_frags)
+               if (!nr_frags--)
                        break;
 
                sum -= skb_frag_size(stale++);
index f751f7b..99833f3 100644 (file)
@@ -1007,7 +1007,7 @@ static void i40evf_configure(struct i40evf_adapter *adapter)
  * i40evf_up_complete - Finish the last steps of bringing up a connection
  * @adapter: board private structure
  **/
-static int i40evf_up_complete(struct i40evf_adapter *adapter)
+static void i40evf_up_complete(struct i40evf_adapter *adapter)
 {
        adapter->state = __I40EVF_RUNNING;
        clear_bit(__I40E_DOWN, &adapter->vsi.state);
@@ -1016,7 +1016,6 @@ static int i40evf_up_complete(struct i40evf_adapter *adapter)
 
        adapter->aq_required |= I40EVF_FLAG_AQ_ENABLE_QUEUES;
        mod_timer_pending(&adapter->watchdog_timer, jiffies + 1);
-       return 0;
 }
 
 /**
@@ -1037,6 +1036,7 @@ void i40evf_down(struct i40evf_adapter *adapter)
 
        netif_carrier_off(netdev);
        netif_tx_disable(netdev);
+       adapter->link_up = false;
        i40evf_napi_disable_all(adapter);
        i40evf_irq_disable(adapter);
 
@@ -1731,6 +1731,7 @@ static void i40evf_reset_task(struct work_struct *work)
                        set_bit(__I40E_DOWN, &adapter->vsi.state);
                        netif_carrier_off(netdev);
                        netif_tx_disable(netdev);
+                       adapter->link_up = false;
                        i40evf_napi_disable_all(adapter);
                        i40evf_irq_disable(adapter);
                        i40evf_free_traffic_irqs(adapter);
@@ -1769,6 +1770,7 @@ continue_reset:
        if (netif_running(adapter->netdev)) {
                netif_carrier_off(netdev);
                netif_tx_stop_all_queues(netdev);
+               adapter->link_up = false;
                i40evf_napi_disable_all(adapter);
        }
        i40evf_irq_disable(adapter);
@@ -1783,8 +1785,7 @@ continue_reset:
        i40evf_free_all_tx_resources(adapter);
 
        /* kill and reinit the admin queue */
-       if (i40evf_shutdown_adminq(hw))
-               dev_warn(&adapter->pdev->dev, "Failed to shut down adminq\n");
+       i40evf_shutdown_adminq(hw);
        adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;
        err = i40evf_init_adminq(hw);
        if (err)
@@ -1824,9 +1825,7 @@ continue_reset:
 
                i40evf_configure(adapter);
 
-               err = i40evf_up_complete(adapter);
-               if (err)
-                       goto reset_err;
+               i40evf_up_complete(adapter);
 
                i40evf_irq_enable(adapter, true);
        } else {
@@ -2056,9 +2055,7 @@ static int i40evf_open(struct net_device *netdev)
        i40evf_add_filter(adapter, adapter->hw.mac.addr);
        i40evf_configure(adapter);
 
-       err = i40evf_up_complete(adapter);
-       if (err)
-               goto err_req_irq;
+       i40evf_up_complete(adapter);
 
        i40evf_irq_enable(adapter, true);
 
@@ -2457,6 +2454,7 @@ static void i40evf_init_task(struct work_struct *work)
                goto err_sw_init;
 
        netif_carrier_off(netdev);
+       adapter->link_up = false;
 
        if (!adapter->netdev_registered) {
                err = register_netdev(netdev);
index cc6cb30..ddf478d 100644 (file)
@@ -898,8 +898,14 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
                            vpe->event_data.link_event.link_status) {
                                adapter->link_up =
                                        vpe->event_data.link_event.link_status;
+                               if (adapter->link_up) {
+                                       netif_tx_start_all_queues(netdev);
+                                       netif_carrier_on(netdev);
+                               } else {
+                                       netif_tx_stop_all_queues(netdev);
+                                       netif_carrier_off(netdev);
+                               }
                                i40evf_print_link_message(adapter);
-                               netif_tx_stop_all_queues(netdev);
                        }
                        break;
                case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
@@ -974,8 +980,6 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
        case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
                /* enable transmits */
                i40evf_irq_enable(adapter, true);
-               netif_tx_start_all_queues(adapter->netdev);
-               netif_carrier_on(adapter->netdev);
                break;
        case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
                i40evf_free_all_tx_resources(adapter);