| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 1 | /** | 
 | 2 |   * This file contains functions for 802.11D. | 
 | 3 |   */ | 
 | 4 | #include <linux/ctype.h> | 
 | 5 | #include <linux/kernel.h> | 
 | 6 | #include <linux/wireless.h> | 
 | 7 |  | 
 | 8 | #include "host.h" | 
 | 9 | #include "decl.h" | 
 | 10 | #include "11d.h" | 
 | 11 | #include "dev.h" | 
 | 12 | #include "wext.h" | 
 | 13 |  | 
 | 14 | #define TX_PWR_DEFAULT	10 | 
 | 15 |  | 
 | 16 | static struct region_code_mapping region_code_mapping[] = { | 
 | 17 | 	{"US ", 0x10},		/* US FCC      */ | 
 | 18 | 	{"CA ", 0x10},		/* IC Canada   */ | 
 | 19 | 	{"SG ", 0x10},		/* Singapore   */ | 
 | 20 | 	{"EU ", 0x30},		/* ETSI        */ | 
 | 21 | 	{"AU ", 0x30},		/* Australia   */ | 
 | 22 | 	{"KR ", 0x30},		/* Republic Of Korea */ | 
 | 23 | 	{"ES ", 0x31},		/* Spain       */ | 
 | 24 | 	{"FR ", 0x32},		/* France      */ | 
 | 25 | 	{"JP ", 0x40},		/* Japan       */ | 
 | 26 | }; | 
 | 27 |  | 
 | 28 | /* Following 2 structure defines the supported channels */ | 
 | 29 | static struct chan_freq_power channel_freq_power_UN_BG[] = { | 
 | 30 | 	{1, 2412, TX_PWR_DEFAULT}, | 
 | 31 | 	{2, 2417, TX_PWR_DEFAULT}, | 
 | 32 | 	{3, 2422, TX_PWR_DEFAULT}, | 
 | 33 | 	{4, 2427, TX_PWR_DEFAULT}, | 
 | 34 | 	{5, 2432, TX_PWR_DEFAULT}, | 
 | 35 | 	{6, 2437, TX_PWR_DEFAULT}, | 
 | 36 | 	{7, 2442, TX_PWR_DEFAULT}, | 
 | 37 | 	{8, 2447, TX_PWR_DEFAULT}, | 
 | 38 | 	{9, 2452, TX_PWR_DEFAULT}, | 
 | 39 | 	{10, 2457, TX_PWR_DEFAULT}, | 
 | 40 | 	{11, 2462, TX_PWR_DEFAULT}, | 
 | 41 | 	{12, 2467, TX_PWR_DEFAULT}, | 
 | 42 | 	{13, 2472, TX_PWR_DEFAULT}, | 
 | 43 | 	{14, 2484, TX_PWR_DEFAULT} | 
 | 44 | }; | 
 | 45 |  | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 46 | static u8 lbs_region_2_code(u8 *region) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 47 | { | 
 | 48 | 	u8 i; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 49 |  | 
 | 50 | 	for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++) | 
 | 51 | 		region[i] = toupper(region[i]); | 
 | 52 |  | 
| Alejandro Martinez Ruiz | c00acf4 | 2007-10-18 10:16:33 +0200 | [diff] [blame] | 53 | 	for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 54 | 		if (!memcmp(region, region_code_mapping[i].region, | 
 | 55 | 			    COUNTRY_CODE_LEN)) | 
 | 56 | 			return (region_code_mapping[i].code); | 
 | 57 | 	} | 
 | 58 |  | 
 | 59 | 	/* default is US */ | 
 | 60 | 	return (region_code_mapping[0].code); | 
 | 61 | } | 
 | 62 |  | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 63 | static u8 *lbs_code_2_region(u8 code) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 64 | { | 
 | 65 | 	u8 i; | 
| Alejandro Martinez Ruiz | c00acf4 | 2007-10-18 10:16:33 +0200 | [diff] [blame] | 66 |  | 
 | 67 | 	for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 68 | 		if (region_code_mapping[i].code == code) | 
 | 69 | 			return (region_code_mapping[i].region); | 
 | 70 | 	} | 
 | 71 | 	/* default is US */ | 
 | 72 | 	return (region_code_mapping[0].region); | 
 | 73 | } | 
 | 74 |  | 
 | 75 | /** | 
 | 76 |  *  @brief This function finds the nrchan-th chan after the firstchan | 
 | 77 |  *  @param band       band | 
 | 78 |  *  @param firstchan  first channel number | 
 | 79 |  *  @param nrchan   number of channels | 
 | 80 |  *  @return 	      the nrchan-th chan number | 
 | 81 | */ | 
