diff options
author | Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> | 2019-02-28 18:25:48 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2019-05-02 03:57:44 -0400 |
commit | bb87ee0efb7396d79ba5f37ff8e8721d01c87d4a (patch) | |
tree | f4cbd3f588e0409d949f865d44d5cc990bf535d1 /drivers/net/ethernet/intel/ice/ice_lib.c | |
parent | f76c4b571feea8eb03184d8ba0ee45f98fff47ff (diff) |
ice: Create framework for VSI queue context
This patch introduces a framework to store queue specific information
in VSI queue contexts. Currently VSI queue context (represented by
struct ice_q_ctx) only has q_handle as a member. In future patches,
this structure will be updated to hold queue specific information.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_lib.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 99 |
1 files changed, 60 insertions, 39 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index f31129e4e9cf..fa8ebd8a10ce 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c | |||
@@ -1715,8 +1715,8 @@ ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings, int offset) | |||
1715 | rings[q_idx]->tail = | 1715 | rings[q_idx]->tail = |
1716 | pf->hw.hw_addr + QTX_COMM_DBELL(pf_q); | 1716 | pf->hw.hw_addr + QTX_COMM_DBELL(pf_q); |
1717 | status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc, | 1717 | status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc, |
1718 | num_q_grps, qg_buf, buf_len, | 1718 | i, num_q_grps, qg_buf, |
1719 | NULL); | 1719 | buf_len, NULL); |
1720 | if (status) { | 1720 | if (status) { |
1721 | dev_err(&vsi->back->pdev->dev, | 1721 | dev_err(&vsi->back->pdev->dev, |
1722 | "Failed to set LAN Tx queue context, error: %d\n", | 1722 | "Failed to set LAN Tx queue context, error: %d\n", |
@@ -2033,10 +2033,10 @@ ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, | |||
2033 | { | 2033 | { |
2034 | struct ice_pf *pf = vsi->back; | 2034 | struct ice_pf *pf = vsi->back; |
2035 | struct ice_hw *hw = &pf->hw; | 2035 | struct ice_hw *hw = &pf->hw; |
2036 | int tc, q_idx = 0, err = 0; | ||
2037 | u16 *q_ids, *q_handles, i; | ||
2036 | enum ice_status status; | 2038 | enum ice_status status; |
2037 | u32 *q_teids, val; | 2039 | u32 *q_teids, val; |
2038 | u16 *q_ids, i; | ||
2039 | int err = 0; | ||
2040 | 2040 | ||
2041 | if (vsi->num_txq > ICE_LAN_TXQ_MAX_QDIS) | 2041 | if (vsi->num_txq > ICE_LAN_TXQ_MAX_QDIS) |
2042 | return -EINVAL; | 2042 | return -EINVAL; |
@@ -2053,50 +2053,71 @@ ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, | |||
2053 | goto err_alloc_q_ids; | 2053 | goto err_alloc_q_ids; |
2054 | } | 2054 | } |
2055 | 2055 | ||
2056 | /* set up the Tx queue list to be disabled */ | 2056 | q_handles = devm_kcalloc(&pf->pdev->dev, vsi->num_txq, |
2057 | ice_for_each_txq(vsi, i) { | 2057 | sizeof(*q_handles), GFP_KERNEL); |
2058 | u16 v_idx; | 2058 | if (!q_handles) { |
2059 | err = -ENOMEM; | ||
2060 | goto err_alloc_q_handles; | ||
2061 | } | ||
2059 | 2062 | ||
2060 | if (!rings || !rings[i] || !rings[i]->q_vector) { | 2063 | /* set up the Tx queue list to be disabled for each enabled TC */ |
2061 | err = -EINVAL; | 2064 | ice_for_each_traffic_class(tc) { |
2062 | goto err_out; | 2065 | if (!(vsi->tc_cfg.ena_tc & BIT(tc))) |
2063 | } | 2066 | break; |
2067 | |||
2068 | for (i = 0; i < vsi->tc_cfg.tc_info[tc].qcount_tx; i++) { | ||
2069 | u16 v_idx; | ||
2070 | |||
2071 | if (!rings || !rings[i] || !rings[i]->q_vector) { | ||
2072 | err = -EINVAL; | ||
2073 | goto err_out; | ||
2074 | } | ||
2064 | 2075 | ||
2065 | q_ids[i] = vsi->txq_map[i + offset]; | 2076 | q_ids[i] = vsi->txq_map[q_idx + offset]; |
2066 | q_teids[i] = rings[i]->txq_teid; | 2077 | q_teids[i] = rings[q_idx]->txq_teid; |
2078 | q_handles[i] = i; | ||
2067 | 2079 | ||
2068 | /* clear cause_ena bit for disabled queues */ | 2080 | /* clear cause_ena bit for disabled queues */ |
2069 | val = rd32(hw, QINT_TQCTL(rings[i]->reg_idx)); | 2081 | val = rd32(hw, QINT_TQCTL(rings[i]->reg_idx)); |
2070 | val &= ~QINT_TQCTL_CAUSE_ENA_M; | 2082 | val &= ~QINT_TQCTL_CAUSE_ENA_M; |
2071 | wr32(hw, QINT_TQCTL(rings[i]->reg_idx), val); | 2083 | wr32(hw, QINT_TQCTL(rings[i]->reg_idx), val); |
2072 | 2084 | ||
2073 | /* software is expected to wait for 100 ns */ | 2085 | /* software is expected to wait for 100 ns */ |
2074 | ndelay(100); | 2086 | ndelay(100); |
2075 | 2087 | ||
2076 | /* trigger a software interrupt for the vector associated to | 2088 | /* trigger a software interrupt for the vector |
2077 | * the queue to schedule NAPI handler | 2089 | * associated to the queue to schedule NAPI handler |
2090 | */ | ||
2091 | v_idx = rings[i]->q_vector->v_idx; | ||
2092 | wr32(hw, GLINT_DYN_CTL(vsi->hw_base_vector + v_idx), | ||
2093 | GLINT_DYN_CTL_SWINT_TRIG_M | | ||
2094 | GLINT_DYN_CTL_INTENA_MSK_M); | ||
2095 | q_idx++; | ||
2096 | } | ||
2097 | status = ice_dis_vsi_txq(vsi->port_info, vsi->idx, tc, | ||
2098 | vsi->num_txq, q_handles, q_ids, | ||
2099 | q_teids, rst_src, rel_vmvf_num, NULL); | ||
2100 | |||
2101 | /* if the disable queue command was exercised during an active | ||
2102 | * reset flow, ICE_ERR_RESET_ONGOING is returned. This is not | ||
2103 | * an error as the reset operation disables queues at the | ||
2104 | * hardware level anyway. | ||
2078 | */ | 2105 | */ |
2079 | v_idx = rings[i]->q_vector->v_idx; | 2106 | if (status == ICE_ERR_RESET_ONGOING) { |
2080 | wr32(hw, GLINT_DYN_CTL(vsi->hw_base_vector + v_idx), | 2107 | dev_dbg(&pf->pdev->dev, |
2081 | GLINT_DYN_CTL_SWINT_TRIG_M | GLINT_DYN_CTL_INTENA_MSK_M); | 2108 | "Reset in progress. LAN Tx queues already disabled\n"); |
2082 | } | 2109 | } else if (status) { |
2083 | status = ice_dis_vsi_txq(vsi->port_info, vsi->num_txq, q_ids, q_teids, | 2110 | dev_err(&pf->pdev->dev, |
2084 | rst_src, rel_vmvf_num, NULL); | 2111 | "Failed to disable LAN Tx queues, error: %d\n", |
2085 | /* if the disable queue command was exercised during an active reset | 2112 | status); |
2086 | * flow, ICE_ERR_RESET_ONGOING is returned. This is not an error as | 2113 | err = -ENODEV; |
2087 | * the reset operation disables queues at the hardware level anyway. | 2114 | } |
2088 | */ | ||
2089 | if (status == ICE_ERR_RESET_ONGOING) { | ||
2090 | dev_info(&pf->pdev->dev, | ||
2091 | "Reset in progress. LAN Tx queues already disabled\n"); | ||
2092 | } else if (status) { | ||
2093 | dev_err(&pf->pdev->dev, | ||
2094 | "Failed to disable LAN Tx queues, error: %d\n", | ||
2095 | status); | ||
2096 | err = -ENODEV; | ||
2097 | } | 2115 | } |
2098 | 2116 | ||
2099 | err_out: | 2117 | err_out: |
2118 | devm_kfree(&pf->pdev->dev, q_handles); | ||
2119 | |||
2120 | err_alloc_q_handles: | ||
2100 | devm_kfree(&pf->pdev->dev, q_ids); | 2121 | devm_kfree(&pf->pdev->dev, q_ids); |
2101 | 2122 | ||
2102 | err_alloc_q_ids: | 2123 | err_alloc_q_ids: |