Merge tag 'mt76-for-kvalo-2022-12-09' of https://github.com/nbd168/wireless
authorKalle Valo <kvalo@kernel.org>
Wed, 21 Dec 2022 18:21:36 +0000 (20:21 +0200)
committerKalle Valo <kvalo@kernel.org>
Wed, 21 Dec 2022 18:21:36 +0000 (20:21 +0200)
mt76 patches for 6.2

- fixes
- per-PHY LED support

34 files changed:
drivers/net/wireless/mediatek/mt76/debugfs.c
drivers/net/wireless/mediatek/mt76/dma.c
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7603/init.c
drivers/net/wireless/mediatek/mt76/mt7615/init.c
drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
drivers/net/wireless/mediatek/mt76/mt7615/regs.h
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
drivers/net/wireless/mediatek/mt76/mt7915/init.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
drivers/net/wireless/mediatek/mt76/mt7915/regs.h
drivers/net/wireless/mediatek/mt76/mt7915/soc.c
drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h
drivers/net/wireless/mediatek/mt76/mt7921/init.c
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c
drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
drivers/net/wireless/mediatek/mt76/mt7996/init.c
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
drivers/net/wireless/mediatek/mt76/mt7996/regs.h
drivers/net/wireless/mediatek/mt76/sdio_txrx.c
drivers/net/wireless/mediatek/mt76/tx.c
include/linux/soc/mediatek/mtk_wed.h

index 11b0b3d..57fbcc8 100644 (file)
@@ -112,7 +112,7 @@ mt76_register_debugfs_fops(struct mt76_phy *phy,
        if (!dir)
                return NULL;
 
-       debugfs_create_u8("led_pin", 0600, dir, &dev->led_pin);
+       debugfs_create_u8("led_pin", 0600, dir, &phy->leds.pin);
        debugfs_create_u32("regidx", 0600, dir, &dev->debugfs_reg);
        debugfs_create_file_unsafe("regval", 0600, dir, dev, fops);
        debugfs_create_file_unsafe("napi_threaded", 0600, dir, dev,
index f795548..5d58218 100644 (file)
@@ -212,14 +212,14 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
 {
        struct mt76_queue_entry *entry;
        struct mt76_desc *desc;
-       u32 ctrl;
        int i, idx = -1;
+       u32 ctrl, next;
 
        for (i = 0; i < nbufs; i += 2, buf += 2) {
                u32 buf0 = buf[0].addr, buf1 = 0;
 
                idx = q->head;
-               q->head = (q->head + 1) % q->ndesc;
+               next = (q->head + 1) % q->ndesc;
 
                desc = &q->desc[idx];
                entry = &q->entry[idx];
@@ -234,13 +234,16 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
 
                        rx_token = mt76_rx_token_consume(dev, (void *)skb, t,
                                                         buf[0].addr);
+                       if (rx_token < 0)
+                               return -ENOMEM;
+
                        buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
                        ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) |
                               MT_DMA_CTL_TO_HOST;
                } else {
                        if (txwi) {
-                               q->entry[q->head].txwi = DMA_DUMMY_DATA;
-                               q->entry[q->head].skip_buf0 = true;
+                               q->entry[next].txwi = DMA_DUMMY_DATA;
+                               q->entry[next].skip_buf0 = true;
                        }
 
                        if (buf[0].skip_unmap)
@@ -271,6 +274,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
                WRITE_ONCE(desc->info, cpu_to_le32(info));
                WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
 
+               q->head = next;
                q->queued++;
        }
 
@@ -550,23 +554,9 @@ free_skb:
        return ret;
 }
 
-static struct page_frag_cache *
-mt76_dma_rx_get_frag_cache(struct mt76_dev *dev, struct mt76_queue *q)
-{
-       struct page_frag_cache *rx_page = &q->rx_page;
-
-#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-       if ((q->flags & MT_QFLAG_WED) &&
-           FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX)
-               rx_page = &dev->mmio.wed.rx_buf_ring.rx_page;
-#endif
-       return rx_page;
-}
-
 static int
 mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
 {
-       struct page_frag_cache *rx_page = mt76_dma_rx_get_frag_cache(dev, q);
        int len = SKB_WITH_OVERHEAD(q->buf_size);
        int frames = 0, offset = q->buf_offset;
        dma_addr_t addr;
@@ -588,7 +578,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
                                break;
                }
 
-               buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC);
+               buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
                if (!buf)
                        break;
 
@@ -601,7 +591,12 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
                qbuf.addr = addr + offset;
                qbuf.len = len - offset;
                qbuf.skip_unmap = false;
-               mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t);
+               if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t) < 0) {
+                       dma_unmap_single(dev->dma_dev, addr, len,
+                                        DMA_FROM_DEVICE);
+                       skb_free_frag(buf);
+                       break;
+               }
                frames++;
        }
 
index fc608b3..7fe7f68 100644 (file)
@@ -192,42 +192,48 @@ static const struct cfg80211_sar_capa mt76_sar_capa = {
        .freq_ranges = &mt76_sar_freq_ranges[0],
 };
 
-static int mt76_led_init(struct mt76_dev *dev)
+static int mt76_led_init(struct mt76_phy *phy)
 {
-       struct device_node *np = dev->dev->of_node;
-       struct ieee80211_hw *hw = dev->hw;
-       int led_pin;
+       struct mt76_dev *dev = phy->dev;
+       struct ieee80211_hw *hw = phy->hw;
 
-       if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set)
+       if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set)
                return 0;
 
-       snprintf(dev->led_name, sizeof(dev->led_name),
-                "mt76-%s", wiphy_name(hw->wiphy));
+       snprintf(phy->leds.name, sizeof(phy->leds.name), "mt76-%s",
+                wiphy_name(hw->wiphy));
 
-       dev->led_cdev.name = dev->led_name;
-       dev->led_cdev.default_trigger =
+       phy->leds.cdev.name = phy->leds.name;
+       phy->leds.cdev.default_trigger =
                ieee80211_create_tpt_led_trigger(hw,
                                        IEEE80211_TPT_LEDTRIG_FL_RADIO,
                                        mt76_tpt_blink,
                                        ARRAY_SIZE(mt76_tpt_blink));
 
-       np = of_get_child_by_name(np, "led");
-       if (np) {
-               if (!of_property_read_u32(np, "led-sources", &led_pin))
-                       dev->led_pin = led_pin;
-               dev->led_al = of_property_read_bool(np, "led-active-low");
-               of_node_put(np);
+       if (phy == &dev->phy) {
+               struct device_node *np = dev->dev->of_node;
+
+               np = of_get_child_by_name(np, "led");
+               if (np) {
+                       int led_pin;
+
+                       if (!of_property_read_u32(np, "led-sources", &led_pin))
+                               phy->leds.pin = led_pin;
+                       phy->leds.al = of_property_read_bool(np,
+                                                            "led-active-low");
+                       of_node_put(np);
+               }
        }
 
-       return led_classdev_register(dev->dev, &dev->led_cdev);
+       return led_classdev_register(dev->dev, &phy->leds.cdev);
 }
 
-static void mt76_led_cleanup(struct mt76_dev *dev)
+static void mt76_led_cleanup(struct mt76_phy *phy)
 {
-       if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set)
+       if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set)
                return;
 