| Holger Schurig | e98a88d | 2008-03-19 14:25:58 +0100 | [diff] [blame] | 82 | static u8 lbs_get_chan_11d(u8 firstchan, u8 nrchan, u8 *chan) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 83 | /*find the nrchan-th chan after the firstchan*/ | 
 | 84 | { | 
 | 85 | 	u8 i; | 
 | 86 | 	struct chan_freq_power *cfp; | 
 | 87 | 	u8 cfp_no; | 
 | 88 |  | 
 | 89 | 	cfp = channel_freq_power_UN_BG; | 
| Alejandro Martinez Ruiz | c00acf4 | 2007-10-18 10:16:33 +0200 | [diff] [blame] | 90 | 	cfp_no = ARRAY_SIZE(channel_freq_power_UN_BG); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 91 |  | 
 | 92 | 	for (i = 0; i < cfp_no; i++) { | 
 | 93 | 		if ((cfp + i)->channel == firstchan) { | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 94 | 			lbs_deb_11d("firstchan found\n"); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 95 | 			break; | 
 | 96 | 		} | 
 | 97 | 	} | 
 | 98 |  | 
 | 99 | 	if (i < cfp_no) { | 
 | 100 | 		/*if beyond the boundary */ | 
 | 101 | 		if (i + nrchan < cfp_no) { | 
 | 102 | 			*chan = (cfp + i + nrchan)->channel; | 
 | 103 | 			return 1; | 
 | 104 | 		} | 
 | 105 | 	} | 
 | 106 |  | 
 | 107 | 	return 0; | 
 | 108 | } | 
 | 109 |  | 
 | 110 | /** | 
 | 111 |  *  @brief This function Checks if chan txpwr is learned from AP/IBSS | 
 | 112 |  *  @param chan                 chan number | 
 | 113 |  *  @param parsed_region_chan   pointer to parsed_region_chan_11d | 
 | 114 |  *  @return 	                TRUE; FALSE | 
 | 115 | */ | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 116 | static u8 lbs_channel_known_11d(u8 chan, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 117 | 			  struct parsed_region_chan_11d * parsed_region_chan) | 
 | 118 | { | 
 | 119 | 	struct chan_power_11d *chanpwr = parsed_region_chan->chanpwr; | 
 | 120 | 	u8 nr_chan = parsed_region_chan->nr_chan; | 
 | 121 | 	u8 i = 0; | 
 | 122 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 123 | 	lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)chanpwr, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 124 | 		sizeof(struct chan_power_11d) * nr_chan); | 
 | 125 |  | 
 | 126 | 	for (i = 0; i < nr_chan; i++) { | 
 | 127 | 		if (chan == chanpwr[i].chan) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 128 | 			lbs_deb_11d("found chan %d\n", chan); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 129 | 			return 1; | 
 | 130 | 		} | 
 | 131 | 	} | 
 | 132 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 133 | 	lbs_deb_11d("chan %d not found\n", chan); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 134 | 	return 0; | 
 | 135 | } | 
 | 136 |  | 
