rt2x00: Fix Descriptor DMA initialization
As Adam Baker reported the DMA address for the
descriptor base was incorrectly initialized in
the PCI drivers.
Instead of the DMA base for the descriptor, the
DMA base for the data was passed resulting in a
broken TX/RX state for PCI drivers.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 52ccb85..28663c0 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -597,11 +597,12 @@
u32 word;
rt2x00_desc_read(priv_rx->desc, 2, &word);
- rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->queue->data_size);
+ rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH,
+ entry->queue->data_size);
rt2x00_desc_write(priv_rx->desc, 2, word);
rt2x00_desc_read(priv_rx->desc, 1, &word);
- rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->dma);
+ rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma);
rt2x00_desc_write(priv_rx->desc, 1, word);
rt2x00_desc_read(priv_rx->desc, 0, &word);
@@ -616,7 +617,7 @@
u32 word;
rt2x00_desc_read(priv_tx->desc, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->dma);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma);
rt2x00_desc_write(priv_tx->desc, 1, word);
rt2x00_desc_read(priv_tx->desc, 2, &word);
@@ -648,22 +649,26 @@
priv_tx = rt2x00dev->tx[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR3, ®);
- rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR3, reg);
priv_tx = rt2x00dev->tx[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR5, ®);
- rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR5, reg);
priv_tx = rt2x00dev->bcn[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR4, ®);
- rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR4, reg);
priv_tx = rt2x00dev->bcn[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR6, ®);
- rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR6, reg);
rt2x00pci_register_read(rt2x00dev, RXCSR1, ®);
@@ -673,7 +678,7 @@
priv_rx = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RXCSR2, ®);
- rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 3bf8560..ec7300e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -691,7 +691,7 @@
u32 word;
rt2x00_desc_read(priv_rx->desc, 1, &word);
- rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->dma);
+ rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma);
rt2x00_desc_write(priv_rx->desc, 1, word);
rt2x00_desc_read(priv_rx->desc, 0, &word);
@@ -706,7 +706,7 @@
u32 word;
rt2x00_desc_read(priv_tx->desc, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->dma);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma);
rt2x00_desc_write(priv_tx->desc, 1, word);
rt2x00_desc_read(priv_tx->desc, 0, &word);
@@ -733,22 +733,26 @@
priv_tx = rt2x00dev->tx[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR3, ®);
- rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR3, reg);
priv_tx = rt2x00dev->tx[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR5, ®);
- rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR5, reg);
priv_tx = rt2x00dev->bcn[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR4, ®);
- rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR4, reg);
priv_tx = rt2x00dev->bcn[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR6, ®);
- rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR6, reg);
rt2x00pci_register_read(rt2x00dev, RXCSR1, ®);
@@ -758,7 +762,7 @@
priv_rx = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RXCSR2, ®);
- rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 7d2f406..1960d93 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -218,40 +218,44 @@
struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
struct queue_entry_priv_pci_rx *priv_rx;
struct queue_entry_priv_pci_tx *priv_tx;
- void *desc;
- void *data_addr;
- void *data;
- dma_addr_t data_dma;
+ void *addr;
dma_addr_t dma;
+ void *desc_addr;
+ dma_addr_t desc_dma;
+ void *data_addr;
+ dma_addr_t data_dma;
unsigned int i;
/*
* Allocate DMA memory for descriptor and buffer.
*/
- data_addr = pci_alloc_consistent(pci_dev, dma_size(queue), &data_dma);
- if (!data_addr)
+ addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma);
+ if (!addr)
return -ENOMEM;
- memset(data_addr, 0, dma_size(queue));
+ memset(addr, 0, dma_size(queue));
/*
* Initialize all queue entries to contain valid addresses.
*/
for (i = 0; i < queue->limit; i++) {
- desc = desc_offset(queue, data_addr, i);
- data = data_offset(queue, data_addr, i);
- dma = data_offset(queue, data_dma, i);
+ desc_addr = desc_offset(queue, addr, i);
+ desc_dma = desc_offset(queue, dma, i);
+ data_addr = data_offset(queue, addr, i);
+ data_dma = data_offset(queue, dma, i);
if (queue->qid == QID_RX) {
priv_rx = queue->entries[i].priv_data;
- priv_rx->desc = desc;
- priv_rx->data = data;
- priv_rx->dma = dma;
+ priv_rx->desc = desc_addr;
+ priv_rx->desc_dma = desc_dma;
+ priv_rx->data = data_addr;
+ priv_rx->data_dma = data_dma;
} else {
priv_tx = queue->entries[i].priv_data;
- priv_tx->desc = desc;
- priv_tx->data = data;
- priv_tx->dma = dma;
+ priv_tx->desc = desc_addr;
+ priv_tx->desc_dma = desc_dma;
+ priv_tx->data = data_addr;
+ priv_tx->data_dma = data_dma;
}
}
@@ -270,13 +274,13 @@
if (queue->qid == QID_RX) {
priv_rx = queue->entries[0].priv_data;
data_addr = priv_rx->data;
- data_dma = priv_rx->dma;
+ data_dma = priv_rx->data_dma;
priv_rx->data = NULL;
} else {
priv_tx = queue->entries[0].priv_data;
data_addr = priv_tx->data;
- data_dma = priv_tx->dma;
+ data_dma = priv_tx->data_dma;
priv_tx->data = NULL;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 8932b31..9d1cdb9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -103,9 +103,10 @@
*/
struct queue_entry_priv_pci_rx {
__le32 *desc;
+ dma_addr_t desc_dma;
void *data;
- dma_addr_t dma;
+ dma_addr_t data_dma;
};
/**
@@ -118,9 +119,10 @@
*/
struct queue_entry_priv_pci_tx {
__le32 *desc;
+ dma_addr_t desc_dma;
void *data;
- dma_addr_t dma;
+ dma_addr_t data_dma;
struct ieee80211_tx_control control;
};
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 75f61f3..dcc694e 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -975,7 +975,8 @@
u32 word;
rt2x00_desc_read(priv_rx->desc, 5, &word);
- rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, priv_rx->dma);
+ rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
+ priv_rx->data_dma);
rt2x00_desc_write(priv_rx->desc, 5, word);
rt2x00_desc_read(priv_rx->desc, 0, &word);
@@ -999,7 +1000,8 @@
rt2x00_desc_write(priv_tx->desc, 5, word);
rt2x00_desc_read(priv_tx->desc, 6, &word);
- rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, priv_tx->dma);
+ rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
+ priv_tx->data_dma);
rt2x00_desc_write(priv_tx->desc, 6, word);
rt2x00_desc_read(priv_tx->desc, 0, &word);
@@ -1035,22 +1037,26 @@
priv_tx = rt2x00dev->tx[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®);
- rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg);
priv_tx = rt2x00dev->tx[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®);
- rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg);
priv_tx = rt2x00dev->tx[2].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®);
- rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg);
priv_tx = rt2x00dev->tx[3].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®);
- rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, priv_tx->dma);
+ rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER,
+ priv_tx->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg);
rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®);
@@ -1062,7 +1068,8 @@
priv_rx = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®);
- rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, priv_rx->dma);
+ rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER,
+ priv_rx->desc_dma);
rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg);
rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®);