Skip to content

Commit

Permalink
cxgb4: parse and configure TC-MQPRIO offload
Browse files Browse the repository at this point in the history
Add logic for validation and configuration of TC-MQPRIO Qdisc
offload. Also, add support to manage EOSW_TXQ, which have 1-to-1
mapping with EOTIDs, and expose them to network stack.

Move common skb validation in Tx path to a separate function and
add minimal Tx path for ETHOFLD. Update Tx queue selection to return
normal NIC Txq to send traffic pattern that can't go through ETHOFLD
Tx path.

Signed-off-by: Rahul Lakkireddy <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
chelsiocudbg authored and davem330 committed Nov 7, 2019
1 parent 76c3a55 commit b1396c2
Show file tree
Hide file tree
Showing 7 changed files with 597 additions and 50 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/chelsio/cxgb4/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ obj-$(CONFIG_CHELSIO_T4) += cxgb4.o
cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o \
cxgb4_uld.o srq.o sched.o cxgb4_filter.o cxgb4_tc_u32.o \
cxgb4_ptp.o cxgb4_tc_flower.o cxgb4_cudbg.o cxgb4_mps.o \
cudbg_common.o cudbg_lib.o cudbg_zlib.o
cudbg_common.o cudbg_lib.o cudbg_zlib.o cxgb4_tc_mqprio.o
cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o
cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o
cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o
Expand Down
40 changes: 40 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,38 @@ struct sge_uld_txq_info {
u16 ntxq; /* # of egress uld queues */
};

enum sge_eosw_state {
CXGB4_EO_STATE_CLOSED = 0, /* Not ready to accept traffic */
};

struct sge_eosw_desc {
struct sk_buff *skb; /* SKB to free after getting completion */
dma_addr_t addr[MAX_SKB_FRAGS + 1]; /* DMA mapped addresses */
};

struct sge_eosw_txq {
spinlock_t lock; /* Per queue lock to synchronize completions */
enum sge_eosw_state state; /* Current ETHOFLD State */
struct sge_eosw_desc *desc; /* Descriptor ring to hold packets */
u32 ndesc; /* Number of descriptors */
u32 pidx; /* Current Producer Index */
u32 last_pidx; /* Last successfully transmitted Producer Index */
u32 cidx; /* Current Consumer Index */
u32 last_cidx; /* Last successfully reclaimed Consumer Index */
u32 inuse; /* Number of packets held in ring */

u32 cred; /* Current available credits */
u32 ncompl; /* # of completions posted */
u32 last_compl; /* # of credits consumed since last completion req */

u32 eotid; /* Index into EOTID table in software */
u32 hwtid; /* Hardware EOTID index */

u32 hwqid; /* Underlying hardware queue index */
struct net_device *netdev; /* Pointer to netdevice */
struct tasklet_struct qresume_tsk; /* Restarts the queue */
};