| Holger Schurig | e98a88d | 2008-03-19 14:25:58 +0100 | [diff] [blame] | 137 | u32 lbs_chan_2_freq(u8 chan) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 138 | { | 
 | 139 | 	struct chan_freq_power *cf; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 140 | 	u16 i; | 
 | 141 | 	u32 freq = 0; | 
 | 142 |  | 
 | 143 | 	cf = channel_freq_power_UN_BG; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 144 |  | 
| Alejandro Martinez Ruiz | c00acf4 | 2007-10-18 10:16:33 +0200 | [diff] [blame] | 145 | 	for (i = 0; i < ARRAY_SIZE(channel_freq_power_UN_BG); i++) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 146 | 		if (chan == cf[i].channel) | 
 | 147 | 			freq = cf[i].freq; | 
 | 148 | 	} | 
 | 149 |  | 
 | 150 | 	return freq; | 
 | 151 | } | 
 | 152 |  | 
 | 153 | static int generate_domain_info_11d(struct parsed_region_chan_11d | 
 | 154 | 				  *parsed_region_chan, | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 155 | 				  struct lbs_802_11d_domain_reg *domaininfo) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 156 | { | 
 | 157 | 	u8 nr_subband = 0; | 
 | 158 |  | 
 | 159 | 	u8 nr_chan = parsed_region_chan->nr_chan; | 
 | 160 | 	u8 nr_parsedchan = 0; | 
 | 161 |  | 
 | 162 | 	u8 firstchan = 0, nextchan = 0, maxpwr = 0; | 
 | 163 |  | 
 | 164 | 	u8 i, flag = 0; | 
 | 165 |  | 
 | 166 | 	memcpy(domaininfo->countrycode, parsed_region_chan->countrycode, | 
 | 167 | 	       COUNTRY_CODE_LEN); | 
 | 168 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 169 | 	lbs_deb_11d("nrchan %d\n", nr_chan); | 
 | 170 | 	lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)parsed_region_chan, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 171 | 		sizeof(struct parsed_region_chan_11d)); | 
 | 172 |  | 
 | 173 | 	for (i = 0; i < nr_chan; i++) { | 
 | 174 | 		if (!flag) { | 
 | 175 | 			flag = 1; | 
 | 176 | 			nextchan = firstchan = | 
 | 177 | 			    parsed_region_chan->chanpwr[i].chan; | 
 | 178 | 			maxpwr = parsed_region_chan->chanpwr[i].pwr; | 
 | 179 | 			nr_parsedchan = 1; | 
 | 180 | 			continue; | 
 | 181 | 		} | 
 | 182 |  | 
 | 183 | 		if (parsed_region_chan->chanpwr[i].chan == nextchan + 1 && | 
 | 184 | 		    parsed_region_chan->chanpwr[i].pwr == maxpwr) { | 
 | 185 | 			nextchan++; | 
 | 186 | 			nr_parsedchan++; | 
 | 187 | 		} else { | 
 | 188 | 			domaininfo->subband[nr_subband].firstchan = firstchan; | 
 | 189 | 			domaininfo->subband[nr_subband].nrchan = | 
 | 190 | 			    nr_parsedchan; | 
 | 191 | 			domaininfo->subband[nr_subband].maxtxpwr = maxpwr; | 
 | 192 | 			nr_subband++; | 
 | 193 | 			nextchan = firstchan = | 
 | 194 | 			    parsed_region_chan->chanpwr[i].chan; | 
 | 195 | 			maxpwr = parsed_region_chan->chanpwr[i].pwr; | 
 | 196 | 		} | 
 | 197 | 	} | 
 | 198 |  | 
 | 199 | 	if (flag) { | 
 | 200 | 		domaininfo->subband[nr_subband].firstchan = firstchan; | 
 | 201 | 		domaininfo->subband[nr_subband].nrchan = nr_parsedchan; | 
 | 202 | 		domaininfo->subband[nr_subband].maxtxpwr = maxpwr; | 
 | 203 | 		nr_subband++; | 
 | 204 | 	} | 
 | 205 | 	domaininfo->nr_subband = nr_subband; | 
 | 206 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 207 | 	lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband); | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 208 | 	lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 209 | 		COUNTRY_CODE_LEN + 1 + | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 210 | 		sizeof(struct ieee_subbandset) * nr_subband); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 211 | 	return 0; | 
 | 212 | } | 
 | 213 |  | 
 | 214 | /** | 
 | 215 |  *  @brief This function generates parsed_region_chan from Domain Info learned from AP/IBSS | 
 | 216 |  *  @param region_chan          pointer to struct region_channel | 
 | 217 |  *  @param *parsed_region_chan  pointer to parsed_region_chan_11d | 
 | 218 |  *  @return 	                N/A | 
 | 219 | */ | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 220 | static void lbs_generate_parsed_region_chan_11d(struct region_channel *region_chan, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 221 | 					  struct parsed_region_chan_11d * | 
 | 222 | 					  parsed_region_chan) | 
 | 223 | { | 
 | 224 | 	u8 i; | 
 | 225 | 	struct chan_freq_power *cfp; | 
 | 226 |  | 
 | 227 | 	if (region_chan == NULL) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 228 | 		lbs_deb_11d("region_chan is NULL\n"); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 229 | 		return; | 
 | 230 | 	} | 
 | 231 |  | 
 | 232 | 	cfp = region_chan->CFP; | 
 | 233 | 	if (cfp == NULL) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 234 | 		lbs_deb_11d("cfp is NULL \n"); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 235 | 		return; | 
 | 236 | 	} | 
 | 237 |  | 
 | 238 | 	parsed_region_chan->band = region_chan->band; | 
 | 239 | 	parsed_region_chan->region = region_chan->region; | 
 | 240 | 	memcpy(parsed_region_chan->countrycode, | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 241 | 	       lbs_code_2_region(region_chan->region), COUNTRY_CODE_LEN); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 242 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 243 | 	lbs_deb_11d("region 0x%x, band %d\n", parsed_region_chan->region, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 244 | 	       parsed_region_chan->band); | 
 | 245 |  | 
 | 246 | 	for (i = 0; i < region_chan->nrcfp; i++, cfp++) { | 
 | 247 | 		parsed_region_chan->chanpwr[i].chan = cfp->channel; | 
 | 248 | 		parsed_region_chan->chanpwr[i].pwr = cfp->maxtxpower; | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 249 | 		lbs_deb_11d("chan %d, pwr %d\n", | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 250 | 		       parsed_region_chan->chanpwr[i].chan, | 
 | 251 | 		       parsed_region_chan->chanpwr[i].pwr); | 
 | 252 | 	} | 
 | 253 | 	parsed_region_chan->nr_chan = region_chan->nrcfp; | 
 | 254 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 255 | 	lbs_deb_11d("nrchan %d\n", parsed_region_chan->nr_chan); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 256 |  | 
 | 257 | 	return; | 
 | 258 | } | 
 | 259 |  | 
 | 260 | /** | 
 | 261 |  *  @brief generate parsed_region_chan from Domain Info learned from AP/IBSS | 
 | 262 |  *  @param region               region ID | 
 | 263 |  *  @param band                 band | 
 | 264 |  *  @param chan                 chan | 
 | 265 |  *  @return 	                TRUE;FALSE | 
 | 266 | */ | 
