aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2015-01-13 09:30:11 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2015-01-15 05:30:07 -0500
commitbe9ce9d8c196bf150eace10aaf43110672d6eb4c (patch)
treeb05d86dadb7c25f3645d41fa779d375b24744fbf /drivers/net/wireless
parent6bf1206289115c277cfa569f570a97ada345a2d5 (diff)
ath10k: implement beacon template command
New firmware revisions may support setting beacon template. Implement wmi interface for it. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h23
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c65
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h12
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c3
4 files changed, 103 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 3a3d15e65e0a..546970259de2 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -129,6 +129,10 @@ struct wmi_ops {
129 struct sk_buff *(*gen_delba_send)(struct ath10k *ar, u32 vdev_id, 129 struct sk_buff *(*gen_delba_send)(struct ath10k *ar, u32 vdev_id,
130 const u8 *mac, u32 tid, u32 initiator, 130 const u8 *mac, u32 tid, u32 initiator,
131 u32 reason); 131 u32 reason);
132 struct sk_buff *(*gen_bcn_tmpl)(struct ath10k *ar, u32 vdev_id,
133 u32 tim_ie_offset, struct sk_buff *bcn,
134 u32 prb_caps, u32 prb_erp,
135 void *prb_ies, size_t prb_ies_len);
132}; 136};
133 137
134int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 138int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -935,4 +939,23 @@ ath10k_wmi_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
935 ar->wmi.cmd->delba_send_cmdid); 939 ar->wmi.cmd->delba_send_cmdid);
936} 940}
937 941
942static inline int
943ath10k_wmi_bcn_tmpl(struct ath10k *ar, u32 vdev_id, u32 tim_ie_offset,
944 struct sk_buff *bcn, u32 prb_caps, u32 prb_erp,
945 void *prb_ies, size_t prb_ies_len)
946{
947 struct sk_buff *skb;
948
949 if (!ar->wmi.ops->gen_bcn_tmpl)
950 return -EOPNOTSUPP;
951
952 skb = ar->wmi.ops->gen_bcn_tmpl(ar, vdev_id, tim_ie_offset, bcn,
953 prb_caps, prb_erp, prb_ies,
954 prb_ies_len);
955 if (IS_ERR(skb))
956 return PTR_ERR(skb);
957
958 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->bcn_tmpl_cmdid);
959}
960
938#endif 961#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 67138a69bb42..08a9b2b35d06 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1972,6 +1972,70 @@ ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar)
1972 return skb; 1972 return skb;
1973} 1973}
1974 1974
1975static struct sk_buff *
1976ath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id,
1977 u32 tim_ie_offset, struct sk_buff *bcn,
1978 u32 prb_caps, u32 prb_erp, void *prb_ies,
1979 size_t prb_ies_len)
1980{
1981 struct wmi_tlv_bcn_tmpl_cmd *cmd;
1982 struct wmi_tlv_bcn_prb_info *info;
1983 struct wmi_tlv *tlv;
1984 struct sk_buff *skb;
1985 void *ptr;
1986 size_t len;
1987
1988 if (WARN_ON(prb_ies_len > 0 && !prb_ies))
1989 return ERR_PTR(-EINVAL);
1990
1991 len = sizeof(*tlv) + sizeof(*cmd) +
1992 sizeof(*tlv) + sizeof(*info) + prb_ies_len +
1993 sizeof(*tlv) + roundup(bcn->len, 4);
1994 skb = ath10k_wmi_alloc_skb(ar, len);
1995 if (!skb)
1996 return ERR_PTR(-ENOMEM);
1997
1998 ptr = (void *)skb->data;
1999 tlv = ptr;
2000 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD);
2001 tlv->len = __cpu_to_le16(sizeof(*cmd));
2002 cmd = (void *)tlv->value;
2003 cmd->vdev_id = __cpu_to_le32(vdev_id);
2004 cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset);
2005 cmd->buf_len = __cpu_to_le32(bcn->len);
2006
2007 ptr += sizeof(*tlv);
2008 ptr += sizeof(*cmd);
2009
2010 /* FIXME: prb_ies_len should be probably aligned to 4byte boundary but
2011 * then it is then impossible to pass original ie len.
2012 * This chunk is not used yet so if setting probe resp template yields
2013 * problems with beaconing or crashes firmware look here.
2014 */
2015 tlv = ptr;
2016 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
2017 tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len);
2018 info = (void *)tlv->value;
2019 info->caps = __cpu_to_le32(prb_caps);
2020 info->erp = __cpu_to_le32(prb_erp);
2021 memcpy(info->ies, prb_ies, prb_ies_len);
2022
2023 ptr += sizeof(*tlv);
2024 ptr += sizeof(*info);
2025 ptr += prb_ies_len;
2026
2027 tlv = ptr;
2028 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2029 tlv->len = __cpu_to_le16(roundup(bcn->len, 4));
2030 memcpy(tlv->value, bcn->data, bcn->len);
2031
2032 /* FIXME: Adjust TSF? */
2033
2034 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n",
2035 vdev_id);
2036 return skb;
2037}
2038
1975/****************/ 2039/****************/
1976/* TLV mappings */ 2040/* TLV mappings */
1977/****************/ 2041/****************/
@@ -2261,6 +2325,7 @@ static const struct wmi_ops wmi_tlv_ops = {
2261 /* .gen_addba_send not implemented */ 2325 /* .gen_addba_send not implemented */
2262 /* .gen_addba_set_resp not implemented */ 2326 /* .gen_addba_set_resp not implemented */
2263 /* .gen_delba_send not implemented */ 2327 /* .gen_delba_send not implemented */
2328 .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
2264}; 2329};
2265 2330
2266/************/ 2331/************/
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index ee19353ce65c..c4773652d380 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1387,6 +1387,18 @@ struct wmi_tlv_bcn_tx_status_ev {
1387 __le32 tx_status; 1387 __le32 tx_status;
1388} __packed; 1388} __packed;
1389 1389
1390struct wmi_tlv_bcn_prb_info {
1391 __le32 caps;
1392 __le32 erp;
1393 u8 ies[0];
1394} __packed;
1395
1396struct wmi_tlv_bcn_tmpl_cmd {
1397 __le32 vdev_id;
1398 __le32 tim_ie_offset;
1399 __le32 buf_len;
1400} __packed;
1401
1390void ath10k_wmi_tlv_attach(struct ath10k *ar); 1402void ath10k_wmi_tlv_attach(struct ath10k *ar);
1391 1403
1392#endif 1404#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 2d3c700e2cbb..d37a4859fc2a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -5038,6 +5038,7 @@ static const struct wmi_ops wmi_ops = {
5038 .gen_addba_send = ath10k_wmi_op_gen_addba_send, 5038 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
5039 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 5039 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
5040 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 5040 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
5041 /* .gen_bcn_tmpl not implemented */
5041}; 5042};
5042 5043
5043static const struct wmi_ops wmi_10_1_ops = { 5044static const struct wmi_ops wmi_10_1_ops = {
@@ -5096,6 +5097,7 @@ static const struct wmi_ops wmi_10_1_ops = {
5096 .gen_addba_send = ath10k_wmi_op_gen_addba_send, 5097 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
5097 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 5098 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
5098 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 5099 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
5100 /* .gen_bcn_tmpl not implemented */
5099}; 5101};
5100 5102
5101static const struct wmi_ops wmi_10_2_ops = { 5103static const struct wmi_ops wmi_10_2_ops = {
@@ -5214,6 +5216,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
5214 .gen_addba_send = ath10k_wmi_op_gen_addba_send, 5216 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
5215 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 5217 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
5216 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 5218 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
5219 /* .gen_bcn_tmpl not implemented */
5217}; 5220};
5218 5221
5219int ath10k_wmi_attach(struct ath10k *ar) 5222int ath10k_wmi_attach(struct ath10k *ar)