-       led_classdev_unregister(&dev->led_cdev);
+       led_classdev_unregister(&phy->leds.cdev);
 }
 
 static void mt76_init_stream_cap(struct mt76_phy *phy,
@@ -517,6 +523,12 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht,
                        return ret;
        }
 
+       if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+               ret = mt76_led_init(phy);
+               if (ret)
+                       return ret;
+       }
+
        wiphy_read_of_freq_limits(phy->hw->wiphy);
        mt76_check_sband(phy, &phy->sband_2g, NL80211_BAND_2GHZ);
        mt76_check_sband(phy, &phy->sband_5g, NL80211_BAND_5GHZ);
@@ -536,6 +548,8 @@ void mt76_unregister_phy(struct mt76_phy *phy)
 {
        struct mt76_dev *dev = phy->dev;
 
+       if (IS_ENABLED(CONFIG_MT76_LEDS))
+               mt76_led_cleanup(phy);
        mt76_tx_status_check(dev, true);
        ieee80211_unregister_hw(phy->hw);
        dev->phys[phy->band_idx] = NULL;
@@ -653,7 +667,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
        mt76_check_sband(&dev->phy, &phy->sband_6g, NL80211_BAND_6GHZ);
 
        if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-               ret = mt76_led_init(dev);
+               ret = mt76_led_init(phy);
                if (ret)
                        return ret;
        }
@@ -674,7 +688,7 @@ void mt76_unregister_device(struct mt76_dev *dev)
        struct ieee80211_hw *hw = dev->hw;
 
        if (IS_ENABLED(CONFIG_MT76_LEDS))
-               mt76_led_cleanup(dev);
+               mt76_led_cleanup(&dev->phy);
        mt76_tx_status_check(dev, true);
        ieee80211_unregister_hw(hw);
 }
index 32a77a0..1037d23 100644 (file)
@@ -731,6 +731,13 @@ struct mt76_phy {
        } rx_amsdu[__MT_RXQ_MAX];
 
        struct mt76_freq_range_power *frp;
+
+       struct {
+               struct led_classdev cdev;
+               char name[32];
+               bool al;
+               u8 pin;
+       } leds;
 };
 
 struct mt76_dev {
@@ -812,11 +819,6 @@ struct mt76_dev {
 
        u32 debugfs_reg;
 
-       struct led_classdev led_cdev;
-       char led_name[32];
-       bool led_al;
-       u8 led_pin;
-
        u8 csa_complete;
 
        u32 rxfilter;
index 031d39a..9a2e632 100644 (file)
@@ -330,10 +330,10 @@ static const struct ieee80211_iface_combination if_comb[] = {
        }
 };
 
-static void mt7603_led_set_config(struct mt76_dev *mt76, u8 delay_on,
+static void mt7603_led_set_config(struct mt76_phy *mphy, u8 delay_on,
                                  u8 delay_off)
 {
-       struct mt7603_dev *dev = container_of(mt76, struct mt7603_dev,
+       struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev,
                                              mt76);
        u32 val, addr;
 
@@ -341,15 +341,15 @@ static void mt7603_led_set_config(struct mt76_dev *mt76, u8 delay_on,
              FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
              FIELD_PREP(MT_LED_STATUS_ON, delay_on);
 
-       addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mt76->led_pin));
+       addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mphy->leds.pin));
        mt76_wr(dev, addr, val);
-       addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mt76->led_pin));
+       addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mphy->leds.pin));
        mt76_wr(dev, addr, val);
 
-       val = MT_LED_CTRL_REPLAY(mt76->led_pin) |
-             MT_LED_CTRL_KICK(mt76->led_pin);
-       if (mt76->led_al)
-               val |= MT_LED_CTRL_POLARITY(mt76->led_pin);
+       val = MT_LED_CTRL_REPLAY(mphy->leds.pin) |
+             MT_LED_CTRL_KICK(mphy->leds.pin);
+       if (mphy->leds.al)
+               val |= MT_LED_CTRL_POLARITY(mphy->leds.pin);
        addr = mt7603_reg_map(dev, MT_LED_CTRL);
        mt76_wr(dev, addr, val);
 }
@@ -358,27 +358,27 @@ static int mt7603_led_set_blink(struct led_classdev *led_cdev,
                                unsigned long *delay_on,
                                unsigned long *delay_off)
 {
-       struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
-                                            led_cdev);
+       struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
+                                            leds.cdev);
        u8 delta_on, delta_off;
 
        delta_off = max_t(u8, *delay_off / 10, 1);
        delta_on = max_t(u8, *delay_on / 10, 1);
 
-       mt7603_led_set_config(mt76, delta_on, delta_off);
+       mt7603_led_set_config(mphy, delta_on, delta_off);
        return 0;
 }
 
 static void mt7603_led_set_brightness(struct led_classdev *led_cdev,
                                      enum led_brightness brightness)
 {
-       struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
-                                            led_cdev);
+       struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
+                                            leds.cdev);
 
        if (!brightness)
-               mt7603_led_set_config(mt76, 0, 0xff);
+               mt7603_led_set_config(mphy, 0, 0xff);
        else
-               mt7603_led_set_config(mt76, 0xff, 0);
+               mt7603_led_set_config(mphy, 0xff, 0);
 }
 
 static u32 __mt7603_reg_addr(struct mt7603_dev *dev, u32 addr)
@@ -535,8 +535,8 @@ int mt7603_register_device(struct mt7603_dev *dev)
 
        /* init led callbacks */
        if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-               dev->mt76.led_cdev.brightness_set = mt7603_led_set_brightness;
-               dev->mt76.led_cdev.blink_set = mt7603_led_set_blink;
+               dev->mphy.leds.cdev.brightness_set = mt7603_led_set_brightness;
+               dev->mphy.leds.cdev.blink_set = mt7603_led_set_blink;
        }
 
        wiphy->reg_notifier = mt7603_regd_notifier;
index 07a1fea..5fa6f09 100644 (file)
@@ -443,6 +443,85 @@ mt7615_cap_dbdc_disable(struct mt7615_dev *dev)
        mt76_set_stream_caps(&dev->mphy, true);
 }
 
