aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarvey Harrison <harvey.harrison@gmail.com>2008-06-11 17:21:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-14 12:18:12 -0400
commitfd7c8a40b2a63863f749e4d17f0d94d2e5ab1331 (patch)
tree098e07d68b4d1e7a6c02750db480204c0dd469d5
parente36cfdc9b17fa64245ee6206287e5120e59bbfca (diff)
mac80211: add helpers for frame control testing
A few general categories: 1) ieee80211_has_* tests if particular fctl bits are set, the helpers are de in the same order as the fctl defines: A combined _has_a4 was also added to test when both FROMDS and TODS are set. 2) ieee80211_is_* is meant to test whether the frame control is of a certain ftype - data, mgmt, ctl, and two special helpers _is_data_qos, _is_data_pres which also test a subset of the stype space. When testing for a particular stype applicable only to one ftype, functions like ieee80211_is_ack have been added. Note that the ftype is also being checked in these helpers. They have been added for all mgmt and ctl stypes in the same order as the STYPE defines. 3) ieee80211_get_* is meant to take a struct ieee80211_hdr * and returns a pointer to somewhere in the struct, see get_SA, get_DA, get_qos_ctl. The intel wireless drivers had helpers that used this namespace, convert the all to use the new helpers and remove the byteshifting as they were defined in cpu-order rather than little-endian. Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c36
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h109
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c33
-rw-r--r--include/linux/ieee80211.h392
8 files changed, 457 insertions, 213 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 0ba6889dfd41..63f20370032d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -388,7 +388,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
388 u32 print_dump = 0; /* set to 1 to dump all frames' contents */ 388 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
389 u32 hundred = 0; 389 u32 hundred = 0;
390 u32 dataframe = 0; 390 u32 dataframe = 0;
391 u16 fc; 391 __le16 fc;
392 u16 seq_ctl; 392 u16 seq_ctl;
393 u16 channel; 393 u16 channel;
394 u16 phy_flags; 394 u16 phy_flags;
@@ -407,7 +407,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
407 u8 *data = IWL_RX_DATA(pkt); 407 u8 *data = IWL_RX_DATA(pkt);
408 408
409 /* MAC header */ 409 /* MAC header */
410 fc = le16_to_cpu(header->frame_control); 410 fc = header->frame_control;
411 seq_ctl = le16_to_cpu(header->seq_ctrl); 411 seq_ctl = le16_to_cpu(header->seq_ctrl);
412 412
413 /* metadata */ 413 /* metadata */
@@ -431,8 +431,8 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
431 431
432 /* if data frame is to us and all is good, 432 /* if data frame is to us and all is good,
433 * (optionally) print summary for only 1 out of every 100 */ 433 * (optionally) print summary for only 1 out of every 100 */
434 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == 434 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
435 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { 435 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
436 dataframe = 1; 436 dataframe = 1;
437 if (!group100) 437 if (!group100)
438 print_summary = 1; /* print each frame */ 438 print_summary = 1; /* print each frame */
@@ -455,13 +455,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
455 455
456 if (hundred) 456 if (hundred)
457 title = "100Frames"; 457 title = "100Frames";
458 else if (fc & IEEE80211_FCTL_RETRY) 458 else if (ieee80211_has_retry(fc))
459 title = "Retry"; 459 title = "Retry";
460 else if (ieee80211_is_assoc_response(fc)) 460 else if (ieee80211_is_assoc_resp(fc))
461 title = "AscRsp"; 461 title = "AscRsp";
462 else if (ieee80211_is_reassoc_response(fc)) 462 else if (ieee80211_is_reassoc_resp(fc))
463 title = "RasRsp"; 463 title = "RasRsp";
464 else if (ieee80211_is_probe_response(fc)) { 464 else if (ieee80211_is_probe_resp(fc)) {
465 title = "PrbRsp"; 465 title = "PrbRsp";
466 print_dump = 1; /* dump frame contents */ 466 print_dump = 1; /* dump frame contents */
467 } else if (ieee80211_is_beacon(fc)) { 467 } else if (ieee80211_is_beacon(fc)) {
@@ -490,14 +490,14 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
490 if (dataframe) 490 if (dataframe)
491 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " 491 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
492 "len=%u, rssi=%d, chnl=%d, rate=%u, \n", 492 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
493 title, fc, header->addr1[5], 493 title, le16_to_cpu(fc), header->addr1[5],
494 length, rssi, channel, rate); 494 length, rssi, channel, rate);
495 else { 495 else {
496 /* src/dst addresses assume managed mode */ 496 /* src/dst addresses assume managed mode */
497 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " 497 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
498 "src=0x%02x, rssi=%u, tim=%lu usec, " 498 "src=0x%02x, rssi=%u, tim=%lu usec, "
499 "phy=0x%02x, chnl=%d\n", 499 "phy=0x%02x, chnl=%d\n",
500 title, fc, header->addr1[5], 500 title, le16_to_cpu(fc), header->addr1[5],
501 header->addr3[5], rssi, 501 header->addr3[5], rssi,
502 tsf_low - priv->scan_start_tsf, 502 tsf_low - priv->scan_start_tsf,
503 phy_flags, channel); 503 phy_flags, channel);
@@ -971,7 +971,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
971 u8 rts_retry_limit; 971 u8 rts_retry_limit;
972 u8 data_retry_limit; 972 u8 data_retry_limit;
973 __le32 tx_flags; 973 __le32 tx_flags;
974 u16 fc = le16_to_cpu(hdr->frame_control); 974 __le16 fc = hdr->frame_control;
975 975
976 rate = iwl3945_rates[rate_index].plcp; 976 rate = iwl3945_rates[rate_index].plcp;
977 tx_flags = cmd->cmd.tx.tx_flags; 977 tx_flags = cmd->cmd.tx.tx_flags;
@@ -996,7 +996,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
996 else 996 else
997 rts_retry_limit = 7; 997 rts_retry_limit = 7;
998 998
999 if (ieee80211_is_probe_response(fc)) { 999 if (ieee80211_is_probe_resp(fc)) {
1000 data_retry_limit = 3; 1000 data_retry_limit = 3;
1001 if (data_retry_limit < rts_retry_limit) 1001 if (data_retry_limit < rts_retry_limit)
1002 rts_retry_limit = data_retry_limit; 1002 rts_retry_limit = data_retry_limit;
@@ -1006,12 +1006,12 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
1006 if (priv->data_retry_limit != -1) 1006 if (priv->data_retry_limit != -1)
1007 data_retry_limit = priv->data_retry_limit; 1007 data_retry_limit = priv->data_retry_limit;
1008 1008
1009 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { 1009 if (ieee80211_is_mgmt(fc)) {
1010 switch (fc & IEEE80211_FCTL_STYPE) { 1010 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
1011 case IEEE80211_STYPE_AUTH: 1011 case cpu_to_le16(IEEE80211_STYPE_AUTH):
1012 case IEEE80211_STYPE_DEAUTH: 1012 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
1013 case IEEE80211_STYPE_ASSOC_REQ: 1013 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
1014 case IEEE80211_STYPE_REASSOC_REQ: 1014 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
1015 if (tx_flags & TX_CMD_FLG_RTS_MSK) { 1015 if (tx_flags & TX_CMD_FLG_RTS_MSK) {
1016 tx_flags &= ~TX_CMD_FLG_RTS_MSK; 1016 tx_flags &= ~TX_CMD_FLG_RTS_MSK;
1017 tx_flags |= TX_CMD_FLG_CTS_MSK; 1017 tx_flags |= TX_CMD_FLG_CTS_MSK;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index d601d31e0de9..202303117285 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -281,11 +281,11 @@ static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
281 u32 time_diff; 281 u32 time_diff;
282 s32 index; 282 s32 index;
283 struct iwl4965_traffic_load *tl = NULL; 283 struct iwl4965_traffic_load *tl = NULL;
284 u16 fc = le16_to_cpu(hdr->frame_control); 284 __le16 fc = hdr->frame_control;
285 u8 tid; 285 u8 tid;
286 286
287 if (ieee80211_is_qos_data(fc)) { 287 if (ieee80211_is_data_qos(fc)) {
288 u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); 288 u8 *qc = ieee80211_get_qos_ctl(hdr);
289 tid = qc[0] & 0xf; 289 tid = qc[0] & 0xf;
290 } else 290 } else
291 return MAX_TID_COUNT; 291 return MAX_TID_COUNT;
@@ -794,7 +794,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
794 struct iwl4965_scale_tbl_info tbl_type; 794 struct iwl4965_scale_tbl_info tbl_type;
795 struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; 795 struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
796 u8 active_index = 0; 796 u8 active_index = 0;
797 u16 fc = le16_to_cpu(hdr->frame_control); 797 __le16 fc = hdr->frame_control;
798 s32 tpt = 0; 798 s32 tpt = 0;
799 799
800 IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n"); 800 IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
@@ -1651,7 +1651,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1651 int high_tpt = IWL_INVALID_VALUE; 1651 int high_tpt = IWL_INVALID_VALUE;
1652 u32 fail_count; 1652 u32 fail_count;
1653 s8 scale_action = 0; 1653 s8 scale_action = 0;
1654 u16 fc, rate_mask; 1654 __le16 fc;
1655 u16 rate_mask;
1655 u8 update_lq = 0; 1656 u8 update_lq = 0;
1656 struct iwl4965_lq_sta *lq_sta; 1657 struct iwl4965_lq_sta *lq_sta;
1657 struct iwl4965_scale_tbl_info *tbl, *tbl1; 1658 struct iwl4965_scale_tbl_info *tbl, *tbl1;
@@ -1666,7 +1667,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1666 1667
1667 IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); 1668 IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
1668 1669
1669 fc = le16_to_cpu(hdr->frame_control); 1670 fc = hdr->frame_control;
1670 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) { 1671 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
1671 /* Send management frames and broadcast/multicast data using 1672 /* Send management frames and broadcast/multicast data using
1672 * lowest rate. */ 1673 * lowest rate. */
@@ -2100,7 +2101,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
2100 struct ieee80211_conf *conf = &local->hw.conf; 2101 struct ieee80211_conf *conf = &local->hw.conf;
2101 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 2102 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2102 struct sta_info *sta; 2103 struct sta_info *sta;
2103 u16 fc; 2104 __le16 fc;
2104 struct iwl_priv *priv = (struct iwl_priv *)priv_rate; 2105 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
2105 struct iwl4965_lq_sta *lq_sta; 2106 struct iwl4965_lq_sta *lq_sta;
2106 2107
@@ -2112,7 +2113,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
2112 2113
2113 /* Send management frames and broadcast/multicast data using lowest 2114 /* Send management frames and broadcast/multicast data using lowest
2114 * rate. */ 2115 * rate. */
2115 fc = le16_to_cpu(hdr->frame_control); 2116 fc = hdr->frame_control;
2116 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || 2117 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
2117 !sta || !sta->rate_ctrl_priv) { 2118 !sta || !sta->rate_ctrl_priv) {
2118 sel->rate_idx = rate_lowest_index(local, sband, sta); 2119 sel->rate_idx = rate_lowest_index(local, sband, sta);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index df345cb6fd7d..ab5027345a01 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2388,7 +2388,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
2388 u32 print_dump = 0; /* set to 1 to dump all frames' contents */ 2388 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
2389 u32 hundred = 0; 2389 u32 hundred = 0;
2390 u32 dataframe = 0; 2390 u32 dataframe = 0;
2391 u16 fc; 2391 __le16 fc;
2392 u16 seq_ctl; 2392 u16 seq_ctl;
2393 u16 channel; 2393 u16 channel;
2394 u16 phy_flags; 2394 u16 phy_flags;
@@ -2411,7 +2411,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
2411 return; 2411 return;
2412 2412
2413 /* MAC header */ 2413 /* MAC header */
2414 fc = le16_to_cpu(header->frame_control); 2414 fc = header->frame_control;
2415 seq_ctl = le16_to_cpu(header->seq_ctrl); 2415 seq_ctl = le16_to_cpu(header->seq_ctrl);
2416 2416
2417 /* metadata */ 2417 /* metadata */
@@ -2436,8 +2436,8 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
2436 2436
2437 /* if data frame is to us and all is good, 2437 /* if data frame is to us and all is good,
2438 * (optionally) print summary for only 1 out of every 100 */ 2438 * (optionally) print summary for only 1 out of every 100 */
2439 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == 2439 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
2440 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { 2440 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
2441 dataframe = 1; 2441 dataframe = 1;
2442 if (!group100) 2442 if (!group100)
2443 print_summary = 1; /* print each frame */ 2443 print_summary = 1; /* print each frame */
@@ -2461,13 +2461,13 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
2461 2461
2462 if (hundred) 2462 if (hundred)
2463 title = "100Frames"; 2463 title = "100Frames";
2464 else if (fc & IEEE80211_FCTL_RETRY) 2464 else if (ieee80211_has_retry(fc))
2465 title = "Retry"; 2465 title = "Retry";
2466 else if (ieee80211_is_assoc_response(fc)) 2466 else if (ieee80211_is_assoc_resp(fc))
2467 title = "AscRsp"; 2467 title = "AscRsp";
2468 else if (ieee80211_is_reassoc_response(fc)) 2468 else if (ieee80211_is_reassoc_resp(fc))
2469 title = "RasRsp"; 2469 title = "RasRsp";
2470 else if (ieee80211_is_probe_response(fc)) { 2470 else if (ieee80211_is_probe_resp(fc)) {
2471 title = "PrbRsp"; 2471 title = "PrbRsp";
2472 print_dump = 1; /* dump frame contents */ 2472 print_dump = 1; /* dump frame contents */
2473 } else if (ieee80211_is_beacon(fc)) { 2473 } else if (ieee80211_is_beacon(fc)) {
@@ -2496,14 +2496,14 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
2496 if (dataframe) 2496 if (dataframe)
2497 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " 2497 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
2498 "len=%u, rssi=%d, chnl=%d, rate=%u, \n", 2498 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
2499 title, fc, header->addr1[5], 2499 title, le16_to_cpu(fc), header->addr1[5],
2500 length, rssi, channel, bitrate); 2500 length, rssi, channel, bitrate);
2501 else { 2501 else {
2502 /* src/dst addresses assume managed mode */ 2502 /* src/dst addresses assume managed mode */
2503 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " 2503 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
2504 "src=0x%02x, rssi=%u, tim=%lu usec, " 2504 "src=0x%02x, rssi=%u, tim=%lu usec, "
2505 "phy=0x%02x, chnl=%d\n", 2505 "phy=0x%02x, chnl=%d\n",
2506 title, fc, header->addr1[5], 2506 title, le16_to_cpu(fc), header->addr1[5],
2507 header->addr3[5], rssi, 2507 header->addr3[5], rssi,
2508 tsf_low - priv->scan_start_tsf, 2508 tsf_low - priv->scan_start_tsf,
2509 phy_flags, channel); 2509 phy_flags, channel);
@@ -3219,7 +3219,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
3219 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 3219 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
3220 u32 status = le32_to_cpu(tx_resp->u.status); 3220 u32 status = le32_to_cpu(tx_resp->u.status);
3221 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; 3221 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
3222 u16 fc; 3222 __le16 fc;
3223 struct ieee80211_hdr *hdr; 3223 struct ieee80211_hdr *hdr;
3224 u8 *qc = NULL; 3224 u8 *qc = NULL;
3225 3225
@@ -3235,9 +3235,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
3235 memset(&info->status, 0, sizeof(info->status)); 3235 memset(&info->status, 0, sizeof(info->status));
3236 3236
3237 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); 3237 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
3238 fc = le16_to_cpu(hdr->frame_control); 3238 fc = hdr->frame_control;
3239 if (ieee80211_is_qos_data(fc)) { 3239 if (ieee80211_is_data_qos(fc)) {
3240 qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); 3240 qc = ieee80211_get_qos_ctl(hdr);
3241 tid = qc[0] & 0xf; 3241 tid = qc[0] & 0xf;
3242 } 3242 }
3243 3243
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 8c466b02bdff..438c3812c390 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1252,7 +1252,6 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1252 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 1252 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
1253 u32 status = le16_to_cpu(tx_resp->status.status); 1253 u32 status = le16_to_cpu(tx_resp->status.status);
1254 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; 1254 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
1255 u16 fc;
1256 struct ieee80211_hdr *hdr; 1255 struct ieee80211_hdr *hdr;
1257 u8 *qc = NULL; 1256 u8 *qc = NULL;
1258 1257
@@ -1268,9 +1267,8 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1268 memset(&info->status, 0, sizeof(info->status)); 1267 memset(&info->status, 0, sizeof(info->status));
1269 1268
1270 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); 1269 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
1271 fc = le16_to_cpu(hdr->frame_control); 1270 if (ieee80211_is_data_qos(hdr->frame_control)) {
1272 if (ieee80211_is_qos_data(fc)) { 1271 qc = ieee80211_get_qos_ctl(hdr);
1273 qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
1274 tid = qc[0] & 0xf; 1272 tid = qc[0] & 0xf;
1275 } 1273 }
1276 1274
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index eec423a98fe6..41eed6793328 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -145,115 +145,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
145 return &hw->conf; 145 return &hw->conf;
146} 146}
147 147
148#define QOS_CONTROL_LEN 2
149
150
151static inline int ieee80211_is_management(u16 fc)
152{
153 return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT;
154}
155
156static inline int ieee80211_is_control(u16 fc)
157{
158 return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL;
159}
160
161static inline int ieee80211_is_data(u16 fc)
162{
163 return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA;
164}
165
166static inline int ieee80211_is_back_request(u16 fc)
167{
168 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
169 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ);
170}
171
172static inline int ieee80211_is_probe_response(u16 fc)
173{
174 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
175 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP);
176}
177
178static inline int ieee80211_is_probe_request(u16 fc)
179{
180 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
181 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_REQ);
182}
183
184static inline int ieee80211_is_beacon(u16 fc)
185{
186 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
187 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON);
188}
189
190static inline int ieee80211_is_atim(u16 fc)
191{
192 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
193 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ATIM);
194}
195
196static inline int ieee80211_is_assoc_request(u16 fc)
197{
198 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
199 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
200}
201
202static inline int ieee80211_is_assoc_response(u16 fc)
203{
204 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
205 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_RESP);
206}
207
208static inline int ieee80211_is_auth(u16 fc)
209{
210 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
211 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
212}
213
214static inline int ieee80211_is_deauth(u16 fc)
215{
216 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
217 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
218}
219
220static inline int ieee80211_is_disassoc(u16 fc)
221{
222 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
223 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
224}
225
226static inline int ieee80211_is_reassoc_request(u16 fc)
227{
228 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
229 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ);
230}
231
232static inline int ieee80211_is_reassoc_response(u16 fc)
233{
234 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
235 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_RESP);
236}
237
238static inline int ieee80211_is_qos_data(u16 fc)
239{
240 return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
241 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
242}
243/**
244 * ieee80211_get_qos_ctrl - get pointer to the QoS control field
245 *
246 * This function returns the pointer to 802.11 header QoS field (2 bytes)
247 * This function doesn't check whether hdr is a QoS hdr, use with care
248 * @hdr: struct ieee80211_hdr *hdr
249 * @hdr_len: header length
250 */
251
252static inline u8 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr, int hdr_len)
253{
254 return ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
255}
256
257static inline int iwl_check_bits(unsigned long field, unsigned long mask) 148static inline int iwl_check_bits(unsigned long field, unsigned long mask)
258{ 149{
259 return ((field & mask) == mask) ? 1 : 0; 150 return ((field & mask) == mask) ? 1 : 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index e804bf8aea80..98c434c52a64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -569,15 +569,15 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
569 struct ieee80211_hdr *hdr, 569 struct ieee80211_hdr *hdr,
570 int is_unicast, u8 std_id) 570 int is_unicast, u8 std_id)
571{ 571{
572 u16 fc = le16_to_cpu(hdr->frame_control); 572 __le16 fc = hdr->frame_control;
573 __le32 tx_flags = tx_cmd->tx_flags; 573 __le32 tx_flags = tx_cmd->tx_flags;
574 574
575 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 575 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
576 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { 576 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
577 tx_flags |= TX_CMD_FLG_ACK_MSK; 577 tx_flags |= TX_CMD_FLG_ACK_MSK;
578 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) 578 if (ieee80211_is_mgmt(fc))
579 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; 579 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
580 if (ieee80211_is_probe_response(fc) && 580 if (ieee80211_is_probe_resp(fc) &&
581 !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) 581 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
582 tx_flags |= TX_CMD_FLG_TSF_MSK; 582 tx_flags |= TX_CMD_FLG_TSF_MSK;
583 } else { 583 } else {
@@ -585,7 +585,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
585 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; 585 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
586 } 586 }
587 587
588 if (ieee80211_is_back_request(fc)) 588 if (ieee80211_is_back_req(fc))
589 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; 589 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
590 590
591 591
@@ -593,8 +593,8 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
593 if (ieee80211_get_morefrag(hdr)) 593 if (ieee80211_get_morefrag(hdr))
594 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; 594 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
595 595
596 if (ieee80211_is_qos_data(fc)) { 596 if (ieee80211_is_data_qos(fc)) {
597 u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); 597 u8 *qc = ieee80211_get_qos_ctl(hdr);
598 tx_cmd->tid_tspec = qc[0] & 0xf; 598 tx_cmd->tid_tspec = qc[0] & 0xf;
599 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; 599 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
600 } else { 600 } else {
@@ -613,9 +613,8 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
613 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; 613 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
614 614
615 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); 615 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
616 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { 616 if (ieee80211_is_mgmt(fc)) {
617 if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || 617 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
618 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
619 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); 618 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
620 else 619 else
621 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); 620 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
@@ -634,7 +633,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
634static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, 633static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
635 struct iwl_tx_cmd *tx_cmd, 634 struct iwl_tx_cmd *tx_cmd,
636 struct ieee80211_tx_info *info, 635 struct ieee80211_tx_info *info,
637 u16 fc, int sta_id, 636 __le16 fc, int sta_id,
638 int is_hcca) 637 int is_hcca)
639{ 638{
640 u8 rts_retry_limit = 0; 639 u8 rts_retry_limit = 0;
@@ -655,7 +654,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
655 rate_flags |= RATE_MCS_CCK_MSK; 654 rate_flags |= RATE_MCS_CCK_MSK;
656 655
657 656
658 if (ieee80211_is_probe_response(fc)) { 657 if (ieee80211_is_probe_resp(fc)) {
659 data_retry_limit = 3; 658 data_retry_limit = 3;
660 if (data_retry_limit < rts_retry_limit) 659 if (data_retry_limit < rts_retry_limit)
661 rts_retry_limit = data_retry_limit; 660 rts_retry_limit = data_retry_limit;
@@ -670,11 +669,11 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
670 tx_cmd->initial_rate_index = 0; 669 tx_cmd->initial_rate_index = 0;
671 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; 670 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
672 } else { 671 } else {
673 switch (fc & IEEE80211_FCTL_STYPE) { 672 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
674 case IEEE80211_STYPE_AUTH: 673 case cpu_to_le16(IEEE80211_STYPE_AUTH):
675 case IEEE80211_STYPE_DEAUTH: 674 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
676 case IEEE80211_STYPE_ASSOC_REQ: 675 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
677 case IEEE80211_STYPE_REASSOC_REQ: 676 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
678 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) { 677 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
679 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK; 678 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
680 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK; 679 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
@@ -771,7 +770,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
771 u16 seq_number = 0; 770 u16 seq_number = 0;
772 u8 id, hdr_len, unicast; 771 u8 id, hdr_len, unicast;
773 u8 sta_id; 772 u8 sta_id;
774 u16 fc; 773 __le16 fc;
775 u8 wait_write_ptr = 0; 774 u8 wait_write_ptr = 0;
776 u8 tid = 0; 775 u8 tid = 0;
777 u8 *qc = NULL; 776 u8 *qc = NULL;
@@ -798,19 +797,19 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
798 unicast = !is_multicast_ether_addr(hdr->addr1); 797 unicast = !is_multicast_ether_addr(hdr->addr1);
799 id = 0; 798 id = 0;
800 799
801 fc = le16_to_cpu(hdr->frame_control); 800 fc = hdr->frame_control;
802 801
803#ifdef CONFIG_IWLWIFI_DEBUG 802#ifdef CONFIG_IWLWIFI_DEBUG
804 if (ieee80211_is_auth(fc)) 803 if (ieee80211_is_auth(fc))
805 IWL_DEBUG_TX("Sending AUTH frame\n"); 804 IWL_DEBUG_TX("Sending AUTH frame\n");
806 else if (ieee80211_is_assoc_request(fc)) 805 else if (ieee80211_is_assoc_req(fc))
807 IWL_DEBUG_TX("Sending ASSOC frame\n"); 806 IWL_DEBUG_TX("Sending ASSOC frame\n");
808 else if (ieee80211_is_reassoc_request(fc)) 807 else if (ieee80211_is_reassoc_req(fc))
809 IWL_DEBUG_TX("Sending REASSOC frame\n"); 808 IWL_DEBUG_TX("Sending REASSOC frame\n");
810#endif 809#endif
811 810
812 /* drop all data frame if we are not associated */ 811 /* drop all data frame if we are not associated */
813 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && 812 if (ieee80211_is_data(fc) &&
814 (!iwl_is_associated(priv) || 813 (!iwl_is_associated(priv) ||
815 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || 814 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
816 !priv->assoc_station_added)) { 815 !priv->assoc_station_added)) {
@@ -820,7 +819,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
820 819
821 spin_unlock_irqrestore(&priv->lock, flags); 820 spin_unlock_irqrestore(&priv->lock, flags);
822 821
823 hdr_len = ieee80211_get_hdrlen(fc); 822 hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
824 823
825 /* Find (or create) index into station table for destination station */ 824 /* Find (or create) index into station table for destination station */
826 sta_id = iwl_get_sta_id(priv, hdr); 825 sta_id = iwl_get_sta_id(priv, hdr);
@@ -834,8 +833,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
834 833
835 IWL_DEBUG_TX("station Id %d\n", sta_id); 834 IWL_DEBUG_TX("station Id %d\n", sta_id);
836 835
837 if (ieee80211_is_qos_data(fc)) { 836 if (ieee80211_is_data_qos(fc)) {
838 qc = ieee80211_get_qos_ctrl(hdr, hdr_len); 837 qc = ieee80211_get_qos_ctl(hdr);
839 tid = qc[0] & 0xf; 838 tid = qc[0] & 0xf;
840 seq_number = priv->stations[sta_id].tid[tid].seq_number & 839 seq_number = priv->stations[sta_id].tid[tid].seq_number &
841 IEEE80211_SCTL_SEQ; 840 IEEE80211_SCTL_SEQ;
@@ -938,7 +937,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
938 /* set is_hcca to 0; it probably will never be implemented */ 937 /* set is_hcca to 0; it probably will never be implemented */
939 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); 938 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
940 939
941 iwl_update_tx_stats(priv, fc, len); 940 iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
942 941
943 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + 942 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
944 offsetof(struct iwl_tx_cmd, scratch); 943 offsetof(struct iwl_tx_cmd, scratch);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d0084bcb1eca..0a5bbe9ee938 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2431,15 +2431,15 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
2431 struct ieee80211_hdr *hdr, 2431 struct ieee80211_hdr *hdr,
2432 int is_unicast, u8 std_id) 2432 int is_unicast, u8 std_id)
2433{ 2433{
2434 u16 fc = le16_to_cpu(hdr->frame_control); 2434 __le16 fc = hdr->frame_control;
2435 __le32 tx_flags = cmd->cmd.tx.tx_flags; 2435 __le32 tx_flags = cmd->cmd.tx.tx_flags;
2436 2436
2437 cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 2437 cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
2438 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { 2438 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
2439 tx_flags |= TX_CMD_FLG_ACK_MSK; 2439 tx_flags |= TX_CMD_FLG_ACK_MSK;
2440 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) 2440 if (ieee80211_is_mgmt(fc))
2441 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; 2441 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
2442 if (ieee80211_is_probe_response(fc) && 2442 if (ieee80211_is_probe_resp(fc) &&
2443 !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) 2443 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
2444 tx_flags |= TX_CMD_FLG_TSF_MSK; 2444 tx_flags |= TX_CMD_FLG_TSF_MSK;
2445 } else { 2445 } else {
@@ -2451,8 +2451,8 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
2451 if (ieee80211_get_morefrag(hdr)) 2451 if (ieee80211_get_morefrag(hdr))
2452 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; 2452 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
2453 2453
2454 if (ieee80211_is_qos_data(fc)) { 2454 if (ieee80211_is_data_qos(fc)) {
2455 u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); 2455 u8 *qc = ieee80211_get_qos_ctl(hdr);
2456 cmd->cmd.tx.tid_tspec = qc[0] & 0xf; 2456 cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
2457 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; 2457 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
2458 } else { 2458 } else {
@@ -2471,9 +2471,8 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
2471 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; 2471 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
2472 2472
2473 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); 2473 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
2474 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { 2474 if (ieee80211_is_mgmt(fc)) {
2475 if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || 2475 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
2476 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
2477 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); 2476 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
2478 else 2477 else
2479 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); 2478 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
@@ -2564,7 +2563,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
2564 u8 sta_id; 2563 u8 sta_id;
2565 u8 tid = 0; 2564 u8 tid = 0;
2566 u16 seq_number = 0; 2565 u16 seq_number = 0;
2567 u16 fc; 2566 __le16 fc;
2568 u8 wait_write_ptr = 0; 2567 u8 wait_write_ptr = 0;
2569 u8 *qc = NULL; 2568 u8 *qc = NULL;
2570 unsigned long flags; 2569 unsigned long flags;
@@ -2589,28 +2588,28 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
2589 unicast = !is_multicast_ether_addr(hdr->addr1); 2588 unicast = !is_multicast_ether_addr(hdr->addr1);
2590 id = 0; 2589 id = 0;
2591 2590
2592 fc = le16_to_cpu(hdr->frame_control); 2591 fc = hdr->frame_control;
2593 2592
2594#ifdef CONFIG_IWL3945_DEBUG 2593#ifdef CONFIG_IWL3945_DEBUG
2595 if (ieee80211_is_auth(fc)) 2594 if (ieee80211_is_auth(fc))
2596 IWL_DEBUG_TX("Sending AUTH frame\n"); 2595 IWL_DEBUG_TX("Sending AUTH frame\n");
2597 else if (ieee80211_is_assoc_request(fc)) 2596 else if (ieee80211_is_assoc_req(fc))
2598 IWL_DEBUG_TX("Sending ASSOC frame\n"); 2597 IWL_DEBUG_TX("Sending ASSOC frame\n");
2599 else if (ieee80211_is_reassoc_request(fc)) 2598 else if (ieee80211_is_reassoc_req(fc))
2600 IWL_DEBUG_TX("Sending REASSOC frame\n"); 2599 IWL_DEBUG_TX("Sending REASSOC frame\n");
2601#endif 2600#endif
2602 2601
2603 /* drop all data frame if we are not associated */ 2602 /* drop all data frame if we are not associated */
2604 if ((!iwl3945_is_associated(priv) || 2603 if ((!iwl3945_is_associated(priv) ||
2605 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && 2604 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
2606 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { 2605 ieee80211_is_data(fc)) {
2607 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); 2606 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
2608 goto drop_unlock; 2607 goto drop_unlock;
2609 } 2608 }
2610 2609
2611 spin_unlock_irqrestore(&priv->lock, flags); 2610 spin_unlock_irqrestore(&priv->lock, flags);
2612 2611
2613 hdr_len = ieee80211_get_hdrlen(fc); 2612 hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
2614 2613
2615 /* Find (or create) index into station table for destination station */ 2614 /* Find (or create) index into station table for destination station */
2616 sta_id = iwl3945_get_sta_id(priv, hdr); 2615 sta_id = iwl3945_get_sta_id(priv, hdr);
@@ -2624,8 +2623,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
2624 2623
2625 IWL_DEBUG_RATE("station Id %d\n", sta_id); 2624 IWL_DEBUG_RATE("station Id %d\n", sta_id);
2626 2625
2627 if (ieee80211_is_qos_data(fc)) { 2626 if (ieee80211_is_data_qos(fc)) {
2628 qc = ieee80211_get_qos_ctrl(hdr, hdr_len); 2627 qc = ieee80211_get_qos_ctl(hdr);
2629 tid = qc[0] & 0xf; 2628 tid = qc[0] & 0xf;
2630 seq_number = priv->stations[sta_id].tid[tid].seq_number & 2629 seq_number = priv->stations[sta_id].tid[tid].seq_number &
2631 IEEE80211_SCTL_SEQ; 2630 IEEE80211_SCTL_SEQ;
@@ -2746,7 +2745,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
2746 sizeof(out_cmd->cmd.tx)); 2745 sizeof(out_cmd->cmd.tx));
2747 2746
2748 iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, 2747 iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
2749 ieee80211_get_hdrlen(fc)); 2748 ieee80211_get_hdrlen(le16_to_cpu(fc)));
2750 2749
2751 /* Tell device the write index *just past* this latest filled TFD */ 2750 /* Tell device the write index *just past* this latest filled TFD */
2752 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 2751 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 8f2c20b4a15d..371237b0d8b9 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -98,6 +98,7 @@
98 98
99#define IEEE80211_MAX_SSID_LEN 32 99#define IEEE80211_MAX_SSID_LEN 32
100#define IEEE80211_MAX_MESH_ID_LEN 32 100#define IEEE80211_MAX_MESH_ID_LEN 32
101#define IEEE80211_QOS_CTL_LEN 2
101 102
102struct ieee80211_hdr { 103struct ieee80211_hdr {
103 __le16 frame_control; 104 __le16 frame_control;
@@ -109,6 +110,355 @@ struct ieee80211_hdr {
109 u8 addr4[6]; 110 u8 addr4[6];
110} __attribute__ ((packed)); 111} __attribute__ ((packed));
111 112
113/**
114 * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
115 * @fc: frame control bytes in little-endian byteorder
116 */
117static inline int ieee80211_has_tods(__le16 fc)
118{
119 return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0;
120}
121
122/**
123 * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set
124 * @fc: frame control bytes in little-endian byteorder
125 */
126static inline int ieee80211_has_fromds(__le16 fc)
127{
128 return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0;
129}
130
131/**
132 * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set
133 * @fc: frame control bytes in little-endian byteorder
134 */
135static inline int ieee80211_has_a4(__le16 fc)
136{
137 __le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
138 return (fc & tmp) == tmp;
139}
140
141/**
142 * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set
143 * @fc: frame control bytes in little-endian byteorder
144 */
145static inline int ieee80211_has_morefrags(__le16 fc)
146{
147 return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0;
148}
149
150/**
151 * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set
152 * @fc: frame control bytes in little-endian byteorder
153 */
154static inline int ieee80211_has_retry(__le16 fc)
155{
156 return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0;
157}
158
159/**
160 * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set
161 * @fc: frame control bytes in little-endian byteorder
162 */
163static inline int ieee80211_has_pm(__le16 fc)
164{
165 return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0;
166}
167
168/**
169 * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set
170 * @fc: frame control bytes in little-endian byteorder
171 */
172static inline int ieee80211_has_moredata(__le16 fc)
173{
174 return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0;
175}
176
177/**
178 * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set
179 * @fc: frame control bytes in little-endian byteorder
180 */
181static inline int ieee80211_has_protected(__le16 fc)
182{
183 return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0;
184}
185
186/**
187 * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set
188 * @fc: frame control bytes in little-endian byteorder
189 */
190static inline int ieee80211_has_order(__le16 fc)
191{
192 return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0;
193}
194
195/**
196 * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT
197 * @fc: frame control bytes in little-endian byteorder
198 */
199static inline int ieee80211_is_mgmt(__le16 fc)
200{
201 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
202 cpu_to_le16(IEEE80211_FTYPE_MGMT);
203}
204
205/**
206 * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL
207 * @fc: frame control bytes in little-endian byteorder
208 */
209static inline int ieee80211_is_ctl(__le16 fc)
210{
211 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
212 cpu_to_le16(IEEE80211_FTYPE_CTL);
213}
214
215/**
216 * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA
217 * @fc: frame control bytes in little-endian byteorder
218 */
219static inline int ieee80211_is_data(__le16 fc)
220{
221 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
222 cpu_to_le16(IEEE80211_FTYPE_DATA);
223}
224
225/**
226 * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set
227 * @fc: frame control bytes in little-endian byteorder
228 */
229static inline int ieee80211_is_data_qos(__le16 fc)
230{
231 /*
232 * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need
233 * to check the one bit
234 */
235 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) ==
236 cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA);
237}
238
239/**
240 * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data
241 * @fc: frame control bytes in little-endian byteorder
242 */
243static inline int ieee80211_is_data_present(__le16 fc)
244{
245 /*
246 * mask with 0x40 and test that that bit is clear to only return true
247 * for the data-containing substypes.
248 */
249 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) ==
250 cpu_to_le16(IEEE80211_FTYPE_DATA);
251}
252
253/**
254 * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ
255 * @fc: frame control bytes in little-endian byteorder
256 */
257static inline int ieee80211_is_assoc_req(__le16 fc)
258{
259 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
260 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
261}
262
263/**
264 * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP
265 * @fc: frame control bytes in little-endian byteorder
266 */
267static inline int ieee80211_is_assoc_resp(__le16 fc)
268{
269 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
270 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP);
271}
272
273/**
274 * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ
275 * @fc: frame control bytes in little-endian byteorder
276 */
277static inline int ieee80211_is_reassoc_req(__le16 fc)
278{
279 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
280 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ);
281}
282
283/**
284 * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP
285 * @fc: frame control bytes in little-endian byteorder
286 */
287static inline int ieee80211_is_reassoc_resp(__le16 fc)
288{
289 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
290 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP);
291}
292
293/**
294 * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ
295 * @fc: frame control bytes in little-endian byteorder
296 */
297static inline int ieee80211_is_probe_req(__le16 fc)
298{
299 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
300 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ);
301}
302
303/**
304 * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP
305 * @fc: frame control bytes in little-endian byteorder
306 */
307static inline int ieee80211_is_probe_resp(__le16 fc)
308{
309 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
310 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
311}
312
313/**
314 * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON
315 * @fc: frame control bytes in little-endian byteorder
316 */
317static inline int ieee80211_is_beacon(__le16 fc)
318{
319 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
320 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
321}
322
323/**
324 * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM
325 * @fc: frame control bytes in little-endian byteorder
326 */
327static inline int ieee80211_is_atim(__le16 fc)
328{
329 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
330 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM);
331}
332
333/**
334 * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC
335 * @fc: frame control bytes in little-endian byteorder
336 */
337static inline int ieee80211_is_disassoc(__le16 fc)
338{
339 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
340 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC);
341}
342
343/**
344 * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH
345 * @fc: frame control bytes in little-endian byteorder
346 */
347static inline int ieee80211_is_auth(__le16 fc)
348{
349 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
350 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
351}
352
353/**
354 * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH
355 * @fc: frame control bytes in little-endian byteorder
356 */
357static inline int ieee80211_is_deauth(__le16 fc)
358{
359 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
360 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
361}
362
363/**
364 * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION
365 * @fc: frame control bytes in little-endian byteorder
366 */
367static inline int ieee80211_is_action(__le16 fc)
368{
369 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
370 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
371}
372
373/**
374 * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ
375 * @fc: frame control bytes in little-endian byteorder
376 */
377static inline int ieee80211_is_back_req(__le16 fc)
378{
379 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
380 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ);
381}
382
383/**
384 * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK
385 * @fc: frame control bytes in little-endian byteorder
386 */
387static inline int ieee80211_is_back(__le16 fc)
388{
389 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
390 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK);
391}
392
393/**
394 * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL
395 * @fc: frame control bytes in little-endian byteorder
396 */
397static inline int ieee80211_is_pspoll(__le16 fc)
398{
399 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
400 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
401}
402
403/**
404 * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS
405 * @fc: frame control bytes in little-endian byteorder
406 */
407static inline int ieee80211_is_rts(__le16 fc)
408{
409 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
410 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
411}
412
413/**
414 * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS
415 * @fc: frame control bytes in little-endian byteorder
416 */
417static inline int ieee80211_is_cts(__le16 fc)
418{
419 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
420 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
421}
422
423/**
424 * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK
425 * @fc: frame control bytes in little-endian byteorder
426 */
427static inline int ieee80211_is_ack(__le16 fc)
428{
429 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
430 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK);
431}
432
433/**
434 * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND
435 * @fc: frame control bytes in little-endian byteorder
436 */
437static inline int ieee80211_is_cfend(__le16 fc)
438{
439 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
440 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND);
441}
442
443/**
444 * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK
445 * @fc: frame control bytes in little-endian byteorder
446 */
447static inline int ieee80211_is_cfendack(__le16 fc)
448{
449 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
450 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK);
451}
452
453/**
454 * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC
455 * @fc: frame control bytes in little-endian byteorder
456 */
457static inline int ieee80211_is_nullfunc(__le16 fc)
458{
459 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
460 cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC);
461}
112 462
113struct ieee80211s_hdr { 463struct ieee80211s_hdr {
114 u8 flags; 464 u8 flags;
@@ -553,48 +903,54 @@ enum ieee80211_back_parties {
553#define WLAN_MAX_KEY_LEN 32 903#define WLAN_MAX_KEY_LEN 32
554 904
555/** 905/**
906 * ieee80211_get_qos_ctl - get pointer to qos control bytes
907 * @hdr: the frame
908 *
909 * The qos ctrl bytes come after the frame_control, duration, seq_num
910 * and 3 or 4 addresses of length ETH_ALEN.
911 * 3 addr: 2 + 2 + 2 + 3*6 = 24
912 * 4 addr: 2 + 2 + 2 + 4*6 = 30
913 */
914static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
915{
916 if (ieee80211_has_a4(hdr->frame_control))
917 return (u8 *)hdr + 30;
918 else
919 return (u8 *)hdr + 24;
920}
921
922/**
556 * ieee80211_get_SA - get pointer to SA 923 * ieee80211_get_SA - get pointer to SA
924 * @hdr: the frame
557 * 925 *
558 * Given an 802.11 frame, this function returns the offset 926 * Given an 802.11 frame, this function returns the offset
559 * to the source address (SA). It does not verify that the 927 * to the source address (SA). It does not verify that the
560 * header is long enough to contain the address, and the 928 * header is long enough to contain the address, and the
561 * header must be long enough to contain the frame control 929 * header must be long enough to contain the frame control
562 * field. 930 * field.
563 *
564 * @hdr: the frame
565 */ 931 */
566static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) 932static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr)
567{ 933{
568 __le16 fc = hdr->frame_control; 934 if (ieee80211_has_a4(hdr->frame_control))
569 fc &= cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
570
571 switch (fc) {
572 case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS):
573 return hdr->addr3;
574 case __constant_cpu_to_le16(IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS):
575 return hdr->addr4; 935 return hdr->addr4;
576 default: 936 if (ieee80211_has_fromds(hdr->frame_control))
577 return hdr->addr2; 937 return hdr->addr3;
578 } 938 return hdr->addr2;
579} 939}
580 940
581/** 941/**
582 * ieee80211_get_DA - get pointer to DA 942 * ieee80211_get_DA - get pointer to DA
943 * @hdr: the frame
583 * 944 *
584 * Given an 802.11 frame, this function returns the offset 945 * Given an 802.11 frame, this function returns the offset
585 * to the destination address (DA). It does not verify that 946 * to the destination address (DA). It does not verify that
586 * the header is long enough to contain the address, and the 947 * the header is long enough to contain the address, and the
587 * header must be long enough to contain the frame control 948 * header must be long enough to contain the frame control
588 * field. 949 * field.
589 *
590 * @hdr: the frame
591 */ 950 */
592static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) 951static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr)
593{ 952{
594 __le16 fc = hdr->frame_control; 953 if (ieee80211_has_tods(hdr->frame_control))
595 fc &= cpu_to_le16(IEEE80211_FCTL_TODS);
596
597 if (fc)
598 return hdr->addr3; 954 return hdr->addr3;
599 else 955 else
600 return hdr->addr1; 956 return hdr->addr1;