Merge branch 'dpaa2-eth-add-support-for-TBF-offload'
Ioana Ciornei says: ==================== dpaa2-eth: add support for TBF offload This patch set adds support for TBF offload in dpaa2-eth. The first patch restructures how the .ndo_setup_tc() callback is implemented (each Qdisc is treated in a separate function), the second patch just adds the necessary APIs for configuring the Tx shaper and the last one is handling TC_SETUP_QDISC_TBF and configures as requested the shaper. ==================== Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#include <linux/fsl/mc.h>
|
#include <linux/fsl/mc.h>
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
#include <linux/bpf_trace.h>
|
#include <linux/bpf_trace.h>
|
||||||
|
#include <net/pkt_cls.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
|
||||||
#include "dpaa2-eth.h"
|
#include "dpaa2-eth.h"
|
||||||
@@ -2213,17 +2214,13 @@ static int update_xps(struct dpaa2_eth_priv *priv)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dpaa2_eth_setup_tc(struct net_device *net_dev,
|
static int dpaa2_eth_setup_mqprio(struct net_device *net_dev,
|
||||||
enum tc_setup_type type, void *type_data)
|
struct tc_mqprio_qopt *mqprio)
|
||||||
{
|
{
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
||||||
struct tc_mqprio_qopt *mqprio = type_data;
|
|
||||||
u8 num_tc, num_queues;
|
u8 num_tc, num_queues;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (type != TC_SETUP_QDISC_MQPRIO)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||||
num_queues = dpaa2_eth_queue_count(priv);
|
num_queues = dpaa2_eth_queue_count(priv);
|
||||||
num_tc = mqprio->num_tc;
|
num_tc = mqprio->num_tc;
|
||||||
@@ -2255,6 +2252,60 @@ out:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define bps_to_mbits(rate) (div_u64((rate), 1000000) * 8)
|
||||||
|
|
||||||
|
static int dpaa2_eth_setup_tbf(struct net_device *net_dev, struct tc_tbf_qopt_offload *p)
|
||||||
|
{
|
||||||
|
struct tc_tbf_qopt_offload_replace_params *cfg = &p->replace_params;
|
||||||
|
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
||||||
|
struct dpni_tx_shaping_cfg tx_cr_shaper = { 0 };
|
||||||
|
struct dpni_tx_shaping_cfg tx_er_shaper = { 0 };
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (p->command == TC_TBF_STATS)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* Only per port Tx shaping */
|
||||||
|
if (p->parent != TC_H_ROOT)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (p->command == TC_TBF_REPLACE) {
|
||||||
|
if (cfg->max_size > DPAA2_ETH_MAX_BURST_SIZE) {
|
||||||
|
netdev_err(net_dev, "burst size cannot be greater than %d\n",
|
||||||
|
DPAA2_ETH_MAX_BURST_SIZE);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_cr_shaper.max_burst_size = cfg->max_size;
|
||||||
|
/* The TBF interface is in bytes/s, whereas DPAA2 expects the
|
||||||
|
* rate in Mbits/s
|
||||||
|
*/
|
||||||
|
tx_cr_shaper.rate_limit = bps_to_mbits(cfg->rate.rate_bytes_ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dpni_set_tx_shaping(priv->mc_io, 0, priv->mc_token, &tx_cr_shaper,
|
||||||
|
&tx_er_shaper, 0);
|
||||||
|
if (err) {
|
||||||
|
netdev_err(net_dev, "dpni_set_tx_shaping() = %d\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dpaa2_eth_setup_tc(struct net_device *net_dev,
|
||||||
|
enum tc_setup_type type, void *type_data)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case TC_SETUP_QDISC_MQPRIO:
|
||||||
|
return dpaa2_eth_setup_mqprio(net_dev, type_data);
|
||||||
|
case TC_SETUP_QDISC_TBF:
|
||||||
|
return dpaa2_eth_setup_tbf(net_dev, type_data);
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct net_device_ops dpaa2_eth_ops = {
|
static const struct net_device_ops dpaa2_eth_ops = {
|
||||||
.ndo_open = dpaa2_eth_open,
|
.ndo_open = dpaa2_eth_open,
|
||||||
.ndo_start_xmit = dpaa2_eth_tx,
|
.ndo_start_xmit = dpaa2_eth_tx,
|
||||||
@@ -3719,7 +3770,7 @@ static int netdev_init(struct net_device *net_dev)
|
|||||||
net_dev->features = NETIF_F_RXCSUM |
|
net_dev->features = NETIF_F_RXCSUM |
|
||||||
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
||||||
NETIF_F_SG | NETIF_F_HIGHDMA |
|
NETIF_F_SG | NETIF_F_HIGHDMA |
|
||||||
NETIF_F_LLTX;
|
NETIF_F_LLTX | NETIF_F_HW_TC;
|
||||||
net_dev->hw_features = net_dev->features;
|
net_dev->hw_features = net_dev->features;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -43,6 +43,9 @@
|
|||||||
*/
|
*/
|
||||||
#define DPAA2_ETH_FQ_TAILDROP_THRESH (1024 * 1024)
|
#define DPAA2_ETH_FQ_TAILDROP_THRESH (1024 * 1024)
|
||||||
|
|
||||||
|
/* Maximum burst size value for Tx shaping */
|
||||||
|
#define DPAA2_ETH_MAX_BURST_SIZE 0xF7FF
|
||||||
|
|
||||||
/* Maximum number of Tx confirmation frames to be processed
|
/* Maximum number of Tx confirmation frames to be processed
|
||||||
* in a single NAPI call
|
* in a single NAPI call
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -626,4 +626,17 @@ struct dpni_cmd_set_congestion_notification {
|
|||||||
__le32 threshold_exit;
|
__le32 threshold_exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DPNI_COUPLED_SHIFT 0
|
||||||
|
#define DPNI_COUPLED_SIZE 1
|
||||||
|
|
||||||
|
struct dpni_cmd_set_tx_shaping {
|
||||||
|
__le16 tx_cr_max_burst_size;
|
||||||
|
__le16 tx_er_max_burst_size;
|
||||||
|
__le32 pad;
|
||||||
|
__le32 tx_cr_rate_limit;
|
||||||
|
__le32 tx_er_rate_limit;
|
||||||
|
/* from LSB: coupled:1 */
|
||||||
|
u8 coupled;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _FSL_DPNI_CMD_H */
|
#endif /* _FSL_DPNI_CMD_H */
|
||||||
|
|||||||
@@ -1963,3 +1963,39 @@ int dpni_clear_qos_table(struct fsl_mc_io *mc_io,
|
|||||||
/* send command to mc*/
|
/* send command to mc*/
|
||||||
return mc_send_command(mc_io, &cmd);
|
return mc_send_command(mc_io, &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dpni_set_tx_shaping() - Set the transmit shaping
|
||||||
|
* @mc_io: Pointer to MC portal's I/O object
|
||||||
|
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
|
||||||
|
* @token: Token of DPNI object
|
||||||
|
* @tx_cr_shaper: TX committed rate shaping configuration
|
||||||
|
* @tx_er_shaper: TX excess rate shaping configuration
|
||||||
|
* @coupled: Committed and excess rate shapers are coupled
|
||||||
|
*
|
||||||
|
* Return: '0' on Success; Error code otherwise.
|
||||||
|
*/
|
||||||
|
int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
|
||||||
|
u32 cmd_flags,
|
||||||
|
u16 token,
|
||||||
|
const struct dpni_tx_shaping_cfg *tx_cr_shaper,
|
||||||
|
const struct dpni_tx_shaping_cfg *tx_er_shaper,
|
||||||
|
int coupled)
|
||||||
|
{
|
||||||
|
struct dpni_cmd_set_tx_shaping *cmd_params;
|
||||||
|
struct fsl_mc_command cmd = { 0 };
|
||||||
|
|
||||||
|
/* prepare command */
|
||||||
|
cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING,
|
||||||
|
cmd_flags,
|
||||||
|
token);
|
||||||
|
cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params;
|
||||||
|
cmd_params->tx_cr_max_burst_size = cpu_to_le16(tx_cr_shaper->max_burst_size);
|
||||||
|
cmd_params->tx_er_max_burst_size = cpu_to_le16(tx_er_shaper->max_burst_size);
|
||||||
|
cmd_params->tx_cr_rate_limit = cpu_to_le32(tx_cr_shaper->rate_limit);
|
||||||
|
cmd_params->tx_er_rate_limit = cpu_to_le32(tx_er_shaper->rate_limit);
|
||||||
|
dpni_set_field(cmd_params->coupled, COUPLED, coupled);
|
||||||
|
|
||||||
|
/* send command to mc*/
|
||||||
|
return mc_send_command(mc_io, &cmd);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1062,5 +1062,21 @@ int dpni_get_api_version(struct fsl_mc_io *mc_io,
|
|||||||
u32 cmd_flags,
|
u32 cmd_flags,
|
||||||
u16 *major_ver,
|
u16 *major_ver,
|
||||||
u16 *minor_ver);
|
u16 *minor_ver);
|
||||||
|
/**
|
||||||
|
* struct dpni_tx_shaping - Structure representing DPNI tx shaping configuration
|
||||||
|
* @rate_limit: Rate in Mbps
|
||||||
|
* @max_burst_size: Burst size in bytes (up to 64KB)
|
||||||
|
*/
|
||||||
|
struct dpni_tx_shaping_cfg {
|
||||||
|
u32 rate_limit;
|
||||||
|
u16 max_burst_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
|
||||||
|
u32 cmd_flags,
|
||||||
|
u16 token,
|
||||||
|
const struct dpni_tx_shaping_cfg *tx_cr_shaper,
|
||||||
|
const struct dpni_tx_shaping_cfg *tx_er_shaper,
|
||||||
|
int coupled);
|
||||||
|
|
||||||
#endif /* __FSL_DPNI_H */
|
#endif /* __FSL_DPNI_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user