+u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr)
+{
+       u32 base, offset;
+
+       if (is_mt7663(&dev->mt76)) {
+               base = addr & MT7663_MCU_PCIE_REMAP_2_BASE;
+               offset = addr & MT7663_MCU_PCIE_REMAP_2_OFFSET;
+       } else {
+               base = addr & MT_MCU_PCIE_REMAP_2_BASE;
+               offset = addr & MT_MCU_PCIE_REMAP_2_OFFSET;
+       }
+       mt76_wr(dev, MT_MCU_PCIE_REMAP_2, base);
+
+       return MT_PCIE_REMAP_BASE_2 + offset;
+}
+EXPORT_SYMBOL_GPL(mt7615_reg_map);
+
+static void
+mt7615_led_set_config(struct led_classdev *led_cdev,
+                     u8 delay_on, u8 delay_off)
+{
+       struct mt7615_dev *dev;
+       struct mt76_phy *mphy;
+       u32 val, addr;
+       u8 index;
+
+       mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);
+       dev = container_of(mphy->dev, struct mt7615_dev, mt76);
+
+       if (!mt76_connac_pm_ref(mphy, &dev->pm))
+               return;
+
+       val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
+             FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
+             FIELD_PREP(MT_LED_STATUS_ON, delay_on);
+
+       index = dev->dbdc_support ? mphy->band_idx : mphy->leds.pin;
+       addr = mt7615_reg_map(dev, MT_LED_STATUS_0(index));
+       mt76_wr(dev, addr, val);
+       addr = mt7615_reg_map(dev, MT_LED_STATUS_1(index));
+       mt76_wr(dev, addr, val);
+
+       val = MT_LED_CTRL_REPLAY(index) | MT_LED_CTRL_KICK(index);
+       if (dev->mphy.leds.al)
+               val |= MT_LED_CTRL_POLARITY(index);
+       if (mphy->band_idx)
+               val |= MT_LED_CTRL_BAND(index);
+
+       addr = mt7615_reg_map(dev, MT_LED_CTRL);
+       mt76_wr(dev, addr, val);
+
+       mt76_connac_pm_unref(mphy, &dev->pm);
+}
+
+int mt7615_led_set_blink(struct led_classdev *led_cdev,
+                        unsigned long *delay_on,
+                        unsigned long *delay_off)
+{
+       u8 delta_on, delta_off;
+
+       delta_off = max_t(u8, *delay_off / 10, 1);
+       delta_on = max_t(u8, *delay_on / 10, 1);
+
+       mt7615_led_set_config(led_cdev, delta_on, delta_off);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mt7615_led_set_blink);
+
+void mt7615_led_set_brightness(struct led_classdev *led_cdev,
+                              enum led_brightness brightness)
+{
+       if (!brightness)
+               mt7615_led_set_config(led_cdev, 0, 0xff);
+       else
+               mt7615_led_set_config(led_cdev, 0xff, 0);
+}
+EXPORT_SYMBOL_GPL(mt7615_led_set_brightness);
+
 int mt7615_register_ext_phy(struct mt7615_dev *dev)
 {
        struct mt7615_phy *phy = mt7615_ext_phy(dev);
@@ -497,6 +576,12 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
        for (i = 0; i <= MT_TXQ_PSD ; i++)
                mphy->q_tx[i] = dev->mphy.q_tx[i];
 
+       /* init led callbacks */
+       if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+               mphy->leds.cdev.brightness_set = mt7615_led_set_brightness;
+               mphy->leds.cdev.blink_set = mt7615_led_set_blink;
+       }
+
        ret = mt76_register_phy(mphy, true, mt76_rates,
                                ARRAY_SIZE(mt76_rates));
        if (ret)
index a784f9d..83173ef 100644 (file)
@@ -63,22 +63,6 @@ const u32 mt7663e_reg_map[] = {
        [MT_EFUSE_ADDR_BASE]    = 0x78011000,
 };
 
-u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr)
-{
-       u32 base, offset;
-
-       if (is_mt7663(&dev->mt76)) {
-               base = addr & MT7663_MCU_PCIE_REMAP_2_BASE;
-               offset = addr & MT7663_MCU_PCIE_REMAP_2_OFFSET;
-       } else {
-               base = addr & MT_MCU_PCIE_REMAP_2_BASE;
-               offset = addr & MT_MCU_PCIE_REMAP_2_OFFSET;
-       }
-       mt76_wr(dev, MT_MCU_PCIE_REMAP_2, base);
-
-       return MT_PCIE_REMAP_BASE_2 + offset;
-}
-
 static void
 mt7615_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
 {
index 087d488..43591b4 100644 (file)
@@ -376,6 +376,12 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
                      int irq, const u32 *map);
 u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);
 
+u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);
+int mt7615_led_set_blink(struct led_classdev *led_cdev,
+                        unsigned long *delay_on,
+                        unsigned long *delay_off);
+void mt7615_led_set_brightness(struct led_classdev *led_cdev,
+                              enum led_brightness brightness);
 void mt7615_init_device(struct mt7615_dev *dev);
 int mt7615_register_device(struct mt7615_dev *dev);
 void mt7615_unregister_device(struct mt7615_dev *dev);
index 87b4aa5..0680e00 100644 (file)
@@ -66,64 +66,6 @@ static int mt7615_init_hardware(struct mt7615_dev *dev)
        return 0;
 }
 
-static void
-mt7615_led_set_config(struct led_classdev *led_cdev,
-                     u8 delay_on, u8 delay_off)
-{
-       struct mt7615_dev *dev;
-       struct mt76_dev *mt76;
-       u32 val, addr;
-
-       mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
-       dev = container_of(mt76, struct mt7615_dev, mt76);
-
-       if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm))
-               return;
-
-       val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
-             FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
-             FIELD_PREP(MT_LED_STATUS_ON, delay_on);
-
-       addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mt76->led_pin));
-       mt76_wr(dev, addr, val);
-       addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mt76->led_pin));
-       mt76_wr(dev, addr, val);
-
-       val = MT_LED_CTRL_REPLAY(mt76->led_pin) |
-             MT_LED_CTRL_KICK(mt76->led_pin);
-       if (mt76->led_al)
-               val |= MT_LED_CTRL_POLARITY(mt76->led_pin);
-       addr = mt7615_reg_map(dev, MT_LED_CTRL);
-       mt76_wr(dev, addr, val);
-
-       mt76_connac_pm_unref(&dev->mphy, &dev->pm);
-}
-
-static int
-mt7615_led_set_blink(struct led_classdev *led_cdev,
-                    unsigned long *delay_on,
-                    unsigned long *delay_off)
-{
-       u8 delta_on, delta_off;
-
-       delta_off = max_t(u8, *delay_off / 10, 1);
-       delta_on = max_t(u8, *delay_on / 10, 1);
-
-       mt7615_led_set_config(led_cdev, delta_on, delta_off);
-
-       return 0;
-}
-
-static void
-mt7615_led_set_brightness(struct led_classdev *led_cdev,
-                         enum led_brightness brightness)
-{
-       if (!brightness)
-               mt7615_led_set_config(led_cdev, 0, 0xff);
-       else
-               mt7615_led_set_config(led_cdev, 0xff, 0);
-}
-
 int mt7615_register_device(struct mt7615_dev *dev)
 {
        int ret;
@@ -133,8 +75,8 @@ int mt7615_register_device(struct mt7615_dev *dev)
 
        /* init led callbacks */
        if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-               dev->mt76.led_cdev.brightness_set = mt7615_led_set_brightness;
-               dev->mt76.led_cdev.blink_set = mt7615_led_set_blink;
+               dev->mphy.leds.cdev.brightness_set = mt7615_led_set_brightness;
+               dev->mphy.leds.cdev.blink_set = mt7615_led_set_blink;
        }
 
        ret = mt7622_wmac_init(dev);