struct sge {
struct sge_eth_txq ethtxq[MAX_ETH_QSETS];
struct sge_eth_txq ptptxq;
Expand Down Expand Up @@ -1044,6 +1076,9 @@ struct adapter {
#if IS_ENABLED(CONFIG_THERMAL)
struct ch_thermal ch_thermal;
#endif

/* TC MQPRIO offload */
struct cxgb4_tc_mqprio *tc_mqprio;
};

/* Support for "sched-class" command to allow a TX Scheduling Class to be
Expand Down Expand Up @@ -1895,6 +1930,9 @@ int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
void free_tx_desc(struct adapter *adap, struct sge_txq *q,
unsigned int n, bool unmap);
void cxgb4_eosw_txq_free_desc(struct adapter *adap, struct sge_eosw_txq *txq,
u32 ndesc);
void cxgb4_ethofld_restart(unsigned long data);
void free_txq(struct adapter *adap, struct sge_txq *q);
void cxgb4_reclaim_completed_tx(struct adapter *adap,
struct sge_txq *q, bool unmap);
Expand Down Expand Up @@ -1955,4 +1993,6 @@ int cxgb4_update_mac_filt(struct port_info *pi, unsigned int viid,
bool persistent, u8 *smt_idx);
int cxgb4_get_msix_idx_from_bmap(struct adapter *adap);
void cxgb4_free_msix_idx_in_bmap(struct adapter *adap, u32 msix_idx);
int cxgb_open(struct net_device *dev);
int cxgb_close(struct net_device *dev);
#endif /* __CXGB4_H__ */
38 changes: 35 additions & 3 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include <linux/uaccess.h>
#include <linux/crash_dump.h>
#include <net/udp_tunnel.h>
#include <net/xfrm.h>

#include "cxgb4.h"
#include "cxgb4_filter.h"
Expand All @@ -82,6 +83,7 @@
#include "sched.h"
#include "cxgb4_tc_u32.h"
#include "cxgb4_tc_flower.h"
#include "cxgb4_tc_mqprio.h"
#include "cxgb4_ptp.h"
#include "cxgb4_cudbg.h"

Expand Down Expand Up @@ -1117,6 +1119,18 @@ static u16 cxgb_select_queue(struct net_device *dev, struct sk_buff *skb,
}
#endif /* CONFIG_CHELSIO_T4_DCB */

if (dev->num_tc) {
struct port_info *pi = netdev2pinfo(dev);

/* Send unsupported traffic pattern to normal NIC queues. */
txq = netdev_pick_tx(dev, skb, sb_dev);
if (xfrm_offload(skb) || is_ptp_enabled(skb, dev) ||
ip_hdr(skb)->protocol != IPPROTO_TCP)
txq = txq % pi->nqsets;

return txq;
}

if (select_queue) {
txq = (skb_rx_queue_recorded(skb)
? skb_get_rx_queue(skb)
Expand Down Expand Up @@ -2472,11 +2486,11 @@ static void cxgb_down(struct adapter *adapter)
/*
* net_device operations
*/
static int cxgb_open(struct net_device *dev)
int cxgb_open(struct net_device *dev)
{
int err;
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
int err;

netif_carrier_off(dev);

Expand All @@ -2499,7 +2513,7 @@ static int cxgb_open(struct net_device *dev)
return err;
}

static int cxgb_close(struct net_device *dev)
int cxgb_close(struct net_device *dev)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
Expand Down Expand Up @@ -3233,6 +3247,17 @@ static int cxgb_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
}
}

static int cxgb_setup_tc_mqprio(struct net_device *dev,
struct tc_mqprio_qopt_offload *mqprio)
{
struct adapter *adap = netdev2adap(dev);

if (!is_ethofld(adap) || !adap->tc_mqprio)
return -ENOMEM;

return cxgb4_setup_tc_mqprio(dev, mqprio);
}

static LIST_HEAD(cxgb_block_cb_list);

static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
Expand All @@ -3241,6 +3266,8 @@ static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
struct port_info *pi = netdev2pinfo(dev);

switch (type) {
case TC_SETUP_QDISC_MQPRIO:
return cxgb_setup_tc_mqprio(dev, type_data);
case TC_SETUP_BLOCK:
return flow_block_cb_setup_simple(type_data,
&cxgb_block_cb_list,
Expand Down Expand Up @@ -5668,6 +5695,7 @@ static void free_some_resources(struct adapter *adapter)
kvfree(adapter->srq);
t4_cleanup_sched(adapter);
kvfree(adapter->tids.tid_tab);
cxgb4_cleanup_tc_mqprio(adapter);
cxgb4_cleanup_tc_flower(adapter);
cxgb4_cleanup_tc_u32(adapter);
kfree(adapter->sge.egr_map);
Expand Down Expand Up @@ -6237,6 +6265,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (cxgb4_init_tc_flower(adapter))
dev_warn(&pdev->dev,
"could not offload tc flower, continuing\n");

if (cxgb4_init_tc_mqprio(adapter))
dev_warn(&pdev->dev,
"could not offload tc mqprio, continuing\n");
}

if (is_offload(adapter) || is_hashfilter(adapter)) {
Expand Down
Loading

0 comments on commit b1396c2

Please sign in to comment.