Skip to content

Commit

Permalink
octeontx2-pf: Add support for HTB offload
Browse files Browse the repository at this point in the history
This patch registers callbacks to support HTB offload.

Below are features supported,

- supports traffic shaping on the given class by honoring rate and ceil
configuration.

- supports traffic scheduling,  which prioritizes different types of
traffic based on strict priority values.

- supports the creation of leaf to inner classes such that parent node
rate limits apply to all child nodes.

Signed-off-by: Naveen Mamindlapalli <[email protected]>
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Kovvuri Goutham <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Naveen Mamindlapalli authored and davem330 committed May 15, 2023
1 parent cb748a7 commit 5e6808b
Show file tree
Hide file tree
Showing 10 changed files with 1,507 additions and 14 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ enum nix_scheduler {

#define TXSCH_RR_QTM_MAX ((1 << 24) - 1)
#define TXSCH_TL1_DFLT_RR_QTM TXSCH_RR_QTM_MAX
#define TXSCH_TL1_DFLT_RR_PRIO (0x1ull)
#define TXSCH_TL1_DFLT_RR_PRIO (0x7ull)
#define CN10K_MAX_DWRR_WEIGHT 16384 /* Weight is 14bit on CN10K */

/* Min/Max packet sizes, excluding FCS */
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o otx2_ptp.o

rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \
otx2_devlink.o qos_sq.o
otx2_devlink.o qos_sq.o qos.o
rvu_nicvf-y := otx2_vf.o otx2_devlink.o

rvu_nicpf-$(CONFIG_DCB) += otx2_dcbnl.o
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ int otx2_update_sq_stats(struct otx2_nic *pfvf, int qidx)
if (!pfvf->qset.sq)
return 0;

if (qidx >= pfvf->hw.non_qos_queues) {
if (!test_bit(qidx - pfvf->hw.non_qos_queues, pfvf->qos.qos_sq_bmap))
return 0;
}

otx2_nix_sq_op_stats(&sq->stats, pfvf, qidx);
return 1;
}
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1099,8 +1099,18 @@ static inline void otx2_qos_init(struct otx2_nic *pfvf, int qos_txqs)
struct otx2_hw *hw = &pfvf->hw;

hw->tc_tx_queues = qos_txqs;
INIT_LIST_HEAD(&pfvf->qos.qos_tree);
mutex_init(&pfvf->qos.qos_lock);
}

static inline void otx2_shutdown_qos(struct otx2_nic *pfvf)
{
mutex_destroy(&pfvf->qos.qos_lock);
}

