aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1251_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1251_main.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c559
1 files changed, 245 insertions, 314 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 1103256ad989..1c8226eee409 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -28,6 +28,8 @@
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>
32#include <linux/slab.h>
31 33
32#include "wl1251.h" 34#include "wl1251.h"
33#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
@@ -83,7 +85,7 @@ static int wl1251_fetch_firmware(struct wl1251 *wl)
83 } 85 }
84 86
85 wl->fw_len = fw->size; 87 wl->fw_len = fw->size;
86 wl->fw = kmalloc(wl->fw_len, GFP_KERNEL); 88 wl->fw = vmalloc(wl->fw_len);
87 89
88 if (!wl->fw) { 90 if (!wl->fw) {
89 wl1251_error("could not allocate memory for the firmware"); 91 wl1251_error("could not allocate memory for the firmware");
@@ -183,8 +185,11 @@ static int wl1251_chip_wakeup(struct wl1251 *wl)
183 wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)", 185 wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
184 wl->chip_id); 186 wl->chip_id);
185 break; 187 break;
186 case CHIP_ID_1251_PG10:
187 case CHIP_ID_1251_PG11: 188 case CHIP_ID_1251_PG11:
189 wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)",
190 wl->chip_id);
191 break;
192 case CHIP_ID_1251_PG10:
188 default: 193 default:
189 wl1251_error("unsupported chip id: 0x%x", wl->chip_id); 194 wl1251_error("unsupported chip id: 0x%x", wl->chip_id);
190 ret = -ENODEV; 195 ret = -ENODEV;
@@ -208,9 +213,10 @@ out:
208 return ret; 213 return ret;
209} 214}
210 215
216#define WL1251_IRQ_LOOP_COUNT 10
211static void wl1251_irq_work(struct work_struct *work) 217static void wl1251_irq_work(struct work_struct *work)
212{ 218{
213 u32 intr; 219 u32 intr, ctr = WL1251_IRQ_LOOP_COUNT;
214 struct wl1251 *wl = 220 struct wl1251 *wl =
215 container_of(work, struct wl1251, irq_work); 221 container_of(work, struct wl1251, irq_work);
216 int ret; 222 int ret;
@@ -231,78 +237,86 @@ static void wl1251_irq_work(struct work_struct *work)
231 intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); 237 intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
232 wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr); 238 wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr);
233 239
234 if (wl->data_path) { 240 do {
235 wl->rx_counter = 241 if (wl->data_path) {
236 wl1251_mem_read32(wl, wl->data_path->rx_control_addr); 242 wl->rx_counter = wl1251_mem_read32(
237 243 wl, wl->data_path->rx_control_addr);
238 /* We handle a frmware bug here */ 244
239 switch ((wl->rx_counter - wl->rx_handled) & 0xf) { 245 /* We handle a frmware bug here */
240 case 0: 246 switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
241 wl1251_debug(DEBUG_IRQ, "RX: FW and host in sync"); 247 case 0:
242 intr &= ~WL1251_ACX_INTR_RX0_DATA; 248 wl1251_debug(DEBUG_IRQ,
243 intr &= ~WL1251_ACX_INTR_RX1_DATA; 249 "RX: FW and host in sync");
244 break; 250 intr &= ~WL1251_ACX_INTR_RX0_DATA;
245 case 1: 251 intr &= ~WL1251_ACX_INTR_RX1_DATA;
246 wl1251_debug(DEBUG_IRQ, "RX: FW +1"); 252 break;
247 intr |= WL1251_ACX_INTR_RX0_DATA; 253 case 1:
248 intr &= ~WL1251_ACX_INTR_RX1_DATA; 254 wl1251_debug(DEBUG_IRQ, "RX: FW +1");
249 break; 255 intr |= WL1251_ACX_INTR_RX0_DATA;
250 case 2: 256 intr &= ~WL1251_ACX_INTR_RX1_DATA;
251 wl1251_debug(DEBUG_IRQ, "RX: FW +2"); 257 break;
252 intr |= WL1251_ACX_INTR_RX0_DATA; 258 case 2:
253 intr |= WL1251_ACX_INTR_RX1_DATA; 259 wl1251_debug(DEBUG_IRQ, "RX: FW +2");
254 break; 260 intr |= WL1251_ACX_INTR_RX0_DATA;
255 default: 261 intr |= WL1251_ACX_INTR_RX1_DATA;
256 wl1251_warning("RX: FW and host out of sync: %d", 262 break;
257 wl->rx_counter - wl->rx_handled); 263 default:
258 break; 264 wl1251_warning(
259 } 265 "RX: FW and host out of sync: %d",
260 266 wl->rx_counter - wl->rx_handled);
261 wl->rx_handled = wl->rx_counter; 267 break;
268 }
262 269
270 wl->rx_handled = wl->rx_counter;
263 271
264 wl1251_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter); 272 wl1251_debug(DEBUG_IRQ, "RX counter: %d",
265 } 273 wl->rx_counter);
274 }
266 275
267 intr &= wl->intr_mask; 276 intr &= wl->intr_mask;
268 277
269 if (intr == 0) { 278 if (intr == 0) {
270 wl1251_debug(DEBUG_IRQ, "INTR is 0"); 279 wl1251_debug(DEBUG_IRQ, "INTR is 0");
271 wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, 280 goto out_sleep;
272 ~(wl->intr_mask)); 281 }
273 282
274 goto out_sleep; 283 if (intr & WL1251_ACX_INTR_RX0_DATA) {
275 } 284 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
285 wl1251_rx(wl);
286 }
276 287
277 if (intr & WL1251_ACX_INTR_RX0_DATA) { 288 if (intr & WL1251_ACX_INTR_RX1_DATA) {
278 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA"); 289 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
279 wl1251_rx(wl); 290 wl1251_rx(wl);
280 } 291 }
281 292
282 if (intr & WL1251_ACX_INTR_RX1_DATA) { 293 if (intr & WL1251_ACX_INTR_TX_RESULT) {
283 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA"); 294 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
284 wl1251_rx(wl); 295 wl1251_tx_complete(wl);
285 } 296 }
286 297
287 if (intr & WL1251_ACX_INTR_TX_RESULT) { 298 if (intr & (WL1251_ACX_INTR_EVENT_A |
288 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT"); 299 WL1251_ACX_INTR_EVENT_B)) {
289 wl1251_tx_complete(wl); 300 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)",
290 } 301 intr);
302 if (intr & WL1251_ACX_INTR_EVENT_A)
303 wl1251_event_handle(wl, 0);
304 else
305 wl1251_event_handle(wl, 1);
306 }
291 307
292 if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) { 308 if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
293 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr); 309 wl1251_debug(DEBUG_IRQ,
294 if (intr & WL1251_ACX_INTR_EVENT_A) 310 "WL1251_ACX_INTR_INIT_COMPLETE");
295 wl1251_event_handle(wl, 0);
296 else
297 wl1251_event_handle(wl, 1);
298 }
299 311
300 if (intr & WL1251_ACX_INTR_INIT_COMPLETE) 312 if (--ctr == 0)
301 wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE"); 313 break;
302 314
303 wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); 315 intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
316 } while (intr);
304 317
305out_sleep: 318out_sleep:
319 wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
306 wl1251_ps_elp_sleep(wl); 320 wl1251_ps_elp_sleep(wl);
307 321
308out: 322out:
@@ -382,6 +396,7 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
382 * the queue here, otherwise the queue will get too long. 396 * the queue here, otherwise the queue will get too long.
383 */ 397 */
384 if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) { 398 if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
399 wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
385 ieee80211_stop_queues(wl->hw); 400 ieee80211_stop_queues(wl->hw);
386 401
387 /* 402 /*
@@ -497,17 +512,23 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
497} 512}
498 513
499static int wl1251_op_add_interface(struct ieee80211_hw *hw, 514static int wl1251_op_add_interface(struct ieee80211_hw *hw,
500 struct ieee80211_if_init_conf *conf) 515 struct ieee80211_vif *vif)
501{ 516{
502 struct wl1251 *wl = hw->priv; 517 struct wl1251 *wl = hw->priv;
503 int ret = 0; 518 int ret = 0;
504 519
505 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 520 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
506 conf->type, conf->mac_addr); 521 vif->type, vif->addr);
507 522
508 mutex_lock(&wl->mutex); 523 mutex_lock(&wl->mutex);
524 if (wl->vif) {
525 ret = -EBUSY;
526 goto out;
527 }
528
529 wl->vif = vif;
509 530
510 switch (conf->type) { 531 switch (vif->type) {
511 case NL80211_IFTYPE_STATION: 532 case NL80211_IFTYPE_STATION:
512 wl->bss_type = BSS_TYPE_STA_BSS; 533 wl->bss_type = BSS_TYPE_STA_BSS;
513 break; 534 break;
@@ -519,8 +540,8 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
519 goto out; 540 goto out;
520 } 541 }
521 542
522 if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) { 543 if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) {
523 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); 544 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
524 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); 545 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
525 ret = wl1251_acx_station_id(wl); 546 ret = wl1251_acx_station_id(wl);
526 if (ret < 0) 547 if (ret < 0)
@@ -533,44 +554,35 @@ out:
533} 554}
534 555
535static void wl1251_op_remove_interface(struct ieee80211_hw *hw, 556static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
536 struct ieee80211_if_init_conf *conf) 557 struct ieee80211_vif *vif)
537{ 558{
559 struct wl1251 *wl = hw->priv;
560
561 mutex_lock(&wl->mutex);
538 wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); 562 wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
563 wl->vif = NULL;
564 mutex_unlock(&wl->mutex);
539} 565}
540 566
541static int wl1251_build_null_data(struct wl1251 *wl) 567static int wl1251_build_qos_null_data(struct wl1251 *wl)
542{ 568{
543 struct wl12xx_null_data_template template; 569 struct ieee80211_qos_hdr template;
544 570
545 if (!is_zero_ether_addr(wl->bssid)) { 571 memset(&template, 0, sizeof(template));
546 memcpy(template.header.da, wl->bssid, ETH_ALEN);
547 memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
548 } else {
549 memset(template.header.da, 0xff, ETH_ALEN);
550 memset(template.header.bssid, 0xff, ETH_ALEN);
551 }
552
553 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
554 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
555 IEEE80211_STYPE_NULLFUNC);
556 572
557 return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template, 573 memcpy(template.addr1, wl->bssid, ETH_ALEN);
558 sizeof(template)); 574 memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
559 575 memcpy(template.addr3, wl->bssid, ETH_ALEN);
560}
561 576
562static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid) 577 template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
563{ 578 IEEE80211_STYPE_QOS_NULLFUNC |
564 struct wl12xx_ps_poll_template template; 579 IEEE80211_FCTL_TODS);
565 580
566 memcpy(template.bssid, wl->bssid, ETH_ALEN); 581 /* FIXME: not sure what priority to use here */
567 memcpy(template.ta, wl->mac_addr, ETH_ALEN); 582 template.qos_ctrl = cpu_to_le16(0);
568 template.aid = aid;
569 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
570 583
571 return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template, 584 return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
572 sizeof(template)); 585 sizeof(template));
573
574} 586}
575 587
576static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) 588static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
@@ -601,35 +613,39 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
601 goto out_sleep; 613 goto out_sleep;
602 } 614 }
603 615
604 ret = wl1251_build_null_data(wl);
605 if (ret < 0)
606 goto out_sleep;
607
608 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { 616 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
609 wl1251_debug(DEBUG_PSM, "psm enabled"); 617 wl1251_debug(DEBUG_PSM, "psm enabled");
610 618
611 wl->psm_requested = true; 619 wl->psm_requested = true;
612 620
621 wl->dtim_period = conf->ps_dtim_period;
622
623 ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
624 wl->dtim_period);
625
613 /* 626 /*
614 * We enter PSM only if we're already associated. 627 * mac80211 enables PSM only if we're already associated.
615 * If we're not, we'll enter it when joining an SSID,
616 * through the bss_info_changed() hook.
617 */ 628 */
618 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 629 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
630 if (ret < 0)
631 goto out_sleep;
619 } else if (!(conf->flags & IEEE80211_CONF_PS) && 632 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
620 wl->psm_requested) { 633 wl->psm_requested) {
621 wl1251_debug(DEBUG_PSM, "psm disabled"); 634 wl1251_debug(DEBUG_PSM, "psm disabled");
622 635
623 wl->psm_requested = false; 636 wl->psm_requested = false;
624 637
625 if (wl->psm) 638 if (wl->psm) {
626 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); 639 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
640 if (ret < 0)
641 goto out_sleep;
642 }
627 } 643 }
628 644
629 if (conf->power_level != wl->power_level) { 645 if (conf->power_level != wl->power_level) {
630 ret = wl1251_acx_tx_power(wl, conf->power_level); 646 ret = wl1251_acx_tx_power(wl, conf->power_level);
631 if (ret < 0) 647 if (ret < 0)
632 goto out; 648 goto out_sleep;
633 649
634 wl->power_level = conf->power_level; 650 wl->power_level = conf->power_level;
635 } 651 }
@@ -840,199 +856,61 @@ out:
840 return ret; 856 return ret;
841} 857}
842 858
843static int wl1251_build_basic_rates(char *rates) 859static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
844{ 860 struct cfg80211_scan_request *req)
845 u8 index = 0;
846
847 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
848 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
849 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
850 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
851
852 return index;
853}
854
855static int wl1251_build_extended_rates(char *rates)
856{ 861{
857 u8 index = 0; 862 struct wl1251 *wl = hw->priv;
858 863 struct sk_buff *skb;
859 rates[index++] = IEEE80211_OFDM_RATE_6MB; 864 size_t ssid_len = 0;
860 rates[index++] = IEEE80211_OFDM_RATE_9MB; 865 u8 *ssid = NULL;
861 rates[index++] = IEEE80211_OFDM_RATE_12MB; 866 int ret;
862 rates[index++] = IEEE80211_OFDM_RATE_18MB;
863 rates[index++] = IEEE80211_OFDM_RATE_24MB;
864 rates[index++] = IEEE80211_OFDM_RATE_36MB;
865 rates[index++] = IEEE80211_OFDM_RATE_48MB;
866 rates[index++] = IEEE80211_OFDM_RATE_54MB;
867
868 return index;
869}
870
871 867
872static int wl1251_build_probe_req(struct wl1251 *wl, u8 *ssid, size_t ssid_len) 868 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
873{
874 struct wl12xx_probe_req_template template;
875 struct wl12xx_ie_rates *rates;
876 char *ptr;
877 u16 size;
878
879 ptr = (char *)&template;
880 size = sizeof(struct ieee80211_header);
881
882 memset(template.header.da, 0xff, ETH_ALEN);
883 memset(template.header.bssid, 0xff, ETH_ALEN);
884 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
885 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
886
887 /* IEs */
888 /* SSID */
889 template.ssid.header.id = WLAN_EID_SSID;
890 template.ssid.header.len = ssid_len;
891 if (ssid_len && ssid)
892 memcpy(template.ssid.ssid, ssid, ssid_len);
893 size += sizeof(struct wl12xx_ie_header) + ssid_len;
894 ptr += size;
895
896 /* Basic Rates */
897 rates = (struct wl12xx_ie_rates *)ptr;
898 rates->header.id = WLAN_EID_SUPP_RATES;
899 rates->header.len = wl1251_build_basic_rates(rates->rates);
900 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
901 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
902
903 /* Extended rates */
904 rates = (struct wl12xx_ie_rates *)ptr;
905 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
906 rates->header.len = wl1251_build_extended_rates(rates->rates);
907 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
908
909 wl1251_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
910
911 return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
912 size);
913}
914 869
915static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len, 870 if (req->n_ssids) {
916 u8 active_scan, u8 high_prio, u8 num_channels, 871 ssid = req->ssids[0].ssid;
917 u8 probe_requests) 872 ssid_len = req->ssids[0].ssid_len;
918{
919 struct wl1251_cmd_trigger_scan_to *trigger = NULL;
920 struct cmd_scan *params = NULL;
921 int i, ret;
922 u16 scan_options = 0;
923
924 if (wl->scanning)
925 return -EINVAL;
926
927 params = kzalloc(sizeof(*params), GFP_KERNEL);
928 if (!params)
929 return -ENOMEM;
930
931 params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
932 params->params.rx_filter_options =
933 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
934
935 /* High priority scan */
936 if (!active_scan)
937 scan_options |= SCAN_PASSIVE;
938 if (high_prio)
939 scan_options |= SCAN_PRIORITY_HIGH;
940 params->params.scan_options = scan_options;
941
942 params->params.num_channels = num_channels;
943 params->params.num_probe_requests = probe_requests;
944 params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
945 params->params.tid_trigger = 0;
946
947 for (i = 0; i < num_channels; i++) {
948 params->channels[i].min_duration = cpu_to_le32(30000);
949 params->channels[i].max_duration = cpu_to_le32(60000);
950 memset(&params->channels[i].bssid_lsb, 0xff, 4);
951 memset(&params->channels[i].bssid_msb, 0xff, 2);
952 params->channels[i].early_termination = 0;
953 params->channels[i].tx_power_att = 0;
954 params->channels[i].channel = i + 1;
955 memset(params->channels[i].pad, 0, 3);
956 } 873 }
957 874
958 for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++) 875 mutex_lock(&wl->mutex);
959 memset(&params->channels[i], 0,
960 sizeof(struct basic_scan_channel_parameters));
961
962 if (len && ssid) {
963 params->params.ssid_len = len;
964 memcpy(params->params.ssid, ssid, len);
965 } else {
966 params->params.ssid_len = 0;
967 memset(params->params.ssid, 0, 32);
968 }
969 876
970 ret = wl1251_build_probe_req(wl, ssid, len); 877 if (wl->scanning) {
971 if (ret < 0) { 878 wl1251_debug(DEBUG_SCAN, "scan already in progress");
972 wl1251_error("PROBE request template failed"); 879 ret = -EINVAL;
973 goto out; 880 goto out;
974 } 881 }
975 882
976 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); 883 ret = wl1251_ps_elp_wakeup(wl);
977 if (!trigger) 884 if (ret < 0)
978 goto out; 885 goto out;
979 886
980 trigger->timeout = 0; 887 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
981 888 req->ie, req->ie_len);
982 ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, 889 if (!skb) {
983 sizeof(*trigger)); 890 ret = -ENOMEM;
984 if (ret < 0) {
985 wl1251_error("trigger scan to failed for hw scan");
986 goto out; 891 goto out;
987 } 892 }
988 893
989 wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); 894 ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
990 895 skb->len);
991 wl->scanning = true; 896 dev_kfree_skb(skb);
897 if (ret < 0)
898 goto out_sleep;
992 899
993 ret = wl1251_cmd_send(wl, CMD_SCAN, params, sizeof(*params)); 900 ret = wl1251_cmd_trigger_scan_to(wl, 0);
994 if (ret < 0) 901 if (ret < 0)
995 wl1251_error("SCAN failed"); 902 goto out_sleep;
996 903
997 wl1251_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params)); 904 wl->scanning = true;
998 905
999 if (params->header.status != CMD_STATUS_SUCCESS) { 906 ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
1000 wl1251_error("TEST command answer error: %d", 907 req->n_channels, WL1251_SCAN_NUM_PROBES);
1001 params->header.status); 908 if (ret < 0) {
1002 wl->scanning = false; 909 wl->scanning = false;
1003 ret = -EIO; 910 goto out_sleep;
1004 goto out;
1005 }
1006
1007out:
1008 kfree(params);
1009 return ret;
1010
1011}
1012
1013static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
1014 struct cfg80211_scan_request *req)
1015{
1016 struct wl1251 *wl = hw->priv;
1017 int ret;
1018 u8 *ssid = NULL;
1019 size_t ssid_len = 0;
1020
1021 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
1022
1023 if (req->n_ssids) {
1024 ssid = req->ssids[0].ssid;
1025 ssid_len = req->ssids[0].ssid_len;
1026 } 911 }
1027 912
1028 mutex_lock(&wl->mutex); 913out_sleep:
1029
1030 ret = wl1251_ps_elp_wakeup(wl);
1031 if (ret < 0)
1032 goto out;
1033
1034 ret = wl1251_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
1035
1036 wl1251_ps_elp_sleep(wl); 914 wl1251_ps_elp_sleep(wl);
1037 915
1038out: 916out:
@@ -1069,9 +947,8 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1069 struct ieee80211_bss_conf *bss_conf, 947 struct ieee80211_bss_conf *bss_conf,
1070 u32 changed) 948 u32 changed)
1071{ 949{
1072 enum wl1251_cmd_ps_mode mode;
1073 struct wl1251 *wl = hw->priv; 950 struct wl1251 *wl = hw->priv;
1074 struct sk_buff *beacon; 951 struct sk_buff *beacon, *skb;
1075 int ret; 952 int ret;
1076 953
1077 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 954 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1082,30 +959,49 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1082 if (ret < 0) 959 if (ret < 0)
1083 goto out; 960 goto out;
1084 961
962 if (changed & BSS_CHANGED_BSSID) {
963 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
964
965 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
966 if (!skb)
967 goto out_sleep;
968
969 ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
970 skb->data, skb->len);
971 dev_kfree_skb(skb);
972 if (ret < 0)
973 goto out_sleep;
974
975 ret = wl1251_build_qos_null_data(wl);
976 if (ret < 0)
977 goto out;
978
979 if (wl->bss_type != BSS_TYPE_IBSS) {
980 ret = wl1251_join(wl, wl->bss_type, wl->channel,
981 wl->beacon_int, wl->dtim_period);
982 if (ret < 0)
983 goto out_sleep;
984 }
985 }
986
1085 if (changed & BSS_CHANGED_ASSOC) { 987 if (changed & BSS_CHANGED_ASSOC) {
1086 if (bss_conf->assoc) { 988 if (bss_conf->assoc) {
1087 wl->beacon_int = bss_conf->beacon_int; 989 wl->beacon_int = bss_conf->beacon_int;
1088 wl->dtim_period = bss_conf->dtim_period;
1089
1090 /* FIXME: call join */
1091 990
1092 wl->aid = bss_conf->aid; 991 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
992 if (!skb)
993 goto out_sleep;
1093 994
1094 ret = wl1251_build_ps_poll(wl, wl->aid); 995 ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
996 skb->data,
997 skb->len);
998 dev_kfree_skb(skb);
1095 if (ret < 0) 999 if (ret < 0)
1096 goto out_sleep; 1000 goto out_sleep;
1097 1001
1098 ret = wl1251_acx_aid(wl, wl->aid); 1002 ret = wl1251_acx_aid(wl, bss_conf->aid);
1099 if (ret < 0) 1003 if (ret < 0)
1100 goto out_sleep; 1004 goto out_sleep;
1101
1102 /* If we want to go in PSM but we're not there yet */
1103 if (wl->psm_requested && !wl->psm) {
1104 mode = STATION_POWER_SAVE_MODE;
1105 ret = wl1251_ps_set_mode(wl, mode);
1106 if (ret < 0)
1107 goto out_sleep;
1108 }
1109 } else { 1005 } else {
1110 /* use defaults when not associated */ 1006 /* use defaults when not associated */
1111 wl->beacon_int = WL1251_DEFAULT_BEACON_INT; 1007 wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
@@ -1137,23 +1033,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1137 ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE); 1033 ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
1138 if (ret < 0) { 1034 if (ret < 0) {
1139 wl1251_warning("Set ctsprotect failed %d", ret); 1035 wl1251_warning("Set ctsprotect failed %d", ret);
1140 goto out;
1141 }
1142 }
1143
1144 if (changed & BSS_CHANGED_BSSID) {
1145 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1146
1147 ret = wl1251_build_null_data(wl);
1148 if (ret < 0)
1149 goto out;
1150
1151 if (wl->bss_type != BSS_TYPE_IBSS) {
1152 ret = wl1251_join(wl, wl->bss_type, wl->channel,
1153 wl->beacon_int, wl->dtim_period);
1154 if (ret < 0)
1155 goto out_sleep;
1156 wl1251_warning("Set ctsprotect failed %d", ret);
1157 goto out_sleep; 1036 goto out_sleep;
1158 } 1037 }
1159 } 1038 }
@@ -1165,7 +1044,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1165 1044
1166 if (ret < 0) { 1045 if (ret < 0) {
1167 dev_kfree_skb(beacon); 1046 dev_kfree_skb(beacon);
1168 goto out; 1047 goto out_sleep;
1169 } 1048 }
1170 1049
1171 ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data, 1050 ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
@@ -1174,13 +1053,13 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1174 dev_kfree_skb(beacon); 1053 dev_kfree_skb(beacon);
1175 1054
1176 if (ret < 0) 1055 if (ret < 0)
1177 goto out; 1056 goto out_sleep;
1178 1057
1179 ret = wl1251_join(wl, wl->bss_type, wl->beacon_int, 1058 ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
1180 wl->channel, wl->dtim_period); 1059 wl->channel, wl->dtim_period);
1181 1060
1182 if (ret < 0) 1061 if (ret < 0)
1183 goto out; 1062 goto out_sleep;
1184 } 1063 }
1185 1064
1186out_sleep: 1065out_sleep:
@@ -1251,6 +1130,49 @@ static struct ieee80211_channel wl1251_channels[] = {
1251 { .hw_value = 13, .center_freq = 2472}, 1130 { .hw_value = 13, .center_freq = 2472},
1252}; 1131};
1253 1132
1133static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1134 const struct ieee80211_tx_queue_params *params)
1135{
1136 enum wl1251_acx_ps_scheme ps_scheme;
1137 struct wl1251 *wl = hw->priv;
1138 int ret;
1139
1140 mutex_lock(&wl->mutex);
1141
1142 wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
1143
1144 ret = wl1251_ps_elp_wakeup(wl);
1145 if (ret < 0)
1146 goto out;
1147
1148 /* mac80211 uses units of 32 usec */
1149 ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
1150 params->cw_min, params->cw_max,
1151 params->aifs, params->txop * 32);
1152 if (ret < 0)
1153 goto out_sleep;
1154
1155 if (params->uapsd)
1156 ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
1157 else
1158 ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
1159
1160 ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
1161 CHANNEL_TYPE_EDCF,
1162 wl1251_tx_get_queue(queue), ps_scheme,
1163 WL1251_ACX_ACK_POLICY_LEGACY);
1164 if (ret < 0)
1165 goto out_sleep;
1166
1167out_sleep:
1168 wl1251_ps_elp_sleep(wl);
1169
1170out:
1171 mutex_unlock(&wl->mutex);
1172
1173 return ret;
1174}
1175
1254/* can't be const, mac80211 writes to this */ 1176/* can't be const, mac80211 writes to this */
1255static struct ieee80211_supported_band wl1251_band_2ghz = { 1177static struct ieee80211_supported_band wl1251_band_2ghz = {
1256 .channels = wl1251_channels, 1178 .channels = wl1251_channels,
@@ -1271,6 +1193,7 @@ static const struct ieee80211_ops wl1251_ops = {
1271 .hw_scan = wl1251_op_hw_scan, 1193 .hw_scan = wl1251_op_hw_scan,
1272 .bss_info_changed = wl1251_op_bss_info_changed, 1194 .bss_info_changed = wl1251_op_bss_info_changed,
1273 .set_rts_threshold = wl1251_op_set_rts_threshold, 1195 .set_rts_threshold = wl1251_op_set_rts_threshold,
1196 .conf_tx = wl1251_op_conf_tx,
1274}; 1197};
1275 1198
1276static int wl1251_register_hw(struct wl1251 *wl) 1199static int wl1251_register_hw(struct wl1251 *wl)
@@ -1308,12 +1231,17 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1308 wl->hw->channel_change_time = 10000; 1231 wl->hw->channel_change_time = 10000;
1309 1232
1310 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 1233 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1311 IEEE80211_HW_NOISE_DBM; 1234 IEEE80211_HW_NOISE_DBM |
1235 IEEE80211_HW_SUPPORTS_PS |
1236 IEEE80211_HW_BEACON_FILTER |
1237 IEEE80211_HW_SUPPORTS_UAPSD;
1312 1238
1313 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1239 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1314 wl->hw->wiphy->max_scan_ssids = 1; 1240 wl->hw->wiphy->max_scan_ssids = 1;
1315 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz; 1241 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
1316 1242
1243 wl->hw->queues = 4;
1244
1317 ret = wl1251_register_hw(wl); 1245 ret = wl1251_register_hw(wl);
1318 if (ret) 1246 if (ret)
1319 goto out; 1247 goto out;
@@ -1351,6 +1279,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
1351 skb_queue_head_init(&wl->tx_queue); 1279 skb_queue_head_init(&wl->tx_queue);
1352 1280
1353 INIT_WORK(&wl->filter_work, wl1251_filter_work); 1281 INIT_WORK(&wl->filter_work, wl1251_filter_work);
1282 INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
1354 wl->channel = WL1251_DEFAULT_CHANNEL; 1283 wl->channel = WL1251_DEFAULT_CHANNEL;
1355 wl->scanning = false; 1284 wl->scanning = false;
1356 wl->default_key = 0; 1285 wl->default_key = 0;
@@ -1368,6 +1297,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
1368 wl->power_level = WL1251_DEFAULT_POWER_LEVEL; 1297 wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
1369 wl->beacon_int = WL1251_DEFAULT_BEACON_INT; 1298 wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
1370 wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; 1299 wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
1300 wl->vif = NULL;
1371 1301
1372 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) 1302 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
1373 wl->tx_frames[i] = NULL; 1303 wl->tx_frames[i] = NULL;
@@ -1409,7 +1339,7 @@ int wl1251_free_hw(struct wl1251 *wl)
1409 1339
1410 kfree(wl->target_mem_map); 1340 kfree(wl->target_mem_map);
1411 kfree(wl->data_path); 1341 kfree(wl->data_path);
1412 kfree(wl->fw); 1342 vfree(wl->fw);
1413 wl->fw = NULL; 1343 wl->fw = NULL;
1414 kfree(wl->nvs); 1344 kfree(wl->nvs);
1415 wl->nvs = NULL; 1345 wl->nvs = NULL;
@@ -1426,4 +1356,5 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw);
1426MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); 1356MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
1427MODULE_LICENSE("GPL"); 1357MODULE_LICENSE("GPL");
1428MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>"); 1358MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
1429MODULE_ALIAS("spi:wl12xx"); 1359MODULE_ALIAS("spi:wl1251");
1360MODULE_FIRMWARE(WL1251_FW_NAME);