diff options
author | Raja Mani <rmani@qca.qualcomm.com> | 2011-11-07 15:52:45 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2011-11-11 05:59:59 -0500 |
commit | 45cf110b2b77914a9f02bbf1ba60796f17898be2 (patch) | |
tree | 53d4a031fcd2a635dc7317847da3af158b1d4d9a /drivers/net/wireless/ath | |
parent | 5c9b4fa19a488de48f1cc2268a7b7b247723568a (diff) |
ath6kl: Add wmi functions to configure WOW mode and host sleep mode
It will be used in WOW suspend/resume functions to
active/deactivate WOW suspend mode.
Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 108 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.h | 41 |
2 files changed, 149 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 925ef4c9bec9..3da1fb502bf5 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -2412,6 +2412,114 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) | |||
2412 | return ret; | 2412 | return ret; |
2413 | } | 2413 | } |
2414 | 2414 | ||
2415 | static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi) | ||
2416 | { | ||
2417 | u16 active_tsids; | ||
2418 | u8 stream_exist; | ||
2419 | int i; | ||
2420 | |||
2421 | /* | ||
2422 | * Relinquish credits from all implicitly created pstreams | ||
2423 | * since when we go to sleep. If user created explicit | ||
2424 | * thinstreams exists with in a fatpipe leave them intact | ||
2425 | * for the user to delete. | ||
2426 | */ | ||
2427 | spin_lock_bh(&wmi->lock); | ||
2428 | stream_exist = wmi->fat_pipe_exist; | ||
2429 | spin_unlock_bh(&wmi->lock); | ||
2430 | |||
2431 | for (i = 0; i < WMM_NUM_AC; i++) { | ||
2432 | if (stream_exist & (1 << i)) { | ||
2433 | |||
2434 | /* | ||
2435 | * FIXME: Is this lock & unlock inside | ||
2436 | * for loop correct? may need rework. | ||
2437 | */ | ||
2438 | spin_lock_bh(&wmi->lock); | ||
2439 | active_tsids = wmi->stream_exist_for_ac[i]; | ||
2440 | spin_unlock_bh(&wmi->lock); | ||
2441 | |||
2442 | /* | ||
2443 | * If there are no user created thin streams | ||
2444 | * delete the fatpipe | ||
2445 | */ | ||
2446 | if (!active_tsids) { | ||
2447 | stream_exist &= ~(1 << i); | ||
2448 | /* | ||
2449 | * Indicate inactivity to driver layer for | ||
2450 | * this fatpipe (pstream) | ||
2451 | */ | ||
2452 | ath6kl_indicate_tx_activity(wmi->parent_dev, | ||
2453 | i, false); | ||
2454 | } | ||
2455 | } | ||
2456 | } | ||
2457 | |||
2458 | /* FIXME: Can we do this assignment without locking ? */ | ||
2459 | spin_lock_bh(&wmi->lock); | ||
2460 | wmi->fat_pipe_exist = stream_exist; | ||
2461 | spin_unlock_bh(&wmi->lock); | ||
2462 | } | ||
2463 | |||
2464 | int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, | ||
2465 | enum ath6kl_host_mode host_mode) | ||
2466 | { | ||
2467 | struct sk_buff *skb; | ||
2468 | struct wmi_set_host_sleep_mode_cmd *cmd; | ||
2469 | int ret; | ||
2470 | |||
2471 | if ((host_mode != ATH6KL_HOST_MODE_ASLEEP) && | ||
2472 | (host_mode != ATH6KL_HOST_MODE_AWAKE)) { | ||
2473 | ath6kl_err("invalid host sleep mode: %d\n", host_mode); | ||
2474 | return -EINVAL; | ||
2475 | } | ||
2476 | |||
2477 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
2478 | if (!skb) | ||
2479 | return -ENOMEM; | ||
2480 | |||
2481 | cmd = (struct wmi_set_host_sleep_mode_cmd *) skb->data; | ||
2482 | |||
2483 | if (host_mode == ATH6KL_HOST_MODE_ASLEEP) { | ||
2484 | ath6kl_wmi_relinquish_implicit_pstream_credits(wmi); | ||
2485 | cmd->asleep = cpu_to_le32(1); | ||
2486 | } else | ||
2487 | cmd->awake = cpu_to_le32(1); | ||
2488 | |||
2489 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, | ||
2490 | WMI_SET_HOST_SLEEP_MODE_CMDID, | ||
2491 | NO_SYNC_WMIFLAG); | ||
2492 | return ret; | ||
2493 | } | ||
2494 | |||
2495 | int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, | ||
2496 | enum ath6kl_wow_mode wow_mode, | ||
2497 | u32 filter, u16 host_req_delay) | ||
2498 | { | ||
2499 | struct sk_buff *skb; | ||
2500 | struct wmi_set_wow_mode_cmd *cmd; | ||
2501 | int ret; | ||
2502 | |||
2503 | if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) && | ||
2504 | wow_mode != ATH6KL_WOW_MODE_DISABLE) { | ||
2505 | ath6kl_err("invalid wow mode: %d\n", wow_mode); | ||
2506 | return -EINVAL; | ||
2507 | } | ||
2508 | |||
2509 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
2510 | if (!skb) | ||
2511 | return -ENOMEM; | ||
2512 | |||
2513 | cmd = (struct wmi_set_wow_mode_cmd *) skb->data; | ||
2514 | cmd->enable_wow = cpu_to_le32(wow_mode); | ||
2515 | cmd->filter = cpu_to_le32(filter); | ||
2516 | cmd->host_req_delay = cpu_to_le16(host_req_delay); | ||
2517 | |||
2518 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_WOW_MODE_CMDID, | ||
2519 | NO_SYNC_WMIFLAG); | ||
2520 | return ret; | ||
2521 | } | ||
2522 | |||
2415 | int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, | 2523 | int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, |
2416 | u8 list_id, u8 filter_size, | 2524 | u8 list_id, u8 filter_size, |
2417 | u8 filter_offset, u8 *filter, u8 *mask) | 2525 | u8 filter_offset, u8 *filter, u8 *mask) |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index df42e4be876a..a65eee20d18a 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h | |||
@@ -1818,6 +1818,42 @@ struct wmi_set_ip_cmd { | |||
1818 | __le32 ips[MAX_IP_ADDRS]; | 1818 | __le32 ips[MAX_IP_ADDRS]; |
1819 | } __packed; | 1819 | } __packed; |
1820 | 1820 | ||
1821 | enum ath6kl_wow_filters { | ||
1822 | WOW_FILTER_SSID = BIT(0), | ||
1823 | WOW_FILTER_OPTION_MAGIC_PACKET = BIT(2), | ||
1824 | WOW_FILTER_OPTION_EAP_REQ = BIT(3), | ||
1825 | WOW_FILTER_OPTION_PATTERNS = BIT(4), | ||
1826 | WOW_FILTER_OPTION_OFFLOAD_ARP = BIT(5), | ||
1827 | WOW_FILTER_OPTION_OFFLOAD_NS = BIT(6), | ||
1828 | WOW_FILTER_OPTION_OFFLOAD_GTK = BIT(7), | ||
1829 | WOW_FILTER_OPTION_8021X_4WAYHS = BIT(8), | ||
1830 | WOW_FILTER_OPTION_NLO_DISCVRY = BIT(9), | ||
1831 | WOW_FILTER_OPTION_NWK_DISASSOC = BIT(10), | ||
1832 | WOW_FILTER_OPTION_GTK_ERROR = BIT(11), | ||
1833 | WOW_FILTER_OPTION_TEST_MODE = BIT(15), | ||
1834 | }; | ||
1835 | |||
1836 | enum ath6kl_host_mode { | ||
1837 | ATH6KL_HOST_MODE_AWAKE, | ||
1838 | ATH6KL_HOST_MODE_ASLEEP, | ||
1839 | }; | ||
1840 | |||
1841 | struct wmi_set_host_sleep_mode_cmd { | ||
1842 | __le32 awake; | ||
1843 | __le32 asleep; | ||
1844 | } __packed; | ||
1845 | |||
1846 | enum ath6kl_wow_mode { | ||
1847 | ATH6KL_WOW_MODE_DISABLE, | ||
1848 | ATH6KL_WOW_MODE_ENABLE, | ||
1849 | }; | ||
1850 | |||
1851 | struct wmi_set_wow_mode_cmd { | ||
1852 | __le32 enable_wow; | ||
1853 | __le32 filter; | ||
1854 | __le16 host_req_delay; | ||
1855 | } __packed; | ||
1856 | |||
1821 | struct wmi_add_wow_pattern_cmd { | 1857 | struct wmi_add_wow_pattern_cmd { |
1822 | u8 filter_list_id; | 1858 | u8 filter_list_id; |
1823 | u8 filter_size; | 1859 | u8 filter_size; |
@@ -2285,6 +2321,11 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); | |||
2285 | s32 ath6kl_wmi_get_rate(s8 rate_index); | 2321 | s32 ath6kl_wmi_get_rate(s8 rate_index); |
2286 | 2322 | ||
2287 | int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); | 2323 | int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); |
2324 | int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, | ||
2325 | enum ath6kl_host_mode host_mode); | ||
2326 | int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, | ||
2327 | enum ath6kl_wow_mode wow_mode, | ||
2328 | u32 filter, u16 host_req_delay); | ||
2288 | int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, | 2329 | int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, |
2289 | u8 list_id, u8 filter_size, | 2330 | u8 list_id, u8 filter_size, |
2290 | u8 filter_offset, u8 *filter, u8 *mask); | 2331 | u8 filter_offset, u8 *filter, u8 *mask); |