/**
 *  @brief This function handles domain info data from UAP interface.
 *         Checks conditions, sets up domain_reg, then downloads CMD.
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param band         Band interface is operating on
 *  @param domain_tlv   Pointer to domain_info tlv
 *  @param pioctl_buf   Pointer to the IOCTL buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_handle_uap_domain_info(mlan_private * pmpriv,
                                t_u8 band,
                                t_u8 * domain_tlv, t_void * pioctl_buf)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_adapter *pmadapter = pmpriv->adapter;
    MrvlIEtypes_DomainParamSet_t *pdomain_tlv;
    t_u8 num_sub_band = 0;
    t_u8 region_code = 0;

    ENTER();

    pdomain_tlv = (MrvlIEtypes_DomainParamSet_t *) domain_tlv;

    // update region code & table based on country string
    if (wlan_11d_region_2_code(pmadapter, pdomain_tlv->country_code,
                               &region_code) == MLAN_STATUS_SUCCESS) {
        pmadapter->region_code = region_code;
        ret = wlan_set_regiontable(pmpriv, region_code, pmadapter->fw_bands);
    }

    num_sub_band = ((pdomain_tlv->header.len - COUNTRY_CODE_LEN) /
                    sizeof(IEEEtypes_SubbandSet_t));

    // TODO: don't just clobber pmadapter->domain_reg.
    // Add some checking or merging between STA & UAP domain_info

    wlan_11d_set_domain_info(pmpriv, band, pdomain_tlv->country_code,
                             num_sub_band, pdomain_tlv->sub_band);
    ret = wlan_11d_send_domain_info(pmpriv, pioctl_buf);

    LEAVE();
    return ret;
}
/**
 *  @brief This function sets up domain_reg and downloads CMD to FW
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   Pointer to the IOCTL request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_cfg_domain_info(IN pmlan_adapter pmadapter,
                         IN mlan_ioctl_req * pioctl_req)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
    mlan_ds_11d_domain_info *domain_info = MNULL;
    mlan_ds_11d_cfg *cfg_11d = MNULL;

    ENTER();

    cfg_11d = (mlan_ds_11d_cfg *) pioctl_req->pbuf;
    domain_info = &cfg_11d->param.domain_info;

    wlan_11d_set_domain_info(pmpriv, domain_info->band,
                             domain_info->country_code,
                             domain_info->no_of_sub_band,
                             (IEEEtypes_SubbandSet_t *) domain_info->sub_band);
    ret = wlan_11d_send_domain_info(pmpriv, pioctl_req);

    if (ret == MLAN_STATUS_SUCCESS)
        ret = MLAN_STATUS_PENDING;

    LEAVE();
    return ret;
}
Exemple #3
0
/**
 *  @brief This function sets up domain_reg and downloads CMD to FW
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   Pointer to the IOCTL request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_cfg_domain_info(IN pmlan_adapter pmadapter,
			 IN mlan_ioctl_req * pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_11d_domain_info *domain_info = MNULL;
	mlan_ds_11d_cfg *cfg_11d = MNULL;
	t_u8 cfp_bg = 0, cfp_a = 0;

	ENTER();

	cfg_11d = (mlan_ds_11d_cfg *) pioctl_req->pbuf;
	domain_info = &cfg_11d->param.domain_info;
	memcpy(pmadapter, pmadapter->country_code, domain_info->country_code,
	       COUNTRY_CODE_LEN);
	wlan_11d_set_domain_info(pmpriv, domain_info->band,
				 domain_info->country_code,
				 domain_info->no_of_sub_band,
				 (IEEEtypes_SubbandSet_t *) domain_info->
				 sub_band);
	ret = wlan_11d_send_domain_info(pmpriv, pioctl_req);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	/* Update region code and table based on country code */
	if (wlan_misc_country_2_cfp_table_code(pmadapter,
					       domain_info->country_code,
					       &cfp_bg, &cfp_a)) {
		PRINTM(MIOCTL, "Country code %c%c not found!\n",
		       domain_info->country_code[0],
		       domain_info->country_code[1]);
		goto done;
	}
	pmadapter->cfp_code_bg = cfp_bg;
	pmadapter->cfp_code_a = cfp_a;
	if (cfp_bg && cfp_a && (cfp_bg == cfp_a))
		pmadapter->region_code = cfp_a;
	else
		pmadapter->region_code = 0;
	if (wlan_set_regiontable(pmpriv, pmadapter->region_code,
				 pmadapter->config_bands | pmadapter->
				 adhoc_start_band)) {
		PRINTM(MIOCTL, "Fail to set regiontabl\n");
		goto done;
	}
done:
	LEAVE();
	return ret;
}
Exemple #4
0
/**
 *  @brief This function handles domain info data from UAP interface.
 *         Checks conditions, sets up domain_reg, then downloads CMD.
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param band         Band interface is operating on
 *  @param domain_tlv   Pointer to domain_info tlv
 *  @param pioctl_buf   Pointer to the IOCTL buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_handle_uap_domain_info(mlan_private * pmpriv,
				t_u8 band,
				t_u8 * domain_tlv, t_void * pioctl_buf)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_adapter *pmadapter = pmpriv->adapter;
	MrvlIEtypes_DomainParamSet_t *pdomain_tlv;
	t_u8 num_sub_band = 0;
	t_u8 cfp_bg = 0, cfp_a = 0;

	ENTER();

	pdomain_tlv = (MrvlIEtypes_DomainParamSet_t *) domain_tlv;

	/* update region code & table based on country string */
	if (wlan_misc_country_2_cfp_table_code(pmadapter,
					       pdomain_tlv->country_code,
					       &cfp_bg,
					       &cfp_a) == MLAN_STATUS_SUCCESS) {
		pmadapter->cfp_code_bg = cfp_bg;
		pmadapter->cfp_code_a = cfp_a;
		if (cfp_bg && cfp_a && (cfp_bg == cfp_a))
			pmadapter->region_code = cfp_a;
		else
			pmadapter->region_code = 0;
		if (wlan_set_regiontable(pmpriv, pmadapter->region_code,
					 pmadapter->config_bands | pmadapter->
					 adhoc_start_band)) {
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
	}

	memcpy(pmadapter, pmadapter->country_code, pdomain_tlv->country_code,
	       COUNTRY_CODE_LEN);
	num_sub_band =
		((pdomain_tlv->header.len -
		  COUNTRY_CODE_LEN) / sizeof(IEEEtypes_SubbandSet_t));

	/* TODO: don't just clobber pmadapter->domain_reg.  Add some checking
	   or merging between STA & UAP domain_info */
	wlan_11d_set_domain_info(pmpriv, band, pdomain_tlv->country_code,
				 num_sub_band, pdomain_tlv->sub_band);
	ret = wlan_11d_send_domain_info(pmpriv, pioctl_buf);

done:
	LEAVE();
	return ret;
}
Exemple #5
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;
}
Exemple #6
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();

    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 */
    memset(pmadapter, &pmadapter->domain_reg, 0,
           sizeof(wlan_802_11d_domain_reg_t));
    wlan_11d_generate_domain_info(pmadapter, &parsed_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;
}