1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2021 MediaTek Inc. */
3 
4 #include <linux/iopoll.h>
5 #include <linux/mmc/sdio_func.h>
6 #include "mt7921.h"
7 #include "mac.h"
8 
9 static void
10 mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
11 		   enum mt76_txq_id qid, struct ieee80211_sta *sta,
12 		   struct sk_buff *skb)
13 {
14 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
15 	struct ieee80211_key_conf *key = info->control.hw_key;
16 	__le32 *txwi;
17 	int pid;
18 
19 	pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
20 	txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
21 	memset(txwi, 0, MT_SDIO_TXD_SIZE);
22 	mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false);
23 	skb_push(skb, MT_SDIO_TXD_SIZE);
24 }
25 
26 int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
27 			   enum mt76_txq_id qid, struct mt76_wcid *wcid,
28 			   struct ieee80211_sta *sta,
29 			   struct mt76_tx_info *tx_info)
30 {
31 	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
32 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
33 	struct sk_buff *skb = tx_info->skb;
34 	int pad;
35 
36 	if (unlikely(tx_info->skb->len <= ETH_HLEN))
37 		return -EINVAL;
38 
39 	if (!wcid)
40 		wcid = &dev->mt76.global_wcid;
41 
42 	if (sta) {
43 		struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;
44 
45 		if (time_after(jiffies, msta->last_txs + HZ / 4)) {
46 			info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
47 			msta->last_txs = jiffies;
48 		}
49 	}
50 
51 	mt7921s_write_txwi(dev, wcid, qid, sta, skb);
52 
53 	mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA);
54 	pad = round_up(skb->len, 4) - skb->len;
55 
56 	return mt76_skb_adjust_pad(skb, pad);
57 }
58 
59 void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
60 {
61 	__le32 *txwi = (__le32 *)(e->skb->data + MT_SDIO_HDR_SIZE);
62 	unsigned int headroom = MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;
63 	struct ieee80211_sta *sta;
64 	struct mt76_wcid *wcid;
65 	u16 idx;
66 
67 	idx = FIELD_GET(MT_TXD1_WLAN_IDX, le32_to_cpu(txwi[1]));
68 	wcid = rcu_dereference(mdev->wcid[idx]);
69 	sta = wcid_to_sta(wcid);
70 
71 	if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
72 		mt7921_tx_check_aggr(sta, txwi);
73 
74 	skb_pull(e->skb, headroom);
75 	mt76_tx_complete_skb(mdev, e->wcid, e->skb);
76 }
77 
78 bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update)
79 {
80 	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
81 
82 	mt7921_mutex_acquire(dev);
83 	mt7921_mac_sta_poll(dev);
84 	mt7921_mutex_release(dev);
85 
86 	return 0;
87 }
88