| Holger Schurig | e98a88d | 2008-03-19 14:25:58 +0100 | [diff] [blame] | 267 | static u8 lbs_region_chan_supported_11d(u8 region, u8 chan) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 268 | { | 
 | 269 | 	struct chan_freq_power *cfp; | 
 | 270 | 	int cfp_no; | 
 | 271 | 	u8 idx; | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 272 | 	int ret = 0; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 273 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 274 | 	lbs_deb_enter(LBS_DEB_11D); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 275 |  | 
| Holger Schurig | e98a88d | 2008-03-19 14:25:58 +0100 | [diff] [blame] | 276 | 	cfp = lbs_get_region_cfp_table(region, &cfp_no); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 277 | 	if (cfp == NULL) | 
 | 278 | 		return 0; | 
 | 279 |  | 
 | 280 | 	for (idx = 0; idx < cfp_no; idx++) { | 
 | 281 | 		if (chan == (cfp + idx)->channel) { | 
 | 282 | 			/* If Mrvl Chip Supported? */ | 
 | 283 | 			if ((cfp + idx)->unsupported) { | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 284 | 				ret = 0; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 285 | 			} else { | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 286 | 				ret = 1; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 287 | 			} | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 288 | 			goto done; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 289 | 		} | 
 | 290 | 	} | 
 | 291 |  | 
 | 292 | 	/*chan is not in the region table */ | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 293 |  | 
 | 294 | done: | 
 | 295 | 	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); | 
 | 296 | 	return ret; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 297 | } | 
 | 298 |  | 
 | 299 | /** | 
 | 300 |  *  @brief This function checks if chan txpwr is learned from AP/IBSS | 
 | 301 |  *  @param chan                 chan number | 
 | 302 |  *  @param parsed_region_chan   pointer to parsed_region_chan_11d | 
 | 303 |  *  @return 	                0 | 
 | 304 | */ | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 305 | static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryinfo, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 306 | 				 u8 band, | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 307 | 				 struct parsed_region_chan_11d *parsed_region_chan) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 308 | { | 
 | 309 | 	u8 nr_subband, nrchan; | 
 | 310 | 	u8 lastchan, firstchan; | 
 | 311 | 	u8 region; | 
 | 312 | 	u8 curchan = 0; | 
 | 313 |  | 
 | 314 | 	u8 idx = 0;		/*chan index in parsed_region_chan */ | 
 | 315 |  | 
 | 316 | 	u8 j, i; | 
 | 317 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 318 | 	lbs_deb_enter(LBS_DEB_11D); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 319 |  | 
 | 320 | 	/*validation Rules: | 
 | 321 | 	   1. valid region Code | 
 | 322 | 	   2. First Chan increment | 
 | 323 | 	   3. channel range no overlap | 
 | 324 | 	   4. channel is valid? | 
 | 325 | 	   5. channel is supported by region? | 
 | 326 | 	   6. Others | 
 | 327 | 	 */ | 
 | 328 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 329 | 	lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 330 |  | 
 | 331 | 	if ((*(countryinfo->countrycode)) == 0 | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 332 | 	    || (countryinfo->header.len <= COUNTRY_CODE_LEN)) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 333 | 		/* No region Info or Wrong region info: treat as No 11D info */ | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 334 | 		goto done; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 335 | 	} | 
 | 336 |  | 
 | 337 | 	/*Step1: check region_code */ | 
 | 338 | 	parsed_region_chan->region = region = | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 339 | 	    lbs_region_2_code(countryinfo->countrycode); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 340 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 341 | 	lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region); | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 342 | 	lbs_deb_hex(LBS_DEB_11D, "countrycode", (char *)countryinfo->countrycode, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 343 | 		COUNTRY_CODE_LEN); | 
 | 344 |  | 
 | 345 | 	parsed_region_chan->band = band; | 
 | 346 |  | 
 | 347 | 	memcpy(parsed_region_chan->countrycode, countryinfo->countrycode, | 
 | 348 | 	       COUNTRY_CODE_LEN); | 
 | 349 |  | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 350 | 	nr_subband = (countryinfo->header.len - COUNTRY_CODE_LEN) / | 
 | 351 | 	    sizeof(struct ieee_subbandset); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 352 |  | 
 | 353 | 	for (j = 0, lastchan = 0; j < nr_subband; j++) { | 
 | 354 |  | 
 | 355 | 		if (countryinfo->subband[j].firstchan <= lastchan) { | 
 | 356 | 			/*Step2&3. Check First Chan Num increment and no overlap */ | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 357 | 			lbs_deb_11d("chan %d>%d, overlap\n", | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 358 | 			       countryinfo->subband[j].firstchan, lastchan); | 
 | 359 | 			continue; | 
 | 360 | 		} | 
 | 361 |  | 
 | 362 | 		firstchan = countryinfo->subband[j].firstchan; | 
 | 363 | 		nrchan = countryinfo->subband[j].nrchan; | 
 | 364 |  | 
 | 365 | 		for (i = 0; idx < MAX_NO_OF_CHAN && i < nrchan; i++) { | 
 | 366 | 			/*step4: channel is supported? */ | 
 | 367 |  | 
| Holger Schurig | e98a88d | 2008-03-19 14:25:58 +0100 | [diff] [blame] | 368 | 			if (!lbs_get_chan_11d(firstchan, i, &curchan)) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 369 | 				/* Chan is not found in UN table */ | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 370 | 				lbs_deb_11d("chan is not supported: %d \n", i); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 371 | 				break; | 
 | 372 | 			} | 
 | 373 |  | 
 | 374 | 			lastchan = curchan; | 
 | 375 |  | 
| Holger Schurig | e98a88d | 2008-03-19 14:25:58 +0100 | [diff] [blame] | 376 | 			if (lbs_region_chan_supported_11d(region, curchan)) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 377 | 				/*step5: Check if curchan is supported by mrvl in region */ | 
 | 378 | 				parsed_region_chan->chanpwr[idx].chan = curchan; | 
 | 379 | 				parsed_region_chan->chanpwr[idx].pwr = | 
 | 380 | 				    countryinfo->subband[j].maxtxpwr; | 
 | 381 | 				idx++; | 
 | 382 | 			} else { | 
 | 383 | 				/*not supported and ignore the chan */ | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 384 | 				lbs_deb_11d( | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 385 | 				       "i %d, chan %d unsupported in region %x, band %d\n", | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 386 | 				       i, curchan, region, band); | 
 | 387 | 			} | 
 | 388 | 		} | 
 | 389 |  | 
 | 390 | 		/*Step6: Add other checking if any */ | 
 | 391 |  | 
 | 392 | 	} | 
 | 393 |  | 
 | 394 | 	parsed_region_chan->nr_chan = idx; | 
 | 395 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 396 | 	lbs_deb_11d("nrchan=%x\n", parsed_region_chan->nr_chan); | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 397 | 	lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (u8 *) parsed_region_chan, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 398 | 		2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx); | 
 | 399 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 400 | done: | 
 | 401 | 	lbs_deb_enter(LBS_DEB_11D); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 402 | 	return 0; | 
 | 403 | } | 
 | 404 |  | 
 | 405 | /** | 
 | 406 |  *  @brief This function calculates the scan type for channels | 
 | 407 |  *  @param chan                 chan number | 
 | 408 |  *  @param parsed_region_chan   pointer to parsed_region_chan_11d | 
 | 409 |  *  @return 	                PASSIVE if chan is unknown; ACTIVE if chan is known | 
 | 410 | */ | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 411 | u8 lbs_get_scan_type_11d(u8 chan, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 412 | 			  struct parsed_region_chan_11d * parsed_region_chan) | 
 | 413 | { | 
| Dan Williams | 0aef64d | 2007-08-02 11:31:18 -0400 | [diff] [blame] | 414 | 	u8 scan_type = CMD_SCAN_TYPE_PASSIVE; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 415 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 416 | 	lbs_deb_enter(LBS_DEB_11D); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 417 |  | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 418 | 	if (lbs_channel_known_11d(chan, parsed_region_chan)) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 419 | 		lbs_deb_11d("found, do active scan\n"); | 
| Dan Williams | 0aef64d | 2007-08-02 11:31:18 -0400 | [diff] [blame] | 420 | 		scan_type = CMD_SCAN_TYPE_ACTIVE; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 421 | 	} else { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 422 | 		lbs_deb_11d("not found, do passive scan\n"); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 423 | 	} | 
 | 424 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 425 | 	lbs_deb_leave_args(LBS_DEB_11D, "ret scan_type %d", scan_type); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 426 | 	return scan_type; | 
 | 427 |  | 
 | 428 | } | 
 | 429 |  | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 430 | void lbs_init_11d(struct lbs_private *priv) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 431 | { | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 432 | 	priv->enable11d = 0; | 
 | 433 | 	memset(&(priv->parsed_region_chan), 0, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 434 | 	       sizeof(struct parsed_region_chan_11d)); | 
 | 435 | 	return; | 
 | 436 | } | 
 | 437 |  | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 438 | /** | 
 | 439 |  *  @brief This function sets DOMAIN INFO to FW | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 440 |  *  @param priv       pointer to struct lbs_private | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 441 |  *  @return 	      0; -1 | 
 | 442 | */ | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 443 | static int set_domain_info_11d(struct lbs_private *priv) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 444 | { | 
 | 445 | 	int ret; | 
 | 446 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 447 | 	if (!priv->enable11d) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 448 | 		lbs_deb_11d("dnld domain Info with 11d disabled\n"); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 449 | 		return 0; | 
 | 450 | 	} | 
 | 451 |  | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 452 | 	ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO, | 
