Commit 40bf06a1 authored by Alexander Duyck's avatar Alexander Duyck Committed by Jakub Kicinski

eth: fbnic: Implement Tx queue alloc/start/stop/free

Implement basic management operations for Tx queues.
Allocate memory for submission and completion rings.
Learn how to start the queues, stop them, and wait for HW
to be idle.

We call HW rings "descriptor rings" (stored in ring->desc),
and SW context rings "buffer rings" (stored in ring->*_buf union).

This is the first patch which actually touches CSRs so add CSR
helpers.

No actual datapath / packet handling here, yet.
Signed-off-by: default avatarAlexander Duyck <alexanderduyck@fb.com>
Link: https://patch.msgid.link/172079938724.1778861.8329677776612865169.stgit@ahduyck-xeon-server.home.arpaSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent bc610777
......@@ -61,10 +61,18 @@
#define FBNIC_INTR_CQ_REARM_INTR_RELOAD CSR_BIT(30)
#define FBNIC_INTR_CQ_REARM_INTR_UNMASK CSR_BIT(31)
#define FBNIC_INTR_RCQ_TIMEOUT(n) \
(0x00401 + 4 * (n)) /* 0x01004 + 16*n */
#define FBNIC_INTR_RCQ_TIMEOUT_CNT 256
#define FBNIC_INTR_TCQ_TIMEOUT(n) \
(0x00402 + 4 * (n)) /* 0x01008 + 16*n */
#define FBNIC_INTR_TCQ_TIMEOUT_CNT 256
#define FBNIC_CSR_END_INTR_CQ 0x007fe /* CSR section delimiter */
/* Global QM Tx registers */
#define FBNIC_CSR_START_QM_TX 0x00800 /* CSR section delimiter */
#define FBNIC_QM_TWQ_IDLE(n) (0x00800 + (n)) /* 0x02000 + 4*n */
#define FBNIC_QM_TWQ_IDLE_CNT 8
#define FBNIC_QM_TWQ_DEFAULT_META_L 0x00818 /* 0x02060 */
#define FBNIC_QM_TWQ_DEFAULT_META_H 0x00819 /* 0x02064 */
......@@ -86,10 +94,16 @@ enum {
#define FBNIC_QM_TQS_MTU_CTL0 0x0081d /* 0x02074 */
#define FBNIC_QM_TQS_MTU_CTL1 0x0081e /* 0x02078 */
#define FBNIC_QM_TQS_MTU_CTL1_BULK CSR_GENMASK(13, 0)
#define FBNIC_QM_TCQ_IDLE(n) (0x00821 + (n)) /* 0x02084 + 4*n */
#define FBNIC_QM_TCQ_IDLE_CNT 4
#define FBNIC_QM_TCQ_CTL0 0x0082d /* 0x020b4 */
#define FBNIC_QM_TCQ_CTL0_COAL_WAIT CSR_GENMASK(15, 0)
#define FBNIC_QM_TCQ_CTL0_TICK_CYCLES CSR_GENMASK(26, 16)
#define FBNIC_QM_TQS_IDLE(n) (0x00830 + (n)) /* 0x020c0 + 4*n */
#define FBNIC_QM_TQS_IDLE_CNT 8
#define FBNIC_QM_TQS_EDT_TS_RANGE 0x00849 /* 0x2124 */
#define FBNIC_QM_TDE_IDLE(n) (0x00853 + (n)) /* 0x0214c + 4*n */
#define FBNIC_QM_TDE_IDLE_CNT 8
#define FBNIC_QM_TNI_TDF_CTL 0x0086c /* 0x021b0 */
#define FBNIC_QM_TNI_TDF_CTL_MRRS CSR_GENMASK(1, 0)
#define FBNIC_QM_TNI_TDF_CTL_CLS CSR_GENMASK(3, 2)
......@@ -110,9 +124,15 @@ enum {
/* Global QM Rx registers */
#define FBNIC_CSR_START_QM_RX 0x00c00 /* CSR section delimiter */
#define FBNIC_QM_RCQ_IDLE(n) (0x00c00 + (n)) /* 0x03000 + 0x4*n */
#define FBNIC_QM_RCQ_IDLE_CNT 4
#define FBNIC_QM_RCQ_CTL0 0x00c0c /* 0x03030 */
#define FBNIC_QM_RCQ_CTL0_COAL_WAIT CSR_GENMASK(15, 0)
#define FBNIC_QM_RCQ_CTL0_TICK_CYCLES CSR_GENMASK(26, 16)
#define FBNIC_QM_HPQ_IDLE(n) (0x00c0f + (n)) /* 0x0303c + 0x4*n */
#define FBNIC_QM_HPQ_IDLE_CNT 4
#define FBNIC_QM_PPQ_IDLE(n) (0x00c13 + (n)) /* 0x0304c + 0x4*n */
#define FBNIC_QM_PPQ_IDLE_CNT 4
#define FBNIC_QM_RNI_RBP_CTL 0x00c2d /* 0x030b4 */
#define FBNIC_QM_RNI_RBP_CTL_MRRS CSR_GENMASK(1, 0)
#define FBNIC_QM_RNI_RBP_CTL_CLS CSR_GENMASK(3, 2)
......@@ -219,6 +239,8 @@ enum {
/* TMI registers */
#define FBNIC_CSR_START_TMI 0x04400 /* CSR section delimiter */
#define FBNIC_TMI_SOP_PROT_CTRL 0x04400 /* 0x11000 */
#define FBNIC_TMI_DROP_CTRL 0x04401 /* 0x11004 */
#define FBNIC_TMI_DROP_CTRL_EN CSR_BIT(0)
#define FBNIC_CSR_END_TMI 0x0443f /* CSR section delimiter */
/* Rx Buffer Registers */
#define FBNIC_CSR_START_RXB 0x08000 /* CSR section delimiter */
......@@ -382,22 +404,52 @@ enum {
#define FBNIC_QUEUE_TWQ1_CTL 0x001 /* 0x004 */
#define FBNIC_QUEUE_TWQ_CTL_RESET CSR_BIT(0)
#define FBNIC_QUEUE_TWQ_CTL_ENABLE CSR_BIT(1)
#define FBNIC_QUEUE_TWQ_CTL_PREFETCH_DISABLE CSR_BIT(2)
#define FBNIC_QUEUE_TWQ_CTL_TXB_FIFO_SEL_MASK CSR_GENMASK(30, 29)
enum {
FBNIC_QUEUE_TWQ_CTL_TXB_SHARED = 0,
FBNIC_QUEUE_TWQ_CTL_TXB_EI_DATA = 1,
FBNIC_QUEUE_TWQ_CTL_TXB_EI_CTL = 2,
};
#define FBNIC_QUEUE_TWQ_CTL_AGGR_MODE CSR_BIT(31)
#define FBNIC_QUEUE_TWQ0_TAIL 0x002 /* 0x008 */
#define FBNIC_QUEUE_TWQ1_TAIL 0x003 /* 0x00c */
#define FBNIC_QUEUE_TWQ0_SIZE 0x00a /* 0x028 */
#define FBNIC_QUEUE_TWQ1_SIZE 0x00b /* 0x02c */
#define FBNIC_QUEUE_TWQ_SIZE_MASK CSR_GENMASK(3, 0)
#define FBNIC_QUEUE_TWQ0_BAL 0x020 /* 0x080 */
#define FBNIC_QUEUE_BAL_MASK CSR_GENMASK(31, 7)
#define FBNIC_QUEUE_TWQ0_BAH 0x021 /* 0x084 */
#define FBNIC_QUEUE_TWQ1_BAL 0x022 /* 0x088 */
#define FBNIC_QUEUE_TWQ1_BAH 0x023 /* 0x08c */
/* Tx Completion Queue Registers */
#define FBNIC_QUEUE_TCQ_CTL 0x080 /* 0x200 */
#define FBNIC_QUEUE_TCQ_CTL_RESET CSR_BIT(0)
#define FBNIC_QUEUE_TCQ_CTL_ENABLE CSR_BIT(1)
#define FBNIC_QUEUE_TCQ_HEAD 0x081 /* 0x204 */
#define FBNIC_QUEUE_TCQ_SIZE 0x084 /* 0x210 */
#define FBNIC_QUEUE_TCQ_SIZE_MASK CSR_GENMASK(3, 0)
#define FBNIC_QUEUE_TCQ_BAL 0x0a0 /* 0x280 */
#define FBNIC_QUEUE_TCQ_BAH 0x0a1 /* 0x284 */
/* Tx Interrupt Manager Registers */
#define FBNIC_QUEUE_TIM_CTL 0x0c0 /* 0x300 */
#define FBNIC_QUEUE_TIM_CTL_MSIX_MASK CSR_GENMASK(7, 0)
#define FBNIC_QUEUE_TIM_THRESHOLD 0x0c1 /* 0x304 */
#define FBNIC_QUEUE_TIM_THRESHOLD_TWD_MASK CSR_GENMASK(14, 0)
#define FBNIC_QUEUE_TIM_CLEAR 0x0c2 /* 0x308 */
#define FBNIC_QUEUE_TIM_CLEAR_MASK CSR_BIT(0)
#define FBNIC_QUEUE_TIM_SET 0x0c3 /* 0x30c */
#define FBNIC_QUEUE_TIM_SET_MASK CSR_BIT(0)
#define FBNIC_QUEUE_TIM_MASK 0x0c4 /* 0x310 */
#define FBNIC_QUEUE_TIM_MASK_MASK CSR_BIT(0)
#define FBNIC_QUEUE_TIM_TIMER 0x0c5 /* 0x314 */
#define FBNIC_QUEUE_TIM_COUNTS 0x0c6 /* 0x318 */
#define FBNIC_QUEUE_TIM_COUNTS_CNT1_MASK CSR_GENMASK(30, 16)
#define FBNIC_QUEUE_TIM_COUNTS_CNT0_MASK CSR_GENMASK(14, 0)
/* Rx Completion Queue Registers */
#define FBNIC_QUEUE_RCQ_HEAD 0x201 /* 0x804 */
......
......@@ -17,6 +17,10 @@ int __fbnic_open(struct fbnic_net *fbn)
if (err)
return err;
err = fbnic_alloc_resources(fbn);
if (err)
goto free_napi_vectors;
err = netif_set_real_num_tx_queues(fbn->netdev,
fbn->num_tx_queues);
if (err)
......@@ -29,6 +33,8 @@ int __fbnic_open(struct fbnic_net *fbn)
return 0;
free_resources:
fbnic_free_resources(fbn);
free_napi_vectors:
fbnic_free_napi_vectors(fbn);
return err;
}
......@@ -51,6 +57,7 @@ static int fbnic_stop(struct net_device *netdev)
fbnic_down(fbn);
fbnic_free_resources(fbn);
fbnic_free_napi_vectors(fbn);
return 0;
......@@ -123,6 +130,8 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
fbn->fbd = fbd;
INIT_LIST_HEAD(&fbn->napis);
fbn->txq_size = FBNIC_TXQ_SIZE_DEFAULT;
default_queues = netif_get_num_default_rss_queues();
if (default_queues > fbd->max_num_queues)
default_queues = fbd->max_num_queues;
......
......@@ -15,6 +15,8 @@ struct fbnic_net {
struct net_device *netdev;
struct fbnic_dev *fbd;
u32 txq_size;
u16 num_napi;
u16 num_tx_queues;
......
......@@ -127,16 +127,33 @@ static void fbnic_service_task_stop(struct fbnic_net *fbn)
void fbnic_up(struct fbnic_net *fbn)
{
fbnic_enable(fbn);
/* Enable Tx/Rx processing */
fbnic_napi_enable(fbn);
netif_tx_start_all_queues(fbn->netdev);
fbnic_service_task_start(fbn);
}
void fbnic_down(struct fbnic_net *fbn)
static void fbnic_down_noidle(struct fbnic_net *fbn)
{
fbnic_service_task_stop(fbn);
/* Disable Tx/Rx Processing */
fbnic_napi_disable(fbn);
netif_tx_disable(fbn->netdev);
fbnic_disable(fbn);
}
void fbnic_down(struct fbnic_net *fbn)
{
fbnic_down_noidle(fbn);
fbnic_wait_all_queues_idle(fbn->fbd, false);
fbnic_flush(fbn);
}
static void fbnic_service_task(struct work_struct *work)
......
......@@ -12,17 +12,30 @@ struct fbnic_net;
#define FBNIC_MAX_TXQS 128u
#define FBNIC_MAX_RXQS 128u
#define FBNIC_TXQ_SIZE_DEFAULT 1024
#define FBNIC_RING_F_DISABLED BIT(0)
#define FBNIC_RING_F_CTX BIT(1)
#define FBNIC_RING_F_STATS BIT(2) /* Ring's stats may be used */
struct fbnic_ring {
/* Pointer to buffer specific info */
union {
void **tx_buf; /* TWQ */
void *buffer; /* Generic pointer */
};
u32 __iomem *doorbell; /* Pointer to CSR space for ring */
__le64 *desc; /* Descriptor ring memory */
u16 size_mask; /* Size of ring in descriptors - 1 */
u8 q_idx; /* Logical netdev ring index */
u8 flags; /* Ring flags (FBNIC_RING_F_*) */
u32 head, tail; /* Head/Tail of ring */
/* Slow path fields follow */
dma_addr_t dma; /* Phys addr of descriptor memory */
size_t size; /* Size of descriptor ring in memory */
};
struct fbnic_q_triad {
......@@ -51,5 +64,14 @@ netdev_tx_t fbnic_xmit_frame(struct sk_buff *skb, struct net_device *dev);
int fbnic_alloc_napi_vectors(struct fbnic_net *fbn);
void fbnic_free_napi_vectors(struct fbnic_net *fbn);
int fbnic_alloc_resources(struct fbnic_net *fbn);
void fbnic_free_resources(struct fbnic_net *fbn);
void fbnic_napi_enable(struct fbnic_net *fbn);
void fbnic_napi_disable(struct fbnic_net *fbn);
void fbnic_enable(struct fbnic_net *fbn);
void fbnic_disable(struct fbnic_net *fbn);
void fbnic_flush(struct fbnic_net *fbn);
int fbnic_wait_all_queues_idle(struct fbnic_dev *fbd, bool may_fail);
#endif /* _FBNIC_TXRX_H_ */
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