summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf.h1
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c66
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c3
3 files changed, 67 insertions, 3 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h
index c8d68c8d2c33..150d676ab87c 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf.h
+++ b/drivers/net/ethernet/intel/i40evf/i40evf.h
@@ -107,6 +107,7 @@ struct i40e_vsi {
#define I40EVF_HKEY_ARRAY_SIZE ((I40E_VFQF_HKEY_MAX_INDEX + 1) * 4)
#define I40EVF_HLUT_ARRAY_SIZE ((I40E_VFQF_HLUT_MAX_INDEX + 1) * 4)
+#define I40EVF_MBPS_DIVISOR 125000 /* divisor to convert to Mbps */
/* MAX_MSIX_Q_VECTORS of these are allocated,
* but we only use one per queue-specific vector.
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 8a26393459ef..2f677a2a4b5c 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2236,6 +2236,48 @@ void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter)
}
/**
+ * i40evf_validate_tx_bandwidth - validate the max Tx bandwidth
+ * @adapter: board private structure
+ * @max_tx_rate: max Tx bw for a tc
+ **/
+static int i40evf_validate_tx_bandwidth(struct i40evf_adapter *adapter,
+ u64 max_tx_rate)
+{
+ int speed = 0, ret = 0;
+
+ switch (adapter->link_speed) {
+ case I40E_LINK_SPEED_40GB:
+ speed = 40000;
+ break;
+ case I40E_LINK_SPEED_25GB:
+ speed = 25000;
+ break;
+ case I40E_LINK_SPEED_20GB:
+ speed = 20000;
+ break;
+ case I40E_LINK_SPEED_10GB:
+ speed = 10000;
+ break;
+ case I40E_LINK_SPEED_1GB:
+ speed = 1000;
+ break;
+ case I40E_LINK_SPEED_100MB:
+ speed = 100;
+ break;
+ default:
+ break;
+ }
+
+ if (max_tx_rate > speed) {
+ dev_err(&adapter->pdev->dev,
+ "Invalid tx rate specified\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/**
* i40evf_validate_channel_config - validate queue mapping info
* @adapter: board private structure
* @mqprio_qopt: queue parameters
@@ -2247,7 +2289,10 @@ void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter)
static int i40evf_validate_ch_config(struct i40evf_adapter *adapter,
struct tc_mqprio_qopt_offload *mqprio_qopt)
{
+ u64 total_max_rate = 0;
int i, num_qps = 0;
+ u64 tx_rate = 0;
+ int ret = 0;
if (mqprio_qopt->qopt.num_tc > I40EVF_MAX_TRAFFIC_CLASS ||
mqprio_qopt->qopt.num_tc < 1)
@@ -2255,16 +2300,24 @@ static int i40evf_validate_ch_config(struct i40evf_adapter *adapter,
for (i = 0; i <= mqprio_qopt->qopt.num_tc - 1; i++) {
if (!mqprio_qopt->qopt.count[i] ||
- mqprio_qopt->min_rate[i] ||
- mqprio_qopt->max_rate[i] ||
mqprio_qopt->qopt.offset[i] != num_qps)
return -EINVAL;
+ if (mqprio_qopt->min_rate[i]) {
+ dev_err(&adapter->pdev->dev,
+ "Invalid min tx rate (greater than 0) specified\n");
+ return -EINVAL;
+ }
+ /*convert to Mbps */
+ tx_rate = div_u64(mqprio_qopt->max_rate[i],
+ I40EVF_MBPS_DIVISOR);
+ total_max_rate += tx_rate;
num_qps += mqprio_qopt->qopt.count[i];
}
if (num_qps > MAX_QUEUES)
return -EINVAL;
- return 0;
+ ret = i40evf_validate_tx_bandwidth(adapter, total_max_rate);
+ return ret;
}
/**
@@ -2285,6 +2338,7 @@ static int __i40evf_setup_tc(struct net_device *netdev, void *type_data)
struct virtchnl_vf_resource *vfres = adapter->vf_res;
u8 num_tc = 0, total_qps = 0;
int ret = 0, netdev_tc = 0;
+ u64 max_tx_rate;
u16 mode;
int i;
@@ -2332,6 +2386,12 @@ static int __i40evf_setup_tc(struct net_device *netdev, void *type_data)
adapter->ch_config.ch_info[i].offset =
mqprio_qopt->qopt.offset[i];
total_qps += mqprio_qopt->qopt.count[i];
+ max_tx_rate = mqprio_qopt->max_rate[i];
+ /* convert to Mbps */
+ max_tx_rate = div_u64(max_tx_rate,
+ I40EVF_MBPS_DIVISOR);
+ adapter->ch_config.ch_info[i].max_tx_rate =
+ max_tx_rate;
} else {
adapter->ch_config.ch_info[i].count = 1;
adapter->ch_config.ch_info[i].offset = 0;
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
index f6c56141b4fe..647ea104d435 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -1003,6 +1003,9 @@ void i40evf_enable_channels(struct i40evf_adapter *adapter)
for (i = 0; i < vti->num_tc; i++) {
vti->list[i].count = adapter->ch_config.ch_info[i].count;
vti->list[i].offset = adapter->ch_config.ch_info[i].offset;
+ vti->list[i].pad = 0;
+ vti->list[i].max_tx_rate =
+ adapter->ch_config.ch_info[i].max_tx_rate;
}
adapter->ch_config.state = __I40EVF_TC_RUNNING;