index fa1b9b2..7cecb22 100644 (file)
@@ -544,6 +544,7 @@ enum mt7615_reg_base {
 #define MT_LED_CTRL_POLARITY(_n)       BIT(1 + (8 * (_n)))
 #define MT_LED_CTRL_TX_BLINK_MODE(_n)  BIT(2 + (8 * (_n)))
 #define MT_LED_CTRL_TX_MANUAL_BLINK(_n)        BIT(3 + (8 * (_n)))
+#define MT_LED_CTRL_BAND(_n)           BIT(4 + (8 * (_n)))
 #define MT_LED_CTRL_TX_OVER_BLINK(_n)  BIT(5 + (8 * (_n)))
 #define MT_LED_CTRL_KICK(_n)           BIT(7 + (8 * (_n)))
 
index fd60123..c8d0c84 100644 (file)
@@ -930,7 +930,7 @@ int mt76_connac2_reverse_frag0_hdr_trans(struct ieee80211_vif *vif,
                ether_addr_copy(hdr.addr4, eth_hdr->h_source);
                break;
        default:
-               break;
+               return -EINVAL;
        }
 
        skb_pull(skb, hdr_offset + sizeof(struct ethhdr) - 2);
index 6c6c8ad..d543ef3 100644 (file)
@@ -642,7 +642,12 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
                if (tx_rate > 9)
                        return -EINVAL;
 
-               *target_power = cur_power + dev->rate_power.vht[tx_rate];
+               *target_power = cur_power;
+               if (tx_rate > 7)
+                       *target_power += dev->rate_power.vht[tx_rate - 8];
+               else
+                       *target_power += dev->rate_power.ht[tx_rate];
+
                *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
                break;
        default:
index 604ddcc..7451a63 100644 (file)
@@ -87,10 +87,9 @@ static const struct ieee80211_iface_combination mt76x02u_if_comb[] = {
 };
 
 static void
-mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on,
-                      u8 delay_off)
+mt76x02_led_set_config(struct mt76_phy *mphy, u8 delay_on, u8 delay_off)
 {
-       struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev,
+       struct mt76x02_dev *dev = container_of(mphy->dev, struct mt76x02_dev,
                                               mt76);
        u32 val;
 
@@ -98,13 +97,13 @@ mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on,
              FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
              FIELD_PREP(MT_LED_STATUS_ON, delay_on);
 
-       mt76_wr(dev, MT_LED_S0(mdev->led_pin), val);
-       mt76_wr(dev, MT_LED_S1(mdev->led_pin), val);
+       mt76_wr(dev, MT_LED_S0(mphy->leds.pin), val);
+       mt76_wr(dev, MT_LED_S1(mphy->leds.pin), val);
 
-       val = MT_LED_CTRL_REPLAY(mdev->led_pin) |
-             MT_LED_CTRL_KICK(mdev->led_pin);
-       if (mdev->led_al)
-               val |= MT_LED_CTRL_POLARITY(mdev->led_pin);
+       val = MT_LED_CTRL_REPLAY(mphy->leds.pin) |
+             MT_LED_CTRL_KICK(mphy->leds.pin);
+       if (mphy->leds.al)
+               val |= MT_LED_CTRL_POLARITY(mphy->leds.pin);
        mt76_wr(dev, MT_LED_CTRL, val);
 }
 
@@ -113,14 +112,14 @@ mt76x02_led_set_blink(struct led_classdev *led_cdev,
                      unsigned long *delay_on,
                      unsigned long *delay_off)
 {
-       struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev,
-                                            led_cdev);
+       struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
+                                            leds.cdev);
        u8 delta_on, delta_off;
 
        delta_off = max_t(u8, *delay_off / 10, 1);
        delta_on = max_t(u8, *delay_on / 10, 1);
 
-       mt76x02_led_set_config(mdev, delta_on, delta_off);
+       mt76x02_led_set_config(mphy, delta_on, delta_off);
 
        return 0;
 }
@@ -129,13 +128,13 @@ static void
 mt76x02_led_set_brightness(struct led_classdev *led_cdev,
                           enum led_brightness brightness)
 {
-       struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev,
-                                            led_cdev);
+       struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
+                                            leds.cdev);
 
        if (!brightness)
-               mt76x02_led_set_config(mdev, 0, 0xff);
+               mt76x02_led_set_config(mphy, 0, 0xff);
        else
-               mt76x02_led_set_config(mdev, 0xff, 0);
+               mt76x02_led_set_config(mphy, 0xff, 0);
 }
 
 int mt76x02_init_device(struct mt76x02_dev *dev)
@@ -167,9 +166,9 @@ int mt76x02_init_device(struct mt76x02_dev *dev)
 
                /* init led callbacks */
                if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-                       dev->mt76.led_cdev.brightness_set =
+                       dev->mphy.leds.cdev.brightness_set =
                                        mt76x02_led_set_brightness;
-                       dev->mt76.led_cdev.blink_set = mt76x02_led_set_blink;
+                       dev->mphy.leds.cdev.blink_set = mt76x02_led_set_blink;
                }
        }
 
index fb46c2c..5a46813 100644 (file)
@@ -811,7 +811,7 @@ mt7915_hw_queue_read(struct seq_file *s, u32 size,
                if (val & BIT(map[i].index))
                        continue;
 
-               ctrl = BIT(31) | (map[i].pid << 10) | (map[i].qid << 24);
+               ctrl = BIT(31) | (map[i].pid << 10) | ((u32)map[i].qid << 24);
                mt76_wr(dev, MT_FL_Q0_CTRL, ctrl);
 
                head = mt76_get_field(dev, MT_FL_Q2_CTRL,
@@ -996,7 +996,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
 
        ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr));
        if (ret)
-               return ret;
+               goto out;
 
        /* Txpower propagation path: TMAC -> TXV -> BBP */
        len += scnprintf(buf + len, sz - len,
@@ -1047,6 +1047,8 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
                         mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER));
 
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+
+out:
        kfree(buf);
        return ret;
 }
index 59069fb..24efa28 100644 (file)
@@ -110,18 +110,23 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
        } else {
                u8 free_block_num;
                u32 block_num, i;
+               u32 eeprom_blk_size = MT7915_EEPROM_BLOCK_SIZE;
 
-               mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);
-               /* efuse info not enough */
+               ret = mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);
+               if (ret < 0)
+                       return ret;
+
+               /* efuse info isn't enough */
                if (free_block_num >= 29)
                        return -EINVAL;
 
                /* read eeprom data from efuse */
-               block_num = DIV_ROUND_UP(eeprom_size,
-                                        MT7915_EEPROM_BLOCK_SIZE);
-               for (i = 0; i < block_num; i++)
-                       mt7915_mcu_get_eeprom(dev,
-                                             i * MT7915_EEPROM_BLOCK_SIZE);
+               block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);
+               for (i = 0; i < block_num; i++) {
+                       ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size);
+                       if (ret < 0)
+                               return ret;
+               }
        }
 
        return mt7915_check_eeprom(dev);
index c810c31..571c948 100644 (file)
@@ -209,30 +209,31 @@ static void mt7915_led_set_config(struct led_classdev *led_cdev,
                                  u8 delay_on, u8 delay_off)
 {
        struct mt7915_dev *dev;
-       struct mt76_dev *mt76;
+       struct mt76_phy *mphy;
        u32 val;
 
-       mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
-       dev = container_of(mt76, struct mt7915_dev, mt76);
+       mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);
+       dev = container_of(mphy->dev, struct mt7915_dev, mt76);
 
-       /* select TX blink mode, 2: only data frames */
-       mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2);
+       /* set PWM mode */
+       val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
+             FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
+             FIELD_PREP(MT_LED_STATUS_ON, delay_on);
+       mt76_wr(dev, MT_LED_STATUS_0(mphy->band_idx), val);
+       mt76_wr(dev, MT_LED_STATUS_1(mphy->band_idx), val);
 
        /* enable LED */
-       mt76_wr(dev, MT_LED_EN(0), 1);
-
-       /* set LED Tx blink on/off time */
-       val = FIELD_PREP(MT_LED_TX_BLINK_ON_MASK, delay_on) |
-             FIELD_PREP(MT_LED_TX_BLINK_OFF_MASK, delay_off);
-       mt76_wr(dev, MT_LED_TX_BLINK(0), val);
+       mt76_wr(dev, MT_LED_EN(mphy->band_idx), 1);
 
        /* control LED */
