/** * @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, ®ion_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; }
/** * @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; }
/** * @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; }
/** * @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, ®ion_chan, 0, sizeof(parsed_region_chan_11d_t)); memset(pmadapter, &bssdesc_region_chan, 0, sizeof(parsed_region_chan_11d_t)); memcpy(pmadapter, ®ion_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, ®ion_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 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; }