aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
-rw-r--r--net/ieee80211/ieee80211_tx.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index cdee41cefb26..f505aa127e21 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -459,7 +459,71 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
459 netif_stop_queue(dev); 459 netif_stop_queue(dev);
460 stats->tx_errors++; 460 stats->tx_errors++;
461 return 1; 461 return 1;
462}
463
464/* Incoming 802.11 strucure is converted to a TXB
465 * a block of 802.11 fragment packets (stored as skbs) */
466int ieee80211_tx_frame(struct ieee80211_device *ieee,
467 struct ieee80211_hdr *frame, int len)
468{
469 struct ieee80211_txb *txb = NULL;
470 unsigned long flags;
471 struct net_device_stats *stats = &ieee->stats;
472 struct sk_buff *skb_frag;
473
474 spin_lock_irqsave(&ieee->lock, flags);
475
476 /* If there is no driver handler to take the TXB, dont' bother
477 * creating it... */
478 if (!ieee->hard_start_xmit) {
479 printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
480 goto success;
481 }
462 482
483 if (unlikely(len < 24)) {
484 printk(KERN_WARNING "%s: skb too small (%d).\n",
485 ieee->dev->name, len);
486 goto success;
487 }
488
489 /* When we allocate the TXB we allocate enough space for the reserve
490 * and full fragment bytes (bytes_per_frag doesn't include prefix,
491 * postfix, header, FCS, etc.) */
492 txb = ieee80211_alloc_txb(1, len, GFP_ATOMIC);
493 if (unlikely(!txb)) {
494 printk(KERN_WARNING "%s: Could not allocate TXB\n",
495 ieee->dev->name);
496 goto failed;
497 }
498 txb->encrypted = 0;
499 txb->payload_size = len;
500
501 skb_frag = txb->fragments[0];
502
503 memcpy(skb_put(skb_frag, len), frame, len);
504
505 if (ieee->config &
506 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
507 skb_put(skb_frag, 4);
508
509 success:
510 spin_unlock_irqrestore(&ieee->lock, flags);
511
512 if (txb) {
513 if ((*ieee->hard_start_xmit) (txb, ieee->dev) == 0) {
514 stats->tx_packets++;
515 stats->tx_bytes += txb->payload_size;
516 return 0;
517 }
518 ieee80211_txb_free(txb);
519 }
520 return 0;
521
522 failed:
523 spin_unlock_irqrestore(&ieee->lock, flags);
524 stats->tx_errors++;
525 return 1;
463} 526}
464 527
528EXPORT_SYMBOL(ieee80211_tx_frame);
465EXPORT_SYMBOL(ieee80211_txb_free); 529EXPORT_SYMBOL(ieee80211_txb_free);