u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb,
struct net_device *sb_dev);
int otx2_get_txq_by_classid(struct otx2_nic *pfvf, u16 classid);
void otx2_qos_config_txschq(struct otx2_nic *pfvf);
void otx2_clean_qos_queues(struct otx2_nic *pfvf);
#endif /* OTX2_COMMON_H */
53 changes: 50 additions & 3 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,9 @@ static void otx2_free_sq_res(struct otx2_nic *pf)
otx2_sq_free_sqbs(pf);
for (qidx = 0; qidx < otx2_get_total_tx_queues(pf); qidx++) {
sq = &qset->sq[qidx];
/* Skip freeing Qos queues if they are not initialized */
if (!sq->sqe)
continue;
qmem_free(pf->dev, sq->sqe);
qmem_free(pf->dev, sq->tso_hdrs);
kfree(sq->sg);
Expand Down Expand Up @@ -1566,6 +1569,8 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
otx2_pfc_txschq_stop(pf);
#endif

otx2_clean_qos_queues(pf);

mutex_lock(&mbox->lock);
/* Disable backpressure */
if (!(pf->pcifunc & RVU_PFVF_FUNC_MASK))
Expand Down Expand Up @@ -1710,7 +1715,7 @@ int otx2_open(struct net_device *netdev)
if (!qset->cq)
goto err_free_mem;

qset->sq = kcalloc(pf->hw.non_qos_queues,
qset->sq = kcalloc(otx2_get_total_tx_queues(pf),
sizeof(struct otx2_snd_queue), GFP_KERNEL);
if (!qset->sq)
goto err_free_mem;
Expand Down Expand Up @@ -1833,6 +1838,9 @@ int otx2_open(struct net_device *netdev)
/* 'intf_down' may be checked on any cpu */
smp_wmb();

/* Enable QoS configuration before starting tx queues */
otx2_qos_config_txschq(pf);

/* we have already received link status notification */
if (pf->linfo.link_up && !(pf->pcifunc & RVU_PFVF_FUNC_MASK))
otx2_handle_link_event(pf);
Expand Down Expand Up @@ -1986,14 +1994,48 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}

static int otx2_qos_select_htb_queue(struct otx2_nic *pf, struct sk_buff *skb,
u16 htb_maj_id)
{
u16 classid;

if ((TC_H_MAJ(skb->priority) >> 16) == htb_maj_id)
classid = TC_H_MIN(skb->priority);
else
classid = READ_ONCE(pf->qos.defcls);

if (!classid)
return 0;

return otx2_get_txq_by_classid(pf, classid);
}

u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb,
struct net_device *sb_dev)
{
#ifdef CONFIG_DCB
struct otx2_nic *pf = netdev_priv(netdev);
bool qos_enabled;
#ifdef CONFIG_DCB
u8 vlan_prio;
#endif
int txq;

qos_enabled = (netdev->real_num_tx_queues > pf->hw.tx_queues) ? true : false;
if (unlikely(qos_enabled)) {
/* This smp_load_acquire() pairs with smp_store_release() in
* otx2_qos_root_add() called from htb offload root creation
*/
u16 htb_maj_id = smp_load_acquire(&pf->qos.maj_id);

if (unlikely(htb_maj_id)) {
txq = otx2_qos_select_htb_queue(pf, skb, htb_maj_id);
if (txq > 0)
return txq;
goto process_pfc;
}
}

process_pfc:
#ifdef CONFIG_DCB
if (!skb_vlan_tag_present(skb))
goto pick_tx;
Expand All @@ -2007,7 +2049,11 @@ u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb,

pick_tx:
#endif
return netdev_pick_tx(netdev, skb, NULL);
txq = netdev_pick_tx(netdev, skb, NULL);
if (unlikely(qos_enabled))
return txq % pf->hw.tx_queues;

return txq;
}
EXPORT_SYMBOL(otx2_select_queue);

Expand Down Expand Up @@ -3121,6 +3167,7 @@ static void otx2_remove(struct pci_dev *pdev)
otx2_ptp_destroy(pf);
otx2_mcam_flow_del(pf);
otx2_shutdown_tc(pf);
otx2_shutdown_qos(pf);
otx2_detach_resources(&pf->mbox);
if (pf->hw.lmt_info)
free_percpu(pf->hw.lmt_info);
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "cn10k.h"
#include "otx2_common.h"
#include "qos.h"

#define CN10K_MAX_BURST_MANTISSA 0x7FFFULL
#define CN10K_MAX_BURST_SIZE 8453888ULL
Expand Down Expand Up @@ -132,8 +133,8 @@ static void otx2_get_egress_rate_cfg(u64 maxrate, u32 *exp,
}
}

static u64 otx2_get_txschq_rate_regval(struct otx2_nic *nic,
u64 maxrate, u32 burst)
u64 otx2_get_txschq_rate_regval(struct otx2_nic *nic,
u64 maxrate, u32 burst)
{
u32 burst_exp, burst_mantissa;
u32 exp, mantissa, div_exp;
Expand Down Expand Up @@ -1109,6 +1110,8 @@ int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
switch (type) {
case TC_SETUP_BLOCK:
return otx2_setup_tc_block(netdev, type_data);
case TC_SETUP_QDISC_HTB:
return otx2_setup_tc_htb(netdev, type_data);
default:
return -EOPNOTSUPP;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ static void otx2vf_remove(struct pci_dev *pdev)
otx2_ptp_destroy(vf);
otx2_mcam_flow_del(vf);
otx2_shutdown_tc(vf);
otx2_shutdown_qos(vf);
otx2vf_disable_mbox_intr(vf);
otx2_detach_resources(&vf->mbox);
free_percpu(vf->hw.lmt_info);
Expand Down
Loading

0 comments on commit 5e6808b

Please sign in to comment.