mt7603: add rudimentary tx path code

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2015-12-20 00:14:23 +01:00
parent 72fdb38c46
commit 3b1ca1b61c
6 changed files with 168 additions and 3 deletions
+1 -1
View File
@@ -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;
};
+7
View File
@@ -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
+21
View File
@@ -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)
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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