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/adm8211.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/adm8211.c')
-rw-r--r-- | drivers/net/wireless/adm8211.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 22db664a58d9..0ba55ba93958 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -324,7 +324,7 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev) | |||
324 | for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) { | 324 | for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) { |
325 | unsigned int entry = dirty_tx % priv->tx_ring_size; | 325 | unsigned int entry = dirty_tx % priv->tx_ring_size; |
326 | u32 status = le32_to_cpu(priv->tx_ring[entry].status); | 326 | u32 status = le32_to_cpu(priv->tx_ring[entry].status); |
327 | struct ieee80211_tx_status tx_status; | 327 | struct ieee80211_tx_info *txi; |
328 | struct adm8211_tx_ring_info *info; | 328 | struct adm8211_tx_ring_info *info; |
329 | struct sk_buff *skb; | 329 | struct sk_buff *skb; |
330 | 330 | ||
@@ -334,24 +334,23 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev) | |||
334 | 334 | ||
335 | info = &priv->tx_buffers[entry]; | 335 | info = &priv->tx_buffers[entry]; |
336 | skb = info->skb; | 336 | skb = info->skb; |
337 | txi = IEEE80211_SKB_CB(skb); | ||
337 | 338 | ||
338 | /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */ | 339 | /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */ |
339 | 340 | ||
340 | pci_unmap_single(priv->pdev, info->mapping, | 341 | pci_unmap_single(priv->pdev, info->mapping, |
341 | info->skb->len, PCI_DMA_TODEVICE); | 342 | info->skb->len, PCI_DMA_TODEVICE); |
342 | 343 | ||
343 | memset(&tx_status, 0, sizeof(tx_status)); | 344 | memset(&txi->status, 0, sizeof(txi->status)); |
344 | skb_pull(skb, sizeof(struct adm8211_tx_hdr)); | 345 | skb_pull(skb, sizeof(struct adm8211_tx_hdr)); |
345 | memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen); | 346 | memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen); |
346 | memcpy(&tx_status.control, &info->tx_control, | 347 | if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { |
347 | sizeof(tx_status.control)); | ||
348 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { | ||
349 | if (status & TDES0_STATUS_ES) | 348 | if (status & TDES0_STATUS_ES) |
350 | tx_status.excessive_retries = 1; | 349 | txi->status.excessive_retries = 1; |
351 | else | 350 | else |
352 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; | 351 | txi->flags |= IEEE80211_TX_STAT_ACK; |
353 | } | 352 | } |
354 | ieee80211_tx_status_irqsafe(dev, skb, &tx_status); | 353 | ieee80211_tx_status_irqsafe(dev, skb); |
355 | 354 | ||
356 | info->skb = NULL; | 355 | info->skb = NULL; |
357 | } | 356 | } |
@@ -1638,7 +1637,6 @@ static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int | |||
1638 | /* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */ | 1637 | /* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */ |
1639 | static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, | 1638 | static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, |
1640 | u16 plcp_signal, | 1639 | u16 plcp_signal, |
1641 | struct ieee80211_tx_control *control, | ||
1642 | size_t hdrlen) | 1640 | size_t hdrlen) |
1643 | { | 1641 | { |
1644 | struct adm8211_priv *priv = dev->priv; | 1642 | struct adm8211_priv *priv = dev->priv; |
@@ -1664,7 +1662,6 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1664 | 1662 | ||
1665 | priv->tx_buffers[entry].skb = skb; | 1663 | priv->tx_buffers[entry].skb = skb; |
1666 | priv->tx_buffers[entry].mapping = mapping; | 1664 | priv->tx_buffers[entry].mapping = mapping; |
1667 | memcpy(&priv->tx_buffers[entry].tx_control, control, sizeof(*control)); | ||
1668 | priv->tx_buffers[entry].hdrlen = hdrlen; | 1665 | priv->tx_buffers[entry].hdrlen = hdrlen; |
1669 | priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping); | 1666 | priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping); |
1670 | 1667 | ||
@@ -1685,17 +1682,17 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1685 | } | 1682 | } |
1686 | 1683 | ||
1687 | /* Put adm8211_tx_hdr on skb and transmit */ | 1684 | /* Put adm8211_tx_hdr on skb and transmit */ |
1688 | static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | 1685 | static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
1689 | struct ieee80211_tx_control *control) | ||
1690 | { | 1686 | { |
1691 | struct adm8211_tx_hdr *txhdr; | 1687 | struct adm8211_tx_hdr *txhdr; |
1692 | u16 fc; | 1688 | u16 fc; |
1693 | size_t payload_len, hdrlen; | 1689 | size_t payload_len, hdrlen; |
1694 | int plcp, dur, len, plcp_signal, short_preamble; | 1690 | int plcp, dur, len, plcp_signal, short_preamble; |
1695 | struct ieee80211_hdr *hdr; | 1691 | struct ieee80211_hdr *hdr; |
1696 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, control); | 1692 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1693 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info); | ||
1697 | 1694 | ||
1698 | short_preamble = !!(txrate->flags & IEEE80211_TXCTL_SHORT_PREAMBLE); | 1695 | short_preamble = !!(txrate->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE); |
1699 | plcp_signal = txrate->bitrate; | 1696 | plcp_signal = txrate->bitrate; |
1700 | 1697 | ||
1701 | hdr = (struct ieee80211_hdr *)skb->data; | 1698 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -1730,15 +1727,15 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1730 | if (short_preamble) | 1727 | if (short_preamble) |
1731 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE); | 1728 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE); |
1732 | 1729 | ||
1733 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | 1730 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
1734 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); | 1731 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); |
1735 | 1732 | ||
1736 | if (fc & IEEE80211_FCTL_PROTECTED) | 1733 | if (fc & IEEE80211_FCTL_PROTECTED) |
1737 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE); | 1734 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE); |
1738 | 1735 | ||
1739 | txhdr->retry_limit = control->retry_limit; | 1736 | txhdr->retry_limit = info->control.retry_limit; |
1740 | 1737 | ||
1741 | adm8211_tx_raw(dev, skb, plcp_signal, control, hdrlen); | 1738 | adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); |
1742 | 1739 | ||
1743 | return NETDEV_TX_OK; | 1740 | return NETDEV_TX_OK; |
1744 | } | 1741 | } |