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 int 8af005f26SLorenzo Bianconi mt7603_init_tx_queue(struct mt7603_dev *dev, struct mt76_sw_queue *q, 9c8846e10SFelix Fietkau int idx, int n_desc) 10c8846e10SFelix Fietkau { 11af005f26SLorenzo Bianconi struct mt76_queue *hwq; 12b1bfbe70SLorenzo Bianconi int err; 13c8846e10SFelix Fietkau 14af005f26SLorenzo Bianconi hwq = devm_kzalloc(dev->mt76.dev, sizeof(*hwq), GFP_KERNEL); 15af005f26SLorenzo Bianconi if (!hwq) 16af005f26SLorenzo Bianconi return -ENOMEM; 17af005f26SLorenzo Bianconi 18af005f26SLorenzo Bianconi err = mt76_queue_alloc(dev, hwq, idx, n_desc, 0, MT_TX_RING_BASE); 19b1bfbe70SLorenzo Bianconi if (err < 0) 20b1bfbe70SLorenzo Bianconi return err; 21c8846e10SFelix Fietkau 22af005f26SLorenzo Bianconi INIT_LIST_HEAD(&q->swq); 23af005f26SLorenzo Bianconi q->q = hwq; 24af005f26SLorenzo Bianconi 25c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_TX_DONE(idx)); 26c8846e10SFelix Fietkau 27c8846e10SFelix Fietkau return 0; 28c8846e10SFelix Fietkau } 29c8846e10SFelix Fietkau 30c8846e10SFelix Fietkau static void 31c8846e10SFelix Fietkau mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb) 32c8846e10SFelix Fietkau { 33c8846e10SFelix Fietkau __le32 *txd = (__le32 *)skb->data; 34e004b700SFelix Fietkau struct ieee80211_hdr *hdr; 35e004b700SFelix Fietkau struct ieee80211_sta *sta; 36c8846e10SFelix Fietkau struct mt7603_sta *msta; 37c8846e10SFelix Fietkau struct mt76_wcid *wcid; 38e004b700SFelix Fietkau void *priv; 39c8846e10SFelix Fietkau int idx; 40c8846e10SFelix Fietkau u32 val; 41e004b700SFelix Fietkau u8 tid; 42c8846e10SFelix Fietkau 43e004b700SFelix Fietkau if (skb->len < MT_TXD_SIZE + sizeof(struct ieee80211_hdr)) 44c8846e10SFelix Fietkau goto free; 45c8846e10SFelix Fietkau 46c8846e10SFelix Fietkau val = le32_to_cpu(txd[1]); 47c8846e10SFelix Fietkau idx = FIELD_GET(MT_TXD1_WLAN_IDX, val); 48c8846e10SFelix Fietkau skb->priority = FIELD_GET(MT_TXD1_TID, val); 49c8846e10SFelix Fietkau 50c8846e10SFelix Fietkau if (idx >= MT7603_WTBL_STA - 1) 51c8846e10SFelix Fietkau goto free; 52c8846e10SFelix Fietkau 53c8846e10SFelix Fietkau wcid = rcu_dereference(dev->mt76.wcid[idx]); 54c8846e10SFelix Fietkau if (!wcid) 55c8846e10SFelix Fietkau goto free; 56c8846e10SFelix Fietkau 57e004b700SFelix Fietkau priv = msta = container_of(wcid, struct mt7603_sta, wcid); 58c8846e10SFelix Fietkau val = le32_to_cpu(txd[0]); 59c8846e10SFelix Fietkau skb_set_queue_mapping(skb, FIELD_GET(MT_TXD0_Q_IDX, val)); 60c8846e10SFelix Fietkau 61fca9615fSFelix Fietkau val &= ~(MT_TXD0_P_IDX | MT_TXD0_Q_IDX); 62fca9615fSFelix Fietkau val |= FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_HW_QUEUE_MGMT); 63fca9615fSFelix Fietkau txd[0] = cpu_to_le32(val); 64fca9615fSFelix Fietkau 65e004b700SFelix Fietkau sta = container_of(priv, struct ieee80211_sta, drv_priv); 66e004b700SFelix Fietkau hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE]; 67e004b700SFelix Fietkau tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 68e004b700SFelix Fietkau ieee80211_sta_set_buffered(sta, tid, true); 69e004b700SFelix Fietkau 70c8846e10SFelix Fietkau spin_lock_bh(&dev->ps_lock); 71c8846e10SFelix Fietkau __skb_queue_tail(&msta->psq, skb); 72c8846e10SFelix Fietkau if (skb_queue_len(&msta->psq) >= 64) { 73c8846e10SFelix Fietkau skb = __skb_dequeue(&msta->psq); 74c8846e10SFelix Fietkau dev_kfree_skb(skb); 75c8846e10SFelix Fietkau } 76c8846e10SFelix Fietkau spin_unlock_bh(&dev->ps_lock); 77c8846e10SFelix Fietkau return; 78c8846e10SFelix Fietkau 79c8846e10SFelix Fietkau free: 80c8846e10SFelix Fietkau dev_kfree_skb(skb); 81c8846e10SFelix Fietkau } 82c8846e10SFelix Fietkau 83c8846e10SFelix Fietkau void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, 84c8846e10SFelix Fietkau struct sk_buff *skb) 85c8846e10SFelix Fietkau { 86c8846e10SFelix Fietkau struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); 87c8846e10SFelix Fietkau __le32 *rxd = (__le32 *)skb->data; 88c8846e10SFelix Fietkau __le32 *end = (__le32 *)&skb->data[skb->len]; 89c8846e10SFelix Fietkau enum rx_pkt_type type; 90c8846e10SFelix Fietkau 91c8846e10SFelix Fietkau type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0])); 92c8846e10SFelix Fietkau 93c8846e10SFelix Fietkau if (q == MT_RXQ_MCU) { 94c8846e10SFelix Fietkau if (type == PKT_TYPE_RX_EVENT) 95c8846e10SFelix Fietkau mt76_mcu_rx_event(&dev->mt76, skb); 96c8846e10SFelix Fietkau else 97c8846e10SFelix Fietkau mt7603_rx_loopback_skb(dev, skb); 98c8846e10SFelix Fietkau return; 99c8846e10SFelix Fietkau } 100c8846e10SFelix Fietkau 101c8846e10SFelix Fietkau switch (type) { 102c8846e10SFelix Fietkau case PKT_TYPE_TXS: 103c8846e10SFelix Fietkau for (rxd++; rxd + 5 <= end; rxd += 5) 104c8846e10SFelix Fietkau mt7603_mac_add_txs(dev, rxd); 105c8846e10SFelix Fietkau dev_kfree_skb(skb); 106c8846e10SFelix Fietkau break; 107c8846e10SFelix Fietkau case PKT_TYPE_RX_EVENT: 108c8846e10SFelix Fietkau mt76_mcu_rx_event(&dev->mt76, skb); 109c8846e10SFelix Fietkau return; 110c8846e10SFelix Fietkau case PKT_TYPE_NORMAL: 111c8846e10SFelix Fietkau if (mt7603_mac_fill_rx(dev, skb) == 0) { 112c8846e10SFelix Fietkau mt76_rx(&dev->mt76, q, skb); 113c8846e10SFelix Fietkau return; 114c8846e10SFelix Fietkau } 115c8846e10SFelix Fietkau /* fall through */ 116c8846e10SFelix Fietkau default: 117c8846e10SFelix Fietkau dev_kfree_skb(skb); 118c8846e10SFelix Fietkau break; 119c8846e10SFelix Fietkau } 120c8846e10SFelix Fietkau } 121c8846e10SFelix Fietkau 122c8846e10SFelix Fietkau static int 123c8846e10SFelix Fietkau mt7603_init_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q, 124c8846e10SFelix Fietkau int idx, int n_desc, int bufsize) 125c8846e10SFelix Fietkau { 126b1bfbe70SLorenzo Bianconi int err; 127c8846e10SFelix Fietkau 128b1bfbe70SLorenzo Bianconi err = mt76_queue_alloc(dev, q, idx, n_desc, bufsize, 129b1bfbe70SLorenzo Bianconi MT_RX_RING_BASE); 130b1bfbe70SLorenzo Bianconi if (err < 0) 131b1bfbe70SLorenzo Bianconi return err; 132c8846e10SFelix Fietkau 133c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_RX_DONE(idx)); 134c8846e10SFelix Fietkau 135c8846e10SFelix Fietkau return 0; 136c8846e10SFelix Fietkau } 137c8846e10SFelix Fietkau 138c8846e10SFelix Fietkau static void 139c8846e10SFelix Fietkau mt7603_tx_tasklet(unsigned long data) 140c8846e10SFelix Fietkau { 141c8846e10SFelix Fietkau struct mt7603_dev *dev = (struct mt7603_dev *)data; 1429e63f5e7SLorenzo Bianconi 1439e63f5e7SLorenzo Bianconi mt76_txq_schedule_all(&dev->mt76); 1449e63f5e7SLorenzo Bianconi } 1459e63f5e7SLorenzo Bianconi 1469e63f5e7SLorenzo Bianconi static int mt7603_poll_tx(struct napi_struct *napi, int budget) 1479e63f5e7SLorenzo Bianconi { 1489e63f5e7SLorenzo Bianconi struct mt7603_dev *dev; 149c8846e10SFelix Fietkau int i; 150c8846e10SFelix Fietkau 1519e63f5e7SLorenzo Bianconi dev = container_of(napi, struct mt7603_dev, mt76.tx_napi); 152c8846e10SFelix Fietkau dev->tx_dma_check = 0; 1539e63f5e7SLorenzo Bianconi 154c8846e10SFelix Fietkau for (i = MT_TXQ_MCU; i >= 0; i--) 155c8846e10SFelix Fietkau mt76_queue_tx_cleanup(dev, i, false); 156c8846e10SFelix Fietkau 1579e63f5e7SLorenzo Bianconi if (napi_complete_done(napi, 0)) 158c8846e10SFelix Fietkau mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL); 1599e63f5e7SLorenzo Bianconi 1609e63f5e7SLorenzo Bianconi for (i = MT_TXQ_MCU; i >= 0; i--) 1619e63f5e7SLorenzo Bianconi mt76_queue_tx_cleanup(dev, i, false); 1629e63f5e7SLorenzo Bianconi 1639e63f5e7SLorenzo Bianconi tasklet_schedule(&dev->mt76.tx_tasklet); 1649e63f5e7SLorenzo Bianconi 1659e63f5e7SLorenzo Bianconi return 0; 166c8846e10SFelix Fietkau } 167c8846e10SFelix Fietkau 168c8846e10SFelix Fietkau int mt7603_dma_init(struct mt7603_dev *dev) 169c8846e10SFelix Fietkau { 170c8846e10SFelix Fietkau static const u8 wmm_queue_map[] = { 171c8846e10SFelix Fietkau [IEEE80211_AC_BK] = 0, 172c8846e10SFelix Fietkau [IEEE80211_AC_BE] = 1, 173c8846e10SFelix Fietkau [IEEE80211_AC_VI] = 2, 174c8846e10SFelix Fietkau [IEEE80211_AC_VO] = 3, 175c8846e10SFelix Fietkau }; 176c8846e10SFelix Fietkau int ret; 177c8846e10SFelix Fietkau int i; 178c8846e10SFelix Fietkau 179c8846e10SFelix Fietkau mt76_dma_attach(&dev->mt76); 180c8846e10SFelix Fietkau 181c8846e10SFelix Fietkau init_waitqueue_head(&dev->mt76.mmio.mcu.wait); 182c8846e10SFelix Fietkau skb_queue_head_init(&dev->mt76.mmio.mcu.res_q); 183c8846e10SFelix Fietkau 1847f17b86aSRyder Lee tasklet_init(&dev->mt76.tx_tasklet, mt7603_tx_tasklet, 1857f17b86aSRyder Lee (unsigned long)dev); 186c8846e10SFelix Fietkau 187c8846e10SFelix Fietkau mt76_clear(dev, MT_WPDMA_GLO_CFG, 188c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_DMA_EN | 189c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_RX_DMA_EN | 190c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_DMA_BURST_SIZE | 191c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); 192c8846e10SFelix Fietkau 193c8846e10SFelix Fietkau mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); 194c8846e10SFelix Fietkau mt7603_pse_client_reset(dev); 195c8846e10SFelix Fietkau 196c8846e10SFelix Fietkau for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) { 197c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[i], 198c8846e10SFelix Fietkau wmm_queue_map[i], 199c8846e10SFelix Fietkau MT_TX_RING_SIZE); 200c8846e10SFelix Fietkau if (ret) 201c8846e10SFelix Fietkau return ret; 202c8846e10SFelix Fietkau } 203c8846e10SFelix Fietkau 204c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_PSD], 205c8846e10SFelix Fietkau MT_TX_HW_QUEUE_MGMT, MT_TX_RING_SIZE); 206c8846e10SFelix Fietkau if (ret) 207c8846e10SFelix Fietkau return ret; 208c8846e10SFelix Fietkau 209c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_MCU], 210c8846e10SFelix Fietkau MT_TX_HW_QUEUE_MCU, MT_MCU_RING_SIZE); 211c8846e10SFelix Fietkau if (ret) 212c8846e10SFelix Fietkau return ret; 213c8846e10SFelix Fietkau 214c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_BEACON], 215c8846e10SFelix Fietkau MT_TX_HW_QUEUE_BCN, MT_MCU_RING_SIZE); 216c8846e10SFelix Fietkau if (ret) 217c8846e10SFelix Fietkau return ret; 218c8846e10SFelix Fietkau 219c8846e10SFelix Fietkau ret = mt7603_init_tx_queue(dev, &dev->mt76.q_tx[MT_TXQ_CAB], 220c8846e10SFelix Fietkau MT_TX_HW_QUEUE_BMC, MT_MCU_RING_SIZE); 221c8846e10SFelix Fietkau if (ret) 222c8846e10SFelix Fietkau return ret; 223c8846e10SFelix Fietkau 224c8846e10SFelix Fietkau ret = mt7603_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1, 225c8846e10SFelix Fietkau MT_MCU_RING_SIZE, MT_RX_BUF_SIZE); 226c8846e10SFelix Fietkau if (ret) 227c8846e10SFelix Fietkau return ret; 228c8846e10SFelix Fietkau 229c8846e10SFelix Fietkau ret = mt7603_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0, 230c8846e10SFelix Fietkau MT7603_RX_RING_SIZE, MT_RX_BUF_SIZE); 231c8846e10SFelix Fietkau if (ret) 232c8846e10SFelix Fietkau return ret; 233c8846e10SFelix Fietkau 234c8846e10SFelix Fietkau mt76_wr(dev, MT_DELAY_INT_CFG, 0); 2359e63f5e7SLorenzo Bianconi ret = mt76_init_queues(dev); 2369e63f5e7SLorenzo Bianconi if (ret) 2379e63f5e7SLorenzo Bianconi return ret; 2389e63f5e7SLorenzo Bianconi 2399e63f5e7SLorenzo Bianconi netif_tx_napi_add(&dev->mt76.napi_dev, &dev->mt76.tx_napi, 2409e63f5e7SLorenzo Bianconi mt7603_poll_tx, NAPI_POLL_WEIGHT); 2419e63f5e7SLorenzo Bianconi napi_enable(&dev->mt76.tx_napi); 2429e63f5e7SLorenzo Bianconi 2439e63f5e7SLorenzo Bianconi return 0; 244c8846e10SFelix Fietkau } 245c8846e10SFelix Fietkau 246c8846e10SFelix Fietkau void mt7603_dma_cleanup(struct mt7603_dev *dev) 247c8846e10SFelix Fietkau { 248c8846e10SFelix Fietkau mt76_clear(dev, MT_WPDMA_GLO_CFG, 249c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_DMA_EN | 250c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_RX_DMA_EN | 251c8846e10SFelix Fietkau MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); 252c8846e10SFelix Fietkau 253a33b8ab8SFelix Fietkau tasklet_kill(&dev->mt76.tx_tasklet); 254c8846e10SFelix Fietkau mt76_dma_cleanup(&dev->mt76); 255c8846e10SFelix Fietkau } 256