aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ieee80211.h23
-rw-r--r--net/ieee80211/ieee80211_rx.c58
-rw-r--r--net/ieee80211/ieee80211_tx.c64
3 files changed, 130 insertions, 15 deletions
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 5e11ccf8a763..43cf2e577191 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -769,6 +769,27 @@ struct ieee80211_device {
769 int (*hard_start_xmit) (struct ieee80211_txb * txb, 769 int (*hard_start_xmit) (struct ieee80211_txb * txb,
770 struct net_device * dev); 770 struct net_device * dev);
771 int (*reset_port) (struct net_device * dev); 771 int (*reset_port) (struct net_device * dev);
772 int (*is_queue_full) (struct net_device * dev, int pri);
773
774 /* Typical STA methods */
775 int (*handle_auth) (struct net_device * dev,
776 struct ieee80211_auth * auth);
777 int (*handle_disassoc) (struct net_device * dev,
778 struct ieee80211_disassoc * assoc);
779 int (*handle_beacon) (struct net_device * dev,
780 struct ieee80211_beacon * beacon,
781 struct ieee80211_network * network);
782 int (*handle_probe_response) (struct net_device * dev,
783 struct ieee80211_probe_response * resp,
784 struct ieee80211_network * network);
785 int (*handle_assoc_response) (struct net_device * dev,
786 struct ieee80211_assoc_response * resp,
787 struct ieee80211_network * network);
788
789 /* Typical AP methods */
790 int (*handle_assoc_request) (struct net_device * dev);
791 int (*handle_reassoc_request) (struct net_device * dev,
792 struct ieee80211_reassoc_request * req);
772 793
773 /* This must be the last item so that it points to the data 794 /* This must be the last item so that it points to the data
774 * allocated beyond this structure by alloc_ieee80211 */ 795 * allocated beyond this structure by alloc_ieee80211 */
@@ -877,6 +898,8 @@ extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
877/* ieee80211_tx.c */ 898/* ieee80211_tx.c */
878extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev); 899extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
879extern void ieee80211_txb_free(struct ieee80211_txb *); 900extern void ieee80211_txb_free(struct ieee80211_txb *);
901extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
902 struct ieee80211_hdr *frame, int len);
880 903
881/* ieee80211_rx.c */ 904/* ieee80211_rx.c */
882extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 905extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 71d14c7d915c..d1ae28280d7e 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -1029,12 +1029,18 @@ static inline void update_network(struct ieee80211_network *dst,
1029 /* dst->last_associate is not overwritten */ 1029 /* dst->last_associate is not overwritten */
1030} 1030}
1031 1031
1032static inline int is_beacon(int fc)
1033{
1034 return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
1035}
1036
1032static inline void ieee80211_process_probe_response(struct ieee80211_device 1037static inline void ieee80211_process_probe_response(struct ieee80211_device
1033 *ieee, struct 1038 *ieee, struct
1034 ieee80211_probe_response 1039 ieee80211_probe_response
1035 *beacon, struct ieee80211_rx_stats 1040 *beacon, struct ieee80211_rx_stats
1036 *stats) 1041 *stats)
1037{ 1042{
1043 struct net_device *dev = ieee->dev;
1038 struct ieee80211_network network; 1044 struct ieee80211_network network;
1039 struct ieee80211_network *target; 1045 struct ieee80211_network *target;
1040 struct ieee80211_network *oldest = NULL; 1046 struct ieee80211_network *oldest = NULL;
@@ -1070,11 +1076,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
1070 escape_essid(info_element->data, 1076 escape_essid(info_element->data,
1071 info_element->len), 1077 info_element->len),
1072 MAC_ARG(beacon->header.addr3), 1078 MAC_ARG(beacon->header.addr3),
1073 WLAN_FC_GET_STYPE(le16_to_cpu 1079 is_beacon(le16_to_cpu
1074 (beacon->header. 1080 (beacon->header.
1075 frame_ctl)) == 1081 frame_ctl)) ?
1076 IEEE80211_STYPE_PROBE_RESP ? 1082 "BEACON" : "PROBE RESPONSE");
1077 "PROBE RESPONSE" : "BEACON");
1078 return; 1083 return;
1079 } 1084 }
1080 1085
@@ -1123,11 +1128,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
1123 escape_essid(network.ssid, 1128 escape_essid(network.ssid,
1124 network.ssid_len), 1129 network.ssid_len),
1125 MAC_ARG(network.bssid), 1130 MAC_ARG(network.bssid),
1126 WLAN_FC_GET_STYPE(le16_to_cpu 1131 is_beacon(le16_to_cpu
1127 (beacon->header. 1132 (beacon->header.
1128 frame_ctl)) == 1133 frame_ctl)) ?
1129 IEEE80211_STYPE_PROBE_RESP ? 1134 "BEACON" : "PROBE RESPONSE");
1130 "PROBE RESPONSE" : "BEACON");
1131#endif 1135#endif
1132 memcpy(target, &network, sizeof(*target)); 1136 memcpy(target, &network, sizeof(*target));
1133 list_add_tail(&target->list, &ieee->network_list); 1137 list_add_tail(&target->list, &ieee->network_list);
@@ -1136,15 +1140,22 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
1136 escape_essid(target->ssid, 1140 escape_essid(target->ssid,
1137 target->ssid_len), 1141 target->ssid_len),
1138 MAC_ARG(target->bssid), 1142 MAC_ARG(target->bssid),
1139 WLAN_FC_GET_STYPE(le16_to_cpu 1143 is_beacon(le16_to_cpu
1140 (beacon->header. 1144 (beacon->header.
1141 frame_ctl)) == 1145 frame_ctl)) ?
1142 IEEE80211_STYPE_PROBE_RESP ? 1146 "BEACON" : "PROBE RESPONSE");
1143 "PROBE RESPONSE" : "BEACON");
1144 update_network(target, &network); 1147 update_network(target, &network);
1145 } 1148 }
1146 1149
1147 spin_unlock_irqrestore(&ieee->lock, flags); 1150 spin_unlock_irqrestore(&ieee->lock, flags);
1151
1152 if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) {
1153 if (ieee->handle_beacon != NULL)
1154 ieee->handle_beacon(dev, beacon, &network);
1155 } else {
1156 if (ieee->handle_probe_response != NULL)
1157 ieee->handle_probe_response(dev, beacon, &network);
1158 }
1148} 1159}
1149 1160
1150void ieee80211_rx_mgt(struct ieee80211_device *ieee, 1161void ieee80211_rx_mgt(struct ieee80211_device *ieee,
@@ -1185,6 +1196,23 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1185 ieee80211_probe_response *) 1196 ieee80211_probe_response *)
1186 header, stats); 1197 header, stats);
1187 break; 1198 break;
1199 case IEEE80211_STYPE_AUTH:
1200
1201 IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
1202 WLAN_FC_GET_STYPE(le16_to_cpu
1203 (header->frame_ctl)));
1204
1205 if (ieee->handle_auth != NULL)
1206 ieee->handle_auth(ieee->dev,
1207 (struct ieee80211_auth *)header);
1208 break;
1209
1210 case IEEE80211_STYPE_DISASSOC:
1211 if (ieee->handle_disassoc != NULL)
1212 ieee->handle_disassoc(ieee->dev,
1213 (struct ieee80211_disassoc *)
1214 header);
1215 break;
1188 1216
1189 default: 1217 default:
1190 IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n", 1218 IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
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);