aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorJanusz Dziedzic <janusz.dziedzic@tieto.com>2015-01-24 05:14:52 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2015-01-27 09:21:12 -0500
commit0c7e477c666e767f231fafe08e117669c64e5e14 (patch)
tree416cb59613243c4503f55a33d4dd2b570a29e7f5 /drivers/net/wireless/ath
parentbf0a26d31ba141b7f41976392ea393ce90ca64e3 (diff)
ath10k: implement uapsd autotrigger command
New wmi-tlv firmware for qca6174 has u-UAPSD autotrigger service. If it is enabled firmware generates trigger frames automatically as configured. 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/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h25
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c73
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h24
3 files changed, 122 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 0dd49a7a89f0..80bd28ac2ccb 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -137,6 +137,10 @@ struct wmi_ops {
137 struct sk_buff *bcn); 137 struct sk_buff *bcn);
138 struct sk_buff *(*gen_p2p_go_bcn_ie)(struct ath10k *ar, u32 vdev_id, 138 struct sk_buff *(*gen_p2p_go_bcn_ie)(struct ath10k *ar, u32 vdev_id,
139 const u8 *p2p_ie); 139 const u8 *p2p_ie);
140 struct sk_buff *(*gen_vdev_sta_uapsd)(struct ath10k *ar, u32 vdev_id,
141 const u8 peer_addr[ETH_ALEN],
142 const struct wmi_sta_uapsd_auto_trig_arg *args,
143 u32 num_ac);
140}; 144};
141 145
142int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 146int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -576,6 +580,27 @@ ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger,
576} 580}
577 581
578static inline int 582static inline int
583ath10k_wmi_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id,
584 const u8 peer_addr[ETH_ALEN],
585 const struct wmi_sta_uapsd_auto_trig_arg *args,
586 u32 num_ac)
587{
588 struct sk_buff *skb;
589 u32 cmd_id;
590
591 if (!ar->wmi.ops->gen_vdev_sta_uapsd)
592 return -EOPNOTSUPP;
593
594 skb = ar->wmi.ops->gen_vdev_sta_uapsd(ar, vdev_id, peer_addr, args,
595 num_ac);
596 if (IS_ERR(skb))
597 return PTR_ERR(skb);
598
599 cmd_id = ar->wmi.cmd->sta_uapsd_auto_trig_cmdid;
600 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
601}
602
603static inline int
579ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, 604ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
580 const u8 peer_addr[ETH_ALEN]) 605 const u8 peer_addr[ETH_ALEN])
581{ 606{
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 35f519123752..d3cf91dc950b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1512,6 +1512,78 @@ ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
1512 return skb; 1512 return skb;
1513} 1513}
1514 1514
1515static void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr,
1516 const struct wmi_sta_uapsd_auto_trig_arg *arg)
1517{
1518 struct wmi_sta_uapsd_auto_trig_param *ac;
1519 struct wmi_tlv *tlv;
1520
1521 tlv = ptr;
1522 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM);
1523 tlv->len = __cpu_to_le16(sizeof(*ac));
1524 ac = (void *)tlv->value;
1525
1526 ac->wmm_ac = __cpu_to_le32(arg->wmm_ac);
1527 ac->user_priority = __cpu_to_le32(arg->user_priority);
1528 ac->service_interval = __cpu_to_le32(arg->service_interval);
1529 ac->suspend_interval = __cpu_to_le32(arg->suspend_interval);
1530 ac->delay_interval = __cpu_to_le32(arg->delay_interval);
1531
1532 ath10k_dbg(ar, ATH10K_DBG_WMI,
1533 "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n",
1534 ac->wmm_ac, ac->user_priority, ac->service_interval,
1535 ac->suspend_interval, ac->delay_interval);
1536
1537 return ptr + sizeof(*tlv) + sizeof(*ac);
1538}
1539
1540static struct sk_buff *
1541ath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id,
1542 const u8 peer_addr[ETH_ALEN],
1543 const struct wmi_sta_uapsd_auto_trig_arg *args,
1544 u32 num_ac)
1545{
1546 struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
1547 struct wmi_sta_uapsd_auto_trig_param *ac;
1548 struct wmi_tlv *tlv;
1549 struct sk_buff *skb;
1550 size_t len;
1551 size_t ac_tlv_len;
1552 void *ptr;
1553 int i;
1554
1555 ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac));
1556 len = sizeof(*tlv) + sizeof(*cmd) +
1557 sizeof(*tlv) + ac_tlv_len;
1558 skb = ath10k_wmi_alloc_skb(ar, len);
1559 if (!skb)
1560 return ERR_PTR(-ENOMEM);
1561
1562 ptr = (void *)skb->data;
1563 tlv = ptr;
1564 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD);
1565 tlv->len = __cpu_to_le16(sizeof(*cmd));
1566 cmd = (void *)tlv->value;
1567 cmd->vdev_id = __cpu_to_le32(vdev_id);
1568 cmd->num_ac = __cpu_to_le32(num_ac);
1569 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1570
1571 ptr += sizeof(*tlv);
1572 ptr += sizeof(*cmd);
1573
1574 tlv = ptr;
1575 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1576 tlv->len = __cpu_to_le16(ac_tlv_len);
1577 ac = (void *)tlv->value;
1578
1579 ptr += sizeof(*tlv);
1580 for (i = 0; i < num_ac; i++)
1581 ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]);
1582
1583 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n");
1584 return skb;
1585}
1586
1515static struct sk_buff * 1587static struct sk_buff *
1516ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, 1588ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
1517 const u8 peer_addr[ETH_ALEN]) 1589 const u8 peer_addr[ETH_ALEN])
@@ -2523,6 +2595,7 @@ static const struct wmi_ops wmi_tlv_ops = {
2523 .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl, 2595 .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
2524 .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl, 2596 .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl,
2525 .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, 2597 .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
2598 .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
2526}; 2599};
2527 2600
2528/************/ 2601/************/
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 0514b1a525ff..34d8c44b90e8 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4119,6 +4119,30 @@ enum wmi_sta_ps_param_uapsd {
4119 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN = (1 << 7), 4119 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN = (1 << 7),
4120}; 4120};
4121 4121
4122#define WMI_STA_UAPSD_MAX_INTERVAL_MSEC UINT_MAX
4123
4124struct wmi_sta_uapsd_auto_trig_param {
4125 __le32 wmm_ac;
4126 __le32 user_priority;
4127 __le32 service_interval;
4128 __le32 suspend_interval;
4129 __le32 delay_interval;
4130};
4131
4132struct wmi_sta_uapsd_auto_trig_cmd_fixed_param {
4133 __le32 vdev_id;
4134 struct wmi_mac_addr peer_macaddr;
4135 __le32 num_ac;
4136};
4137
4138struct wmi_sta_uapsd_auto_trig_arg {
4139 u32 wmm_ac;
4140 u32 user_priority;
4141 u32 service_interval;
4142 u32 suspend_interval;
4143 u32 delay_interval;
4144};
4145
4122enum wmi_sta_powersave_param { 4146enum wmi_sta_powersave_param {
4123 /* 4147 /*
4124 * Controls how frames are retrievd from AP while STA is sleeping 4148 * Controls how frames are retrievd from AP while STA is sleeping