diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_acx.c | 68 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_acx.h | 36 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_boot.c | 55 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_event.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_init.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_main.c | 162 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_ps.c | 44 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_ps.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_reg.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_rx.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_spi.c | 2 |
12 files changed, 310 insertions, 96 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 998e4b6252bd..054533f7a124 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h | |||
@@ -269,6 +269,7 @@ struct wl1251 { | |||
269 | 269 | ||
270 | void (*set_power)(bool enable); | 270 | void (*set_power)(bool enable); |
271 | int irq; | 271 | int irq; |
272 | bool use_eeprom; | ||
272 | 273 | ||
273 | enum wl1251_state state; | 274 | enum wl1251_state state; |
274 | struct mutex mutex; | 275 | struct mutex mutex; |
@@ -354,6 +355,8 @@ struct wl1251 { | |||
354 | /* is firmware in elp mode */ | 355 | /* is firmware in elp mode */ |
355 | bool elp; | 356 | bool elp; |
356 | 357 | ||
358 | struct delayed_work elp_work; | ||
359 | |||
357 | /* we can be in psm, but not in elp, we have to differentiate */ | 360 | /* we can be in psm, but not in elp, we have to differentiate */ |
358 | bool psm; | 361 | bool psm; |
359 | 362 | ||
@@ -374,6 +377,8 @@ struct wl1251 { | |||
374 | u8 buffer_busyword[WL1251_BUSY_WORD_LEN]; | 377 | u8 buffer_busyword[WL1251_BUSY_WORD_LEN]; |
375 | struct wl1251_rx_descriptor *rx_descriptor; | 378 | struct wl1251_rx_descriptor *rx_descriptor; |
376 | 379 | ||
380 | struct ieee80211_vif *vif; | ||
381 | |||
377 | u32 chip_id; | 382 | u32 chip_id; |
378 | char fw_ver[21]; | 383 | char fw_ver[21]; |
379 | }; | 384 | }; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c index 10b26c4532c9..acfa086dbfc5 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.c +++ b/drivers/net/wireless/wl12xx/wl1251_acx.c | |||
@@ -494,7 +494,7 @@ out: | |||
494 | return ret; | 494 | return ret; |
495 | } | 495 | } |
496 | 496 | ||
497 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl) | 497 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter) |
498 | { | 498 | { |
499 | struct acx_beacon_filter_option *beacon_filter; | 499 | struct acx_beacon_filter_option *beacon_filter; |
500 | int ret; | 500 | int ret; |
@@ -507,7 +507,7 @@ int wl1251_acx_beacon_filter_opt(struct wl1251 *wl) | |||
507 | goto out; | 507 | goto out; |
508 | } | 508 | } |
509 | 509 | ||
510 | beacon_filter->enable = 0; | 510 | beacon_filter->enable = enable_filter; |
511 | beacon_filter->max_num_beacons = 0; | 511 | beacon_filter->max_num_beacons = 0; |
512 | 512 | ||
513 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT, | 513 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT, |
@@ -525,6 +525,7 @@ out: | |||
525 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl) | 525 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl) |
526 | { | 526 | { |
527 | struct acx_beacon_filter_ie_table *ie_table; | 527 | struct acx_beacon_filter_ie_table *ie_table; |
528 | int idx = 0; | ||
528 | int ret; | 529 | int ret; |
529 | 530 | ||
530 | wl1251_debug(DEBUG_ACX, "acx beacon filter table"); | 531 | wl1251_debug(DEBUG_ACX, "acx beacon filter table"); |
@@ -535,8 +536,10 @@ int wl1251_acx_beacon_filter_table(struct wl1251 *wl) | |||
535 | goto out; | 536 | goto out; |
536 | } | 537 | } |
537 | 538 | ||
538 | ie_table->num_ie = 0; | 539 | /* configure default beacon pass-through rules */ |
539 | memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE); | 540 | ie_table->num_ie = 1; |
541 | ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN; | ||
542 | ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE; | ||
540 | 543 | ||
541 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, | 544 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, |
542 | ie_table, sizeof(*ie_table)); | 545 | ie_table, sizeof(*ie_table)); |
@@ -550,6 +553,35 @@ out: | |||
550 | return ret; | 553 | return ret; |
551 | } | 554 | } |
552 | 555 | ||
556 | int wl1251_acx_conn_monit_params(struct wl1251 *wl) | ||
557 | { | ||
558 | struct acx_conn_monit_params *acx; | ||
559 | int ret; | ||
560 | |||
561 | wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); | ||
562 | |||
563 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
564 | if (!acx) { | ||
565 | ret = -ENOMEM; | ||
566 | goto out; | ||
567 | } | ||
568 | |||
569 | acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD; | ||
570 | acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT; | ||
571 | |||
572 | ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, | ||
573 | acx, sizeof(*acx)); | ||
574 | if (ret < 0) { | ||
575 | wl1251_warning("failed to set connection monitor " | ||
576 | "parameters: %d", ret); | ||
577 | goto out; | ||
578 | } | ||
579 | |||
580 | out: | ||
581 | kfree(acx); | ||
582 | return ret; | ||
583 | } | ||
584 | |||
553 | int wl1251_acx_sg_enable(struct wl1251 *wl) | 585 | int wl1251_acx_sg_enable(struct wl1251 *wl) |
554 | { | 586 | { |
555 | struct acx_bt_wlan_coex *pta; | 587 | struct acx_bt_wlan_coex *pta; |
@@ -916,3 +948,31 @@ out: | |||
916 | kfree(mem_conf); | 948 | kfree(mem_conf); |
917 | return ret; | 949 | return ret; |
918 | } | 950 | } |
951 | |||
952 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim) | ||
953 | { | ||
954 | struct wl1251_acx_wr_tbtt_and_dtim *acx; | ||
955 | int ret; | ||
956 | |||
957 | wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); | ||
958 | |||
959 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
960 | if (!acx) { | ||
961 | ret = -ENOMEM; | ||
962 | goto out; | ||
963 | } | ||
964 | |||
965 | acx->tbtt = tbtt; | ||
966 | acx->dtim = dtim; | ||
967 | |||
968 | ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM, | ||
969 | acx, sizeof(*acx)); | ||
970 | if (ret < 0) { | ||
971 | wl1251_warning("failed to set tbtt and dtim: %d", ret); | ||
972 | goto out; | ||
973 | } | ||
974 | |||
975 | out: | ||
976 | kfree(acx); | ||
977 | return ret; | ||
978 | } | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h index cafb91459504..652371432cd8 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl12xx/wl1251_acx.h | |||
@@ -450,6 +450,11 @@ struct acx_beacon_filter_option { | |||
450 | (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ | 450 | (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ |
451 | BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) | 451 | BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) |
452 | 452 | ||
453 | #define BEACON_RULE_PASS_ON_CHANGE BIT(0) | ||
454 | #define BEACON_RULE_PASS_ON_APPEARANCE BIT(1) | ||
455 | |||
456 | #define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN (37) | ||
457 | |||
453 | struct acx_beacon_filter_ie_table { | 458 | struct acx_beacon_filter_ie_table { |
454 | struct acx_header header; | 459 | struct acx_header header; |
455 | 460 | ||
@@ -458,6 +463,16 @@ struct acx_beacon_filter_ie_table { | |||
458 | u8 pad[3]; | 463 | u8 pad[3]; |
459 | } __attribute__ ((packed)); | 464 | } __attribute__ ((packed)); |
460 | 465 | ||
466 | #define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */ | ||
467 | #define NO_BEACON_DEFAULT_TIMEOUT (500) /* in microseconds */ | ||
468 | |||
469 | struct acx_conn_monit_params { | ||
470 | struct acx_header header; | ||
471 | |||
472 | u32 synch_fail_thold; /* number of beacons missed */ | ||
473 | u32 bss_lose_timeout; /* number of TU's from synch fail */ | ||
474 | }; | ||
475 | |||
461 | enum { | 476 | enum { |
462 | SG_ENABLE = 0, | 477 | SG_ENABLE = 0, |
463 | SG_DISABLE, | 478 | SG_DISABLE, |
@@ -1134,6 +1149,23 @@ struct wl1251_acx_mem_map { | |||
1134 | u32 num_rx_mem_blocks; | 1149 | u32 num_rx_mem_blocks; |
1135 | } __attribute__ ((packed)); | 1150 | } __attribute__ ((packed)); |
1136 | 1151 | ||
1152 | |||
1153 | struct wl1251_acx_wr_tbtt_and_dtim { | ||
1154 | |||
1155 | struct acx_header header; | ||
1156 | |||
1157 | /* Time in TUs between two consecutive beacons */ | ||
1158 | u16 tbtt; | ||
1159 | |||
1160 | /* | ||
1161 | * DTIM period | ||
1162 | * For BSS: Number of TBTTs in a DTIM period (range: 1-10) | ||
1163 | * For IBSS: value shall be set to 1 | ||
1164 | */ | ||
1165 | u8 dtim; | ||
1166 | u8 padding; | ||
1167 | } __attribute__ ((packed)); | ||
1168 | |||
1137 | /************************************************************************* | 1169 | /************************************************************************* |
1138 | 1170 | ||
1139 | Host Interrupt Register (WiLink -> Host) | 1171 | Host Interrupt Register (WiLink -> Host) |
@@ -1273,8 +1305,9 @@ int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time); | |||
1273 | int wl1251_acx_group_address_tbl(struct wl1251 *wl); | 1305 | int wl1251_acx_group_address_tbl(struct wl1251 *wl); |
1274 | int wl1251_acx_service_period_timeout(struct wl1251 *wl); | 1306 | int wl1251_acx_service_period_timeout(struct wl1251 *wl); |
1275 | int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); | 1307 | int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); |
1276 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl); | 1308 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter); |
1277 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl); | 1309 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl); |
1310 | int wl1251_acx_conn_monit_params(struct wl1251 *wl); | ||
1278 | int wl1251_acx_sg_enable(struct wl1251 *wl); | 1311 | int wl1251_acx_sg_enable(struct wl1251 *wl); |
1279 | int wl1251_acx_sg_cfg(struct wl1251 *wl); | 1312 | int wl1251_acx_sg_cfg(struct wl1251 *wl); |
1280 | int wl1251_acx_cca_threshold(struct wl1251 *wl); | 1313 | int wl1251_acx_cca_threshold(struct wl1251 *wl); |
@@ -1288,5 +1321,6 @@ int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats); | |||
1288 | int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); | 1321 | int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); |
1289 | int wl1251_acx_rate_policies(struct wl1251 *wl); | 1322 | int wl1251_acx_rate_policies(struct wl1251 *wl); |
1290 | int wl1251_acx_mem_cfg(struct wl1251 *wl); | 1323 | int wl1251_acx_mem_cfg(struct wl1251 *wl); |
1324 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); | ||
1291 | 1325 | ||
1292 | #endif /* __WL1251_ACX_H__ */ | 1326 | #endif /* __WL1251_ACX_H__ */ |
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 452d748e42c6..2e733e7bdfd4 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c | |||
@@ -296,8 +296,12 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
296 | WL1251_ACX_INTR_INIT_COMPLETE; | 296 | WL1251_ACX_INTR_INIT_COMPLETE; |
297 | wl1251_boot_target_enable_interrupts(wl); | 297 | wl1251_boot_target_enable_interrupts(wl); |
298 | 298 | ||
299 | /* unmask all mbox events */ | 299 | wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID | |
300 | wl->event_mask = 0xffffffff; | 300 | SYNCHRONIZATION_TIMEOUT_EVENT_ID | |
301 | ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | | ||
302 | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | | ||
303 | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | | ||
304 | BT_PTA_PREDICTION_EVENT_ID; | ||
301 | 305 | ||
302 | ret = wl1251_event_unmask(wl); | 306 | ret = wl1251_event_unmask(wl); |
303 | if (ret < 0) { | 307 | if (ret < 0) { |
@@ -314,8 +318,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
314 | static int wl1251_boot_upload_firmware(struct wl1251 *wl) | 318 | static int wl1251_boot_upload_firmware(struct wl1251 *wl) |
315 | { | 319 | { |
316 | int addr, chunk_num, partition_limit; | 320 | int addr, chunk_num, partition_limit; |
317 | size_t fw_data_len; | 321 | size_t fw_data_len, len; |
318 | u8 *p; | 322 | u8 *p, *buf; |
319 | 323 | ||
320 | /* whal_FwCtrl_LoadFwImageSm() */ | 324 | /* whal_FwCtrl_LoadFwImageSm() */ |
321 | 325 | ||
@@ -334,6 +338,12 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl) | |||
334 | return -EIO; | 338 | return -EIO; |
335 | } | 339 | } |
336 | 340 | ||
341 | buf = kmalloc(CHUNK_SIZE, GFP_KERNEL); | ||
342 | if (!buf) { | ||
343 | wl1251_error("allocation for firmware upload chunk failed"); | ||
344 | return -ENOMEM; | ||
345 | } | ||
346 | |||
337 | wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, | 347 | wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, |
338 | WL1251_PART_DOWN_MEM_SIZE, | 348 | WL1251_PART_DOWN_MEM_SIZE, |
339 | WL1251_PART_DOWN_REG_START, | 349 | WL1251_PART_DOWN_REG_START, |
@@ -364,7 +374,11 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl) | |||
364 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; | 374 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; |
365 | wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", | 375 | wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", |
366 | p, addr); | 376 | p, addr); |
367 | wl1251_mem_write(wl, addr, p, CHUNK_SIZE); | 377 | |
378 | /* need to copy the chunk for dma */ | ||
379 | len = CHUNK_SIZE; | ||
380 | memcpy(buf, p, len); | ||
381 | wl1251_mem_write(wl, addr, buf, len); | ||
368 | 382 | ||
369 | chunk_num++; | 383 | chunk_num++; |
370 | } | 384 | } |
@@ -372,9 +386,16 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl) | |||
372 | /* 10.4 upload the last chunk */ | 386 | /* 10.4 upload the last chunk */ |
373 | addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; | 387 | addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; |
374 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; | 388 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; |
389 | |||
390 | /* need to copy the chunk for dma */ | ||
391 | len = fw_data_len % CHUNK_SIZE; | ||
392 | memcpy(buf, p, len); | ||
393 | |||
375 | wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", | 394 | wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", |
376 | fw_data_len % CHUNK_SIZE, p, addr); | 395 | len, p, addr); |
377 | wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE); | 396 | wl1251_mem_write(wl, addr, buf, len); |
397 | |||
398 | kfree(buf); | ||
378 | 399 | ||
379 | return 0; | 400 | return 0; |
380 | } | 401 | } |
@@ -473,13 +494,19 @@ int wl1251_boot(struct wl1251 *wl) | |||
473 | goto out; | 494 | goto out; |
474 | 495 | ||
475 | /* 2. start processing NVS file */ | 496 | /* 2. start processing NVS file */ |
476 | ret = wl1251_boot_upload_nvs(wl); | 497 | if (wl->use_eeprom) { |
477 | if (ret < 0) | 498 | wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); |
478 | goto out; | 499 | msleep(4000); |
479 | 500 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); | |
480 | /* write firmware's last address (ie. it's length) to | 501 | } else { |
481 | * ACX_EEPROMLESS_IND_REG */ | 502 | ret = wl1251_boot_upload_nvs(wl); |
482 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len); | 503 | if (ret < 0) |
504 | goto out; | ||
505 | |||
506 | /* write firmware's last address (ie. it's length) to | ||
507 | * ACX_EEPROMLESS_IND_REG */ | ||
508 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len); | ||
509 | } | ||
483 | 510 | ||
484 | /* 6. read the EEPROM parameters */ | 511 | /* 6. read the EEPROM parameters */ |
485 | tmp = wl1251_reg_read32(wl, SCR_PAD2); | 512 | tmp = wl1251_reg_read32(wl, SCR_PAD2); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c index 00076c4a8a21..020d764f9c13 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.c +++ b/drivers/net/wireless/wl12xx/wl1251_event.c | |||
@@ -79,6 +79,21 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) { | ||
83 | wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); | ||
84 | |||
85 | /* indicate to the stack, that beacons have been lost */ | ||
86 | ieee80211_beacon_loss(wl->vif); | ||
87 | } | ||
88 | |||
89 | if (vector & REGAINED_BSS_EVENT_ID) { | ||
90 | if (wl->psm_requested) { | ||
91 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); | ||
92 | if (ret < 0) | ||
93 | return ret; | ||
94 | } | ||
95 | } | ||
96 | |||
82 | return 0; | 97 | return 0; |
83 | } | 98 | } |
84 | 99 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c index b2ee4f468fc4..5cb573383eeb 100644 --- a/drivers/net/wireless/wl12xx/wl1251_init.c +++ b/drivers/net/wireless/wl12xx/wl1251_init.c | |||
@@ -147,7 +147,8 @@ int wl1251_hw_init_beacon_filter(struct wl1251 *wl) | |||
147 | { | 147 | { |
148 | int ret; | 148 | int ret; |
149 | 149 | ||
150 | ret = wl1251_acx_beacon_filter_opt(wl); | 150 | /* disable beacon filtering at this stage */ |
151 | ret = wl1251_acx_beacon_filter_opt(wl, false); | ||
151 | if (ret < 0) | 152 | if (ret < 0) |
152 | return ret; | 153 | return ret; |
153 | 154 | ||
@@ -364,6 +365,11 @@ int wl1251_hw_init(struct wl1251 *wl) | |||
364 | if (ret < 0) | 365 | if (ret < 0) |
365 | goto out_free_data_path; | 366 | goto out_free_data_path; |
366 | 367 | ||
368 | /* Initialize connection monitoring thresholds */ | ||
369 | ret = wl1251_acx_conn_monit_params(wl); | ||
370 | if (ret < 0) | ||
371 | goto out_free_data_path; | ||
372 | |||
367 | /* Beacon filtering */ | 373 | /* Beacon filtering */ |
368 | ret = wl1251_hw_init_beacon_filter(wl); | 374 | ret = wl1251_hw_init_beacon_filter(wl); |
369 | if (ret < 0) | 375 | if (ret < 0) |
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index d03a07e1be7c..ff4be7bf5d36 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
29 | #include <linux/crc32.h> | 29 | #include <linux/crc32.h> |
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <linux/vmalloc.h> | ||
31 | 32 | ||
32 | #include "wl1251.h" | 33 | #include "wl1251.h" |
33 | #include "wl12xx_80211.h" | 34 | #include "wl12xx_80211.h" |
@@ -83,7 +84,7 @@ static int wl1251_fetch_firmware(struct wl1251 *wl) | |||
83 | } | 84 | } |
84 | 85 | ||
85 | wl->fw_len = fw->size; | 86 | wl->fw_len = fw->size; |
86 | wl->fw = kmalloc(wl->fw_len, GFP_KERNEL); | 87 | wl->fw = vmalloc(wl->fw_len); |
87 | 88 | ||
88 | if (!wl->fw) { | 89 | if (!wl->fw) { |
89 | wl1251_error("could not allocate memory for the firmware"); | 90 | wl1251_error("could not allocate memory for the firmware"); |
@@ -211,9 +212,10 @@ out: | |||
211 | return ret; | 212 | return ret; |
212 | } | 213 | } |
213 | 214 | ||
215 | #define WL1251_IRQ_LOOP_COUNT 10 | ||
214 | static void wl1251_irq_work(struct work_struct *work) | 216 | static void wl1251_irq_work(struct work_struct *work) |
215 | { | 217 | { |
216 | u32 intr; | 218 | u32 intr, ctr = WL1251_IRQ_LOOP_COUNT; |
217 | struct wl1251 *wl = | 219 | struct wl1251 *wl = |
218 | container_of(work, struct wl1251, irq_work); | 220 | container_of(work, struct wl1251, irq_work); |
219 | int ret; | 221 | int ret; |
@@ -234,78 +236,86 @@ static void wl1251_irq_work(struct work_struct *work) | |||
234 | intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); | 236 | intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); |
235 | wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr); | 237 | wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr); |
236 | 238 | ||
237 | if (wl->data_path) { | 239 | do { |
238 | wl->rx_counter = | 240 | if (wl->data_path) { |
239 | wl1251_mem_read32(wl, wl->data_path->rx_control_addr); | 241 | wl->rx_counter = wl1251_mem_read32( |
240 | 242 | wl, wl->data_path->rx_control_addr); | |
241 | /* We handle a frmware bug here */ | 243 | |
242 | switch ((wl->rx_counter - wl->rx_handled) & 0xf) { | 244 | /* We handle a frmware bug here */ |
243 | case 0: | 245 | switch ((wl->rx_counter - wl->rx_handled) & 0xf) { |
244 | wl1251_debug(DEBUG_IRQ, "RX: FW and host in sync"); | 246 | case 0: |
245 | intr &= ~WL1251_ACX_INTR_RX0_DATA; | 247 | wl1251_debug(DEBUG_IRQ, |
246 | intr &= ~WL1251_ACX_INTR_RX1_DATA; | 248 | "RX: FW and host in sync"); |
247 | break; | 249 | intr &= ~WL1251_ACX_INTR_RX0_DATA; |
248 | case 1: | 250 | intr &= ~WL1251_ACX_INTR_RX1_DATA; |
249 | wl1251_debug(DEBUG_IRQ, "RX: FW +1"); | 251 | break; |
250 | intr |= WL1251_ACX_INTR_RX0_DATA; | 252 | case 1: |
251 | intr &= ~WL1251_ACX_INTR_RX1_DATA; | 253 | wl1251_debug(DEBUG_IRQ, "RX: FW +1"); |
252 | break; | 254 | intr |= WL1251_ACX_INTR_RX0_DATA; |
253 | case 2: | 255 | intr &= ~WL1251_ACX_INTR_RX1_DATA; |
254 | wl1251_debug(DEBUG_IRQ, "RX: FW +2"); | 256 | break; |
255 | intr |= WL1251_ACX_INTR_RX0_DATA; | 257 | case 2: |
256 | intr |= WL1251_ACX_INTR_RX1_DATA; | 258 | wl1251_debug(DEBUG_IRQ, "RX: FW +2"); |
257 | break; | 259 | intr |= WL1251_ACX_INTR_RX0_DATA; |
258 | default: | 260 | intr |= WL1251_ACX_INTR_RX1_DATA; |
259 | wl1251_warning("RX: FW and host out of sync: %d", | 261 | break; |
260 | wl->rx_counter - wl->rx_handled); | 262 | default: |
261 | break; | 263 | wl1251_warning( |
262 | } | 264 | "RX: FW and host out of sync: %d", |
263 | 265 | wl->rx_counter - wl->rx_handled); | |
264 | wl->rx_handled = wl->rx_counter; | 266 | break; |
267 | } | ||
265 | 268 | ||
269 | wl->rx_handled = wl->rx_counter; | ||
266 | 270 | ||
267 | wl1251_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter); | 271 | wl1251_debug(DEBUG_IRQ, "RX counter: %d", |
268 | } | 272 | wl->rx_counter); |
273 | } | ||
269 | 274 | ||
270 | intr &= wl->intr_mask; | 275 | intr &= wl->intr_mask; |
271 | 276 | ||
272 | if (intr == 0) { | 277 | if (intr == 0) { |
273 | wl1251_debug(DEBUG_IRQ, "INTR is 0"); | 278 | wl1251_debug(DEBUG_IRQ, "INTR is 0"); |
274 | wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, | 279 | goto out_sleep; |
275 | ~(wl->intr_mask)); | 280 | } |
276 | 281 | ||
277 | goto out_sleep; | 282 | if (intr & WL1251_ACX_INTR_RX0_DATA) { |
278 | } | 283 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA"); |
284 | wl1251_rx(wl); | ||
285 | } | ||
279 | 286 | ||
280 | if (intr & WL1251_ACX_INTR_RX0_DATA) { | 287 | if (intr & WL1251_ACX_INTR_RX1_DATA) { |
281 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA"); | 288 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA"); |
282 | wl1251_rx(wl); | 289 | wl1251_rx(wl); |
283 | } | 290 | } |
284 | 291 | ||
285 | if (intr & WL1251_ACX_INTR_RX1_DATA) { | 292 | if (intr & WL1251_ACX_INTR_TX_RESULT) { |
286 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA"); | 293 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT"); |
287 | wl1251_rx(wl); | 294 | wl1251_tx_complete(wl); |
288 | } | 295 | } |
289 | 296 | ||
290 | if (intr & WL1251_ACX_INTR_TX_RESULT) { | 297 | if (intr & (WL1251_ACX_INTR_EVENT_A | |
291 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT"); | 298 | WL1251_ACX_INTR_EVENT_B)) { |
292 | wl1251_tx_complete(wl); | 299 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", |
293 | } | 300 | intr); |
301 | if (intr & WL1251_ACX_INTR_EVENT_A) | ||
302 | wl1251_event_handle(wl, 0); | ||
303 | else | ||
304 | wl1251_event_handle(wl, 1); | ||
305 | } | ||
294 | 306 | ||
295 | if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) { | 307 | if (intr & WL1251_ACX_INTR_INIT_COMPLETE) |
296 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr); | 308 | wl1251_debug(DEBUG_IRQ, |
297 | if (intr & WL1251_ACX_INTR_EVENT_A) | 309 | "WL1251_ACX_INTR_INIT_COMPLETE"); |
298 | wl1251_event_handle(wl, 0); | ||
299 | else | ||
300 | wl1251_event_handle(wl, 1); | ||
301 | } | ||
302 | 310 | ||
303 | if (intr & WL1251_ACX_INTR_INIT_COMPLETE) | 311 | if (--ctr == 0) |
304 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE"); | 312 | break; |
305 | 313 | ||
306 | wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); | 314 | intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); |
315 | } while (intr); | ||
307 | 316 | ||
308 | out_sleep: | 317 | out_sleep: |
318 | wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); | ||
309 | wl1251_ps_elp_sleep(wl); | 319 | wl1251_ps_elp_sleep(wl); |
310 | 320 | ||
311 | out: | 321 | out: |
@@ -509,6 +519,12 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, | |||
509 | conf->type, conf->mac_addr); | 519 | conf->type, conf->mac_addr); |
510 | 520 | ||
511 | mutex_lock(&wl->mutex); | 521 | mutex_lock(&wl->mutex); |
522 | if (wl->vif) { | ||
523 | ret = -EBUSY; | ||
524 | goto out; | ||
525 | } | ||
526 | |||
527 | wl->vif = conf->vif; | ||
512 | 528 | ||
513 | switch (conf->type) { | 529 | switch (conf->type) { |
514 | case NL80211_IFTYPE_STATION: | 530 | case NL80211_IFTYPE_STATION: |
@@ -538,7 +554,12 @@ out: | |||
538 | static void wl1251_op_remove_interface(struct ieee80211_hw *hw, | 554 | static void wl1251_op_remove_interface(struct ieee80211_hw *hw, |
539 | struct ieee80211_if_init_conf *conf) | 555 | struct ieee80211_if_init_conf *conf) |
540 | { | 556 | { |
557 | struct wl1251 *wl = hw->priv; | ||
558 | |||
559 | mutex_lock(&wl->mutex); | ||
541 | wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); | 560 | wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); |
561 | wl->vif = NULL; | ||
562 | mutex_unlock(&wl->mutex); | ||
542 | } | 563 | } |
543 | 564 | ||
544 | static int wl1251_build_null_data(struct wl1251 *wl) | 565 | static int wl1251_build_null_data(struct wl1251 *wl) |
@@ -555,7 +576,8 @@ static int wl1251_build_null_data(struct wl1251 *wl) | |||
555 | 576 | ||
556 | memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); | 577 | memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); |
557 | template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | | 578 | template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | |
558 | IEEE80211_STYPE_NULLFUNC); | 579 | IEEE80211_STYPE_NULLFUNC | |
580 | IEEE80211_FCTL_TODS); | ||
559 | 581 | ||
560 | return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template, | 582 | return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template, |
561 | sizeof(template)); | 583 | sizeof(template)); |
@@ -568,7 +590,10 @@ static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid) | |||
568 | 590 | ||
569 | memcpy(template.bssid, wl->bssid, ETH_ALEN); | 591 | memcpy(template.bssid, wl->bssid, ETH_ALEN); |
570 | memcpy(template.ta, wl->mac_addr, ETH_ALEN); | 592 | memcpy(template.ta, wl->mac_addr, ETH_ALEN); |
571 | template.aid = aid; | 593 | |
594 | /* aid in PS-Poll has its two MSBs each set to 1 */ | ||
595 | template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid); | ||
596 | |||
572 | template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); | 597 | template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); |
573 | 598 | ||
574 | return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template, | 599 | return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template, |
@@ -1090,8 +1115,8 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1090 | wl->beacon_int = bss_conf->beacon_int; | 1115 | wl->beacon_int = bss_conf->beacon_int; |
1091 | wl->dtim_period = bss_conf->dtim_period; | 1116 | wl->dtim_period = bss_conf->dtim_period; |
1092 | 1117 | ||
1093 | /* FIXME: call join */ | 1118 | ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, |
1094 | 1119 | wl->dtim_period); | |
1095 | wl->aid = bss_conf->aid; | 1120 | wl->aid = bss_conf->aid; |
1096 | 1121 | ||
1097 | ret = wl1251_build_ps_poll(wl, wl->aid); | 1122 | ret = wl1251_build_ps_poll(wl, wl->aid); |
@@ -1312,7 +1337,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl) | |||
1312 | 1337 | ||
1313 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 1338 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
1314 | IEEE80211_HW_NOISE_DBM | | 1339 | IEEE80211_HW_NOISE_DBM | |
1315 | IEEE80211_HW_SUPPORTS_PS; | 1340 | IEEE80211_HW_SUPPORTS_PS | |
1341 | IEEE80211_HW_BEACON_FILTER; | ||
1316 | 1342 | ||
1317 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | 1343 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); |
1318 | wl->hw->wiphy->max_scan_ssids = 1; | 1344 | wl->hw->wiphy->max_scan_ssids = 1; |
@@ -1355,6 +1381,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | |||
1355 | skb_queue_head_init(&wl->tx_queue); | 1381 | skb_queue_head_init(&wl->tx_queue); |
1356 | 1382 | ||
1357 | INIT_WORK(&wl->filter_work, wl1251_filter_work); | 1383 | INIT_WORK(&wl->filter_work, wl1251_filter_work); |
1384 | INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); | ||
1358 | wl->channel = WL1251_DEFAULT_CHANNEL; | 1385 | wl->channel = WL1251_DEFAULT_CHANNEL; |
1359 | wl->scanning = false; | 1386 | wl->scanning = false; |
1360 | wl->default_key = 0; | 1387 | wl->default_key = 0; |
@@ -1372,6 +1399,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | |||
1372 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; | 1399 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; |
1373 | wl->beacon_int = WL1251_DEFAULT_BEACON_INT; | 1400 | wl->beacon_int = WL1251_DEFAULT_BEACON_INT; |
1374 | wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; | 1401 | wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; |
1402 | wl->vif = NULL; | ||
1375 | 1403 | ||
1376 | for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) | 1404 | for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) |
1377 | wl->tx_frames[i] = NULL; | 1405 | wl->tx_frames[i] = NULL; |
@@ -1413,7 +1441,7 @@ int wl1251_free_hw(struct wl1251 *wl) | |||
1413 | 1441 | ||
1414 | kfree(wl->target_mem_map); | 1442 | kfree(wl->target_mem_map); |
1415 | kfree(wl->data_path); | 1443 | kfree(wl->data_path); |
1416 | kfree(wl->fw); | 1444 | vfree(wl->fw); |
1417 | wl->fw = NULL; | 1445 | wl->fw = NULL; |
1418 | kfree(wl->nvs); | 1446 | kfree(wl->nvs); |
1419 | wl->nvs = NULL; | 1447 | wl->nvs = NULL; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c index c53e28727ed4..9931b197ff77 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ b/drivers/net/wireless/wl12xx/wl1251_ps.c | |||
@@ -28,17 +28,41 @@ | |||
28 | 28 | ||
29 | #define WL1251_WAKEUP_TIMEOUT 2000 | 29 | #define WL1251_WAKEUP_TIMEOUT 2000 |
30 | 30 | ||
31 | /* Routines to toggle sleep mode while in ELP */ | 31 | void wl1251_elp_work(struct work_struct *work) |
32 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
33 | { | 32 | { |
33 | struct delayed_work *dwork; | ||
34 | struct wl1251 *wl; | ||
35 | |||
36 | dwork = container_of(work, struct delayed_work, work); | ||
37 | wl = container_of(dwork, struct wl1251, elp_work); | ||
38 | |||
39 | wl1251_debug(DEBUG_PSM, "elp work"); | ||
40 | |||
41 | mutex_lock(&wl->mutex); | ||
42 | |||
34 | if (wl->elp || !wl->psm) | 43 | if (wl->elp || !wl->psm) |
35 | return; | 44 | goto out; |
36 | 45 | ||
37 | wl1251_debug(DEBUG_PSM, "chip to elp"); | 46 | wl1251_debug(DEBUG_PSM, "chip to elp"); |
38 | |||
39 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); | 47 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); |
40 | |||
41 | wl->elp = true; | 48 | wl->elp = true; |
49 | |||
50 | out: | ||
51 | mutex_unlock(&wl->mutex); | ||
52 | } | ||
53 | |||
54 | #define ELP_ENTRY_DELAY 5 | ||
55 | |||
56 | /* Routines to toggle sleep mode while in ELP */ | ||
57 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
58 | { | ||
59 | unsigned long delay; | ||
60 | |||
61 | if (wl->psm) { | ||
62 | cancel_delayed_work(&wl->elp_work); | ||
63 | delay = msecs_to_jiffies(ELP_ENTRY_DELAY); | ||
64 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); | ||
65 | } | ||
42 | } | 66 | } |
43 | 67 | ||
44 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) | 68 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) |
@@ -119,6 +143,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) | |||
119 | case STATION_POWER_SAVE_MODE: | 143 | case STATION_POWER_SAVE_MODE: |
120 | wl1251_debug(DEBUG_PSM, "entering psm"); | 144 | wl1251_debug(DEBUG_PSM, "entering psm"); |
121 | 145 | ||
146 | /* enable beacon filtering */ | ||
147 | ret = wl1251_acx_beacon_filter_opt(wl, true); | ||
148 | if (ret < 0) | ||
149 | return ret; | ||
150 | |||
122 | ret = wl1251_acx_wake_up_conditions(wl, | 151 | ret = wl1251_acx_wake_up_conditions(wl, |
123 | WAKE_UP_EVENT_DTIM_BITMAP, | 152 | WAKE_UP_EVENT_DTIM_BITMAP, |
124 | wl->listen_int); | 153 | wl->listen_int); |
@@ -142,6 +171,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) | |||
142 | if (ret < 0) | 171 | if (ret < 0) |
143 | return ret; | 172 | return ret; |
144 | 173 | ||
174 | /* disable beacon filtering */ | ||
175 | ret = wl1251_acx_beacon_filter_opt(wl, false); | ||
176 | if (ret < 0) | ||
177 | return ret; | ||
178 | |||
145 | ret = wl1251_acx_wake_up_conditions(wl, | 179 | ret = wl1251_acx_wake_up_conditions(wl, |
146 | WAKE_UP_EVENT_DTIM_BITMAP, | 180 | WAKE_UP_EVENT_DTIM_BITMAP, |
147 | wl->listen_int); | 181 | wl->listen_int); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h index db036fe12f25..c688ac57aee4 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.h +++ b/drivers/net/wireless/wl12xx/wl1251_ps.h | |||
@@ -31,6 +31,7 @@ | |||
31 | int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); | 31 | int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); |
32 | void wl1251_ps_elp_sleep(struct wl1251 *wl); | 32 | void wl1251_ps_elp_sleep(struct wl1251 *wl); |
33 | int wl1251_ps_elp_wakeup(struct wl1251 *wl); | 33 | int wl1251_ps_elp_wakeup(struct wl1251 *wl); |
34 | void wl1251_elp_work(struct work_struct *work); | ||
34 | 35 | ||
35 | 36 | ||
36 | #endif /* __WL1251_PS_H__ */ | 37 | #endif /* __WL1251_PS_H__ */ |
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h index 06e1bd94a739..0ca3b4326056 100644 --- a/drivers/net/wireless/wl12xx/wl1251_reg.h +++ b/drivers/net/wireless/wl12xx/wl1251_reg.h | |||
@@ -370,6 +370,7 @@ enum wl12xx_acx_int_reg { | |||
370 | EEPROM location specified in the EE_ADDR register. | 370 | EEPROM location specified in the EE_ADDR register. |
371 | The Wlan hardware hardware clears this bit automatically. | 371 | The Wlan hardware hardware clears this bit automatically. |
372 | *===============================================*/ | 372 | *===============================================*/ |
373 | #define EE_CTL (REGISTERS_BASE + 0x2000) | ||
373 | #define ACX_EE_CTL_REG EE_CTL | 374 | #define ACX_EE_CTL_REG EE_CTL |
374 | #define EE_WRITE 0x00000001ul | 375 | #define EE_WRITE 0x00000001ul |
375 | #define EE_READ 0x00000002ul | 376 | #define EE_READ 0x00000002ul |
@@ -380,6 +381,7 @@ enum wl12xx_acx_int_reg { | |||
380 | This register specifies the address | 381 | This register specifies the address |
381 | within the EEPROM from/to which to read/write data. | 382 | within the EEPROM from/to which to read/write data. |
382 | ===============================================*/ | 383 | ===============================================*/ |
384 | #define EE_ADDR (REGISTERS_BASE + 0x2008) | ||
383 | #define ACX_EE_ADDR_REG EE_ADDR | 385 | #define ACX_EE_ADDR_REG EE_ADDR |
384 | 386 | ||
385 | /*=============================================== | 387 | /*=============================================== |
@@ -389,8 +391,12 @@ enum wl12xx_acx_int_reg { | |||
389 | data from the EEPROM or the write data | 391 | data from the EEPROM or the write data |
390 | to be written to the EEPROM. | 392 | to be written to the EEPROM. |
391 | ===============================================*/ | 393 | ===============================================*/ |
394 | #define EE_DATA (REGISTERS_BASE + 0x2004) | ||
392 | #define ACX_EE_DATA_REG EE_DATA | 395 | #define ACX_EE_DATA_REG EE_DATA |
393 | 396 | ||
397 | #define EEPROM_ACCESS_TO 10000 /* timeout counter */ | ||
398 | #define START_EEPROM_MGR 0x00000001 | ||
399 | |||
394 | /*=============================================== | 400 | /*=============================================== |
395 | EEPROM Base Address - 32bit RW | 401 | EEPROM Base Address - 32bit RW |
396 | ------------------------------------------ | 402 | ------------------------------------------ |
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c index 601fe0d67827..f84cc89cbffc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/drivers/net/wireless/wl12xx/wl1251_rx.c | |||
@@ -72,10 +72,6 @@ static void wl1251_rx_status(struct wl1251 *wl, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | status->signal = desc->rssi; | 74 | status->signal = desc->rssi; |
75 | status->qual = (desc->rssi - WL1251_RX_MIN_RSSI) * 100 / | ||
76 | (WL1251_RX_MAX_RSSI - WL1251_RX_MIN_RSSI); | ||
77 | status->qual = min(status->qual, 100); | ||
78 | status->qual = max(status->qual, 0); | ||
79 | 75 | ||
80 | /* | 76 | /* |
81 | * FIXME: guessing that snr needs to be divided by two, otherwise | 77 | * FIXME: guessing that snr needs to be divided by two, otherwise |
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index 2cf8a2169d43..9cc8c323830f 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c | |||
@@ -270,6 +270,8 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) | |||
270 | return -ENODEV; | 270 | return -ENODEV; |
271 | } | 271 | } |
272 | 272 | ||
273 | wl->use_eeprom = pdata->use_eeprom; | ||
274 | |||
273 | ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); | 275 | ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); |
274 | if (ret < 0) { | 276 | if (ret < 0) { |
275 | wl1251_error("request_irq() failed: %d", ret); | 277 | wl1251_error("request_irq() failed: %d", ret); |