aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43legacy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43legacy')
-rw-r--r--drivers/net/wireless/b43legacy/dma.c23
-rw-r--r--drivers/net/wireless/b43legacy/main.c9
-rw-r--r--drivers/net/wireless/b43legacy/pio.c21
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c15
-rw-r--r--drivers/net/wireless/b43legacy/xmit.h2
5 files changed, 59 insertions, 11 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 83161d9af813..6e08405e8026 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -1164,7 +1164,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1164{ 1164{
1165 const struct b43legacy_dma_ops *ops = ring->ops; 1165 const struct b43legacy_dma_ops *ops = ring->ops;
1166 u8 *header; 1166 u8 *header;
1167 int slot; 1167 int slot, old_top_slot, old_used_slots;
1168 int err; 1168 int err;
1169 struct b43legacy_dmadesc_generic *desc; 1169 struct b43legacy_dmadesc_generic *desc;
1170 struct b43legacy_dmadesc_meta *meta; 1170 struct b43legacy_dmadesc_meta *meta;
@@ -1174,6 +1174,9 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1174#define SLOTS_PER_PACKET 2 1174#define SLOTS_PER_PACKET 2
1175 B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); 1175 B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
1176 1176
1177 old_top_slot = ring->current_slot;
1178 old_used_slots = ring->used_slots;
1179
1177 /* Get a slot for the header. */ 1180 /* Get a slot for the header. */
1178 slot = request_slot(ring); 1181 slot = request_slot(ring);
1179 desc = ops->idx2desc(ring, slot, &meta_hdr); 1182 desc = ops->idx2desc(ring, slot, &meta_hdr);
@@ -1181,9 +1184,14 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1181 1184
1182 header = &(ring->txhdr_cache[slot * sizeof( 1185 header = &(ring->txhdr_cache[slot * sizeof(
1183 struct b43legacy_txhdr_fw3)]); 1186 struct b43legacy_txhdr_fw3)]);
1184 b43legacy_generate_txhdr(ring->dev, header, 1187 err = b43legacy_generate_txhdr(ring->dev, header,
1185 skb->data, skb->len, ctl, 1188 skb->data, skb->len, ctl,
1186 generate_cookie(ring, slot)); 1189 generate_cookie(ring, slot));
1190 if (unlikely(err)) {
1191 ring->current_slot = old_top_slot;
1192 ring->used_slots = old_used_slots;
1193 return err;
1194 }
1187 1195
1188 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, 1196 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
1189 sizeof(struct b43legacy_txhdr_fw3), 1); 1197 sizeof(struct b43legacy_txhdr_fw3), 1);
@@ -1206,6 +1214,8 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1206 if (dma_mapping_error(meta->dmaaddr)) { 1214 if (dma_mapping_error(meta->dmaaddr)) {
1207 bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); 1215 bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
1208 if (!bounce_skb) { 1216 if (!bounce_skb) {
1217 ring->current_slot = old_top_slot;
1218 ring->used_slots = old_used_slots;
1209 err = -ENOMEM; 1219 err = -ENOMEM;
1210 goto out_unmap_hdr; 1220 goto out_unmap_hdr;
1211 } 1221 }
@@ -1216,6 +1226,8 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
1216 meta->skb = skb; 1226 meta->skb = skb;
1217 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); 1227 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
1218 if (dma_mapping_error(meta->dmaaddr)) { 1228 if (dma_mapping_error(meta->dmaaddr)) {
1229 ring->current_slot = old_top_slot;
1230 ring->used_slots = old_used_slots;
1219 err = -EIO; 1231 err = -EIO;
1220 goto out_free_bounce; 1232 goto out_free_bounce;
1221 } 1233 }
@@ -1282,6 +1294,13 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1282 B43legacy_BUG_ON(ring->stopped); 1294 B43legacy_BUG_ON(ring->stopped);
1283 1295
1284 err = dma_tx_fragment(ring, skb, ctl); 1296 err = dma_tx_fragment(ring, skb, ctl);
1297 if (unlikely(err == -ENOKEY)) {
1298 /* Drop this packet, as we don't have the encryption key
1299 * anymore and must not transmit it unencrypted. */
1300 dev_kfree_skb_any(skb);
1301 err = 0;
1302 goto out_unlock;
1303 }
1285 if (unlikely(err)) { 1304 if (unlikely(err)) {
1286 b43legacyerr(dev->wl, "DMA tx mapping failure\n"); 1305 b43legacyerr(dev->wl, "DMA tx mapping failure\n");
1287 goto out_unlock; 1306 goto out_unlock;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index aa20d5d56e2f..53f7f2e97615 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3160,8 +3160,6 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
3160 b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4); 3160 b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4);
3161 3161
3162 ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */ 3162 ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
3163 memset(wl->bssid, 0, ETH_ALEN);
3164 memset(wl->mac_addr, 0, ETH_ALEN);
3165 b43legacy_upload_card_macaddress(dev); 3163 b43legacy_upload_card_macaddress(dev);
3166 b43legacy_security_init(dev); 3164 b43legacy_security_init(dev);
3167 b43legacy_rng_init(wl); 3165 b43legacy_rng_init(wl);
@@ -3263,6 +3261,13 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
3263 * LEDs that are registered later depend on it. */ 3261 * LEDs that are registered later depend on it. */
3264 b43legacy_rfkill_init(dev); 3262 b43legacy_rfkill_init(dev);
3265 3263
3264 /* Kill all old instance specific information to make sure
3265 * the card won't use it in the short timeframe between start
3266 * and mac80211 reconfiguring it. */
3267 memset(wl->bssid, 0, ETH_ALEN);
3268 memset(wl->mac_addr, 0, ETH_ALEN);
3269 wl->filter_flags = 0;
3270
3266 mutex_lock(&wl->mutex); 3271 mutex_lock(&wl->mutex);
3267 3272
3268 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { 3273 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index e4f4c5c39e33..bcdd54eb2edb 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -181,7 +181,7 @@ union txhdr_union {
181 struct b43legacy_txhdr_fw3 txhdr_fw3; 181 struct b43legacy_txhdr_fw3 txhdr_fw3;
182}; 182};
183 183
184static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue, 184static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
185 struct sk_buff *skb, 185 struct sk_buff *skb,
186 struct b43legacy_pio_txpacket *packet, 186 struct b43legacy_pio_txpacket *packet,
187 size_t txhdr_size) 187 size_t txhdr_size)
@@ -189,14 +189,17 @@ static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
189 union txhdr_union txhdr_data; 189 union txhdr_union txhdr_data;
190 u8 *txhdr = NULL; 190 u8 *txhdr = NULL;
191 unsigned int octets; 191 unsigned int octets;
192 int err;
192 193
193 txhdr = (u8 *)(&txhdr_data.txhdr_fw3); 194 txhdr = (u8 *)(&txhdr_data.txhdr_fw3);
194 195
195 B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0); 196 B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
196 b43legacy_generate_txhdr(queue->dev, 197 err = b43legacy_generate_txhdr(queue->dev,
197 txhdr, skb->data, skb->len, 198 txhdr, skb->data, skb->len,
198 &packet->txstat.control, 199 &packet->txstat.control,
199 generate_cookie(queue, packet)); 200 generate_cookie(queue, packet));
201 if (err)
202 return err;
200 203
201 tx_start(queue); 204 tx_start(queue);
202 octets = skb->len + txhdr_size; 205 octets = skb->len + txhdr_size;
@@ -204,6 +207,8 @@ static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
204 octets--; 207 octets--;
205 tx_data(queue, txhdr, (u8 *)skb->data, octets); 208 tx_data(queue, txhdr, (u8 *)skb->data, octets);
206 tx_complete(queue, skb); 209 tx_complete(queue, skb);
210
211 return 0;
207} 212}
208 213
209static void free_txpacket(struct b43legacy_pio_txpacket *packet, 214static void free_txpacket(struct b43legacy_pio_txpacket *packet,
@@ -226,6 +231,7 @@ static int pio_tx_packet(struct b43legacy_pio_txpacket *packet)
226 struct b43legacy_pioqueue *queue = packet->queue; 231 struct b43legacy_pioqueue *queue = packet->queue;
227 struct sk_buff *skb = packet->skb; 232 struct sk_buff *skb = packet->skb;
228 u16 octets; 233 u16 octets;
234 int err;
229 235
230 octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3); 236 octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3);
231 if (queue->tx_devq_size < octets) { 237 if (queue->tx_devq_size < octets) {
@@ -247,8 +253,14 @@ static int pio_tx_packet(struct b43legacy_pio_txpacket *packet)
247 if (queue->tx_devq_used + octets > queue->tx_devq_size) 253 if (queue->tx_devq_used + octets > queue->tx_devq_size)
248 return -EBUSY; 254 return -EBUSY;
249 /* Now poke the device. */ 255 /* Now poke the device. */
250 pio_tx_write_fragment(queue, skb, packet, 256 err = pio_tx_write_fragment(queue, skb, packet,
251 sizeof(struct b43legacy_txhdr_fw3)); 257 sizeof(struct b43legacy_txhdr_fw3));
258 if (unlikely(err == -ENOKEY)) {
259 /* Drop this packet, as we don't have the encryption key
260 * anymore and must not transmit it unencrypted. */
261 free_txpacket(packet, 1);
262 return 0;
263 }
252 264
253 /* Account for the packet size. 265 /* Account for the packet size.
254 * (We must not overflow the device TX queue) 266 * (We must not overflow the device TX queue)
@@ -486,6 +498,9 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
486 queue = parse_cookie(dev, status->cookie, &packet); 498 queue = parse_cookie(dev, status->cookie, &packet);
487 B43legacy_WARN_ON(!queue); 499 B43legacy_WARN_ON(!queue);
488 500
501 if (!packet->skb)
502 return;
503
489 queue->tx_devq_packets--; 504 queue->tx_devq_packets--;
490 queue->tx_devq_used -= (packet->skb->len + 505 queue->tx_devq_used -= (packet->skb->len +
491 sizeof(struct b43legacy_txhdr_fw3)); 506 sizeof(struct b43legacy_txhdr_fw3));
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index e20c552442d5..d84408a82db9 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -181,7 +181,7 @@ static u8 b43legacy_calc_fallback_rate(u8 bitrate)
181 return 0; 181 return 0;
182} 182}
183 183
184static void generate_txhdr_fw3(struct b43legacy_wldev *dev, 184static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
185 struct b43legacy_txhdr_fw3 *txhdr, 185 struct b43legacy_txhdr_fw3 *txhdr,
186 const unsigned char *fragment_data, 186 const unsigned char *fragment_data,
187 unsigned int fragment_len, 187 unsigned int fragment_len,
@@ -252,6 +252,13 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
252 iv_len = min((size_t)txctl->iv_len, 252 iv_len = min((size_t)txctl->iv_len,
253 ARRAY_SIZE(txhdr->iv)); 253 ARRAY_SIZE(txhdr->iv));
254 memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len); 254 memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
255 } else {
256 /* This key is invalid. This might only happen
257 * in a short timeframe after machine resume before
258 * we were able to reconfigure keys.
259 * Drop this packet completely. Do not transmit it
260 * unencrypted to avoid leaking information. */
261 return -ENOKEY;
255 } 262 }
256 } 263 }
257 b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) 264 b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
@@ -345,16 +352,18 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
345 /* Apply the bitfields */ 352 /* Apply the bitfields */
346 txhdr->mac_ctl = cpu_to_le32(mac_ctl); 353 txhdr->mac_ctl = cpu_to_le32(mac_ctl);
347 txhdr->phy_ctl = cpu_to_le16(phy_ctl); 354 txhdr->phy_ctl = cpu_to_le16(phy_ctl);
355
356 return 0;
348} 357}
349 358
350void b43legacy_generate_txhdr(struct b43legacy_wldev *dev, 359int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
351 u8 *txhdr, 360 u8 *txhdr,
352 const unsigned char *fragment_data, 361 const unsigned char *fragment_data,
353 unsigned int fragment_len, 362 unsigned int fragment_len,
354 const struct ieee80211_tx_control *txctl, 363 const struct ieee80211_tx_control *txctl,
355 u16 cookie) 364 u16 cookie)
356{ 365{
357 generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr, 366 return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
358 fragment_data, fragment_len, 367 fragment_data, fragment_len,
359 txctl, cookie); 368 txctl, cookie);
360} 369}
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h
index 8a155d0a5d1f..bab47928a0c9 100644
--- a/drivers/net/wireless/b43legacy/xmit.h
+++ b/drivers/net/wireless/b43legacy/xmit.h
@@ -76,7 +76,7 @@ struct b43legacy_txhdr_fw3 {
76 76
77 77
78 78
79void b43legacy_generate_txhdr(struct b43legacy_wldev *dev, 79int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
80 u8 *txhdr, 80 u8 *txhdr,
81 const unsigned char *fragment_data, 81 const unsigned char *fragment_data,
82 unsigned int fragment_len, 82 unsigned int fragment_len,