|
@@ -2596,6 +2596,155 @@ ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id,
|
|
|
return skb;
|
|
|
}
|
|
|
|
|
|
+static struct sk_buff *
|
|
|
+ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
|
|
|
+ enum wmi_tdls_state state)
|
|
|
+{
|
|
|
+ struct wmi_tdls_set_state_cmd *cmd;
|
|
|
+ struct wmi_tlv *tlv;
|
|
|
+ struct sk_buff *skb;
|
|
|
+ void *ptr;
|
|
|
+ size_t len;
|
|
|
+ /* Set to options from wmi_tlv_tdls_options,
|
|
|
+ * for now none of them are enabled.
|
|
|
+ */
|
|
|
+ u32 options = 0;
|
|
|
+
|
|
|
+ len = sizeof(*tlv) + sizeof(*cmd);
|
|
|
+ skb = ath10k_wmi_alloc_skb(ar, len);
|
|
|
+ if (!skb)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+
|
|
|
+ ptr = (void *)skb->data;
|
|
|
+ tlv = ptr;
|
|
|
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD);
|
|
|
+ tlv->len = __cpu_to_le16(sizeof(*cmd));
|
|
|
+
|
|
|
+ cmd = (void *)tlv->value;
|
|
|
+ cmd->vdev_id = __cpu_to_le32(vdev_id);
|
|
|
+ cmd->state = __cpu_to_le32(state);
|
|
|
+ cmd->notification_interval_ms = __cpu_to_le32(5000);
|
|
|
+ cmd->tx_discovery_threshold = __cpu_to_le32(100);
|
|
|
+ cmd->tx_teardown_threshold = __cpu_to_le32(5);
|
|
|
+ cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
|
|
|
+ cmd->rssi_delta = __cpu_to_le32(-20);
|
|
|
+ cmd->tdls_options = __cpu_to_le32(options);
|
|
|
+ cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
|
|
|
+ cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
|
|
|
+ cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
|
|
|
+ cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
|
|
|
+ cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
|
|
|
+
|
|
|
+ ptr += sizeof(*tlv);
|
|
|
+ ptr += sizeof(*cmd);
|
|
|
+
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n",
|
|
|
+ state, vdev_id);
|
|
|
+ return skb;
|
|
|
+}
|
|
|
+
|
|
|
+static u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp)
|
|
|
+{
|
|
|
+ u32 peer_qos = 0;
|
|
|
+
|
|
|
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
|
|
|
+ peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO;
|
|
|
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
|
|
|
+ peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI;
|
|
|
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
|
|
|
+ peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK;
|
|
|
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
|
|
|
+ peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE;
|
|
|
+
|
|
|
+ peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP);
|
|
|
+
|
|
|
+ return peer_qos;
|
|
|
+}
|
|
|
+
|
|
|
+static struct sk_buff *
|
|
|
+ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
|
|
|
+ const struct wmi_tdls_peer_update_cmd_arg *arg,
|
|
|
+ const struct wmi_tdls_peer_capab_arg *cap,
|
|
|
+ const struct wmi_channel_arg *chan_arg)
|
|
|
+{
|
|
|
+ struct wmi_tdls_peer_update_cmd *cmd;
|
|
|
+ struct wmi_tdls_peer_capab *peer_cap;
|
|
|
+ struct wmi_channel *chan;
|
|
|
+ struct wmi_tlv *tlv;
|
|
|
+ struct sk_buff *skb;
|
|
|
+ u32 peer_qos;
|
|
|
+ void *ptr;
|
|
|
+ int len;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ len = sizeof(*tlv) + sizeof(*cmd) +
|
|
|
+ sizeof(*tlv) + sizeof(*peer_cap) +
|
|
|
+ sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan);
|
|
|
+
|
|
|
+ skb = ath10k_wmi_alloc_skb(ar, len);
|
|
|
+ if (!skb)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+
|
|
|
+ ptr = (void *)skb->data;
|
|
|
+ tlv = ptr;
|
|
|
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD);
|
|
|
+ tlv->len = __cpu_to_le16(sizeof(*cmd));
|
|
|
+
|
|
|
+ cmd = (void *)tlv->value;
|
|
|
+ cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
|
|
|
+ ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
|
|
|
+ cmd->peer_state = __cpu_to_le32(arg->peer_state);
|
|
|
+
|
|
|
+ ptr += sizeof(*tlv);
|
|
|
+ ptr += sizeof(*cmd);
|
|
|
+
|
|
|
+ tlv = ptr;
|
|
|
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES);
|
|
|
+ tlv->len = __cpu_to_le16(sizeof(*peer_cap));
|
|
|
+ peer_cap = (void *)tlv->value;
|
|
|
+ peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues,
|
|
|
+ cap->peer_max_sp);
|
|
|
+ peer_cap->peer_qos = __cpu_to_le32(peer_qos);
|
|
|
+ peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
|
|
|
+ peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
|
|
|
+ peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
|
|
|
+ peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
|
|
|
+ peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
|
|
|
+ peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
|
|
|
+
|
|
|
+ for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
|
|
|
+ peer_cap->peer_operclass[i] = cap->peer_operclass[i];
|
|
|
+
|
|
|
+ peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
|
|
|
+ peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
|
|
|
+ peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
|
|
|
+
|
|
|
+ ptr += sizeof(*tlv);
|
|
|
+ ptr += sizeof(*peer_cap);
|
|
|
+
|
|
|
+ tlv = ptr;
|
|
|
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
|
|
|
+ tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan));
|
|
|
+
|
|
|
+ ptr += sizeof(*tlv);
|
|
|
+
|
|
|
+ for (i = 0; i < cap->peer_chan_len; i++) {
|
|
|
+ tlv = ptr;
|
|
|
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
|
|
|
+ tlv->len = __cpu_to_le16(sizeof(*chan));
|
|
|
+ chan = (void *)tlv->value;
|
|
|
+ ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
|
|
|
+
|
|
|
+ ptr += sizeof(*tlv);
|
|
|
+ ptr += sizeof(*chan);
|
|
|
+ }
|
|
|
+
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
|
|
|
+ "wmi tlv tdls peer update vdev %i state %d n_chans %u\n",
|
|
|
+ arg->vdev_id, arg->peer_state, cap->peer_chan_len);
|
|
|
+ return skb;
|
|
|
+}
|
|
|
+
|
|
|
static struct sk_buff *
|
|
|
ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
|
|
|
{
|
|
@@ -2924,6 +3073,8 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = {
|
|
|
.gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
|
|
|
.pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED,
|
|
|
.vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
|
|
|
+ .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID,
|
|
|
+ .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID,
|
|
|
};
|
|
|
|
|
|
static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
|
|
@@ -3103,6 +3254,8 @@ static const struct wmi_ops wmi_tlv_ops = {
|
|
|
.gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind,
|
|
|
.gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern,
|
|
|
.gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern,
|
|
|
+ .gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
|
|
|
+ .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
|
|
|
};
|
|
|
|
|
|
/************/
|