Commit 78485054 authored by Sara Sharon's avatar Sara Sharon Committed by Emmanuel Grumbach

iwlwifi: pcie: add infrastructure for multi-queue rx

The 9000 series devices will support multi rx queues.
Current code has one static rx queue - change it to allocate
a number of queues per the device capability (pre-9000 devices
have the number of rx queues set to one).

Subsequent generalizations are:

Change the code to access an explicit numbered rx queue only
when the queue number is known - when handling interrupt, when
accessing the default queue and when iterating the queues.
The rest of the functions will receive the rx queue as a pointer.

Generalize the warning in allocation failure to consider the
allocator status instead of a single rx queue status.

Move the rx initial pool of memory buffers to be shared among
all the queues and allocated to the default queue on init.
Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 3955525d
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
#define RX_POST_REQ_ALLOC 2 #define RX_POST_REQ_ALLOC 2
#define RX_CLAIM_REQ_ALLOC 8 #define RX_CLAIM_REQ_ALLOC 8
#define RX_POOL_SIZE ((RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC) * RX_NUM_QUEUES) #define RX_POOL_SIZE ((RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC) * RX_NUM_QUEUES)
#define RX_LOW_WATERMARK 8 #define RX_PENDING_WATERMARK 16
struct iwl_host_cmd; struct iwl_host_cmd;
...@@ -103,7 +103,6 @@ struct isr_statistics { ...@@ -103,7 +103,6 @@ struct isr_statistics {
* @rb_stts: driver's pointer to receive buffer status * @rb_stts: driver's pointer to receive buffer status
* @rb_stts_dma: bus address of receive buffer status * @rb_stts_dma: bus address of receive buffer status
* @lock: * @lock:
* @pool: initial pool of iwl_rx_mem_buffer for the queue
* @queue: actual rx queue * @queue: actual rx queue
* *
* NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
...@@ -122,7 +121,6 @@ struct iwl_rxq { ...@@ -122,7 +121,6 @@ struct iwl_rxq {
struct iwl_rb_status *rb_stts; struct iwl_rb_status *rb_stts;
dma_addr_t rb_stts_dma; dma_addr_t rb_stts_dma;
spinlock_t lock; spinlock_t lock;
struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE];
struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
}; };
...@@ -298,6 +296,7 @@ struct iwl_tso_hdr_page { ...@@ -298,6 +296,7 @@ struct iwl_tso_hdr_page {
/** /**
* struct iwl_trans_pcie - PCIe transport specific data * struct iwl_trans_pcie - PCIe transport specific data
* @rxq: all the RX queue data * @rxq: all the RX queue data
* @rx_pool: initial pool of iwl_rx_mem_buffer for all the queues
* @rba: allocator for RX replenishing * @rba: allocator for RX replenishing
* @drv - pointer to iwl_drv * @drv - pointer to iwl_drv
* @trans: pointer to the generic transport area * @trans: pointer to the generic transport area
...@@ -324,7 +323,8 @@ struct iwl_tso_hdr_page { ...@@ -324,7 +323,8 @@ struct iwl_tso_hdr_page {
* @fw_mon_size: size of the buffer for the firmware monitor * @fw_mon_size: size of the buffer for the firmware monitor
*/ */
struct iwl_trans_pcie { struct iwl_trans_pcie {
struct iwl_rxq rxq; struct iwl_rxq *rxq;
struct iwl_rx_mem_buffer rx_pool[RX_QUEUE_SIZE];
struct iwl_rb_allocator rba; struct iwl_rb_allocator rba;
struct iwl_trans *trans; struct iwl_trans *trans;
struct iwl_drv *drv; struct iwl_drv *drv;
......
...@@ -2001,29 +2001,48 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, ...@@ -2001,29 +2001,48 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
{ {
struct iwl_trans *trans = file->private_data; struct iwl_trans *trans = file->private_data;
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_rxq *rxq = &trans_pcie->rxq; char *buf;
char buf[256]; int pos = 0, i, ret;
int pos = 0; size_t bufsz = sizeof(buf);
const size_t bufsz = sizeof(buf);
bufsz = sizeof(char) * 121 * trans->num_rx_queues;
pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
rxq->read); if (!trans_pcie->rxq)
pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", return -EAGAIN;
rxq->write);
pos += scnprintf(buf + pos, bufsz - pos, "write_actual: %u\n", buf = kzalloc(bufsz, GFP_KERNEL);
rxq->write_actual); if (!buf)
pos += scnprintf(buf + pos, bufsz - pos, "need_update: %d\n", return -ENOMEM;
rxq->need_update);
pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", for (i = 0; i < trans->num_rx_queues && pos < bufsz; i++) {
rxq->free_count); struct iwl_rxq *rxq = &trans_pcie->rxq[i];
if (rxq->rb_stts) {
pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", pos += scnprintf(buf + pos, bufsz - pos, "queue#: %2d\n",
le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); i);
} else { pos += scnprintf(buf + pos, bufsz - pos, "\tread: %u\n",
pos += scnprintf(buf + pos, bufsz - pos, rxq->read);
"closed_rb_num: Not Allocated\n"); pos += scnprintf(buf + pos, bufsz - pos, "\twrite: %u\n",
rxq->write);
pos += scnprintf(buf + pos, bufsz - pos, "\twrite_actual: %u\n",
rxq->write_actual);
pos += scnprintf(buf + pos, bufsz - pos, "\tneed_update: %2d\n",
rxq->need_update);
pos += scnprintf(buf + pos, bufsz - pos, "\tfree_count: %u\n",
rxq->free_count);
if (rxq->rb_stts) {
pos += scnprintf(buf + pos, bufsz - pos,
"\tclosed_rb_num: %u\n",
le16_to_cpu(rxq->rb_stts->closed_rb_num) &
0x0FFF);
} else {
pos += scnprintf(buf + pos, bufsz - pos,
"\tclosed_rb_num: Not Allocated\n");
}
} }
return simple_read_from_buffer(user_buf, count, ppos, buf, pos); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
} }
static ssize_t iwl_dbgfs_interrupt_read(struct file *file, static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
...@@ -2188,7 +2207,8 @@ static u32 iwl_trans_pcie_dump_rbs(struct iwl_trans *trans, ...@@ -2188,7 +2207,8 @@ static u32 iwl_trans_pcie_dump_rbs(struct iwl_trans *trans,
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int max_len = PAGE_SIZE << trans_pcie->rx_page_order; int max_len = PAGE_SIZE << trans_pcie->rx_page_order;
struct iwl_rxq *rxq = &trans_pcie->rxq; /* Dump RBs is supported only for pre-9000 devices (1 queue) */
struct iwl_rxq *rxq = &trans_pcie->rxq[0];
u32 i, r, j, rb_len = 0; u32 i, r, j, rb_len = 0;
spin_lock(&rxq->lock); spin_lock(&rxq->lock);
...@@ -2438,11 +2458,12 @@ static struct iwl_trans_dump_data ...@@ -2438,11 +2458,12 @@ static struct iwl_trans_dump_data
len += sizeof(*data) + (FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND); len += sizeof(*data) + (FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND);
if (dump_rbs) { if (dump_rbs) {
/* Dump RBs is supported only for pre-9000 devices (1 queue) */
struct iwl_rxq *rxq = &trans_pcie->rxq[0];
/* RBs */ /* RBs */
num_rbs = le16_to_cpu(ACCESS_ONCE( num_rbs = le16_to_cpu(ACCESS_ONCE(rxq->rb_stts->closed_rb_num))
trans_pcie->rxq.rb_stts->closed_rb_num))
& 0x0FFF; & 0x0FFF;
num_rbs = (num_rbs - trans_pcie->rxq.read) & RX_QUEUE_MASK; num_rbs = (num_rbs - rxq->read) & RX_QUEUE_MASK;
len += num_rbs * (sizeof(*data) + len += num_rbs * (sizeof(*data) +
sizeof(struct iwl_fw_error_dump_rb) + sizeof(struct iwl_fw_error_dump_rb) +
(PAGE_SIZE << trans_pcie->rx_page_order)); (PAGE_SIZE << trans_pcie->rx_page_order));
......
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