Ejemplo n.º 1
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 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;
}
Ejemplo n.º 2
0
/** 
 *  @brief This function parses country information for region channel
 *
 *  @param pmadapter            Pointer to mlan_adapter structure
 *  @param country_info         Country information
 *  @param band                 Chan band
 *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t     
 *
 *  @return                     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_11d_parse_domain_info(pmlan_adapter pmadapter,
                           IEEEtypes_CountryInfoFullSet_t * country_info,
                           t_u8 band,
                           parsed_region_chan_11d_t * parsed_region_chan)
{
    t_u8 no_of_sub_band, no_of_chan;
    t_u8 last_chan, first_chan, cur_chan = 0;
    t_u8 idx = 0;
    t_u8 j, i;

    ENTER();

    /* 
     * Validation Rules:
     *    1. Valid Region Code
     *    2. First Chan increment
     *    3. Channel range no overlap
     *    4. Channel is valid?
     *    5. Channel is supported by Region?
     *    6. Others
     */

    HEXDUMP("country_info", (t_u8 *) country_info, 30);

    if (!(*(country_info->country_code)) ||
        (country_info->len <= COUNTRY_CODE_LEN)) {
        /* No region info or wrong region info: treat as no 11D info */
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    /* Step 1: Check region_code */
    parsed_region_chan->region =
        wlan_11d_region_2_code(pmadapter, country_info->country_code);

    PRINTM(MINFO, "11D: region code=0x%x\n", (t_u8) parsed_region_chan->region);
    HEXDUMP("11D: Country Code", (t_u8 *) country_info->country_code,
            COUNTRY_CODE_LEN);

    parsed_region_chan->band = band;

    memcpy(pmadapter, parsed_region_chan->country_code,
           country_info->country_code, COUNTRY_CODE_LEN);

    no_of_sub_band = (country_info->len - COUNTRY_CODE_LEN) /
        sizeof(IEEEtypes_SubbandSet_t);

    for (j = 0, last_chan = 0; j < no_of_sub_band; j++) {

        if (country_info->sub_band[j].first_chan <= last_chan) {
            /* Step2&3: Check First Chan Num increment and no overlap */
            PRINTM(MINFO, "11D: Chan[%d>%d] Overlap\n",
                   country_info->sub_band[j].first_chan, last_chan);
            continue;
        }

        first_chan = country_info->sub_band[j].first_chan;
        no_of_chan = country_info->sub_band[j].no_of_chan;

        for (i = 0; idx < MAX_NO_OF_CHAN && i < no_of_chan; i++) {
            /* Step 4 : Channel is supported? */
            if (wlan_11d_get_chan(pmadapter, band, first_chan, i, &cur_chan) ==
                MFALSE) {
                /* Chan is not found in UN table */
                PRINTM(MWARN, "11D: channel is not supported: %d\n", i);
                break;
            }

            last_chan = cur_chan;

            /* Step 5: We don't need to check if cur_chan is supported by mrvl
               in region */
            parsed_region_chan->chan_pwr[idx].chan = cur_chan;
            parsed_region_chan->chan_pwr[idx].pwr =
                country_info->sub_band[j].max_tx_pwr;
            idx++;
        }

        /* Step 6: Add other checking if any */
    }

    parsed_region_chan->no_of_chan = idx;

    PRINTM(MINFO, "11D: number of channel=0x%x\n",
           parsed_region_chan->no_of_chan);
    HEXDUMP("11D: parsed_region_chan", (t_u8 *) parsed_region_chan,
            2 + COUNTRY_CODE_LEN + sizeof(parsed_region_chan_11d_t) * idx);

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}