diff options
author | Janusz Dziedzic <janusz.dziedzic@tieto.com> | 2015-01-24 05:14:52 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2015-01-27 09:21:12 -0500 |
commit | 0c7e477c666e767f231fafe08e117669c64e5e14 (patch) | |
tree | 416cb59613243c4503f55a33d4dd2b570a29e7f5 /drivers/net/wireless/ath | |
parent | bf0a26d31ba141b7f41976392ea393ce90ca64e3 (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.h | 25 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-tlv.c | 73 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.h | 24 |
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 | ||
142 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); | 146 | int 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 | ||
578 | static inline int | 582 | static inline int |
583 | ath10k_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 | |||
603 | static inline int | ||
579 | ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, | 604 | ath10k_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 | ||
1515 | static 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 | |||
1540 | static struct sk_buff * | ||
1541 | ath10k_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 | |||
1515 | static struct sk_buff * | 1587 | static struct sk_buff * |
1516 | ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, | 1588 | ath10k_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 | |||
4124 | struct 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 | |||
4132 | struct 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 | |||
4138 | struct 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 | |||
4122 | enum wmi_sta_powersave_param { | 4146 | enum 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 |