Commit d3b6fab9 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'mt76-for-kvalo-2020-12-04' of https://github.com/nbd168/wireless

mt76 patches for 5.11

* mt7915 fixes
* mt7615 fixes
* support for more sta interfaces on mt7615/mt7915
* mt7915 encap offload
* performance improvements
* channel noise report on mt7915
* usb/sdio support improvements
* mt7915 testmode support
* mt7915 DBDC support
* warning fixes
parents 3324e05e f12758f6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -30,8 +30,8 @@ int mt76_queues_read(struct seq_file *s, void *data)
	struct mt76_dev *dev = dev_get_drvdata(s->private);
	int i;

	for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
		struct mt76_queue *q = dev->q_tx[i];
	for (i = 0; i < ARRAY_SIZE(dev->phy.q_tx); i++) {
		struct mt76_queue *q = dev->phy.q_tx[i];

		if (!q)
			continue;
+18 −19
Original line number Diff line number Diff line
@@ -72,9 +72,11 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
{
	struct mt76_txwi_cache *t;

	local_bh_disable();
	while ((t = __mt76_get_txwi(dev)) != NULL)
		dma_unmap_single(dev->dev, t->dma_addr, dev->drv->txwi_size,
				 DMA_TO_DEVICE);
	local_bh_enable();
}

static int
@@ -86,6 +88,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
	int i;

	spin_lock_init(&q->lock);
	spin_lock_init(&q->cleanup_lock);

	q->regs = dev->mmio.regs + ring_base + idx * MT_RING_SIZE;
	q->ndesc = n_desc;
@@ -215,16 +218,15 @@ mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q)
}

static void
mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
{
	struct mt76_queue *q = dev->q_tx[qid];
	struct mt76_queue_entry entry;
	bool wake = false;
	int last;

	if (!q)
		return;

	spin_lock_bh(&q->cleanup_lock);
	if (flush)
		last = -1;
	else
@@ -237,13 +239,13 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
		if (entry.txwi) {
			if (!(dev->drv->drv_flags & MT_DRV_TXWI_NO_FREE))
				mt76_put_txwi(dev, entry.txwi);
			wake = !flush;
		}

		if (!flush && q->tail == last)
			last = readl(&q->regs->dma_idx);

	}
	spin_unlock_bh(&q->cleanup_lock);

	if (flush) {
		spin_lock_bh(&q->lock);
@@ -252,16 +254,8 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
		spin_unlock_bh(&q->lock);
	}

	wake = wake && q->stopped &&
	       qid < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8;
	if (wake)
		q->stopped = false;

	if (!q->queued)
		wake_up(&dev->tx_wait);

	if (wake)
		ieee80211_wake_queue(dev->hw, qid);
}

static void *
@@ -312,10 +306,9 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
}

static int
mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, enum mt76_txq_id qid,
mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
			  struct sk_buff *skb, u32 tx_info)
{
	struct mt76_queue *q = dev->q_tx[qid];
	struct mt76_queue_buf buf;
	dma_addr_t addr;

@@ -343,11 +336,10 @@ error:
}

static int
mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
		      struct sk_buff *skb, struct mt76_wcid *wcid,
		      struct ieee80211_sta *sta)
{
	struct mt76_queue *q = dev->q_tx[qid];
	struct mt76_tx_info tx_info = {
		.skb = skb,
	};
@@ -397,7 +389,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,

	dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
				DMA_TO_DEVICE);
	ret = dev->drv->tx_prepare_skb(dev, txwi, qid, wcid, sta, &tx_info);
	ret = dev->drv->tx_prepare_skb(dev, txwi, q->qid, wcid, sta, &tx_info);
	dma_sync_single_for_device(dev->dev, t->dma_addr, dev->drv->txwi_size,
				   DMA_TO_DEVICE);
	if (ret < 0)
@@ -661,8 +653,15 @@ void mt76_dma_cleanup(struct mt76_dev *dev)

	mt76_worker_disable(&dev->tx_worker);
	netif_napi_del(&dev->tx_napi);
	for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++)
		mt76_dma_tx_cleanup(dev, i, true);

	for (i = 0; i < ARRAY_SIZE(dev->phy.q_tx); i++) {
		mt76_dma_tx_cleanup(dev, dev->phy.q_tx[i], true);
		if (dev->phy2)
			mt76_dma_tx_cleanup(dev, dev->phy2->q_tx[i], true);
	}

	for (i = 0; i < ARRAY_SIZE(dev->q_mcu); i++)
		mt76_dma_tx_cleanup(dev, dev->q_mcu[i], true);

	mt76_for_each_q_rx(dev, i) {
		netif_napi_del(&dev->napi[i]);
+7 −5
Original line number Diff line number Diff line
@@ -88,8 +88,10 @@ out_put_node:
}

