ath10k: bring back the WMI path for mgmt frames
This is still the only way to submit mgmt frames in case of 10.X firmware. This patch introduces wmi_mgmt_tx queue, because of the fact WMI command can block. This is a problem for ath10k_tx_htt(), since it's called from atomic context. The skb queue and worker are introduced to move the mgmt frame handling out of .tx callback context and not block. Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:

committed by
Kalle Valo

parent
b3effe61a1
commit
5e00d31a0f
@@ -410,6 +410,57 @@ static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
int ret = 0;
|
||||
struct wmi_mgmt_tx_cmd *cmd;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *wmi_skb;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
int len;
|
||||
u16 fc;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
fc = le16_to_cpu(hdr->frame_control);
|
||||
|
||||
if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
|
||||
return -EINVAL;
|
||||
|
||||
len = sizeof(cmd->hdr) + skb->len;
|
||||
len = round_up(len, 4);
|
||||
|
||||
wmi_skb = ath10k_wmi_alloc_skb(len);
|
||||
if (!wmi_skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_mgmt_tx_cmd *)wmi_skb->data;
|
||||
|
||||
cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id);
|
||||
cmd->hdr.tx_rate = 0;
|
||||
cmd->hdr.tx_power = 0;
|
||||
cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len));
|
||||
|
||||
memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN);
|
||||
memcpy(cmd->buf, skb->data, skb->len);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n",
|
||||
wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE,
|
||||
fc & IEEE80211_FCTL_STYPE);
|
||||
|
||||
/* Send the management frame buffer to the target */
|
||||
ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid);
|
||||
if (ret) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO: report tx status to mac80211 - temporary just ACK */
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
ieee80211_tx_status_irqsafe(ar->hw, skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data;
|
||||
|
Reference in New Issue
Block a user