On 2017-02-06 12:25, Stanislaw Gruszka wrote:
> On Thu, Feb 02, 2017 at 12:52:08PM +0100, Felix Fietkau wrote:
>> This is a 2x2 PCIe 802.11ac chipset by MediaTek
>> 
>> Signed-off-by: Felix Fietkau <n...@nbd.name>
> Driver looks great to me, though I think it could be better commented.
> I have some minor issues, but if they need to be fixed, it could be done
> by incremental patches after apply this one to the tree.
> 
> Reviewed-by: Stanislaw Gruszka <sgrus...@redhat.com>
Thanks for the review.

>> +enum dma_msg_port {
>> +    WLAN_PORT,
>> +    CPU_RX_PORT,
>> +    CPU_TX_PORT,
>> +    HOST_PORT,
>> +    VIRTUAL_CPU_RX_PORT,
>> +    VIRTUAL_CPU_TX_PORT,
>> +    DISCARD,
>> +};
> Not used ?
Yeah, I guess it can be removed.

>> +void mt76x2_set_tx_ackto(struct mt76x2_dev *dev)
>> +{
>> +    u8 ackto, sifs, slottime = dev->slottime;
>> +
>> +    slottime += 3 * dev->coverage_class;
>> +
>> +    sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG,
>> +                          MT_XIFS_TIME_CFG_OFDM_SIFS);
>> +
>> +    ackto = slottime + sifs;
>> +    mt76_rmw_field(dev, MT_TX_TIMEOUT_CFG,
>> +                   MT_TX_TIMEOUT_CFG_ACKTO, ackto);
>> +}
> Interesting, if this correct way to configure the TX_TIMEOUT_CFG_ACKTO
> we will also need this in rt2x00. Vendor drivers use 32 for this setting
> and do not change it.
I don't think vendor drivers even have support for coverage class.

> Note we have also EXP_ACT_TIME and EXP_CTS_TIME registers, which stay
> with default settings, but perhaps should be changed depending on
> channel properties as well.
> 
>> +static u32
>> +mt76x2_tx_power_mask(u8 v1, u8 v2, u8 v3, u8 v4)
>> +{
>> +    u32 val = 0;
>> +
>> +    val |= (v1 & (BIT(6) - 1)) << 0;
>> +    val |= (v2 & (BIT(6) - 1)) << 8;
>> +    val |= (v3 & (BIT(6) - 1)) << 16;
>> +    val |= (v4 & (BIT(6) - 1)) << 24;
>> +    return val;
>> +}
> TX_PWR_CFG registers consist of eight 4bit entries, masking 
> two entries with 0x3f does not seems to be correct.
No, these registers consist of four 6bit entries. Both the vendor driver
and the datasheet describe them this way.

>> +    mt76_wr(dev, MT_TX_PWR_CFG_3,
>> +            mt76x2_tx_power_mask(t.ht[12], t.ht[14], t.ht[0], t.ht[2]));
>> +    mt76_wr(dev, MT_TX_PWR_CFG_4,
>> +            mt76x2_tx_power_mask(t.ht[4], t.ht[6], 0, 0));
>> +    mt76_wr(dev, MT_TX_PWR_CFG_7,
>> +            mt76x2_tx_power_mask(t.ofdm[6], t.vht[8], t.ht[6], t.vht[8]));
>> +    mt76_wr(dev, MT_TX_PWR_CFG_8,
>> +            mt76x2_tx_power_mask(t.ht[14], t.vht[8], t.vht[8], 0));
>> +    mt76_wr(dev, MT_TX_PWR_CFG_9,
>> +            mt76x2_tx_power_mask(t.ht[6], t.vht[8], t.vht[8], 0));
> Looks like some of arguments instead of t.vht[x] accidentally become t.ht[x],
> for example t.vht[6] is never used.
There are not enough register fields for all rates individually, so they
overlap. This looks a bit confusing and random, but I did check it
carefully against the vendor driver and the datasheet.

>> +static void
>> +mt76x2_configure_tx_delay(struct mt76x2_dev *dev, enum nl80211_band band, 
>> u8 bw)
>> +{
>> +    u32 cfg0, cfg1;
>> +
>> +    if (mt76x2_ext_pa_enabled(dev, band)) {
>> +            cfg0 = bw ? 0x000b0c01 : 0x00101101;
>> +            cfg1 = 0x00011414;
>> +    } else {
>> +            cfg0 = bw ? 0x000b0b01 : 0x00101001;
>> +            cfg1 = 0x00021414;
>> +    }
>> +    mt76_wr(dev, MT_TX_SW_CFG0, cfg0);
>> +    mt76_wr(dev, MT_TX_SW_CFG1, cfg1);
>> +
>> +    mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_CCK_SIFS,
>> +                   13 + (bw ? 1 : 0));
>> +}
> SIFS for 2GHz should be 10us and for 5GHz 16us. Setting SIFS to 13
> or 14 looks wrong for 2GHz band. Can be correct for 5GHz assuming
> we have some internal delays configured on TX_SW_CFG registers.
This is a CCK-only SIFS value (there's a separate one for OFDM).

> But again this is interesting for rt2x00, where we stay with
> defaults, but looks we should configure XIFS_TIME_CFG based on
> channel. 
I think many of these might be mt76x2 specific tweaks, so be careful
with applying any of that to rt2x00.

>> +    if (chandef->width >= NL80211_CHAN_WIDTH_40)
>> +            sifs++;
>> +
>> +    mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_OFDM_SIFS, sifs);
> This probably should be set together with MT_XIFS_TIME_CFG_CCK_SIFS in 
> mt76x2_configure_tx_delay().
Will look into that.

>> +static int mt76x2_insert_hdr_pad(struct sk_buff *skb)
>> +{
>> +    int len = ieee80211_get_hdrlen_from_skb(skb);
>> +    int ret;
>> +
>> +    if (len % 4 == 0)
>> +            return 0;
>> +
>> +    if (skb_headroom(skb) < 2) {
>> +            ret = pskb_expand_head(skb, 2, 0, GFP_ATOMIC);
>> +            if (ret != 0)
>> +                    return ret;
> This should not be needed if hw->extra_tx_headroom is set properly.
Thanks, will send a follow-up cleanup patch if this one is accepted.

>> +    if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
>> +            qsel = 0;
> For better understating: qsel = MT_QSEL_MGMT;
Right.

>> +void mt76x2_pre_tbtt_tasklet(unsigned long arg)
>> +{
>> +    struct mt76x2_dev *dev = (struct mt76x2_dev *) arg;
>> +    struct mt76_queue *q = &dev->mt76.q_tx[MT_TXQ_PSD];
>> +    struct beacon_bc_data data = {};
>> +    struct sk_buff *skb;
>> +    int i, nframes;
>> +
>> +    data.dev = dev;
>> +    __skb_queue_head_init(&data.q);
>> +
>> +    ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
> This symbol, not like most of other mac80211 symbols, is exported via
> EXPORT_SYMBOL_GPL(), so I'm not sure if it can be used on dual licensed
> file, perhaps licence of this file should be changed to GPL only.
Technically only the resulting binary will become GPL. I still want to
keep the source code of the entire driver ISC licensed to make it easier
for the BSDs to copy code from it.

- Felix

Reply via email to