Skip to content

Commit 5ebdc3e

Browse files
LorenzoBianconiKalle Valo
authored andcommitted
mt76x2: add mac80211 {set,get}_antenna callbacks
Add capability to select tx/rx antennas. Possible values are: - 1: to use only the first antenna - 2: to use only the second antenna - 3: to use both of them Signed-off-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent 551e1ef commit 5ebdc3e

File tree

6 files changed

+88
-16
lines changed

6 files changed

+88
-16
lines changed

drivers/net/wireless/mediatek/mt76/mac80211.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ static void mt76_init_stream_cap(struct mt76_dev *dev,
156156
vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
157157
}
158158

159+
void mt76_set_stream_caps(struct mt76_dev *dev, bool vht)
160+
{
161+
if (dev->cap.has_2ghz)
162+
mt76_init_stream_cap(dev, &dev->sband_2g.sband, false);
163+
if (dev->cap.has_5ghz)
164+
mt76_init_stream_cap(dev, &dev->sband_5g.sband, vht);
165+
}
166+
EXPORT_SYMBOL_GPL(mt76_set_stream_caps);
167+
159168
static int
160169
mt76_init_sband(struct mt76_dev *dev, struct mt76_sband *msband,
161170
const struct ieee80211_channel *chan, int n_chan,

drivers/net/wireless/mediatek/mt76/mt76.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw,
425425
void mt76_set_channel(struct mt76_dev *dev);
426426
int mt76_get_survey(struct ieee80211_hw *hw, int idx,
427427
struct survey_info *survey);
428+
void mt76_set_stream_caps(struct mt76_dev *dev, bool vht);
428429

429430
int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid,
430431
u16 ssn, u8 size);

drivers/net/wireless/mediatek/mt76/mt76x2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ int mt76x2_eeprom_init(struct mt76x2_dev *dev);
180180
int mt76x2_apply_calibration_data(struct mt76x2_dev *dev, int channel);
181181
void mt76x2_set_tx_ackto(struct mt76x2_dev *dev);
182182

183+
void mt76x2_phy_set_antenna(struct mt76x2_dev *dev);
183184
int mt76x2_phy_start(struct mt76x2_dev *dev);
184185
int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
185186
struct cfg80211_chan_def *chandef);

drivers/net/wireless/mediatek/mt76/mt76x2_main.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,40 @@ mt76x2_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
549549
return 0;
550550
}
551551

552+
static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,
553+
u32 rx_ant)
554+
{
555+
struct mt76x2_dev *dev = hw->priv;
556+
557+
if (!tx_ant || tx_ant > 3 || tx_ant != rx_ant)
558+
return -EINVAL;
559+
560+
mutex_lock(&dev->mutex);
561+
562+
dev->chainmask = (tx_ant == 3) ? 0x202 : 0x101;
563+
dev->mt76.antenna_mask = tx_ant;
564+
565+
mt76_set_stream_caps(&dev->mt76, true);
566+
mt76x2_phy_set_antenna(dev);
567+
568+
mutex_unlock(&dev->mutex);
569+
570+
return 0;
571+
}
572+
573+
static int mt76x2_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
574+
u32 *rx_ant)
575+
{
576+
struct mt76x2_dev *dev = hw->priv;
577+
578+
mutex_lock(&dev->mutex);
579+
*tx_ant = dev->mt76.antenna_mask;
580+
*rx_ant = dev->mt76.antenna_mask;
581+
mutex_unlock(&dev->mutex);
582+
583+
return 0;
584+
}
585+
552586
const struct ieee80211_ops mt76x2_ops = {
553587
.tx = mt76x2_tx,
554588
.start = mt76x2_start,
@@ -573,5 +607,7 @@ const struct ieee80211_ops mt76x2_ops = {
573607
.set_coverage_class = mt76x2_set_coverage_class,
574608
.get_survey = mt76_get_survey,
575609
.set_tim = mt76x2_set_tim,
610+
.set_antenna = mt76x2_set_antenna,
611+
.get_antenna = mt76x2_get_antenna,
576612
};
577613

drivers/net/wireless/mediatek/mt76/mt76x2_phy.c

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -361,29 +361,52 @@ mt76x2_phy_set_band(struct mt76x2_dev *dev, int band, bool primary_upper)
361361
primary_upper);
362362
}
363363

