mt76x02: introduce beacon_ops
authorStanislaw Gruszka <sgruszka@redhat.com>
Tue, 19 Mar 2019 10:37:38 +0000 (11:37 +0100)
committerFelix Fietkau <nbd@nbd.name>
Wed, 1 May 2019 11:03:56 +0000 (13:03 +0200)
Enabling/disableing TBTT and beacon will be diffrent for USB. Introduce
beacon_ops to encapsulate that and implement it for MMIO. USB
implementation is noop for now.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76x0/main.c
drivers/net/wireless/mediatek/mt76/mt76x02.h
drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c

index fee16ab..6919840 100644 (file)
@@ -22,10 +22,9 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
        int ret;
 
        cancel_delayed_work_sync(&dev->cal_work);
-       if (mt76_is_mmio(dev)) {
-               tasklet_disable(&dev->pre_tbtt_tasklet);
+       dev->beacon_ops->pre_tbtt_enable(dev, false);
+       if (mt76_is_mmio(dev))
                tasklet_disable(&dev->dfs_pd.dfs_tasklet);
-       }
 
        mt76_set_channel(&dev->mt76);
        ret = mt76x0_phy_set_channel(dev, chandef);
@@ -38,9 +37,10 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
 
        if (mt76_is_mmio(dev)) {
                mt76x02_dfs_init_params(dev);
-               tasklet_enable(&dev->pre_tbtt_tasklet);
                tasklet_enable(&dev->dfs_pd.dfs_tasklet);
        }
+       dev->beacon_ops->pre_tbtt_enable(dev, true);
+
        mt76_txq_schedule_all(&dev->mt76);
 
        return ret;
index 1a5fc10..74495a4 100644 (file)
@@ -68,6 +68,11 @@ struct mt76x02_calibration {
        s8 tssi_dc;
 };
 
+struct mt76x02_beacon_ops {
+       void (*pre_tbtt_enable) (struct mt76x02_dev *, bool);
+       void (*beacon_enable) (struct mt76x02_dev *, bool);
+};
+
 struct mt76x02_dev {
        struct mt76_dev mt76; /* must be first */
 
@@ -91,6 +96,8 @@ struct mt76x02_dev {
        struct hrtimer pre_tbtt_timer;
        struct work_struct pre_tbtt_work;
 
+       const struct mt76x02_beacon_ops *beacon_ops;
+
        u32 aggr_stats[32];
 
        struct sk_buff *beacons[8];
index e9f71de..e980bec 100644 (file)
@@ -162,14 +162,7 @@ __mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev, u8 vif_idx,
              MT_BEACON_TIME_CFG_TIMER_EN;
        mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en);
 
-       if (mt76_is_usb(dev))
-               return;
-
-       mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en);
-       if (en)
-               mt76x02_irq_enable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
-       else
-               mt76x02_irq_disable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
+       dev->beacon_ops->beacon_enable(dev, en);
 }
 
 void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
@@ -178,9 +171,9 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
        u8 vif_idx = ((struct mt76x02_vif *)vif->drv_priv)->idx;
        struct sk_buff *skb = NULL;
 
-       if (mt76_is_mmio(dev))
-               tasklet_disable(&dev->pre_tbtt_tasklet);
-       else if (val)
+       dev->beacon_ops->pre_tbtt_enable(dev, false);
+
+       if (mt76_is_usb(dev))
                skb = ieee80211_beacon_get(mt76_hw(dev), vif);
 
        if (!dev->beacon_mask)
@@ -188,8 +181,7 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
 
        __mt76x02_mac_set_beacon_enable(dev, vif_idx, val, skb);
 
-       if (mt76_is_mmio(dev))
-               tasklet_enable(&dev->pre_tbtt_tasklet);
+       dev->beacon_ops->pre_tbtt_enable(dev, true);
 }
 
 void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
index ac40a04..5aac38c 100644 (file)
@@ -152,8 +152,32 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
        spin_unlock_bh(&q->lock);
 }
 
+static void mt76x02e_pre_tbtt_enable(struct mt76x02_dev *dev, bool en)
+{
+       if (en)
+               tasklet_enable(&dev->pre_tbtt_tasklet);
+       else
+               tasklet_disable(&dev->pre_tbtt_tasklet);
+}
+
+static void mt76x02e_beacon_enable(struct mt76x02_dev *dev, bool en)
+{
+       mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en);
+       if (en)
+               mt76x02_irq_enable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
+       else
+               mt76x02_irq_disable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
+}
+
 void mt76x02e_init_beacon_config(struct mt76x02_dev *dev)
 {
+       static const struct mt76x02_beacon_ops beacon_ops = {
+               .pre_tbtt_enable = mt76x02e_pre_tbtt_enable,
+               .beacon_enable = mt76x02e_beacon_enable,
+       };
+
+       dev->beacon_ops = &beacon_ops;
+
        /* Fire a pre-TBTT interrupt 8 ms before TBTT */
        mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT, 8 << 4);
        mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER,
index f1a3d41..eec6f85 100644 (file)
@@ -171,8 +171,22 @@ static enum hrtimer_restart mt76x02u_pre_tbtt_interrupt(struct hrtimer *timer)
        return HRTIMER_NORESTART;
 }
 
+static void mt76x02u_pre_tbtt_enable(struct mt76x02_dev *dev, bool en)
+{
+}
+
+static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en)
+{
+}
+
 void mt76x02u_init_beacon_config(struct mt76x02_dev *dev)
 {
+       static const struct mt76x02_beacon_ops beacon_ops = {
+               .pre_tbtt_enable = mt76x02u_pre_tbtt_enable,
+               .beacon_enable = mt76x02u_beacon_enable,
+       };
+       dev->beacon_ops = &beacon_ops;
+
        hrtimer_init(&dev->pre_tbtt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        dev->pre_tbtt_timer.function = mt76x02u_pre_tbtt_interrupt;
        INIT_WORK(&dev->pre_tbtt_work, mt76x02u_pre_tbtt_work);
index 2ac78e4..1e68568 100644 (file)
@@ -57,6 +57,8 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,
 
        mt76_set_channel(&dev->mt76);
 
+       dev->beacon_ops->pre_tbtt_enable(dev, false);
+
        mt76x2_mac_stop(dev, false);
 
        err = mt76x2u_phy_set_channel(dev, chandef);
@@ -64,6 +66,8 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,
        mt76x2_mac_resume(dev);
        mt76x02_edcca_init(dev, true);
 
+       dev->beacon_ops->pre_tbtt_enable(dev, true);
+
        clear_bit(MT76_RESET, &dev->mt76.state);
        mt76_txq_schedule_all(&dev->mt76);