aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00mac.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-15 06:55:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:11 -0400
commite039fa4a4195ac4ee895e6f3d1334beed63256fe (patch)
treecfd0762d73df96b73052378be7b157c4ac6e7035 /drivers/net/wireless/rt2x00/rt2x00mac.c
parente24549485f859be6518929bb1c9c0257d79f033d (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/rt2x00/rt2x00mac.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c74
1 files changed, 43 insertions, 31 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c5cedb29b87d..b5379b027b18 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -31,14 +31,15 @@
31 31
32static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, 32static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
33 struct data_queue *queue, 33 struct data_queue *queue,
34 struct sk_buff *frag_skb, 34 struct sk_buff *frag_skb)
35 struct ieee80211_tx_control *control)
36{ 35{
36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
37 struct skb_frame_desc *skbdesc; 37 struct skb_frame_desc *skbdesc;
38 struct ieee80211_tx_info *rts_info;
38 struct sk_buff *skb; 39 struct sk_buff *skb;
39 int size; 40 int size;
40 41
41 if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) 42 if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
42 size = sizeof(struct ieee80211_cts); 43 size = sizeof(struct ieee80211_cts);
43 else 44 else
44 size = sizeof(struct ieee80211_rts); 45 size = sizeof(struct ieee80211_rts);
@@ -52,13 +53,33 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
52 skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom); 53 skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom);
53 skb_put(skb, size); 54 skb_put(skb, size);
54 55
55 if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) 56 /*
56 ieee80211_ctstoself_get(rt2x00dev->hw, control->vif, 57 * Copy TX information over from original frame to
57 frag_skb->data, frag_skb->len, control, 58 * RTS/CTS frame. Note that we set the no encryption flag
59 * since we don't want this frame to be encrypted.
60 * RTS frames should be acked, while CTS-to-self frames
61 * should not. The ready for TX flag is cleared to prevent
62 * it being automatically send when the descriptor is
63 * written to the hardware.
64 */
65 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
66 rts_info = IEEE80211_SKB_CB(skb);
67 rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
68 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
69 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
70
71 if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
72 rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
73 else
74 rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
75
76 if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
77 ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
78 frag_skb->data, size, tx_info,
58 (struct ieee80211_cts *)(skb->data)); 79 (struct ieee80211_cts *)(skb->data));
59 else 80 else
60 ieee80211_rts_get(rt2x00dev->hw, control->vif, 81 ieee80211_rts_get(rt2x00dev->hw, tx_info->control.vif,
61 frag_skb->data, frag_skb->len, control, 82 frag_skb->data, size, tx_info,
62 (struct ieee80211_rts *)(skb->data)); 83 (struct ieee80211_rts *)(skb->data));
63 84
64 /* 85 /*
@@ -68,7 +89,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
68 memset(skbdesc, 0, sizeof(*skbdesc)); 89 memset(skbdesc, 0, sizeof(*skbdesc));
69 skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; 90 skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
70 91
71 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { 92 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
72 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); 93 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
73 return NETDEV_TX_BUSY; 94 return NETDEV_TX_BUSY;
74 } 95 }
@@ -76,14 +97,13 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
76 return NETDEV_TX_OK; 97 return NETDEV_TX_OK;
77} 98}
78 99
79int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, 100int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
80 struct ieee80211_tx_control *control)
81{ 101{
82 struct rt2x00_dev *rt2x00dev = hw->priv; 102 struct rt2x00_dev *rt2x00dev = hw->priv;
103 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
83 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; 104 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
84 enum data_queue_qid qid = mac80211_queue_to_qid(control->queue); 105 enum data_queue_qid qid = mac80211_queue_to_qid(tx_info->queue);
85 struct data_queue *queue; 106 struct data_queue *queue;
86 struct skb_frame_desc *skbdesc;
87 u16 frame_control; 107 u16 frame_control;
88 108
89 /* 109 /*
@@ -100,7 +120,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
100 /* 120 /*
101 * Determine which queue to put packet on. 121 * Determine which queue to put packet on.
102 */ 122 */
103 if (control->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM && 123 if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
104 test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) 124 test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
105 queue = rt2x00queue_get_queue(rt2x00dev, QID_ATIM); 125 queue = rt2x00queue_get_queue(rt2x00dev, QID_ATIM);
106 else 126 else
@@ -125,33 +145,27 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
125 */ 145 */
126 frame_control = le16_to_cpu(ieee80211hdr->frame_control); 146 frame_control = le16_to_cpu(ieee80211hdr->frame_control);
127 if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && 147 if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
128 (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | 148 (tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
129 IEEE80211_TXCTL_USE_CTS_PROTECT)) && 149 IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
130 !rt2x00dev->ops->hw->set_rts_threshold) { 150 !rt2x00dev->ops->hw->set_rts_threshold) {
131 if (rt2x00queue_available(queue) <= 1) { 151 if (rt2x00queue_available(queue) <= 1) {
132 ieee80211_stop_queue(rt2x00dev->hw, control->queue); 152 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
133 return NETDEV_TX_BUSY; 153 return NETDEV_TX_BUSY;
134 } 154 }
135 155
136 if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) { 156 if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb)) {
137 ieee80211_stop_queue(rt2x00dev->hw, control->queue); 157 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
138 return NETDEV_TX_BUSY; 158 return NETDEV_TX_BUSY;
139 } 159 }
140 } 160 }
141 161
142 /* 162 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
143 * Initialize skb descriptor 163 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
144 */
145 skbdesc = get_skb_frame_desc(skb);
146 memset(skbdesc, 0, sizeof(*skbdesc));
147
148 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
149 ieee80211_stop_queue(rt2x00dev->hw, control->queue);
150 return NETDEV_TX_BUSY; 164 return NETDEV_TX_BUSY;
151 } 165 }
152 166
153 if (rt2x00queue_full(queue)) 167 if (rt2x00queue_full(queue))
154 ieee80211_stop_queue(rt2x00dev->hw, control->queue); 168 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue);
155 169
156 if (rt2x00dev->ops->lib->kick_tx_queue) 170 if (rt2x00dev->ops->lib->kick_tx_queue)
157 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid); 171 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid);
@@ -380,9 +394,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
380 if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon) 394 if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon)
381 return 0; 395 return 0;
382 396
383 status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, 397 status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, conf->beacon);
384 conf->beacon,
385 conf->beacon_control);
386 if (status) 398 if (status)
387 dev_kfree_skb(conf->beacon); 399 dev_kfree_skb(conf->beacon);
388 400