diff --git a/mt7925/mac.c b/mt7925/mac.c index 80e51bc1..31b45dc6 100644 --- a/mt7925/mac.c +++ b/mt7925/mac.c @@ -1087,7 +1087,7 @@ mt7928_mac_add_txs_skb_msg(struct mt792x_dev *dev, struct mt76_wcid *wcid, info->status.rates[0].idx = -1; - txrate = pevt->tx_rate; + txrate = le16_to_cpu(pevt->tx_rate); rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate); rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1; @@ -1236,10 +1236,12 @@ void mt7925_mac_add_txs(struct mt792x_dev *dev, void *data) txs_fm = le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT); - if (is_mt7928(&dev->mt76) && txs_fm != TXS_FM_MPDU && txs_fm != TXS_FM_PPDU) - return; - else if (txs_fm > 1) + if (is_mt7928(&dev->mt76)) { + if (txs_fm != TXS_FM_MPDU && txs_fm != TXS_FM_PPDU) + return; + } else if (txs_fm > 1) { return; + } wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID); pid = le32_get_bits(txs_data[3], MT_TXS3_PID); diff --git a/mt792x_usb.c b/mt792x_usb.c index e5d2d2f6..850f6b2c 100644 --- a/mt792x_usb.c +++ b/mt792x_usb.c @@ -130,11 +130,16 @@ EXPORT_SYMBOL_GPL(mt792xu_check_bus); int mt792xu_reset_on_bus_error(struct mt792x_dev *dev) { - int err = 0; + int err; - if (!atomic_read(&dev->mt76.bus_hung)) - err = mt792xu_check_bus(dev); + /* Once hung, the no-op bus ops stay installed until the queued USB + * reset re-probes the device. Do not clear bus_hung here, or the caller + * would run a full reset over dropped register I/O and report success. + */ + if (atomic_read(&dev->mt76.bus_hung)) + return -EIO; + err = mt792xu_check_bus(dev); if (err) { mt792xu_set_bus_hung(dev); mt792xu_queue_usb_reset(dev, err); @@ -142,7 +147,6 @@ int mt792xu_reset_on_bus_error(struct mt792x_dev *dev) return err; } - atomic_set(&dev->mt76.bus_hung, false); return 0; } EXPORT_SYMBOL_GPL(mt792xu_reset_on_bus_error); diff --git a/usb.c b/usb.c index c0332c80..c3ce615a 100644 --- a/usb.c +++ b/usb.c @@ -755,8 +755,6 @@ void mt76u_stop_rx(struct mt76_dev *dev) int i; mt76_worker_disable(&dev->usb.rx_worker); - if (dev->napi_dev) - napi_disable(&dev->napi[MT_RXQ_MAIN]); mt76_for_each_q_rx(dev, i) { struct mt76_queue *q = &dev->q_rx[i]; @@ -765,6 +763,13 @@ void mt76u_stop_rx(struct mt76_dev *dev) for (j = 0; j < q->ndesc; j++) usb_poison_urb(q->entry[j].urb); } + + /* The MAIN queue napi stays enabled for the device lifetime. The URBs + * are now poisoned, so mt76u_complete_rx() can no longer reschedule it; + * just drain any in-flight poll before the caller frees or resets. + */ + if (dev->napi_dev) + napi_synchronize(&dev->napi[MT_RXQ_MAIN]); } EXPORT_SYMBOL_GPL(mt76u_stop_rx); @@ -785,8 +790,6 @@ int mt76u_resume_rx(struct mt76_dev *dev) } mt76_worker_enable(&dev->usb.rx_worker); - if (dev->napi_dev) - napi_enable(&dev->napi[MT_RXQ_MAIN]); return 0; } @@ -1086,8 +1089,8 @@ void mt76u_queues_deinit(struct mt76_dev *dev) mt76u_stop_rx(dev); mt76u_stop_tx(dev); - /* mt76u_stop_rx() (above) already napi_disable()d the MAIN queue */ if (dev->napi_dev) { + napi_disable(&dev->napi[MT_RXQ_MAIN]); netif_napi_del(&dev->napi[MT_RXQ_MAIN]); free_netdev(dev->napi_dev); dev->napi_dev = NULL;