1 #include <linux/kernel.h>
2 #include <linux/mmc/sdio_func.h>
6 #include "ks_wlan_ioctl.h"
10 #define WEP_ON_64BIT 1
11 #define WEP_ON_128BIT 2
14 #define WEP_KEY_CHARACTER 0
18 void analyze_character_wep_key(struct ks_wlan_parameter *param,
19 int wep_key_index, char *value)
22 unsigned char wep_key[26], key_length;
24 key_length = (wep_on_off == WEP_ON_64BIT) ? 5 : 13;
25 /* 64bit key_length = 5; 128bit key_length = 13; */
27 for (i = 0; i < key_length; i++) {
28 wep_key[i] = value[i];
31 if (wep_key_index < 0 || wep_key_index > 3)
34 param->wep_key[wep_key_index].size = key_length;
35 for (i = 0; i < (param->wep_key[wep_key_index].size); i++) {
36 param->wep_key[wep_key_index].val[i] = wep_key[i];
41 void analyze_hex_wep_key(struct ks_wlan_parameter *param, int wep_key_index,
44 unsigned char wep_end[26], i, j, key_length;
46 key_length = (wep_on_off == WEP_ON_64BIT) ? 10 : 26;
47 /* 64bit key_length = 10; 128bit key_length = 26; */
49 for (i = 0; i < key_length; i++) {
50 wep_end[i] = value[i];
53 for (j = 0x00; j < 0x10; j++) {
55 if (wep_end[i] == j + 0x30)
59 j + 0x37) | (wep_end[i] ==
66 for (j = 0x00; j < 0x10; j++) {
68 if (wep_end[i] == j + 0x30) {
73 j + 0x37) | (wep_end[i] ==
81 for (i = 0; i < key_length / 2; i++) {
82 wep_end[i] = wep_end[i * 2] + wep_end[(i * 2) + 1];
85 if (wep_key_index < 0 || wep_key_index > 3)
88 param->wep_key[wep_key_index].size = key_length / 2;
89 for (i = 0; i < (param->wep_key[wep_key_index].size); i++) {
90 param->wep_key[wep_key_index].val[i] = wep_end[i];
96 int rate_set_configuration(struct ks_wlan_private *priv, char *value)
100 priv->reg.tx_rate = TX_RATE_FIXED;
101 priv->reg.rate_set.size = 1;
104 case '1': /* 1M 11M 12M 18M */
105 if (*(value + 1) == '8') {
106 priv->reg.rate_set.body[0] = TX_RATE_18M;
107 } else if (*(value + 1) == '2') {
108 priv->reg.rate_set.body[0] = TX_RATE_12M | BASIC_RATE;
109 } else if (*(value + 1) == '1') {
110 priv->reg.rate_set.body[0] = TX_RATE_11M | BASIC_RATE;
112 priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
115 case '2': /* 2M 24M */
116 if (*(value + 1) == '4') {
117 priv->reg.rate_set.body[0] = TX_RATE_24M | BASIC_RATE;
119 priv->reg.rate_set.body[0] = TX_RATE_2M | BASIC_RATE;
123 priv->reg.rate_set.body[0] = TX_RATE_36M;
126 priv->reg.rate_set.body[0] = TX_RATE_48M;
128 case '5': /* 5.5M 54M */
129 if (*(value + 1) == '4') {
130 priv->reg.rate_set.body[0] = TX_RATE_54M;
132 priv->reg.rate_set.body[0] = TX_RATE_5M | BASIC_RATE;
136 priv->reg.rate_set.body[0] = TX_RATE_6M | BASIC_RATE;
139 priv->reg.rate_set.body[0] = TX_RATE_9M;
142 priv->reg.rate_set.body[6] = TX_RATE_36M;
143 priv->reg.rate_set.body[5] = TX_RATE_18M;
144 priv->reg.rate_set.body[4] = TX_RATE_24M | BASIC_RATE;
145 priv->reg.rate_set.body[3] = TX_RATE_12M | BASIC_RATE;
146 priv->reg.rate_set.body[2] = TX_RATE_6M | BASIC_RATE;
147 priv->reg.rate_set.body[1] = TX_RATE_11M | BASIC_RATE;
148 priv->reg.rate_set.body[0] = TX_RATE_2M | BASIC_RATE;
149 priv->reg.tx_rate = TX_RATE_FULL_AUTO;
150 priv->reg.rate_set.size = 7;
153 priv->reg.rate_set.body[11] = TX_RATE_54M;
154 priv->reg.rate_set.body[10] = TX_RATE_48M;
155 priv->reg.rate_set.body[9] = TX_RATE_36M;
156 priv->reg.rate_set.body[8] = TX_RATE_18M;
157 priv->reg.rate_set.body[7] = TX_RATE_9M;
158 priv->reg.rate_set.body[6] = TX_RATE_24M | BASIC_RATE;
159 priv->reg.rate_set.body[5] = TX_RATE_12M | BASIC_RATE;
160 priv->reg.rate_set.body[4] = TX_RATE_6M | BASIC_RATE;
161 priv->reg.rate_set.body[3] = TX_RATE_11M | BASIC_RATE;
162 priv->reg.rate_set.body[2] = TX_RATE_5M | BASIC_RATE;
163 priv->reg.rate_set.body[1] = TX_RATE_2M | BASIC_RATE;
164 priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
165 priv->reg.tx_rate = TX_RATE_FULL_AUTO;
166 priv->reg.rate_set.size = 12;
172 #include <linux/firmware.h>
173 int ks_wlan_read_config_file(struct ks_wlan_private *priv)
180 {15, "BeaconLostCount", "20"}, /* 0 */
181 {7, "Channel", "1"}, /* 1 */
182 {17, "FragmentThreshold", "2346"}, /* 2 */
183 {13, "OperationMode", "Infrastructure"}, /* 3 */
184 {19, "PowerManagementMode", "ACTIVE"}, /* 4 */
185 {12, "RTSThreshold", "2347"}, /* 5 */
186 {4, "SSID", "default"}, /* 6 */
187 {6, "TxRate", "Auto"}, /* 7 */
188 {23, "AuthenticationAlgorithm", ""}, /* 8 */
189 {12, "WepKeyValue1", ""}, /* 9 */
190 {12, "WepKeyValue2", ""}, /* 10 */
191 {12, "WepKeyValue3", ""}, /* 11 */
192 {12, "WepKeyValue4", ""}, /* 12 */
193 {8, "WepIndex", "1"}, /* 13 */
194 {7, "WepType", "STRING"}, /* 14 */
195 {3, "Wep", "OFF"}, /* 15 */
196 {13, "PREAMBLE_TYPE", "LONG"}, /* 16 */
197 {8, "ScanType", "ACTIVE_SCAN"}, /* 17 */
198 {8, "ROM_FILE", ROM_FILE}, /* 18 */
199 {7, "PhyType", "BG_MODE"}, /* 19 */
200 {7, "CtsMode", "FALSE"}, /* 20 */
201 {19, "PhyInformationTimer", "0"}, /* 21 */
205 const struct firmware *fw_entry;
206 struct device *dev = NULL;
207 char cfg_file[] = CFG_FILE;
209 char wk_buff[256], *wk_p;
211 /* Initialize Variable */
212 priv->reg.operation_mode = MODE_INFRASTRUCTURE; /* Infrastructure */
213 priv->reg.channel = 10; /* 10 */
214 memset(priv->reg.bssid, 0x0, ETH_ALEN); /* BSSID */
215 priv->reg.ssid.body[0] = '\0'; /* SSID */
216 priv->reg.ssid.size = 0; /* SSID size */
217 priv->reg.tx_rate = TX_RATE_AUTO; /* TxRate Fully Auto */
218 priv->reg.preamble = LONG_PREAMBLE; /* Preamble = LONG */
219 priv->reg.powermgt = POWMGT_ACTIVE_MODE; /* POWMGT_ACTIVE_MODE */
220 priv->reg.scan_type = ACTIVE_SCAN; /* Active */
221 priv->reg.beacon_lost_count = 20; /* Beacon Lost Count */
222 priv->reg.rts = 2347UL; /* RTS Threashold */
223 priv->reg.fragment = 2346UL; /* Fragmentation Threashold */
225 strcpy(&priv->reg.rom_file[0], ROM_FILE);
229 priv->reg.authenticate_type = AUTH_TYPE_OPEN_SYSTEM; /* AuthenticationAlgorithm */
231 priv->reg.privacy_invoked = 0x00; /* WEP */
232 priv->reg.wep_index = 0;
233 memset(&priv->reg.wep_key[0], 0, sizeof(priv->reg.wep_key[0]));
234 memset(&priv->reg.wep_key[1], 0, sizeof(priv->reg.wep_key[0]));
235 memset(&priv->reg.wep_key[2], 0, sizeof(priv->reg.wep_key[0]));
236 memset(&priv->reg.wep_key[3], 0, sizeof(priv->reg.wep_key[0]));
238 priv->reg.phy_type = D_11BG_COMPATIBLE_MODE;
239 priv->reg.cts_mode = CTS_MODE_FALSE;
240 priv->reg.phy_info_timer = 0;
241 priv->reg.rate_set.body[11] = TX_RATE_54M;
242 priv->reg.rate_set.body[10] = TX_RATE_48M;
243 priv->reg.rate_set.body[9] = TX_RATE_36M;
244 priv->reg.rate_set.body[8] = TX_RATE_18M;
245 priv->reg.rate_set.body[7] = TX_RATE_9M;
246 priv->reg.rate_set.body[6] = TX_RATE_24M | BASIC_RATE;
247 priv->reg.rate_set.body[5] = TX_RATE_12M | BASIC_RATE;
248 priv->reg.rate_set.body[4] = TX_RATE_6M | BASIC_RATE;
249 priv->reg.rate_set.body[3] = TX_RATE_11M | BASIC_RATE;
250 priv->reg.rate_set.body[2] = TX_RATE_5M | BASIC_RATE;
251 priv->reg.rate_set.body[1] = TX_RATE_2M | BASIC_RATE;
252 priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
253 priv->reg.tx_rate = TX_RATE_FULL_AUTO;
254 priv->reg.rate_set.size = 12;
256 dev = &priv->ks_wlan_hw.sdio_card->func->dev;
257 /* If no cfg file, stay with the defaults */
258 if (request_firmware_direct(&fw_entry, cfg_file, dev))
261 DPRINTK(4, "success request_firmware() file=%s size=%zu\n", cfg_file,
263 cur_p = fw_entry->data;
264 end_p = cur_p + fw_entry->size;
267 while (cur_p < end_p) {
271 for (i = 0; cfg_tbl[i].key_len != 0; i++) {
275 if (len < cfg_tbl[i].key_len) {
278 if (!strncmp(cfg_tbl[i].key, cur_p, cfg_tbl[i].key_len)) {
282 if ((*cur_p == '#') || (cfg_tbl[i].key_len == 0)) {
283 while (*cur_p != '\n') {
284 if (cur_p >= end_p) {
291 cur_p += cfg_tbl[i].key_len;
293 while (*cur_p != '\n') {
294 if (cur_p >= end_p) {
303 for (j = 0, wk_p = cur_p; *wk_p != '\n' && wk_p < end_p;
309 DPRINTK(4, "%s=%s\n", cfg_tbl[i].key, wk_buff);
313 case 0: /* "BeaconLostCount", "10" */
314 priv->reg.beacon_lost_count =
315 simple_strtol(wk_buff, NULL, 10);
317 case 1: /* "Channel", "1" */
319 simple_strtol(wk_buff, NULL, 10);
321 case 2: /* "FragmentThreshold","2346" */
322 j = simple_strtol(wk_buff, NULL, 10);
323 priv->reg.fragment = (unsigned long)j;
325 case 3: /* "OperationMode","Infrastructure" */
328 priv->reg.operation_mode =
332 priv->reg.operation_mode =
336 priv->reg.operation_mode = MODE_ADHOC;
339 priv->reg.operation_mode =
343 case 4: /* "PowerManagementMode","POWER_ACTIVE" */
344 if (!strncmp(wk_buff, "SAVE1", 5)) {
345 priv->reg.powermgt = POWMGT_SAVE1_MODE;
346 } else if (!strncmp(wk_buff, "SAVE2", 5)) {
347 priv->reg.powermgt = POWMGT_SAVE2_MODE;
349 priv->reg.powermgt = POWMGT_ACTIVE_MODE;
352 case 5: /* "RTSThreshold","2347" */
353 j = simple_strtol(wk_buff, NULL, 10);
354 priv->reg.rts = (unsigned long)j;
356 case 6: /* "SSID","" */
360 for (j = 0; *wk_p != '"'; j++) {
364 priv->reg.ssid.body[j] = *wk_p++;
366 priv->reg.ssid.body[j] = '\0';
367 priv->reg.ssid.size = j;
370 case 7: /* "TxRate","Auto" */
371 rate_set_configuration(priv, wk_p);
373 case 8: /* "AuthenticationAlgorithm","OPEN_SYSTEM" */
375 case 'O': /* Authenticate System : Open System */
376 priv->reg.authenticate_type =
377 AUTH_TYPE_OPEN_SYSTEM;
379 case 'S': /* Authenticate System : Shared Key */
380 priv->reg.authenticate_type =
381 AUTH_TYPE_SHARED_KEY;
385 case 9: /* "WepKeyValue1","" */
386 case 10: /* "WepKeyValue2","" */
387 case 11: /* "WepKeyValue3","" */
388 case 12: /* "WepKeyValue4","" */
389 if (wep_on_off != WEP_OFF) {
391 case WEP_KEY_CHARACTER:
392 analyze_character_wep_key
393 (&priv->reg, (i - 9), wk_p);
396 analyze_hex_wep_key(&priv->reg,
403 case 13: /* "WepIndex","1"->0 (So, Zero Origin) */
404 priv->reg.wep_index =
405 simple_strtol(wk_buff, NULL, 10) - 1;
407 case 14: /* "WepType","STRING" */
408 if (!strncmp(wk_buff, "STRING", 6)) {
409 wep_type = WEP_KEY_CHARACTER;
411 wep_type = WEP_KEY_HEX;
414 case 15: /* "Wep","OFF" */
415 if (!strncmp(wk_buff, "OFF", 3)) {
416 priv->reg.privacy_invoked = 0x00;
417 wep_on_off = WEP_OFF;
418 } else { /* 64bit or 128bit */
419 priv->reg.privacy_invoked = 0x01;
420 if (*wk_buff == '6') { /* 64bit */
421 wep_on_off = WEP_ON_64BIT;
422 } else { /* 128bit */
423 wep_on_off = WEP_ON_128BIT;
427 case 16: /* "PREAMBLE_TYPE","LONG" */
428 if (!strncmp(wk_buff, "SHORT", 5)) {
429 priv->reg.preamble = SHORT_PREAMBLE;
430 } else { /* "LONG" */
431 priv->reg.preamble = LONG_PREAMBLE;
434 case 17: /* "ScanType","ACTIVE_SCAN" */
435 if (!strncmp(wk_buff, "PASSIVE_SCAN", 12)) {
436 priv->reg.scan_type = PASSIVE_SCAN;
437 } else { /* "ACTIVE_SCAN" */
438 priv->reg.scan_type = ACTIVE_SCAN;
441 case 18: // "ROM_FILE",ROMFILE
445 for (j = 0; *wk_p != '"'; j++) {
449 priv->reg.rom_file[j] = *wk_p++;
451 priv->reg.rom_file[j] = '\0';
454 case 19: /*"PhyType", "BG_MODE" */
455 if (!strncmp(wk_buff, "B_MODE", 6)) {
456 priv->reg.phy_type = D_11B_ONLY_MODE;
457 } else if (!strncmp(wk_buff, "G_MODE", 6)) {
458 priv->reg.phy_type = D_11G_ONLY_MODE;
461 D_11BG_COMPATIBLE_MODE;
464 case 20: /* "CtsMode", "FALSE" */
465 if (!strncmp(wk_buff, "TRUE", 4)) {
466 priv->reg.cts_mode = CTS_MODE_TRUE;
468 priv->reg.cts_mode = CTS_MODE_FALSE;
471 case 21: /* "PhyInformationTimer", "0" */
472 j = simple_strtol(wk_buff, NULL, 10);
473 priv->reg.phy_info_timer = (uint16_t) j;
478 if (cur_p >= end_p) {
485 release_firmware(fw_entry);
488 "\n operation_mode = %d\n channel = %d\n ssid = %s\n tx_rate = %d\n \
489 preamble = %d\n powermgt = %d\n scan_type = %d\n beacon_lost_count = %d\n rts = %d\n \
490 fragment = %d\n privacy_invoked = %d\n wep_type = %d\n wep_on_off = %d\n wep_index = %d\n romfile = %s\n",
491 priv->reg.operation_mode, priv->reg.channel, &priv->reg.ssid.body[0], priv->reg.tx_rate, priv->reg.preamble, priv->reg.powermgt, priv->reg.scan_type, priv->reg.beacon_lost_count, priv->reg.rts, priv->reg.fragment, priv->reg.privacy_invoked, wep_type, wep_on_off,
492 priv->reg.wep_index, &priv->reg.rom_file[0]
495 "\n phy_type = %d\n cts_mode = %d\n tx_rate = %d\n phy_info_timer = %d\n",
496 priv->reg.phy_type, priv->reg.cts_mode, priv->reg.tx_rate,
497 priv->reg.phy_info_timer);