diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-15 06:55:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:11 -0400 |
commit | e039fa4a4195ac4ee895e6f3d1334beed63256fe (patch) | |
tree | cfd0762d73df96b73052378be7b157c4ac6e7035 /drivers/net/wireless/rtl8180_dev.c | |
parent | e24549485f859be6518929bb1c9c0257d79f033d (diff) |
mac80211: move TX info into skb->cb
This patch converts mac80211 and all drivers to have transmit
information and status in skb->cb rather than allocating extra
memory for it and copying all the data around. To make it fit,
a union is used where only data that is necessary for all steps
is kept outside of the union.
A number of fixes were done by Ivo, as well as the rt2x00 part
of this patch.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl8180_dev.c')
-rw-r--r-- | drivers/net/wireless/rtl8180_dev.c | 57 |
1 files changed, 24 insertions, 33 deletions
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index 6263209b889e..4427bc9f78a9 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c | |||
@@ -170,34 +170,29 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) | |||
170 | while (skb_queue_len(&ring->queue)) { | 170 | while (skb_queue_len(&ring->queue)) { |
171 | struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; | 171 | struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; |
172 | struct sk_buff *skb; | 172 | struct sk_buff *skb; |
173 | struct ieee80211_tx_status status; | 173 | struct ieee80211_tx_info *info; |
174 | struct ieee80211_tx_control *control; | ||
175 | u32 flags = le32_to_cpu(entry->flags); | 174 | u32 flags = le32_to_cpu(entry->flags); |
176 | 175 | ||
177 | if (flags & RTL8180_TX_DESC_FLAG_OWN) | 176 | if (flags & RTL8180_TX_DESC_FLAG_OWN) |
178 | return; | 177 | return; |
179 | 178 | ||
180 | memset(&status, 0, sizeof(status)); | ||
181 | |||
182 | ring->idx = (ring->idx + 1) % ring->entries; | 179 | ring->idx = (ring->idx + 1) % ring->entries; |
183 | skb = __skb_dequeue(&ring->queue); | 180 | skb = __skb_dequeue(&ring->queue); |
184 | pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), | 181 | pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), |
185 | skb->len, PCI_DMA_TODEVICE); | 182 | skb->len, PCI_DMA_TODEVICE); |
186 | 183 | ||
187 | control = *((struct ieee80211_tx_control **)skb->cb); | 184 | info = IEEE80211_SKB_CB(skb); |
188 | if (control) | 185 | memset(&info->status, 0, sizeof(info->status)); |
189 | memcpy(&status.control, control, sizeof(*control)); | ||
190 | kfree(control); | ||
191 | 186 | ||
192 | if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) { | 187 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
193 | if (flags & RTL8180_TX_DESC_FLAG_TX_OK) | 188 | if (flags & RTL8180_TX_DESC_FLAG_TX_OK) |
194 | status.flags = IEEE80211_TX_STATUS_ACK; | 189 | info->flags |= IEEE80211_TX_STAT_ACK; |
195 | else | 190 | else |
196 | status.excessive_retries = 1; | 191 | info->status.excessive_retries = 1; |
197 | } | 192 | } |
198 | status.retry_count = flags & 0xFF; | 193 | info->status.retry_count = flags & 0xFF; |
199 | 194 | ||
200 | ieee80211_tx_status_irqsafe(dev, skb, &status); | 195 | ieee80211_tx_status_irqsafe(dev, skb); |
201 | if (ring->entries - skb_queue_len(&ring->queue) == 2) | 196 | if (ring->entries - skb_queue_len(&ring->queue) == 2) |
202 | ieee80211_wake_queue(dev, prio); | 197 | ieee80211_wake_queue(dev, prio); |
203 | } | 198 | } |
@@ -238,9 +233,9 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) | |||
238 | return IRQ_HANDLED; | 233 | return IRQ_HANDLED; |
239 | } | 234 | } |
240 | 235 | ||
241 | static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | 236 | static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
242 | struct ieee80211_tx_control *control) | ||
243 | { | 237 | { |
238 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
244 | struct rtl8180_priv *priv = dev->priv; | 239 | struct rtl8180_priv *priv = dev->priv; |
245 | struct rtl8180_tx_ring *ring; | 240 | struct rtl8180_tx_ring *ring; |
246 | struct rtl8180_tx_desc *entry; | 241 | struct rtl8180_tx_desc *entry; |
@@ -251,7 +246,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
251 | u16 plcp_len = 0; | 246 | u16 plcp_len = 0; |
252 | __le16 rts_duration = 0; | 247 | __le16 rts_duration = 0; |
253 | 248 | ||
254 | prio = control->queue; | 249 | prio = info->queue; |
255 | ring = &priv->tx_ring[prio]; | 250 | ring = &priv->tx_ring[prio]; |
256 | 251 | ||
257 | mapping = pci_map_single(priv->pdev, skb->data, | 252 | mapping = pci_map_single(priv->pdev, skb->data, |
@@ -259,35 +254,32 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
259 | 254 | ||
260 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | | 255 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | |
261 | RTL8180_TX_DESC_FLAG_LS | | 256 | RTL8180_TX_DESC_FLAG_LS | |
262 | (ieee80211_get_tx_rate(dev, control)->hw_value << 24) | | 257 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | |
263 | skb->len; | 258 | skb->len; |
264 | 259 | ||
265 | if (priv->r8185) | 260 | if (priv->r8185) |
266 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | | 261 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | |
267 | RTL8180_TX_DESC_FLAG_NO_ENC; | 262 | RTL8180_TX_DESC_FLAG_NO_ENC; |
268 | 263 | ||
269 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 264 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { |
270 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; | 265 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; |
271 | tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19; | 266 | tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
272 | } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { | 267 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { |
273 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; | 268 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; |
274 | tx_flags |= ieee80211_get_rts_cts_rate(dev, control)->hw_value << 19; | 269 | tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
275 | } | 270 | } |
276 | 271 | ||
277 | *((struct ieee80211_tx_control **) skb->cb) = | 272 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
278 | kmemdup(control, sizeof(*control), GFP_ATOMIC); | ||
279 | |||
280 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | ||
281 | rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, | 273 | rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, |
282 | control); | 274 | info); |
283 | 275 | ||
284 | if (!priv->r8185) { | 276 | if (!priv->r8185) { |
285 | unsigned int remainder; | 277 | unsigned int remainder; |
286 | 278 | ||
287 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), | 279 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), |
288 | (ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10); | 280 | (ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); |
289 | remainder = (16 * (skb->len + 4)) % | 281 | remainder = (16 * (skb->len + 4)) % |
290 | ((ieee80211_get_tx_rate(dev, control)->bitrate * 2) / 10); | 282 | ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10); |
291 | if (remainder > 0 && remainder <= 6) | 283 | if (remainder > 0 && remainder <= 6) |
292 | plcp_len |= 1 << 15; | 284 | plcp_len |= 1 << 15; |
293 | } | 285 | } |
@@ -300,13 +292,13 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
300 | entry->plcp_len = cpu_to_le16(plcp_len); | 292 | entry->plcp_len = cpu_to_le16(plcp_len); |
301 | entry->tx_buf = cpu_to_le32(mapping); | 293 | entry->tx_buf = cpu_to_le32(mapping); |
302 | entry->frame_len = cpu_to_le32(skb->len); | 294 | entry->frame_len = cpu_to_le32(skb->len); |
303 | entry->flags2 = control->alt_retry_rate_idx >= 0 ? | 295 | entry->flags2 = info->control.alt_retry_rate_idx >= 0 ? |
304 | ieee80211_get_alt_retry_rate(dev, control)->bitrate << 4 : 0; | 296 | ieee80211_get_alt_retry_rate(dev, info)->bitrate << 4 : 0; |
305 | entry->retry_limit = control->retry_limit; | 297 | entry->retry_limit = info->control.retry_limit; |
306 | entry->flags = cpu_to_le32(tx_flags); | 298 | entry->flags = cpu_to_le32(tx_flags); |
307 | __skb_queue_tail(&ring->queue, skb); | 299 | __skb_queue_tail(&ring->queue, skb); |
308 | if (ring->entries - skb_queue_len(&ring->queue) < 2) | 300 | if (ring->entries - skb_queue_len(&ring->queue) < 2) |
309 | ieee80211_stop_queue(dev, control->queue); | 301 | ieee80211_stop_queue(dev, info->queue); |
310 | spin_unlock_irqrestore(&priv->lock, flags); | 302 | spin_unlock_irqrestore(&priv->lock, flags); |
311 | 303 | ||
312 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); | 304 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); |
@@ -522,7 +514,6 @@ static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio) | |||
522 | 514 | ||
523 | pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), | 515 | pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), |
524 | skb->len, PCI_DMA_TODEVICE); | 516 | skb->len, PCI_DMA_TODEVICE); |
525 | kfree(*((struct ieee80211_tx_control **) skb->cb)); | ||
526 | kfree_skb(skb); | 517 | kfree_skb(skb); |
527 | ring->idx = (ring->idx + 1) % ring->entries; | 518 | ring->idx = (ring->idx + 1) % ring->entries; |
528 | } | 519 | } |