-       val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
-       if (dev->mt76.led_al)
+       val = MT_LED_CTRL_KICK;
+       if (dev->mphy.leds.al)
                val |= MT_LED_CTRL_POLARITY;
+       if (mphy->band_idx)
+               val |= MT_LED_CTRL_BAND;
 
-       mt76_wr(dev, MT_LED_CTRL(0), val);
-       mt76_clear(dev, MT_LED_CTRL(0), MT_LED_CTRL_KICK);
+       mt76_wr(dev, MT_LED_CTRL(mphy->band_idx), val);
+       mt76_clear(dev, MT_LED_CTRL(mphy->band_idx), MT_LED_CTRL_KICK);
 }
 
 static int mt7915_led_set_blink(struct led_classdev *led_cdev,
@@ -319,9 +320,10 @@ mt7915_regd_notifier(struct wiphy *wiphy,
 }
 
 static void
-mt7915_init_wiphy(struct ieee80211_hw *hw)
+mt7915_init_wiphy(struct mt7915_phy *phy)
 {
-       struct mt7915_phy *phy = mt7915_hw_phy(hw);
+       struct mt76_phy *mphy = phy->mt76;
+       struct ieee80211_hw *hw = mphy->hw;
        struct mt76_dev *mdev = &phy->dev->mt76;
        struct wiphy *wiphy = hw->wiphy;
        struct mt7915_dev *dev = phy->dev;
@@ -415,6 +417,12 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
 
        wiphy->available_antennas_rx = phy->mt76->antenna_mask;
        wiphy->available_antennas_tx = phy->mt76->antenna_mask;
+
+       /* init led callbacks */
+       if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+               mphy->leds.cdev.brightness_set = mt7915_led_set_brightness;
+               mphy->leds.cdev.blink_set = mt7915_led_set_blink;
+       }
 }
 
 static void
@@ -473,6 +481,72 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
        mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
 }
 
+static void
+mt7915_init_led_mux(struct mt7915_dev *dev)
+{
+       if (!IS_ENABLED(CONFIG_MT76_LEDS))
+               return;
+
+       if (dev->dbdc_support) {
+               switch (mt76_chip(&dev->mt76)) {
+               case 0x7915:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX2,
+                                      GENMASK(11, 8), 4);
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX3,
+                                      GENMASK(11, 8), 4);
+                       break;
+               case 0x7986:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
+                                      GENMASK(7, 4), 1);
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
+                                      GENMASK(11, 8), 1);
+                       break;
+               case 0x7916:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
+                                      GENMASK(27, 24), 3);
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
+                                      GENMASK(31, 28), 3);
+                       break;
+               default:
+                       break;
+               }
+       } else if (dev->mphy.leds.pin) {
+               switch (mt76_chip(&dev->mt76)) {
+               case 0x7915:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX3,
+                                      GENMASK(11, 8), 4);
+                       break;
+               case 0x7986:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
+                                      GENMASK(11, 8), 1);
+                       break;
+               case 0x7916:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
+                                      GENMASK(31, 28), 3);
+                       break;
+               default:
+                       break;
+               }
+       } else {
+               switch (mt76_chip(&dev->mt76)) {
+               case 0x7915:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX2,
+                                      GENMASK(11, 8), 4);
+                       break;
+               case 0x7986:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
+                                      GENMASK(7, 4), 1);
+                       break;
+               case 0x7916:
+                       mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
+                                      GENMASK(27, 24), 3);
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
 void mt7915_mac_init(struct mt7915_dev *dev)
 {
        int i;
@@ -497,10 +571,7 @@ void mt7915_mac_init(struct mt7915_dev *dev)
        for (i = 0; i < 2; i++)
                mt7915_mac_init_band(dev, i);
 
-       if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-               i = dev->mt76.led_pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;
-               mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4);
-       }
+       mt7915_init_led_mux(dev);
 }
 
 int mt7915_txbf_init(struct mt7915_dev *dev)
@@ -569,7 +640,7 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
        mt76_eeprom_override(mphy);
 
        /* init wiphy according to mphy and phy */
-       mt7915_init_wiphy(mphy->hw);
+       mt7915_init_wiphy(phy);
 
        ret = mt76_register_phy(mphy, true, mt76_rates,
                                ARRAY_SIZE(mt76_rates));
@@ -1104,7 +1175,6 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
 
 int mt7915_register_device(struct mt7915_dev *dev)
 {
-       struct ieee80211_hw *hw = mt76_hw(dev);
        struct mt7915_phy *phy2;
        int ret;
 
@@ -1133,18 +1203,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
        if (ret)
                goto free_phy2;
 
-       mt7915_init_wiphy(hw);
+       mt7915_init_wiphy(&dev->phy);
 
 #ifdef CONFIG_NL80211_TESTMODE
        dev->mt76.test_ops = &mt7915_testmode_ops;
 #endif
 
-       /* init led callbacks */
-       if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-               dev->mt76.led_cdev.brightness_set = mt7915_led_set_brightness;
-               dev->mt76.led_cdev.blink_set = mt7915_led_set_blink;
-       }
-
        ret = mt76_register_device(&dev->mt76, true, mt76_rates,
                                   ARRAY_SIZE(mt76_rates));
        if (ret)
index b2652de..37a3c1f 100644 (file)
@@ -232,8 +232,11 @@ mt7915_mcu_rx_csa_notify(struct mt7915_dev *dev, struct sk_buff *skb)
 
        c = (struct mt7915_mcu_csa_notify *)skb->data;
 
+       if (c->band_idx > MT_BAND1)
+               return;
+
        if ((c->band_idx && !dev->phy.mt76->band_idx) &&
-            dev->mt76.phys[MT_BAND1])
+           dev->mt76.phys[MT_BAND1])
                mphy = dev->mt76.phys[MT_BAND1];
 
        ieee80211_iterate_active_interfaces_atomic(mphy->hw,
@@ -252,8 +255,11 @@ mt7915_mcu_rx_thermal_notify(struct mt7915_dev *dev, struct sk_buff *skb)
        if (t->ctrl.ctrl_id != THERMAL_PROTECT_ENABLE)
                return;
 
+       if (t->ctrl.band_idx > MT_BAND1)
+               return;
+
        if ((t->ctrl.band_idx && !dev->phy.mt76->band_idx) &&
-            dev->mt76.phys[MT_BAND1])
+           dev->mt76.phys[MT_BAND1])
                mphy = dev->mt76.phys[MT_BAND1];
 
        phy = (struct mt7915_phy *)mphy->priv;
@@ -268,8 +274,11 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
 
        r = (struct mt7915_mcu_rdd_report *)skb->data;
 
+       if (r->band_idx > MT_BAND1)
+               return;
+
        if ((r->band_idx && !dev->phy.mt76->band_idx) &&
-            dev->mt76.phys[MT_BAND1])
+           dev->mt76.phys[MT_BAND1])
                mphy = dev->mt76.phys[MT_BAND1];
 
        if (r->band_idx == MT_RX_SEL2)
@@ -326,7 +335,11 @@ mt7915_mcu_rx_bcc_notify(struct mt7915_dev *dev, struct sk_buff *skb)
 
        b = (struct mt7915_mcu_bcc_notify *)skb->data;
 
