summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c121
1 files changed, 75 insertions, 46 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 98f62d78cf9c..286ae1757fc3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -169,15 +169,21 @@ enum iwl_rx_handler_context {
* @fn: the function is called when notification is received
*/
struct iwl_rx_handlers {
- u16 cmd_id;
+ u16 cmd_id, min_size;
enum iwl_rx_handler_context context;
void (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
};
-#define RX_HANDLER(_cmd_id, _fn, _context) \
- { .cmd_id = _cmd_id, .fn = _fn, .context = _context }
-#define RX_HANDLER_GRP(_grp, _cmd, _fn, _context) \
- { .cmd_id = WIDE_ID(_grp, _cmd), .fn = _fn, .context = _context }
+#define RX_HANDLER_NO_SIZE(_cmd_id, _fn, _context) \
+ { .cmd_id = _cmd_id, .fn = _fn, .context = _context, }
+#define RX_HANDLER_GRP_NO_SIZE(_grp, _cmd, _fn, _context) \
+ { .cmd_id = WIDE_ID(_grp, _cmd), .fn = _fn, .context = _context, }
+#define RX_HANDLER(_cmd_id, _fn, _context, _struct) \
+ { .cmd_id = _cmd_id, .fn = _fn, \
+ .context = _context, .min_size = sizeof(_struct), }
+#define RX_HANDLER_GRP(_grp, _cmd, _fn, _context, _struct) \
+ { .cmd_id = WIDE_ID(_grp, _cmd), .fn = _fn, \
+ .context = _context, .min_size = sizeof(_struct), }
/*
* Handlers for fw notifications
@@ -187,85 +193,104 @@ struct iwl_rx_handlers {
* The handler can be one from three contexts, see &iwl_rx_handler_context
*/
static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
- RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, RX_HANDLER_SYNC),
- RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, RX_HANDLER_SYNC),
+ RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, RX_HANDLER_SYNC,
+ struct iwl_mvm_tx_resp),
+ RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, RX_HANDLER_SYNC,
+ struct iwl_mvm_ba_notif),
RX_HANDLER_GRP(DATA_PATH_GROUP, TLC_MNG_UPDATE_NOTIF,
- iwl_mvm_tlc_update_notif, RX_HANDLER_SYNC),
+ iwl_mvm_tlc_update_notif, RX_HANDLER_SYNC,
+ struct iwl_tlc_update_notif),
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif,
- RX_HANDLER_ASYNC_LOCKED),
- RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif,
- RX_HANDLER_ASYNC_LOCKED),
- RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics,
- RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_ASYNC_LOCKED, struct iwl_bt_coex_profile_notif),
+ RX_HANDLER_NO_SIZE(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif,
+ RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_NO_SIZE(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics,
+ RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER(BA_WINDOW_STATUS_NOTIFICATION_ID,
- iwl_mvm_window_status_notif, RX_HANDLER_SYNC),
+ iwl_mvm_window_status_notif, RX_HANDLER_SYNC,
+ struct iwl_ba_window_status_notif),
RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif,
- RX_HANDLER_SYNC),
+ RX_HANDLER_SYNC, struct iwl_time_event_notif),
RX_HANDLER_GRP(MAC_CONF_GROUP, SESSION_PROTECTION_NOTIF,
- iwl_mvm_rx_session_protect_notif, RX_HANDLER_SYNC),
+ iwl_mvm_rx_session_protect_notif, RX_HANDLER_SYNC,
+ struct iwl_mvm_session_prot_notif),
RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc,
- RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_ASYNC_LOCKED, struct iwl_mcc_chub_notif),
- RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, RX_HANDLER_SYNC),
+ RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, RX_HANDLER_SYNC,
+ struct iwl_mvm_eosp_notification),
RX_HANDLER(SCAN_ITERATION_COMPLETE,
- iwl_mvm_rx_lmac_scan_iter_complete_notif, RX_HANDLER_SYNC),
+ iwl_mvm_rx_lmac_scan_iter_complete_notif, RX_HANDLER_SYNC,
+ struct iwl_lmac_scan_complete_notif),
RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
iwl_mvm_rx_lmac_scan_complete_notif,
- RX_HANDLER_ASYNC_LOCKED),
- RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_match_found,
- RX_HANDLER_SYNC),
+ RX_HANDLER_ASYNC_LOCKED, struct iwl_periodic_scan_complete),
+ RX_HANDLER_NO_SIZE(MATCH_FOUND_NOTIFICATION,
+ iwl_mvm_rx_scan_match_found,
+ RX_HANDLER_SYNC),
RX_HANDLER(SCAN_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_complete_notif,
- RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_ASYNC_LOCKED, struct iwl_umac_scan_complete),
RX_HANDLER(SCAN_ITERATION_COMPLETE_UMAC,
- iwl_mvm_rx_umac_scan_iter_complete_notif, RX_HANDLER_SYNC),
+ iwl_mvm_rx_umac_scan_iter_complete_notif, RX_HANDLER_SYNC,
+ struct iwl_umac_scan_iter_complete_notif),
RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif,
- RX_HANDLER_SYNC),
+ RX_HANDLER_SYNC, struct iwl_card_state_notif),
RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif,
- RX_HANDLER_SYNC),
+ RX_HANDLER_SYNC, struct iwl_missed_beacons_notif),
- RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, RX_HANDLER_SYNC),
+ RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, RX_HANDLER_SYNC,
+ struct iwl_error_resp),
RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION,
- iwl_mvm_power_uapsd_misbehaving_ap_notif, RX_HANDLER_SYNC),
- RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif,
- RX_HANDLER_ASYNC_LOCKED),
- RX_HANDLER_GRP(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE,
- iwl_mvm_temp_notif, RX_HANDLER_ASYNC_UNLOCKED),
+ iwl_mvm_power_uapsd_misbehaving_ap_notif, RX_HANDLER_SYNC,
+ struct iwl_uapsd_misbehaving_ap_notif),
+ RX_HANDLER_NO_SIZE(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif,
+ RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_GRP_NO_SIZE(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE,
+ iwl_mvm_temp_notif, RX_HANDLER_ASYNC_UNLOCKED),
RX_HANDLER_GRP(PHY_OPS_GROUP, CT_KILL_NOTIFICATION,
- iwl_mvm_ct_kill_notif, RX_HANDLER_SYNC),
+ iwl_mvm_ct_kill_notif, RX_HANDLER_SYNC,
+ struct ct_kill_notif),
RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif,
- RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_ASYNC_LOCKED,
+ struct iwl_tdls_channel_switch_notif),
RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif,
- RX_HANDLER_SYNC),
+ RX_HANDLER_SYNC, struct iwl_mfuart_load_notif_v1),
RX_HANDLER_GRP(LOCATION_GROUP, TOF_RESPONDER_STATS,
- iwl_mvm_ftm_responder_stats, RX_HANDLER_ASYNC_LOCKED),
+ iwl_mvm_ftm_responder_stats, RX_HANDLER_ASYNC_LOCKED,
+ struct iwl_ftm_responder_stats),
- RX_HANDLER_GRP(LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF,
- iwl_mvm_ftm_range_resp, RX_HANDLER_ASYNC_LOCKED),
- RX_HANDLER_GRP(LOCATION_GROUP, TOF_LC_NOTIF,
- iwl_mvm_ftm_lc_notif, RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_GRP_NO_SIZE(LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF,
+ iwl_mvm_ftm_range_resp, RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_GRP_NO_SIZE(LOCATION_GROUP, TOF_LC_NOTIF,
+ iwl_mvm_ftm_lc_notif, RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER_GRP(DEBUG_GROUP, MFU_ASSERT_DUMP_NTF,
- iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC),
+ iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC,
+ struct iwl_mfu_assert_dump_notif),
RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF,
- iwl_mvm_rx_stored_beacon_notif, RX_HANDLER_SYNC),
+ iwl_mvm_rx_stored_beacon_notif, RX_HANDLER_SYNC,
+ struct iwl_stored_beacon_notif),
RX_HANDLER_GRP(DATA_PATH_GROUP, MU_GROUP_MGMT_NOTIF,
- iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC),
+ iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC,
+ struct iwl_mu_group_mgmt_notif),
RX_HANDLER_GRP(DATA_PATH_GROUP, STA_PM_NOTIF,
- iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC),
+ iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC,
+ struct iwl_mvm_pm_state_notification),
RX_HANDLER_GRP(MAC_CONF_GROUP, PROBE_RESPONSE_DATA_NOTIF,
iwl_mvm_probe_resp_data_notif,
- RX_HANDLER_ASYNC_LOCKED),
+ RX_HANDLER_ASYNC_LOCKED,
+ struct iwl_probe_resp_data_notif),
RX_HANDLER_GRP(MAC_CONF_GROUP, CHANNEL_SWITCH_NOA_NOTIF,
iwl_mvm_channel_switch_noa_notif,
- RX_HANDLER_SYNC),
+ RX_HANDLER_SYNC, struct iwl_channel_switch_noa_notif),
};
#undef RX_HANDLER
#undef RX_HANDLER_GRP
@@ -960,6 +985,7 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_rx_packet *pkt)
{
+ unsigned int pkt_len = iwl_rx_packet_payload_len(pkt);
int i;
union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt };
@@ -981,6 +1007,9 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm,
if (rx_h->cmd_id != WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd))
continue;
+ if (unlikely(pkt_len < rx_h->min_size))
+ return;
+
if (rx_h->context == RX_HANDLER_SYNC) {
rx_h->fn(mvm, rxb);
return;