/** * @brief This function prepares domain info from scan table and * downloads the domain info command to the FW. * * @param pmpriv A pointer to mlan_private structure * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status wlan_11d_prepare_dnld_domain_info_cmd(mlan_private * pmpriv) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_adapter *pmadapter = pmpriv->adapter; IEEEtypes_CountryInfoFullSet_t *pcountry_full = MNULL; t_u32 idx; ENTER(); /* Only valid if 11D is enabled */ if (wlan_11d_get_state(pmpriv) == ENABLE_11D && pmadapter->num_in_scan_table != 0) { for (idx = 0; idx < pmadapter->num_in_scan_table; idx++) { pcountry_full = &pmadapter->pscan_table[idx].country_info; if (*(pcountry_full->country_code) == 0 || (pcountry_full->len <= COUNTRY_CODE_LEN)) { /* Country info not found in the BSS descriptor */ ret = wlan_11d_update_chan_pwr_table(pmpriv, &pmadapter-> pscan_table[idx]); } else { /* Country info found in the BSS Descriptor */ ret = wlan_11d_process_country_info(pmpriv, &pmadapter->pscan_table[idx]); /* * If valid country IE found, in BSS, channel table is updated * Send FW command */ if (ret == MLAN_STATUS_SUCCESS) break; } } /* Check if connected */ if (pmpriv->media_connected == MTRUE) { ret = wlan_11d_parse_dnld_countryinfo(pmpriv, &pmpriv->curr_bss_params. bss_descriptor); } else { ret = wlan_11d_parse_dnld_countryinfo(pmpriv, MNULL); } } LEAVE(); return ret; }
/** * @brief Process an TLV buffer for a pending BSS Adhoc start command. * * Activate 11h functionality in the firmware if driver has is enabled * for 11h (configured by the application via IOCTL). * * @param priv Private driver information structure * @param ppbuffer Output parameter: Pointer to the TLV output buffer, * modified on return to point after the appended 11h TLVs * @param pcap_info Pointer to the capability info for the BSS to join * @param channel Channel on which we are starting the IBSS * @param p11h_bss_info Input/Output parameter: Pointer to the 11h BSS * information for this network that we are establishing. * 11h sensed flag set on output if warranted. * * @return Integer number of bytes appended to the TLV output * buffer (ppbuffer) * */ int wlan_11h_process_start(mlan_private * priv, t_u8 ** ppbuffer, IEEEtypes_CapInfo_t * pcap_info, t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info) { mlan_adapter *adapter = priv->adapter; int ret = 0; ENTER(); if (wlan_11h_is_enabled(priv) && ((adapter->adhoc_start_band & BAND_A) || (adapter->adhoc_start_band & BAND_AN) ) ) { if (wlan_11d_get_state(priv) == DISABLE_11D) { /* No use having 11h enabled without 11d enabled */ wlan_11d_enable(priv, MNULL, ENABLE_11D); wlan_11d_create_dnld_countryinfo(priv, adapter->adhoc_start_band); } /* Activate 11h functions in firmware, turns on capability bit */ wlan_11h_activate(priv, MTRUE); pcap_info->spectrum_mgmt = 1; /* Set flag indicating this BSS we are starting is using 11h */ p11h_bss_info->sensed_11h = MTRUE; ret = wlan_11h_process_adhoc(priv, ppbuffer, channel, MNULL); } else { /* Deactivate 11h functions in the firmware */ wlan_11h_activate(priv, MFALSE); pcap_info->spectrum_mgmt = 0; } LEAVE(); return ret; }
/** * @brief This function parses country info from AP and * download country info to FW * * @param pmpriv A pointer to mlan_private structure * @param pbss_desc A pointer to BSS descriptor * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status wlan_11d_parse_dnld_countryinfo(mlan_private * pmpriv, BSSDescriptor_t * pbss_desc) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_adapter *pmadapter = pmpriv->adapter; parsed_region_chan_11d_t region_chan; parsed_region_chan_11d_t bssdesc_region_chan; t_u32 i, j; ENTER(); /* Only valid if 11D is enabled */ if (wlan_11d_get_state(pmpriv) == ENABLE_11D) { memset(pmadapter, &pmadapter->domain_reg, 0, sizeof(wlan_802_11d_domain_reg_t)); memset(pmadapter, ®ion_chan, 0, sizeof(parsed_region_chan_11d_t)); memset(pmadapter, &bssdesc_region_chan, 0, sizeof(parsed_region_chan_11d_t)); memcpy(pmadapter, ®ion_chan, &pmadapter->parsed_region_chan, sizeof(parsed_region_chan_11d_t)); if (pbss_desc) { /* Parse domain info if available */ ret = wlan_11d_parse_domain_info(pmadapter, &pbss_desc->country_info, pbss_desc->bss_band, &bssdesc_region_chan); if (ret == MLAN_STATUS_SUCCESS) { /* Update the channel-power table */ for (i = 0; ((i < bssdesc_region_chan.no_of_chan) && (i < MAX_NO_OF_CHAN)); i++) { for (j = 0; ((j < region_chan.no_of_chan) && (j < MAX_NO_OF_CHAN)); j++) { /* * Channel already exists, so overwrite existing * tx power with the tx_power received from * country info of the current AP */ if (region_chan.chan_pwr[i].chan == bssdesc_region_chan.chan_pwr[j].chan) { region_chan.chan_pwr[j].pwr = bssdesc_region_chan.chan_pwr[i].pwr; break; } } } } } /* Generate domain info */ wlan_11d_generate_domain_info(pmadapter, ®ion_chan, &pmadapter->domain_reg); /* Set domain info */ ret = wlan_11d_set_domain_info(pmpriv); if (ret) { PRINTM(MERROR, "11D: Error setting domain info in FW\n"); } } LEAVE(); return ret; }
/** * @brief This function handles disconnect event, reports disconnect * to upper layer, cleans tx/rx packets, * resets link state etc. * * @param priv A pointer to mlan_private structure * * @return N/A */ t_void wlan_reset_connect_state(pmlan_private priv) { mlan_adapter *pmadapter = priv->adapter; mlan_status ret = MLAN_STATUS_SUCCESS; state_11d_t enable; ENTER(); if (priv->media_connected != MTRUE) { LEAVE(); return; } PRINTM(MINFO, "Handles disconnect event.\n"); priv->media_connected = MFALSE; if (priv->port_ctrl_mode == MTRUE) { /* Close the port on Disconnect */ PRINTM(MINFO, "DISC: port_status = CLOSED\n"); priv->port_open = MFALSE; } priv->scan_block = MFALSE; /* Free Tx and Rx packets, report disconnect to upper layer */ wlan_clean_txrx(priv); /* Reset SNR/NF/RSSI values */ priv->data_rssi_last = 0; priv->data_nf_last = 0; priv->data_rssi_avg = 0; priv->data_nf_avg = 0; priv->bcn_rssi_last = 0; priv->bcn_nf_last = 0; priv->bcn_rssi_avg = 0; priv->bcn_nf_avg = 0; priv->rxpd_rate = 0; priv->rxpd_htinfo = 0; priv->sec_info.ewpa_enabled = MFALSE; priv->sec_info.wpa_enabled = MFALSE; priv->sec_info.wpa2_enabled = MFALSE; priv->wpa_ie_len = 0; priv->sec_info.wapi_enabled = MFALSE; priv->wapi_ie_len = 0; priv->sec_info.wapi_key_on = MFALSE; priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE; /* Enable auto data rate */ priv->is_data_rate_auto = MTRUE; priv->data_rate = 0; if (priv->bss_mode == MLAN_BSS_MODE_IBSS) { priv->adhoc_state = ADHOC_IDLE; priv->adhoc_is_link_sensed = MFALSE; priv->adhoc_auto_sel = MTRUE; } /* * Memorize the previous SSID and BSSID so * it could be used for re-assoc */ PRINTM(MINFO, "Previous SSID=%s, SSID Length=%u\n", priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); PRINTM(MINFO, "Current SSID=%s, SSID Length=%u\n", priv->curr_bss_params.bss_descriptor.ssid.ssid, priv->curr_bss_params.bss_descriptor.ssid.ssid_len); memcpy(pmadapter, &priv->prev_ssid, &priv->curr_bss_params.bss_descriptor.ssid, sizeof(mlan_802_11_ssid)); memcpy(pmadapter, priv->prev_bssid, priv->curr_bss_params.bss_descriptor.mac_address, MLAN_MAC_ADDR_LENGTH); /* Need to erase the current SSID and BSSID info */ memset(pmadapter, &priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params)); pmadapter->tx_lock_flag = MFALSE; pmadapter->pps_uapsd_mode = MFALSE; if ((wlan_11d_get_state(priv) == ENABLE_11D) && (pmadapter->state_11d.user_enable_11d == DISABLE_11D)) { pmadapter->state_11d.enable_11d = DISABLE_11D; enable = DISABLE_11D; /* Send cmd to FW to enable/disable 11D function */ ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, HostCmd_ACT_GEN_SET, Dot11D_i, MNULL, &enable); if (ret) PRINTM(MERROR, "11D: Failed to enable 11D\n"); } if (pmadapter->num_cmd_timeout && pmadapter->curr_cmd && (pmadapter->cmd_timer_is_set == MFALSE)) { LEAVE(); return; } wlan_recv_event(priv, MLAN_EVENT_ID_FW_DISCONNECTED, MNULL); LEAVE(); }