aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-07-27 09:43:22 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:47:31 -0400
commit23a24defa0da567eac615828563935c195fb48dc (patch)
treedd698a74e0e8a7c3412266f884acb4795a62a0a4 /net/mac80211/rx.c
parent570bd537a9a1520ddebfed772bcf6eaf7510bec4 (diff)
[MAC80211]: split up __ieee80211_rx
The really indented part that does the huge switch on the interface type is a nuisance. Put it into an own function 'prepare_for_handlers'. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c157
1 files changed, 83 insertions, 74 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f7a1b61f9bef..21d401523d13 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1240,6 +1240,73 @@ ieee80211_rx_handler ieee80211_rx_handlers[] =
1240 1240
1241/* main receive path */ 1241/* main receive path */
1242 1242
1243static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1244 u8 *bssid, struct ieee80211_txrx_data *rx,
1245 struct ieee80211_hdr *hdr)
1246{
1247 int multicast = is_multicast_ether_addr(hdr->addr1);
1248
1249 switch (sdata->type) {
1250 case IEEE80211_IF_TYPE_STA:
1251 if (!bssid)
1252 return 0;
1253 if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
1254 if (!rx->u.rx.in_scan)
1255 return 0;
1256 rx->u.rx.ra_match = 0;
1257 } else if (!multicast &&
1258 compare_ether_addr(sdata->dev->dev_addr,
1259 hdr->addr1) != 0) {
1260 if (!sdata->promisc)
1261 return 0;
1262 rx->u.rx.ra_match = 0;
1263 }
1264 break;
1265 case IEEE80211_IF_TYPE_IBSS:
1266 if (!bssid)
1267 return 0;
1268 if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
1269 if (!rx->u.rx.in_scan)
1270 return 0;
1271 rx->u.rx.ra_match = 0;
1272 } else if (!multicast &&
1273 compare_ether_addr(sdata->dev->dev_addr,
1274 hdr->addr1) != 0) {
1275 if (!sdata->promisc)
1276 return 0;
1277 rx->u.rx.ra_match = 0;
1278 } else if (!rx->sta)
1279 rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb,
1280 bssid, hdr->addr2);
1281 break;
1282 case IEEE80211_IF_TYPE_AP:
1283 if (!bssid) {
1284 if (compare_ether_addr(sdata->dev->dev_addr,
1285 hdr->addr1))
1286 return 0;
1287 } else if (!ieee80211_bssid_match(bssid,
1288 sdata->dev->dev_addr)) {
1289 if (!rx->u.rx.in_scan)
1290 return 0;
1291 rx->u.rx.ra_match = 0;
1292 }
1293 if (sdata->dev == sdata->local->mdev && !rx->u.rx.in_scan)
1294 /* do not receive anything via
1295 * master device when not scanning */
1296 return 0;
1297 break;
1298 case IEEE80211_IF_TYPE_WDS:
1299 if (bssid ||
1300 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
1301 return 0;
1302 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
1303 return 0;
1304 break;
1305 }
1306
1307 return 1;
1308}
1309
1243/* 1310/*
1244 * This is the receive path handler. It is called by a low level driver when an 1311 * This is the receive path handler. It is called by a low level driver when an
1245 * 802.11 MPDU is received from the hardware. 1312 * 802.11 MPDU is received from the hardware.
@@ -1253,8 +1320,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1253 struct ieee80211_hdr *hdr; 1320 struct ieee80211_hdr *hdr;
1254 struct ieee80211_txrx_data rx; 1321 struct ieee80211_txrx_data rx;
1255 u16 type; 1322 u16 type;
1256 int multicast; 1323 int radiotap_len = 0, prepres;
1257 int radiotap_len = 0;
1258 struct ieee80211_sub_if_data *prev = NULL; 1324 struct ieee80211_sub_if_data *prev = NULL;
1259 struct sk_buff *skb_new; 1325 struct sk_buff *skb_new;
1260 u8 *bssid; 1326 u8 *bssid;
@@ -1274,18 +1340,16 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1274 type = rx.fc & IEEE80211_FCTL_FTYPE; 1340 type = rx.fc & IEEE80211_FCTL_FTYPE;
1275 if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) 1341 if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT)
1276 local->dot11ReceivedFragmentCount++; 1342 local->dot11ReceivedFragmentCount++;
1277 multicast = is_multicast_ether_addr(hdr->addr1);
1278 1343
1279 if (skb->len >= 16) 1344 if (skb->len >= 16) {
1280 sta = rx.sta = sta_info_get(local, hdr->addr2); 1345 sta = rx.sta = sta_info_get(local, hdr->addr2);
1281 else 1346 if (sta) {
1347 rx.dev = rx.sta->dev;
1348 rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
1349 }
1350 } else
1282 sta = rx.sta = NULL; 1351 sta = rx.sta = NULL;
1283 1352
1284 if (sta) {
1285 rx.dev = sta->dev;
1286 rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
1287 }
1288
1289 if ((status->flag & RX_FLAG_MMIC_ERROR)) { 1353 if ((status->flag & RX_FLAG_MMIC_ERROR)) {
1290 ieee80211_rx_michael_mic_report(local->mdev, hdr, sta, &rx); 1354 ieee80211_rx_michael_mic_report(local->mdev, hdr, sta, &rx);
1291 goto end; 1355 goto end;
@@ -1301,10 +1365,10 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1301 1365
1302 skb_push(skb, radiotap_len); 1366 skb_push(skb, radiotap_len);
1303 if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) && 1367 if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) &&
1304 !local->iff_promiscs && !multicast) { 1368 !local->iff_promiscs && !is_multicast_ether_addr(hdr->addr1)) {
1305 rx.u.rx.ra_match = 1; 1369 rx.u.rx.ra_match = 1;
1306 ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx, 1370 ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx,
1307 sta); 1371 rx.sta);
1308 sta_info_put(sta); 1372 sta_info_put(sta);
1309 return; 1373 return;
1310 } 1374 }
@@ -1314,68 +1378,13 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
1314 read_lock(&local->sub_if_lock); 1378 read_lock(&local->sub_if_lock);
1315 list_for_each_entry(sdata, &local->sub_if_list, list) { 1379 list_for_each_entry(sdata, &local->sub_if_list, list) {
1316 rx.u.rx.ra_match = 1; 1380 rx.u.rx.ra_match = 1;
1317 switch (sdata->type) { 1381
1318 case IEEE80211_IF_TYPE_STA: 1382 prepres = prepare_for_handlers(sdata, bssid, &rx, hdr);
1319 if (!bssid) 1383 /* prepare_for_handlers can change sta */
1320 continue; 1384 sta = rx.sta;
1321 if (!ieee80211_bssid_match(bssid, 1385
1322 sdata->u.sta.bssid)) { 1386 if (!prepres)
1323 if (!rx.u.rx.in_scan) 1387 continue;
1324 continue;
1325 rx.u.rx.ra_match = 0;
1326 } else if (!multicast &&
1327 compare_ether_addr(sdata->dev->dev_addr,
1328 hdr->addr1) != 0) {
1329 if (!sdata->promisc)
1330 continue;
1331 rx.u.rx.ra_match = 0;
1332 }
1333 break;
1334 case IEEE80211_IF_TYPE_IBSS:
1335 if (!bssid)
1336 continue;
1337 if (!ieee80211_bssid_match(bssid,
1338 sdata->u.sta.bssid)) {
1339 if (!rx.u.rx.in_scan)
1340 continue;
1341 rx.u.rx.ra_match = 0;
1342 } else if (!multicast &&
1343 compare_ether_addr(sdata->dev->dev_addr,
1344 hdr->addr1) != 0) {
1345 if (!sdata->promisc)
1346 continue;
1347 rx.u.rx.ra_match = 0;
1348 } else if (!sta)
1349 sta = rx.sta =
1350 ieee80211_ibss_add_sta(sdata->dev,
1351 skb, bssid,
1352 hdr->addr2);
1353 break;
1354 case IEEE80211_IF_TYPE_AP:
1355 if (!bssid) {
1356 if (compare_ether_addr(sdata->dev->dev_addr,
1357 hdr->addr1))
1358 continue;
1359 } else if (!ieee80211_bssid_match(bssid,
1360 sdata->dev->dev_addr)) {
1361 if (!rx.u.rx.in_scan)
1362 continue;
1363 rx.u.rx.ra_match = 0;
1364 }
1365 if (sdata->dev == local->mdev && !rx.u.rx.in_scan)
1366 /* do not receive anything via
1367 * master device when not scanning */
1368 continue;
1369 break;
1370 case IEEE80211_IF_TYPE_WDS:
1371 if (bssid ||
1372 (rx.fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
1373 continue;
1374 if (compare_ether_addr(sdata->u.wds.remote_addr,
1375 hdr->addr2))
1376 continue;
1377 break;
1378 }
1379 1388
1380 if (prev) { 1389 if (prev) {
1381 skb_new = skb_copy(skb, GFP_ATOMIC); 1390 skb_new = skb_copy(skb, GFP_ATOMIC);