aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
commit5c01d5669356e13f0fb468944c1dd4c6a7e978ad (patch)
treefa43345288d7b25fac92b3b35360a177c4947313 /drivers/net/wireless/wl12xx
parentfea069152614cdeefba4b2bf80afcddb9c217fc8 (diff)
parenta5e944f1d955f3819503348426763e21e0413ba6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: Documentation/feature-removal-schedule.txt drivers/net/wireless/ath/ath5k/phy.c drivers/net/wireless/wl12xx/wl1271_main.c
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h19
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c146
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h89
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c15
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h7
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c127
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h13
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h158
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c66
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.h8
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c53
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c393
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c83
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c71
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c43
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h2
21 files changed, 912 insertions, 401 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 56b78e4b0198..4d479708158d 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -202,8 +202,8 @@ static int wl1251_chip_wakeup(struct wl1251 *wl)
202 goto out; 202 goto out;
203 } 203 }
204 204
205 /* No NVS from netlink, try to get it from the filesystem */ 205 if (wl->nvs == NULL && !wl->use_eeprom) {
206 if (wl->nvs == NULL) { 206 /* No NVS from netlink, try to get it from the filesystem */
207 ret = wl1251_fetch_nvs(wl); 207 ret = wl1251_fetch_nvs(wl);
208 if (ret < 0) 208 if (ret < 0)
209 goto out; 209 goto out;
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 3bfb59bd4635..e81474203a23 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -310,7 +310,7 @@ static int __devexit wl1251_spi_remove(struct spi_device *spi)
310 310
311static struct spi_driver wl1251_spi_driver = { 311static struct spi_driver wl1251_spi_driver = {
312 .driver = { 312 .driver = {
313 .name = "wl1251", 313 .name = DRIVER_NAME,
314 .bus = &spi_bus_type, 314 .bus = &spi_bus_type,
315 .owner = THIS_MODULE, 315 .owner = THIS_MODULE,
316 }, 316 },
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 8f11506f8310..75887e74205b 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -55,6 +55,7 @@ enum {
55 DEBUG_ACX = BIT(13), 55 DEBUG_ACX = BIT(13),
56 DEBUG_SDIO = BIT(14), 56 DEBUG_SDIO = BIT(14),
57 DEBUG_FILTERS = BIT(15), 57 DEBUG_FILTERS = BIT(15),
58 DEBUG_ADHOC = BIT(16),
58 DEBUG_ALL = ~0, 59 DEBUG_ALL = ~0,
59}; 60};
60 61
@@ -147,14 +148,7 @@ struct wl1271_nvs_file {
147 */ 148 */
148#undef WL1271_80211A_ENABLED 149#undef WL1271_80211A_ENABLED
149 150
150/* 151#define WL1271_BUSY_WORD_CNT 1
151 * FIXME: for the wl1271, a busy word count of 1 here will result in a more
152 * optimal SPI interface. There is some SPI bug however, causing RXS time outs
153 * with this mode occasionally on boot, so lets have three for now. A value of
154 * three should make sure, that the chipset will always be ready, though this
155 * will impact throughput and latencies slightly.
156 */
157#define WL1271_BUSY_WORD_CNT 3
158#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) 152#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
159 153
160#define WL1271_ELP_HW_STATE_ASLEEP 0 154#define WL1271_ELP_HW_STATE_ASLEEP 0
@@ -380,6 +374,7 @@ struct wl1271 {
380#define WL1271_FLAG_PSM_REQUESTED (8) 374#define WL1271_FLAG_PSM_REQUESTED (8)
381#define WL1271_FLAG_IRQ_PENDING (9) 375#define WL1271_FLAG_IRQ_PENDING (9)
382#define WL1271_FLAG_IRQ_RUNNING (10) 376#define WL1271_FLAG_IRQ_RUNNING (10)
377#define WL1271_FLAG_IDLE (11)
383 unsigned long flags; 378 unsigned long flags;
384 379
385 struct wl1271_partition_set part; 380 struct wl1271_partition_set part;
@@ -396,6 +391,7 @@ struct wl1271 {
396 u8 bssid[ETH_ALEN]; 391 u8 bssid[ETH_ALEN];
397 u8 mac_addr[ETH_ALEN]; 392 u8 mac_addr[ETH_ALEN];
398 u8 bss_type; 393 u8 bss_type;
394 u8 set_bss_type;
399 u8 ssid[IW_ESSID_MAX_SIZE + 1]; 395 u8 ssid[IW_ESSID_MAX_SIZE + 1];
400 u8 ssid_len; 396 u8 ssid_len;
401 int channel; 397 int channel;
@@ -452,11 +448,15 @@ struct wl1271 {
452 /* currently configured rate set */ 448 /* currently configured rate set */
453 u32 sta_rate_set; 449 u32 sta_rate_set;
454 u32 basic_rate_set; 450 u32 basic_rate_set;
451 u32 basic_rate;
455 u32 rate_set; 452 u32 rate_set;
456 453
457 /* The current band */ 454 /* The current band */
458 enum ieee80211_band band; 455 enum ieee80211_band band;
459 456
457 /* Beaconing interval (needed for ad-hoc) */
458 u32 beacon_int;
459
460 /* Default key (for WEP) */ 460 /* Default key (for WEP) */
461 u32 default_key; 461 u32 default_key;
462 462
@@ -473,6 +473,9 @@ struct wl1271 {
473 /* in dBm */ 473 /* in dBm */
474 int power_level; 474 int power_level;
475 475
476 int rssi_thold;
477 int last_rssi_event;
478
476 struct wl1271_stats stats; 479 struct wl1271_stats stats;
477 struct wl1271_debugfs debugfs; 480 struct wl1271_debugfs debugfs;
478 481
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index adaa3f2485c3..2ad086efe06e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -505,12 +505,17 @@ out:
505 return ret; 505 return ret;
506} 506}
507 507
508int wl1271_acx_conn_monit_params(struct wl1271 *wl) 508#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff
509
510int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
509{ 511{
510 struct acx_conn_monit_params *acx; 512 struct acx_conn_monit_params *acx;
513 u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
514 u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
511 int ret; 515 int ret;
512 516
513 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters"); 517 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
518 enable ? "enabled" : "disabled");
514 519
515 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 520 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
516 if (!acx) { 521 if (!acx) {
@@ -518,8 +523,13 @@ int wl1271_acx_conn_monit_params(struct wl1271 *wl)
518 goto out; 523 goto out;
519 } 524 }
520 525
521 acx->synch_fail_thold = cpu_to_le32(wl->conf.conn.synch_fail_thold); 526 if (enable) {
522 acx->bss_lose_timeout = cpu_to_le32(wl->conf.conn.bss_lose_timeout); 527 threshold = wl->conf.conn.synch_fail_thold;
528 timeout = wl->conf.conn.bss_lose_timeout;
529 }
530
531 acx->synch_fail_thold = cpu_to_le32(threshold);
532 acx->bss_lose_timeout = cpu_to_le32(timeout);
523 533
524 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, 534 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
525 acx, sizeof(*acx)); 535 acx, sizeof(*acx));
@@ -793,7 +803,7 @@ int wl1271_acx_rate_policies(struct wl1271 *wl)
793 803
794 /* configure one basic rate class */ 804 /* configure one basic rate class */
795 idx = ACX_TX_BASIC_RATE; 805 idx = ACX_TX_BASIC_RATE;
796 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set); 806 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate);
797 acx->rate_class[idx].short_retry_limit = c->short_retry_limit; 807 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
798 acx->rate_class[idx].long_retry_limit = c->long_retry_limit; 808 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
799 acx->rate_class[idx].aflags = c->aflags; 809 acx->rate_class[idx].aflags = c->aflags;
@@ -1130,3 +1140,129 @@ out:
1130 kfree(acx); 1140 kfree(acx);
1131 return ret; 1141 return ret;
1132} 1142}
1143
1144int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
1145{
1146 struct wl1271_acx_keep_alive_mode *acx = NULL;
1147 int ret = 0;
1148
1149 wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
1150
1151 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1152 if (!acx) {
1153 ret = -ENOMEM;
1154 goto out;
1155 }
1156
1157 acx->enabled = enable;
1158
1159 ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
1160 if (ret < 0) {
1161 wl1271_warning("acx keep alive mode failed: %d", ret);
1162 goto out;
1163 }
1164
1165out:
1166 kfree(acx);
1167 return ret;
1168}
1169
1170int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
1171{
1172 struct wl1271_acx_keep_alive_config *acx = NULL;
1173 int ret = 0;
1174
1175 wl1271_debug(DEBUG_ACX, "acx keep alive config");
1176
1177 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1178 if (!acx) {
1179 ret = -ENOMEM;
1180 goto out;
1181 }
1182
1183 acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
1184 acx->index = index;
1185 acx->tpl_validation = tpl_valid;
1186 acx->trigger = ACX_KEEP_ALIVE_NO_TX;
1187
1188 ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
1189 acx, sizeof(*acx));
1190 if (ret < 0) {
1191 wl1271_warning("acx keep alive config failed: %d", ret);
1192 goto out;
1193 }
1194
1195out:
1196 kfree(acx);
1197 return ret;
1198}
1199
1200int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1201 s16 thold, u8 hyst)
1202{
1203 struct wl1271_acx_rssi_snr_trigger *acx = NULL;
1204 int ret = 0;
1205
1206 wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
1207
1208 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1209 if (!acx) {
1210 ret = -ENOMEM;
1211 goto out;
1212 }
1213
1214 wl->last_rssi_event = -1;
1215
1216 acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
1217 acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
1218 acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
1219 if (enable)
1220 acx->enable = WL1271_ACX_TRIG_ENABLE;
1221 else
1222 acx->enable = WL1271_ACX_TRIG_DISABLE;
1223
1224 acx->index = WL1271_ACX_TRIG_IDX_RSSI;
1225 acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
1226 acx->threshold = cpu_to_le16(thold);
1227 acx->hysteresis = hyst;
1228
1229 ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
1230 if (ret < 0) {
1231 wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
1232 goto out;
1233 }
1234
1235out:
1236 kfree(acx);
1237 return ret;
1238}
1239
1240int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
1241{
1242 struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
1243 struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
1244 int ret = 0;
1245
1246 wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
1247
1248 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1249 if (!acx) {
1250 ret = -ENOMEM;
1251 goto out;
1252 }
1253
1254 acx->rssi_beacon = c->avg_weight_rssi_beacon;
1255 acx->rssi_data = c->avg_weight_rssi_data;
1256 acx->snr_beacon = c->avg_weight_snr_beacon;
1257 acx->snr_data = c->avg_weight_snr_data;
1258
1259 ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
1260 if (ret < 0) {
1261 wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
1262 goto out;
1263 }
1264
1265out:
1266 kfree(acx);
1267 return ret;
1268}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 8e5870fa9609..420e7e2fc021 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -915,6 +915,84 @@ struct wl1271_acx_pm_config {
915 u8 padding[3]; 915 u8 padding[3];
916} __attribute__ ((packed)); 916} __attribute__ ((packed));
917 917
918struct wl1271_acx_keep_alive_mode {
919 struct acx_header header;
920
921 u8 enabled;
922 u8 padding[3];
923} __attribute__ ((packed));
924
925enum {
926 ACX_KEEP_ALIVE_NO_TX = 0,
927 ACX_KEEP_ALIVE_PERIOD_ONLY
928};
929
930enum {
931 ACX_KEEP_ALIVE_TPL_INVALID = 0,
932 ACX_KEEP_ALIVE_TPL_VALID
933};
934
935struct wl1271_acx_keep_alive_config {
936 struct acx_header header;
937
938 __le32 period;
939 u8 index;
940 u8 tpl_validation;
941 u8 trigger;
942 u8 padding;
943} __attribute__ ((packed));
944
945enum {
946 WL1271_ACX_TRIG_TYPE_LEVEL = 0,
947 WL1271_ACX_TRIG_TYPE_EDGE,
948};
949
950enum {
951 WL1271_ACX_TRIG_DIR_LOW = 0,
952 WL1271_ACX_TRIG_DIR_HIGH,
953 WL1271_ACX_TRIG_DIR_BIDIR,
954};
955
956enum {
957 WL1271_ACX_TRIG_ENABLE = 1,
958 WL1271_ACX_TRIG_DISABLE,
959};
960
961enum {
962 WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0,
963 WL1271_ACX_TRIG_METRIC_RSSI_DATA,
964 WL1271_ACX_TRIG_METRIC_SNR_BEACON,
965 WL1271_ACX_TRIG_METRIC_SNR_DATA,
966};
967
968enum {
969 WL1271_ACX_TRIG_IDX_RSSI = 0,
970 WL1271_ACX_TRIG_COUNT = 8,
971};
972
973struct wl1271_acx_rssi_snr_trigger {
974 struct acx_header header;
975
976 __le16 threshold;
977 __le16 pacing; /* 0 - 60000 ms */
978 u8 metric;
979 u8 type;
980 u8 dir;
981 u8 hysteresis;
982 u8 index;
983 u8 enable;
984 u8 padding[2];
985};
986
987struct wl1271_acx_rssi_snr_avg_weights {
988 struct acx_header header;
989
990 u8 rssi_beacon;
991 u8 rssi_data;
992 u8 snr_beacon;
993 u8 snr_data;
994};
995
918enum { 996enum {
919 ACX_WAKE_UP_CONDITIONS = 0x0002, 997 ACX_WAKE_UP_CONDITIONS = 0x0002,
920 ACX_MEM_CFG = 0x0003, 998 ACX_MEM_CFG = 0x0003,
@@ -963,8 +1041,8 @@ enum {
963 ACX_FRAG_CFG = 0x004F, 1041 ACX_FRAG_CFG = 0x004F,
964 ACX_BET_ENABLE = 0x0050, 1042 ACX_BET_ENABLE = 0x0050,
965 ACX_RSSI_SNR_TRIGGER = 0x0051, 1043 ACX_RSSI_SNR_TRIGGER = 0x0051,
966 ACX_RSSI_SNR_WEIGHTS = 0x0051, 1044 ACX_RSSI_SNR_WEIGHTS = 0x0052,
967 ACX_KEEP_ALIVE_MODE = 0x0052, 1045 ACX_KEEP_ALIVE_MODE = 0x0053,
968 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, 1046 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
969 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, 1047 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
970 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, 1048 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
@@ -1004,7 +1082,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
1004int wl1271_acx_dco_itrim_params(struct wl1271 *wl); 1082int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
1005int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); 1083int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
1006int wl1271_acx_beacon_filter_table(struct wl1271 *wl); 1084int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
1007int wl1271_acx_conn_monit_params(struct wl1271 *wl); 1085int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable);
1008int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable); 1086int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
1009int wl1271_acx_sg_cfg(struct wl1271 *wl); 1087int wl1271_acx_sg_cfg(struct wl1271 *wl);
1010int wl1271_acx_cca_threshold(struct wl1271 *wl); 1088int wl1271_acx_cca_threshold(struct wl1271 *wl);
@@ -1031,5 +1109,10 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
1031int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, 1109int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
1032 u8 version); 1110 u8 version);
1033int wl1271_acx_pm_config(struct wl1271 *wl); 1111int wl1271_acx_pm_config(struct wl1271 *wl);
1112int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
1113int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
1114int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1115 s16 thold, u8 hyst);
1116int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);
1034 1117
1035#endif /* __WL1271_ACX_H__ */ 1118#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 1937859d74eb..8087dc17f29d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.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) 2008-2009 Nokia Corporation 4 * Copyright (C) 2008-2010 Nokia Corporation
5 * 5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 * 7 *
@@ -411,7 +411,10 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
411 /* unmask required mbox events */ 411 /* unmask required mbox events */
412 wl->event_mask = BSS_LOSE_EVENT_ID | 412 wl->event_mask = BSS_LOSE_EVENT_ID |
413 SCAN_COMPLETE_EVENT_ID | 413 SCAN_COMPLETE_EVENT_ID |
414 PS_REPORT_EVENT_ID; 414 PS_REPORT_EVENT_ID |
415 JOIN_EVENT_COMPLETE_ID |
416 DISCONNECT_EVENT_COMPLETE_ID |
417 RSSI_SNR_TRIGGER_0_EVENT_ID;
415 418
416 ret = wl1271_event_unmask(wl); 419 ret = wl1271_event_unmask(wl);
417 if (ret < 0) { 420 if (ret < 0) {
@@ -452,11 +455,15 @@ int wl1271_boot(struct wl1271 *wl)
452 455
453 if (REF_CLOCK != 0) { 456 if (REF_CLOCK != 0) {
454 u16 val; 457 u16 val;
455 /* Set clock type */ 458 /* Set clock type (open drain) */
456 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); 459 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
457 val &= FREF_CLK_TYPE_BITS; 460 val &= FREF_CLK_TYPE_BITS;
458 val |= CLK_REQ_PRCM;
459 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val); 461 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
462
463 /* Set clock pull mode (no pull) */
464 val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL);
465 val |= NO_PULL;
466 wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val);
460 } else { 467 } else {
461 u16 val; 468 u16 val;
462 /* Set clock polarity */ 469 /* Set clock polarity */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index 412443ee655a..95ecc5241959 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -53,10 +53,13 @@ struct wl1271_static_data {
53#define OCP_REG_POLARITY 0x0064 53#define OCP_REG_POLARITY 0x0064
54#define OCP_REG_CLK_TYPE 0x0448 54#define OCP_REG_CLK_TYPE 0x0448
55#define OCP_REG_CLK_POLARITY 0x0cb2 55#define OCP_REG_CLK_POLARITY 0x0cb2
56#define OCP_REG_CLK_PULL 0x0cb4
56 57
57#define CMD_MBOX_ADDRESS 0x407B4
58 58
59#define POLARITY_LOW BIT(1) 59#define CMD_MBOX_ADDRESS 0x407B4
60
61#define POLARITY_LOW BIT(1)
62#define NO_PULL (BIT(14) | BIT(15))
60 63
61#define FREF_CLK_TYPE_BITS 0xfffffe7f 64#define FREF_CLK_TYPE_BITS 0xfffffe7f
62#define CLK_REQ_PRCM 0x100 65#define CLK_REQ_PRCM 0x100
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
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index 6324bbf36843..00f78b7aa384 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -45,13 +45,14 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
45 const u8 *ie, size_t ie_len, u8 active_scan, 45 const u8 *ie, size_t ie_len, u8 active_scan,
46 u8 high_prio, u8 band, u8 probe_requests); 46 u8 high_prio, u8 band, u8 probe_requests);
47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
48 void *buf, size_t buf_len); 48 void *buf, size_t buf_len, int index, u32 rates);
49int wl1271_cmd_build_null_data(struct wl1271 *wl); 49int wl1271_cmd_build_null_data(struct wl1271 *wl);
50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); 50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
51int wl1271_cmd_build_probe_req(struct wl1271 *wl, 51int wl1271_cmd_build_probe_req(struct wl1271 *wl,
52 const u8 *ssid, size_t ssid_len, 52 const u8 *ssid, size_t ssid_len,
53 const u8 *ie, size_t ie_len, u8 band); 53 const u8 *ie, size_t ie_len, u8 band);
54int wl1271_build_qos_null_data(struct wl1271 *wl); 54int wl1271_build_qos_null_data(struct wl1271 *wl);
55int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
55int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); 56int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
56int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 57int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
57 u8 key_size, const u8 *key, const u8 *addr, 58 u8 key_size, const u8 *key, const u8 *addr,
@@ -101,6 +102,11 @@ enum wl1271_commands {
101 102
102#define MAX_CMD_PARAMS 572 103#define MAX_CMD_PARAMS 572
103 104
105enum {
106 CMD_TEMPL_KLV_IDX_NULL_DATA = 0,
107 CMD_TEMPL_KLV_IDX_MAX = 4
108};
109
104enum cmd_templ { 110enum cmd_templ {
105 CMD_TEMPL_NULL_DATA = 0, 111 CMD_TEMPL_NULL_DATA = 0,
106 CMD_TEMPL_BEACON, 112 CMD_TEMPL_BEACON,
@@ -123,6 +129,7 @@ enum cmd_templ {
123/* unit ms */ 129/* unit ms */
124#define WL1271_COMMAND_TIMEOUT 2000 130#define WL1271_COMMAND_TIMEOUT 2000
125#define WL1271_CMD_TEMPL_MAX_SIZE 252 131#define WL1271_CMD_TEMPL_MAX_SIZE 252
132#define WL1271_EVENT_TIMEOUT 100
126 133
127struct wl1271_cmd_header { 134struct wl1271_cmd_header {
128 __le16 id; 135 __le16 id;
@@ -245,6 +252,8 @@ struct cmd_enabledisable_path {
245 u8 padding[3]; 252 u8 padding[3];
246} __attribute__ ((packed)); 253} __attribute__ ((packed));
247 254
255#define WL1271_RATE_AUTOMATIC 0
256
248struct wl1271_cmd_template_set { 257struct wl1271_cmd_template_set {
249 struct wl1271_cmd_header header; 258 struct wl1271_cmd_header header;
250 259
@@ -511,6 +520,8 @@ enum wl1271_disconnect_type {
511}; 520};
512 521
513struct wl1271_cmd_disconnect { 522struct wl1271_cmd_disconnect {
523 struct wl1271_cmd_header header;
524
514 __le32 rx_config_options; 525 __le32 rx_config_options;
515 __le32 rx_filter_options; 526 __le32 rx_filter_options;
516 527
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 7fcfe06b1412..c44307c4bcf8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -66,6 +66,32 @@ enum {
66}; 66};
67 67
68enum { 68enum {
69 CONF_HW_RXTX_RATE_MCS7 = 0,
70 CONF_HW_RXTX_RATE_MCS6,
71 CONF_HW_RXTX_RATE_MCS5,
72 CONF_HW_RXTX_RATE_MCS4,
73 CONF_HW_RXTX_RATE_MCS3,
74 CONF_HW_RXTX_RATE_MCS2,
75 CONF_HW_RXTX_RATE_MCS1,
76 CONF_HW_RXTX_RATE_MCS0,
77 CONF_HW_RXTX_RATE_54,
78 CONF_HW_RXTX_RATE_48,
79 CONF_HW_RXTX_RATE_36,
80 CONF_HW_RXTX_RATE_24,
81 CONF_HW_RXTX_RATE_22,
82 CONF_HW_RXTX_RATE_18,
83 CONF_HW_RXTX_RATE_12,
84 CONF_HW_RXTX_RATE_11,
85 CONF_HW_RXTX_RATE_9,
86 CONF_HW_RXTX_RATE_6,
87 CONF_HW_RXTX_RATE_5_5,
88 CONF_HW_RXTX_RATE_2,
89 CONF_HW_RXTX_RATE_1,
90 CONF_HW_RXTX_RATE_MAX,
91 CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff
92};
93
94enum {
69 CONF_SG_DISABLE = 0, 95 CONF_SG_DISABLE = 0,
70 CONF_SG_PROTECTIVE, 96 CONF_SG_PROTECTIVE,
71 CONF_SG_OPPORTUNISTIC 97 CONF_SG_OPPORTUNISTIC
@@ -648,6 +674,19 @@ struct conf_tx_settings {
648 */ 674 */
649 u16 tx_compl_threshold; 675 u16 tx_compl_threshold;
650 676
677 /*
678 * The rate used for control messages and scanning on the 2.4GHz band
679 *
680 * Range: CONF_HW_BIT_RATE_* bit mask
681 */
682 u32 basic_rate;
683
684 /*
685 * The rate used for control messages and scanning on the 5GHz band
686 *
687 * Range: CONF_HW_BIT_RATE_* bit mask
688 */
689 u32 basic_rate_5;
651}; 690};
652 691
653enum { 692enum {
@@ -717,65 +756,6 @@ enum {
717 CONF_TRIG_EVENT_DIR_BIDIR 756 CONF_TRIG_EVENT_DIR_BIDIR
718}; 757};
719 758
720
721struct conf_sig_trigger {
722 /*
723 * The RSSI / SNR threshold value.
724 *
725 * FIXME: what is the range?
726 */
727 s16 threshold;
728
729 /*
730 * Minimum delay between two trigger events for this trigger in ms.
731 *
732 * Range: 0 - 60000
733 */
734 u16 pacing;
735
736 /*
737 * The measurement data source for this trigger.
738 *
739 * Range: CONF_TRIG_METRIC_*
740 */
741 u8 metric;
742
743 /*
744 * The trigger type of this trigger.
745 *
746 * Range: CONF_TRIG_EVENT_TYPE_*
747 */
748 u8 type;
749
750 /*
751 * The direction of the trigger.
752 *
753 * Range: CONF_TRIG_EVENT_DIR_*
754 */
755 u8 direction;
756
757 /*
758 * Hysteresis range of the trigger around the threshold (in dB)
759 *
760 * Range: u8
761 */
762 u8 hysteresis;
763
764 /*
765 * Index of the trigger rule.
766 *
767 * Range: 0 - CONF_MAX_RSSI_SNR_TRIGGERS-1
768 */
769 u8 index;
770
771 /*
772 * Enable / disable this rule (to use for clearing rules.)
773 *
774 * Range: 1 - Enabled, 2 - Not enabled
775 */
776 u8 enable;
777};
778
779struct conf_sig_weights { 759struct conf_sig_weights {
780 760
781 /* 761 /*
@@ -894,12 +874,6 @@ struct conf_conn_settings {
894 u8 ps_poll_threshold; 874 u8 ps_poll_threshold;
895 875
896 /* 876 /*
897 * Configuration of signal (rssi/snr) triggers.
898 */
899 u8 sig_trigger_count;
900 struct conf_sig_trigger sig_trigger[CONF_MAX_RSSI_SNR_TRIGGERS];
901
902 /*
903 * Configuration of signal average weights. 877 * Configuration of signal average weights.
904 */ 878 */
905 struct conf_sig_weights sig_weights; 879 struct conf_sig_weights sig_weights;
@@ -929,6 +903,22 @@ struct conf_conn_settings {
929 * Range 0 - 255 903 * Range 0 - 255
930 */ 904 */
931 u8 psm_entry_retries; 905 u8 psm_entry_retries;
906
907 /*
908 *
909 * Specifies the interval of the connection keep-alive null-func
910 * frame in ms.
911 *
912 * Range: 1000 - 3600000
913 */
914 u32 keep_alive_interval;
915
916 /*
917 * Maximum listen interval supported by the driver in units of beacons.
918 *
919 * Range: u16
920 */
921 u8 max_listen_interval;
932}; 922};
933 923
934enum { 924enum {
@@ -990,6 +980,43 @@ struct conf_pm_config_settings {
990 bool host_fast_wakeup_support; 980 bool host_fast_wakeup_support;
991}; 981};
992 982
983struct conf_roam_trigger_settings {
984 /*
985 * The minimum interval between two trigger events.
986 *
987 * Range: 0 - 60000 ms
988 */
989 u16 trigger_pacing;
990
991 /*
992 * The weight for rssi/beacon average calculation
993 *
994 * Range: 0 - 255
995 */
996 u8 avg_weight_rssi_beacon;
997
998 /*
999 * The weight for rssi/data frame average calculation
1000 *
1001 * Range: 0 - 255
1002 */
1003 u8 avg_weight_rssi_data;
1004
1005 /*
1006 * The weight for snr/beacon average calculation
1007 *
1008 * Range: 0 - 255
1009 */
1010 u8 avg_weight_snr_beacon;
1011
1012 /*
1013 * The weight for snr/data frame average calculation
1014 *
1015 * Range: 0 - 255
1016 */
1017 u8 avg_weight_snr_data;
1018};
1019
993struct conf_drv_settings { 1020struct conf_drv_settings {
994 struct conf_sg_settings sg; 1021 struct conf_sg_settings sg;
995 struct conf_rx_settings rx; 1022 struct conf_rx_settings rx;
@@ -998,6 +1025,7 @@ struct conf_drv_settings {
998 struct conf_init_settings init; 1025 struct conf_init_settings init;
999 struct conf_itrim_settings itrim; 1026 struct conf_itrim_settings itrim;
1000 struct conf_pm_config_settings pm_config; 1027 struct conf_pm_config_settings pm_config;
1028 struct conf_roam_trigger_settings roam_trigger;
1001}; 1029};
1002 1030
1003#endif 1031#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 4d35af96c597..cf37aa6eb137 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -31,14 +31,11 @@
31static int wl1271_event_scan_complete(struct wl1271 *wl, 31static int wl1271_event_scan_complete(struct wl1271 *wl,
32 struct event_mailbox *mbox) 32 struct event_mailbox *mbox)
33{ 33{
34 int size = sizeof(struct wl12xx_probe_req_template);
35 wl1271_debug(DEBUG_EVENT, "status: 0x%x", 34 wl1271_debug(DEBUG_EVENT, "status: 0x%x",
36 mbox->scheduled_scan_status); 35 mbox->scheduled_scan_status);
37 36
38 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) { 37 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
39 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { 38 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
40 wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
41 NULL, size);
42 /* 2.4 GHz band scanned, scan 5 GHz band, pretend 39 /* 2.4 GHz band scanned, scan 5 GHz band, pretend
43 * to the wl1271_cmd_scan function that we are not 40 * to the wl1271_cmd_scan function that we are not
44 * scanning as it checks that. 41 * scanning as it checks that.
@@ -52,15 +49,6 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
52 WL1271_SCAN_BAND_5_GHZ, 49 WL1271_SCAN_BAND_5_GHZ,
53 wl->scan.probe_requests); 50 wl->scan.probe_requests);
54 } else { 51 } else {
55 if (wl->scan.state == WL1271_SCAN_BAND_2_4_GHZ)
56 wl1271_cmd_template_set(wl,
57 CMD_TEMPL_CFG_PROBE_REQ_2_4,
58 NULL, size);
59 else
60 wl1271_cmd_template_set(wl,
61 CMD_TEMPL_CFG_PROBE_REQ_5,
62 NULL, size);
63
64 mutex_unlock(&wl->mutex); 52 mutex_unlock(&wl->mutex);
65 ieee80211_scan_completed(wl->hw, false); 53 ieee80211_scan_completed(wl->hw, false);
66 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
@@ -93,16 +81,9 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
93 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 81 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
94 true); 82 true);
95 } else { 83 } else {
96 wl1271_error("PSM entry failed, giving up.\n"); 84 wl1271_info("No ack to nullfunc from AP.");
97 /* FIXME: this may need to be reconsidered. for now it
98 is not possible to indicate to the mac80211
99 afterwards that PSM entry failed. To maximize
100 functionality (receiving data and remaining
101 associated) make sure that we are in sync with the
102 AP in regard of PSM mode. */
103 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
104 false);
105 wl->psm_entry_retry = 0; 85 wl->psm_entry_retry = 0;
86 *beacon_loss = true;
106 } 87 }
107 break; 88 break;
108 case EVENT_ENTER_POWER_SAVE_SUCCESS: 89 case EVENT_ENTER_POWER_SAVE_SUCCESS:
@@ -144,6 +125,24 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
144 return ret; 125 return ret;
145} 126}
146 127
128static void wl1271_event_rssi_trigger(struct wl1271 *wl,
129 struct event_mailbox *mbox)
130{
131 enum nl80211_cqm_rssi_threshold_event event;
132 s8 metric = mbox->rssi_snr_trigger_metric[0];
133
134 wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric);
135
136 if (metric <= wl->rssi_thold)
137 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
138 else
139 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
140
141 if (event != wl->last_rssi_event)
142 ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL);
143 wl->last_rssi_event = event;
144}
145
147static void wl1271_event_mbox_dump(struct event_mailbox *mbox) 146static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
148{ 147{
149 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); 148 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -173,10 +172,13 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
173 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon 172 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
174 * filtering) is enabled. Without PSM, the stack will receive all 173 * filtering) is enabled. Without PSM, the stack will receive all
175 * beacons and can detect beacon loss by itself. 174 * beacons and can detect beacon loss by itself.
175 *
176 * As there's possibility that the driver disables PSM before receiving
177 * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
178 *
176 */ 179 */
177 if (vector & BSS_LOSE_EVENT_ID && 180 if (vector & BSS_LOSE_EVENT_ID) {
178 test_bit(WL1271_FLAG_PSM, &wl->flags)) { 181 wl1271_info("Beacon loss detected.");
179 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
180 182
181 /* indicate to the stack, that beacons have been lost */ 183 /* indicate to the stack, that beacons have been lost */
182 beacon_loss = true; 184 beacon_loss = true;
@@ -189,17 +191,15 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
189 return ret; 191 return ret;
190 } 192 }
191 193
192 if (wl->vif && beacon_loss) { 194 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
193 /* Obviously, it's dangerous to release the mutex while 195 wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
194 we are holding many of the variables in the wl struct. 196 if (wl->vif)
195 That's why it's done last in the function, and care must 197 wl1271_event_rssi_trigger(wl, mbox);
196 be taken that nothing more is done after this function
197 returns. */
198 mutex_unlock(&wl->mutex);
199 ieee80211_beacon_loss(wl->vif);
200 mutex_lock(&wl->mutex);
201 } 198 }
202 199
200 if (wl->vif && beacon_loss)
201 ieee80211_connection_loss(wl->vif);
202
203 return 0; 203 return 0;
204} 204}
205 205
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
index 278f9206aa56..58371008f270 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -38,6 +38,14 @@
38 */ 38 */
39 39
40enum { 40enum {
41 RSSI_SNR_TRIGGER_0_EVENT_ID = BIT(0),
42 RSSI_SNR_TRIGGER_1_EVENT_ID = BIT(1),
43 RSSI_SNR_TRIGGER_2_EVENT_ID = BIT(2),
44 RSSI_SNR_TRIGGER_3_EVENT_ID = BIT(3),
45 RSSI_SNR_TRIGGER_4_EVENT_ID = BIT(4),
46 RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5),
47 RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6),
48 RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7),
41 MEASUREMENT_START_EVENT_ID = BIT(8), 49 MEASUREMENT_START_EVENT_ID = BIT(8),
42 MEASUREMENT_COMPLETE_EVENT_ID = BIT(9), 50 MEASUREMENT_COMPLETE_EVENT_ID = BIT(9),
43 SCAN_COMPLETE_EVENT_ID = BIT(10), 51 SCAN_COMPLETE_EVENT_ID = BIT(10),
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index e3806b035d0c..4447af1557f5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -52,50 +52,65 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
52 52
53int wl1271_init_templates_config(struct wl1271 *wl) 53int wl1271_init_templates_config(struct wl1271 *wl)
54{ 54{
55 int ret; 55 int ret, i;
56 56
57 /* send empty templates for fw memory reservation */ 57 /* send empty templates for fw memory reservation */
58 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 58 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
59 sizeof(struct wl12xx_probe_req_template)); 59 sizeof(struct wl12xx_probe_req_template),
60 0, WL1271_RATE_AUTOMATIC);
60 if (ret < 0) 61 if (ret < 0)
61 return ret; 62 return ret;
62 63
63 if (wl1271_11a_enabled()) { 64 if (wl1271_11a_enabled()) {
65 size_t size = sizeof(struct wl12xx_probe_req_template);
64 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 66 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
65 NULL, 67 NULL, size, 0,
66 sizeof(struct wl12xx_probe_req_template)); 68 WL1271_RATE_AUTOMATIC);
67 if (ret < 0) 69 if (ret < 0)
68 return ret; 70 return ret;
69 } 71 }
70 72
71 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 73 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
72 sizeof(struct wl12xx_null_data_template)); 74 sizeof(struct wl12xx_null_data_template),
75 0, WL1271_RATE_AUTOMATIC);
73 if (ret < 0) 76 if (ret < 0)
74 return ret; 77 return ret;
75 78
76 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, 79 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
77 sizeof(struct wl12xx_ps_poll_template)); 80 sizeof(struct wl12xx_ps_poll_template),
81 0, WL1271_RATE_AUTOMATIC);
78 if (ret < 0) 82 if (ret < 0)
79 return ret; 83 return ret;
80 84
81 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, 85 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
82 sizeof 86 sizeof
83 (struct wl12xx_qos_null_data_template)); 87 (struct wl12xx_qos_null_data_template),
88 0, WL1271_RATE_AUTOMATIC);
84 if (ret < 0) 89 if (ret < 0)
85 return ret; 90 return ret;
86 91
87 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, 92 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
88 sizeof 93 sizeof
89 (struct wl12xx_probe_resp_template)); 94 (struct wl12xx_probe_resp_template),
95 0, WL1271_RATE_AUTOMATIC);
90 if (ret < 0) 96 if (ret < 0)
91 return ret; 97 return ret;
92 98
93 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, 99 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
94 sizeof 100 sizeof
95 (struct wl12xx_beacon_template)); 101 (struct wl12xx_beacon_template),
102 0, WL1271_RATE_AUTOMATIC);
96 if (ret < 0) 103 if (ret < 0)
97 return ret; 104 return ret;
98 105
106 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
107 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
108 WL1271_CMD_TEMPL_MAX_SIZE, i,
109 WL1271_RATE_AUTOMATIC);
110 if (ret < 0)
111 return ret;
112 }
113
99 return 0; 114 return 0;
100} 115}
101 116
@@ -237,7 +252,7 @@ int wl1271_hw_init(struct wl1271 *wl)
237 goto out_free_memmap; 252 goto out_free_memmap;
238 253
239 /* Initialize connection monitoring thresholds */ 254 /* Initialize connection monitoring thresholds */
240 ret = wl1271_acx_conn_monit_params(wl); 255 ret = wl1271_acx_conn_monit_params(wl, false);
241 if (ret < 0) 256 if (ret < 0)
242 goto out_free_memmap; 257 goto out_free_memmap;
243 258
@@ -325,6 +340,24 @@ int wl1271_hw_init(struct wl1271 *wl)
325 if (ret < 0) 340 if (ret < 0)
326 goto out_free_memmap; 341 goto out_free_memmap;
327 342
343 /* disable all keep-alive templates */
344 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
345 ret = wl1271_acx_keep_alive_config(wl, i,
346 ACX_KEEP_ALIVE_TPL_INVALID);
347 if (ret < 0)
348 goto out_free_memmap;
349 }
350
351 /* disable the keep-alive feature */
352 ret = wl1271_acx_keep_alive_mode(wl, false);
353 if (ret < 0)
354 goto out_free_memmap;
355
356 /* Configure rssi/snr averaging weights */
357 ret = wl1271_acx_rssi_snr_avg_weights(wl);
358 if (ret < 0)
359 goto out_free_memmap;
360
328 return 0; 361 return 0;
329 362
330 out_free_memmap: 363 out_free_memmap:
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index aa970b759dd5..814f300c3f17 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -117,8 +117,7 @@ static struct conf_drv_settings default_conf = {
117 .tx = { 117 .tx = {
118 .tx_energy_detection = 0, 118 .tx_energy_detection = 0,
119 .rc_conf = { 119 .rc_conf = {
120 .enabled_rates = CONF_HW_BIT_RATE_1MBPS | 120 .enabled_rates = 0,
121 CONF_HW_BIT_RATE_2MBPS,
122 .short_retry_limit = 10, 121 .short_retry_limit = 10,
123 .long_retry_limit = 10, 122 .long_retry_limit = 10,
124 .aflags = 0 123 .aflags = 0
@@ -215,11 +214,13 @@ static struct conf_drv_settings default_conf = {
215 }, 214 },
216 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, 215 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
217 .tx_compl_timeout = 700, 216 .tx_compl_timeout = 700,
218 .tx_compl_threshold = 4 217 .tx_compl_threshold = 4,
218 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
219 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
219 }, 220 },
220 .conn = { 221 .conn = {
221 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 222 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
222 .listen_interval = 0, 223 .listen_interval = 1,
223 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, 224 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
224 .bcn_filt_ie_count = 1, 225 .bcn_filt_ie_count = 1,
225 .bcn_filt_ie = { 226 .bcn_filt_ie = {
@@ -234,38 +235,11 @@ static struct conf_drv_settings default_conf = {
234 .broadcast_timeout = 20000, 235 .broadcast_timeout = 20000,
235 .rx_broadcast_in_ps = 1, 236 .rx_broadcast_in_ps = 1,
236 .ps_poll_threshold = 20, 237 .ps_poll_threshold = 20,
237 .sig_trigger_count = 2,
238 .sig_trigger = {
239 [0] = {
240 .threshold = -75,
241 .pacing = 500,
242 .metric = CONF_TRIG_METRIC_RSSI_BEACON,
243 .type = CONF_TRIG_EVENT_TYPE_EDGE,
244 .direction = CONF_TRIG_EVENT_DIR_LOW,
245 .hysteresis = 2,
246 .index = 0,
247 .enable = 1
248 },
249 [1] = {
250 .threshold = -75,
251 .pacing = 500,
252 .metric = CONF_TRIG_METRIC_RSSI_BEACON,
253 .type = CONF_TRIG_EVENT_TYPE_EDGE,
254 .direction = CONF_TRIG_EVENT_DIR_HIGH,
255 .hysteresis = 2,
256 .index = 1,
257 .enable = 1
258 }
259 },
260 .sig_weights = {
261 .rssi_bcn_avg_weight = 10,
262 .rssi_pkt_avg_weight = 10,
263 .snr_bcn_avg_weight = 10,
264 .snr_pkt_avg_weight = 10
265 },
266 .bet_enable = CONF_BET_MODE_ENABLE, 238 .bet_enable = CONF_BET_MODE_ENABLE,
267 .bet_max_consecutive = 10, 239 .bet_max_consecutive = 10,
268 .psm_entry_retries = 3 240 .psm_entry_retries = 3,
241 .keep_alive_interval = 55000,
242 .max_listen_interval = 20,
269 }, 243 },
270 .init = { 244 .init = {
271 .radioparam = { 245 .radioparam = {
@@ -279,6 +253,14 @@ static struct conf_drv_settings default_conf = {
279 .pm_config = { 253 .pm_config = {
280 .host_clk_settling_time = 5000, 254 .host_clk_settling_time = 5000,
281 .host_fast_wakeup_support = false 255 .host_fast_wakeup_support = false
256 },
257 .roam_trigger = {
258 /* FIXME: due to firmware bug, must use value 1 for now */
259 .trigger_pacing = 1,
260 .avg_weight_rssi_beacon = 20,
261 .avg_weight_rssi_data = 10,
262 .avg_weight_snr_beacon = 20,
263 .avg_weight_snr_data = 10
282 } 264 }
283}; 265};
284 266
@@ -349,7 +331,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
349 goto out_free_memmap; 331 goto out_free_memmap;
350 332
351 /* Initialize connection monitoring thresholds */ 333 /* Initialize connection monitoring thresholds */
352 ret = wl1271_acx_conn_monit_params(wl); 334 ret = wl1271_acx_conn_monit_params(wl, false);
353 if (ret < 0) 335 if (ret < 0)
354 goto out_free_memmap; 336 goto out_free_memmap;
355 337
@@ -959,9 +941,11 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
959 switch (vif->type) { 941 switch (vif->type) {
960 case NL80211_IFTYPE_STATION: 942 case NL80211_IFTYPE_STATION:
961 wl->bss_type = BSS_TYPE_STA_BSS; 943 wl->bss_type = BSS_TYPE_STA_BSS;
944 wl->set_bss_type = BSS_TYPE_STA_BSS;
962 break; 945 break;
963 case NL80211_IFTYPE_ADHOC: 946 case NL80211_IFTYPE_ADHOC:
964 wl->bss_type = BSS_TYPE_IBSS; 947 wl->bss_type = BSS_TYPE_IBSS;
948 wl->set_bss_type = BSS_TYPE_STA_BSS;
965 break; 949 break;
966 default: 950 default:
967 ret = -EOPNOTSUPP; 951 ret = -EOPNOTSUPP;
@@ -1066,6 +1050,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1066 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1); 1050 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
1067 wl->ssid_len = 0; 1051 wl->ssid_len = 0;
1068 wl->bss_type = MAX_BSS_TYPE; 1052 wl->bss_type = MAX_BSS_TYPE;
1053 wl->set_bss_type = MAX_BSS_TYPE;
1069 wl->band = IEEE80211_BAND_2GHZ; 1054 wl->band = IEEE80211_BAND_2GHZ;
1070 1055
1071 wl->rx_counter = 0; 1056 wl->rx_counter = 0;
@@ -1088,6 +1073,14 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1088 wl->tx_blocks_freed[i] = 0; 1073 wl->tx_blocks_freed[i] = 0;
1089 1074
1090 wl1271_debugfs_reset(wl); 1075 wl1271_debugfs_reset(wl);
1076
1077 kfree(wl->fw_status);
1078 wl->fw_status = NULL;
1079 kfree(wl->tx_res_if);
1080 wl->tx_res_if = NULL;
1081 kfree(wl->target_mem_map);
1082 wl->target_mem_map = NULL;
1083
1091 mutex_unlock(&wl->mutex); 1084 mutex_unlock(&wl->mutex);
1092} 1085}
1093 1086
@@ -1138,10 +1131,7 @@ static int wl1271_join_channel(struct wl1271 *wl, int channel)
1138 /* pass through frames from all BSS */ 1131 /* pass through frames from all BSS */
1139 wl1271_configure_filters(wl, FIF_OTHER_BSS); 1132 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1140 1133
1141 /* the dummy join is performed always with STATION BSS type to allow 1134 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1142 also ad-hoc mode to listen to the surroundings without sending any
1143 beacons yet. */
1144 ret = wl1271_cmd_join(wl, BSS_TYPE_STA_BSS);
1145 if (ret < 0) 1135 if (ret < 0)
1146 goto out; 1136 goto out;
1147 1137
@@ -1171,6 +1161,32 @@ out:
1171 return ret; 1161 return ret;
1172} 1162}
1173 1163
1164static void wl1271_set_band_rate(struct wl1271 *wl)
1165{
1166 if (wl->band == IEEE80211_BAND_2GHZ)
1167 wl->basic_rate_set = wl->conf.tx.basic_rate;
1168 else
1169 wl->basic_rate_set = wl->conf.tx.basic_rate_5;
1170}
1171
1172static u32 wl1271_min_rate_get(struct wl1271 *wl)
1173{
1174 int i;
1175 u32 rate = 0;
1176
1177 if (!wl->basic_rate_set) {
1178 WARN_ON(1);
1179 wl->basic_rate_set = wl->conf.tx.basic_rate;
1180 }
1181
1182 for (i = 0; !rate; i++) {
1183 if ((wl->basic_rate_set >> i) & 0x1)
1184 rate = 1 << i;
1185 }
1186
1187 return rate;
1188}
1189
1174static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 1190static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1175{ 1191{
1176 struct wl1271 *wl = hw->priv; 1192 struct wl1271 *wl = hw->priv;
@@ -1187,12 +1203,41 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1187 1203
1188 mutex_lock(&wl->mutex); 1204 mutex_lock(&wl->mutex);
1189 1205
1190 wl->band = conf->channel->band; 1206 if (unlikely(wl->state == WL1271_STATE_OFF))
1207 goto out;
1191 1208
1192 ret = wl1271_ps_elp_wakeup(wl, false); 1209 ret = wl1271_ps_elp_wakeup(wl, false);
1193 if (ret < 0) 1210 if (ret < 0)
1194 goto out; 1211 goto out;
1195 1212
1213 /* if the channel changes while joined, join again */
1214 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1215 wl->band = conf->channel->band;
1216 wl->channel = channel;
1217
1218 /*
1219 * FIXME: the mac80211 should really provide a fixed rate
1220 * to use here. for now, just use the smallest possible rate
1221 * for the band as a fixed rate for association frames and
1222 * other control messages.
1223 */
1224 if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1225 wl1271_set_band_rate(wl);
1226
1227 wl->basic_rate = wl1271_min_rate_get(wl);
1228 ret = wl1271_acx_rate_policies(wl);
1229 if (ret < 0)
1230 wl1271_warning("rate policy for update channel "
1231 "failed %d", ret);
1232
1233 if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1234 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1235 if (ret < 0)
1236 wl1271_warning("cmd join to update channel "
1237 "failed %d", ret);
1238 }
1239 }
1240
1196 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1241 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1197 if (conf->flags & IEEE80211_CONF_IDLE && 1242 if (conf->flags & IEEE80211_CONF_IDLE &&
1198 test_bit(WL1271_FLAG_JOINED, &wl->flags)) 1243 test_bit(WL1271_FLAG_JOINED, &wl->flags))
@@ -1201,24 +1246,17 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1201 wl1271_join_channel(wl, channel); 1246 wl1271_join_channel(wl, channel);
1202 1247
1203 if (conf->flags & IEEE80211_CONF_IDLE) { 1248 if (conf->flags & IEEE80211_CONF_IDLE) {
1204 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1249 wl->rate_set = wl1271_min_rate_get(wl);
1205 wl->sta_rate_set = 0; 1250 wl->sta_rate_set = 0;
1206 wl1271_acx_rate_policies(wl); 1251 wl1271_acx_rate_policies(wl);
1207 } 1252 wl1271_acx_keep_alive_config(
1253 wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1254 ACX_KEEP_ALIVE_TPL_INVALID);
1255 set_bit(WL1271_FLAG_IDLE, &wl->flags);
1256 } else
1257 clear_bit(WL1271_FLAG_IDLE, &wl->flags);
1208 } 1258 }
1209 1259
1210 /* if the channel changes while joined, join again */
1211 if (channel != wl->channel &&
1212 test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1213 wl->channel = channel;
1214 /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */
1215 ret = wl1271_cmd_join(wl, wl->bss_type);
1216 if (ret < 0)
1217 wl1271_warning("cmd join to update channel failed %d",
1218 ret);
1219 } else
1220 wl->channel = channel;
1221
1222 if (conf->flags & IEEE80211_CONF_PS && 1260 if (conf->flags & IEEE80211_CONF_PS &&
1223 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1261 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1224 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); 1262 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
@@ -1272,6 +1310,11 @@ static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
1272{ 1310{
1273 struct wl1271_filter_params *fp; 1311 struct wl1271_filter_params *fp;
1274 struct netdev_hw_addr *ha; 1312 struct netdev_hw_addr *ha;
1313 struct wl1271 *wl = hw->priv;
1314 int i;
1315
1316 if (unlikely(wl->state == WL1271_STATE_OFF))
1317 return 0;
1275 1318
1276 fp = kzalloc(sizeof(*fp), GFP_ATOMIC); 1319 fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
1277 if (!fp) { 1320 if (!fp) {
@@ -1314,15 +1357,16 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
1314 1357
1315 mutex_lock(&wl->mutex); 1358 mutex_lock(&wl->mutex);
1316 1359
1317 if (wl->state == WL1271_STATE_OFF) 1360 *total &= WL1271_SUPPORTED_FILTERS;
1361 changed &= WL1271_SUPPORTED_FILTERS;
1362
1363 if (unlikely(wl->state == WL1271_STATE_OFF))
1318 goto out; 1364 goto out;
1319 1365
1320 ret = wl1271_ps_elp_wakeup(wl, false); 1366 ret = wl1271_ps_elp_wakeup(wl, false);
1321 if (ret < 0) 1367 if (ret < 0)
1322 goto out; 1368 goto out;
1323 1369
1324 *total &= WL1271_SUPPORTED_FILTERS;
1325 changed &= WL1271_SUPPORTED_FILTERS;
1326 1370
1327 if (*total & FIF_ALLMULTI) 1371 if (*total & FIF_ALLMULTI)
1328 ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0); 1372 ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0);
@@ -1516,10 +1560,13 @@ out:
1516static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1560static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1517{ 1561{
1518 struct wl1271 *wl = hw->priv; 1562 struct wl1271 *wl = hw->priv;
1519 int ret; 1563 int ret = 0;
1520 1564
1521 mutex_lock(&wl->mutex); 1565 mutex_lock(&wl->mutex);
1522 1566
1567 if (unlikely(wl->state == WL1271_STATE_OFF))
1568 goto out;
1569
1523 ret = wl1271_ps_elp_wakeup(wl, false); 1570 ret = wl1271_ps_elp_wakeup(wl, false);
1524 if (ret < 0) 1571 if (ret < 0)
1525 goto out; 1572 goto out;
@@ -1561,6 +1608,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1561 enum wl1271_cmd_ps_mode mode; 1608 enum wl1271_cmd_ps_mode mode;
1562 struct wl1271 *wl = hw->priv; 1609 struct wl1271 *wl = hw->priv;
1563 bool do_join = false; 1610 bool do_join = false;
1611 bool do_keepalive = false;
1564 int ret; 1612 int ret;
1565 1613
1566 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 1614 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1571,20 +1619,29 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1571 if (ret < 0) 1619 if (ret < 0)
1572 goto out; 1620 goto out;
1573 1621
1574 if (wl->bss_type == BSS_TYPE_IBSS) { 1622 if ((changed && BSS_CHANGED_BEACON_INT) &&
1575 /* FIXME: This implements rudimentary ad-hoc support - 1623 (wl->bss_type == BSS_TYPE_IBSS)) {
1576 proper templates are on the wish list and notification 1624 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d",
1577 on when they change. This patch will update the templates 1625 bss_conf->beacon_int);
1578 on every call to this function. */ 1626
1627 wl->beacon_int = bss_conf->beacon_int;
1628 do_join = true;
1629 }
1630
1631 if ((changed && BSS_CHANGED_BEACON) &&
1632 (wl->bss_type == BSS_TYPE_IBSS)) {
1579 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 1633 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1580 1634
1635 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon updated");
1636
1581 if (beacon) { 1637 if (beacon) {
1582 struct ieee80211_hdr *hdr; 1638 struct ieee80211_hdr *hdr;
1583 1639
1584 wl1271_ssid_set(wl, beacon); 1640 wl1271_ssid_set(wl, beacon);
1585 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, 1641 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1586 beacon->data, 1642 beacon->data,
1587 beacon->len); 1643 beacon->len, 0,
1644 wl1271_min_rate_get(wl));
1588 1645
1589 if (ret < 0) { 1646 if (ret < 0) {
1590 dev_kfree_skb(beacon); 1647 dev_kfree_skb(beacon);
@@ -1599,7 +1656,8 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1599 ret = wl1271_cmd_template_set(wl, 1656 ret = wl1271_cmd_template_set(wl,
1600 CMD_TEMPL_PROBE_RESPONSE, 1657 CMD_TEMPL_PROBE_RESPONSE,
1601 beacon->data, 1658 beacon->data,
1602 beacon->len); 1659 beacon->len, 0,
1660 wl1271_min_rate_get(wl));
1603 dev_kfree_skb(beacon); 1661 dev_kfree_skb(beacon);
1604 if (ret < 0) 1662 if (ret < 0)
1605 goto out_sleep; 1663 goto out_sleep;
@@ -1609,6 +1667,30 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1609 } 1667 }
1610 } 1668 }
1611 1669
1670 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1671 (wl->bss_type == BSS_TYPE_IBSS)) {
1672 wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s",
1673 bss_conf->enable_beacon ? "enabled" : "disabled");
1674
1675 if (bss_conf->enable_beacon)
1676 wl->set_bss_type = BSS_TYPE_IBSS;
1677 else
1678 wl->set_bss_type = BSS_TYPE_STA_BSS;
1679 do_join = true;
1680 }
1681
1682 if (changed & BSS_CHANGED_CQM) {
1683 bool enable = false;
1684 if (bss_conf->cqm_rssi_thold)
1685 enable = true;
1686 ret = wl1271_acx_rssi_snr_trigger(wl, enable,
1687 bss_conf->cqm_rssi_thold,
1688 bss_conf->cqm_rssi_hyst);
1689 if (ret < 0)
1690 goto out;
1691 wl->rssi_thold = bss_conf->cqm_rssi_thold;
1692 }
1693
1612 if ((changed & BSS_CHANGED_BSSID) && 1694 if ((changed & BSS_CHANGED_BSSID) &&
1613 /* 1695 /*
1614 * Now we know the correct bssid, so we send a new join command 1696 * Now we know the correct bssid, so we send a new join command
@@ -1630,10 +1712,23 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1630 1712
1631 if (changed & BSS_CHANGED_ASSOC) { 1713 if (changed & BSS_CHANGED_ASSOC) {
1632 if (bss_conf->assoc) { 1714 if (bss_conf->assoc) {
1715 u32 rates;
1633 wl->aid = bss_conf->aid; 1716 wl->aid = bss_conf->aid;
1634 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1717 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1635 1718
1636 /* 1719 /*
1720 * use basic rates from AP, and determine lowest rate
1721 * to use with control frames.
1722 */
1723 rates = bss_conf->basic_rates;
1724 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
1725 rates);
1726 wl->basic_rate = wl1271_min_rate_get(wl);
1727 ret = wl1271_acx_rate_policies(wl);
1728 if (ret < 0)
1729 goto out_sleep;
1730
1731 /*
1637 * with wl1271, we don't need to update the 1732 * with wl1271, we don't need to update the
1638 * beacon_int and dtim_period, because the firmware 1733 * beacon_int and dtim_period, because the firmware
1639 * updates it by itself when the first beacon is 1734 * updates it by itself when the first beacon is
@@ -1643,7 +1738,30 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1643 if (ret < 0) 1738 if (ret < 0)
1644 goto out_sleep; 1739 goto out_sleep;
1645 1740
1646 ret = wl1271_acx_aid(wl, wl->aid); 1741 /*
1742 * The SSID is intentionally set to NULL here - the
1743 * firmware will set the probe request with a
1744 * broadcast SSID regardless of what we set in the
1745 * template.
1746 */
1747 ret = wl1271_cmd_build_probe_req(wl, NULL, 0,
1748 NULL, 0, wl->band);
1749
1750 /* Enable the keep-alive feature */
1751 ret = wl1271_acx_keep_alive_mode(wl, true);
1752 if (ret < 0)
1753 goto out_sleep;
1754
1755 /*
1756 * This is awkward. The keep-alive configs must be done
1757 * *after* the join command, because otherwise it will
1758 * not work, but it must only be done *once* because
1759 * otherwise the firmware will start complaining.
1760 */
1761 do_keepalive = true;
1762
1763 /* enable the connection monitoring feature */
1764 ret = wl1271_acx_conn_monit_params(wl, true);
1647 if (ret < 0) 1765 if (ret < 0)
1648 goto out_sleep; 1766 goto out_sleep;
1649 1767
@@ -1659,6 +1777,22 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1659 /* use defaults when not associated */ 1777 /* use defaults when not associated */
1660 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1778 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1661 wl->aid = 0; 1779 wl->aid = 0;
1780
1781 /* revert back to minimum rates for the current band */
1782 wl1271_set_band_rate(wl);
1783 wl->basic_rate = wl1271_min_rate_get(wl);
1784 ret = wl1271_acx_rate_policies(wl);
1785 if (ret < 0)
1786 goto out_sleep;
1787
1788 /* disable connection monitor features */
1789 ret = wl1271_acx_conn_monit_params(wl, false);
1790
1791 /* Disable the keep-alive feature */
1792 ret = wl1271_acx_keep_alive_mode(wl, false);
1793
1794 if (ret < 0)
1795 goto out_sleep;
1662 } 1796 }
1663 1797
1664 } 1798 }
@@ -1693,7 +1827,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1693 } 1827 }
1694 1828
1695 if (do_join) { 1829 if (do_join) {
1696 ret = wl1271_cmd_join(wl, wl->bss_type); 1830 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1697 if (ret < 0) { 1831 if (ret < 0) {
1698 wl1271_warning("cmd join failed %d", ret); 1832 wl1271_warning("cmd join failed %d", ret);
1699 goto out_sleep; 1833 goto out_sleep;
@@ -1701,6 +1835,29 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1701 set_bit(WL1271_FLAG_JOINED, &wl->flags); 1835 set_bit(WL1271_FLAG_JOINED, &wl->flags);
1702 } 1836 }
1703 1837
1838 /*
1839 * The JOIN operation shuts down the firmware keep-alive as a side
1840 * effect, and the ACX_AID will start the keep-alive as a side effect.
1841 * Hence, for non-IBSS, the ACX_AID must always happen *after* the
1842 * JOIN operation, and the template config after the ACX_AID.
1843 */
1844 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1845 ret = wl1271_acx_aid(wl, wl->aid);
1846 if (ret < 0)
1847 goto out_sleep;
1848 }
1849
1850 if (do_keepalive) {
1851 ret = wl1271_cmd_build_klv_null_data(wl);
1852 if (ret < 0)
1853 goto out_sleep;
1854 ret = wl1271_acx_keep_alive_config(
1855 wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1856 ACX_KEEP_ALIVE_TPL_VALID);
1857 if (ret < 0)
1858 goto out_sleep;
1859 }
1860
1704out_sleep: 1861out_sleep:
1705 wl1271_ps_elp_sleep(wl); 1862 wl1271_ps_elp_sleep(wl);
1706 1863
@@ -1812,6 +1969,36 @@ static struct ieee80211_channel wl1271_channels[] = {
1812 { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, 1969 { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
1813}; 1970};
1814 1971
1972/* mapping to indexes for wl1271_rates */
1973const static u8 wl1271_rate_to_idx_2ghz[] = {
1974 /* MCS rates are used only with 11n */
1975 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
1976 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
1977 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
1978 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
1979 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
1980 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
1981 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
1982 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
1983
1984 11, /* CONF_HW_RXTX_RATE_54 */
1985 10, /* CONF_HW_RXTX_RATE_48 */
1986 9, /* CONF_HW_RXTX_RATE_36 */
1987 8, /* CONF_HW_RXTX_RATE_24 */
1988
1989 /* TI-specific rate */
1990 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
1991
1992 7, /* CONF_HW_RXTX_RATE_18 */
1993 6, /* CONF_HW_RXTX_RATE_12 */
1994 3, /* CONF_HW_RXTX_RATE_11 */
1995 5, /* CONF_HW_RXTX_RATE_9 */
1996 4, /* CONF_HW_RXTX_RATE_6 */
1997 2, /* CONF_HW_RXTX_RATE_5_5 */
1998 1, /* CONF_HW_RXTX_RATE_2 */
1999 0 /* CONF_HW_RXTX_RATE_1 */
2000};
2001
1815/* can't be const, mac80211 writes to this */ 2002/* can't be const, mac80211 writes to this */
1816static struct ieee80211_supported_band wl1271_band_2ghz = { 2003static struct ieee80211_supported_band wl1271_band_2ghz = {
1817 .channels = wl1271_channels, 2004 .channels = wl1271_channels,
@@ -1894,6 +2081,35 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
1894 { .hw_value = 165, .center_freq = 5825}, 2081 { .hw_value = 165, .center_freq = 5825},
1895}; 2082};
1896 2083
2084/* mapping to indexes for wl1271_rates_5ghz */
2085const static u8 wl1271_rate_to_idx_5ghz[] = {
2086 /* MCS rates are used only with 11n */
2087 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
2088 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
2089 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
2090 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
2091 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
2092 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
2093 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
2094 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
2095
2096 7, /* CONF_HW_RXTX_RATE_54 */
2097 6, /* CONF_HW_RXTX_RATE_48 */
2098 5, /* CONF_HW_RXTX_RATE_36 */
2099 4, /* CONF_HW_RXTX_RATE_24 */
2100
2101 /* TI-specific rate */
2102 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
2103
2104 3, /* CONF_HW_RXTX_RATE_18 */
2105 2, /* CONF_HW_RXTX_RATE_12 */
2106 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */
2107 1, /* CONF_HW_RXTX_RATE_9 */
2108 0, /* CONF_HW_RXTX_RATE_6 */
2109 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */
2110 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */
2111 CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */
2112};
1897 2113
1898static struct ieee80211_supported_band wl1271_band_5ghz = { 2114static struct ieee80211_supported_band wl1271_band_5ghz = {
1899 .channels = wl1271_channels_5ghz, 2115 .channels = wl1271_channels_5ghz,
@@ -1902,6 +2118,11 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
1902 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 2118 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
1903}; 2119};
1904 2120
2121const static u8 *wl1271_band_rate_to_idx[] = {
2122 [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
2123 [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
2124};
2125
1905static const struct ieee80211_ops wl1271_ops = { 2126static const struct ieee80211_ops wl1271_ops = {
1906 .start = wl1271_op_start, 2127 .start = wl1271_op_start,
1907 .stop = wl1271_op_stop, 2128 .stop = wl1271_op_stop,
@@ -1919,6 +2140,27 @@ static const struct ieee80211_ops wl1271_ops = {
1919 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 2140 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
1920}; 2141};
1921 2142
2143
2144u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate)
2145{
2146 u8 idx;
2147
2148 BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
2149
2150 if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
2151 wl1271_error("Illegal RX rate from HW: %d", rate);
2152 return 0;
2153 }
2154
2155 idx = wl1271_band_rate_to_idx[wl->band][rate];
2156 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
2157 wl1271_error("Unsupported RX rate from HW: %d", rate);
2158 return 0;
2159 }
2160
2161 return idx;
2162}
2163
1922static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev, 2164static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
1923 struct device_attribute *attr, 2165 struct device_attribute *attr,
1924 char *buf) 2166 char *buf)
@@ -2021,13 +2263,16 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
2021 /* unit us */ 2263 /* unit us */
2022 /* FIXME: find a proper value */ 2264 /* FIXME: find a proper value */
2023 wl->hw->channel_change_time = 10000; 2265 wl->hw->channel_change_time = 10000;
2266 wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
2024 2267
2025 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 2268 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
2026 IEEE80211_HW_NOISE_DBM | 2269 IEEE80211_HW_NOISE_DBM |
2027 IEEE80211_HW_BEACON_FILTER | 2270 IEEE80211_HW_BEACON_FILTER |
2028 IEEE80211_HW_SUPPORTS_PS | 2271 IEEE80211_HW_SUPPORTS_PS |
2029 IEEE80211_HW_SUPPORTS_UAPSD | 2272 IEEE80211_HW_SUPPORTS_UAPSD |
2030 IEEE80211_HW_HAS_RATE_CONTROL; 2273 IEEE80211_HW_HAS_RATE_CONTROL |
2274 IEEE80211_HW_CONNECTION_MONITOR |
2275 IEEE80211_HW_SUPPORTS_CQM_RSSI;
2031 2276
2032 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2277 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2033 BIT(NL80211_IFTYPE_ADHOC); 2278 BIT(NL80211_IFTYPE_ADHOC);
@@ -2038,6 +2283,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
2038 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; 2283 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
2039 2284
2040 wl->hw->queues = 4; 2285 wl->hw->queues = 4;
2286 wl->hw->max_rates = 1;
2041 2287
2042 SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); 2288 SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl));
2043 2289
@@ -2053,7 +2299,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2053 struct platform_device *plat_dev = NULL; 2299 struct platform_device *plat_dev = NULL;
2054 struct wl1271 *wl; 2300 struct wl1271 *wl;
2055 int i, ret; 2301 int i, ret;
2056 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
2057 2302
2058 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 2303 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
2059 if (!hw) { 2304 if (!hw) {
@@ -2083,6 +2328,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2083 2328
2084 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 2329 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
2085 wl->channel = WL1271_DEFAULT_CHANNEL; 2330 wl->channel = WL1271_DEFAULT_CHANNEL;
2331 wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
2086 wl->default_key = 0; 2332 wl->default_key = 0;
2087 wl->rx_counter = 0; 2333 wl->rx_counter = 0;
2088 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 2334 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
@@ -2090,6 +2336,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2090 wl->psm_entry_retry = 0; 2336 wl->psm_entry_retry = 0;
2091 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 2337 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
2092 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 2338 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
2339 wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
2093 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 2340 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
2094 wl->sta_rate_set = 0; 2341 wl->sta_rate_set = 0;
2095 wl->band = IEEE80211_BAND_2GHZ; 2342 wl->band = IEEE80211_BAND_2GHZ;
@@ -2105,13 +2352,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2105 wl->state = WL1271_STATE_OFF; 2352 wl->state = WL1271_STATE_OFF;
2106 mutex_init(&wl->mutex); 2353 mutex_init(&wl->mutex);
2107 2354
2108 /*
2109 * FIXME: we should use a zero MAC address here, but for now we
2110 * generate a random Nokia address.
2111 */
2112 memcpy(wl->mac_addr, nokia_oui, 3);
2113 get_random_bytes(wl->mac_addr + 3, 3);
2114
2115 /* Apply default driver configuration. */ 2355 /* Apply default driver configuration. */
2116 wl1271_conf_init(wl); 2356 wl1271_conf_init(wl);
2117 2357
@@ -2157,7 +2397,6 @@ int wl1271_free_hw(struct wl1271 *wl)
2157 2397
2158 wl1271_debugfs_exit(wl); 2398 wl1271_debugfs_exit(wl);
2159 2399
2160 kfree(wl->target_mem_map);
2161 vfree(wl->fw); 2400 vfree(wl->fw);
2162 wl->fw = NULL; 2401 wl->fw = NULL;
2163 kfree(wl->nvs); 2402 kfree(wl->nvs);
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index 5a04482b9353..a5e60e0403e5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -40,7 +40,8 @@ void wl1271_elp_work(struct work_struct *work)
40 mutex_lock(&wl->mutex); 40 mutex_lock(&wl->mutex);
41 41
42 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || 42 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
43 !test_bit(WL1271_FLAG_PSM, &wl->flags)) 43 (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
44 !test_bit(WL1271_FLAG_IDLE, &wl->flags)))
44 goto out; 45 goto out;
45 46
46 wl1271_debug(DEBUG_PSM, "chip to elp"); 47 wl1271_debug(DEBUG_PSM, "chip to elp");
@@ -56,7 +57,8 @@ out:
56/* Routines to toggle sleep mode while in ELP */ 57/* Routines to toggle sleep mode while in ELP */
57void wl1271_ps_elp_sleep(struct wl1271 *wl) 58void wl1271_ps_elp_sleep(struct wl1271 *wl)
58{ 59{
59 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { 60 if (test_bit(WL1271_FLAG_PSM, &wl->flags) ||
61 test_bit(WL1271_FLAG_IDLE, &wl->flags)) {
60 cancel_delayed_work(&wl->elp_work); 62 cancel_delayed_work(&wl->elp_work);
61 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 63 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
62 msecs_to_jiffies(ELP_ENTRY_DELAY)); 64 msecs_to_jiffies(ELP_ENTRY_DELAY));
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 6f1b732ae43b..57f4bfd959c8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -43,66 +43,6 @@ static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
43 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; 43 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
44} 44}
45 45
46/* The values of this table must match the wl1271_rates[] array */
47static u8 wl1271_rx_rate_to_idx[] = {
48 /* MCS rates are used only with 11n */
49 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
50 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
51 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
52 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
53 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
54 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
55 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
56 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
57
58 11, /* WL1271_RATE_54 */
59 10, /* WL1271_RATE_48 */
60 9, /* WL1271_RATE_36 */
61 8, /* WL1271_RATE_24 */
62
63 /* TI-specific rate */
64 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22 */
65
66 7, /* WL1271_RATE_18 */
67 6, /* WL1271_RATE_12 */
68 3, /* WL1271_RATE_11 */
69 5, /* WL1271_RATE_9 */
70 4, /* WL1271_RATE_6 */
71 2, /* WL1271_RATE_5_5 */
72 1, /* WL1271_RATE_2 */
73 0 /* WL1271_RATE_1 */
74};
75
76/* The values of this table must match the wl1271_rates[] array */
77static u8 wl1271_5_ghz_rx_rate_to_idx[] = {
78 /* MCS rates are used only with 11n */
79 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
80 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
81 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
82 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
83 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
84 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
85 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
86 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
87
88 7, /* WL1271_RATE_54 */
89 6, /* WL1271_RATE_48 */
90 5, /* WL1271_RATE_36 */
91 4, /* WL1271_RATE_24 */
92
93 /* TI-specific rate */
94 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22 */
95
96 3, /* WL1271_RATE_18 */
97 2, /* WL1271_RATE_12 */
98 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_11 */
99 1, /* WL1271_RATE_9 */
100 0, /* WL1271_RATE_6 */
101 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_5_5 */
102 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_2 */
103 WL1271_RX_RATE_UNSUPPORTED /* WL1271_RATE_1 */
104};
105
106static void wl1271_rx_status(struct wl1271 *wl, 46static void wl1271_rx_status(struct wl1271 *wl,
107 struct wl1271_rx_descriptor *desc, 47 struct wl1271_rx_descriptor *desc,
108 struct ieee80211_rx_status *status, 48 struct ieee80211_rx_status *status,
@@ -110,20 +50,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
110{ 50{
111 memset(status, 0, sizeof(struct ieee80211_rx_status)); 51 memset(status, 0, sizeof(struct ieee80211_rx_status));
112 52
113 if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == 53 status->band = wl->band;
114 WL1271_RX_DESC_BAND_BG) { 54 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
115 status->band = IEEE80211_BAND_2GHZ;
116 status->rate_idx = wl1271_rx_rate_to_idx[desc->rate];
117 } else if ((desc->flags & WL1271_RX_DESC_BAND_MASK) ==
118 WL1271_RX_DESC_BAND_A) {
119 status->band = IEEE80211_BAND_5GHZ;
120 status->rate_idx = wl1271_5_ghz_rx_rate_to_idx[desc->rate];
121 } else
122 wl1271_warning("unsupported band 0x%x",
123 desc->flags & WL1271_RX_DESC_BAND_MASK);
124
125 if (unlikely(status->rate_idx == WL1271_RX_RATE_UNSUPPORTED))
126 wl1271_warning("unsupported rate");
127 55
128 /* 56 /*
129 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the 57 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the
@@ -133,13 +61,6 @@ static void wl1271_rx_status(struct wl1271 *wl,
133 */ 61 */
134 status->signal = desc->rssi; 62 status->signal = desc->rssi;
135 63
136 /*
137 * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we
138 * need to divide by two for now, but TI has been discussing about
139 * changing it. This needs to be rechecked.
140 */
141 status->noise = desc->rssi - (desc->snr >> 1);
142
143 status->freq = ieee80211_channel_to_frequency(desc->channel); 64 status->freq = ieee80211_channel_to_frequency(desc->channel);
144 65
145 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { 66 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h
index 1ae6d1783ed4..b89be4758e78 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.h
@@ -43,7 +43,6 @@
43#define RX_MAX_PACKET_ID 3 43#define RX_MAX_PACKET_ID 3
44 44
45#define NUM_RX_PKT_DESC_MOD_MASK 7 45#define NUM_RX_PKT_DESC_MOD_MASK 7
46#define WL1271_RX_RATE_UNSUPPORTED 0xFF
47 46
48#define RX_DESC_VALID_FCS 0x0001 47#define RX_DESC_VALID_FCS 0x0001
49#define RX_DESC_MATCH_RXADDR1 0x0002 48#define RX_DESC_MATCH_RXADDR1 0x0002
@@ -117,5 +116,6 @@ struct wl1271_rx_descriptor {
117} __attribute__ ((packed)); 116} __attribute__ ((packed));
118 117
119void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); 118void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
119u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
120 120
121#endif 121#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 3c03de74dbfc..d3d6f302f705 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -117,7 +117,7 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
117 else 117 else
118 ret = sdio_memcpy_fromio(func, buf, addr, len); 118 ret = sdio_memcpy_fromio(func, buf, addr, len);
119 119
120 wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %d bytes", 120 wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes",
121 addr, len); 121 addr, len);
122 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); 122 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
123 } 123 }
@@ -138,7 +138,7 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
138 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", 138 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
139 addr, ((u8 *)buf)[0]); 139 addr, ((u8 *)buf)[0]);
140 } else { 140 } else {
141 wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %d bytes", 141 wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes",
142 addr, len); 142 addr, len);
143 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); 143 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
144 144
@@ -255,7 +255,7 @@ static void __devexit wl1271_remove(struct sdio_func *func)
255} 255}
256 256
257static struct sdio_driver wl1271_sdio_driver = { 257static struct sdio_driver wl1271_sdio_driver = {
258 .name = "wl1271", 258 .name = "wl1271_sdio",
259 .id_table = wl1271_devices, 259 .id_table = wl1271_devices,
260 .probe = wl1271_probe, 260 .probe = wl1271_probe,
261 .remove = __devexit_p(wl1271_remove), 261 .remove = __devexit_p(wl1271_remove),
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 256e84ad0baf..5189b812f939 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -105,6 +105,7 @@ static void wl1271_spi_reset(struct wl1271 *wl)
105 spi_message_add_tail(&t, &m); 105 spi_message_add_tail(&t, &m);
106 106
107 spi_sync(wl_to_spi(wl), &m); 107 spi_sync(wl_to_spi(wl), &m);
108 kfree(cmd);
108 109
109 wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); 110 wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
110} 111}
@@ -159,47 +160,24 @@ static void wl1271_spi_init(struct wl1271 *wl)
159 spi_message_add_tail(&t, &m); 160 spi_message_add_tail(&t, &m);
160 161
161 spi_sync(wl_to_spi(wl), &m); 162 spi_sync(wl_to_spi(wl), &m);
163 kfree(cmd);
162 164
163 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); 165 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
164} 166}
165 167
166#define WL1271_BUSY_WORD_TIMEOUT 1000 168#define WL1271_BUSY_WORD_TIMEOUT 1000
167 169
168/* FIXME: Check busy words, removed due to SPI bug */ 170static int wl1271_spi_read_busy(struct wl1271 *wl)
169#if 0
170static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
171{ 171{
172 struct spi_transfer t[1]; 172 struct spi_transfer t[1];
173 struct spi_message m; 173 struct spi_message m;
174 u32 *busy_buf; 174 u32 *busy_buf;
175 int num_busy_bytes = 0; 175 int num_busy_bytes = 0;
176 176
177 wl1271_info("spi read BUSY!");
178
179 /*
180 * Look for the non-busy word in the read buffer, and if found,
181 * read in the remaining data into the buffer.
182 */
183 busy_buf = (u32 *)buf;
184 for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
185 num_busy_bytes += sizeof(u32);
186 if (*busy_buf & 0x1) {
187 spi_message_init(&m);
188 memset(t, 0, sizeof(t));
189 memmove(buf, busy_buf, len - num_busy_bytes);
190 t[0].rx_buf = buf + (len - num_busy_bytes);
191 t[0].len = num_busy_bytes;
192 spi_message_add_tail(&t[0], &m);
193 spi_sync(wl_to_spi(wl), &m);
194 return;
195 }
196 }
197
198 /* 177 /*
199 * Read further busy words from SPI until a non-busy word is 178 * Read further busy words from SPI until a non-busy word is
200 * encountered, then read the data itself into the buffer. 179 * encountered, then read the data itself into the buffer.
201 */ 180 */
202 wl1271_info("spi read BUSY-polling needed!");
203 181
204 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT; 182 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
205 busy_buf = wl->buffer_busyword; 183 busy_buf = wl->buffer_busyword;
@@ -209,28 +187,21 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
209 memset(t, 0, sizeof(t)); 187 memset(t, 0, sizeof(t));
210 t[0].rx_buf = busy_buf; 188 t[0].rx_buf = busy_buf;
211 t[0].len = sizeof(u32); 189 t[0].len = sizeof(u32);
190 t[0].cs_change = true;
212 spi_message_add_tail(&t[0], &m); 191 spi_message_add_tail(&t[0], &m);
213 spi_sync(wl_to_spi(wl), &m); 192 spi_sync(wl_to_spi(wl), &m);
214 193
215 if (*busy_buf & 0x1) { 194 if (*busy_buf & 0x1)
216 spi_message_init(&m); 195 return 0;
217 memset(t, 0, sizeof(t));
218 t[0].rx_buf = buf;
219 t[0].len = len;
220 spi_message_add_tail(&t[0], &m);
221 spi_sync(wl_to_spi(wl), &m);
222 return;
223 }
224 } 196 }
225 197
226 /* The SPI bus is unresponsive, the read failed. */ 198 /* The SPI bus is unresponsive, the read failed. */
227 memset(buf, 0, len);
228 wl1271_error("SPI read busy-word timeout!\n"); 199 wl1271_error("SPI read busy-word timeout!\n");
200 return -ETIMEDOUT;
229} 201}
230#endif
231 202
232static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, 203static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
233 size_t len, bool fixed) 204 size_t len, bool fixed)
234{ 205{
235 struct spi_transfer t[3]; 206 struct spi_transfer t[3];
236 struct spi_message m; 207 struct spi_message m;
@@ -253,22 +224,32 @@ static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
253 224
254 t[0].tx_buf = cmd; 225 t[0].tx_buf = cmd;
255 t[0].len = 4; 226 t[0].len = 4;
227 t[0].cs_change = true;
256 spi_message_add_tail(&t[0], &m); 228 spi_message_add_tail(&t[0], &m);
257 229
258 /* Busy and non busy words read */ 230 /* Busy and non busy words read */
259 t[1].rx_buf = busy_buf; 231 t[1].rx_buf = busy_buf;
260 t[1].len = WL1271_BUSY_WORD_LEN; 232 t[1].len = WL1271_BUSY_WORD_LEN;
233 t[1].cs_change = true;
261 spi_message_add_tail(&t[1], &m); 234 spi_message_add_tail(&t[1], &m);
262 235
263 t[2].rx_buf = buf;
264 t[2].len = len;
265 spi_message_add_tail(&t[2], &m);
266
267 spi_sync(wl_to_spi(wl), &m); 236 spi_sync(wl_to_spi(wl), &m);
268 237
269 /* FIXME: Check busy words, removed due to SPI bug */ 238 if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
270 /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1)) 239 wl1271_spi_read_busy(wl)) {
271 wl1271_spi_read_busy(wl, buf, len); */ 240 memset(buf, 0, len);
241 return;
242 }
243
244 spi_message_init(&m);
245 memset(t, 0, sizeof(t));
246
247 t[0].rx_buf = buf;
248 t[0].len = len;
249 t[0].cs_change = true;
250 spi_message_add_tail(&t[0], &m);
251
252 spi_sync(wl_to_spi(wl), &m);
272 253
273 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); 254 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
274 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); 255 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
@@ -443,7 +424,7 @@ static int __devexit wl1271_remove(struct spi_device *spi)
443 424
444static struct spi_driver wl1271_spi_driver = { 425static struct spi_driver wl1271_spi_driver = {
445 .driver = { 426 .driver = {
446 .name = "wl1271", 427 .name = "wl1271_spi",
447 .bus = &spi_bus_type, 428 .bus = &spi_bus_type,
448 .owner = THIS_MODULE, 429 .owner = THIS_MODULE,
449 }, 430 },
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 6d109df9a0a0..62db79508ddf 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -220,7 +220,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
220 return ret; 220 return ret;
221} 221}
222 222
223static u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) 223u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
224{ 224{
225 struct ieee80211_supported_band *band; 225 struct ieee80211_supported_band *band;
226 u32 enabled_rates = 0; 226 u32 enabled_rates = 0;
@@ -304,6 +304,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
304 struct ieee80211_tx_info *info; 304 struct ieee80211_tx_info *info;
305 struct sk_buff *skb; 305 struct sk_buff *skb;
306 int id = result->id; 306 int id = result->id;
307 int rate = -1;
308 u8 retries = 0;
307 309
308 /* check for id legality */ 310 /* check for id legality */
309 if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) { 311 if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) {
@@ -314,19 +316,22 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
314 skb = wl->tx_frames[id]; 316 skb = wl->tx_frames[id];
315 info = IEEE80211_SKB_CB(skb); 317 info = IEEE80211_SKB_CB(skb);
316 318
317 /* update packet status */ 319 /* update the TX status info */
318 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { 320 if (result->status == TX_SUCCESS) {
319 if (result->status == TX_SUCCESS) 321 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
320 info->flags |= IEEE80211_TX_STAT_ACK; 322 info->flags |= IEEE80211_TX_STAT_ACK;
321 if (result->status & TX_RETRY_EXCEEDED) { 323 rate = wl1271_rate_to_idx(wl, result->rate_class_index);
322 /* FIXME */ 324 retries = result->ack_failures;
323 /* info->status.excessive_retries = 1; */ 325 } else if (result->status == TX_RETRY_EXCEEDED) {
324 wl->stats.excessive_retries++; 326 wl->stats.excessive_retries++;
325 } 327 retries = result->ack_failures;
326 } 328 }
327 329
328 /* FIXME */ 330 info->status.rates[0].idx = rate;
329 /* info->status.retry_count = result->ack_failures; */ 331 info->status.rates[0].count = retries;
332 info->status.rates[0].flags = 0;
333 info->status.ack_signal = -1;
334
330 wl->stats.retry_count += result->ack_failures; 335 wl->stats.retry_count += result->ack_failures;
331 336
332 /* update security sequence number */ 337 /* update security sequence number */
@@ -350,8 +355,6 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
350 result->id, skb, result->ack_failures, 355 result->id, skb, result->ack_failures,
351 result->rate_class_index, result->status); 356 result->rate_class_index, result->status);
352 357
353 /* FIXME: do we need to tell the stack about the used rate? */
354
355 /* return the packet to the stack */ 358 /* return the packet to the stack */
356 ieee80211_tx_status(wl->hw, skb); 359 ieee80211_tx_status(wl->hw, skb);
357 wl->tx_frames[result->id] = NULL; 360 wl->tx_frames[result->id] = NULL;
@@ -413,31 +416,19 @@ void wl1271_tx_flush(struct wl1271 *wl)
413{ 416{
414 int i; 417 int i;
415 struct sk_buff *skb; 418 struct sk_buff *skb;
416 struct ieee80211_tx_info *info;
417 419
418 /* TX failure */ 420 /* TX failure */
419/* control->flags = 0; FIXME */ 421/* control->flags = 0; FIXME */
420 422
421 while ((skb = skb_dequeue(&wl->tx_queue))) { 423 while ((skb = skb_dequeue(&wl->tx_queue))) {
422 info = IEEE80211_SKB_CB(skb);
423
424 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb); 424 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb);
425
426 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
427 continue;
428
429 ieee80211_tx_status(wl->hw, skb); 425 ieee80211_tx_status(wl->hw, skb);
430 } 426 }
431 427
432 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 428 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
433 if (wl->tx_frames[i] != NULL) { 429 if (wl->tx_frames[i] != NULL) {
434 skb = wl->tx_frames[i]; 430 skb = wl->tx_frames[i];
435 info = IEEE80211_SKB_CB(skb);
436
437 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
438 continue;
439
440 ieee80211_tx_status(wl->hw, skb);
441 wl->tx_frames[i] = NULL; 431 wl->tx_frames[i] = NULL;
432 ieee80211_tx_status(wl->hw, skb);
442 } 433 }
443} 434}
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 5e6c27a57415..3b8b7ac253fd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -159,5 +159,7 @@ static inline int wl1271_tx_ac_to_tid(int ac)
159void wl1271_tx_work(struct work_struct *work); 159void wl1271_tx_work(struct work_struct *work);
160void wl1271_tx_complete(struct wl1271 *wl); 160void wl1271_tx_complete(struct wl1271 *wl);
161void wl1271_tx_flush(struct wl1271 *wl); 161void wl1271_tx_flush(struct wl1271 *wl);
162u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
163u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
162 164
163#endif 165#endif