void
mt76_eeprom_override(struct mt76_dev *dev)
mt76_eeprom_override(struct mt76_phy *phy)
{
	struct mt76_dev *dev = phy->dev;

#ifdef CONFIG_OF
	struct device_node *np = dev->dev->of_node;
	const u8 *mac = NULL;
@@ -97,14 +99,14 @@ mt76_eeprom_override(struct mt76_dev *dev)
	if (np)
		mac = of_get_mac_address(np);
	if (!IS_ERR_OR_NULL(mac))
		ether_addr_copy(dev->macaddr, mac);
		ether_addr_copy(phy->macaddr, mac);
#endif

	if (!is_valid_ether_addr(dev->macaddr)) {
		eth_random_addr(dev->macaddr);
	if (!is_valid_ether_addr(phy->macaddr)) {
		eth_random_addr(phy->macaddr);
		dev_info(dev->dev,
			 "Invalid MAC address, using random address %pM\n",
			 dev->macaddr);
			 phy->macaddr);
	}
}
EXPORT_SYMBOL_GPL(mt76_eeprom_override);
+84 −65
Original line number Diff line number Diff line
@@ -159,21 +159,22 @@ static void mt76_init_stream_cap(struct mt76_phy *phy,

void mt76_set_stream_caps(struct mt76_phy *phy, bool vht)
{
	if (phy->dev->cap.has_2ghz)
	if (phy->cap.has_2ghz)
		mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
	if (phy->dev->cap.has_5ghz)
	if (phy->cap.has_5ghz)
		mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht);
}
EXPORT_SYMBOL_GPL(mt76_set_stream_caps);

