diff options
author | Ivo van Doorn <IvDoorn@gmail.com> | 2008-06-06 16:50:28 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-14 12:17:56 -0400 |
commit | 6db3786aee36b32e5ed072ed67fad6d5341b0991 (patch) | |
tree | af6ef8406b539e418f2cbc74609e50faa28a4ee1 /drivers/net/wireless/rt2x00 | |
parent | f019d51410a9b61278eeff811a1ca11d2a905241 (diff) |
rt2x00: Move generic TX frame writing code into rt2x00queue
The write_tx_data functions in rt2x00pci and rt2x00usb have
a lot in common. This moves that duplicate code into
rt2x00queue_write_tx_frame().
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 43 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.h | 11 |
8 files changed, 85 insertions, 85 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2f79336297ca..c7da3c25237e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -546,8 +546,7 @@ struct rt2x00lib_ops { | |||
546 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 546 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, |
547 | struct sk_buff *skb, | 547 | struct sk_buff *skb, |
548 | struct txentry_desc *txdesc); | 548 | struct txentry_desc *txdesc); |
549 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, | 549 | int (*write_tx_data) (struct queue_entry *entry); |
550 | struct data_queue *queue, struct sk_buff *skb); | ||
551 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 550 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
552 | struct sk_buff *skb); | 551 | struct sk_buff *skb); |
553 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 552 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index c4ce534e3cdb..558f45bf27e3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -101,6 +101,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
101 | /* | 101 | /* |
102 | * Queue handlers. | 102 | * Queue handlers. |
103 | */ | 103 | */ |
104 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); | ||
104 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); | 105 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); |
105 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); | 106 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); |
106 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); | 107 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 97d9095037b9..e7f544c404bc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -89,7 +89,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
89 | memset(skbdesc, 0, sizeof(*skbdesc)); | 89 | memset(skbdesc, 0, sizeof(*skbdesc)); |
90 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | 90 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
91 | 91 | ||
92 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { | 92 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
93 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 93 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); |
94 | return NETDEV_TX_BUSY; | 94 | return NETDEV_TX_BUSY; |
95 | } | 95 | } |
@@ -158,7 +158,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
161 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { | 161 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
162 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 162 | ieee80211_stop_queue(rt2x00dev->hw, qid); |
163 | return NETDEV_TX_BUSY; | 163 | return NETDEV_TX_BUSY; |
164 | } | 164 | } |
@@ -166,9 +166,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
166 | if (rt2x00queue_full(queue)) | 166 | if (rt2x00queue_full(queue)) |
167 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 167 | ieee80211_stop_queue(rt2x00dev->hw, qid); |
168 | 168 | ||
169 | if (rt2x00dev->ops->lib->kick_tx_queue) | ||
170 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid); | ||
171 | |||
172 | return NETDEV_TX_OK; | 169 | return NETDEV_TX_OK; |
173 | } | 170 | } |
174 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); | 171 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 70a3d135f64e..a6bac75de9f2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -34,52 +34,40 @@ | |||
34 | /* | 34 | /* |
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 queue_entry *entry) |
38 | struct data_queue *queue, struct sk_buff *skb) | ||
39 | { | 38 | { |
40 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
41 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 39 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
42 | struct skb_frame_desc *skbdesc; | 40 | struct skb_frame_desc *skbdesc; |
43 | struct txentry_desc txdesc; | ||
44 | u32 word; | 41 | u32 word; |
45 | 42 | ||
46 | if (rt2x00queue_full(queue)) | ||
47 | return -EINVAL; | ||
48 | |||
49 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 43 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
50 | 44 | ||
51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | 45 | /* |
52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | 46 | * This should not happen, we already checked the entry |
53 | ERROR(rt2x00dev, | 47 | * was ours. When the hardware disagrees there has been |
54 | "Arrived at non-free entry in the non-full queue %d.\n" | 48 | * a queue corruption! |
49 | */ | ||
50 | if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | ||
51 | rt2x00_get_field32(word, TXD_ENTRY_VALID))) { | ||
52 | ERROR(entry->queue->rt2x00dev, | ||
53 | "Corrupt queue %d, accessing entry which is not ours.\n" | ||
55 | "Please file bug report to %s.\n", | 54 | "Please file bug report to %s.\n", |
56 | entry->queue->qid, DRV_PROJECT); | 55 | entry->queue->qid, DRV_PROJECT); |
57 | return -EINVAL; | 56 | return -EINVAL; |
58 | } | 57 | } |
59 | 58 | ||
60 | /* | 59 | /* |
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 | /* | ||
69 | * Fill in skb descriptor | 60 | * Fill in skb descriptor |
70 | */ | 61 | */ |
71 | skbdesc = get_skb_frame_desc(skb); | 62 | skbdesc = get_skb_frame_desc(entry->skb); |
72 | memset(skbdesc, 0, sizeof(*skbdesc)); | 63 | memset(skbdesc, 0, sizeof(*skbdesc)); |
73 | skbdesc->data = skb->data; | 64 | skbdesc->data = entry->skb->data; |
74 | skbdesc->data_len = skb->len; | 65 | skbdesc->data_len = entry->skb->len; |
75 | skbdesc->desc = entry_priv->desc; | 66 | skbdesc->desc = entry_priv->desc; |
76 | skbdesc->desc_len = queue->desc_size; | 67 | skbdesc->desc_len = entry->queue->desc_size; |
77 | skbdesc->entry = entry; | 68 | skbdesc->entry = entry; |
78 | 69 | ||
79 | memcpy(entry_priv->data, skb->data, skb->len); | 70 | memcpy(entry_priv->data, entry->skb->data, entry->skb->len); |
80 | |||
81 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
82 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
83 | 71 | ||
84 | return 0; | 72 | return 0; |
85 | } | 73 | } |
@@ -178,6 +166,7 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | |||
178 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | 166 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); |
179 | rt2x00_desc_write(entry_priv->desc, 0, word); | 167 | rt2x00_desc_write(entry_priv->desc, 0, word); |
180 | 168 | ||
169 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
181 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | 170 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
182 | 171 | ||
183 | /* | 172 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 37c851e442c1..87c4a0cd78db 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -87,11 +87,14 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
87 | memcpy_toio(rt2x00dev->csr.base + offset, value, length); | 87 | memcpy_toio(rt2x00dev->csr.base + offset, value, length); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /** |
91 | * TX data handlers. | 91 | * rt2x00pci_write_tx_data - Initialize data for TX operation |
92 | * @entry: The entry where the frame is located | ||
93 | * | ||
94 | * This function will initialize the DMA and skb descriptor | ||
95 | * to prepare the entry for the actual TX operation. | ||
92 | */ | 96 | */ |
93 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 97 | int rt2x00pci_write_tx_data(struct queue_entry *entry); |
94 | struct data_queue *queue, struct sk_buff *skb); | ||
95 | 98 | ||
96 | /** | 99 | /** |
97 | * struct queue_entry_priv_pci: Per entry PCI specific information | 100 | * struct queue_entry_priv_pci: Per entry PCI specific information |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 6f3aa0f71f9f..f875b7ab09fe 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -188,6 +188,43 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
188 | } | 188 | } |
189 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); | 189 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); |
190 | 190 | ||
191 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | ||
192 | { | ||
193 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
194 | struct txentry_desc txdesc; | ||
195 | |||
196 | if (unlikely(rt2x00queue_full(queue))) | ||
197 | return -EINVAL; | ||
198 | |||
199 | if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { | ||
200 | ERROR(queue->rt2x00dev, | ||
201 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
202 | "Please file bug report to %s.\n", | ||
203 | queue->qid, DRV_PROJECT); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Copy all TX descriptor information into txdesc, | ||
209 | * after that we are free to use the skb->cb array | ||
210 | * for our information. | ||
211 | */ | ||
212 | entry->skb = skb; | ||
213 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
214 | |||
215 | if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { | ||
216 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
217 | return -EIO; | ||
218 | } | ||
219 | |||
220 | __set_bit(ENTRY_DATA_PENDING, &entry->flags); | ||
221 | |||
222 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
223 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
191 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 228 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
192 | const enum data_queue_qid queue) | 229 | const enum data_queue_qid queue) |
193 | { | 230 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index cdac9280fe42..fdf505beb79c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -173,71 +173,42 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
173 | ieee80211_wake_queue(rt2x00dev->hw, qid); | 173 | ieee80211_wake_queue(rt2x00dev->hw, qid); |
174 | } | 174 | } |
175 | 175 | ||
176 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 176 | int rt2x00usb_write_tx_data(struct queue_entry *entry) |
177 | struct data_queue *queue, struct sk_buff *skb) | ||
178 | { | 177 | { |
178 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
179 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 179 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
180 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
181 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 180 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
182 | struct skb_frame_desc *skbdesc; | 181 | struct skb_frame_desc *skbdesc; |
183 | struct txentry_desc txdesc; | ||
184 | u32 length; | 182 | u32 length; |
185 | 183 | ||
186 | if (rt2x00queue_full(queue)) | ||
187 | return -EINVAL; | ||
188 | |||
189 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { | ||
190 | ERROR(rt2x00dev, | ||
191 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
192 | "Please file bug report to %s.\n", | ||
193 | entry->queue->qid, DRV_PROJECT); | ||
194 | return -EINVAL; | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * Copy all TX descriptor information into txdesc, | ||
199 | * after that we are free to use the skb->cb array | ||
200 | * for our information. | ||
201 | */ | ||
202 | entry->skb = skb; | ||
203 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
204 | |||
205 | /* | 184 | /* |
206 | * Add the descriptor in front of the skb. | 185 | * Add the descriptor in front of the skb. |
207 | */ | 186 | */ |
208 | skb_push(skb, queue->desc_size); | 187 | skb_push(entry->skb, entry->queue->desc_size); |
209 | memset(skb->data, 0, queue->desc_size); | 188 | memset(entry->skb->data, 0, entry->queue->desc_size); |
210 | 189 | ||
211 | /* | 190 | /* |
212 | * Fill in skb descriptor | 191 | * Fill in skb descriptor |
213 | */ | 192 | */ |
214 | skbdesc = get_skb_frame_desc(skb); | 193 | skbdesc = get_skb_frame_desc(entry->skb); |
215 | memset(skbdesc, 0, sizeof(*skbdesc)); | 194 | memset(skbdesc, 0, sizeof(*skbdesc)); |
216 | skbdesc->data = skb->data + queue->desc_size; | 195 | skbdesc->data = entry->skb->data + entry->queue->desc_size; |
217 | skbdesc->data_len = skb->len - queue->desc_size; | 196 | skbdesc->data_len = entry->skb->len - entry->queue->desc_size; |
218 | skbdesc->desc = skb->data; | 197 | skbdesc->desc = entry->skb->data; |
219 | skbdesc->desc_len = queue->desc_size; | 198 | skbdesc->desc_len = entry->queue->desc_size; |
220 | skbdesc->entry = entry; | 199 | skbdesc->entry = entry; |
221 | 200 | ||
222 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
223 | |||
224 | /* | 201 | /* |
225 | * USB devices cannot blindly pass the skb->len as the | 202 | * USB devices cannot blindly pass the skb->len as the |
226 | * length of the data to usb_fill_bulk_urb. Pass the skb | 203 | * length of the data to usb_fill_bulk_urb. Pass the skb |
227 | * to the driver to determine what the length should be. | 204 | * to the driver to determine what the length should be. |
228 | */ | 205 | */ |
229 | length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb); | 206 | length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb); |
230 | |||
231 | /* | ||
232 | * Initialize URB and send the frame to the device. | ||
233 | */ | ||
234 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
235 | __set_bit(ENTRY_DATA_PENDING, &entry->flags); | ||
236 | 207 | ||
237 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1), | 208 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, |
238 | skb->data, length, rt2x00usb_interrupt_txdone, entry); | 209 | usb_sndbulkpipe(usb_dev, 1), |
239 | 210 | entry->skb->data, length, | |
240 | rt2x00queue_index_inc(queue, Q_INDEX); | 211 | rt2x00usb_interrupt_txdone, entry); |
241 | 212 | ||
242 | return 0; | 213 | return 0; |
243 | } | 214 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 460d32c444d1..b1187c812e7f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -212,11 +212,14 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, | |||
212 | */ | 212 | */ |
213 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); | 213 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); |
214 | 214 | ||
215 | /* | 215 | /** |
216 | * TX data handlers. | 216 | * rt2x00usb_write_tx_data - Initialize URB for TX operation |
217 | * @entry: The entry where the frame is located | ||
218 | * | ||
219 | * This function will initialize the URB and skb descriptor | ||
220 | * to prepare the entry for the actual TX operation. | ||
217 | */ | 221 | */ |
218 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 222 | int rt2x00usb_write_tx_data(struct queue_entry *entry); |
219 | struct data_queue *queue, struct sk_buff *skb); | ||
220 | 223 | ||
221 | /** | 224 | /** |
222 | * struct queue_entry_priv_usb: Per entry USB specific information | 225 | * struct queue_entry_priv_usb: Per entry USB specific information |