コード例 #1
0
ファイル: mlan_11d.c プロジェクト: Lloir/nvidia-linux-3.10
/**
 *  @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_is_enabled(pmpriv) && pmadapter->num_in_scan_table != 0) {
		for (idx = 0; idx < pmadapter->num_in_scan_table; idx++) {
			pcountry_full =
				&pmadapter->pscan_table[idx].country_info;

			ret = wlan_11d_update_chan_pwr_table(pmpriv,
							     &pmadapter->
							     pscan_table[idx]);

			if (*(pcountry_full->country_code) != 0 &&
			    (pcountry_full->len > COUNTRY_CODE_LEN)) {
				/* Country info found in the BSS Descriptor */
				ret = wlan_11d_process_country_info(pmpriv,
								    &pmadapter->
								    pscan_table
								    [idx]);
			}
		}

		/* Sort parsed_region_chan in ascending channel number */
		wlan_11d_sort_parsed_region_chan(&pmadapter->
						 parsed_region_chan);

		/* 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;
}
コード例 #2
0
/**
 *  @brief This function clears the parsed region table, if 11D is enabled
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_clear_parsedtable(mlan_private * pmpriv)
{
    mlan_adapter *pmadapter = pmpriv->adapter;
    mlan_status ret = MLAN_STATUS_SUCCESS;

    ENTER();

    if (wlan_11d_is_enabled(pmpriv))
        memset(pmadapter, &(pmadapter->parsed_region_chan), 0,
               sizeof(parsed_region_chan_11d_t));
    else
        ret = MLAN_STATUS_FAILURE;

    LEAVE();
    return ret;
}
コード例 #3
0
/**
 *  @brief Set SNMP MIB for 11H
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return     MLAN_STATUS_PENDING --success, otherwise fail
 *  @sa         wlan_uap_callback_snmp_mib_11h
 */
static mlan_status
wlan_uap_snmp_mib_11h(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
    mlan_ds_snmp_mib *snmp = MNULL;
    t_bool enable;

    ENTER();

    if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) {
        PRINTM(MWARN, "MLAN snmp_mib IOCTL length is too short.\n");
        pioctl_req->data_read_written = 0;
        pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib);
        LEAVE();
        return MLAN_STATUS_RESOURCE;
    }
    snmp = (mlan_ds_snmp_mib *) pioctl_req->pbuf;
    enable = (snmp->param.oid_value) ? MTRUE : MFALSE;

    if (enable) {
        /* first enable 11D if it is not enabled */
        if (!wlan_11d_is_enabled(pmpriv)) {
            ret = wlan_11d_enable(pmpriv, MNULL, ENABLE_11D);
            if (ret != MLAN_STATUS_SUCCESS) {
                PRINTM(MERROR,
                       "Failed to first enable 11D before enabling 11H.\n");
                LEAVE();
                return ret;
            }
        }
    }

    /* store params, issue command to get UAP channel, whose CMD_RESP will
       callback remainder of 11H handling (and radar detect if DFS chan) */
    pmpriv->uap_state_chan_cb.pioctl_req_curr = pioctl_req;
    pmpriv->uap_state_chan_cb.get_chan_callback =
        wlan_uap_callback_snmp_mib_11h;

    ret = wlan_uap_get_channel(pmpriv);
    if (ret == MLAN_STATUS_SUCCESS)
        ret = MLAN_STATUS_PENDING;

    LEAVE();
    return ret;
}
コード例 #4
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_is_enabled(pmpriv)) {

        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,
                                           (t_u8) 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, use minimum of existing
                         * tx power and 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[i].band ==
                            bssdesc_region_chan.chan_pwr[j].band) {
                            region_chan.chan_pwr[j].pwr =
                                MIN(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);

        /* Set domain info */
        ret = wlan_11d_send_domain_info(pmpriv, MNULL);
        if (ret) {
            PRINTM(MERROR, "11D: Error sending domain info to FW\n");
        }
    }

    LEAVE();
    return ret;
}
コード例 #5
0
/**
 *  @brief This function generates 11D info from user specified regioncode
 *         and download to FW
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param band         Band to create
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_create_dnld_countryinfo(mlan_private * pmpriv, t_u8 band)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_adapter *pmadapter = pmpriv->adapter;
    region_chan_t *region_chan;
    parsed_region_chan_11d_t parsed_region_chan;
    t_u8 j;

    ENTER();

    /* Only valid if 11D is enabled */
    if (wlan_11d_is_enabled(pmpriv)) {

        PRINTM(MINFO, "11D: Band[%d]\n", band);

        /* Update parsed_region_chan; download domain info to FW */

        /* Find region channel */
        for (j = 0;
             j <
             sizeof(pmadapter->region_channel) /
             sizeof(pmadapter->region_channel[0]); j++) {
            region_chan = &pmadapter->region_channel[j];

            PRINTM(MINFO, "11D: [%d] region_chan->Band[%d]\n", j,
                   region_chan->band);

            if (!region_chan || !region_chan->valid || !region_chan->pcfp)
                continue;
            switch (region_chan->band) {
            case BAND_A:
                switch (band) {
                case BAND_A:
                case BAND_AN:
                case BAND_A | BAND_AN:
                    break;
                default:
                    continue;
                }
                break;
            case BAND_B:
            case BAND_G:
                switch (band) {
                case BAND_B:
                case BAND_G:
                case BAND_G | BAND_B:
                case BAND_GN:
                case BAND_G | BAND_GN:
                case BAND_B | BAND_G | BAND_GN:
                    break;
                default:
                    continue;
                }
                break;
            default:
                continue;
            }
            break;
        }

        /* Check if region channel found */
        if (j >= sizeof(pmadapter->region_channel) /
            sizeof(pmadapter->region_channel[0])) {
            PRINTM(MERROR, "11D: region_chan not found. Band[%d]\n", band);
            LEAVE();
            return MLAN_STATUS_FAILURE;
        }

        /* Generate parsed region channel info from region channel */
        memset(pmadapter, &parsed_region_chan, 0,
               sizeof(parsed_region_chan_11d_t));
        wlan_11d_generate_parsed_region_chan(pmadapter, region_chan,
                                             &parsed_region_chan);

        /* Generate domain info from parsed region channel info */
        wlan_11d_generate_domain_info(pmadapter, &parsed_region_chan);

        /* Set domain info */
        ret = wlan_11d_send_domain_info(pmpriv, MNULL);
        if (ret) {
            PRINTM(MERROR, "11D: Error sending domain info to FW\n");
        }
    }

    LEAVE();
    return ret;
}
コード例 #6
0
/**
 *  @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
 *  @param drv_disconnect   Flag indicating the driver should disconnect
 *                          and flush pending packets.
 *
 *  @return                 N/A
 */
