diff options
author | Hila Gonen <hila.gonen@intel.com> | 2013-03-13 12:00:03 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-05-29 03:03:24 -0400 |
commit | d64048edcd714095a5cf2d7019769d0d94e19892 (patch) | |
tree | 82b8a0a66772258c0a9320c5f3f14195b59b5326 /drivers | |
parent | 9ce4fa7291ff797f04849075a2ee3cf60f752aee (diff) |
iwlwifi: mvm: Add support for connection monitor offload
The firmware supports periodic keep alive and beacon monitoring,
so advertise connection monitor offload capability by setting
IEEE80211_HW_CONNECTION_MONITOR flag. Implement missed beacons
notification handler. Call ieee80211_beacon_loss in case of
missed beacons, so AP probing by mac80211 can be triggered.
Signed-off-by: Hila Gonen <hila.gonen@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/fw-api.h | 20 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/ops.c | 4 |
5 files changed, 54 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index db6f47406ac2..cbfb3beae783 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -164,6 +164,8 @@ enum { | |||
164 | CARD_STATE_CMD = 0xa0, | 164 | CARD_STATE_CMD = 0xa0, |
165 | CARD_STATE_NOTIFICATION = 0xa1, | 165 | CARD_STATE_NOTIFICATION = 0xa1, |
166 | 166 | ||
167 | MISSED_BEACONS_NOTIFICATION = 0xa2, | ||
168 | |||
167 | REPLY_RX_PHY_CMD = 0xc0, | 169 | REPLY_RX_PHY_CMD = 0xc0, |
168 | REPLY_RX_MPDU_CMD = 0xc1, | 170 | REPLY_RX_MPDU_CMD = 0xc1, |
169 | BA_NOTIF = 0xc5, | 171 | BA_NOTIF = 0xc5, |
@@ -943,6 +945,24 @@ struct iwl_card_state_notif { | |||
943 | } __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ | 945 | } __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ |
944 | 946 | ||
945 | /** | 947 | /** |
948 | * struct iwl_missed_beacons_notif - information on missed beacons | ||
949 | * ( MISSED_BEACONS_NOTIFICATION = 0xa2 ) | ||
950 | * @mac_id: interface ID | ||
951 | * @consec_missed_beacons_since_last_rx: number of consecutive missed | ||
952 | * beacons since last RX. | ||
953 | * @consec_missed_beacons: number of consecutive missed beacons | ||
954 | * @num_expected_beacons: | ||
955 | * @num_recvd_beacons: | ||
956 | */ | ||
957 | struct iwl_missed_beacons_notif { | ||
958 | __le32 mac_id; | ||
959 | __le32 consec_missed_beacons_since_last_rx; | ||
960 | __le32 consec_missed_beacons; | ||
961 | __le32 num_expected_beacons; | ||
962 | __le32 num_recvd_beacons; | ||
963 | } __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */ | ||
964 | |||
965 | /** | ||
946 | * struct iwl_set_calib_default_cmd - set default value for calibration. | 966 | * struct iwl_set_calib_default_cmd - set default value for calibration. |
947 | * ( SET_CALIB_DEFAULT_CMD = 0x8e ) | 967 | * ( SET_CALIB_DEFAULT_CMD = 0x8e ) |
948 | * @calib_index: the calibration to set value for | 968 | * @calib_index: the calibration to set value for |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index dc5f4ef50198..b4e8e597d2b7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -1050,3 +1050,28 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, | |||
1050 | rate); | 1050 | rate); |
1051 | return 0; | 1051 | return 0; |
1052 | } | 1052 | } |
1053 | |||
1054 | static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, | ||
1055 | struct ieee80211_vif *vif) | ||
1056 | { | ||
1057 | u16 *id = _data; | ||
1058 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
1059 | |||
1060 | if (mvmvif->id == *id) | ||
1061 | ieee80211_beacon_loss(vif); | ||
1062 | } | ||
1063 | |||
1064 | int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, | ||
1065 | struct iwl_rx_cmd_buffer *rxb, | ||
1066 | struct iwl_device_cmd *cmd) | ||
1067 | { | ||
1068 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1069 | struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data; | ||
1070 | u16 id = (u16)le32_to_cpu(missed_beacons->mac_id); | ||
1071 | |||
1072 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
1073 | IEEE80211_IFACE_ITER_NORMAL, | ||
1074 | iwl_mvm_beacon_loss_iterator, | ||
1075 | &id); | ||
1076 | return 0; | ||
1077 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c26f6b504460..dc50020d746d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -152,7 +152,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
152 | IEEE80211_HW_SUPPORTS_PS | | 152 | IEEE80211_HW_SUPPORTS_PS | |
153 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | | 153 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | |
154 | IEEE80211_HW_AMPDU_AGGREGATION | | 154 | IEEE80211_HW_AMPDU_AGGREGATION | |
155 | IEEE80211_HW_TIMING_BEACON_ONLY; | 155 | IEEE80211_HW_TIMING_BEACON_ONLY | |
156 | IEEE80211_HW_CONNECTION_MONITOR; | ||
156 | 157 | ||
157 | hw->queues = IWL_MVM_FIRST_AGG_QUEUE; | 158 | hw->queues = IWL_MVM_FIRST_AGG_QUEUE; |
158 | hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; | 159 | hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index a288552491b3..0e7450372f2c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -552,6 +552,9 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, | |||
552 | int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, | 552 | int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, |
553 | struct iwl_rx_cmd_buffer *rxb, | 553 | struct iwl_rx_cmd_buffer *rxb, |
554 | struct iwl_device_cmd *cmd); | 554 | struct iwl_device_cmd *cmd); |
555 | int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, | ||
556 | struct iwl_rx_cmd_buffer *rxb, | ||
557 | struct iwl_device_cmd *cmd); | ||
555 | 558 | ||
556 | /* Bindings */ | 559 | /* Bindings */ |
557 | int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 560 | int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 8431637e38f2..d7a199b1cdef 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -227,6 +227,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { | |||
227 | RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), | 227 | RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), |
228 | RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), | 228 | RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), |
229 | 229 | ||
230 | RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif, | ||
231 | false), | ||
232 | |||
230 | RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), | 233 | RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), |
231 | }; | 234 | }; |
232 | #undef RX_HANDLER | 235 | #undef RX_HANDLER |
@@ -289,6 +292,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { | |||
289 | CMD(NET_DETECT_HOTSPOTS_CMD), | 292 | CMD(NET_DETECT_HOTSPOTS_CMD), |
290 | CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), | 293 | CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), |
291 | CMD(CARD_STATE_NOTIFICATION), | 294 | CMD(CARD_STATE_NOTIFICATION), |
295 | CMD(MISSED_BEACONS_NOTIFICATION), | ||
292 | CMD(BT_COEX_PRIO_TABLE), | 296 | CMD(BT_COEX_PRIO_TABLE), |
293 | CMD(BT_COEX_PROT_ENV), | 297 | CMD(BT_COEX_PROT_ENV), |
294 | CMD(BT_PROFILE_NOTIFICATION), | 298 | CMD(BT_PROFILE_NOTIFICATION), |