diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/sta_cmdresp.c')
| -rw-r--r-- | drivers/net/wireless/mwifiex/sta_cmdresp.c | 475 |
1 files changed, 321 insertions, 154 deletions
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index a79ed9bd969..577f2979ed8 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -24,6 +24,7 @@ #include "main.h" #include "wmm.h" #include "11n.h" +#include "11ac.h" /* @@ -68,6 +69,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, break; case HostCmd_CMD_802_11_SCAN: + case HostCmd_CMD_802_11_SCAN_EXT: /* Cancel all pending scan command */ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); list_for_each_entry_safe(cmd_node, tmp_node, @@ -85,10 +87,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); if (priv->report_scan_result) priv->report_scan_result = false; - if (priv->scan_pending_on_block) { - priv->scan_pending_on_block = false; - up(&priv->async_sem); - } break; case HostCmd_CMD_MAC_CONTROL: @@ -98,7 +96,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, break; } /* Handling errors here */ - mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = NULL; @@ -123,7 +121,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, { struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = &resp->params.rssi_info_rsp; - struct mwifiex_ds_misc_subsc_evt subsc_evt; + struct mwifiex_ds_misc_subsc_evt *subsc_evt = + &priv->async_subsc_evt_storage; priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); @@ -140,26 +139,27 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, if (priv->subsc_evt_rssi_state == EVENT_HANDLED) return 0; + memset(subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt)); + /* Resubscribe low and high rssi events with new thresholds */ - memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt)); - subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH; - subsc_evt.action = HostCmd_ACT_BITWISE_SET; + subsc_evt->events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH; + subsc_evt->action = HostCmd_ACT_BITWISE_SET; if (priv->subsc_evt_rssi_state == RSSI_LOW_RECVD) { - subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg - + subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg - priv->cqm_rssi_hyst); - subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); + subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); } else if (priv->subsc_evt_rssi_state == RSSI_HIGH_RECVD) { - subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); - subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg + + subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); + subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg + priv->cqm_rssi_hyst); } - subsc_evt.bcn_l_rssi_cfg.evt_freq = 1; - subsc_evt.bcn_h_rssi_cfg.evt_freq = 1; + subsc_evt->bcn_l_rssi_cfg.evt_freq = 1; + subsc_evt->bcn_h_rssi_cfg.evt_freq = 1; priv->subsc_evt_rssi_state = EVENT_HANDLED; - mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT, - 0, 0, &subsc_evt); + mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT, + 0, 0, subsc_evt, false); return 0; } @@ -227,7 +227,7 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, struct mwifiex_ds_get_stats *stats) { struct host_cmd_ds_802_11_get_log *get_log = - (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; + &resp->params.get_log; if (stats) { stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); @@ -267,28 +267,28 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, * * Based on the new rate bitmaps, the function re-evaluates if * auto data rate has been activated. If not, it sends another - * query to the firmware to get the current Tx data rate and updates - * the driver value. + * query to the firmware to get the current Tx data rate. */ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - struct mwifiex_rate_cfg *ds_rate) + struct host_cmd_ds_command *resp) { struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; struct mwifiex_ie_types_header *head; - u16 tlv, tlv_buf_len; + u16 tlv, tlv_buf_len, tlv_buf_left; u8 *tlv_buf; u32 i; - int ret = 0; - tlv_buf = (u8 *) ((u8 *) rate_cfg) + - sizeof(struct host_cmd_ds_tx_rate_cfg); - tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16)); + tlv_buf = ((u8 *)rate_cfg) + sizeof(struct host_cmd_ds_tx_rate_cfg); + tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*rate_cfg); - while (tlv_buf && tlv_buf_len > 0) { - tlv = (*tlv_buf); - tlv = tlv | (*(tlv_buf + 1) << 8); + while (tlv_buf_left >= sizeof(*head)) { + head = (struct mwifiex_ie_types_header *)tlv_buf; + tlv = le16_to_cpu(head->type); + tlv_buf_len = le16_to_cpu(head->len); + + if (tlv_buf_left < (sizeof(*head) + tlv_buf_len)) + break; switch (tlv) { case TLV_TYPE_RATE_SCOPE: @@ -304,13 +304,21 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, priv->bitmap_rates[2 + i] = le16_to_cpu(rate_scope-> ht_mcs_rate_bitmap[i]); + + if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) { + for (i = 0; i < ARRAY_SIZE(rate_scope-> + vht_mcs_rate_bitmap); + i++) + priv->bitmap_rates[10 + i] = + le16_to_cpu(rate_scope-> + vht_mcs_rate_bitmap[i]); + } break; /* Add RATE_DROP tlv here */ } - head = (struct mwifiex_ie_types_header *) tlv_buf; - tlv_buf += le16_to_cpu(head->len) + sizeof(*head); - tlv_buf_len -= le16_to_cpu(head->len); + tlv_buf += (sizeof(*head) + tlv_buf_len); + tlv_buf_left -= (sizeof(*head) + tlv_buf_len); } priv->is_data_rate_auto = mwifiex_is_rate_auto(priv); @@ -318,33 +326,10 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, if (priv->is_data_rate_auto) priv->data_rate = 0; else - ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_802_11_TX_RATE_QUERY, - HostCmd_ACT_GEN_GET, 0, NULL); - - if (!ds_rate) - return ret; - - if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { - if (priv->is_data_rate_auto) { - ds_rate->is_rate_auto = 1; - return ret; - } - ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates, - sizeof(priv->bitmap_rates)); - - if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 && - ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7) - ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 - - MWIFIEX_RATE_INDEX_OFDM0); - - if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 && - ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127) - ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 - - MWIFIEX_RATE_INDEX_MCS0); - } + return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, + HostCmd_ACT_GEN_GET, 0, NULL, false); - return ret; + return 0; } /* @@ -362,17 +347,20 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) if (!data_buf) return -1; - pg_tlv_hdr = (struct mwifiex_types_power_group *) - ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg)); + pg_tlv_hdr = (struct mwifiex_types_power_group *)((u8 *)data_buf); pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); - length = pg_tlv_hdr->length; - if (length > 0) { - max_power = pg->power_max; - min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - } - while (length) { + length = le16_to_cpu(pg_tlv_hdr->length); + + /* At least one structure required to update power */ + if (length < sizeof(struct mwifiex_power_group)) + return 0; + + max_power = pg->power_max; + min_power = pg->power_min; + length -= sizeof(struct mwifiex_power_group); + + while (length >= sizeof(struct mwifiex_power_group)) { pg++; if (max_power < pg->power_max) max_power = pg->power_max; @@ -382,10 +370,8 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) length -= sizeof(struct mwifiex_power_group); } - if (pg_tlv_hdr->length > 0) { - priv->min_tx_power_level = (u8) min_power; - priv->max_tx_power_level = (u8) max_power; - } + priv->min_tx_power_level = (u8) min_power; + priv->max_tx_power_level = (u8) max_power; return 0; } @@ -405,19 +391,25 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, struct mwifiex_types_power_group *pg_tlv_hdr; struct mwifiex_power_group *pg; u16 action = le16_to_cpu(txp_cfg->action); + u16 tlv_buf_left; - switch (action) { - case HostCmd_ACT_GEN_GET: - pg_tlv_hdr = (struct mwifiex_types_power_group *) - ((u8 *) txp_cfg + - sizeof(struct host_cmd_ds_txpwr_cfg)); + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *)txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + + pg = (struct mwifiex_power_group *) + ((u8 *)pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); - pg = (struct mwifiex_power_group *) - ((u8 *) pg_tlv_hdr + - sizeof(struct mwifiex_types_power_group)); + tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg); + if (tlv_buf_left < + le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr)) + return 0; + switch (action) { + case HostCmd_ACT_GEN_GET: if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) - mwifiex_get_power_level(priv, txp_cfg); + mwifiex_get_power_level(priv, pg_tlv_hdr); priv->tx_power_level = (u16) pg->power_min; break; @@ -426,14 +418,6 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, if (!le32_to_cpu(txp_cfg->mode)) break; - pg_tlv_hdr = (struct mwifiex_types_power_group *) - ((u8 *) txp_cfg + - sizeof(struct host_cmd_ds_txpwr_cfg)); - - pg = (struct mwifiex_power_group *) - ((u8 *) pg_tlv_hdr + - sizeof(struct mwifiex_types_power_group)); - if (pg->power_max == pg->power_min) priv->tx_power_level = (u16) pg->power_min; break; @@ -451,6 +435,57 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, } /* + * This function handles the command response of get RF Tx power. + */ +static int mwifiex_ret_rf_tx_power(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_rf_tx_pwr *txp = &resp->params.txp; + u16 action = le16_to_cpu(txp->action); + + priv->tx_power_level = le16_to_cpu(txp->cur_level); + + if (action == HostCmd_ACT_GEN_GET) { + priv->max_tx_power_level = txp->max_power; + priv->min_tx_power_level = txp->min_power; + } + + dev_dbg(priv->adapter->dev, + "Current TxPower Level=%d, Max Power=%d, Min Power=%d\n", + priv->tx_power_level, priv->max_tx_power_level, + priv->min_tx_power_level); + + return 0; +} + +/* + * This function handles the command response of set rf antenna + */ +static int mwifiex_ret_rf_antenna(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_rf_ant_mimo *ant_mimo = &resp->params.ant_mimo; + struct host_cmd_ds_rf_ant_siso *ant_siso = &resp->params.ant_siso; + struct mwifiex_adapter *adapter = priv->adapter; + + if (adapter->hw_dev_mcs_support == HT_STREAM_2X2) + dev_dbg(adapter->dev, + "RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x" + " Rx action = 0x%x, Rx Mode = 0x%04x\n", + le16_to_cpu(ant_mimo->action_tx), + le16_to_cpu(ant_mimo->tx_ant_mode), + le16_to_cpu(ant_mimo->action_rx), + le16_to_cpu(ant_mimo->rx_ant_mode)); + else + dev_dbg(adapter->dev, + "RF_ANT_RESP: action = 0x%x, Mode = 0x%04x\n", + le16_to_cpu(ant_siso->action), + le16_to_cpu(ant_siso->ant_mode)); + + return 0; +} + +/* * This function handles the command response of set/get MAC address. * * Handling includes saving the MAC address in driver. @@ -517,7 +552,7 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv, if (!memcmp(resp->params.deauth.mac_addr, &priv->curr_bss_params.bss_descriptor.mac_address, sizeof(resp->params.deauth.mac_addr))) - mwifiex_reset_connect_state(priv); + mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING); return 0; } @@ -530,18 +565,18 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv, static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { - mwifiex_reset_connect_state(priv); + mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING); return 0; } /* - * This function handles the command response of set/get key material. + * This function handles the command response of set/get v1 key material. * * Handling includes updating the driver parameters to reflect the * changes. */ -static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp) +static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_key_material *key = &resp->params.key_material; @@ -564,6 +599,51 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, } /* + * This function handles the command response of set/get v2 key material. + * + * Handling includes updating the driver parameters to reflect the + * changes. + */ +static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_802_11_key_material_v2 *key_v2; + __le16 len; + + key_v2 = &resp->params.key_material_v2; + if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) { + if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) { + dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); + priv->wpa_is_gtk_set = true; + priv->scan_block = false; + } + } + + if (key_v2->key_param_set.key_type != KEY_TYPE_ID_AES) + return 0; + + memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0, + WLAN_KEY_LEN_CCMP); + priv->aes_key_v2.key_param_set.key_params.aes.key_len = + key_v2->key_param_set.key_params.aes.key_len; + len = priv->aes_key_v2.key_param_set.key_params.aes.key_len; + memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key, + key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len)); + + return 0; +} + +/* Wrapper function for processing response of key material command */ +static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) + return mwifiex_ret_802_11_key_material_v2(priv, resp); + else + return mwifiex_ret_802_11_key_material_v1(priv, resp); +} + +/* * This function handles the command response of get 11d domain information. */ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, @@ -605,34 +685,6 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, } /* - * This function handles the command response of get RF channel. - * - * Handling includes changing the header fields into CPU format - * and saving the new channel in driver. - */ -static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - u16 *data_buf) -{ - struct host_cmd_ds_802_11_rf_channel *rf_channel = - &resp->params.rf_channel; - u16 new_channel = le16_to_cpu(rf_channel->current_channel); - - if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { - dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", - priv->curr_bss_params.bss_descriptor.channel, - new_channel); - /* Update the channel again */ - priv->curr_bss_params.bss_descriptor.channel = new_channel; - } - - if (data_buf) - *data_buf = new_channel; - - return 0; -} - -/* * This function handles the command response of get extended version. * * Handling includes forming the extended version string and sending it @@ -654,6 +706,38 @@ static int mwifiex_ret_ver_ext(struct mwifiex_private *priv, } /* + * This function handles the command response of remain on channel. + */ +static int +mwifiex_ret_remain_on_chan(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + struct host_cmd_ds_remain_on_chan *roc_cfg) +{ + struct host_cmd_ds_remain_on_chan *resp_cfg = &resp->params.roc_cfg; + + if (roc_cfg) + memcpy(roc_cfg, resp_cfg, sizeof(*roc_cfg)); + + return 0; +} + +/* + * This function handles the command response of P2P mode cfg. + */ +static int +mwifiex_ret_p2p_mode_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct host_cmd_ds_p2p_mode_cfg *mode_cfg = &resp->params.mode_cfg; + + if (data_buf) + *((u16 *)data_buf) = le16_to_cpu(mode_cfg->mode); + + return 0; +} + +/* * This function handles the command response of register access. * * The register value and offset are returned to the user. For EEPROM @@ -679,39 +763,33 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, eeprom = data_buf; switch (type) { case HostCmd_CMD_MAC_REG_ACCESS: - r.mac = (struct host_cmd_ds_mac_reg_access *) - &resp->params.mac_reg; + r.mac = &resp->params.mac_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); reg_rw->value = r.mac->value; break; case HostCmd_CMD_BBP_REG_ACCESS: - r.bbp = (struct host_cmd_ds_bbp_reg_access *) - &resp->params.bbp_reg; + r.bbp = &resp->params.bbp_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); reg_rw->value = cpu_to_le32((u32) r.bbp->value); break; case HostCmd_CMD_RF_REG_ACCESS: - r.rf = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; + r.rf = &resp->params.rf_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); reg_rw->value = cpu_to_le32((u32) r.bbp->value); break; case HostCmd_CMD_PMIC_REG_ACCESS: - r.pmic = (struct host_cmd_ds_pmic_reg_access *) - &resp->params.pmic_reg; + r.pmic = &resp->params.pmic_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); reg_rw->value = cpu_to_le32((u32) r.pmic->value); break; case HostCmd_CMD_CAU_REG_ACCESS: - r.rf = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; + r.rf = &resp->params.rf_reg; reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); reg_rw->value = cpu_to_le32((u32) r.rf->value); break; case HostCmd_CMD_802_11_EEPROM_ACCESS: - r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *) - &resp->params.eeprom; + r.eeprom = &resp->params.eeprom; pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); if (le16_to_cpu(eeprom->byte_count) < le16_to_cpu(r.eeprom->byte_count)) { @@ -744,7 +822,6 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, { struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp = &(resp->params.ibss_coalescing); - u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET) return 0; @@ -753,14 +830,13 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, "info: new BSSID %pM\n", ibss_coal_resp->bssid); /* If rsp has NULL BSSID, Just return..... No Action */ - if (!memcmp(ibss_coal_resp->bssid, zero_mac, ETH_ALEN)) { + if (is_zero_ether_addr(ibss_coal_resp->bssid)) { dev_warn(priv->adapter->dev, "new BSSID is NULL\n"); return 0; } /* If BSSID is diff, modify current BSS parameters */ - if (memcmp(priv->curr_bss_params.bss_descriptor.mac_address, - ibss_coal_resp->bssid, ETH_ALEN)) { + if (!ether_addr_equal(priv->curr_bss_params.bss_descriptor.mac_address, ibss_coal_resp->bssid)) { /* BSSID */ memcpy(priv->curr_bss_params.bss_descriptor.mac_address, ibss_coal_resp->bssid, ETH_ALEN); @@ -778,25 +854,91 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, return 0; } +static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_tdls_oper *cmd_tdls_oper = &resp->params.tdls_oper; + u16 reason = le16_to_cpu(cmd_tdls_oper->reason); + u16 action = le16_to_cpu(cmd_tdls_oper->tdls_action); + struct mwifiex_sta_node *node = + mwifiex_get_sta_entry(priv, cmd_tdls_oper->peer_mac); + + switch (action) { + case ACT_TDLS_DELETE: + if (reason) { + if (!node || reason == TDLS_ERR_LINK_NONEXISTENT) + dev_dbg(priv->adapter->dev, + "TDLS link delete for %pM failed: reason %d\n", + cmd_tdls_oper->peer_mac, reason); + else + dev_err(priv->adapter->dev, + "TDLS link delete for %pM failed: reason %d\n", + cmd_tdls_oper->peer_mac, reason); + } else { + dev_dbg(priv->adapter->dev, + "TDLS link delete for %pM successful\n", + cmd_tdls_oper->peer_mac); + } + break; + case ACT_TDLS_CREATE: + if (reason) { + dev_err(priv->adapter->dev, + "TDLS link creation for %pM failed: reason %d", + cmd_tdls_oper->peer_mac, reason); + if (node && reason != TDLS_ERR_LINK_EXISTS) + node->tdls_status = TDLS_SETUP_FAILURE; + } else { + dev_dbg(priv->adapter->dev, + "TDLS link creation for %pM successful", + cmd_tdls_oper->peer_mac); + } + break; + case ACT_TDLS_CONFIG: + if (reason) { + dev_err(priv->adapter->dev, + "TDLS link config for %pM failed, reason %d\n", + cmd_tdls_oper->peer_mac, reason); + if (node) + node->tdls_status = TDLS_SETUP_FAILURE; + } else { + dev_dbg(priv->adapter->dev, + "TDLS link config for %pM successful\n", + cmd_tdls_oper->peer_mac); + } + break; + default: + dev_err(priv->adapter->dev, + "Unknown TDLS command action respnse %d", action); + return -1; + } + return 0; +} /* * This function handles the command response for subscribe event command. */ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - struct mwifiex_ds_misc_subsc_evt *sub_event) + struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event = - (struct host_cmd_ds_802_11_subsc_evt *)&resp->params.subsc_evt; + &resp->params.subsc_evt; /* For every subscribe event command (Get/Set/Clear), FW reports the * current set of subscribed events*/ dev_dbg(priv->adapter->dev, "Bitmap of currently subscribed events: %16x\n", le16_to_cpu(cmd_sub_event->events)); - /*Return the subscribed event info for a Get request*/ - if (sub_event) - sub_event->events = le16_to_cpu(cmd_sub_event->events); + return 0; +} + +/* This function handles the command response of set_cfg_data */ +static int mwifiex_ret_cfg_data(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + if (resp->result != HostCmd_RESULT_OK) { + dev_err(priv->adapter->dev, "Cal data cmd resp failed\n"); + return -1; + } return 0; } @@ -824,6 +966,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_GET_HW_SPEC: ret = mwifiex_ret_get_hw_spec(priv, resp); break; + case HostCmd_CMD_CFG_DATA: + ret = mwifiex_ret_cfg_data(priv, resp); + break; case HostCmd_CMD_MAC_CONTROL: break; case HostCmd_CMD_802_11_MAC_ADDRESS: @@ -833,12 +978,16 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, ret = mwifiex_ret_mac_multicast_adr(priv, resp); break; case HostCmd_CMD_TX_RATE_CFG: - ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); + ret = mwifiex_ret_tx_rate_cfg(priv, resp); break; case HostCmd_CMD_802_11_SCAN: ret = mwifiex_ret_802_11_scan(priv, resp); adapter->curr_cmd->wait_q_enabled = false; break; + case HostCmd_CMD_802_11_SCAN_EXT: + ret = mwifiex_ret_802_11_scan_ext(priv); + adapter->curr_cmd->wait_q_enabled = false; + break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: ret = mwifiex_ret_802_11_scan(priv, resp); dev_dbg(adapter->dev, @@ -847,6 +996,12 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_TXPWR_CFG: ret = mwifiex_ret_tx_power_cfg(priv, resp); break; + case HostCmd_CMD_RF_TX_PWR: + ret = mwifiex_ret_rf_tx_power(priv, resp); + break; + case HostCmd_CMD_RF_ANTENNA: + ret = mwifiex_ret_rf_antenna(priv, resp); + break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); break; @@ -878,12 +1033,18 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_802_11_TX_RATE_QUERY: ret = mwifiex_ret_802_11_tx_rate_query(priv, resp); break; - case HostCmd_CMD_802_11_RF_CHANNEL: - ret = mwifiex_ret_802_11_rf_channel(priv, resp, data_buf); - break; case HostCmd_CMD_VERSION_EXT: ret = mwifiex_ret_ver_ext(priv, resp, data_buf); break; + case HostCmd_CMD_REMAIN_ON_CHAN: + ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf); + break; + case HostCmd_CMD_11AC_CFG: + break; + case HostCmd_CMD_P2P_MODE_CFG: + ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf); + break; + case HostCmd_CMD_MGMT_FRAME_REG: case HostCmd_CMD_FUNC_INIT: case HostCmd_CMD_FUNC_SHUTDOWN: break; @@ -909,16 +1070,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, / MWIFIEX_SDIO_BLOCK_SIZE) * MWIFIEX_SDIO_BLOCK_SIZE; adapter->curr_tx_buf_size = adapter->tx_buf_size; - dev_dbg(adapter->dev, - "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", - adapter->max_tx_buf_size, adapter->tx_buf_size); + dev_dbg(adapter->dev, "cmd: curr_tx_buf_size=%d\n", + adapter->curr_tx_buf_size); if (adapter->if_ops.update_mp_end_port) adapter->if_ops.update_mp_end_port(adapter, le16_to_cpu(resp->params.tx_buf.mp_end_port)); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: - ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: ret = mwifiex_ret_wmm_get_status(priv, resp); @@ -937,12 +1096,11 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_SET_BSS_MODE: break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_ret_11n_cfg(resp, data_buf); break; case HostCmd_CMD_PCIE_DESC_DETAILS: break; case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: - ret = mwifiex_ret_subsc_evt(priv, resp, data_buf); + ret = mwifiex_ret_subsc_evt(priv, resp); break; case HostCmd_CMD_UAP_SYS_CONFIG: break; @@ -952,6 +1110,15 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_UAP_BSS_STOP: priv->bss_started = 0; break; + case HostCmd_CMD_UAP_STA_DEAUTH: + break; + case HostCmd_CMD_MEF_CFG: + break; + case HostCmd_CMD_COALESCE_CFG: + break; + case HostCmd_CMD_TDLS_OPER: + ret = mwifiex_ret_tdls_oper(priv, resp); + break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", resp->command); |
