Commit 41b9eff0 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2023-07-05 (ice)

This series contains updates to ice driver only.

Sridhar fixes incorrect comparison of max Tx rate limit to occur against
each TC value rather than the aggregate. He also resolves an issue with
the wrong VSI being used when setting max Tx rate when TCs are enabled.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  ice: Fix tx queue rate limit when TCs are configured
  ice: Fix max_rate check while configuring TX rate limits
====================

Link: https://lore.kernel.org/r/20230705201346.49370-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 4863b57b 479cdfe3
...@@ -5739,6 +5739,13 @@ ice_set_tx_maxrate(struct net_device *netdev, int queue_index, u32 maxrate) ...@@ -5739,6 +5739,13 @@ ice_set_tx_maxrate(struct net_device *netdev, int queue_index, u32 maxrate)
q_handle = vsi->tx_rings[queue_index]->q_handle; q_handle = vsi->tx_rings[queue_index]->q_handle;
tc = ice_dcb_get_tc(vsi, queue_index); tc = ice_dcb_get_tc(vsi, queue_index);
vsi = ice_locate_vsi_using_queue(vsi, queue_index);
if (!vsi) {
netdev_err(netdev, "Invalid VSI for given queue %d\n",
queue_index);
return -EINVAL;
}
/* Set BW back to default, when user set maxrate to 0 */ /* Set BW back to default, when user set maxrate to 0 */
if (!maxrate) if (!maxrate)
status = ice_cfg_q_bw_dflt_lmt(vsi->port_info, vsi->idx, tc, status = ice_cfg_q_bw_dflt_lmt(vsi->port_info, vsi->idx, tc,
...@@ -7872,10 +7879,10 @@ static int ...@@ -7872,10 +7879,10 @@ static int
ice_validate_mqprio_qopt(struct ice_vsi *vsi, ice_validate_mqprio_qopt(struct ice_vsi *vsi,
struct tc_mqprio_qopt_offload *mqprio_qopt) struct tc_mqprio_qopt_offload *mqprio_qopt)
{ {
u64 sum_max_rate = 0, sum_min_rate = 0;
int non_power_of_2_qcount = 0; int non_power_of_2_qcount = 0;
struct ice_pf *pf = vsi->back; struct ice_pf *pf = vsi->back;
int max_rss_q_cnt = 0; int max_rss_q_cnt = 0;
u64 sum_min_rate = 0;
struct device *dev; struct device *dev;
int i, speed; int i, speed;
u8 num_tc; u8 num_tc;
...@@ -7891,6 +7898,7 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi, ...@@ -7891,6 +7898,7 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi,
dev = ice_pf_to_dev(pf); dev = ice_pf_to_dev(pf);
vsi->ch_rss_size = 0; vsi->ch_rss_size = 0;
num_tc = mqprio_qopt->qopt.num_tc; num_tc = mqprio_qopt->qopt.num_tc;
speed = ice_get_link_speed_kbps(vsi);
for (i = 0; num_tc; i++) { for (i = 0; num_tc; i++) {
int qcount = mqprio_qopt->qopt.count[i]; int qcount = mqprio_qopt->qopt.count[i];
...@@ -7931,7 +7939,6 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi, ...@@ -7931,7 +7939,6 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi,
*/ */
max_rate = mqprio_qopt->max_rate[i]; max_rate = mqprio_qopt->max_rate[i];
max_rate = div_u64(max_rate, ICE_BW_KBPS_DIVISOR); max_rate = div_u64(max_rate, ICE_BW_KBPS_DIVISOR);
sum_max_rate += max_rate;
/* min_rate is minimum guaranteed rate and it can't be zero */ /* min_rate is minimum guaranteed rate and it can't be zero */
min_rate = mqprio_qopt->min_rate[i]; min_rate = mqprio_qopt->min_rate[i];
...@@ -7944,6 +7951,12 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi, ...@@ -7944,6 +7951,12 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi,
return -EINVAL; return -EINVAL;
} }
if (max_rate && max_rate > speed) {
dev_err(dev, "TC%d: max_rate(%llu Kbps) > link speed of %u Kbps\n",
i, max_rate, speed);
return -EINVAL;
}
iter_div_u64_rem(min_rate, ICE_MIN_BW_LIMIT, &rem); iter_div_u64_rem(min_rate, ICE_MIN_BW_LIMIT, &rem);
if (rem) { if (rem) {
dev_err(dev, "TC%d: Min Rate not multiple of %u Kbps", dev_err(dev, "TC%d: Min Rate not multiple of %u Kbps",
...@@ -7981,12 +7994,6 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi, ...@@ -7981,12 +7994,6 @@ ice_validate_mqprio_qopt(struct ice_vsi *vsi,
(mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i])) (mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i]))
return -EINVAL; return -EINVAL;
speed = ice_get_link_speed_kbps(vsi);
if (sum_max_rate && sum_max_rate > (u64)speed) {
dev_err(dev, "Invalid max Tx rate(%llu) Kbps > speed(%u) Kbps specified\n",
sum_max_rate, speed);
return -EINVAL;
}
if (sum_min_rate && sum_min_rate > (u64)speed) { if (sum_min_rate && sum_min_rate > (u64)speed) {
dev_err(dev, "Invalid min Tx rate(%llu) Kbps > speed (%u) Kbps specified\n", dev_err(dev, "Invalid min Tx rate(%llu) Kbps > speed (%u) Kbps specified\n",
sum_min_rate, speed); sum_min_rate, speed);
......
...@@ -750,17 +750,16 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr) ...@@ -750,17 +750,16 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
/** /**
* ice_locate_vsi_using_queue - locate VSI using queue (forward to queue action) * ice_locate_vsi_using_queue - locate VSI using queue (forward to queue action)
* @vsi: Pointer to VSI * @vsi: Pointer to VSI
* @tc_fltr: Pointer to tc_flower_filter * @queue: Queue index
* *
* Locate the VSI using specified queue. When ADQ is not enabled, always * Locate the VSI using specified "queue". When ADQ is not enabled,
* return input VSI, otherwise locate corresponding VSI based on per channel * always return input VSI, otherwise locate corresponding
* offset and qcount * VSI based on per channel "offset" and "qcount"
*/ */
static struct ice_vsi * struct ice_vsi *
ice_locate_vsi_using_queue(struct ice_vsi *vsi, ice_locate_vsi_using_queue(struct ice_vsi *vsi, int queue)
struct ice_tc_flower_fltr *tc_fltr)
{ {
int num_tc, tc, queue; int num_tc, tc;
/* if ADQ is not active, passed VSI is the candidate VSI */ /* if ADQ is not active, passed VSI is the candidate VSI */
if (!ice_is_adq_active(vsi->back)) if (!ice_is_adq_active(vsi->back))
...@@ -770,7 +769,6 @@ ice_locate_vsi_using_queue(struct ice_vsi *vsi, ...@@ -770,7 +769,6 @@ ice_locate_vsi_using_queue(struct ice_vsi *vsi,
* upon queue number) * upon queue number)
*/ */
num_tc = vsi->mqprio_qopt.qopt.num_tc; num_tc = vsi->mqprio_qopt.qopt.num_tc;
queue = tc_fltr->action.fwd.q.queue;
for (tc = 0; tc < num_tc; tc++) { for (tc = 0; tc < num_tc; tc++) {
int qcount = vsi->mqprio_qopt.qopt.count[tc]; int qcount = vsi->mqprio_qopt.qopt.count[tc];
...@@ -812,6 +810,7 @@ ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr) ...@@ -812,6 +810,7 @@ ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
struct ice_pf *pf = vsi->back; struct ice_pf *pf = vsi->back;
struct device *dev; struct device *dev;
u32 tc_class; u32 tc_class;
int q;
dev = ice_pf_to_dev(pf); dev = ice_pf_to_dev(pf);
...@@ -840,7 +839,8 @@ ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr) ...@@ -840,7 +839,8 @@ ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
/* Determine destination VSI even though the action is /* Determine destination VSI even though the action is
* FWD_TO_QUEUE, because QUEUE is associated with VSI * FWD_TO_QUEUE, because QUEUE is associated with VSI
*/ */
dest_vsi = tc_fltr->dest_vsi; q = tc_fltr->action.fwd.q.queue;
dest_vsi = ice_locate_vsi_using_queue(vsi, q);
break; break;
default: default:
dev_err(dev, dev_err(dev,
...@@ -1716,7 +1716,7 @@ ice_tc_forward_to_queue(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr, ...@@ -1716,7 +1716,7 @@ ice_tc_forward_to_queue(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr,
/* If ADQ is configured, and the queue belongs to ADQ VSI, then prepare /* If ADQ is configured, and the queue belongs to ADQ VSI, then prepare
* ADQ switch filter * ADQ switch filter
*/ */
ch_vsi = ice_locate_vsi_using_queue(vsi, fltr); ch_vsi = ice_locate_vsi_using_queue(vsi, fltr->action.fwd.q.queue);
if (!ch_vsi) if (!ch_vsi)
return -EINVAL; return -EINVAL;
fltr->dest_vsi = ch_vsi; fltr->dest_vsi = ch_vsi;
......
...@@ -204,6 +204,7 @@ static inline int ice_chnl_dmac_fltr_cnt(struct ice_pf *pf) ...@@ -204,6 +204,7 @@ static inline int ice_chnl_dmac_fltr_cnt(struct ice_pf *pf)
return pf->num_dmac_chnl_fltrs; return pf->num_dmac_chnl_fltrs;
} }
struct ice_vsi *ice_locate_vsi_using_queue(struct ice_vsi *vsi, int queue);
int int
ice_add_cls_flower(struct net_device *netdev, struct ice_vsi *vsi, ice_add_cls_flower(struct net_device *netdev, struct ice_vsi *vsi,
struct flow_cls_offload *cls_flower); struct flow_cls_offload *cls_flower);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment