Beispiel #1
0
/** 
 *  @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;
}
Beispiel #2
0
/**
 *  @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;
}
Beispiel #3
0
/** 
 *  @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, &region_chan, 0, sizeof(parsed_region_chan_11d_t));
        memset(pmadapter, &bssdesc_region_chan, 0,
               sizeof(parsed_region_chan_11d_t));

        memcpy(pmadapter, &region_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, &region_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();
}