aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/acx.c51
-rw-r--r--drivers/net/wireless/wl12xx/acx.h41
-rw-r--r--drivers/net/wireless/wl12xx/boot.c24
-rw-r--r--drivers/net/wireless/wl12xx/conf.h6
-rw-r--r--drivers/net/wireless/wl12xx/init.c42
-rw-r--r--drivers/net/wireless/wl12xx/main.c12
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h17
7 files changed, 183 insertions, 10 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 679bb37f0ca4..0b9cacc74903 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1342,6 +1342,57 @@ out:
1342 return ret; 1342 return ret;
1343} 1343}
1344 1344
1345/* Configure BA session initiator/receiver parameters setting in the FW. */
1346int wl1271_acx_set_ba_session(struct wl1271 *wl,
1347 enum ieee80211_back_parties direction,
1348 u8 tid_index, u8 policy)
1349{
1350 struct wl1271_acx_ba_session_policy *acx;
1351 int ret;
1352
1353 wl1271_debug(DEBUG_ACX, "acx ba session setting");
1354
1355 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1356 if (!acx) {
1357 ret = -ENOMEM;
1358 goto out;
1359 }
1360
1361 /* ANY role */
1362 acx->role_id = 0xff;
1363 acx->tid = tid_index;
1364 acx->enable = policy;
1365 acx->ba_direction = direction;
1366
1367 switch (direction) {
1368 case WLAN_BACK_INITIATOR:
1369 acx->win_size = wl->conf.ht.tx_ba_win_size;
1370 acx->inactivity_timeout = wl->conf.ht.inactivity_timeout;
1371 break;
1372 case WLAN_BACK_RECIPIENT:
1373 acx->win_size = RX_BA_WIN_SIZE;
1374 acx->inactivity_timeout = 0;
1375 break;
1376 default:
1377 wl1271_error("Incorrect acx command id=%x\n", direction);
1378 ret = -EINVAL;
1379 goto out;
1380 }
1381
1382 ret = wl1271_cmd_configure(wl,
1383 ACX_BA_SESSION_POLICY_CFG,
1384 acx,
1385 sizeof(*acx));
1386 if (ret < 0) {
1387 wl1271_warning("acx ba session setting failed: %d", ret);
1388 goto out;
1389 }
1390
1391out:
1392 kfree(acx);
1393 return ret;
1394}
1395
1345int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) 1396int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
1346{ 1397{
1347 struct wl1271_acx_fw_tsf_information *tsf_info; 1398 struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 62a269d84ebe..f643e60a566b 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1061,6 +1061,40 @@ struct wl1271_acx_ht_information {
1061 u8 padding[3]; 1061 u8 padding[3];
1062} __packed; 1062} __packed;
1063 1063
1064#define RX_BA_WIN_SIZE 8
1065
1066struct wl1271_acx_ba_session_policy {
1067 struct acx_header header;
1068 /*
1069 * Specifies role Id, Range 0-7, 0xFF means ANY role.
1070 * Future use. For now this field is irrelevant
1071 */
1072 u8 role_id;
1073 /*
1074 * Specifies Link Id, Range 0-31, 0xFF means ANY Link Id.
1075 * Not applicable if Role Id is set to ANY.
1076 */
1077 u8 link_id;
1078
1079 u8 tid;
1080
1081 u8 enable;
1082
1083 /* Windows size in number of packets */
1084 u16 win_size;
1085
1086 /*
1087 * As initiator inactivity timeout in time units(TU) of 1024us.
1088 * As receiver reserved
1089 */
1090 u16 inactivity_timeout;
1091
1092 /* Initiator = 1/Receiver = 0 */
1093 u8 ba_direction;
1094
1095 u8 padding[3];
1096} __packed;
1097
1064struct wl1271_acx_fw_tsf_information { 1098struct wl1271_acx_fw_tsf_information {
1065 struct acx_header header; 1099 struct acx_header header;
1066 1100
@@ -1134,8 +1168,8 @@ enum {
1134 ACX_RSSI_SNR_WEIGHTS = 0x0052, 1168 ACX_RSSI_SNR_WEIGHTS = 0x0052,
1135 ACX_KEEP_ALIVE_MODE = 0x0053, 1169 ACX_KEEP_ALIVE_MODE = 0x0053,
1136 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, 1170 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
1137 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, 1171 ACX_BA_SESSION_POLICY_CFG = 0x0055,
1138 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, 1172 ACX_BA_SESSION_RX_SETUP = 0x0056,
1139 ACX_PEER_HT_CAP = 0x0057, 1173 ACX_PEER_HT_CAP = 0x0057,
1140 ACX_HT_BSS_OPERATION = 0x0058, 1174 ACX_HT_BSS_OPERATION = 0x0058,
1141 ACX_COEX_ACTIVITY = 0x0059, 1175 ACX_COEX_ACTIVITY = 0x0059,
@@ -1209,6 +1243,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1209 bool allow_ht_operation); 1243 bool allow_ht_operation);
1210int wl1271_acx_set_ht_information(struct wl1271 *wl, 1244int wl1271_acx_set_ht_information(struct wl1271 *wl,
1211 u16 ht_operation_mode); 1245 u16 ht_operation_mode);
1246int wl1271_acx_set_ba_session(struct wl1271 *wl,
1247 enum ieee80211_back_parties direction,
1248 u8 tid_index, u8 policy);
1212int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); 1249int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
1213int wl1271_acx_max_tx_retry(struct wl1271 *wl); 1250int wl1271_acx_max_tx_retry(struct wl1271 *wl);
1214 1251
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index d7e036f42958..1ffbad67d2d8 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -101,6 +101,22 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
101 wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); 101 wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
102} 102}
103 103
104static void wl1271_parse_fw_ver(struct wl1271 *wl)
105{
106 int ret;
107
108 ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
109 &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
110 &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
111 &wl->chip.fw_ver[4]);
112
113 if (ret != 5) {
114 wl1271_warning("fw version incorrect value");
115 memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
116 return;
117 }
118}
119
104static void wl1271_boot_fw_version(struct wl1271 *wl) 120static void wl1271_boot_fw_version(struct wl1271 *wl)
105{ 121{
106 struct wl1271_static_data static_data; 122 struct wl1271_static_data static_data;
@@ -108,11 +124,13 @@ static void wl1271_boot_fw_version(struct wl1271 *wl)
108 wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data), 124 wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
109 false); 125 false);
110 126
111 strncpy(wl->chip.fw_ver, static_data.fw_version, 127 strncpy(wl->chip.fw_ver_str, static_data.fw_version,
112 sizeof(wl->chip.fw_ver)); 128 sizeof(wl->chip.fw_ver_str));
113 129
114 /* make sure the string is NULL-terminated */ 130 /* make sure the string is NULL-terminated */
115 wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0'; 131 wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
132
133 wl1271_parse_fw_ver(wl);
116} 134}
117 135
118static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, 136static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index f5c048c9bea4..135d837cefb1 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -1138,6 +1138,11 @@ struct conf_rf_settings {
1138 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; 1138 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
1139}; 1139};
1140 1140
1141struct conf_ht_setting {
1142 u16 tx_ba_win_size;
1143 u16 inactivity_timeout;
1144};
1145
1141struct conf_drv_settings { 1146struct conf_drv_settings {
1142 struct conf_sg_settings sg; 1147 struct conf_sg_settings sg;
1143 struct conf_rx_settings rx; 1148 struct conf_rx_settings rx;
@@ -1148,6 +1153,7 @@ struct conf_drv_settings {
1148 struct conf_roam_trigger_settings roam_trigger; 1153 struct conf_roam_trigger_settings roam_trigger;
1149 struct conf_scan_settings scan; 1154 struct conf_scan_settings scan;
1150 struct conf_rf_settings rf; 1155 struct conf_rf_settings rf;
1156 struct conf_ht_setting ht;
1151}; 1157};
1152 1158
1153#endif 1159#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index bdb61232f80c..2348eadc0de1 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -455,6 +455,43 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
455 return 0; 455 return 0;
456} 456}
457 457
458static void wl1271_check_ba_support(struct wl1271 *wl)
459{
460 /* validate FW cose ver x.x.x.50-60.x */
461 if ((wl->chip.fw_ver[3] >= WL12XX_BA_SUPPORT_FW_COST_VER2_START) &&
462 (wl->chip.fw_ver[3] < WL12XX_BA_SUPPORT_FW_COST_VER2_END)) {
463 wl->ba_support = true;
464 return;
465 }
466
467 wl->ba_support = false;
468}
469
470static int wl1271_set_ba_policies(struct wl1271 *wl)
471{
472 u8 tid_index;
473 u8 ret = 0;
474
475 /* Reset the BA RX indicators */
476 wl->ba_allowed = true;
477 wl->ba_rx_bitmap = 0;
478
479 /* validate that FW support BA */
480 wl1271_check_ba_support(wl);
481
482 if (wl->ba_support)
483 /* 802.11n initiator BA session setting */
484 for (tid_index = 0; tid_index < CONF_TX_MAX_TID_COUNT;
485 ++tid_index) {
486 ret = wl1271_acx_set_ba_session(wl, WLAN_BACK_INITIATOR,
487 tid_index, true);
488 if (ret < 0)
489 break;
490 }
491
492 return ret;
493}
494
458int wl1271_hw_init(struct wl1271 *wl) 495int wl1271_hw_init(struct wl1271 *wl)
459{ 496{
460 struct conf_tx_ac_category *conf_ac; 497 struct conf_tx_ac_category *conf_ac;
@@ -568,6 +605,11 @@ int wl1271_hw_init(struct wl1271 *wl)
568 if (ret < 0) 605 if (ret < 0)
569 goto out_free_memmap; 606 goto out_free_memmap;
570 607
608 /* Configure initiator BA sessions policies */
609 ret = wl1271_set_ba_policies(wl);
610 if (ret < 0)
611 goto out_free_memmap;
612
571 return 0; 613 return 0;
572 614
573 out_free_memmap: 615 out_free_memmap:
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 48194629c00b..01ca666b6c2d 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -274,7 +274,7 @@ static struct conf_drv_settings default_conf = {
274 .avg_weight_rssi_beacon = 20, 274 .avg_weight_rssi_beacon = 20,
275 .avg_weight_rssi_data = 10, 275 .avg_weight_rssi_data = 10,
276 .avg_weight_snr_beacon = 20, 276 .avg_weight_snr_beacon = 20,
277 .avg_weight_snr_data = 10 277 .avg_weight_snr_data = 10,
278 }, 278 },
279 .scan = { 279 .scan = {
280 .min_dwell_time_active = 7500, 280 .min_dwell_time_active = 7500,
@@ -293,6 +293,10 @@ static struct conf_drv_settings default_conf = {
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 }, 294 },
295 }, 295 },
296 .ht = {
297 .tx_ba_win_size = 64,
298 .inactivity_timeout = 10000,
299 },
296}; 300};
297 301
298static void __wl1271_op_remove_interface(struct wl1271 *wl); 302static void __wl1271_op_remove_interface(struct wl1271 *wl);
@@ -890,7 +894,7 @@ int wl1271_plt_start(struct wl1271 *wl)
890 894
891 wl->state = WL1271_STATE_PLT; 895 wl->state = WL1271_STATE_PLT;
892 wl1271_notice("firmware booted in PLT mode (%s)", 896 wl1271_notice("firmware booted in PLT mode (%s)",
893 wl->chip.fw_ver); 897 wl->chip.fw_ver_str);
894 goto out; 898 goto out;
895 899
896irq_disable: 900irq_disable:
@@ -1138,11 +1142,11 @@ power_off:
1138 1142
1139 wl->vif = vif; 1143 wl->vif = vif;
1140 wl->state = WL1271_STATE_ON; 1144 wl->state = WL1271_STATE_ON;
1141 wl1271_info("firmware booted (%s)", wl->chip.fw_ver); 1145 wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
1142 1146
1143 /* update hw/fw version info in wiphy struct */ 1147 /* update hw/fw version info in wiphy struct */
1144 wiphy->hw_version = wl->chip.id; 1148 wiphy->hw_version = wl->chip.id;
1145 strncpy(wiphy->fw_version, wl->chip.fw_ver, 1149 strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
1146 sizeof(wiphy->fw_version)); 1150 sizeof(wiphy->fw_version));
1147 1151
1148 /* 1152 /*
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index ca727e0c4ce9..e0bac79cd516 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -38,6 +38,13 @@
38#define DRIVER_NAME "wl1271" 38#define DRIVER_NAME "wl1271"
39#define DRIVER_PREFIX DRIVER_NAME ": " 39#define DRIVER_PREFIX DRIVER_NAME ": "
40 40
41/*
42 * FW versions support BA 11n
43 * versions marks x.x.x.50-60.x
44 */
45#define WL12XX_BA_SUPPORT_FW_COST_VER2_START 50
46#define WL12XX_BA_SUPPORT_FW_COST_VER2_END 60
47
41enum { 48enum {
42 DEBUG_NONE = 0, 49 DEBUG_NONE = 0,
43 DEBUG_IRQ = BIT(0), 50 DEBUG_IRQ = BIT(0),
@@ -182,10 +189,13 @@ struct wl1271_partition_set {
182 189
183struct wl1271; 190struct wl1271;
184 191
192#define WL12XX_NUM_FW_VER 5
193
185/* FIXME: I'm not sure about this structure name */ 194/* FIXME: I'm not sure about this structure name */
186struct wl1271_chip { 195struct wl1271_chip {
187 u32 id; 196 u32 id;
188 char fw_ver[21]; 197 char fw_ver_str[ETHTOOL_BUSINFO_LEN];
198 unsigned int fw_ver[WL12XX_NUM_FW_VER];
189}; 199};
190 200
191struct wl1271_stats { 201struct wl1271_stats {
@@ -460,6 +470,11 @@ struct wl1271 {
460 470
461 /* bands supported by this instance of wl12xx */ 471 /* bands supported by this instance of wl12xx */
462 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 472 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
473
474 /* RX BA constraint value */
475 bool ba_support;
476 u8 ba_allowed;
477 u8 ba_rx_bitmap;
463}; 478};
464 479
465struct wl1271_station { 480struct wl1271_station {