aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_cmd.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c127
1 files changed, 95 insertions, 32 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 92254d0d6c4c..6b5ba8ec94c9 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file is part of wl1271 2 * This file is part of wl1271
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009-2010 Nokia Corporation
5 * 5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 * 7 *
@@ -35,6 +35,9 @@
35#include "wl1271_acx.h" 35#include "wl1271_acx.h"
36#include "wl12xx_80211.h" 36#include "wl12xx_80211.h"
37#include "wl1271_cmd.h" 37#include "wl1271_cmd.h"
38#include "wl1271_event.h"
39
40#define WL1271_CMD_POLL_COUNT 5
38 41
39/* 42/*
40 * send command to firmware 43 * send command to firmware
@@ -52,6 +55,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
52 u32 intr; 55 u32 intr;
53 int ret = 0; 56 int ret = 0;
54 u16 status; 57 u16 status;
58 u16 poll_count = 0;
55 59
56 cmd = buf; 60 cmd = buf;
57 cmd->id = cpu_to_le16(id); 61 cmd->id = cpu_to_le16(id);
@@ -73,7 +77,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
73 goto out; 77 goto out;
74 } 78 }
75 79
76 msleep(1); 80 udelay(10);
81 poll_count++;
82 if (poll_count == WL1271_CMD_POLL_COUNT)
83 wl1271_info("cmd polling took over %d cycles",
84 poll_count);
77 85
78 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 86 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
79 } 87 }
@@ -249,6 +257,35 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
249 return ret; 257 return ret;
250} 258}
251 259
260/*
261 * Poll the mailbox event field until any of the bits in the mask is set or a
262 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
263 */
264static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
265{
266 u32 events_vector, event;
267 unsigned long timeout;
268
269 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
270
271 do {
272 if (time_after(jiffies, timeout))
273 return -ETIMEDOUT;
274
275 msleep(1);
276
277 /* read from both event fields */
278 wl1271_read(wl, wl->mbox_ptr[0], &events_vector,
279 sizeof(events_vector), false);
280 event = events_vector & mask;
281 wl1271_read(wl, wl->mbox_ptr[1], &events_vector,
282 sizeof(events_vector), false);
283 event |= events_vector & mask;
284 } while (!event);
285
286 return 0;
287}
288
252int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) 289int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
253{ 290{
254 static bool do_cal = true; 291 static bool do_cal = true;
@@ -281,20 +318,12 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
281 join->rx_config_options = cpu_to_le32(wl->rx_config); 318 join->rx_config_options = cpu_to_le32(wl->rx_config);
282 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 319 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
283 join->bss_type = bss_type; 320 join->bss_type = bss_type;
321 join->basic_rate_set = wl->basic_rate_set;
284 322
285 if (wl->band == IEEE80211_BAND_2GHZ) 323 if (wl->band == IEEE80211_BAND_5GHZ)
286 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS |
287 CONF_HW_BIT_RATE_2MBPS |
288 CONF_HW_BIT_RATE_5_5MBPS |
289 CONF_HW_BIT_RATE_11MBPS);
290 else {
291 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; 324 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
292 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_6MBPS |
293 CONF_HW_BIT_RATE_12MBPS |
294 CONF_HW_BIT_RATE_24MBPS);
295 }
296 325
297 join->beacon_interval = cpu_to_le16(WL1271_DEFAULT_BEACON_INT); 326 join->beacon_interval = cpu_to_le16(wl->beacon_int);
298 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; 327 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD;
299 328
300 join->channel = wl->channel; 329 join->channel = wl->channel;
@@ -319,11 +348,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
319 goto out_free; 348 goto out_free;
320 } 349 }
321 350
322 /* 351 ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID);
323 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to 352 if (ret < 0)
324 * simplify locking we just sleep instead, for now 353 wl1271_error("cmd join event completion error");
325 */
326 msleep(10);
327 354
328out_free: 355out_free:
329 kfree(join); 356 kfree(join);
@@ -455,7 +482,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
455 if (ret < 0) { 482 if (ret < 0) {
456 wl1271_error("tx %s cmd for channel %d failed", 483 wl1271_error("tx %s cmd for channel %d failed",
457 enable ? "start" : "stop", cmd->channel); 484 enable ? "start" : "stop", cmd->channel);
458 return ret; 485 goto out;
459 } 486 }
460 487
461 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", 488 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
@@ -547,17 +574,21 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
547 struct wl1271_cmd_trigger_scan_to *trigger = NULL; 574 struct wl1271_cmd_trigger_scan_to *trigger = NULL;
548 struct wl1271_cmd_scan *params = NULL; 575 struct wl1271_cmd_scan *params = NULL;
549 struct ieee80211_channel *channels; 576 struct ieee80211_channel *channels;
577 u32 rate;
550 int i, j, n_ch, ret; 578 int i, j, n_ch, ret;
551 u16 scan_options = 0; 579 u16 scan_options = 0;
552 u8 ieee_band; 580 u8 ieee_band;
553 581
554 if (band == WL1271_SCAN_BAND_2_4_GHZ) 582 if (band == WL1271_SCAN_BAND_2_4_GHZ) {
555 ieee_band = IEEE80211_BAND_2GHZ; 583 ieee_band = IEEE80211_BAND_2GHZ;
556 else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) 584 rate = wl->conf.tx.basic_rate;
585 } else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) {
557 ieee_band = IEEE80211_BAND_2GHZ; 586 ieee_band = IEEE80211_BAND_2GHZ;
558 else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) 587 rate = wl->conf.tx.basic_rate;
588 } else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) {
559 ieee_band = IEEE80211_BAND_5GHZ; 589 ieee_band = IEEE80211_BAND_5GHZ;
560 else 590 rate = wl->conf.tx.basic_rate_5;
591 } else
561 return -EINVAL; 592 return -EINVAL;
562 593
563 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL) 594 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL)
@@ -584,8 +615,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
584 params->params.scan_options = cpu_to_le16(scan_options); 615 params->params.scan_options = cpu_to_le16(scan_options);
585 616
586 params->params.num_probe_requests = probe_requests; 617 params->params.num_probe_requests = probe_requests;
587 /* Let the fw autodetect suitable tx_rate for probes */ 618 params->params.tx_rate = rate;
588 params->params.tx_rate = 0;
589 params->params.tid_trigger = 0; 619 params->params.tid_trigger = 0;
590 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; 620 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
591 621
@@ -666,11 +696,12 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
666 696
667out: 697out:
668 kfree(params); 698 kfree(params);
699 kfree(trigger);
669 return ret; 700 return ret;
670} 701}
671 702
672int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 703int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
673 void *buf, size_t buf_len) 704 void *buf, size_t buf_len, int index, u32 rates)
674{ 705{
675 struct wl1271_cmd_template_set *cmd; 706 struct wl1271_cmd_template_set *cmd;
676 int ret = 0; 707 int ret = 0;
@@ -688,9 +719,10 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
688 719
689 cmd->len = cpu_to_le16(buf_len); 720 cmd->len = cpu_to_le16(buf_len);
690 cmd->template_type = template_id; 721 cmd->template_type = template_id;
691 cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates); 722 cmd->enabled_rates = cpu_to_le32(rates);
692 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; 723 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
693 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; 724 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
725 cmd->index = index;
694 726
695 if (buf) 727 if (buf)
696 memcpy(cmd->template_data, buf, buf_len); 728 memcpy(cmd->template_data, buf, buf_len);
@@ -727,7 +759,8 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
727 ptr = skb->data; 759 ptr = skb->data;
728 } 760 }
729 761
730 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size); 762 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
763 WL1271_RATE_AUTOMATIC);
731 764
732out: 765out:
733 dev_kfree_skb(skb); 766 dev_kfree_skb(skb);
@@ -738,6 +771,29 @@ out:
738 771
739} 772}
740 773
774int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
775{
776 struct sk_buff *skb = NULL;
777 int ret = -ENOMEM;
778
779 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
780 if (!skb)
781 goto out;
782
783 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
784 skb->data, skb->len,
785 CMD_TEMPL_KLV_IDX_NULL_DATA,
786 WL1271_RATE_AUTOMATIC);
787
788out:
789 dev_kfree_skb(skb);
790 if (ret)
791 wl1271_warning("cmd build klv null data failed %d", ret);
792
793 return ret;
794
795}
796
741int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) 797int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
742{ 798{
743 struct sk_buff *skb; 799 struct sk_buff *skb;
@@ -748,7 +804,7 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
748 goto out; 804 goto out;
749 805
750 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, 806 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
751 skb->len); 807 skb->len, 0, wl->basic_rate);
752 808
753out: 809out:
754 dev_kfree_skb(skb); 810 dev_kfree_skb(skb);
@@ -773,10 +829,12 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
773 829
774 if (band == IEEE80211_BAND_2GHZ) 830 if (band == IEEE80211_BAND_2GHZ)
775 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 831 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
776 skb->data, skb->len); 832 skb->data, skb->len, 0,
833 wl->conf.tx.basic_rate);
777 else 834 else
778 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 835 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
779 skb->data, skb->len); 836 skb->data, skb->len, 0,
837 wl->conf.tx.basic_rate_5);
780 838
781out: 839out:
782 dev_kfree_skb(skb); 840 dev_kfree_skb(skb);
@@ -801,7 +859,8 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
801 template.qos_ctrl = cpu_to_le16(0); 859 template.qos_ctrl = cpu_to_le16(0);
802 860
803 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, 861 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
804 sizeof(template)); 862 sizeof(template), 0,
863 WL1271_RATE_AUTOMATIC);
805} 864}
806 865
807int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) 866int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
@@ -914,6 +973,10 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
914 goto out_free; 973 goto out_free;
915 } 974 }
916 975
976 ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
977 if (ret < 0)
978 wl1271_error("cmd disconnect event completion error");
979
917out_free: 980out_free:
918 kfree(cmd); 981 kfree(cmd);
919 982