Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next...
[linux-2.6-microblaze.git] / drivers / net / ethernet / intel / ice / ice_lib.c
index 89bb573..c14be5c 100644 (file)
@@ -169,12 +169,13 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
 
        switch (vsi->type) {
        case ICE_VSI_PF:
-               vsi->alloc_txq = min3(pf->num_lan_msix,
-                                     ice_get_avail_txq_count(pf),
-                                     (u16)num_online_cpus());
                if (vsi->req_txq) {
                        vsi->alloc_txq = vsi->req_txq;
                        vsi->num_txq = vsi->req_txq;
+               } else {
+                       vsi->alloc_txq = min3(pf->num_lan_msix,
+                                             ice_get_avail_txq_count(pf),
+                                             (u16)num_online_cpus());
                }
 
                pf->num_lan_tx = vsi->alloc_txq;
@@ -183,12 +184,13 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
                if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
                        vsi->alloc_rxq = 1;
                } else {
-                       vsi->alloc_rxq = min3(pf->num_lan_msix,
-                                             ice_get_avail_rxq_count(pf),
-                                             (u16)num_online_cpus());
                        if (vsi->req_rxq) {
                                vsi->alloc_rxq = vsi->req_rxq;
                                vsi->num_rxq = vsi->req_rxq;
+                       } else {
+                               vsi->alloc_rxq = min3(pf->num_lan_msix,
+                                                     ice_get_avail_rxq_count(pf),
+                                                     (u16)num_online_cpus());
                        }
                }
 
@@ -1693,6 +1695,33 @@ ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio)
        wr32(hw, QRXFLXP_CNTXT(pf_q), regval);
 }
 
+int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx)
+{
+       if (q_idx >= vsi->num_rxq)
+               return -EINVAL;
+
+       return ice_vsi_cfg_rxq(vsi->rx_rings[q_idx]);
+}
+
+int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_ring **tx_rings, u16 q_idx)
+{
+       struct ice_aqc_add_tx_qgrp *qg_buf;
+       int err;
+
+       if (q_idx >= vsi->alloc_txq || !tx_rings || !tx_rings[q_idx])
+               return -EINVAL;
+
+       qg_buf = kzalloc(struct_size(qg_buf, txqs, 1), GFP_KERNEL);
+       if (!qg_buf)
+               return -ENOMEM;
+
+       qg_buf->num_txqs = 1;
+
+       err = ice_vsi_cfg_txq(vsi, tx_rings[q_idx], qg_buf);
+       kfree(qg_buf);
+       return err;
+}
+
 /**
  * ice_vsi_cfg_rxqs - Configure the VSI for Rx
  * @vsi: the VSI being configured
@@ -1710,15 +1739,11 @@ int ice_vsi_cfg_rxqs(struct ice_vsi *vsi)
        ice_vsi_cfg_frame_size(vsi);
 setup_rings:
        /* set up individual rings */
-       for (i = 0; i < vsi->num_rxq; i++) {
-               int err;
+       ice_for_each_rxq(vsi, i) {
+               int err = ice_vsi_cfg_rxq(vsi->rx_rings[i]);
 
-               err = ice_setup_rx_ctx(vsi->rx_rings[i]);
-               if (err) {
-                       dev_err(ice_pf_to_dev(vsi->back), "ice_setup_rx_ctx failed for RxQ %d, err %d\n",
-                               i, err);
+               if (err)
                        return err;
-               }
        }
 
        return 0;
@@ -2226,7 +2251,7 @@ void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create)
        }
 
        if (status)
-               dev_err(dev, "Fail %s %s LLDP rule on VSI %i error: %s\n",
+               dev_dbg(dev, "Fail %s %s LLDP rule on VSI %i error: %s\n",
                        create ? "adding" : "removing", tx ? "TX" : "RX",
                        vsi->vsi_num, ice_stat_str(status));
 }
@@ -3205,6 +3230,34 @@ bool ice_is_reset_in_progress(unsigned long *state)
               test_bit(ICE_GLOBR_REQ, state);
 }
 
+/**
+ * ice_wait_for_reset - Wait for driver to finish reset and rebuild
+ * @pf: pointer to the PF structure
+ * @timeout: length of time to wait, in jiffies
+ *
+ * Wait (sleep) for a short time until the driver finishes cleaning up from
+ * a device reset. The caller must be able to sleep. Use this to delay
+ * operations that could fail while the driver is cleaning up after a device
+ * reset.
+ *
+ * Returns 0 on success, -EBUSY if the reset is not finished within the
+ * timeout, and -ERESTARTSYS if the thread was interrupted.
+ */
+int ice_wait_for_reset(struct ice_pf *pf, unsigned long timeout)
+{
+       long ret;
+
+       ret = wait_event_interruptible_timeout(pf->reset_wait_queue,
+                                              !ice_is_reset_in_progress(pf->state),
+                                              timeout);
+       if (ret < 0)
+               return ret;
+       else if (!ret)
+               return -EBUSY;
+       else
+               return 0;
+}
+
 #ifdef CONFIG_DCB
 /**
  * ice_vsi_update_q_map - update our copy of the VSI info with new queue map