diff options
author | Maya Erez <qca_merez@qca.qualcomm.com> | 2016-11-23 09:06:40 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2016-11-23 09:49:48 -0500 |
commit | 2c207eb8e6ab3f46d6c6a0daab16dc756562802b (patch) | |
tree | 74487686679e7ac8044fb7bb52d7259b1ca313a9 /drivers/net/wireless | |
parent | f9e3033ff7eb9a0018856f5295312f78828a34f2 (diff) |
wil6210: add support for power save enable / disable
New power management wmi commands provide the ability to change
the device power save profile (enable / disable power save).
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/cfg80211.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.c | 34 |
3 files changed, 67 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index d117240d9a73..c6dd7a3892f9 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -1424,6 +1424,34 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy, | |||
1424 | mutex_unlock(&wil->mutex); | 1424 | mutex_unlock(&wil->mutex); |
1425 | } | 1425 | } |
1426 | 1426 | ||
1427 | static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy, | ||
1428 | struct net_device *dev, | ||
1429 | bool enabled, int timeout) | ||
1430 | { | ||
1431 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | ||
1432 | enum wmi_ps_profile_type ps_profile; | ||
1433 | int rc; | ||
1434 | |||
1435 | if (!test_bit(WMI_FW_CAPABILITY_PS_CONFIG, wil->fw_capabilities)) { | ||
1436 | wil_err(wil, "set_power_mgmt not supported\n"); | ||
1437 | return -EOPNOTSUPP; | ||
1438 | } | ||
1439 | |||
1440 | wil_dbg_misc(wil, "enabled=%d, timeout=%d\n", | ||
1441 | enabled, timeout); | ||
1442 | |||
1443 | if (enabled) | ||
1444 | ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT; | ||
1445 | else | ||
1446 | ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED; | ||
1447 | |||
1448 | rc = wmi_ps_dev_profile_cfg(wil, ps_profile); | ||
1449 | if (rc) | ||
1450 | wil_err(wil, "wmi_ps_dev_profile_cfg failed (%d)\n", rc); | ||
1451 | |||
1452 | return rc; | ||
1453 | } | ||
1454 | |||
1427 | static struct cfg80211_ops wil_cfg80211_ops = { | 1455 | static struct cfg80211_ops wil_cfg80211_ops = { |
1428 | .add_virtual_intf = wil_cfg80211_add_iface, | 1456 | .add_virtual_intf = wil_cfg80211_add_iface, |
1429 | .del_virtual_intf = wil_cfg80211_del_iface, | 1457 | .del_virtual_intf = wil_cfg80211_del_iface, |
@@ -1450,6 +1478,7 @@ static struct cfg80211_ops wil_cfg80211_ops = { | |||
1450 | /* P2P device */ | 1478 | /* P2P device */ |
1451 | .start_p2p_device = wil_cfg80211_start_p2p_device, | 1479 | .start_p2p_device = wil_cfg80211_start_p2p_device, |
1452 | .stop_p2p_device = wil_cfg80211_stop_p2p_device, | 1480 | .stop_p2p_device = wil_cfg80211_stop_p2p_device, |
1481 | .set_power_mgmt = wil_cfg80211_set_power_mgmt, | ||
1453 | }; | 1482 | }; |
1454 | 1483 | ||
1455 | static void wil_wiphy_init(struct wiphy *wiphy) | 1484 | static void wil_wiphy_init(struct wiphy *wiphy) |
@@ -1466,7 +1495,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) | |||
1466 | BIT(NL80211_IFTYPE_MONITOR); | 1495 | BIT(NL80211_IFTYPE_MONITOR); |
1467 | wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | | 1496 | wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | |
1468 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | | 1497 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | |
1469 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | 1498 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | |
1499 | WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1470 | dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n", | 1500 | dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n", |
1471 | __func__, wiphy->flags); | 1501 | __func__, wiphy->flags); |
1472 | wiphy->probe_resp_offload = | 1502 | wiphy->probe_resp_offload = |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 12cd81bccb47..4b22ea4bc4cf 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -819,6 +819,8 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason); | |||
819 | int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason); | 819 | int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason); |
820 | int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, | 820 | int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, |
821 | u16 status, bool amsdu, u16 agg_wsize, u16 timeout); | 821 | u16 status, bool amsdu, u16 agg_wsize, u16 timeout); |
822 | int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, | ||
823 | enum wmi_ps_profile_type ps_profile); | ||
822 | int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, | 824 | int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, |
823 | u8 dialog_token, __le16 ba_param_set, | 825 | u8 dialog_token, __le16 ba_param_set, |
824 | __le16 ba_timeout, __le16 ba_seq_ctrl); | 826 | __le16 ba_timeout, __le16 ba_seq_ctrl); |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 890960e9b1d3..8c60437e57e0 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -1563,6 +1563,40 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, | |||
1563 | return rc; | 1563 | return rc; |
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, | ||
1567 | enum wmi_ps_profile_type ps_profile) | ||
1568 | { | ||
1569 | int rc; | ||
1570 | struct wmi_ps_dev_profile_cfg_cmd cmd = { | ||
1571 | .ps_profile = ps_profile, | ||
1572 | }; | ||
1573 | struct { | ||
1574 | struct wmi_cmd_hdr wmi; | ||
1575 | struct wmi_ps_dev_profile_cfg_event evt; | ||
1576 | } __packed reply; | ||
1577 | u32 status; | ||
1578 | |||
1579 | wil_dbg_wmi(wil, "Setting ps dev profile %d\n", ps_profile); | ||
1580 | |||
1581 | reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR); | ||
1582 | |||
1583 | rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, &cmd, sizeof(cmd), | ||
1584 | WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply), | ||
1585 | 100); | ||
1586 | if (rc) | ||
1587 | return rc; | ||
1588 | |||
1589 | status = le32_to_cpu(reply.evt.status); | ||
1590 | |||
1591 | if (status != WMI_PS_CFG_CMD_STATUS_SUCCESS) { | ||
1592 | wil_err(wil, "ps dev profile cfg failed with status %d\n", | ||
1593 | status); | ||
1594 | rc = -EINVAL; | ||
1595 | } | ||
1596 | |||
1597 | return rc; | ||
1598 | } | ||
1599 | |||
1566 | void wmi_event_flush(struct wil6210_priv *wil) | 1600 | void wmi_event_flush(struct wil6210_priv *wil) |
1567 | { | 1601 | { |
1568 | struct pending_wmi_event *evt, *t; | 1602 | struct pending_wmi_event *evt, *t; |