diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 103 |
1 files changed, 39 insertions, 64 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index c17078eac197..70a3d135f64e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -35,18 +35,18 @@ | |||
35 | * TX data handlers. | 35 | * TX data handlers. |
36 | */ | 36 | */ |
37 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 37 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, |
38 | struct data_queue *queue, struct sk_buff *skb, | 38 | struct data_queue *queue, struct sk_buff *skb) |
39 | struct ieee80211_tx_control *control) | ||
40 | { | 39 | { |
41 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | 40 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
42 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | 41 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
43 | struct skb_frame_desc *skbdesc; | 42 | struct skb_frame_desc *skbdesc; |
43 | struct txentry_desc txdesc; | ||
44 | u32 word; | 44 | u32 word; |
45 | 45 | ||
46 | if (rt2x00queue_full(queue)) | 46 | if (rt2x00queue_full(queue)) |
47 | return -EINVAL; | 47 | return -EINVAL; |
48 | 48 | ||
49 | rt2x00_desc_read(priv_tx->desc, 0, &word); | 49 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
50 | 50 | ||
51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | 51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || |
52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | 52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { |
@@ -58,19 +58,27 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
58 | } | 58 | } |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Copy all TX descriptor information into txdesc, | ||
62 | * after that we are free to use the skb->cb array | ||
63 | * for our information. | ||
64 | */ | ||
65 | entry->skb = skb; | ||
66 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
67 | |||
68 | /* | ||
61 | * Fill in skb descriptor | 69 | * Fill in skb descriptor |
62 | */ | 70 | */ |
63 | skbdesc = get_skb_frame_desc(skb); | 71 | skbdesc = get_skb_frame_desc(skb); |
72 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
64 | skbdesc->data = skb->data; | 73 | skbdesc->data = skb->data; |
65 | skbdesc->data_len = skb->len; | 74 | skbdesc->data_len = skb->len; |
66 | skbdesc->desc = priv_tx->desc; | 75 | skbdesc->desc = entry_priv->desc; |
67 | skbdesc->desc_len = queue->desc_size; | 76 | skbdesc->desc_len = queue->desc_size; |
68 | skbdesc->entry = entry; | 77 | skbdesc->entry = entry; |
69 | 78 | ||
70 | memcpy(&priv_tx->control, control, sizeof(priv_tx->control)); | 79 | memcpy(entry_priv->data, skb->data, skb->len); |
71 | memcpy(priv_tx->data, skb->data, skb->len); | ||
72 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
73 | 80 | ||
81 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
74 | rt2x00queue_index_inc(queue, Q_INDEX); | 82 | rt2x00queue_index_inc(queue, Q_INDEX); |
75 | 83 | ||
76 | return 0; | 84 | return 0; |
@@ -84,7 +92,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
84 | { | 92 | { |
85 | struct data_queue *queue = rt2x00dev->rx; | 93 | struct data_queue *queue = rt2x00dev->rx; |
86 | struct queue_entry *entry; | 94 | struct queue_entry *entry; |
87 | struct queue_entry_priv_pci_rx *priv_rx; | 95 | struct queue_entry_priv_pci *entry_priv; |
88 | struct ieee80211_hdr *hdr; | 96 | struct ieee80211_hdr *hdr; |
89 | struct skb_frame_desc *skbdesc; | 97 | struct skb_frame_desc *skbdesc; |
90 | struct rxdone_entry_desc rxdesc; | 98 | struct rxdone_entry_desc rxdesc; |
@@ -94,8 +102,8 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
94 | 102 | ||
95 | while (1) { | 103 | while (1) { |
96 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | 104 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
97 | priv_rx = entry->priv_data; | 105 | entry_priv = entry->priv_data; |
98 | rt2x00_desc_read(priv_rx->desc, 0, &word); | 106 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
99 | 107 | ||
100 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 108 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
101 | break; | 109 | break; |
@@ -103,7 +111,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
103 | memset(&rxdesc, 0, sizeof(rxdesc)); | 111 | memset(&rxdesc, 0, sizeof(rxdesc)); |
104 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | 112 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
105 | 113 | ||
106 | hdr = (struct ieee80211_hdr *)priv_rx->data; | 114 | hdr = (struct ieee80211_hdr *)entry_priv->data; |
107 | header_size = | 115 | header_size = |
108 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | 116 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); |
109 | 117 | ||
@@ -123,7 +131,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
123 | 131 | ||
124 | skb_reserve(entry->skb, align); | 132 | skb_reserve(entry->skb, align); |
125 | memcpy(skb_put(entry->skb, rxdesc.size), | 133 | memcpy(skb_put(entry->skb, rxdesc.size), |
126 | priv_rx->data, rxdesc.size); | 134 | entry_priv->data, rxdesc.size); |
127 | 135 | ||
128 | /* | 136 | /* |
129 | * Fill in skb descriptor | 137 | * Fill in skb descriptor |
@@ -132,7 +140,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
132 | memset(skbdesc, 0, sizeof(*skbdesc)); | 140 | memset(skbdesc, 0, sizeof(*skbdesc)); |
133 | skbdesc->data = entry->skb->data; | 141 | skbdesc->data = entry->skb->data; |
134 | skbdesc->data_len = entry->skb->len; | 142 | skbdesc->data_len = entry->skb->len; |
135 | skbdesc->desc = priv_rx->desc; | 143 | skbdesc->desc = entry_priv->desc; |
136 | skbdesc->desc_len = queue->desc_size; | 144 | skbdesc->desc_len = queue->desc_size; |
137 | skbdesc->entry = entry; | 145 | skbdesc->entry = entry; |
138 | 146 | ||
@@ -143,7 +151,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
143 | 151 | ||
144 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { | 152 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { |
145 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | 153 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); |
146 | rt2x00_desc_write(priv_rx->desc, 0, word); | 154 | rt2x00_desc_write(entry_priv->desc, 0, word); |
147 | } | 155 | } |
148 | 156 | ||
149 | rt2x00queue_index_inc(queue, Q_INDEX); | 157 | rt2x00queue_index_inc(queue, Q_INDEX); |
@@ -154,10 +162,10 @@ EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | |||
154 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | 162 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, |
155 | struct txdone_entry_desc *txdesc) | 163 | struct txdone_entry_desc *txdesc) |
156 | { | 164 | { |
157 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | 165 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
166 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | ||
158 | u32 word; | 167 | u32 word; |
159 | 168 | ||
160 | txdesc->control = &priv_tx->control; | ||
161 | rt2x00lib_txdone(entry, txdesc); | 169 | rt2x00lib_txdone(entry, txdesc); |
162 | 170 | ||
163 | /* | 171 | /* |
@@ -165,10 +173,10 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | |||
165 | */ | 173 | */ |
166 | entry->flags = 0; | 174 | entry->flags = 0; |
167 | 175 | ||
168 | rt2x00_desc_read(priv_tx->desc, 0, &word); | 176 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
169 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); | 177 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); |
170 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | 178 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); |
171 | rt2x00_desc_write(priv_tx->desc, 0, word); | 179 | rt2x00_desc_write(entry_priv->desc, 0, word); |
172 | 180 | ||
173 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | 181 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
174 | 182 | ||
@@ -178,7 +186,7 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | |||
178 | * is reenabled when the txdone handler has finished. | 186 | * is reenabled when the txdone handler has finished. |
179 | */ | 187 | */ |
180 | if (!rt2x00queue_full(entry->queue)) | 188 | if (!rt2x00queue_full(entry->queue)) |
181 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); | 189 | ieee80211_wake_queue(rt2x00dev->hw, qid); |
182 | 190 | ||
183 | } | 191 | } |
184 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | 192 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); |
@@ -217,14 +225,9 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
217 | struct data_queue *queue) | 225 | struct data_queue *queue) |
218 | { | 226 | { |
219 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 227 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
220 | struct queue_entry_priv_pci_rx *priv_rx; | 228 | struct queue_entry_priv_pci *entry_priv; |
221 | struct queue_entry_priv_pci_tx *priv_tx; | ||
222 | void *addr; | 229 | void *addr; |
223 | dma_addr_t dma; | 230 | dma_addr_t dma; |
224 | void *desc_addr; | ||
225 | dma_addr_t desc_dma; | ||
226 | void *data_addr; | ||
227 | dma_addr_t data_dma; | ||
228 | unsigned int i; | 231 | unsigned int i; |
229 | 232 | ||
230 | /* | 233 | /* |
@@ -240,24 +243,11 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
240 | * Initialize all queue entries to contain valid addresses. | 243 | * Initialize all queue entries to contain valid addresses. |
241 | */ | 244 | */ |
242 | for (i = 0; i < queue->limit; i++) { | 245 | for (i = 0; i < queue->limit; i++) { |
243 | desc_addr = desc_offset(queue, addr, i); | 246 | entry_priv = queue->entries[i].priv_data; |
244 | desc_dma = desc_offset(queue, dma, i); | 247 | entry_priv->desc = desc_offset(queue, addr, i); |
245 | data_addr = data_offset(queue, addr, i); | 248 | entry_priv->desc_dma = desc_offset(queue, dma, i); |
246 | data_dma = data_offset(queue, dma, i); | 249 | entry_priv->data = data_offset(queue, addr, i); |
247 | 250 | entry_priv->data_dma = data_offset(queue, dma, i); | |
248 | if (queue->qid == QID_RX) { | ||
249 | priv_rx = queue->entries[i].priv_data; | ||
250 | priv_rx->desc = desc_addr; | ||
251 | priv_rx->desc_dma = desc_dma; | ||
252 | priv_rx->data = data_addr; | ||
253 | priv_rx->data_dma = data_dma; | ||
254 | } else { | ||
255 | priv_tx = queue->entries[i].priv_data; | ||
256 | priv_tx->desc = desc_addr; | ||
257 | priv_tx->desc_dma = desc_dma; | ||
258 | priv_tx->data = data_addr; | ||
259 | priv_tx->data_dma = data_dma; | ||
260 | } | ||
261 | } | 251 | } |
262 | 252 | ||
263 | return 0; | 253 | return 0; |
@@ -267,28 +257,13 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
267 | struct data_queue *queue) | 257 | struct data_queue *queue) |
268 | { | 258 | { |
269 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 259 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
270 | struct queue_entry_priv_pci_rx *priv_rx; | 260 | struct queue_entry_priv_pci *entry_priv = |
271 | struct queue_entry_priv_pci_tx *priv_tx; | 261 | queue->entries[0].priv_data; |
272 | void *data_addr; | ||
273 | dma_addr_t data_dma; | ||
274 | |||
275 | if (queue->qid == QID_RX) { | ||
276 | priv_rx = queue->entries[0].priv_data; | ||
277 | data_addr = priv_rx->data; | ||
278 | data_dma = priv_rx->data_dma; | ||
279 | |||
280 | priv_rx->data = NULL; | ||
281 | } else { | ||
282 | priv_tx = queue->entries[0].priv_data; | ||
283 | data_addr = priv_tx->data; | ||
284 | data_dma = priv_tx->data_dma; | ||
285 | |||
286 | priv_tx->data = NULL; | ||
287 | } | ||
288 | 262 | ||
289 | if (data_addr) | 263 | if (entry_priv->data) |
290 | pci_free_consistent(pci_dev, dma_size(queue), | 264 | pci_free_consistent(pci_dev, dma_size(queue), |
291 | data_addr, data_dma); | 265 | entry_priv->data, entry_priv->data_dma); |
266 | entry_priv->data = NULL; | ||
292 | } | 267 | } |
293 | 268 | ||
294 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 269 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) |