Skip to content

Commit

Permalink
rt2x00: rt2x00queue: initialize data_queue fields earlier
Browse files Browse the repository at this point in the history
Support for rt2800 device is broken since my
'rt2x00: rt2x00dev: use rt2x00dev->tx->limit'
patch. The changelog of that commit says that the
TX data queue is initialized already when the
rt2x00lib_probe_hw() function is called.

However as Jakub noticed it, this statement is not
correct. The queue->limit field is initialized in
the rt2x00queue_alloc_entries routine and that is
not yet called when rt2x00lib_probe_hw() runs.
Because the value of tx->limit contains zero, the
driver tries to allocate a kernel fifo with zero
size and kfifo_alloc rejects that with -EINVAL.

  PCI: Enabling device 0000:01:00.0 (0000 -> 0002)
  ieee80211 phy1: rt2x00_set_rt: Info - RT chipset 3071, rev 021c detected
  ieee80211 phy1: rt2x00_set_rf: Info - RF chipset 0008 detected
  ieee80211 phy1: rt2x00lib_probe_dev: Error - Failed to initialize hw
  rt2800pci: probe of 0000:01:00.0 failed with error -22

Move the data_queue field initialization from
the rt2x00queue_alloc_entries routine into the
rt2x00queue_init function. The initialization
code is not strictly related to the allocation,
and the change ensures that the queue_data fields
can be used in the probe routines.

The patch also introduces a helper function in
order to be able to get the correct data_queue_desc
structure for a given queue. This helper is only
needed temporarily and it will be removed later.

Reported-by: Jakub Kicinski <moorray@wp.pl>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Gabor Juhos authored and John W. Linville committed Jun 10, 2013
1 parent ec71997 commit 10af87c
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions drivers/net/wireless/rt2x00/rt2x00queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,12 +1170,6 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,

rt2x00queue_reset(queue);

queue->limit = qdesc->entry_num;
queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);
queue->data_size = qdesc->data_size;
queue->desc_size = qdesc->desc_size;
queue->winfo_size = qdesc->winfo_size;

/*
* Allocate all queue entries.
*/
Expand Down Expand Up @@ -1284,9 +1278,38 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
}
}

static const struct data_queue_desc *
rt2x00queue_get_qdesc_by_qid(struct rt2x00_dev *rt2x00dev,
enum data_queue_qid qid)
{
switch (qid) {
case QID_RX:
return rt2x00dev->ops->rx;

case QID_AC_BE:
case QID_AC_BK:
case QID_AC_VO:
case QID_AC_VI:
return rt2x00dev->ops->tx;

case QID_BEACON:
return rt2x00dev->ops->bcn;

case QID_ATIM:
return rt2x00dev->ops->atim;

default:
break;
}

return NULL;
}

static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue, enum data_queue_qid qid)
{
const struct data_queue_desc *qdesc;

mutex_init(&queue->status_lock);
spin_lock_init(&queue->tx_lock);
spin_lock_init(&queue->index_lock);
Expand All @@ -1297,6 +1320,15 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
queue->aifs = 2;
queue->cw_min = 5;
queue->cw_max = 10;

qdesc = rt2x00queue_get_qdesc_by_qid(rt2x00dev, qid);
BUG_ON(!qdesc);

queue->limit = qdesc->entry_num;
queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);
queue->data_size = qdesc->data_size;
queue->desc_size = qdesc->desc_size;
queue->winfo_size = qdesc->winfo_size;
}

int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
Expand Down

0 comments on commit 10af87c

Please sign in to comment.