| Dan Williams | 0aef64d | 2007-08-02 11:31:18 -0400 | [diff] [blame] | 453 | 				    CMD_ACT_SET, | 
 | 454 | 				    CMD_OPTION_WAITFORRSP, 0, NULL); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 455 | 	if (ret) | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 456 | 		lbs_deb_11d("fail to dnld domain info\n"); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 457 |  | 
 | 458 | 	return ret; | 
 | 459 | } | 
 | 460 |  | 
 | 461 | /** | 
 | 462 |  *  @brief This function setups scan channels | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 463 |  *  @param priv       pointer to struct lbs_private | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 464 |  *  @param band       band | 
 | 465 |  *  @return 	      0 | 
 | 466 | */ | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 467 | int lbs_set_universaltable(struct lbs_private *priv, u8 band) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 468 | { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 469 | 	u16 size = sizeof(struct chan_freq_power); | 
 | 470 | 	u16 i = 0; | 
 | 471 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 472 | 	memset(priv->universal_channel, 0, | 
 | 473 | 	       sizeof(priv->universal_channel)); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 474 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 475 | 	priv->universal_channel[i].nrcfp = | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 476 | 	    sizeof(channel_freq_power_UN_BG) / size; | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 477 | 	lbs_deb_11d("BG-band nrcfp %d\n", | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 478 | 	       priv->universal_channel[i].nrcfp); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 479 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 480 | 	priv->universal_channel[i].CFP = channel_freq_power_UN_BG; | 
 | 481 | 	priv->universal_channel[i].valid = 1; | 
 | 482 | 	priv->universal_channel[i].region = UNIVERSAL_REGION_CODE; | 
 | 483 | 	priv->universal_channel[i].band = band; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 484 | 	i++; | 
 | 485 |  | 
 | 486 | 	return 0; | 
 | 487 | } | 
 | 488 |  | 
 | 489 | /** | 
 | 490 |  *  @brief This function implements command CMD_802_11D_DOMAIN_INFO | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 491 |  *  @param priv       pointer to struct lbs_private | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 492 |  *  @param cmd        pointer to cmd buffer | 
 | 493 |  *  @param cmdno      cmd ID | 
 | 494 |  *  @param cmdOption  cmd action | 
 | 495 |  *  @return 	      0 | 
 | 496 | */ | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 497 | int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 498 | 				 struct cmd_ds_command *cmd, u16 cmdno, | 
 | 499 | 				 u16 cmdoption) | 
 | 500 | { | 
 | 501 | 	struct cmd_ds_802_11d_domain_info *pdomaininfo = | 
 | 502 | 	    &cmd->params.domaininfo; | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 503 | 	struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain; | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 504 | 	u8 nr_subband = priv->domainreg.nr_subband; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 505 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 506 | 	lbs_deb_enter(LBS_DEB_11D); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 507 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 508 | 	lbs_deb_11d("nr_subband=%x\n", nr_subband); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 509 |  | 
 | 510 | 	cmd->command = cpu_to_le16(cmdno); | 
 | 511 | 	pdomaininfo->action = cpu_to_le16(cmdoption); | 
| Dan Williams | 0aef64d | 2007-08-02 11:31:18 -0400 | [diff] [blame] | 512 | 	if (cmdoption == CMD_ACT_GET) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 513 | 		cmd->size = | 
 | 514 | 		    cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN); | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 515 | 		lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, | 
