aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_rx.c
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2006-01-19 03:22:15 -0500
committerJohn W. Linville <linville@tuxdriver.com>2006-01-27 17:08:07 -0500
commitd1b46b0fba8c1049135ee5d60910b04463dccc95 (patch)
tree1ec055eee19d523f5fdd7bbe696dc1f0c0dbd105 /net/ieee80211/ieee80211_rx.c
parent15f385982e3a4782fe8ed71a9a6beb64a2160c30 (diff)
[PATCH] ieee80211: Add 802.11h information element parsing
Added default handlers for various 802.11h DFS and TPC information elements. Moved all information elements into single location (called from two places). Added debug message with information on unparsed IEs if debug_level set. Added code to reset network IBSS DFS information when appropriate. Added code to invoke driver callback for 802.11h ACTION STYPE. Changed a few printk's to IEEE80211_DEBUG_MGMT. Signed-off-by: James Ketrenos <jketreno@linux.intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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: