diff options
author | Janusz Dziedzic <janusz.dziedzic@tieto.com> | 2015-01-28 02:57:39 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2015-01-29 05:15:00 -0500 |
commit | 6e8b188ba782bd04f942b7d489b8b2b81606f690 (patch) | |
tree | fb704a8a56312558c8534c993b99bf45c2b733b6 /drivers/net | |
parent | 7fc979a79d9b9af15052b4c7fd1debd44294ba4f (diff) |
ath10k: implement sta keepalive command
New wmi-tlv firmware for qca6174 has STA keepalive
service available. The service can provide
automatic idle connection polling via NullFunc
frames to AP when acting as a client.
Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-ops.h | 20 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-tlv.c | 45 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-tlv.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.h | 10 |
4 files changed, 82 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h index 987414abc443..058f88b6ff53 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h | |||
@@ -143,6 +143,8 @@ struct wmi_ops { | |||
143 | const u8 peer_addr[ETH_ALEN], | 143 | const u8 peer_addr[ETH_ALEN], |
144 | const struct wmi_sta_uapsd_auto_trig_arg *args, | 144 | const struct wmi_sta_uapsd_auto_trig_arg *args, |
145 | u32 num_ac); | 145 | u32 num_ac); |
146 | struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar, | ||
147 | const struct wmi_sta_keepalive_arg *arg); | ||
146 | }; | 148 | }; |
147 | 149 | ||
148 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); | 150 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); |
@@ -1034,4 +1036,22 @@ ath10k_wmi_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id, const u8 *p2p_ie) | |||
1034 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->p2p_go_set_beacon_ie); | 1036 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->p2p_go_set_beacon_ie); |
1035 | } | 1037 | } |
1036 | 1038 | ||
1039 | static inline int | ||
1040 | ath10k_wmi_sta_keepalive(struct ath10k *ar, | ||
1041 | const struct wmi_sta_keepalive_arg *arg) | ||
1042 | { | ||
1043 | struct sk_buff *skb; | ||
1044 | u32 cmd_id; | ||
1045 | |||
1046 | if (!ar->wmi.ops->gen_sta_keepalive) | ||
1047 | return -EOPNOTSUPP; | ||
1048 | |||
1049 | skb = ar->wmi.ops->gen_sta_keepalive(ar, arg); | ||
1050 | if (IS_ERR(skb)) | ||
1051 | return PTR_ERR(skb); | ||
1052 | |||
1053 | cmd_id = ar->wmi.cmd->sta_keepalive_cmd; | ||
1054 | return ath10k_wmi_cmd_send(ar, skb, cmd_id); | ||
1055 | } | ||
1056 | |||
1037 | #endif | 1057 | #endif |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 00ca544bc94d..be32db96701f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c | |||
@@ -1636,6 +1636,50 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id, | |||
1636 | } | 1636 | } |
1637 | 1637 | ||
1638 | static struct sk_buff * | 1638 | static struct sk_buff * |
1639 | ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar, | ||
1640 | const struct wmi_sta_keepalive_arg *arg) | ||
1641 | { | ||
1642 | struct wmi_tlv_sta_keepalive_cmd *cmd; | ||
1643 | struct wmi_sta_keepalive_arp_resp *arp; | ||
1644 | struct sk_buff *skb; | ||
1645 | struct wmi_tlv *tlv; | ||
1646 | void *ptr; | ||
1647 | size_t len; | ||
1648 | |||
1649 | len = sizeof(*tlv) + sizeof(*cmd) + | ||
1650 | sizeof(*tlv) + sizeof(*arp); | ||
1651 | skb = ath10k_wmi_alloc_skb(ar, len); | ||
1652 | if (!skb) | ||
1653 | return ERR_PTR(-ENOMEM); | ||
1654 | |||
1655 | ptr = (void *)skb->data; | ||
1656 | tlv = ptr; | ||
1657 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD); | ||
1658 | tlv->len = __cpu_to_le16(sizeof(*cmd)); | ||
1659 | cmd = (void *)tlv->value; | ||
1660 | cmd->vdev_id = __cpu_to_le32(arg->vdev_id); | ||
1661 | cmd->enabled = __cpu_to_le32(arg->enabled); | ||
1662 | cmd->method = __cpu_to_le32(arg->method); | ||
1663 | cmd->interval = __cpu_to_le32(arg->interval); | ||
1664 | |||
1665 | ptr += sizeof(*tlv); | ||
1666 | ptr += sizeof(*cmd); | ||
1667 | |||
1668 | tlv = ptr; | ||
1669 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE); | ||
1670 | tlv->len = __cpu_to_le16(sizeof(*arp)); | ||
1671 | arp = (void *)tlv->value; | ||
1672 | |||
1673 | arp->src_ip4_addr = arg->src_ip4_addr; | ||
1674 | arp->dest_ip4_addr = arg->dest_ip4_addr; | ||
1675 | ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr); | ||
1676 | |||
1677 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d inverval %d\n", | ||
1678 | arg->vdev_id, arg->enabled, arg->method, arg->interval); | ||
1679 | return skb; | ||
1680 | } | ||
1681 | |||
1682 | static struct sk_buff * | ||
1639 | ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, | 1683 | ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, |
1640 | const u8 peer_addr[ETH_ALEN]) | 1684 | const u8 peer_addr[ETH_ALEN]) |
1641 | { | 1685 | { |
@@ -2634,6 +2678,7 @@ static const struct wmi_ops wmi_tlv_ops = { | |||
2634 | .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl, | 2678 | .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl, |
2635 | .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, | 2679 | .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, |
2636 | .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd, | 2680 | .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd, |
2681 | .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive, | ||
2637 | }; | 2682 | }; |
2638 | 2683 | ||
2639 | /************/ | 2684 | /************/ |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index 3dc43b90469d..de68fe76eae6 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h | |||
@@ -1432,6 +1432,13 @@ struct wmi_tlv_diag_data_ev { | |||
1432 | __le32 num_items; | 1432 | __le32 num_items; |
1433 | } __packed; | 1433 | } __packed; |
1434 | 1434 | ||
1435 | struct wmi_tlv_sta_keepalive_cmd { | ||
1436 | __le32 vdev_id; | ||
1437 | __le32 enabled; | ||
1438 | __le32 method; /* WMI_STA_KEEPALIVE_METHOD_ */ | ||
1439 | __le32 interval; /* in seconds */ | ||
1440 | } __packed; | ||
1441 | |||
1435 | void ath10k_wmi_tlv_attach(struct ath10k *ar); | 1442 | void ath10k_wmi_tlv_attach(struct ath10k *ar); |
1436 | 1443 | ||
1437 | #endif | 1444 | #endif |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 3c48e0d21900..1a99a7dd0e95 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -4680,6 +4680,16 @@ struct wmi_sta_keepalive_cmd { | |||
4680 | struct wmi_sta_keepalive_arp_resp arp_resp; | 4680 | struct wmi_sta_keepalive_arp_resp arp_resp; |
4681 | } __packed; | 4681 | } __packed; |
4682 | 4682 | ||
4683 | struct wmi_sta_keepalive_arg { | ||
4684 | u32 vdev_id; | ||
4685 | u32 enabled; | ||
4686 | u32 method; | ||
4687 | u32 interval; | ||
4688 | __be32 src_ip4_addr; | ||
4689 | __be32 dest_ip4_addr; | ||
4690 | const u8 dest_mac_addr[ETH_ALEN]; | ||
4691 | }; | ||
4692 | |||
4683 | enum wmi_force_fw_hang_type { | 4693 | enum wmi_force_fw_hang_type { |
4684 | WMI_FORCE_FW_HANG_ASSERT = 1, | 4694 | WMI_FORCE_FW_HANG_ASSERT = 1, |
4685 | WMI_FORCE_FW_HANG_NO_DETECT, | 4695 | WMI_FORCE_FW_HANG_NO_DETECT, |