-       if ((b->band_idx && !dev->phy.mt76->band_idx) && dev->mt76.phys[MT_BAND1])
+       if (b->band_idx > MT_BAND1)
+               return;
+
+       if ((b->band_idx && !dev->phy.mt76->band_idx) &&
+           dev->mt76.phys[MT_BAND1])
                mphy = dev->mt76.phys[MT_BAND1];
 
        ieee80211_iterate_active_interfaces_atomic(mphy->hw,
@@ -2792,8 +2805,9 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
        int ret;
        u8 *buf;
 
-       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_ACCESS), &req,
-                               sizeof(req), true, &skb);
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+                                       MCU_EXT_QUERY(EFUSE_ACCESS),
+                                       &req, sizeof(req), true, &skb);
        if (ret)
                return ret;
 
@@ -2818,8 +2832,9 @@ int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num)
        struct sk_buff *skb;
        int ret;
 
-       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_FREE_BLOCK), &req,
-                                       sizeof(req), true, &skb);
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+                                       MCU_EXT_QUERY(EFUSE_FREE_BLOCK),
+                                       &req, sizeof(req), true, &skb);
        if (ret)
                return ret;
 
@@ -2974,38 +2989,42 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
 
 int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
 {
-       /* strict order */
-       static const u32 offs[] = {
-               MIB_NON_WIFI_TIME,
-               MIB_TX_TIME,
-               MIB_RX_TIME,
-               MIB_OBSS_AIRTIME,
-               MIB_TXOP_INIT_COUNT,
-               /* v2 */
-               MIB_NON_WIFI_TIME_V2,
-               MIB_TX_TIME_V2,
-               MIB_RX_TIME_V2,
-               MIB_OBSS_AIRTIME_V2
-       };
        struct mt76_channel_state *state = phy->mt76->chan_state;
        struct mt76_channel_state *state_ts = &phy->state_ts;
        struct mt7915_dev *dev = phy->dev;
        struct mt7915_mcu_mib *res, req[5];
        struct sk_buff *skb;
-       int i, ret, start = 0, ofs = 20;
+       static const u32 *offs;
+       int i, ret, len, offs_cc;
        u64 cc_tx;
 
-       if (!is_mt7915(&dev->mt76)) {
-               start = 5;
-               ofs = 0;
+       /* strict order */
+       if (is_mt7915(&dev->mt76)) {
+               static const u32 chip_offs[] = {
+                       MIB_NON_WIFI_TIME,
+                       MIB_TX_TIME,
+                       MIB_RX_TIME,
+                       MIB_OBSS_AIRTIME,
+                       MIB_TXOP_INIT_COUNT,
+               };
+               len = ARRAY_SIZE(chip_offs);
+               offs = chip_offs;
+               offs_cc = 20;
+       } else {
+               static const u32 chip_offs[] = {
+                       MIB_NON_WIFI_TIME_V2,
+                       MIB_TX_TIME_V2,
+                       MIB_RX_TIME_V2,
+                       MIB_OBSS_AIRTIME_V2
+               };
+               len = ARRAY_SIZE(chip_offs);
+               offs = chip_offs;
+               offs_cc = 0;
        }
 
-       for (i = 0; i < 5; i++) {
+       for (i = 0; i < len; i++) {
                req[i].band = cpu_to_le32(phy->mt76->band_idx);
-               req[i].offs = cpu_to_le32(offs[i + start]);
-
-               if (!is_mt7915(&dev->mt76) && i == 3)
-                       break;
+               req[i].offs = cpu_to_le32(offs[i]);
        }
 
        ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO),
@@ -3013,7 +3032,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
        if (ret)
                return ret;
 
-       res = (struct mt7915_mcu_mib *)(skb->data + ofs);
+       res = (struct mt7915_mcu_mib *)(skb->data + offs_cc);
 
 #define __res_u64(s) le64_to_cpu(res[s].data)
        /* subtract Tx backoff time from Tx duration */
index 0a95c3d..1a2e4df 100644 (file)
@@ -495,7 +495,7 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
 
        if (dev_is_pci(dev->mt76.dev) &&
            ((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) ||
-            (addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END)))
+           addr >= MT_CBTOP2_PHY_START))
                return mt7915_reg_map_l1(dev, addr);
 
        /* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */
@@ -594,10 +594,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
 static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
 {
        struct mt7915_dev *dev;
-       struct page *page;
+       u32 length;
        int i;
 
        dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+       length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
+                               sizeof(struct skb_shared_info));
+
        for (i = 0; i < dev->mt76.rx_token_size; i++) {
                struct mt76_txwi_cache *t;
 
@@ -607,18 +610,11 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
 
                dma_unmap_single(dev->mt76.dma_dev, t->dma_addr,
                                 wed->wlan.rx_size, DMA_FROM_DEVICE);
-               skb_free_frag(t->ptr);
+               __free_pages(virt_to_page(t->ptr), get_order(length));
                t->ptr = NULL;
 
                mt76_put_rxwi(&dev->mt76, t);
        }
-
-       if (!wed->rx_buf_ring.rx_page.va)
-               return;
-
-       page = virt_to_page(wed->rx_buf_ring.rx_page.va);
-       __page_frag_cache_drain(page, wed->rx_buf_ring.rx_page.pagecnt_bias);
-       memset(&wed->rx_buf_ring.rx_page, 0, sizeof(wed->rx_buf_ring.rx_page));
 }
 
 static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
@@ -635,24 +631,32 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
        for (i = 0; i < size; i++) {
                struct mt76_txwi_cache *t = mt76_get_rxwi(&dev->mt76);
                dma_addr_t phy_addr;
+               struct page *page;
                int token;
                void *ptr;
 
-               ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
-                                     GFP_KERNEL);
-               if (!ptr)
+               page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
+               if (!page)
                        goto unmap;
 
+               ptr = page_address(page);
                phy_addr = dma_map_single(dev->mt76.dma_dev, ptr,
                                          wed->wlan.rx_size,
                                          DMA_TO_DEVICE);
                if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
-                       skb_free_frag(ptr);
+                       __free_pages(page, get_order(length));
                        goto unmap;
                }
 
                desc->buf0 = cpu_to_le32(phy_addr);
                token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr);
+               if (token < 0) {
+                       dma_unmap_single(dev->mt76.dma_dev, phy_addr,
+                                        wed->wlan.rx_size, DMA_TO_DEVICE);
+                       __free_pages(page, get_order(length));
+                       goto unmap;
+               }
+
                desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
                                                      token));
                desc++;