| Holger Schurig | c2df2ef | 2007-12-07 15:30:44 +0000 | [diff] [blame] | 516 | 			le16_to_cpu(cmd->size)); | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 517 | 		goto done; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 518 | 	} | 
 | 519 |  | 
 | 520 | 	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 521 | 	memcpy(domain->countrycode, priv->domainreg.countrycode, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 522 | 	       sizeof(domain->countrycode)); | 
 | 523 |  | 
 | 524 | 	domain->header.len = | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 525 | 	    cpu_to_le16(nr_subband * sizeof(struct ieee_subbandset) + | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 526 | 			     sizeof(domain->countrycode)); | 
 | 527 |  | 
 | 528 | 	if (nr_subband) { | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 529 | 		memcpy(domain->subband, priv->domainreg.subband, | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 530 | 		       nr_subband * sizeof(struct ieee_subbandset)); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 531 |  | 
 | 532 | 		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + | 
| Dan Williams | 8362cd4 | 2007-08-03 09:40:55 -0400 | [diff] [blame] | 533 | 					     le16_to_cpu(domain->header.len) + | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 534 | 					     sizeof(struct mrvl_ie_header) + | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 535 | 					     S_DS_GEN); | 
 | 536 | 	} else { | 
 | 537 | 		cmd->size = | 
 | 538 | 		    cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN); | 
 | 539 | 	} | 
 | 540 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 541 | 	lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, le16_to_cpu(cmd->size)); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 542 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 543 | done: | 
 | 544 | 	lbs_deb_enter(LBS_DEB_11D); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 545 | 	return 0; | 
 | 546 | } | 
 | 547 |  | 
 | 548 | /** | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 549 |  *  @brief This function parses countryinfo from AP and download country info to FW | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 550 |  *  @param priv    pointer to struct lbs_private | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 551 |  *  @param resp    pointer to command response buffer | 
 | 552 |  *  @return 	   0; -1 | 
 | 553 |  */ | 