364-
static void
365-
mt76x2_set_rx_chains(struct mt76x2_dev *dev)
364+
void mt76x2_phy_set_antenna(struct mt76x2_dev *dev)
366365
{
367366
u32 val;
368367

369368
val = mt76_rr(dev, MT_BBP(AGC, 0));
370-
val &= ~(BIT(3) | BIT(4));
369+
val &= ~(BIT(4) | BIT(1));
370+
switch (dev->mt76.antenna_mask) {
371+
case 1:
372+
/* disable mac DAC control */
373+
mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
374+
mt76_clear(dev, MT_BBP(TXBE, 5), 3);
375+
mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0x3);
376+
mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 2);
377+
/* disable DAC 1 */
378+
mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 4);
371379

372-
if (dev->chainmask & BIT(1))
373-
val |= BIT(3);
380+
val &= ~(BIT(3) | BIT(0));
381+
break;
382+
case 2:
383+
/* disable mac DAC control */
384+
mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
385+
mt76_rmw_field(dev, MT_BBP(TXBE, 5), 3, 1);
386+
mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xc);
387+
mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 1);
388+
/* disable DAC 0 */
389+
mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 1);
390+
391+
val &= ~BIT(3);
392+
val |= BIT(0);
393+
break;
394+
case 3:
395+
default:
396+
/* enable mac DAC control */
397+
mt76_set(dev, MT_BBP(IBI, 9), BIT(11));
398+
mt76_set(dev, MT_BBP(TXBE, 5), 3);
399+
mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xf);
400+
mt76_clear(dev, MT_BBP(CORE, 32), GENMASK(21, 20));
401+
mt76_clear(dev, MT_BBP(CORE, 33), GENMASK(12, 9));
374402

403+
val &= ~BIT(0);
404+
val |= BIT(3);
405+
break;
406+
}
375407
mt76_wr(dev, MT_BBP(AGC, 0), val);
376408
}
377409

378-
static void
379-
mt76x2_set_tx_dac(struct mt76x2_dev *dev)
380-
{
381-
if (dev->chainmask & BIT(1))
382-
mt76_set(dev, MT_BBP(TXBE, 5), 3);
383-
else
384-
mt76_clear(dev, MT_BBP(TXBE, 5), 3);
385-
}
386-
387410
static void
388411
mt76x2_get_agc_gain(struct mt76x2_dev *dev, u8 *dest)
389412
{
@@ -585,10 +608,8 @@ int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
585608
mt76x2_configure_tx_delay(dev, band, bw);
586609
mt76x2_phy_set_txpower(dev);
587610

588-
mt76x2_set_rx_chains(dev);
589611
mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
590612
mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
591-
mt76x2_set_tx_dac(dev);
592613

593614
mt76_rmw(dev, MT_EXT_CCA_CFG,
594615
(MT_EXT_CCA_CFG_CCA0 |
@@ -604,6 +625,8 @@ int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
604625

605626
mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
606627

628+
mt76x2_phy_set_antenna(dev);
629+
607630
/* Enable LDPC Rx */
608631
if (mt76xx_rev(dev) >= MT76XX_REV_E3)
609632
mt76_set(dev, MT_BBP(RXO, 13), BIT(10));

drivers/net/wireless/mediatek/mt76/mt76x2_regs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@
321321
#define MT_TX_PWR_CFG_2 0x131c
322322
#define MT_TX_PWR_CFG_3 0x1320
323323
#define MT_TX_PWR_CFG_4 0x1324
324+
#define MT_TX_PIN_CFG 0x1328
325+
#define MT_TX_PIN_CFG_TXANT GENMASK(3, 0)
324326

325327
#define MT_TX_BAND_CFG 0x132c
326328
#define MT_TX_BAND_CFG_UPPER_40M BIT(0)

0 commit comments

Comments
 (0)