Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 278110
b: refs/heads/master
c: 6cb3c71
h: refs/heads/master
v: v3
  • Loading branch information
Raja Mani authored and Kalle Valo committed Nov 11, 2011
1 parent 012e897 commit 27d12e3
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 45cf110b2b77914a9f02bbf1ba60796f17898be2
refs/heads/master: 6cb3c714e75c6e70fa1c379b7f3af2f143f31c70
109 changes: 109 additions & 0 deletions trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,115 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
return 0;
}

static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
{
struct ath6kl_vif *vif;
int ret, pos, left;
u32 filter = 0;
u16 i;
u8 mask[WOW_MASK_SIZE];

vif = ath6kl_vif_first(ar);
if (!vif)
return -EIO;

if (!ath6kl_cfg80211_ready(vif))
return -EIO;

if (!test_bit(CONNECTED, &vif->flags))
return -EINVAL;

/* Clear existing WOW patterns */
for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
WOW_LIST_ID, i);
/* Configure new WOW patterns */
for (i = 0; i < wow->n_patterns; i++) {

/*
* Convert given nl80211 specific mask value to equivalent
* driver specific mask value and send it to the chip along
* with patterns. For example, If the mask value defined in
* struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
* then equivalent driver specific mask value is
* "0xFF 0x00 0xFF 0x00".
*/
memset(&mask, 0, sizeof(mask));
for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
mask[pos] = 0xFF;
}
/*
* Note: Pattern's offset is not passed as part of wowlan
* parameter from CFG layer. So it's always passed as ZERO
* to the firmware. It means, given WOW patterns are always
* matched from the first byte of received pkt in the firmware.
*/
ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
vif->fw_vif_idx, WOW_LIST_ID,
wow->patterns[i].pattern_len,
0 /* pattern offset */,
wow->patterns[i].pattern, mask);
if (ret)
return ret;
}

if (wow->disconnect)
filter |= WOW_FILTER_OPTION_NWK_DISASSOC;

if (wow->magic_pkt)
filter |= WOW_FILTER_OPTION_MAGIC_PACKET;

if (wow->gtk_rekey_failure)
filter |= WOW_FILTER_OPTION_GTK_ERROR;

if (wow->eap_identity_req)
filter |= WOW_FILTER_OPTION_EAP_REQ;

if (wow->four_way_handshake)
filter |= WOW_FILTER_OPTION_8021X_4WAYHS;

ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
ATH6KL_WOW_MODE_ENABLE,
filter,
WOW_HOST_REQ_DELAY);
if (ret)
return ret;

ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
ATH6KL_HOST_MODE_ASLEEP);
if (ret)
return ret;

if (ar->tx_pending[ar->ctrl_ep]) {
left = wait_event_interruptible_timeout(ar->event_wq,
ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
if (left == 0) {
ath6kl_warn("clear wmi ctrl data timeout\n");
ret = -ETIMEDOUT;
} else if (left < 0) {
ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
ret = left;
}
}

return ret;
}

static int ath6kl_wow_resume(struct ath6kl *ar)
{
struct ath6kl_vif *vif;
int ret;

vif = ath6kl_vif_first(ar);
if (!vif)
return -EIO;

ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
ATH6KL_HOST_MODE_AWAKE);
return ret;
}

int ath6kl_cfg80211_suspend(struct ath6kl *ar,
enum ath6kl_cfg_suspend_mode mode)
{
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/wireless/ath/ath6kl/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,9 @@ struct ath6kl_vif {
struct target_stats target_stats;
};

#define WOW_LIST_ID 0
#define WOW_HOST_REQ_DELAY 500 /* ms */

/* Flag info */
enum ath6kl_dev_state {
WMI_ENABLED,
Expand Down

0 comments on commit 27d12e3

Please sign in to comment.