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