index aca1b2f..c8e478a 100644 (file)
@@ -803,7 +803,6 @@ enum offs_rev {
 #define MT_CBTOP1_PHY_START            0x70000000
 #define MT_CBTOP1_PHY_END              __REG(CBTOP1_PHY_END)
 #define MT_CBTOP2_PHY_START            0xf0000000
-#define MT_CBTOP2_PHY_END              0xffffffff
 #define MT_INFRA_MCU_START             0x7c000000
 #define MT_INFRA_MCU_END               __REG(INFRA_MCU_ADDR_END)
 #define MT_CONN_INFRA_OFFSET(p)                ((p) - MT_INFRA_BASE)
@@ -1055,6 +1054,7 @@ enum offs_rev {
 
 #define MT_LED_CTRL(_n)                        MT_LED_PHYS(0x00 + ((_n) * 4))
 #define MT_LED_CTRL_KICK               BIT(7)
+#define MT_LED_CTRL_BAND               BIT(4)
 #define MT_LED_CTRL_BLINK_MODE         BIT(2)
 #define MT_LED_CTRL_POLARITY           BIT(1)
 
@@ -1062,11 +1062,18 @@ enum offs_rev {
 #define MT_LED_TX_BLINK_ON_MASK                GENMASK(7, 0)
 #define MT_LED_TX_BLINK_OFF_MASK        GENMASK(15, 8)
 
+#define MT_LED_STATUS_0(_n)            MT_LED_PHYS(0x20 + ((_n) * 8))
+#define MT_LED_STATUS_1(_n)            MT_LED_PHYS(0x24 + ((_n) * 8))
+#define MT_LED_STATUS_OFF              GENMASK(31, 24)
+#define MT_LED_STATUS_ON               GENMASK(23, 16)
+#define MT_LED_STATUS_DURATION         GENMASK(15, 0)
+
 #define MT_LED_EN(_n)                  MT_LED_PHYS(0x40 + ((_n) * 4))
 
+#define MT_LED_GPIO_MUX0               0x70005050 /* GPIO 1 and GPIO 2 */
+#define MT_LED_GPIO_MUX1               0x70005054 /* GPIO 14 and 15 */
 #define MT_LED_GPIO_MUX2                0x70005058 /* GPIO 18 */
-#define MT_LED_GPIO_MUX3                0x7000505C /* GPIO 26 */
-#define MT_LED_GPIO_SEL_MASK            GENMASK(11, 8)
+#define MT_LED_GPIO_MUX3               0x7000505c /* GPIO 26 */
 
 /* MT TOP */
 #define MT_TOP_BASE                    0x18060000
index c06c56a..686c9bb 100644 (file)
@@ -278,6 +278,7 @@ static int mt7986_wmac_coninfra_setup(struct mt7915_dev *dev)
                return -EINVAL;
 
        rmem = of_reserved_mem_lookup(np);
+       of_node_put(np);
        if (!rmem)
                return -EINVAL;
 
index 47e034a..a98d0fb 100644 (file)
@@ -135,6 +135,22 @@ mt7921_asar_acpi_read_mtgs(struct mt7921_dev *dev, u8 **table, u8 version)
        return ret;
 }
 
+/* MTFG : Flag Table */
+static int
+mt7921_asar_acpi_read_mtfg(struct mt7921_dev *dev, u8 **table)
+{
+       int len, ret;
+
+       ret = mt7921_acpi_read(dev, MT7921_ACPI_MTFG, table, &len);
+       if (ret)
+               return ret;
+
+       if (len < MT7921_ASAR_MIN_FG)
+               ret = -EINVAL;
+
+       return ret;
+}
+
 int mt7921_init_acpi_sar(struct mt7921_dev *dev)
 {
        struct mt7921_acpi_sar *asar;
@@ -162,6 +178,12 @@ int mt7921_init_acpi_sar(struct mt7921_dev *dev)
                asar->geo = NULL;
        }
 
+       /* MTFG is optional */
+       ret = mt7921_asar_acpi_read_mtfg(dev, (u8 **)&asar->fg);
+       if (ret) {
+               devm_kfree(dev->mt76.dev, asar->fg);
+               asar->fg = NULL;
+       }
        dev->phy.acpisar = asar;
 
        return 0;
@@ -280,3 +302,36 @@ int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default)
 
        return 0;
 }
+
+u8 mt7921_acpi_get_flags(struct mt7921_phy *phy)
+{
+       struct mt7921_asar_fg *fg;
+       struct {
+               u8 acpi_idx;
+               u8 chip_idx;
+       } map[] = {
+               {1, 1},
+               {4, 2},
+       };
+       u8 flags = BIT(0);
+       int i, j;
+
+       if (!phy->acpisar)
+               return 0;
+
+       fg = phy->acpisar->fg;
+       if (!fg)
+               return flags;
+
+       /* pickup necessary settings per device and
+        * translate the index of bitmap for chip command.
+        */
+       for (i = 0; i < fg->nr_flag; i++)
+               for (j = 0; j < ARRAY_SIZE(map); j++)
+                       if (fg->flag[i] == map[j].acpi_idx) {
+                               flags |= BIT(map[j].chip_idx);
+                               break;
+                       }
+
+       return flags;
+}
index 23f86bf..35268b0 100644 (file)
@@ -8,10 +8,12 @@
 #define MT7921_ASAR_MAX_DYN            8
 #define MT7921_ASAR_MIN_GEO            3
 #define MT7921_ASAR_MAX_GEO            8
+#define MT7921_ASAR_MIN_FG             8
 
 #define MT7921_ACPI_MTCL               "MTCL"
 #define MT7921_ACPI_MTDS               "MTDS"
 #define MT7921_ACPI_MTGS               "MTGS"
+#define MT7921_ACPI_MTFG               "MTFG"
 
 struct mt7921_asar_dyn_limit {
        u8 idx;
@@ -77,6 +79,15 @@ struct mt7921_asar_cl {
        u8 cl6g[6];
 } __packed;
 
+struct mt7921_asar_fg {
+       u8 names[4];
+       u8 version;
+       u8 rsvd;
+       u8 nr_flag;
+       u8 rsvd1;
+       u8 flag[0];
+} __packed;
+
 struct mt7921_acpi_sar {
        u8 ver;
        union {
@@ -88,6 +99,7 @@ struct mt7921_acpi_sar {
                struct mt7921_asar_geo_v2 *geo_v2;
        };
        struct mt7921_asar_cl *countrylist;
+       struct mt7921_asar_fg *fg;
 };
 
 #endif
index 542dfd4..d4b681d 100644 (file)
@@ -175,7 +175,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
 
        if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
                dev_err(dev, "Invalid firmware\n");
-               return -EINVAL;
+               goto out;
        }
 
        data = fw->data;
@@ -206,6 +206,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
                data += le16_to_cpu(rel_info->len) + rel_info->pad_len;
        }
 
+out:
        release_firmware(fw);
 
        return features ? features->data : 0;
index fb9c0f6..8930b5a 100644 (file)
@@ -1184,13 +1184,15 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
                __le16 len;
                u8 idx;
                u8 env;
-               u8 pad1[2];
+               u8 acpi_conf;
+               u8 pad1;
                u8 alpha2[2];
                u8 type[2];
                u8 rsvd[64];
        } __packed req = {
                .idx = idx,
                .env = env_cap,
+               .acpi_conf = mt7921_acpi_get_flags(&dev->phy),
        };
        int ret, valid_cnt = 0;
        u8 i, *pos;
index 15d6b7f..efff4d4 100644 (file)
@@ -554,6 +554,7 @@ int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
 #ifdef CONFIG_ACPI
 int mt7921_init_acpi_sar(struct mt7921_dev *dev);
 int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default);
+u8 mt7921_acpi_get_flags(struct mt7921_phy *phy);
 #else
 static inline int
 mt7921_init_acpi_sar(struct mt7921_dev *dev)
@@ -566,6 +567,12 @@ mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default)
 {
        return 0;
 }
+
+static inline u8
+mt7921_acpi_get_flags(struct mt7921_phy *phy)
+{
+       return 0;
+}
 #endif
 int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw,
                          const struct cfg80211_sar_specs *sar);
