diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2015-01-13 09:30:11 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2015-01-15 05:30:07 -0500 |
commit | be9ce9d8c196bf150eace10aaf43110672d6eb4c (patch) | |
tree | b05d86dadb7c25f3645d41fa779d375b24744fbf /drivers/net/wireless | |
parent | 6bf1206289115c277cfa569f570a97ada345a2d5 (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.h | 23 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-tlv.c | 65 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-tlv.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 3 |
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 | ||
134 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); | 138 | int 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 | ||
942 | static inline int | ||
943 | ath10k_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 | ||
1975 | static struct sk_buff * | ||
1976 | ath10k_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 | ||
1390 | struct wmi_tlv_bcn_prb_info { | ||
1391 | __le32 caps; | ||
1392 | __le32 erp; | ||
1393 | u8 ies[0]; | ||
1394 | } __packed; | ||
1395 | |||
1396 | struct wmi_tlv_bcn_tmpl_cmd { | ||
1397 | __le32 vdev_id; | ||
1398 | __le32 tim_ie_offset; | ||
1399 | __le32 buf_len; | ||
1400 | } __packed; | ||
1401 | |||
1390 | void ath10k_wmi_tlv_attach(struct ath10k *ar); | 1402 | void 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 | ||
5043 | static const struct wmi_ops wmi_10_1_ops = { | 5044 | static 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 | ||
5101 | static const struct wmi_ops wmi_10_2_ops = { | 5103 | static 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 | ||
5219 | int ath10k_wmi_attach(struct ath10k *ar) | 5222 | int ath10k_wmi_attach(struct ath10k *ar) |