aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211/ieee80211_rx.c')
-rw-r--r--net/ieee80211/ieee80211_rx.c109
1 files changed, 103 insertions, 6 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 4165da7ecff2..a4ebc22ee712 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -937,6 +937,45 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
937 return rc; 937 return rc;
938} 938}
939 939
940#ifdef CONFIG_IEEE80211_DEBUG
941#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
942
943static const char *get_info_element_string(u16 id)
944{
945 switch (id) {
946 MFIE_STRING(SSID);
947 MFIE_STRING(RATES);
948 MFIE_STRING(FH_SET);
949 MFIE_STRING(DS_SET);
950 MFIE_STRING(CF_SET);
951 MFIE_STRING(TIM);
952 MFIE_STRING(IBSS_SET);
953 MFIE_STRING(COUNTRY);
954 MFIE_STRING(HOP_PARAMS);
955 MFIE_STRING(HOP_TABLE);
956 MFIE_STRING(REQUEST);
957 MFIE_STRING(CHALLENGE);
958 MFIE_STRING(POWER_CONSTRAINT);
959 MFIE_STRING(POWER_CAPABILITY);
960 MFIE_STRING(TPC_REQUEST);
961 MFIE_STRING(TPC_REPORT);
962 MFIE_STRING(SUPP_CHANNELS);
963 MFIE_STRING(CSA);
964 MFIE_STRING(MEASURE_REQUEST);
965 MFIE_STRING(MEASURE_REPORT);
966 MFIE_STRING(QUIET);
967 MFIE_STRING(IBSS_DFS);
968 MFIE_STRING(ERP_INFO);
969 MFIE_STRING(RSN);
970 MFIE_STRING(RATES_EX);
971 MFIE_STRING(GENERIC);
972 MFIE_STRING(QOS_PARAMETER);
973 default:
974 return "UNKNOWN";
975 }
976}
977#endif
978
940static int ieee80211_parse_info_param(struct ieee80211_info_element 979static int ieee80211_parse_info_param(struct ieee80211_info_element
941 *info_element, u16 length, 980 *info_element, u16 length,
942 struct ieee80211_network *network) 981 struct ieee80211_network *network)
@@ -1100,10 +1139,49 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1100 printk(KERN_ERR 1139 printk(KERN_ERR
1101 "QoS Error need to parse QOS_PARAMETER IE\n"); 1140 "QoS Error need to parse QOS_PARAMETER IE\n");
1102 break; 1141 break;
1142 /* 802.11h */
1143 case MFIE_TYPE_POWER_CONSTRAINT:
1144 network->power_constraint = info_element->data[0];
1145 network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
1146 break;
1147
1148 case MFIE_TYPE_CSA:
1149 network->power_constraint = info_element->data[0];
1150 network->flags |= NETWORK_HAS_CSA;
1151 break;
1152
1153 case MFIE_TYPE_QUIET:
1154 network->quiet.count = info_element->data[0];
1155 network->quiet.period = info_element->data[1];
1156 network->quiet.duration = info_element->data[2];
1157 network->quiet.offset = info_element->data[3];
1158 network->flags |= NETWORK_HAS_QUIET;
1159 break;
1160
1161 case MFIE_TYPE_IBSS_DFS:
1162 if (network->ibss_dfs)
1163 break;
1164 network->ibss_dfs =
1165 kmalloc(info_element->len, GFP_ATOMIC);
1166 if (!network->ibss_dfs)
1167 return 1;
1168 memcpy(network->ibss_dfs, info_element->data,
1169 info_element->len);
1170 network->flags |= NETWORK_HAS_IBSS_DFS;
1171 break;
1172
1173 case MFIE_TYPE_TPC_REPORT:
1174 network->tpc_report.transmit_power =
1175 info_element->data[0];
1176 network->tpc_report.link_margin = info_element->data[1];
1177 network->flags |= NETWORK_HAS_TPC_REPORT;
1178 break;
1103 1179
1104 default: 1180 default:
1105 IEEE80211_DEBUG_MGMT("unsupported IE %d\n", 1181 IEEE80211_DEBUG_MGMT
1106 info_element->id); 1182 ("Unsupported info element: %s (%d)\n",
1183 get_info_element_string(info_element->id),
1184 info_element->id);
1107 break; 1185 break;
1108 } 1186 }
1109 1187
@@ -1119,7 +1197,9 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1119static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response 1197static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
1120 *frame, struct ieee80211_rx_stats *stats) 1198 *frame, struct ieee80211_rx_stats *stats)
1121{ 1199{
1122 struct ieee80211_network network_resp; 1200 struct ieee80211_network network_resp = {
1201 .ibss_dfs = NULL,
1202 };
1123 struct ieee80211_network *network = &network_resp; 1203 struct ieee80211_network *network = &network_resp;
1124 struct net_device *dev = ieee->dev; 1204 struct net_device *dev = ieee->dev;
1125 1205
@@ -1262,6 +1342,9 @@ static void update_network(struct ieee80211_network *dst,
1262 int qos_active; 1342 int qos_active;
1263 u8 old_param; 1343 u8 old_param;
1264 1344
1345 ieee80211_network_reset(dst);
1346 dst->ibss_dfs = src->ibss_dfs;
1347
1265 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); 1348 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
1266 dst->capability = src->capability; 1349 dst->capability = src->capability;
1267 memcpy(dst->rates, src->rates, src->rates_len); 1350 memcpy(dst->rates, src->rates, src->rates_len);
@@ -1323,7 +1406,9 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1323 *stats) 1406 *stats)
1324{ 1407{
1325 struct net_device *dev = ieee->dev; 1408 struct net_device *dev = ieee->dev;
1326 struct ieee80211_network network; 1409 struct ieee80211_network network = {
1410 .ibss_dfs = NULL,
1411 };
1327 struct ieee80211_network *target; 1412 struct ieee80211_network *target;
1328 struct ieee80211_network *oldest = NULL; 1413 struct ieee80211_network *oldest = NULL;
1329#ifdef CONFIG_IEEE80211_DEBUG 1414#ifdef CONFIG_IEEE80211_DEBUG
@@ -1398,6 +1483,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1398 escape_essid(target->ssid, 1483 escape_essid(target->ssid,
1399 target->ssid_len), 1484 target->ssid_len),
1400 MAC_ARG(target->bssid)); 1485 MAC_ARG(target->bssid));
1486 ieee80211_network_reset(target);
1401 } else { 1487 } else {
1402 /* Otherwise just pull from the free list */ 1488 /* Otherwise just pull from the free list */
1403 target = list_entry(ieee->network_free_list.next, 1489 target = list_entry(ieee->network_free_list.next,
@@ -1416,6 +1502,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1416 "BEACON" : "PROBE RESPONSE"); 1502 "BEACON" : "PROBE RESPONSE");
1417#endif 1503#endif
1418 memcpy(target, &network, sizeof(*target)); 1504 memcpy(target, &network, sizeof(*target));
1505 network.ibss_dfs = NULL;
1419 list_add_tail(&target->list, &ieee->network_list); 1506 list_add_tail(&target->list, &ieee->network_list);
1420 } else { 1507 } else {
1421 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", 1508 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
@@ -1427,6 +1514,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1427 frame_ctl)) ? 1514 frame_ctl)) ?
1428 "BEACON" : "PROBE RESPONSE"); 1515 "BEACON" : "PROBE RESPONSE");
1429 update_network(target, &network); 1516 update_network(target, &network);
1517 network.ibss_dfs = NULL;
1430 } 1518 }
1431 1519
1432 spin_unlock_irqrestore(&ieee->lock, flags); 1520 spin_unlock_irqrestore(&ieee->lock, flags);
@@ -1511,10 +1599,19 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1511 header); 1599 header);
1512 break; 1600 break;
1513 1601
1602 case IEEE80211_STYPE_ACTION:
1603 IEEE80211_DEBUG_MGMT("ACTION\n");
1604 if (ieee->handle_action)
1605 ieee->handle_action(ieee->dev,
1606 (struct ieee80211_action *)
1607 header, stats);
1608 break;
1609
1514 case IEEE80211_STYPE_DEAUTH: 1610 case IEEE80211_STYPE_DEAUTH:
1515 printk("DEAUTH from AP\n"); 1611 IEEE80211_DEBUG_MGMT("DEAUTH\n");
1516 if (ieee->handle_deauth != NULL) 1612 if (ieee->handle_deauth != NULL)
1517 ieee->handle_deauth(ieee->dev, (struct ieee80211_deauth *) 1613 ieee->handle_deauth(ieee->dev,
1614 (struct ieee80211_deauth *)
1518 header); 1615 header);
1519 break; 1616 break;
1520 default: 1617 default: