aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-13 14:56:37 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:08 -0500
commit6ab10ff8738dfb098fd32132b7ebcf5cdb43ebde (patch)
tree7bb2cf0ce4d1b286aa14f4e0ae9d24dfee8b75c2 /drivers/net/wireless/iwlwifi/iwl-rx.c
parent9bb487b406692e172b15eba58de7d69358ac2005 (diff)
iwlwifi: handle unicast PS buffering
Using the new mac80211 functionality, this makes iwlwifi handle unicast PS buffering correctly. The device works like this: * when a station goes to sleep, the microcode notices this and marks the station as asleep * when the station is marked asleep, the microcode refuses to transmit to the station and rejects all frames queued to it with the failure status code TX_STATUS_FAIL_DEST_PS (a previous patch handled this correctly) * when we need to send frames to the station _although_ it is asleep, we need to tell the ucode how many, and this is asynchronous with sending so we cannot just send the frames, we need to wait for all other frames to be flushed, and then update the counter before sending out the poll response frames. This is handled partially in the driver and partially in mac80211. In order to do all this correctly, we need to * keep track of how many frames are pending for each associated client station (avoid doing it for other stations to avoid the atomic ops) * tell mac80211 that we driver-block the PS status while there are still frames pending on the queues, and once they are all rejected (due to the dest sta being in PS) unblock mac80211 Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c17
1 files changed, 2 insertions, 15 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 9d010a0d83af..cc980d5d57c2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1028,7 +1028,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1028 struct iwl4965_rx_mpdu_res_start *amsdu; 1028 struct iwl4965_rx_mpdu_res_start *amsdu;
1029 u32 len; 1029 u32 len;
1030 u32 ampdu_status; 1030 u32 ampdu_status;
1031 u16 fc;
1032 u32 rate_n_flags; 1031 u32 rate_n_flags;
1033 1032
1034 /** 1033 /**
@@ -1161,20 +1160,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1161 priv->last_tsf = le64_to_cpu(phy_res->timestamp); 1160 priv->last_tsf = le64_to_cpu(phy_res->timestamp);
1162 } 1161 }
1163 1162
1164 fc = le16_to_cpu(header->frame_control); 1163 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1165 switch (fc & IEEE80211_FCTL_FTYPE) { 1164 rxb, &rx_status);
1166 case IEEE80211_FTYPE_MGMT:
1167 case IEEE80211_FTYPE_DATA:
1168 if (priv->iw_mode == NL80211_IFTYPE_AP)
1169 iwl_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
1170 header->addr2);
1171 /* fall through */
1172 default:
1173 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1174 rxb, &rx_status);
1175 break;
1176
1177 }
1178} 1165}
1179EXPORT_SYMBOL(iwl_rx_reply_rx); 1166EXPORT_SYMBOL(iwl_rx_reply_rx);
1180 1167