aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJanusz Dziedzic <janusz.dziedzic@tieto.com>2015-01-28 02:57:39 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2015-01-29 05:15:00 -0500
commit6e8b188ba782bd04f942b7d489b8b2b81606f690 (patch)
treefb704a8a56312558c8534c993b99bf45c2b733b6 /drivers/net
parent7fc979a79d9b9af15052b4c7fd1debd44294ba4f (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.h20
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c45
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h10
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
148int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 150int 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
1039static inline int
1040ath10k_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
1638static struct sk_buff * 1638static struct sk_buff *
1639ath10k_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
1682static struct sk_buff *
1639ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, 1683ath10k_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
1435struct 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
1435void ath10k_wmi_tlv_attach(struct ath10k *ar); 1442void 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
4683struct 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
4683enum wmi_force_fw_hang_type { 4693enum 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,