static int
mt76_init_sband(struct mt76_dev *dev, struct mt76_sband *msband,
mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband,
		const struct ieee80211_channel *chan, int n_chan,
		struct ieee80211_rate *rates, int n_rates, bool vht)
{
	struct ieee80211_supported_band *sband = &msband->sband;
	struct ieee80211_sta_ht_cap *ht_cap;
	struct ieee80211_sta_vht_cap *vht_cap;
	struct ieee80211_sta_ht_cap *ht_cap;
	struct mt76_dev *dev = phy->dev;
	void *chanlist;
	int size;

@@ -203,7 +204,7 @@ mt76_init_sband(struct mt76_dev *dev, struct mt76_sband *msband,
	ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
	ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;

	mt76_init_stream_cap(&dev->phy, sband, vht);
	mt76_init_stream_cap(phy, sband, vht);

	if (!vht)
		return 0;
@@ -221,27 +222,25 @@ mt76_init_sband(struct mt76_dev *dev, struct mt76_sband *msband,
}

static int
mt76_init_sband_2g(struct mt76_dev *dev, struct ieee80211_rate *rates,
mt76_init_sband_2g(struct mt76_phy *phy, struct ieee80211_rate *rates,
		   int n_rates)
{
	dev->hw->wiphy->bands[NL80211_BAND_2GHZ] = &dev->phy.sband_2g.sband;
	phy->hw->wiphy->bands[NL80211_BAND_2GHZ] = &phy->sband_2g.sband;

	return mt76_init_sband(dev, &dev->phy.sband_2g,
			       mt76_channels_2ghz,
			       ARRAY_SIZE(mt76_channels_2ghz),
			       rates, n_rates, false);
	return mt76_init_sband(phy, &phy->sband_2g, mt76_channels_2ghz,
			       ARRAY_SIZE(mt76_channels_2ghz), rates,
			       n_rates, false);
}

static int
mt76_init_sband_5g(struct mt76_dev *dev, struct ieee80211_rate *rates,
mt76_init_sband_5g(struct mt76_phy *phy, struct ieee80211_rate *rates,
		   int n_rates, bool vht)
{
	dev->hw->wiphy->bands[NL80211_BAND_5GHZ] = &dev->phy.sband_5g.sband;
	phy->hw->wiphy->bands[NL80211_BAND_5GHZ] = &phy->sband_5g.sband;

	return mt76_init_sband(dev, &dev->phy.sband_5g,
			       mt76_channels_5ghz,
			       ARRAY_SIZE(mt76_channels_5ghz),
			       rates, n_rates, vht);
	return mt76_init_sband(phy, &phy->sband_5g, mt76_channels_5ghz,
			       ARRAY_SIZE(mt76_channels_5ghz), rates,
			       n_rates, vht);
}

static void
@@ -274,12 +273,13 @@ mt76_check_sband(struct mt76_phy *phy, struct mt76_sband *msband,
}

static void
mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
{
	struct mt76_dev *dev = phy->dev;
	struct wiphy *wiphy = hw->wiphy;

	SET_IEEE80211_DEV(hw, dev->dev);
	SET_IEEE80211_PERM_ADDR(hw, dev->macaddr);
	SET_IEEE80211_PERM_ADDR(hw, phy->macaddr);

	wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
	wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
@@ -305,6 +305,7 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
	ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
	ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
	ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);

	if (!(dev->drv->drv_flags & MT_DRV_AMSDU_OFFLOAD)) {
		ieee80211_hw_set(hw, TX_AMSDU);
@@ -314,7 +315,6 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
	ieee80211_hw_set(hw, MFP_CAPABLE);
	ieee80211_hw_set(hw, AP_LINK_PS);
	ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
	ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);

	wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
	wiphy->interface_modes =
@@ -333,65 +333,57 @@ mt76_alloc_phy(struct mt76_dev *dev, unsigned int size,
	       const struct ieee80211_ops *ops)
{
	struct ieee80211_hw *hw;
	unsigned int phy_size;
	struct mt76_phy *phy;
	unsigned int phy_size, chan_size;
	unsigned int size_2g, size_5g;
	void *priv;

	phy_size = ALIGN(sizeof(*phy), 8);
	chan_size = sizeof(dev->phy.sband_2g.chan[0]);
	size_2g = ALIGN(ARRAY_SIZE(mt76_channels_2ghz) * chan_size, 8);
	size_5g = ALIGN(ARRAY_SIZE(mt76_channels_5ghz) * chan_size, 8);

	size += phy_size + size_2g + size_5g;
	hw = ieee80211_alloc_hw(size, ops);
	hw = ieee80211_alloc_hw(size + phy_size, ops);
	if (!hw)
		return NULL;

	phy = hw->priv;
	phy->dev = dev;
	phy->hw = hw;
	phy->priv = hw->priv + phy_size;

	mt76_phy_init(dev, hw);

	priv = hw->priv + phy_size;
	return phy;
}
EXPORT_SYMBOL_GPL(mt76_alloc_phy);

	phy->sband_2g = dev->phy.sband_2g;
	phy->sband_2g.chan = priv;
	priv += size_2g;
int mt76_register_phy(struct mt76_phy *phy, bool vht,
		      struct ieee80211_rate *rates, int n_rates)
{
	int ret;

	phy->sband_5g = dev->phy.sband_5g;
	phy->sband_5g.chan = priv;
	priv += size_5g;
	mt76_phy_init(phy, phy->hw);

	phy->priv = priv;
	if (phy->cap.has_2ghz) {
		ret = mt76_init_sband_2g(phy, rates, n_rates);
		if (ret)
			return ret;
	}

	hw->wiphy->bands[NL80211_BAND_2GHZ] = &phy->sband_2g.sband;
	hw->wiphy->bands[NL80211_BAND_5GHZ] = &phy->sband_5g.sband;
	if (phy->cap.has_5ghz) {
		ret = mt76_init_sband_5g(phy, rates + 4, n_rates - 4, vht);
		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);

	return phy;
}
EXPORT_SYMBOL_GPL(mt76_alloc_phy);

int
mt76_register_phy(struct mt76_phy *phy)
{
	int ret;

	ret = ieee80211_register_hw(phy->hw);
	if (ret)
		return ret;

	phy->dev->phy2 = phy;

	return 0;
}
EXPORT_SYMBOL_GPL(mt76_register_phy);

void
mt76_unregister_phy(struct mt76_phy *phy)
void mt76_unregister_phy(struct mt76_phy *phy)
{
	struct mt76_dev *dev = phy->dev;

@@ -459,16 +451,16 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
	int ret;

	dev_set_drvdata(dev->dev, dev);
	mt76_phy_init(dev, hw);
	mt76_phy_init(phy, hw);

	if (dev->cap.has_2ghz) {
		ret = mt76_init_sband_2g(dev, rates, n_rates);
	if (phy->cap.has_2ghz) {
		ret = mt76_init_sband_2g(phy, rates, n_rates);
		if (ret)
			return ret;
	}

	if (dev->cap.has_5ghz) {
		ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht);
	if (phy->cap.has_5ghz) {
		ret = mt76_init_sband_5g(phy, rates + 4, n_rates - 4, vht);
		if (ret)
			return ret;
	}
@@ -539,14 +531,11 @@ EXPORT_SYMBOL_GPL(mt76_rx);

bool mt76_has_tx_pending(struct mt76_phy *phy)
{
	struct mt76_dev *dev = phy->dev;
	struct mt76_queue *q;
	int i, offset;

	offset = __MT_TXQ_MAX * (phy != &dev->phy);
	int i;

	for (i = 0; i < __MT_TXQ_MAX; i++) {
		q = dev->q_tx[offset + i];
		q = phy->q_tx[i];
		if (q && q->queued)
			return true;
	}
@@ -842,7 +831,7 @@ mt76_airtime_check(struct mt76_dev *dev, struct sk_buff *skb)
		return;

	if (!wcid || !wcid->sta) {
		if (!ether_addr_equal(hdr->addr1, dev->macaddr))
		if (!ether_addr_equal(hdr->addr1, dev->phy.macaddr))
			return;

		wcid = NULL;
@@ -932,7 +921,8 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
{
	struct ieee80211_sta *sta;
	struct ieee80211_hw *hw;
	struct sk_buff *skb;
	struct sk_buff *skb, *tmp;
	LIST_HEAD(list);

	spin_lock(&dev->rx_lock);
	while ((skb = __skb_dequeue(frames)) != NULL) {
@@ -942,9 +932,19 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
		}

		mt76_rx_convert(dev, skb, &hw, &sta);
		ieee80211_rx_napi(hw, sta, skb, napi);
		ieee80211_rx_list(hw, sta, skb, &list);
	}
	spin_unlock(&dev->rx_lock);

	if (!napi) {
		netif_receive_skb_list(&list);
		return;
	}

	list_for_each_entry_safe(skb, tmp, &list, list) {
		skb_list_del_init(skb);
		napi_gro_receive(napi, skb);
	}
}

void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
@@ -1202,3 +1202,22 @@ int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
	return 0;
}
EXPORT_SYMBOL_GPL(mt76_get_antenna);

struct mt76_queue *
mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
		int ring_base)
{
	struct mt76_queue *hwq;
	int err;

	hwq = devm_kzalloc(dev->dev, sizeof(*hwq), GFP_KERNEL);
	if (!hwq)
		return ERR_PTR(-ENOMEM);

	err = dev->queue_ops->alloc(dev, hwq, idx, n_desc, 0, ring_base);
	if (err < 0)
		return ERR_PTR(err);

	return hwq;
}
EXPORT_SYMBOL_GPL(mt76_init_queue);
+80 −0
Original line number Diff line number Diff line
@@ -50,3 +50,83 @@ void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb)
	wake_up(&dev->mcu.wait);
}
EXPORT_SYMBOL_GPL(mt76_mcu_rx_event);

int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data,
			      int len, bool wait_resp, struct sk_buff **ret_skb)
{
	struct sk_buff *skb;

	if (dev->mcu_ops->mcu_send_msg)
		return dev->mcu_ops->mcu_send_msg(dev, cmd, data, len, wait_resp);

	skb = mt76_mcu_msg_alloc(dev, data, len);
	if (!skb)
		return -ENOMEM;

	return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, ret_skb);
}
EXPORT_SYMBOL_GPL(mt76_mcu_send_and_get_msg);

int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
				  int cmd, bool wait_resp,
				  struct sk_buff **ret_skb)
{
	unsigned long expires;
	int ret, seq;

	if (ret_skb)
		*ret_skb = NULL;

	mutex_lock(&dev->mcu.mutex);

	ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
	if (ret < 0)
		goto out;

	if (!wait_resp) {
		ret = 0;
		goto out;
	}

	expires = jiffies + dev->mcu.timeout;

	do {
		skb = mt76_mcu_get_response(dev, expires);
		ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb, seq);
		if (!ret && ret_skb)
			*ret_skb = skb;
		else
			dev_kfree_skb(skb);
	} while (ret == -EAGAIN);

out:
	mutex_unlock(&dev->mcu.mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(mt76_mcu_skb_send_and_get_msg);

int mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data,
			   int len)
{
	int err, cur_len;

	while (len > 0) {
		cur_len = min_t(int, 4096 - dev->mcu_ops->headroom, len);

		err = mt76_mcu_send_msg(dev, cmd, data, cur_len, false);
		if (err)
			return err;

		data += cur_len;
		len -= cur_len;

		if (dev->queue_ops->tx_cleanup)
			dev->queue_ops->tx_cleanup(dev,
						   dev->q_mcu[MT_MCUQ_FWDL],
						   false);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(mt76_mcu_send_firmware);
Loading