index 2e4a890..3d4fbbb 100644 (file)
@@ -457,7 +457,7 @@ mt7996_hw_queue_read(struct seq_file *s, u32 size,
                if (val & BIT(map[i].index))
                        continue;
 
-               ctrl = BIT(31) | (map[i].pid << 10) | (map[i].qid << 24);
+               ctrl = BIT(31) | (map[i].pid << 10) | ((u32)map[i].qid << 24);
                mt76_wr(dev, MT_FL_Q0_CTRL, ctrl);
 
                head = mt76_get_field(dev, MT_FL_Q2_CTRL,
@@ -653,8 +653,9 @@ static int
 mt7996_rf_regval_set(void *data, u64 val)
 {
        struct mt7996_dev *dev = data;
+       u32 val32 = val;
 
-       return mt7996_mcu_rf_regval(dev, dev->mt76.debugfs_reg, (u32 *)&val, true);
+       return mt7996_mcu_rf_regval(dev, dev->mt76.debugfs_reg, &val32, true);
 }
 
 DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7996_rf_regval_get,
index b9f62be..5d8e035 100644 (file)
@@ -65,17 +65,23 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
        } else {
                u8 free_block_num;
                u32 block_num, i;
+               u32 eeprom_blk_size = MT7996_EEPROM_BLOCK_SIZE;
 
-               /* TODO: check free block event */
-               mt7996_mcu_get_eeprom_free_block(dev, &free_block_num);
-               /* efuse info not enough */
+               ret = mt7996_mcu_get_eeprom_free_block(dev, &free_block_num);
+               if (ret < 0)
+                       return ret;
+
+               /* efuse info isn't enough */
                if (free_block_num >= 59)
                        return -EINVAL;
 
                /* read eeprom data from efuse */
-               block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, MT7996_EEPROM_BLOCK_SIZE);
-               for (i = 0; i < block_num; i++)
-                       mt7996_mcu_get_eeprom(dev, i * MT7996_EEPROM_BLOCK_SIZE);
+               block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size);
+               for (i = 0; i < block_num; i++) {
+                       ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size);
+                       if (ret < 0)
+                               return ret;
+               }
        }
 
        return mt7996_check_eeprom(dev);
index 46b2905..64e8dfd 100644 (file)
@@ -46,11 +46,11 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev,
                                  u8 delay_on, u8 delay_off)
 {
        struct mt7996_dev *dev;
-       struct mt76_dev *mt76;
+       struct mt76_phy *mphy;
        u32 val;
 
-       mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
-       dev = container_of(mt76, struct mt7996_dev, mt76);
+       mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);
+       dev = container_of(mphy->dev, struct mt7996_dev, mt76);
 
        /* select TX blink mode, 2: only data frames */
        mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2);
@@ -65,7 +65,7 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev,
 
        /* control LED */
        val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
-       if (dev->mt76.led_al)
+       if (mphy->leds.al)
                val |= MT_LED_CTRL_POLARITY;
 
        mt76_wr(dev, MT_LED_CTRL(0), val);
@@ -261,7 +261,7 @@ static void mt7996_mac_init(struct mt7996_dev *dev)
                                       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
 
        if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-               i = dev->mt76.led_pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;
+               i = dev->mphy.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;
                mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4);
        }
 
@@ -787,8 +787,8 @@ int mt7996_register_device(struct mt7996_dev *dev)
 
        /* init led callbacks */
        if (IS_ENABLED(CONFIG_MT76_LEDS)) {
-               dev->mt76.led_cdev.brightness_set = mt7996_led_set_brightness;
-               dev->mt76.led_cdev.blink_set = mt7996_led_set_blink;
+               dev->mphy.leds.cdev.brightness_set = mt7996_led_set_brightness;
+               dev->mphy.leds.cdev.blink_set = mt7996_led_set_blink;
        }
 
        ret = mt76_register_device(&dev->mt76, true, mt76_rates,
index 04e1d10..a88fc76 100644 (file)
@@ -335,6 +335,9 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
 
        r = (struct mt7996_mcu_rdd_report *)skb->data;
 
+       if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
+               return;
+
        mphy = dev->mt76.phys[r->band_idx];
        if (!mphy)
                return;
@@ -412,6 +415,9 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
        struct header *hdr = (struct header *)data;
        struct tlv *tlv = (struct tlv *)(data + 4);
 
+       if (hdr->band >= ARRAY_SIZE(dev->mt76.phys))
+               return;
+
        if (hdr->band && dev->mt76.phys[hdr->band])
                mphy = dev->mt76.phys[hdr->band];
 
@@ -903,8 +909,8 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
        he = (struct sta_rec_he_v2 *)tlv;
        for (i = 0; i < 11; i++) {
                if (i < 6)
-                       he->he_mac_cap[i] = cpu_to_le16(elem->mac_cap_info[i]);
-               he->he_phy_cap[i] = cpu_to_le16(elem->phy_cap_info[i]);
+                       he->he_mac_cap[i] = elem->mac_cap_info[i];
+               he->he_phy_cap[i] = elem->phy_cap_info[i];
        }
 
        mcs_map = sta->deflink.he_cap.he_mcs_nss_supp;
@@ -2921,8 +2927,9 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset)
        bool valid;
        int ret;
 
-       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL), &req,
-                                       sizeof(req), true, &skb);
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+                                       MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL),
+                                       &req, sizeof(req), true, &skb);
        if (ret)
                return ret;
 
index 521769e..60781d0 100644 (file)
@@ -149,7 +149,7 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
 
        if (dev_is_pci(dev->mt76.dev) &&
            ((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) ||
-            (addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END)))
+           addr >= MT_CBTOP2_PHY_START))
                return mt7996_reg_map_l1(dev, addr);
 
        /* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */
index 794f61b..42980b9 100644 (file)
@@ -463,7 +463,6 @@ enum base_rev {
 #define MT_CBTOP1_PHY_START                    0x70000000
 #define MT_CBTOP1_PHY_END                      0x77ffffff
 #define MT_CBTOP2_PHY_START                    0xf0000000
-#define MT_CBTOP2_PHY_END                      0xffffffff
 #define MT_INFRA_MCU_START                     0x7c000000
 #define MT_INFRA_MCU_END                       0x7c3fffff
 
index bfc4de5..ddd8c0c 100644 (file)
@@ -254,6 +254,10 @@ static int mt76s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q)
 
                if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state)) {
                        __skb_put_zero(e->skb, 4);
+                       err = __skb_grow(e->skb, roundup(e->skb->len,
+                                                        sdio->func->cur_blksize));
+                       if (err)
+                               return err;
                        err = __mt76s_xmit_queue(dev, e->skb->data,
                                                 e->skb->len);
                        if (err)
index 24568b9..1f309d0 100644 (file)
@@ -764,11 +764,12 @@ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
        spin_lock_bh(&dev->rx_token_lock);
        token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size,
                          GFP_ATOMIC);
+       if (token >= 0) {
+               t->ptr = ptr;
+               t->dma_addr = phys;
+       }
        spin_unlock_bh(&dev->rx_token_lock);
 
-       t->ptr = ptr;
-       t->dma_addr = phys;
-
        return token;
 }
 EXPORT_SYMBOL_GPL(mt76_rx_token_consume);
index a0746d4..db637a1 100644 (file)
@@ -103,7 +103,6 @@ struct mtk_wed_device {
 
        struct {
                int size;
-               struct page_frag_cache rx_page;
                struct mtk_rxbm_desc *desc;
                dma_addr_t desc_phys;
        } rx_buf_ring;