diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 19:29:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 19:29:25 -0400 |
commit | 7a6362800cb7d1d618a697a650c7aaed3eb39320 (patch) | |
tree | 087f9bc6c13ef1fad4b392c5cf9325cd28fa8523 /drivers/net/wireless/wl12xx/acx.c | |
parent | 6445ced8670f37cfc2c5e24a9de9b413dbfc788d (diff) | |
parent | ceda86a108671294052cbf51660097b6534672f5 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1480 commits)
bonding: enable netpoll without checking link status
xfrm: Refcount destination entry on xfrm_lookup
net: introduce rx_handler results and logic around that
bonding: get rid of IFF_SLAVE_INACTIVE netdev->priv_flag
bonding: wrap slave state work
net: get rid of multiple bond-related netdevice->priv_flags
bonding: register slave pointer for rx_handler
be2net: Bump up the version number
be2net: Copyright notice change. Update to Emulex instead of ServerEngines
e1000e: fix kconfig for crc32 dependency
netfilter ebtables: fix xt_AUDIT to work with ebtables
xen network backend driver
bonding: Improve syslog message at device creation time
bonding: Call netif_carrier_off after register_netdevice
bonding: Incorrect TX queue offset
net_sched: fix ip_tos2prio
xfrm: fix __xfrm_route_forward()
be2net: Fix UDP packet detected status in RX compl
Phonet: fix aligned-mode pipe socket buffer header reserve
netxen: support for GbE port settings
...
Fix up conflicts in drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
with the staging updates.
Diffstat (limited to 'drivers/net/wireless/wl12xx/acx.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.c | 277 |
1 files changed, 255 insertions, 22 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index cc4068d2b4a8..a3db755ceeda 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c | |||
@@ -751,10 +751,10 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) | |||
751 | return 0; | 751 | return 0; |
752 | } | 752 | } |
753 | 753 | ||
754 | int wl1271_acx_rate_policies(struct wl1271 *wl) | 754 | int wl1271_acx_sta_rate_policies(struct wl1271 *wl) |
755 | { | 755 | { |
756 | struct acx_rate_policy *acx; | 756 | struct acx_sta_rate_policy *acx; |
757 | struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf; | 757 | struct conf_tx_rate_class *c = &wl->conf.tx.sta_rc_conf; |
758 | int idx = 0; | 758 | int idx = 0; |
759 | int ret = 0; | 759 | int ret = 0; |
760 | 760 | ||
@@ -783,6 +783,10 @@ int wl1271_acx_rate_policies(struct wl1271 *wl) | |||
783 | 783 | ||
784 | acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); | 784 | acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); |
785 | 785 | ||
786 | wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x", | ||
787 | acx->rate_class[ACX_TX_BASIC_RATE].enabled_rates, | ||
788 | acx->rate_class[ACX_TX_AP_FULL_RATE].enabled_rates); | ||
789 | |||
786 | ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); | 790 | ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); |
787 | if (ret < 0) { | 791 | if (ret < 0) { |
788 | wl1271_warning("Setting of rate policies failed: %d", ret); | 792 | wl1271_warning("Setting of rate policies failed: %d", ret); |
@@ -794,6 +798,38 @@ out: | |||
794 | return ret; | 798 | return ret; |
795 | } | 799 | } |
796 | 800 | ||
801 | int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, | ||
802 | u8 idx) | ||
803 | { | ||
804 | struct acx_ap_rate_policy *acx; | ||
805 | int ret = 0; | ||
806 | |||
807 | wl1271_debug(DEBUG_ACX, "acx ap rate policy"); | ||
808 | |||
809 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
810 | if (!acx) { | ||
811 | ret = -ENOMEM; | ||
812 | goto out; | ||
813 | } | ||
814 | |||
815 | acx->rate_policy.enabled_rates = cpu_to_le32(c->enabled_rates); | ||
816 | acx->rate_policy.short_retry_limit = c->short_retry_limit; | ||
817 | acx->rate_policy.long_retry_limit = c->long_retry_limit; | ||
818 | acx->rate_policy.aflags = c->aflags; | ||
819 | |||
820 | acx->rate_policy_idx = cpu_to_le32(idx); | ||
821 | |||
822 | ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); | ||
823 | if (ret < 0) { | ||
824 | wl1271_warning("Setting of ap rate policy failed: %d", ret); | ||
825 | goto out; | ||
826 | } | ||
827 | |||
828 | out: | ||
829 | kfree(acx); | ||
830 | return ret; | ||
831 | } | ||
832 | |||
797 | int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, | 833 | int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, |
798 | u8 aifsn, u16 txop) | 834 | u8 aifsn, u16 txop) |
799 | { | 835 | { |
@@ -915,9 +951,9 @@ out: | |||
915 | return ret; | 951 | return ret; |
916 | } | 952 | } |
917 | 953 | ||
918 | int wl1271_acx_mem_cfg(struct wl1271 *wl) | 954 | int wl1271_acx_ap_mem_cfg(struct wl1271 *wl) |
919 | { | 955 | { |
920 | struct wl1271_acx_config_memory *mem_conf; | 956 | struct wl1271_acx_ap_config_memory *mem_conf; |
921 | int ret; | 957 | int ret; |
922 | 958 | ||
923 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); | 959 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); |
@@ -929,10 +965,10 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl) | |||
929 | } | 965 | } |
930 | 966 | ||
931 | /* memory config */ | 967 | /* memory config */ |
932 | mem_conf->num_stations = DEFAULT_NUM_STATIONS; | 968 | mem_conf->num_stations = wl->conf.mem.num_stations; |
933 | mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; | 969 | mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; |
934 | mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; | 970 | mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; |
935 | mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; | 971 | mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; |
936 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); | 972 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); |
937 | 973 | ||
938 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, | 974 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, |
@@ -947,13 +983,45 @@ out: | |||
947 | return ret; | 983 | return ret; |
948 | } | 984 | } |
949 | 985 | ||
950 | int wl1271_acx_init_mem_config(struct wl1271 *wl) | 986 | int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) |
951 | { | 987 | { |
988 | struct wl1271_acx_sta_config_memory *mem_conf; | ||
952 | int ret; | 989 | int ret; |
953 | 990 | ||
954 | ret = wl1271_acx_mem_cfg(wl); | 991 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); |
955 | if (ret < 0) | 992 | |
956 | return ret; | 993 | mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); |
994 | if (!mem_conf) { | ||
995 | ret = -ENOMEM; | ||
996 | goto out; | ||
997 | } | ||
998 | |||
999 | /* memory config */ | ||
1000 | mem_conf->num_stations = wl->conf.mem.num_stations; | ||
1001 | mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; | ||
1002 | mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; | ||
1003 | mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; | ||
1004 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); | ||
1005 | mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory; | ||
1006 | mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks; | ||
1007 | mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks; | ||
1008 | mem_conf->tx_min = wl->conf.mem.tx_min; | ||
1009 | |||
1010 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, | ||
1011 | sizeof(*mem_conf)); | ||
1012 | if (ret < 0) { | ||
1013 | wl1271_warning("wl1271 mem config failed: %d", ret); | ||
1014 | goto out; | ||
1015 | } | ||
1016 | |||
1017 | out: | ||
1018 | kfree(mem_conf); | ||
1019 | return ret; | ||
1020 | } | ||
1021 | |||
1022 | int wl1271_acx_init_mem_config(struct wl1271 *wl) | ||
1023 | { | ||
1024 | int ret; | ||
957 | 1025 | ||
958 | wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), | 1026 | wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), |
959 | GFP_KERNEL); | 1027 | GFP_KERNEL); |
@@ -1233,6 +1301,7 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, | |||
1233 | struct wl1271_acx_ht_capabilities *acx; | 1301 | struct wl1271_acx_ht_capabilities *acx; |
1234 | u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 1302 | u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
1235 | int ret = 0; | 1303 | int ret = 0; |
1304 | u32 ht_capabilites = 0; | ||
1236 | 1305 | ||
1237 | wl1271_debug(DEBUG_ACX, "acx ht capabilities setting"); | 1306 | wl1271_debug(DEBUG_ACX, "acx ht capabilities setting"); |
1238 | 1307 | ||
@@ -1244,27 +1313,26 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, | |||
1244 | 1313 | ||
1245 | /* Allow HT Operation ? */ | 1314 | /* Allow HT Operation ? */ |
1246 | if (allow_ht_operation) { | 1315 | if (allow_ht_operation) { |
1247 | acx->ht_capabilites = | 1316 | ht_capabilites = |
1248 | WL1271_ACX_FW_CAP_HT_OPERATION; | 1317 | WL1271_ACX_FW_CAP_HT_OPERATION; |
1249 | if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD) | 1318 | if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD) |
1250 | acx->ht_capabilites |= | 1319 | ht_capabilites |= |
1251 | WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT; | 1320 | WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT; |
1252 | if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) | 1321 | if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) |
1253 | acx->ht_capabilites |= | 1322 | ht_capabilites |= |
1254 | WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS; | 1323 | WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS; |
1255 | if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT) | 1324 | if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT) |
1256 | acx->ht_capabilites |= | 1325 | ht_capabilites |= |
1257 | WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION; | 1326 | WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION; |
1258 | 1327 | ||
1259 | /* get data from A-MPDU parameters field */ | 1328 | /* get data from A-MPDU parameters field */ |
1260 | acx->ampdu_max_length = ht_cap->ampdu_factor; | 1329 | acx->ampdu_max_length = ht_cap->ampdu_factor; |
1261 | acx->ampdu_min_spacing = ht_cap->ampdu_density; | 1330 | acx->ampdu_min_spacing = ht_cap->ampdu_density; |
1262 | |||
1263 | memcpy(acx->mac_address, mac_address, ETH_ALEN); | ||
1264 | } else { /* HT operations are not allowed */ | ||
1265 | acx->ht_capabilites = 0; | ||
1266 | } | 1331 | } |
1267 | 1332 | ||
1333 | memcpy(acx->mac_address, mac_address, ETH_ALEN); | ||
1334 | acx->ht_capabilites = cpu_to_le32(ht_capabilites); | ||
1335 | |||
1268 | ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); | 1336 | ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); |
1269 | if (ret < 0) { | 1337 | if (ret < 0) { |
1270 | wl1271_warning("acx ht capabilities setting failed: %d", ret); | 1338 | wl1271_warning("acx ht capabilities setting failed: %d", ret); |
@@ -1293,7 +1361,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl, | |||
1293 | acx->ht_protection = | 1361 | acx->ht_protection = |
1294 | (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); | 1362 | (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); |
1295 | acx->rifs_mode = 0; | 1363 | acx->rifs_mode = 0; |
1296 | acx->gf_protection = 0; | 1364 | acx->gf_protection = |
1365 | !!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
1297 | acx->ht_tx_burst_limit = 0; | 1366 | acx->ht_tx_burst_limit = 0; |
1298 | acx->dual_cts_protection = 0; | 1367 | acx->dual_cts_protection = 0; |
1299 | 1368 | ||
@@ -1309,6 +1378,91 @@ out: | |||
1309 | return ret; | 1378 | return ret; |
1310 | } | 1379 | } |
1311 | 1380 | ||
1381 | /* Configure BA session initiator/receiver parameters setting in the FW. */ | ||
1382 | int wl1271_acx_set_ba_session(struct wl1271 *wl, | ||
1383 | enum ieee80211_back_parties direction, | ||
1384 | u8 tid_index, u8 policy) | ||
1385 | { | ||
1386 | struct wl1271_acx_ba_session_policy *acx; | ||
1387 | int ret; | ||
1388 | |||
1389 | wl1271_debug(DEBUG_ACX, "acx ba session setting"); | ||
1390 | |||
1391 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1392 | if (!acx) { | ||
1393 | ret = -ENOMEM; | ||
1394 | goto out; | ||
1395 | } | ||
1396 | |||
1397 | /* ANY role */ | ||
1398 | acx->role_id = 0xff; | ||
1399 | acx->tid = tid_index; | ||
1400 | acx->enable = policy; | ||
1401 | acx->ba_direction = direction; | ||
1402 | |||
1403 | switch (direction) { | ||
1404 | case WLAN_BACK_INITIATOR: | ||
1405 | acx->win_size = wl->conf.ht.tx_ba_win_size; | ||
1406 | acx->inactivity_timeout = wl->conf.ht.inactivity_timeout; | ||
1407 | break; | ||
1408 | case WLAN_BACK_RECIPIENT: | ||
1409 | acx->win_size = RX_BA_WIN_SIZE; | ||
1410 | acx->inactivity_timeout = 0; | ||
1411 | break; | ||
1412 | default: | ||
1413 | wl1271_error("Incorrect acx command id=%x\n", direction); | ||
1414 | ret = -EINVAL; | ||
1415 | goto out; | ||
1416 | } | ||
1417 | |||
1418 | ret = wl1271_cmd_configure(wl, | ||
1419 | ACX_BA_SESSION_POLICY_CFG, | ||
1420 | acx, | ||
1421 | sizeof(*acx)); | ||
1422 | if (ret < 0) { | ||
1423 | wl1271_warning("acx ba session setting failed: %d", ret); | ||
1424 | goto out; | ||
1425 | } | ||
1426 | |||
1427 | out: | ||
1428 | kfree(acx); | ||
1429 | return ret; | ||
1430 | } | ||
1431 | |||
1432 | /* setup BA session receiver setting in the FW. */ | ||
1433 | int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, | ||
1434 | bool enable) | ||
1435 | { | ||
1436 | struct wl1271_acx_ba_receiver_setup *acx; | ||
1437 | int ret; | ||
1438 | |||
1439 | wl1271_debug(DEBUG_ACX, "acx ba receiver session setting"); | ||
1440 | |||
1441 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1442 | if (!acx) { | ||
1443 | ret = -ENOMEM; | ||
1444 | goto out; | ||
1445 | } | ||
1446 | |||
1447 | /* Single link for now */ | ||
1448 | acx->link_id = 1; | ||
1449 | acx->tid = tid_index; | ||
1450 | acx->enable = enable; | ||
1451 | acx->win_size = 0; | ||
1452 | acx->ssn = ssn; | ||
1453 | |||
1454 | ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx, | ||
1455 | sizeof(*acx)); | ||
1456 | if (ret < 0) { | ||
1457 | wl1271_warning("acx ba receiver session failed: %d", ret); | ||
1458 | goto out; | ||
1459 | } | ||
1460 | |||
1461 | out: | ||
1462 | kfree(acx); | ||
1463 | return ret; | ||
1464 | } | ||
1465 | |||
1312 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) | 1466 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) |
1313 | { | 1467 | { |
1314 | struct wl1271_acx_fw_tsf_information *tsf_info; | 1468 | struct wl1271_acx_fw_tsf_information *tsf_info; |
@@ -1334,3 +1488,82 @@ out: | |||
1334 | kfree(tsf_info); | 1488 | kfree(tsf_info); |
1335 | return ret; | 1489 | return ret; |
1336 | } | 1490 | } |
1491 | |||
1492 | int wl1271_acx_max_tx_retry(struct wl1271 *wl) | ||
1493 | { | ||
1494 | struct wl1271_acx_max_tx_retry *acx = NULL; | ||
1495 | int ret; | ||
1496 | |||
1497 | wl1271_debug(DEBUG_ACX, "acx max tx retry"); | ||
1498 | |||
1499 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1500 | if (!acx) | ||
1501 | return -ENOMEM; | ||
1502 | |||
1503 | acx->max_tx_retry = cpu_to_le16(wl->conf.tx.ap_max_tx_retries); | ||
1504 | |||
1505 | ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx)); | ||
1506 | if (ret < 0) { | ||
1507 | wl1271_warning("acx max tx retry failed: %d", ret); | ||
1508 | goto out; | ||
1509 | } | ||
1510 | |||
1511 | out: | ||
1512 | kfree(acx); | ||
1513 | return ret; | ||
1514 | } | ||
1515 | |||
1516 | int wl1271_acx_config_ps(struct wl1271 *wl) | ||
1517 | { | ||
1518 | struct wl1271_acx_config_ps *config_ps; | ||
1519 | int ret; | ||
1520 | |||
1521 | wl1271_debug(DEBUG_ACX, "acx config ps"); | ||
1522 | |||
1523 | config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL); | ||
1524 | if (!config_ps) { | ||
1525 | ret = -ENOMEM; | ||
1526 | goto out; | ||
1527 | } | ||
1528 | |||
1529 | config_ps->exit_retries = wl->conf.conn.psm_exit_retries; | ||
1530 | config_ps->enter_retries = wl->conf.conn.psm_entry_retries; | ||
1531 | config_ps->null_data_rate = cpu_to_le32(wl->basic_rate); | ||
1532 | |||
1533 | ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps, | ||
1534 | sizeof(*config_ps)); | ||
1535 | |||
1536 | if (ret < 0) { | ||
1537 | wl1271_warning("acx config ps failed: %d", ret); | ||
1538 | goto out; | ||
1539 | } | ||
1540 | |||
1541 | out: | ||
1542 | kfree(config_ps); | ||
1543 | return ret; | ||
1544 | } | ||
1545 | |||
1546 | int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr) | ||
1547 | { | ||
1548 | struct wl1271_acx_inconnection_sta *acx = NULL; | ||
1549 | int ret; | ||
1550 | |||
1551 | wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr); | ||
1552 | |||
1553 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1554 | if (!acx) | ||
1555 | return -ENOMEM; | ||
1556 | |||
1557 | memcpy(acx->addr, addr, ETH_ALEN); | ||
1558 | |||
1559 | ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST, | ||
1560 | acx, sizeof(*acx)); | ||
1561 | if (ret < 0) { | ||
1562 | wl1271_warning("acx set inconnaction sta failed: %d", ret); | ||
1563 | goto out; | ||
1564 | } | ||
1565 | |||
1566 | out: | ||
1567 | kfree(acx); | ||
1568 | return ret; | ||
1569 | } | ||