1c8846e10SFelix Fietkau /* SPDX-License-Identifier: ISC */ 2c8846e10SFelix Fietkau 3c8846e10SFelix Fietkau #include "mt7603.h" 4c8846e10SFelix Fietkau #include "mac.h" 5c8846e10SFelix Fietkau #include "../dma.h" 6c8846e10SFelix Fietkau 7c8846e10SFelix Fietkau static int 8c8846e10SFelix Fietkau mt7603_init_tx_queue(struct mt7603_dev *dev, struct mt76_queue *q, 9c8846e10SFelix Fietkau int idx, int n_desc) 10c8846e10SFelix Fietkau { 11b1bfbe70SLorenzo Bianconi int err; 12c8846e10SFelix Fietkau 13b1bfbe70SLorenzo Bianconi err = mt76_queue_alloc(dev, q, idx, n_desc, 0, 14b1bfbe70SLorenzo Bianconi MT_TX_RING_BASE); 15b1bfbe70SLorenzo Bianconi if (err < 0) 16b1bfbe70SLorenzo Bianconi return err; 17c8846e10SFelix Fietkau 18c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_TX_DONE(idx)); 19c8846e10SFelix Fietkau 20c8846e10SFelix Fietkau return 0; 21c8846e10SFelix Fietkau } 22c8846e10SFelix Fietkau 23c8846e10SFelix Fietkau static void 24c8846e10SFelix Fietkau mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb) 25c8846e10SFelix Fietkau { 26c8846e10SFelix Fietkau __le32 *txd = (__le32 *)skb->data; 27e004b700SFelix Fietkau struct ieee80211_hdr *hdr; 28e004b700SFelix Fietkau struct ieee80211_sta *sta; 29c8846e10SFelix Fietkau struct mt7603_sta *msta; 30c8846e10SFelix Fietkau struct mt76_wcid *wcid; 31e004b700SFelix Fietkau void *priv; 32c8846e10SFelix Fietkau int idx; 33c8846e10SFelix Fietkau u32 val; 34e004b700SFelix Fietkau u8 tid; 35c8846e10SFelix Fietkau 36e004b700SFelix Fietkau if (skb->len < MT_TXD_SIZE + sizeof(struct ieee80211_hdr)) 37c8846e10SFelix Fietkau goto free; 38c8846e10SFelix Fietkau 39c8846e10SFelix Fietkau val = le32_to_cpu(txd[1]); 40c8846e10SFelix Fietkau idx = FIELD_GET(MT_TXD1_WLAN_IDX, val); 41c8846e10SFelix Fietkau skb->priority = FIELD_GET(MT_TXD1_TID, val); 42c8846e10SFelix Fietkau 43c8846e10SFelix Fietkau if (idx >= MT7603_WTBL_STA - 1) 44c8846e10SFelix Fietkau goto free; 45c8846e10SFelix Fietkau 46c8846e10SFelix Fietkau wcid = rcu_dereference(dev->mt76.wcid[idx]); 47c8846e10SFelix Fietkau if (!wcid) 48c8846e10SFelix Fietkau goto free; 49c8846e10SFelix Fietkau 50e004b700SFelix Fietkau priv = msta = container_of(wcid, struct mt7603_sta, wcid); 51c8846e10SFelix Fietkau val = le32_to_cpu(txd[0]); 52c8846e10SFelix Fietkau skb_set_queue_mapping(skb, FIELD_GET(MT_TXD0_Q_IDX, val)); 53c8846e10SFelix Fietkau 54fca9615fSFelix Fietkau val &= ~(MT_TXD0_P_IDX | MT_TXD0_Q_IDX); 55fca9615fSFelix Fietkau val |= FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_HW_QUEUE_MGMT); 56fca9615fSFelix Fietkau txd[0] = cpu_to_le32(val); 57fca9615fSFelix Fietkau 58e004b700SFelix Fietkau sta = container_of(priv, struct ieee80211_sta, drv_priv); 59e004b700SFelix Fietkau hdr = (struct ieee80211_hdr *) &skb->data[MT_TXD_SIZE]; 60e004b700SFelix Fietkau tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 61e004b700SFelix Fietkau ieee80211_sta_set_buffered(sta, tid, true); 62e004b700SFelix Fietkau 63c8846e10SFelix Fietkau spin_lock_bh(&dev->ps_lock); 64c8846e10SFelix Fietkau __skb_queue_tail(&msta->psq, skb); 65c8846e10SFelix Fietkau if (skb_queue_len(&msta->psq) >= 64) { 66c8846e10SFelix Fietkau skb = __skb_dequeue(&msta->psq); 67c8846e10SFelix Fietkau dev_kfree_skb(skb); 68c8846e10SFelix Fietkau } 69c8846e10SFelix Fietkau spin_unlock_bh(&dev->ps_lock); 70c8846e10SFelix Fietkau return; 71c8846e10SFelix Fietkau 72c8846e10SFelix Fietkau free: 73c8846e10SFelix Fietkau dev_kfree_skb(skb); 74c8846e10SFelix Fietkau } 75c8846e10SFelix Fietkau 76c8846e10SFelix Fietkau void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, 77c8846e10SFelix Fietkau struct sk_buff *skb) 78c8846e10SFelix Fietkau { 79c8846e10SFelix Fietkau struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); 80c8846e10SFelix Fietkau __le32 *rxd = (__le32 *)skb->data; 81c8846e10SFelix Fietkau __le32 *end = (__le32 *)&skb->data[skb->len]; 82c8846e10SFelix Fietkau enum rx_pkt_type type; 83c8846e10SFelix Fietkau 84c8846e10SFelix Fietkau type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0])); 85c8846e10SFelix Fietkau 86c8846e10SFelix Fietkau if (q == MT_RXQ_MCU) { 87c8846e10SFelix Fietkau if (type == PKT_TYPE_RX_EVENT) 88c8846e10SFelix Fietkau mt76_mcu_rx_event(&dev->mt76, skb); 89c8846e10SFelix Fietkau else 90c8846e10SFelix Fietkau mt7603_rx_loopback_skb(dev, skb); 91c8846e10SFelix Fietkau return; 92c8846e10SFelix Fietkau } 93c8846e10SFelix Fietkau 94c8846e10SFelix Fietkau switch (type) { 95c8846e10SFelix Fietkau case PKT_TYPE_TXS: 96c8846e10SFelix Fietkau for (rxd++; rxd + 5 <= end; rxd += 5) 97c8846e10SFelix Fietkau mt7603_mac_add_txs(dev, rxd); 98c8846e10SFelix Fietkau dev_kfree_skb(skb); 99c8846e10SFelix Fietkau break; 100c8846e10SFelix Fietkau case PKT_TYPE_RX_EVENT: 101c8846e10SFelix Fietkau mt76_mcu_rx_event(&dev->mt76, skb); 102c8846e10SFelix Fietkau return; 103c8846e10SFelix Fietkau case PKT_TYPE_NORMAL: 104c8846e10SFelix Fietkau if (mt7603_mac_fill_rx(dev, skb) == 0) { 105c8846e10SFelix Fietkau mt76_rx(&dev->mt76, q, skb); 106c8846e10SFelix Fietkau return; 107c8846e10SFelix Fietkau } 108c8846e10SFelix Fietkau /* fall through */ 109c8846e10SFelix Fietkau default: 110c8846e10SFelix Fietkau dev_kfree_skb(skb); 111c8846e10SFelix Fietkau break; 112c8846e10SFelix Fietkau } 113c8846e10SFelix Fietkau } 114c8846e10SFelix Fietkau 115c8846e10SFelix Fietkau static int 116c8846e10SFelix Fietkau mt7603_init_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q, 117c8846e10SFelix Fietkau int idx, int n_desc, int bufsize) 118c8846e10SFelix Fietkau { 119b1bfbe70SLorenzo Bianconi int err; 120c8846e10SFelix Fietkau 121b1bfbe70SLorenzo Bianconi err = mt76_queue_alloc(dev, q, idx, n_desc, bufsize, 122b1bfbe70SLorenzo Bianconi MT_RX_RING_BASE); 123b1bfbe70SLorenzo Bianconi if (err < 0) 124b1bfbe70SLorenzo Bianconi return err; 125c8846e10SFelix Fietkau 126c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_RX_DONE(idx)); 127c8846e10SFelix Fietkau 128c8846e10SFelix Fietkau return 0; 129c8846e10SFelix Fietkau } 130c8846e10SFelix Fietkau 131c8846e10SFelix Fietkau static void 132c8846e10SFelix Fietkau mt7603_tx_tasklet(unsigned long data) 133c8846e10SFelix Fietkau { 134c8846e10SFelix Fietkau struct mt7603_dev *dev = (struct mt7603_dev *)data; 135c8846e10SFelix Fietkau int i; 136c8846e10SFelix Fietkau 137c8846e10SFelix Fietkau dev->tx_dma_check = 0; 138c8846e10SFelix Fietkau for (i = MT_TXQ_MCU; i >= 0; i--) 139c8846e10SFelix Fietkau mt76_queue_tx_cleanup(dev, i, false); 140c8846e10SFelix Fietkau 141c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL); 142c8846e10SFelix Fietkau } 143c8846e10SFelix Fietkau 144c8846e10SFelix Fietkau int mt7603_dma_init(struct mt7603_dev *dev) 145c8846e10SFelix Fietkau { 146c8846e10SFelix Fietkau static const u8 wmm_queue_map[] = { 147c8846e10SFelix Fietkau [IEEE80211_AC_BK] = 0, 148c8846e10SFelix Fietkau [IEEE80211_AC_BE] = 1, 149c8846e10SFelix Fietkau [IEEE80211_AC_VI] = 2, 150c8846e10SFelix Fietkau [IEEE80211_AC_VO] = 3, 151c8846e10SFelix Fietkau }; 152c8846e10SFelix Fietkau int ret; 153c8846e10SFelix Fietkau int i; 154c8846e10SFelix Fietkau 155c8846e10SFelix Fietkau mt76_dma_attach(&dev->mt76); 156c8846e10SFelix Fietkau 157c8846e10SFelix Fietkau init_waitqueue_head(&dev->mt76.mmio.mcu.wait); 158c8846e10SFelix Fietkau skb_queue_head_init(&dev->mt76.mmio.mcu.res_q); 159c8846e10SFelix Fietkau 160c8846e10SFelix Fietkau tasklet_init(&dev->tx_tasklet, mt7603_tx_tasklet, (unsigned long)dev); 161c8846e10SFelix Fietkau 162c8846e10SFelix Fietkau mt76_clear(dev, MT_WPDMA_GLO_CFG, 163c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_DMA_EN | 164c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_RX_DMA_EN | 165c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_DMA_BURST_SIZE | 166c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); 167c8846e10SFelix Fietkau 168c8846e10SFelix Fietkau mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); 169c8846e10SFelix Fietkau mt7603_pse_client_reset(dev); 170c8846e10SFelix Fietkau 171c8846e10SFelix Fietkau for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) { 172c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[i], 173c8846e10SFelix Fietkau wmm_queue_map[i], 174c8846e10SFelix Fietkau MT_TX_RING_SIZE); 175c8846e10SFelix Fietkau if (ret) 176c8846e10SFelix Fietkau return ret; 177c8846e10SFelix Fietkau } 178c8846e10SFelix Fietkau 179c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_PSD], 180c8846e10SFelix Fietkau MT_TX_HW_QUEUE_MGMT, MT_TX_RING_SIZE); 181c8846e10SFelix Fietkau if (ret) 182c8846e10SFelix Fietkau return ret; 183c8846e10SFelix Fietkau 184c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_MCU], 185c8846e10SFelix Fietkau MT_TX_HW_QUEUE_MCU, MT_MCU_RING_SIZE); 186c8846e10SFelix Fietkau if (ret) 187c8846e10SFelix Fietkau return ret; 188c8846e10SFelix Fietkau 189c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_BEACON], 190c8846e10SFelix Fietkau MT_TX_HW_QUEUE_BCN, MT_MCU_RING_SIZE); 191c8846e10SFelix Fietkau if (ret) 192c8846e10SFelix Fietkau return ret; 193c8846e10SFelix Fietkau 194c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_CAB], 195c8846e10SFelix Fietkau MT_TX_HW_QUEUE_BMC, MT_MCU_RING_SIZE); 196c8846e10SFelix Fietkau if (ret) 197c8846e10SFelix Fietkau return ret; 198c8846e10SFelix Fietkau 199c8846e10SFelix Fietkau ret = mt7603_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1, 200c8846e10SFelix Fietkau MT_MCU_RING_SIZE, MT_RX_BUF_SIZE); 201c8846e10SFelix Fietkau if (ret) 202c8846e10SFelix Fietkau return ret; 203c8846e10SFelix Fietkau 204c8846e10SFelix Fietkau ret = mt7603_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0, 205c8846e10SFelix Fietkau MT7603_RX_RING_SIZE, MT_RX_BUF_SIZE); 206c8846e10SFelix Fietkau if (ret) 207c8846e10SFelix Fietkau return ret; 208c8846e10SFelix Fietkau 209c8846e10SFelix Fietkau mt76_wr(dev, MT_DELAY_INT_CFG, 0); 210c8846e10SFelix Fietkau return mt76_init_queues(dev); 211c8846e10SFelix Fietkau } 212c8846e10SFelix Fietkau 213c8846e10SFelix Fietkau void mt7603_dma_cleanup(struct mt7603_dev *dev) 214c8846e10SFelix Fietkau { 215c8846e10SFelix Fietkau mt76_clear(dev, MT_WPDMA_GLO_CFG, 216c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_DMA_EN | 217c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_RX_DMA_EN | 218c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); 219c8846e10SFelix Fietkau 220c8846e10SFelix Fietkau tasklet_kill(&dev->tx_tasklet); 221c8846e10SFelix Fietkau mt76_dma_cleanup(&dev->mt76); 222c8846e10SFelix Fietkau } 223