/** * @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; }
/** * @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 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, ®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, (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, ®ion_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; }