mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
mt7603: add rudimentary tx path code
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -123,7 +123,7 @@ struct mt76_txq {
|
||||
};
|
||||
|
||||
struct mt76_txwi_cache {
|
||||
u32 txwi[6];
|
||||
u32 txwi[8];
|
||||
dma_addr_t dma_addr;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
@@ -89,6 +89,9 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev);
|
||||
int mt7603_mcu_init(struct mt7603_dev *dev);
|
||||
int mt7603_tx_queue_mcu(struct mt7603_dev *dev, enum mt76_txq_id qid,
|
||||
struct sk_buff *skb);
|
||||
int mt7603_tx_queue_skb(struct mt76_dev *cdev, struct mt76_queue *q,
|
||||
struct sk_buff *skb, struct mt76_txwi_cache *t,
|
||||
struct mt76_wcid *wcid, struct ieee80211_sta *sta);
|
||||
|
||||
void mt7603_set_irq_mask(struct mt7603_dev *dev, u32 clear, u32 set);
|
||||
|
||||
@@ -115,4 +118,8 @@ int mt7603_mcu_exit(struct mt7603_dev *dev);
|
||||
void mt7603_wtbl_init(struct mt7603_dev *dev, int idx, const u8 *addr);
|
||||
void mt7603_wtbl_clear(struct mt7603_dev *dev, int idx);
|
||||
|
||||
int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||
struct ieee80211_sta *sta);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,27 @@ mt7603_tx_queue_mcu(struct mt7603_dev *dev, enum mt76_txq_id qid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mt7603_tx_queue_skb(struct mt76_dev *cdev, struct mt76_queue *q,
|
||||
struct sk_buff *skb, struct mt76_txwi_cache *t,
|
||||
struct mt76_wcid *wcid, struct ieee80211_sta *sta)
|
||||
{
|
||||
struct mt7603_dev *dev = container_of(cdev, struct mt7603_dev, mt76);
|
||||
dma_addr_t addr;
|
||||
int idx;
|
||||
|
||||
addr = dma_map_single(dev->mt76.dev, skb->data, skb->len, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev->mt76.dev, addr))
|
||||
return -ENOMEM;
|
||||
|
||||
idx = mt76_queue_add_buf(dev, q, t->dma_addr, MT_TXD_SIZE,
|
||||
addr, skb->len, 0);
|
||||
q->entry[idx].skb = skb;
|
||||
q->entry[idx].txwi = t;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_tx_cleanup_entry(struct mt76_dev *mdev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e)
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
struct mt7603_dev *mt7603_alloc_device(struct device *pdev)
|
||||
{
|
||||
static const struct mt76_driver_ops drv_ops = {
|
||||
.fill_txwi = mt7603_mac_write_txwi,
|
||||
.tx_queue_skb = mt7603_tx_queue_skb,
|
||||
};
|
||||
struct ieee80211_hw *hw;
|
||||
struct mt7603_dev *dev;
|
||||
|
||||
@@ -28,6 +32,7 @@ struct mt7603_dev *mt7603_alloc_device(struct device *pdev)
|
||||
dev = hw->priv;
|
||||
dev->mt76.dev = pdev;
|
||||
dev->mt76.hw = hw;
|
||||
dev->mt76.drv = &drv_ops;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
+117
@@ -11,6 +11,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include "mt7603.h"
|
||||
#include "mt7603_mac.h"
|
||||
|
||||
@@ -233,6 +234,122 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16
|
||||
mt7603_mac_tx_rate_val(struct mt7603_dev *dev,
|
||||
const struct ieee80211_tx_rate *rate, u8 *nss, u8 *bw)
|
||||
{
|
||||
u8 phy, rate_idx;
|
||||
|
||||
*nss = 1;
|
||||
*bw = 0;
|
||||
if (rate->flags & IEEE80211_TX_RC_MCS) {
|
||||
rate_idx = rate->idx;
|
||||
*nss = 1 + (rate->idx >> 3);
|
||||
phy = MT_PHY_TYPE_HT;
|
||||
if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD)
|
||||
phy = MT_PHY_TYPE_HT_GF;
|
||||
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
*bw = 1;
|
||||
} else {
|
||||
const struct ieee80211_rate *r;
|
||||
int band = dev->chandef.chan->band;
|
||||
u16 val;
|
||||
|
||||
r = &mt76_hw(dev)->wiphy->bands[band]->bitrates[rate->idx];
|
||||
if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
|
||||
val = r->hw_value_short;
|
||||
else
|
||||
val = r->hw_value;
|
||||
|
||||
phy = val >> 8;
|
||||
rate_idx = val & 0xff;
|
||||
}
|
||||
|
||||
return (MT76_SET(MT_TX_RATE_IDX, rate_idx) |
|
||||
MT76_SET(MT_TX_RATE_MODE, phy));
|
||||
}
|
||||
|
||||
int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_tx_rate *rate = &info->control.rates[0];
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
__le32 *txwi = txwi_ptr;
|
||||
int wlan_idx;
|
||||
int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
|
||||
u8 frame_type, frame_subtype;
|
||||
u8 nss, bw;
|
||||
|
||||
if (wcid)
|
||||
wlan_idx = wcid->idx;
|
||||
else
|
||||
wlan_idx = MT7603_WTBL_RESERVED;
|
||||
|
||||
frame_type = MT76_GET(IEEE80211_FCTL_FTYPE,
|
||||
le16_to_cpu(hdr->frame_control));
|
||||
frame_subtype = MT76_GET(IEEE80211_FCTL_STYPE,
|
||||
le16_to_cpu(hdr->frame_control));
|
||||
|
||||
txwi[0] = cpu_to_le32(
|
||||
MT76_SET(MT_TXD0_TX_BYTES, skb->len + MT_TXD_SIZE) |
|
||||
MT76_SET(MT_TXD0_Q_IDX, skb_get_queue_mapping(skb))
|
||||
);
|
||||
txwi[1] = cpu_to_le32(
|
||||
MT_TXD1_LONG_FORMAT |
|
||||
MT76_SET(MT_TXD1_OWN_MAC, 0) |
|
||||
MT76_SET(MT_TXD1_TID, skb->priority &
|
||||
IEEE80211_QOS_CTL_TID_MASK) |
|
||||
MT76_SET(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) |
|
||||
MT76_SET(MT_TXD1_HDR_INFO, hdr_len / 2) |
|
||||
MT76_SET(MT_TXD1_WLAN_IDX, wlan_idx)
|
||||
);
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
txwi[1] |= cpu_to_le32(MT_TXD1_NO_ACK);
|
||||
|
||||
txwi[2] = cpu_to_le32(
|
||||
MT76_SET(MT_TXD2_FRAME_TYPE, frame_type) |
|
||||
MT76_SET(MT_TXD2_SUB_TYPE, frame_subtype) |
|
||||
MT76_SET(MT_TXD2_MULTICAST, is_multicast_ether_addr(hdr->addr1))
|
||||
);
|
||||
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
|
||||
txwi[2] |= cpu_to_le32(MT_TXD2_BA_DISABLE);
|
||||
|
||||
txwi[3] = cpu_to_le32(MT76_SET(MT_TXD3_REM_TX_COUNT, 0xf));
|
||||
txwi[4] = 0;
|
||||
txwi[5] = cpu_to_le32(MT_TXD5_TX_STATUS_HOST | MT_TXD5_SW_POWER_MGMT);
|
||||
txwi[6] = 0;
|
||||
|
||||
spin_lock_bh(&dev->mt76.lock);
|
||||
if (rate->idx >= 0 && !rate->count) {
|
||||
u16 rateval = mt7603_mac_tx_rate_val(dev, rate, &nss, &bw);
|
||||
|
||||
if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1)
|
||||
rateval |= MT_TX_RATE_STBC;
|
||||
|
||||
txwi[6] |= cpu_to_le32(
|
||||
MT_TXD6_FIXED_RATE |
|
||||
MT_TXD6_FIXED_BW |
|
||||
MT76_SET(MT_TXD6_BW, bw) |
|
||||
MT76_SET(MT_TXD6_TX_RATE, rateval)
|
||||
);
|
||||
|
||||
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
txwi[6] |= cpu_to_le32(MT_TXD6_SGI);
|
||||
}
|
||||
spin_unlock_bh(&dev->mt76.lock);
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_LDPC)
|
||||
txwi[6] |= cpu_to_le32(MT_TXD6_LDPC);
|
||||
|
||||
txwi[7] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt7603_mac_start(struct mt7603_dev *dev)
|
||||
{
|
||||
mt76_clear(dev, MT_WF_ARB_SCR, MT_WF_ARB_TX_DISABLE | MT_WF_ARB_RX_DISABLE);
|
||||
|
||||
+17
-2
@@ -129,6 +129,15 @@ enum rx_pkt_type {
|
||||
#define MT_RXV6_NF1 GENMASK(15, 8)
|
||||
#define MT_RXV6_NF0 GENMASK(7, 0)
|
||||
|
||||
enum mt7603_tx_header_format {
|
||||
MT_HDR_FORMAT_802_3,
|
||||
MT_HDR_FORMAT_CMD,
|
||||
MT_HDR_FORMAT_802_11,
|
||||
MT_HDR_FORMAT_802_11_EXT,
|
||||
};
|
||||
|
||||
#define MT_TXD_SIZE (8 * 4)
|
||||
|
||||
#define MT_TXD0_P_IDX BIT(31)
|
||||
#define MT_TXD0_Q_IDX GENMASK(30, 27)
|
||||
#define MT_TXD0_UTXB BIT(26)
|
||||
@@ -143,7 +152,7 @@ enum rx_pkt_type {
|
||||
#define MT_TXD1_TID GENMASK(22, 20)
|
||||
#define MT_TXD1_NO_ACK BIT(19)
|
||||
#define MT_TXD1_HDR_PAD GENMASK(18, 16)
|
||||
#define MT_TXD1_FT BIT(15)
|
||||
#define MT_TXD1_LONG_FORMAT BIT(15)
|
||||
#define MT_TXD1_HDR_FORMAT GENMASK(14, 13)
|
||||
#define MT_TXD1_HDR_INFO GENMASK(12, 8)
|
||||
#define MT_TXD1_WLAN_IDX GENMASK(7, 0)
|
||||
@@ -190,8 +199,14 @@ enum rx_pkt_type {
|
||||
#define MT_TXD6_DYN_BW BIT(15)
|
||||
#define MT_TXD6_ANT_PRI GENMASK(14, 12)
|
||||
#define MT_TXD6_SPE_EN BIT(11)
|
||||
#define MT_TXD6_BW GENMASK(10, 8)
|
||||
#define MT_TXD6_FIXED_BW BIT(10)
|
||||
#define MT_TXD6_BW GENMASK(9, 8)
|
||||
#define MT_TXD6_ANT_ID GENMASK(7, 2)
|
||||
#define MT_TXD6_FIXED_RATE BIT(0)
|
||||
|
||||
#define MT_TX_RATE_STBC BIT(11)
|
||||
#define MT_TX_RATE_NSS GENAMSK(10, 9)
|
||||
#define MT_TX_RATE_MODE GENMASK(8, 6)
|
||||
#define MT_TX_RATE_IDX GENMASK(5, 0)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user