17f17b86aSRyder Lee // 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 void 8c8846e10SFelix Fietkau mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb) 9c8846e10SFelix Fietkau { 10d55aa5e1SFelix Fietkau static const u8 tid_to_ac[8] = { 11d55aa5e1SFelix Fietkau IEEE80211_AC_BE, 12d55aa5e1SFelix Fietkau IEEE80211_AC_BK, 13d55aa5e1SFelix Fietkau IEEE80211_AC_BK, 14d55aa5e1SFelix Fietkau IEEE80211_AC_BE, 15d55aa5e1SFelix Fietkau IEEE80211_AC_VI, 16d55aa5e1SFelix Fietkau IEEE80211_AC_VI, 17d55aa5e1SFelix Fietkau IEEE80211_AC_VO, 18d55aa5e1SFelix Fietkau IEEE80211_AC_VO 19d55aa5e1SFelix Fietkau }; 20c8846e10SFelix Fietkau __le32 *txd = (__le32 *)skb->data; 21e004b700SFelix Fietkau struct ieee80211_hdr *hdr; 22e004b700SFelix Fietkau struct ieee80211_sta *sta; 23c8846e10SFelix Fietkau struct mt7603_sta *msta; 24c8846e10SFelix Fietkau struct mt76_wcid *wcid; 25e004b700SFelix Fietkau void *priv; 26c8846e10SFelix Fietkau int idx; 27c8846e10SFelix Fietkau u32 val; 28d55aa5e1SFelix Fietkau u8 tid = 0; 29c8846e10SFelix Fietkau 30e004b700SFelix Fietkau if (skb->len < MT_TXD_SIZE + sizeof(struct ieee80211_hdr)) 31c8846e10SFelix Fietkau goto free; 32c8846e10SFelix Fietkau 33c8846e10SFelix Fietkau val = le32_to_cpu(txd[1]); 34c8846e10SFelix Fietkau idx = FIELD_GET(MT_TXD1_WLAN_IDX, val); 35c8846e10SFelix Fietkau skb->priority = FIELD_GET(MT_TXD1_TID, val); 36c8846e10SFelix Fietkau 37c8846e10SFelix Fietkau if (idx >= MT7603_WTBL_STA - 1) 38c8846e10SFelix Fietkau goto free; 39c8846e10SFelix Fietkau 40c8846e10SFelix Fietkau wcid = rcu_dereference(dev->mt76.wcid[idx]); 41c8846e10SFelix Fietkau if (!wcid) 42c8846e10SFelix Fietkau goto free; 43c8846e10SFelix Fietkau 44e004b700SFelix Fietkau priv = msta = container_of(wcid, struct mt7603_sta, wcid); 45c8846e10SFelix Fietkau val = le32_to_cpu(txd[0]); 46fca9615fSFelix Fietkau val &= ~(MT_TXD0_P_IDX | MT_TXD0_Q_IDX); 47fca9615fSFelix Fietkau val |= FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_HW_QUEUE_MGMT); 48fca9615fSFelix Fietkau txd[0] = cpu_to_le32(val); 49fca9615fSFelix Fietkau 50e004b700SFelix Fietkau sta = container_of(priv, struct ieee80211_sta, drv_priv); 51e004b700SFelix Fietkau hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE]; 52d55aa5e1SFelix Fietkau if (ieee80211_is_data_qos(hdr->frame_control)) 53d55aa5e1SFelix Fietkau tid = *ieee80211_get_qos_ctl(hdr) & 54d55aa5e1SFelix Fietkau IEEE80211_QOS_CTL_TAG1D_MASK; 55d55aa5e1SFelix Fietkau skb_set_queue_mapping(skb, tid_to_ac[tid]); 56e004b700SFelix Fietkau ieee80211_sta_set_buffered(sta, tid, true); 57e004b700SFelix Fietkau 58c8846e10SFelix Fietkau spin_lock_bh(&dev->ps_lock); 59c8846e10SFelix Fietkau __skb_queue_tail(&msta->psq, skb); 60c8846e10SFelix Fietkau if (skb_queue_len(&msta->psq) >= 64) { 61c8846e10SFelix Fietkau skb = __skb_dequeue(&msta->psq); 62c8846e10SFelix Fietkau dev_kfree_skb(skb); 63c8846e10SFelix Fietkau } 64c8846e10SFelix Fietkau spin_unlock_bh(&dev->ps_lock); 65c8846e10SFelix Fietkau return; 66c8846e10SFelix Fietkau 67c8846e10SFelix Fietkau free: 68c8846e10SFelix Fietkau dev_kfree_skb(skb); 69c8846e10SFelix Fietkau } 70c8846e10SFelix Fietkau 71c8846e10SFelix Fietkau void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, 72c8846e10SFelix Fietkau struct sk_buff *skb) 73c8846e10SFelix Fietkau { 74c8846e10SFelix Fietkau struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); 75c8846e10SFelix Fietkau __le32 *rxd = (__le32 *)skb->data; 76c8846e10SFelix Fietkau __le32 *end = (__le32 *)&skb->data[skb->len]; 77c8846e10SFelix Fietkau enum rx_pkt_type type; 78c8846e10SFelix Fietkau 79*f1fe8eefSRyder Lee type = le32_get_bits(rxd[0], MT_RXD0_PKT_TYPE); 80c8846e10SFelix Fietkau 81c8846e10SFelix Fietkau if (q == MT_RXQ_MCU) { 82c8846e10SFelix Fietkau if (type == PKT_TYPE_RX_EVENT) 83c8846e10SFelix Fietkau mt76_mcu_rx_event(&dev->mt76, skb); 84c8846e10SFelix Fietkau else 85c8846e10SFelix Fietkau mt7603_rx_loopback_skb(dev, skb); 86c8846e10SFelix Fietkau return; 87c8846e10SFelix Fietkau } 88c8846e10SFelix Fietkau 89c8846e10SFelix Fietkau switch (type) { 90c8846e10SFelix Fietkau case PKT_TYPE_TXS: 91c8846e10SFelix Fietkau for (rxd++; rxd + 5 <= end; rxd += 5) 92c8846e10SFelix Fietkau mt7603_mac_add_txs(dev, rxd); 93c8846e10SFelix Fietkau dev_kfree_skb(skb); 94c8846e10SFelix Fietkau break; 95c8846e10SFelix Fietkau case PKT_TYPE_RX_EVENT: 96c8846e10SFelix Fietkau mt76_mcu_rx_event(&dev->mt76, skb); 97c8846e10SFelix Fietkau return; 98c8846e10SFelix Fietkau case PKT_TYPE_NORMAL: 99c8846e10SFelix Fietkau if (mt7603_mac_fill_rx(dev, skb) == 0) { 100c8846e10SFelix Fietkau mt76_rx(&dev->mt76, q, skb); 101c8846e10SFelix Fietkau return; 102c8846e10SFelix Fietkau } 103aab662ccSGustavo A. R. Silva fallthrough; 104c8846e10SFelix Fietkau default: 105c8846e10SFelix Fietkau dev_kfree_skb(skb); 106c8846e10SFelix Fietkau break; 107c8846e10SFelix Fietkau } 108c8846e10SFelix Fietkau } 109c8846e10SFelix Fietkau 110c8846e10SFelix Fietkau static int 111c8846e10SFelix Fietkau mt7603_init_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q, 112c8846e10SFelix Fietkau int idx, int n_desc, int bufsize) 113c8846e10SFelix Fietkau { 114b1bfbe70SLorenzo Bianconi int err; 115c8846e10SFelix Fietkau 116b1bfbe70SLorenzo Bianconi err = mt76_queue_alloc(dev, q, idx, n_desc, bufsize, 117b1bfbe70SLorenzo Bianconi MT_RX_RING_BASE); 118b1bfbe70SLorenzo Bianconi if (err < 0) 119b1bfbe70SLorenzo Bianconi return err; 120c8846e10SFelix Fietkau 121c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_RX_DONE(idx)); 122c8846e10SFelix Fietkau 123c8846e10SFelix Fietkau return 0; 124c8846e10SFelix Fietkau } 125c8846e10SFelix Fietkau 1269e63f5e7SLorenzo Bianconi static int mt7603_poll_tx(struct napi_struct *napi, int budget) 1279e63f5e7SLorenzo Bianconi { 1289e63f5e7SLorenzo Bianconi struct mt7603_dev *dev; 129c8846e10SFelix Fietkau int i; 130c8846e10SFelix Fietkau 1319e63f5e7SLorenzo Bianconi dev = container_of(napi, struct mt7603_dev, mt76.tx_napi); 132c8846e10SFelix Fietkau dev->tx_dma_check = 0; 1339e63f5e7SLorenzo Bianconi 134e637763bSLorenzo Bianconi mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false); 135e637763bSLorenzo Bianconi for (i = MT_TXQ_PSD; i >= 0; i--) 13691990519SLorenzo Bianconi mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], false); 137c8846e10SFelix Fietkau 1389e63f5e7SLorenzo Bianconi if (napi_complete_done(napi, 0)) 139c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL); 1409e63f5e7SLorenzo Bianconi 141e637763bSLorenzo Bianconi mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false); 142e637763bSLorenzo Bianconi for (i = MT_TXQ_PSD; i >= 0; i--) 14391990519SLorenzo Bianconi mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], false); 1449e63f5e7SLorenzo Bianconi 145ea565833SFelix Fietkau mt7603_mac_sta_poll(dev); 146ea565833SFelix Fietkau 147781eef5bSFelix Fietkau mt76_worker_schedule(&dev->mt76.tx_worker); 1489e63f5e7SLorenzo Bianconi 1499e63f5e7SLorenzo Bianconi return 0; 150c8846e10SFelix Fietkau } 151c8846e10SFelix Fietkau 152c8846e10SFelix Fietkau int mt7603_dma_init(struct mt7603_dev *dev) 153c8846e10SFelix Fietkau { 154c8846e10SFelix Fietkau static const u8 wmm_queue_map[] = { 155c8846e10SFelix Fietkau [IEEE80211_AC_BK] = 0, 156c8846e10SFelix Fietkau [IEEE80211_AC_BE] = 1, 157c8846e10SFelix Fietkau [IEEE80211_AC_VI] = 2, 158c8846e10SFelix Fietkau [IEEE80211_AC_VO] = 3, 159c8846e10SFelix Fietkau }; 160c8846e10SFelix Fietkau int ret; 161c8846e10SFelix Fietkau int i; 162c8846e10SFelix Fietkau 163c8846e10SFelix Fietkau mt76_dma_attach(&dev->mt76); 164c8846e10SFelix Fietkau 165c8846e10SFelix Fietkau mt76_clear(dev, MT_WPDMA_GLO_CFG, 166c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_DMA_EN | 167c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_RX_DMA_EN | 168c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_DMA_BURST_SIZE | 169c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); 170c8846e10SFelix Fietkau 171c8846e10SFelix Fietkau mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); 172c8846e10SFelix Fietkau mt7603_pse_client_reset(dev); 173c8846e10SFelix Fietkau 174c8846e10SFelix Fietkau for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) { 175e637763bSLorenzo Bianconi ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i], 176e637763bSLorenzo Bianconi MT7603_TX_RING_SIZE, MT_TX_RING_BASE); 177c8846e10SFelix Fietkau if (ret) 178c8846e10SFelix Fietkau return ret; 179c8846e10SFelix Fietkau } 180c8846e10SFelix Fietkau 181e637763bSLorenzo Bianconi ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT, 182e637763bSLorenzo Bianconi MT7603_PSD_RING_SIZE, MT_TX_RING_BASE); 183c8846e10SFelix Fietkau if (ret) 184c8846e10SFelix Fietkau return ret; 185c8846e10SFelix Fietkau 186e637763bSLorenzo Bianconi ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT_TX_HW_QUEUE_MCU, 187e637763bSLorenzo Bianconi MT_MCU_RING_SIZE, MT_TX_RING_BASE); 188c8846e10SFelix Fietkau if (ret) 189c8846e10SFelix Fietkau return ret; 190c8846e10SFelix Fietkau 191e637763bSLorenzo Bianconi ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_BEACON, MT_TX_HW_QUEUE_BCN, 192e637763bSLorenzo Bianconi MT_MCU_RING_SIZE, MT_TX_RING_BASE); 193c8846e10SFelix Fietkau if (ret) 194c8846e10SFelix Fietkau return ret; 195c8846e10SFelix Fietkau 196e637763bSLorenzo Bianconi ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_CAB, MT_TX_HW_QUEUE_BMC, 197e637763bSLorenzo Bianconi MT_MCU_RING_SIZE, MT_TX_RING_BASE); 198c8846e10SFelix Fietkau if (ret) 199c8846e10SFelix Fietkau return ret; 200c8846e10SFelix Fietkau 201e637763bSLorenzo Bianconi mt7603_irq_enable(dev, 202e637763bSLorenzo Bianconi MT_INT_TX_DONE(IEEE80211_AC_VO) | 203e637763bSLorenzo Bianconi MT_INT_TX_DONE(IEEE80211_AC_VI) | 204e637763bSLorenzo Bianconi MT_INT_TX_DONE(IEEE80211_AC_BE) | 205e637763bSLorenzo Bianconi MT_INT_TX_DONE(IEEE80211_AC_BK) | 206e637763bSLorenzo Bianconi MT_INT_TX_DONE(MT_TX_HW_QUEUE_MGMT) | 207e637763bSLorenzo Bianconi MT_INT_TX_DONE(MT_TX_HW_QUEUE_MCU) | 208e637763bSLorenzo Bianconi MT_INT_TX_DONE(MT_TX_HW_QUEUE_BCN) | 209e637763bSLorenzo Bianconi MT_INT_TX_DONE(MT_TX_HW_QUEUE_BMC)); 210e637763bSLorenzo Bianconi 211c8846e10SFelix Fietkau ret = mt7603_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1, 212e970e665SFelix Fietkau MT7603_MCU_RX_RING_SIZE, MT_RX_BUF_SIZE); 213c8846e10SFelix Fietkau if (ret) 214c8846e10SFelix Fietkau return ret; 215c8846e10SFelix Fietkau 216c8846e10SFelix Fietkau ret = mt7603_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0, 217c8846e10SFelix Fietkau MT7603_RX_RING_SIZE, MT_RX_BUF_SIZE); 218c8846e10SFelix Fietkau if (ret) 219c8846e10SFelix Fietkau return ret; 220c8846e10SFelix Fietkau 221c8846e10SFelix Fietkau mt76_wr(dev, MT_DELAY_INT_CFG, 0); 222cb8ed33dSLorenzo Bianconi ret = mt76_init_queues(dev, mt76_dma_rx_poll); 2239e63f5e7SLorenzo Bianconi if (ret) 2249e63f5e7SLorenzo Bianconi return ret; 2259e63f5e7SLorenzo Bianconi 226aa40528aSFelix Fietkau netif_tx_napi_add(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, 2279e63f5e7SLorenzo Bianconi mt7603_poll_tx, NAPI_POLL_WEIGHT); 2289e63f5e7SLorenzo Bianconi napi_enable(&dev->mt76.tx_napi); 2299e63f5e7SLorenzo Bianconi 2309e63f5e7SLorenzo Bianconi return 0; 231c8846e10SFelix Fietkau } 232c8846e10SFelix Fietkau 233c8846e10SFelix Fietkau void mt7603_dma_cleanup(struct mt7603_dev *dev) 234c8846e10SFelix Fietkau { 235c8846e10SFelix Fietkau mt76_clear(dev, MT_WPDMA_GLO_CFG, 236c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_DMA_EN | 237c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_RX_DMA_EN | 238c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); 239c8846e10SFelix Fietkau 240c8846e10SFelix Fietkau mt76_dma_cleanup(&dev->mt76); 241c8846e10SFelix Fietkau } 242