t_void
wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect)
{
	mlan_adapter *pmadapter = priv->adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	state_11d_t enable;

	ENTER();

	PRINTM(MINFO, "Handles disconnect event.\n");

	if (drv_disconnect) {
		priv->media_connected = MFALSE;
		wlan_11h_check_update_radar_det_state(priv);
	}

	if (priv->port_ctrl_mode == MTRUE) {
		/* Close the port on Disconnect */
		PRINTM(MINFO, "DISC: port_status = CLOSED\n");
		priv->port_open = MFALSE;
	}
	pmadapter->scan_block = MFALSE;

	/* 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_rate_info = 0;
	priv->max_amsdu = 0;
	wlan_coex_ampdu_rxwinsize(pmadapter);

	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->wps.session_enable = MFALSE;
	memset(priv->adapter, (t_u8 *)&priv->wps.wps_ie, 0x00,
	       sizeof(priv->wps.wps_ie));
	priv->sec_info.osen_enabled = MFALSE;
	priv->osen_ie_len = 0;

	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->intf_state_11h.adhoc_auto_sel_chan = MTRUE;
	}

	if (drv_disconnect) {
		/* Free Tx and Rx packets, report disconnect to upper layer */
		wlan_clean_txrx(priv);

		/* Need to erase the current SSID and BSSID info */
		memset(pmadapter,
		       &priv->curr_bss_params, 0x00,
		       sizeof(priv->curr_bss_params));
	}
	wlan_send_tdls_tear_down_request(priv);
	wlan_delete_station_list(priv);
	pmadapter->tdls_status = TDLS_NOT_SETUP;
	priv->wmm_qosinfo = priv->saved_wmm_qosinfo;
	pmadapter->sleep_period.period = pmadapter->saved_sleep_period.period;
	pmadapter->tx_lock_flag = MFALSE;
	pmadapter->pps_uapsd_mode = MFALSE;
	pmadapter->delay_null_pkt = MFALSE;

	if ((wlan_11d_is_enabled(priv)) &&
	    (priv->state_11d.user_enable_11d == DISABLE_11D)) {

		priv->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();
}