Commit e3951539 authored by Edward Cree's avatar Edward Cree Committed by David S. Miller

sfc: add ability for an RXQ to grant credits on refill

EF100 hardware streams MAE counter updates to the driver over a dedicated
 RX queue; however, the MCPU is not able to detect when RX buffers have
 been posted to the ring.  Thus, the driver must call
 MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS; this patch adds the
 infrastructure to support that to the core RXQ handling code.
Signed-off-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5ae0c226
...@@ -183,24 +183,32 @@ void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event) ...@@ -183,24 +183,32 @@ void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event)
void ef100_rx_write(struct efx_rx_queue *rx_queue) void ef100_rx_write(struct efx_rx_queue *rx_queue)
{ {
unsigned int notified_count = rx_queue->notified_count;
struct efx_rx_buffer *rx_buf; struct efx_rx_buffer *rx_buf;
unsigned int idx; unsigned int idx;
efx_qword_t *rxd; efx_qword_t *rxd;
efx_dword_t rxdb; efx_dword_t rxdb;
while (rx_queue->notified_count != rx_queue->added_count) { while (notified_count != rx_queue->added_count) {
idx = rx_queue->notified_count & rx_queue->ptr_mask; idx = notified_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, idx); rx_buf = efx_rx_buffer(rx_queue, idx);
rxd = efx_rx_desc(rx_queue, idx); rxd = efx_rx_desc(rx_queue, idx);
EFX_POPULATE_QWORD_1(*rxd, ESF_GZ_RX_BUF_ADDR, rx_buf->dma_addr); EFX_POPULATE_QWORD_1(*rxd, ESF_GZ_RX_BUF_ADDR, rx_buf->dma_addr);
++rx_queue->notified_count; ++notified_count;
} }
if (notified_count == rx_queue->notified_count)
return;
wmb(); wmb();
EFX_POPULATE_DWORD_1(rxdb, ERF_GZ_RX_RING_PIDX, EFX_POPULATE_DWORD_1(rxdb, ERF_GZ_RX_RING_PIDX,
rx_queue->added_count & rx_queue->ptr_mask); rx_queue->added_count & rx_queue->ptr_mask);
efx_writed_page(rx_queue->efx, &rxdb, efx_writed_page(rx_queue->efx, &rxdb,
ER_GZ_RX_RING_DOORBELL, efx_rx_queue_index(rx_queue)); ER_GZ_RX_RING_DOORBELL, efx_rx_queue_index(rx_queue));
if (rx_queue->grant_credits)
wmb();
rx_queue->notified_count = notified_count;
if (rx_queue->grant_credits)
schedule_work(&rx_queue->grant_work);
} }
...@@ -363,8 +363,12 @@ struct efx_rx_page_state { ...@@ -363,8 +363,12 @@ struct efx_rx_page_state {
* @refill_enabled: Enable refill whenever fill level is low * @refill_enabled: Enable refill whenever fill level is low
* @flush_pending: Set when a RX flush is pending. Has the same lifetime as * @flush_pending: Set when a RX flush is pending. Has the same lifetime as
* @rxq_flush_pending. * @rxq_flush_pending.
* @grant_credits: Posted RX descriptors need to be granted to the MAE with
* %MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS. For %EFX_EXTRA_CHANNEL_TC,
* and only supported on EF100.
* @added_count: Number of buffers added to the receive queue. * @added_count: Number of buffers added to the receive queue.
* @notified_count: Number of buffers given to NIC (<= @added_count). * @notified_count: Number of buffers given to NIC (<= @added_count).
* @granted_count: Number of buffers granted to the MAE (<= @notified_count).
* @removed_count: Number of buffers removed from the receive queue. * @removed_count: Number of buffers removed from the receive queue.
* @scatter_n: Used by NIC specific receive code. * @scatter_n: Used by NIC specific receive code.
* @scatter_len: Used by NIC specific receive code. * @scatter_len: Used by NIC specific receive code.
...@@ -385,6 +389,7 @@ struct efx_rx_page_state { ...@@ -385,6 +389,7 @@ struct efx_rx_page_state {
* refill was triggered. * refill was triggered.
* @recycle_count: RX buffer recycle counter. * @recycle_count: RX buffer recycle counter.
* @slow_fill: Timer used to defer efx_nic_generate_fill_event(). * @slow_fill: Timer used to defer efx_nic_generate_fill_event().
* @grant_work: workitem used to grant credits to the MAE if @grant_credits
* @xdp_rxq_info: XDP specific RX queue information. * @xdp_rxq_info: XDP specific RX queue information.
* @xdp_rxq_info_valid: Is xdp_rxq_info valid data?. * @xdp_rxq_info_valid: Is xdp_rxq_info valid data?.
*/ */
...@@ -396,9 +401,11 @@ struct efx_rx_queue { ...@@ -396,9 +401,11 @@ struct efx_rx_queue {
unsigned int ptr_mask; unsigned int ptr_mask;
bool refill_enabled; bool refill_enabled;
bool flush_pending; bool flush_pending;
bool grant_credits;
unsigned int added_count; unsigned int added_count;
unsigned int notified_count; unsigned int notified_count;
unsigned int granted_count;
unsigned int removed_count; unsigned int removed_count;
unsigned int scatter_n; unsigned int scatter_n;
unsigned int scatter_len; unsigned int scatter_len;
...@@ -416,6 +423,7 @@ struct efx_rx_queue { ...@@ -416,6 +423,7 @@ struct efx_rx_queue {
unsigned int recycle_count; unsigned int recycle_count;
struct timer_list slow_fill; struct timer_list slow_fill;
unsigned int slow_fill_count; unsigned int slow_fill_count;
struct work_struct grant_work;
/* Statistics to supplement MAC stats */ /* Statistics to supplement MAC stats */
unsigned long rx_packets; unsigned long rx_packets;
struct xdp_rxq_info xdp_rxq_info; struct xdp_rxq_info xdp_rxq_info;
......
...@@ -229,6 +229,7 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) ...@@ -229,6 +229,7 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
/* Initialise ptr fields */ /* Initialise ptr fields */
rx_queue->added_count = 0; rx_queue->added_count = 0;
rx_queue->notified_count = 0; rx_queue->notified_count = 0;
rx_queue->granted_count = 0;
rx_queue->removed_count = 0; rx_queue->removed_count = 0;
rx_queue->min_fill = -1U; rx_queue->min_fill = -1U;
efx_init_rx_recycle_ring(rx_queue); efx_init_rx_recycle_ring(rx_queue);
...@@ -281,6 +282,8 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) ...@@ -281,6 +282,8 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
"shutting down RX queue %d\n", efx_rx_queue_index(rx_queue)); "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
del_timer_sync(&rx_queue->slow_fill); del_timer_sync(&rx_queue->slow_fill);
if (rx_queue->grant_credits)
flush_work(&rx_queue->grant_work);
/* Release RX buffers from the current read ptr to the write ptr */ /* Release RX buffers from the current read ptr to the write ptr */
if (rx_queue->buffer) { if (rx_queue->buffer) {
......
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