Esempio n. 1
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;
}
Esempio n. 2
0
/** 
 *  @brief This function processes the country info present in BSSDescriptor.
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pbss_desc     A pointer to BSSDescriptor_t
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
wlan_11d_process_country_info(mlan_private * pmpriv,
                              BSSDescriptor_t * pbss_desc)
{
    mlan_adapter *pmadapter = pmpriv->adapter;
    parsed_region_chan_11d_t region_chan;
    parsed_region_chan_11d_t *parsed_region_chan =
        &pmadapter->parsed_region_chan;
    t_u16 i, j, num_chan_added = 0;

    ENTER();

    memset(pmadapter, &region_chan, 0, sizeof(parsed_region_chan_11d_t));

    /* Parse 11D country info */
    if (wlan_11d_parse_domain_info(pmadapter, &pbss_desc->country_info,
                                   (t_u8) pbss_desc->bss_band,
                                   &region_chan) != MLAN_STATUS_SUCCESS)
        return MLAN_STATUS_FAILURE;

    memcpy(pmadapter, parsed_region_chan->country_code,
           &region_chan.country_code, COUNTRY_CODE_LEN);

    if (parsed_region_chan->no_of_chan != 0) {
        /* 
         * Check if the channel number already exists in the 
         * chan-power table of parsed_region_chan
         */
        for (i = 0; (i < region_chan.no_of_chan && i < MAX_NO_OF_CHAN); i++) {
            for (j = 0; (j < parsed_region_chan->no_of_chan &&
                         j < MAX_NO_OF_CHAN); j++) {
                /* 
                 * Channel already exists, update the tx power with new tx
                 * power, since country IE is valid here.
                 */
                if (region_chan.chan_pwr[i].chan ==
                    parsed_region_chan->chan_pwr[j].chan) {
                    parsed_region_chan->chan_pwr[j].pwr =
                        region_chan.chan_pwr[i].pwr;
                    break;
                }
            }

            if (j == parsed_region_chan->no_of_chan && j < MAX_NO_OF_CHAN) {
                /* 
                 * Channel does not exist in the channel power table, 
                 * update this new chan and tx_power to the channel power table
                 */
                parsed_region_chan->chan_pwr[parsed_region_chan->no_of_chan +
                                             num_chan_added].chan =
                    region_chan.chan_pwr[i].chan;
                parsed_region_chan->chan_pwr[parsed_region_chan->no_of_chan +
                                             num_chan_added].pwr =
                    region_chan.chan_pwr[i].pwr;
                num_chan_added++;
            }
        }
        parsed_region_chan->no_of_chan += num_chan_added;
    } else {
        /* Parsed region is empty, copy the first one */
        memcpy(pmadapter, parsed_region_chan,
               &region_chan, sizeof(parsed_region_chan_11d_t));
    }

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Esempio n. 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_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;
}