| Holger Schurig | e98a88d | 2008-03-19 14:25:58 +0100 | [diff] [blame] | 554 | int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 555 | { | 
| David Woodhouse | 981f187 | 2007-05-25 23:36:54 -0400 | [diff] [blame] | 556 | 	struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp; | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 557 | 	struct mrvl_ie_domain_param_set *domain = &domaininfo->domain; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 558 | 	u16 action = le16_to_cpu(domaininfo->action); | 
 | 559 | 	s16 ret = 0; | 
 | 560 | 	u8 nr_subband = 0; | 
 | 561 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 562 | 	lbs_deb_enter(LBS_DEB_11D); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 563 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 564 | 	lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 565 | 		(int)le16_to_cpu(resp->size)); | 
 | 566 |  | 
| David Woodhouse | 981f187 | 2007-05-25 23:36:54 -0400 | [diff] [blame] | 567 | 	nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / | 
| Dan Williams | 75b6a61 | 2009-05-22 20:03:09 -0400 | [diff] [blame] | 568 | 		      sizeof(struct ieee_subbandset); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 569 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 570 | 	lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 571 |  | 
 | 572 | 	if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) { | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 573 | 		lbs_deb_11d("Invalid Numrer of Subband returned!!\n"); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 574 | 		return -1; | 
 | 575 | 	} | 
 | 576 |  | 
 | 577 | 	switch (action) { | 
| Dan Williams | 0aef64d | 2007-08-02 11:31:18 -0400 | [diff] [blame] | 578 | 	case CMD_ACT_SET:	/*Proc Set action */ | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 579 | 		break; | 
 | 580 |  | 
| Dan Williams | 0aef64d | 2007-08-02 11:31:18 -0400 | [diff] [blame] | 581 | 	case CMD_ACT_GET: | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 582 | 		break; | 
 | 583 | 	default: | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 584 | 		lbs_deb_11d("Invalid action:%d\n", domaininfo->action); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 585 | 		ret = -1; | 
 | 586 | 		break; | 
 | 587 | 	} | 
 | 588 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 589 | 	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 590 | 	return ret; | 
 | 591 | } | 
 | 592 |  | 
 | 593 | /** | 
 | 594 |  *  @brief This function parses countryinfo from AP and download country info to FW | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 595 |  *  @param priv    pointer to struct lbs_private | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 596 |  *  @return 	   0; -1 | 
 | 597 |  */ | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 598 | int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv, | 
