1#include <stdlib.h> 2#include <stdio.h> 3#include <string.h> 4#include <unistd.h> 5#include <sys/types.h> 6#include <sys/ioctl.h> 7#include <sys/socket.h> 8#include <net/if.h> 9#include <netinet/in.h> 10#include <arpa/inet.h> 11#include <net/if_arp.h> 12#include <time.h> 13#include <shutils.h> 14#include <rc.h> 15#include <wlioctl.h> 16#include <bcmnvram.h> 17 18#define A_UCHAR unsigned char 19#define A_UINT8 unsigned char 20#define A_UINT16 unsigned int 21#define A_UINT32 unsigned long 22 23 24/*----------------------------------------------------------------*/ 25/* Magic number, a quick test to see we're getting the desired struct */ 26#define P80211_IOCTL_MAGIC (0x4a2d464dUL) 27#define MSG_BUFF_LEN 4000 28#define WLAN_DEVNAMELEN_MAX 16 29 30 31#define CHANNEL_CW_INT 0x0001 // CW interference detected on the channel 32#define CHANNEL_RADAR_INT 0x0002 // Radar interference detected on the channel 33#define CHANNEL_BUSY 0x0004 // Busy, occupied directly or overlap from BSS on adjoining channel 34#define CHANNEL_TURBO 0x0100 // Turbo Channel 35#define CHANNEL_CCK 0x0200 // CCK channel 36#define CHANNEL_OFDM 0x0400 // OFDM channel 37#define CHANNEL_2GHZ 0x0800 // 2 GHz spectrum channel. 38#define CHANNEL_5GHZ 0x1000 // 5 GHz spectrum channel 39#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) 40#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) 41#define CHANNEL_PUREG (CHANNEL_2GHZ|CHANNEL_OFDM) 42#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO) 43#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_5GHZ|CHANNEL_2GHZ|CHANNEL_TURBO) 44#define CHANNEL_DEFAULT (CHANNEL_5GHZ|CHANNEL_OFDM) // default is normal 11a mode 45#define MAX_REG_DOM_NAME_SIZE 10 // Max string size of reg dom name inc NULL 46 47enum { 48 FCC = 0, 49 MKK, 50 ETSI 51}; 52 53#ifdef REMOVE_WL600 54enum { 55 DEBUG_REG_DMN = 0, 56 FCC1, 57 FCC2, 58 MKK1, 59 ETSI1, 60 ETSI2, 61 ETSI3, 62 ETSI4, 63 ETSI5, 64 ETSI6, 65 APL1, 66 APL2, 67 APL3, 68 APL4 69}; 70 71#define APL5 APL4 72 73enum { 74 WORLD = 1, 75 FCCA, 76 MKKA, 77 APLA, 78 APLB, 79 APLC, 80 ETSIA, 81 ETSIB, 82 ETSIC, 83}; 84#endif 85 86/* Enumerated Regulatory Domain Information */ 87/* Enumerated Regulatory Domain Information */ 88enum EnumRd { 89 /* 90 * The following regulatory domain definitions are 91 * found in the EEPROM. Each regulatory domain 92 * can operate in either a 5GHz or 2.4GHz wireless mode or 93 * both 5GHz and 2.4GHz wireless modes. 94 * In general, the value holds no special 95 * meaning and is used to decode into either specific 96 * 2.4GHz or 5GHz wireless mode for that particular 97 * regulatory domain. 98 * 99 */ 100 NO_ENUMRD = 0x00, 101 FCC1_FCCA = 0x10, // USA 102 FCC1_WORLD = 0x11, // Hong Kong 103 104 FCC2_FCCA = 0x20, // Canada 105 FCC2_WORLD = 0x21, // Australia 106 FCC2_ETSIC = 0x22, 107 108 ETSI1_WORLD = 0x37, 109 ETSI3_ETSIA = 0x32, // France 110 ETSI2_WORLD = 0x35, // Germany 111 ETSI3_WORLD = 0x36, // Austria 112 ETSI4_WORLD = 0x30, 113 ETSI4_ETSIC = 0x38, 114 ETSI1_ETSIB = 0x39, // Special for ISRAEL 115 116 MKK1_MKKA = 0x40, // Japan 117 MKK1_MKKB = 0x41, // Japan 118 APL4_WORLD = 0x42, // Singapore 119 APL3_FCCA = 0x43, 120 APL1_APLB = 0x44, // China 121 APL2_WORLD = 0x45, // Korea 122 APL2_APLC = 0x46, 123 APL3_WORLD = 0x47, 124 125 APL1_WORLD = 0x52, // Latin America 126 APL1_FCCA = 0x53, // Mexico 127 APL1_APLA = 0x54, // Chile 128 APL1_ETSIC = 0x55, 129 130 131 /* 132 * Super Domain Definitions 133 */ 134 WOR0_WORLD = 0x060, /* World0 (WO0 SKU) */ 135 WOR1_WORLD = 0x061, /* World1 (WO1 SKU) */ 136 WOR2_WORLD = 0x062, /* World2 (WO2 SKU) */ 137 WOR3_WORLD = 0x063, /* World3 (WO3 SKU) */ 138 WOR4_WORLD = 0x064, /* World4 (WO4 SKU) */ 139 APL5_WORLD = 0x065, /* Asia/Latin (AL1 SKU) */ 140 APL5_APLB = 0x066, /* China (CN1 SKU) */ 141 142 /* "Regulatory domains ending in a number (e.g. APL1, 143 * MKK1, ETSI4,etc) apply to 5GHz channel and power information. 144 * Reg. domains ending in a letter (e.g. APLA, FCCA, etc.) 145 * apply to 2.4GHz channel and power information." 146 */ 147 148 /* 149 * The following wireless modes are either 2.4 or 5GHz 150 */ 151 APL1 = 0x0150, /* LAT & Asia */ 152 APL2 = 0x0250, /* LAT & Asia */ 153 APL3 = 0x0350, /* Taiwan */ 154 APL4 = 0x0450, /* Singapore */ 155 156 ETSI1 = 0x0130, /* Europe & others */ 157 ETSI2 = 0x0230, /* Europe & others */ 158 ETSI3 = 0x0330, /* Europe & others */ 159 ETSI4 = 0x0430, /* Europe & others */ 160 ETSIA = 0x0A30, /* France */ 161 ETSIB = 0x0B30, /* Israel */ 162 ETSIC = 0x0C30, /* Latin America */ 163 164 165 FCC1 = 0x0110, /* US & others */ 166 FCC2 = 0x0120, /* Canada, Australia & New Zealand */ 167 FCCA = 0x0A10, 168 169 APLA = 0x0A50, /* Chile */ 170 APLB = 0x0B50, /* China */ 171 APLC = 0x0C50, /* South Korea */ 172 173 MKK1 = 0x0140, /* Japan */ 174 MKKA = 0x0A40, /* Japan */ 175 176 WORLD = 0x0199, 177 DEBUG_REG_DMN = 0x01ff 178}; 179 180#define TURBO_CHANNEL_SEPARATION (8) 181#define OFDM5_CHANNEL_SEPARATION (4) 182#define CCK_CHANNEL_SEPARATION (1) 183 184#define MHZ2IEEE_CH(mhz) ( ( mhz - 5000 ) / 5 ) 185#define FCC_OUTDOOR_FIRST_FREQ 5725 186 187/* 5 GHz table settings */ 188 189typedef struct regDmnEnumChannelGroup { 190 A_UINT16 lowChannel; // Low Channel center in MHz 191 A_UINT16 highChannel; // High Channel center in MHz 192} REG_DMN_ENUM_CHANNEL_GROUP; 193 194/* TODO: Add EIRP emission addition */ 195/* TODO: Define test groups for 2.4 */ 196 197#define MAX_CHANNEL_GROUPS 2 198 199typedef struct regDmnEnumFreqTable { 200 A_UINT16 regDmnEnum; 201 A_UINT16 entries; 202 A_UINT8 testGroup; 203 A_UCHAR name[8]; 204 REG_DMN_ENUM_CHANNEL_GROUP chanGroup[MAX_CHANNEL_GROUPS]; 205} REG_DMN_ENUM_FREQ_TABLE; 206 207typedef struct CountryCodeToEnumRd { 208 A_UINT16 regDmnEnum; 209 const A_UCHAR isoName[3]; 210 const A_UCHAR name[16]; 211} COUNTRY_CODE_TO_ENUM_RD; 212 213 214 215/* 216 * Regulatory Domain Tables 217 * 218 * Tables have entries ordered with AP/Adhoc planting preference in mind. 219 * -Indoor channels are ordered before outdoor 220 * -Higher power level indoor channels are first 221 */ 222 223static const REG_DMN_ENUM_FREQ_TABLE regDmnEnum5[] = { 224 {DEBUG_REG_DMN, 2, FCC, "NONE", { 225 {36 , 64}, 226 {149,165}}}, 227 228 {FCC1, 2, FCC, "FCC1", { 229 {36 , 64}, 230 {149,165}}}, 231 232 {FCC2, 2, FCC, "FCC2", { 233 {36 , 64}, 234 {149,165}}}, 235 236 {MKK1, 1, MKK, "MKK1", { 237 { 34, 46}, 238 { 0, 0}}}, 239 240 {ETSI1, 2, ETSI, "ETSI1", { 241 { 36, 64}, 242 {100,140}}}, 243 244 {ETSI2, 1, ETSI, "ETSI2", { 245 { 36, 48}, 246 { 0, 0}}}, 247 248 249 {ETSI3, 1, ETSI, "ETSI3", { 250 { 36, 64}, 251 { 0, 0}}}, 252 253 {ETSI4, 1, ETSI, "ETSI4", { 254 { 36, 64}, 255 { 0, 0}}}, 256 257 258 {APL1, 1, FCC, "APL1", { 259 {149,165}, 260 { 0, 0}}}, 261 262 {APL2, 1, FCC, "APL2", { 263 {149,161}, 264 { 0, 0}}}, 265 266 {APL3, 2, FCC, "APL3", { 267 { 52, 64}, 268 {149,165}}}, 269 270 {APL4, 2, FCC, "APL4", { 271 { 36, 48}, 272 {149,165}}}, 273}; 274 275static const REG_DMN_ENUM_FREQ_TABLE regDmnEnum5Turbo[] = { 276 {DEBUG_REG_DMN, 2, 0, "NONE", { 277 {42, 58}, 278 {152,160}}}, 279 280 {FCC1, 2, FCC, "FCC1", { 281 {42, 58}, 282 {152,160}}} 283}; 284 285/* "Worldwide", 1-13 286 "Thailand", "Israel", "Jordan", "China", "Japan", "USA", "Europe", "USA Low", "Japan High", "All" */ 287 288static const char *br_name[] = 289{ 290 "All", 291 "Europe", 292 "USA", 293 "Japan", 294 "Europe", 295 "Europe", 296 "USA", 297 "Jordan", 298 "Israel", 299 "Europe" 300}; 301 302static const REG_DMN_ENUM_FREQ_TABLE regDmnEnum2[] = { 303 {DEBUG_REG_DMN, 1, 0, "NONE", { 304 { 1, 14}, 305 { 0, 0}}}, 306 307 {WORLD, 1, FCC, "WORLD", { 308 { 1, 13}, 309 { 0, 0}}}, 310 311 {FCCA, 1, FCC, "FCCA", { 312 { 1, 11}, 313 { 0, 0}}}, 314 315 {MKKA, 1, MKK, "MKKA", { 316 { 1, 14}, 317 { 0, 0}}}, 318 319 {APLA, 1, FCC, "APLA", { 320 { 1, 13}, 321 { 0, 0}}}, 322 323 {APLB, 1, FCC, "APLB", { 324 { 1, 13}, 325 { 0, 0}}}, 326 327 {APLC, 1, FCC, "APLC", { 328 { 1, 12}, 329 { 0, 0}}}, 330 331 {ETSIA, 1, ETSI, "ETSIA", { 332 { 10, 13}, 333 { 0, 0}}}, 334 335 {ETSIB, 1, ETSI, "ETSIB", { 336 { 5, 7}, 337 { 0, 0}}}, 338 339 {ETSIC, 1, ETSI, "ETSIC", { 340 { 1, 13}, 341 { 0, 0}}}, 342 343 344}; 345 346#define RDMAPPING_SIZE 32 347 348static const A_UINT16 RDMapping[RDMAPPING_SIZE][3] = 349{ 350 {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN}, 351 {FCC2_FCCA, FCC2, FCCA }, 352 {FCC2_WORLD, FCC2, WORLD }, 353 {FCC2_ETSIC, FCC2, ETSIC }, 354 355 {ETSI1_WORLD, ETSI1, WORLD }, 356 {ETSI2_WORLD, ETSI2, WORLD }, 357 {ETSI3_WORLD, ETSI3, WORLD }, 358 {ETSI4_WORLD, ETSI4, WORLD }, 359 360 {ETSI3_ETSIA, ETSI3, ETSIA }, 361 {ETSI4_ETSIC, ETSI4, ETSIC }, 362 363 {FCC1_WORLD, FCC1, WORLD }, 364 {FCC1_FCCA, FCC1, FCCA }, 365 366 {APL1_WORLD, APL1, WORLD }, 367 {APL2_WORLD, APL2, WORLD }, 368 {APL3_WORLD, APL3, WORLD }, 369 {APL4_WORLD, APL4, WORLD }, 370 371 {APL1_APLA, APL1, APLA }, 372 {APL1_APLB, APL1, APLB }, 373 374 {APL1_FCCA, APL1, FCCA }, 375 {APL3_FCCA, APL3, FCCA }, 376 377 {APL1_ETSIC, APL1, ETSIC }, 378 {APL2_APLC, APL2, APLC }, 379 380 {MKK1_MKKA, MKK1, MKKA }, 381 {MKK1_MKKB, MKK1, MKKA }, 382 383 {ETSI1_ETSIB, ETSI1, ETSIB }, 384 385 /* 386 * The area below is reserved for super domains 387 */ 388 {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD }, 389 {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD }, 390 {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD }, 391 {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD }, 392 {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD }, 393 {APL5_WORLD, APL5_WORLD, APL5_WORLD }, 394 {APL5_APLB, APL5_APLB, APL5_APLB } 395}; 396 397static const COUNTRY_CODE_TO_ENUM_RD allCountries[] = { 398 {0x00, "DB", "NONE" }, 399 {APL1_ETSIC, "AR", "ARGENTINA" }, 400 {FCC2_WORLD, "AU", "AUSTRALIA" }, 401 {ETSI4_WORLD, "AT", "AUSTRIA" }, 402 {ETSI4_WORLD, "BE", "BELGUIM" }, 403 {APL1_ETSIC, "BR", "BRAZIL" }, 404 {FCC2_FCCA, "CA", "CANADA" }, 405 {APL1_APLA, "CL", "CHILE" }, 406 {ETSI4_WORLD, "CZ", "CZECH_REPUBLIC"}, 407 {APL1_WORLD, "CN", "CHINA" }, 408 {APL1_ETSIC, "CO", "COLOMBIA" }, 409 {ETSI4_WORLD, "DK", "DENMARK" }, 410 {APL2_WORLD, "EC", "ECUADOR" }, 411 {ETSI4_WORLD, "FI", "FINLAND" }, 412 {ETSI3_ETSIA, "FR", "FRANCE" }, 413 {ETSI4_WORLD, "DE", "GERMANY" }, 414 {ETSI4_WORLD, "GR", "GREECE" }, 415 {FCC1_WORLD, "HK", "HONG_KONG" }, 416 {ETSI4_ETSIC, "HU", "HUNGARY" }, 417 {ETSI4_WORLD, "IS", "ICELAND" }, 418 {ETSI4_WORLD, "IE", "IRELAND" }, 419 {ETSI2_WORLD, "IT", "ITALY" }, 420 {MKK1_MKKA, "JP", "JAPAN" }, 421 {APL2_APLC, "KR", "KOREA_REPUBLIC"}, 422 {ETSI4_WORLD, "LI", "LIECHTENSTEIN"}, 423 {ETSI4_WORLD, "LT", "LITHUANIA" }, 424 {ETSI4_WORLD, "LU", "LUXEMBOURG" }, 425 {FCC1_WORLD, "MO", "MACAU" }, 426 {APL1_WORLD, "MX", "MEXICO" }, 427 {ETSI4_WORLD, "MC", "MONACO" }, 428 {ETSI1_WORLD, "NL", "NETHERLANDS" }, 429 {FCC2_ETSIC, "NZ", "NEW_ZEALAND" }, 430 {ETSI3_WORLD, "NO", "NORWAY" }, 431 {APL1_WORLD, "PA", "PANAMA" }, 432 {APL1_WORLD, "PE", "PERU" }, 433 {FCC1_WORLD, "PH", "PHILIPPINES" }, 434 {ETSI2_WORLD, "PL", "POLAND" }, 435 {ETSI4_WORLD, "PT", "PORTUGAL" }, 436 {FCC1_FCCA, "PR", "PUERTO_RICO" }, 437 {APL4_WORLD, "SG", "SINGAPORE" }, 438 {ETSI4_WORLD, "ZA", "SOUTH_AFRICA"}, 439 {ETSI4_WORLD, "ES", "SPAIN" }, 440 {ETSI4_WORLD, "SE", "SWEDEN" }, 441 {ETSI2_WORLD, "CH", "SWITZERLAND" }, 442 {APL3_WORLD, "TW", "TAIWAN" }, 443 {APL2_WORLD, "TH", "THAILAND" }, 444 {ETSI2_WORLD, "TR", "TURKEY" }, 445 {ETSI4_WORLD, "GB", "UNITED_KINGDOM"}, 446 {FCC1_FCCA, "US", "UNITED_STATES" }, 447 {APL1_ETSIC, "VE", "VENEZUELA" }, 448 {ETSI1_ETSIB, "IR", "ISRAEL" } 449}; 450 451static const REG_DMN_ENUM_FREQ_TABLE * 452wlanGetCcTable(A_UINT16 channelFlags) 453{ 454 if (channelFlags & CHANNEL_2GHZ) 455 { 456 return (®DmnEnum2[0]); 457 } 458 else if (channelFlags & CHANNEL_5GHZ) { 459 if (channelFlags & CHANNEL_TURBO) 460 { 461 return(®DmnEnum5Turbo[0]); 462 } else { 463 return(®DmnEnum5[0]); 464 } 465 } 466 else { 467 // either 2 or 5 GHz flags must be set 468 //ASSERT(0); 469 return NULL; 470 } 471} 472 473static int 474wlanGetCcEntries(A_UINT16 channelFlags) 475{ 476 if (channelFlags & CHANNEL_2GHZ) { 477 return(sizeof(regDmnEnum2)/sizeof(REG_DMN_ENUM_FREQ_TABLE)); 478 } 479 else if (channelFlags & CHANNEL_5GHZ) { 480 if (channelFlags & CHANNEL_TURBO) { 481 return(sizeof(regDmnEnum5Turbo)/sizeof(REG_DMN_ENUM_FREQ_TABLE)); 482 } else { 483 return(sizeof(regDmnEnum5)/sizeof(REG_DMN_ENUM_FREQ_TABLE)); 484 } 485 } 486 else { 487 // either 2 or 5 GHz flags must be set 488 //ASSERT(0); 489 return 0; 490 } 491} 492 493void ParseReg(char *regDmnName, A_UINT16 *regDmnCode, char *country) 494{ 495 char reg[5]; 496 497 if (strlen(regDmnName)>=4) // With Country Code 498 { 499 strncpy(reg, regDmnName, 4); 500 reg[4] = 0; 501 sscanf(reg, "%x", regDmnCode); 502 if (country!=NULL) 503 strcpy(country, regDmnName+4); 504 } 505 else 506 { 507 *regDmnCode = 0x00; 508 regDmnName = NULL; 509 } 510} 511 512 513/*********************************************************** 514 * RefreshBRCountry 515 * 516 * Print out the channel list based only on the given reg 517 * domain and turbo mode 518 */ 519void 520RefreshBRCountry(char *regDmnName, char *country, char *country_code) 521{ 522 A_UINT16 regDmnEnum, channelFlags, regDmnCode; 523 int i, j, regDmnEnumEntries, newPrint = 0; 524 const REG_DMN_ENUM_FREQ_TABLE *pCcTable; 525 A_UINT16 lowChannel = 24, highChannel = 220; 526 527 528 /* Add by ChenI to translate regulatory domain code */ 529 ParseReg(regDmnName, ®DmnCode, country_code); 530 531 dprintf("Domain Code: %x\n", regDmnCode); 532 regDmnEnum = regDmnCode; 533 534 for(i=0; i<RDMAPPING_SIZE; i++) 535 { 536 if (RDMapping[i][0] == regDmnCode) 537 break; 538 } 539 540 if (i==RDMAPPING_SIZE) i=0; 541 542 regDmnEnum = RDMapping[i][2]; 543 lowChannel = 1; 544 highChannel = 14; 545 channelFlags = CHANNEL_B; 546 547 pCcTable = wlanGetCcTable(channelFlags); 548 regDmnEnumEntries = wlanGetCcEntries(channelFlags); 549 550 /* Search through Regulatory Domain (Enum) table for a match */ 551 for (i = 0; i < regDmnEnumEntries; i++) 552 { 553 if (pCcTable[i].regDmnEnum == regDmnEnum) 554 { 555 dprintf("%s\n",br_name[i]); 556 strcpy(country, br_name[i]); 557 return; 558 } 559 } 560 strcpy(country, "WorldWide"); 561 return; 562} 563 564 565/*********************************************************** 566 * RefreshChannelList 567 * 568 * Print out the channel list based only on the given reg 569 * domain and turbo mode 570 */ 571void 572RefreshChannelList(char *regDmnName, A_UINT16 current, A_UINT16 chanList[]) 573{ 574 A_UINT16 regDmnEnum, channelFlags, regDmnCode; 575 int i, j, regDmnEnumEntries, newPrint = 0; 576 const REG_DMN_ENUM_FREQ_TABLE *pCcTable; 577 A_UINT16 channelSpread, searchChannel, firstChannel; 578 A_UINT16 lowChannel = 24, highChannel = 220; 579 A_UINT16 maxRdChannel = 220; 580 A_UINT16 chanIdx=0; 581 582 583 /* Add by ChenI to translate regulatory domain code */ 584 ParseReg(regDmnName, ®DmnCode, NULL); 585 586 dprintf("Domain Code: %x\n", regDmnCode); 587 588 regDmnEnum = regDmnCode; 589 590 for(i=0; i<RDMAPPING_SIZE; i++) 591 { 592 if (RDMapping[i][0] == regDmnCode) 593 break; 594 } 595 596 if (i==RDMAPPING_SIZE) i=0; 597 598 regDmnEnum = RDMapping[i][2]; 599 lowChannel = 1; 600 highChannel = 14; 601 channelFlags = CHANNEL_B; 602 603 pCcTable = wlanGetCcTable(channelFlags); 604 regDmnEnumEntries = wlanGetCcEntries(channelFlags); 605 channelSpread = CCK_CHANNEL_SEPARATION; 606 607 608 firstChannel = 0; 609 /* Search through Regulatory Domain (Enum) table for a match */ 610 for (i = 0; i < regDmnEnumEntries; i++) { 611 if (pCcTable[i].regDmnEnum == regDmnEnum) { 612 for (j = 0; j < pCcTable[i].entries; j++) 613 { 614 /* Find this channel's entry */ 615 for(searchChannel = pCcTable[i].chanGroup[j].lowChannel; 616 searchChannel <= pCcTable[i].chanGroup[j].highChannel; 617 searchChannel += channelSpread) 618 { 619 if ((searchChannel >= lowChannel) && (searchChannel <= highChannel) && (searchChannel <= maxRdChannel)) 620 { 621 chanList[chanIdx++] = searchChannel; 622 chanList[chanIdx] = -1; 623 624 if (firstChannel==0) 625 { 626 firstChannel = searchChannel; 627 } 628 629 if (current!=999) 630 { 631 if (current == searchChannel) 632 { 633 dprintf("%d", current); 634 return; 635 } 636 } 637 else 638 { 639 dprintf("%d\n", searchChannel); 640 } 641 } 642 } 643 } 644 645 if (current!=999) 646 { 647 /* Find the middle channel for default value */ 648 if (chanIdx!=0) 649 firstChannel = chanList[chanIdx/2]; 650 651 dprintf("%d\n", firstChannel); 652 } 653 return; 654 } 655 } 656} 657 658 659void convert_country(void) 660{ 661#ifdef REMOVE 662 char *countrylist[]= 663 {"Worldwide", "Thailand", "Israel", "Jordan", "China", "Japan", "USA", 664 "Europe", "USA Low", "Japan High", "All", NULL}; 665 666 char country[32], country_code[32]; 667 int i; 668 669 strcpy(country, nvram_safe_get("wl_country")); 670 671 i=0; 672 while(countrylist[i]!=NULL) 673 { 674 if (strcmp(countrylist[i], country)==0) 675 { 676 break; 677 } 678 i++; 679 } 680 681 if (countrylist[i]==NULL) 682 { 683 RefreshBRCountry(nvram_safe_get("regulation_domain"), country, country_code); 684 nvram_set("wl_country", country); 685 if (strlen(country_code)<2) 686 nvram_set("wl_country_code", "ALL"); 687 else 688 nvram_set("wl_country_code", country_code); 689 } 690#endif 691 A_UINT16 chanList[16]; 692 char chanListStr[64]; 693 char reg[32]; 694 int i; 695 696 strcpy(reg, nvram_safe_get("regulation_domain")); 697 698 if (strlen(reg)>4) // With Country Code 699 { 700 nvram_set("wl_country_code", reg + 4); 701 } 702 else nvram_set("wl_country_code", "ALL"); 703 704 RefreshChannelList(nvram_safe_get("regulation_domain"), 999, chanList); 705 706 i=0; 707 708 *chanListStr='\0'; 709 while(chanList[i]!=-1) 710 { 711 if (i==0) sprintf(chanListStr, "%d", chanList[i]); 712 else sprintf(chanListStr, "%s %d", chanListStr, chanList[i]); 713 i++; 714 //printf("chan :%s\n", chanListStr); 715 } 716 nvram_set("wl_chan_list", chanListStr); 717} 718 719#define MAXBUF 32 720 721void sync_mac(char *devname, char *mac) 722{ 723 int cmd, result, i, j; 724 char buf[MAXBUF], macstr[32], s[3]; 725 unsigned char t; 726 srom_rw_t *srom; 727 728 if (strlen(mac)!=17) return; 729 730 //printf("dev: %s, mac : %s\n", devname, mac); 731 732 s[2] = 0; 733 734 for (i=0; i<6; i++) 735 { 736 strncpy(s, mac+i*3, 2); 737 t = (unsigned char)strtoul(s, NULL, 16); 738 if (i%2==0) macstr[i+1] = t; 739 else macstr[i-1] = t ; 740 } 741 742 srom=buf; 743 srom->byteoff=72; 744 srom->nbytes=6; 745 746 if ( (result = wl_ioctl(devname, WLC_GET_SROM, buf, MAXBUF)) == 0 ) 747 { 748 for(i=0;i<6;i++) 749 { 750 //printf(" %x %x \n", buf[8+i], macstr[i]); 751 } 752 753 if (memcmp(macstr, buf+8, 6)!=0) 754 { 755 eval("nvram", "set", "asuscfewatchdog=1"); 756 memcpy(buf+8, macstr, 6); 757 result = wl_ioctl(devname, WLC_SET_SROM, buf, MAXBUF); 758#ifdef WL500GX_REMOVE 759 /* setup afterburner flag */ 760 wsrom_main(devname, 114, 0x20f); 761#else 762 wlan_update(); 763#endif 764 return; 765 } 766 } 767 return; 768} 769 770int 771rsrom_main(char *devname, unsigned int pos, int pflag) 772{ 773 int result; 774 unsigned short *oval; 775 char buf[MAXBUF]; 776 srom_rw_t *srom; 777 unsigned int val; 778 779 srom = buf; 780 srom->byteoff=pos; 781 srom->nbytes=2; //sizeof(val); 782 783 if ( (result = wl_ioctl(devname, WLC_GET_SROM, buf, MAXBUF)) == 0) 784 { 785 oval =(unsigned int)(buf + 8); 786 val = (unsigned int)*oval; 787 } 788 else val = 0; 789 790 if (pflag) printf("srom[%x] : %x\n", pos, val); 791 return val; 792} 793 794int 795wsrom_main(char *devname, unsigned int pos, unsigned short val) 796{ 797 int result; 798 unsigned short *oval; 799 char buf[MAXBUF]; 800 srom_rw_t *srom; 801 /* Usage srom [postion] [val in 2 byte] */ 802 dprintf("write %s srom[%x] : %x\n", devname, pos, val); 803 srom = buf; 804 srom->byteoff=pos; 805 srom->nbytes=2; //sizeof(val); 806 807 if ( (result = wl_ioctl(devname, WLC_GET_SROM, buf, MAXBUF)) == 0) 808 { 809 oval =(unsigned int)(buf + 8); 810 811 if (*oval!=val) 812 { 813 memcpy(buf+8, &val, sizeof(val)); 814 result = wl_ioctl(devname, WLC_SET_SROM, buf, MAXBUF); } 815 } 816 return 0; 817} 818 819void write_mac(char *devname, char *mac) 820{ 821 int cmd, result, i, j; 822 char buf[MAXBUF], macstr[32], s[3]; 823 unsigned char t; 824 srom_rw_t *srom; 825 826 if (strlen(mac)!=17) return; 827 828 //printf("dev: %s, mac : %s\n", devname, mac); 829 830 s[2] = 0; 831 832 for (i=0; i<6; i++) 833 { 834 strncpy(s, mac+i*3, 2); 835 t = (unsigned char)strtoul(s, NULL, 16); 836 if (i%2==0) macstr[i+1] = t; 837 else macstr[i-1] = t ; 838 } 839 840 srom=buf; 841 srom->byteoff=72; 842 srom->nbytes=6; 843 844 memcpy(buf+8, macstr, 6); 845 result = wl_ioctl(devname, WLC_SET_SROM, buf, MAXBUF); 846 return; 847} 848 849 850int 851wlan_update() 852{ 853 int result; 854 unsigned short *oval; 855 char buf[MAXBUF]; 856 srom_rw_t *srom; 857 unsigned short val; 858 859 /* update eerpom for driver 3.90.x.x */ 860 if (nvram_match("productid", "WL500g")) 861 { 862 val = rsrom_main("eth2", 104, 0); 863 if (val==0x003c) wsrom_main("eth2", 104, 0x004c);// ver 1.6 864 else if (val==0x0035) wsrom_main("eth2", 104, 0x0046); // ver 2.2 865 else wsrom_main("eth2", 104, 0x0046); 866 wsrom_main("eth2", 114, 0x0249); 867 } 868 else if(nvram_match("productid", "WL500g.Deluxe")) 869 { 870 // ver 2.2 871 wsrom_main("eth1", 104, 0x0046); 872 wsrom_main("eth1", 114, 0x0249); 873 } 874 return 0; 875} 876 877