| Dan Williams | e76850d | 2007-05-25 17:09:41 -0400 | [diff] [blame] | 599 |                                         struct bss_descriptor * bss) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 600 | { | 
 | 601 | 	int ret; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 602 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 603 | 	lbs_deb_enter(LBS_DEB_11D); | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 604 | 	if (priv->enable11d) { | 
 | 605 | 		memset(&priv->parsed_region_chan, 0, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 606 | 		       sizeof(struct parsed_region_chan_11d)); | 
| Dan Williams | e76850d | 2007-05-25 17:09:41 -0400 | [diff] [blame] | 607 | 		ret = parse_domain_info_11d(&bss->countryinfo, 0, | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 608 | 					       &priv->parsed_region_chan); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 609 |  | 
 | 610 | 		if (ret == -1) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 611 | 			lbs_deb_11d("error parsing domain_info from AP\n"); | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 612 | 			goto done; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 613 | 		} | 
 | 614 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 615 | 		memset(&priv->domainreg, 0, | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 616 | 		       sizeof(struct lbs_802_11d_domain_reg)); | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 617 | 		generate_domain_info_11d(&priv->parsed_region_chan, | 
 | 618 | 				      &priv->domainreg); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 619 |  | 
 | 620 | 		ret = set_domain_info_11d(priv); | 
 | 621 |  | 
 | 622 | 		if (ret) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 623 | 			lbs_deb_11d("error setting domain info\n"); | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 624 | 			goto done; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 625 | 		} | 
 | 626 | 	} | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 627 | 	ret = 0; | 
 | 628 |  | 
 | 629 | done: | 
 | 630 | 	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); | 
 | 631 | 	return ret; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 632 | } | 
 | 633 |  | 
 | 634 | /** | 
 | 635 |  *  @brief This function generates 11D info from user specified regioncode and download to FW | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 636 |  *  @param priv    pointer to struct lbs_private | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 637 |  *  @return 	   0; -1 | 
 | 638 |  */ | 
| Holger Schurig | 69f9032 | 2007-11-23 15:43:44 +0100 | [diff] [blame] | 639 | int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 640 | { | 
 | 641 | 	int ret; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 642 | 	struct region_channel *region_chan; | 
 | 643 | 	u8 j; | 
 | 644 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 645 | 	lbs_deb_enter(LBS_DEB_11D); | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 646 | 	lbs_deb_11d("curbssparams.band %d\n", priv->curbssparams.band); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 647 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 648 | 	if (priv->enable11d) { | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 649 | 		/* update parsed_region_chan_11; dnld domaininf to FW */ | 
 | 650 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 651 | 		for (j = 0; j < ARRAY_SIZE(priv->region_channel); j++) { | 
 | 652 | 			region_chan = &priv->region_channel[j]; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 653 |  | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 654 | 			lbs_deb_11d("%d region_chan->band %d\n", j, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 655 | 			       region_chan->band); | 
 | 656 |  | 
 | 657 | 			if (!region_chan || !region_chan->valid | 
 | 658 | 			    || !region_chan->CFP) | 
 | 659 | 				continue; | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 660 | 			if (region_chan->band != priv->curbssparams.band) | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 661 | 				continue; | 
 | 662 | 			break; | 
 | 663 | 		} | 
 | 664 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 665 | 		if (j >= ARRAY_SIZE(priv->region_channel)) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 666 | 			lbs_deb_11d("region_chan not found, band %d\n", | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 667 | 			       priv->curbssparams.band); | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 668 | 			ret = -1; | 
 | 669 | 			goto done; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 670 | 		} | 
 | 671 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 672 | 		memset(&priv->parsed_region_chan, 0, | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 673 | 		       sizeof(struct parsed_region_chan_11d)); | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 674 | 		lbs_generate_parsed_region_chan_11d(region_chan, | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 675 | 						     &priv-> | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 676 | 						     parsed_region_chan); | 
 | 677 |  | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 678 | 		memset(&priv->domainreg, 0, | 
| Holger Schurig | 1007832 | 2007-11-15 18:05:47 -0500 | [diff] [blame] | 679 | 		       sizeof(struct lbs_802_11d_domain_reg)); | 
| David Woodhouse | aa21c00 | 2007-12-08 20:04:36 +0000 | [diff] [blame] | 680 | 		generate_domain_info_11d(&priv->parsed_region_chan, | 
 | 681 | 					 &priv->domainreg); | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 682 |  | 
 | 683 | 		ret = set_domain_info_11d(priv); | 
 | 684 |  | 
 | 685 | 		if (ret) { | 
| Holger Schurig | ece5619 | 2007-08-02 11:53:06 -0400 | [diff] [blame] | 686 | 			lbs_deb_11d("error setting domain info\n"); | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 687 | 			goto done; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 688 | 		} | 
 | 689 |  | 
 | 690 | 	} | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 691 | 	ret = 0; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 692 |  | 
| Holger Schurig | 9012b28 | 2007-05-25 11:27:16 -0400 | [diff] [blame] | 693 | done: | 
 | 694 | 	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); | 
 | 695 | 	return ret; | 
| Marcelo Tosatti | 876c9d3 | 2007-02-10 12:25:27 -0200 | [diff] [blame] | 696 | } |