wireless-next patches for v6.3

First set of patches for v6.3. The most important change here is that
 the old Wireless Extension user space interface is not supported on
 Wi-Fi 7 devices at all. We also added a warning if anyone with modern
 drivers (ie. cfg80211 and mac80211 drivers) tries to use Wireless
 Extensions, everyone should switch to using nl80211 interface instead.
 
 Static WEP support is removed, there wasn't any driver using that
 anyway so there's no user impact. Otherwise it's smaller features and
 fixes as usual.
 
 Note: As mt76 had tricky conflicts due to the fixes in wireless tree,
 we decided to merge wireless into wireless-next to solve them easily.
 There should not be any merge problems anymore.
 
 Major changes:
 
 cfg80211
 
 * remove never used static WEP support
 
 * warn if Wireless Extention interface is used with cfg80211/mac80211 drivers
 
 * stop supporting Wireless Extensions with Wi-Fi 7 devices
 
 * support minimal Wi-Fi 7 Extremely High Throughput (EHT) rate reporting
 
 rfkill
 
 * add GPIO DT support
 
 bitfield
 
 * add FIELD_PREP_CONST()
 
 mt76
 
 * per-PHY LED support
 
 rtw89
 
 * support new Bluetooth co-existance version
 
 rtl8xxxu
 
 * support RTL8188EU
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmPOYeQRHGt2YWxvQGtl
 cm5lbC5vcmcACgkQbhckVSbrbZvSlAf/Y5ZY5xLEytUma7fBkBObXEfP/7tlBBsu
 RoRKVx77D1LGfGu0WXG9PCdvyY70e2QtrkdeLHF3gfzLYpNZIyB/eOFhwzCtbJrD
 ls2yXhdTm9OwDOHAdvXLXx3fmF4bXni7dYdi78VrGCFOnU6XE6X5JpnZYU1SmQ1U
 8Ro7H6D9yp8MKfh5Ct19PYSTS5hmHB09vfJ4rbkjHp7kEGvJjYNbvAqGsxatPnh9
 Zw35TEIwmhZO4GsXxsG12g6LZa8W8RO8uCwepHxtFM8oGsF68Yb/lkLcdtMiuN6V
 WdB6qn24faEWjdmt5BzJGueA3Td8KI6t5cHhGbQVKjyFD8lAC+IJQA==
 =Nq9U
 -----END PGP SIGNATURE-----

Merge tag 'wireless-next-2023-01-23' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Kalle Valo says:

====================
wireless-next patches for v6.3

First set of patches for v6.3. The most important change here is that
the old Wireless Extension user space interface is not supported on
Wi-Fi 7 devices at all. We also added a warning if anyone with modern
drivers (ie. cfg80211 and mac80211 drivers) tries to use Wireless
Extensions, everyone should switch to using nl80211 interface instead.

Static WEP support is removed, there wasn't any driver using that
anyway so there's no user impact. Otherwise it's smaller features and
fixes as usual.

Note: As mt76 had tricky conflicts due to the fixes in wireless tree,
we decided to merge wireless into wireless-next to solve them easily.
There should not be any merge problems anymore.

Major changes:

cfg80211
 - remove never used static WEP support
 - warn if Wireless Extention interface is used with cfg80211/mac80211 drivers
 - stop supporting Wireless Extensions with Wi-Fi 7 devices
 - support minimal Wi-Fi 7 Extremely High Throughput (EHT) rate reporting

rfkill
 - add GPIO DT support

bitfield
 - add FIELD_PREP_CONST()

mt76
 - per-PHY LED support

rtw89
 - support new Bluetooth co-existance version

rtl8xxxu
 - support RTL8188EU

* tag 'wireless-next-2023-01-23' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (123 commits)
  wifi: wireless: deny wireless extensions on MLO-capable devices
  wifi: wireless: warn on most wireless extension usage
  wifi: mac80211: drop extra 'e' from ieeee80211... name
  wifi: cfg80211: Deduplicate certificate loading
  bitfield: add FIELD_PREP_CONST()
  wifi: mac80211: add kernel-doc for EHT structure
  mac80211: support minimal EHT rate reporting on RX
  wifi: mac80211: Add HE MU-MIMO related flags in ieee80211_bss_conf
  wifi: mac80211: Add VHT MU-MIMO related flags in ieee80211_bss_conf
  wifi: cfg80211: Use MLD address to indicate MLD STA disconnection
  wifi: cfg80211: Support 32 bytes KCK key in GTK rekey offload
  wifi: cfg80211: Fix extended KCK key length check in nl80211_set_rekey_data()
  wifi: cfg80211: remove support for static WEP
  wifi: rtl8xxxu: Dump the efuse only for untested devices
  wifi: rtl8xxxu: Print the ROM version too
  wifi: rtw88: Use non-atomic sta iterator in rtw_ra_mask_info_update()
  wifi: rtw88: Use rtw_iterate_vifs() for rtw_vif_watch_dog_iter()
  wifi: rtw88: Move register access from rtw_bf_assoc() outside the RCU
  wifi: rtl8xxxu: Use a longer retry limit of 48
  wifi: rtl8xxxu: Report the RSSI to the firmware
  ...
====================

Link: https://lore.kernel.org/r/20230123103338.330CBC433EF@smtp.kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2023-01-23 21:27:30 -08:00
commit 62be69397e
109 changed files with 5095 additions and 1357 deletions

View file

@ -0,0 +1,51 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/rfkill-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: GPIO controlled rfkill switch
maintainers:
- Johannes Berg <johannes@sipsolutions.net>
- Philipp Zabel <p.zabel@pengutronix.de>
properties:
compatible:
const: rfkill-gpio
label:
description: rfkill switch name, defaults to node name
radio-type:
description: rfkill radio type
enum:
- bluetooth
- fm
- gps
- nfc
- ultrawideband
- wimax
- wlan
- wwan
shutdown-gpios:
maxItems: 1
required:
- compatible
- radio-type
- shutdown-gpios
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
rfkill {
compatible = "rfkill-gpio";
label = "rfkill-pcie-wlan";
radio-type = "wlan";
shutdown-gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>;
};

View file

@ -55,3 +55,4 @@ int x509_load_certificate_list(const u8 cert_list[],
pr_err("Problem parsing in-kernel X.509 certificate list\n");
return 0;
}
EXPORT_SYMBOL_GPL(x509_load_certificate_list);

View file

@ -3853,8 +3853,8 @@ ath11k_wmi_obss_color_collision_event(struct ath11k_base *ab, struct sk_buff *sk
switch (ev->evt_type) {
case WMI_BSS_COLOR_COLLISION_DETECTION:
ieeee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap,
GFP_KERNEL);
ieee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap,
GFP_KERNEL);
ath11k_dbg(ab, ATH11K_DBG_WMI,
"OBSS color collision detected vdev:%d, event:%d, bitmap:%08llx\n",
ev->vdev_id, ev->evt_type, ev->obss_color_bitmap);

View file

@ -299,6 +299,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
err);
goto done;
}
buf[sizeof(buf) - 1] = '\0';
ptr = (char *)buf;
strsep(&ptr, "\n");
@ -319,15 +320,17 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
if (err) {
brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
} else {
buf[sizeof(buf) - 1] = '\0';
clmver = (char *)buf;
/* store CLM version for adding it to revinfo debugfs file */
memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
/* Replace all newline/linefeed characters with space
* character
*/
strreplace(clmver, '\n', ' ');
/* store CLM version for adding it to revinfo debugfs file */
memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
brcmf_dbg(INFO, "CLM version = %s\n", clmver);
}

View file

@ -336,6 +336,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
bphy_err(drvr, "%s: failed to expand headroom\n",
brcmf_ifname(ifp));
atomic_inc(&drvr->bus_if->stats.pktcow_failed);
dev_kfree_skb(skb);
goto done;
}
}

View file

@ -347,8 +347,11 @@ brcmf_msgbuf_alloc_pktid(struct device *dev,
count++;
} while (count < pktids->array_size);
if (count == pktids->array_size)
if (count == pktids->array_size) {
dma_unmap_single(dev, *physaddr, skb->len - data_offset,
pktids->direction);
return -ENOMEM;
}
array[*idx].data_offset = data_offset;
array[*idx].physaddr = *physaddr;

View file

@ -3427,7 +3427,7 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
dma_unmap_single(&priv->pci_dev->dev,
rxq->pool[i].dma_addr,
IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
dev_kfree_skb(rxq->pool[i].skb);
dev_kfree_skb_irq(rxq->pool[i].skb);
rxq->pool[i].skb = NULL;
}
list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
@ -11383,9 +11383,14 @@ static int ipw_wdev_init(struct net_device *dev)
set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
/* With that information in place, we can now register the wiphy... */
if (wiphy_register(wdev->wiphy))
rc = -EIO;
rc = wiphy_register(wdev->wiphy);
if (rc)
goto out;
return 0;
out:
kfree(priv->ieee->a_band.channels);
kfree(priv->ieee->bg_band.channels);
return rc;
}

View file

@ -5174,7 +5174,7 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));
/* new association get rid of ibss beacon skb */
dev_kfree_skb(il->beacon_skb);
dev_consume_skb_irq(il->beacon_skb);
il->beacon_skb = NULL;
il->timestamp = 0;
@ -5293,7 +5293,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
}
spin_lock_irqsave(&il->lock, flags);
dev_kfree_skb(il->beacon_skb);
dev_consume_skb_irq(il->beacon_skb);
il->beacon_skb = skb;
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;

View file

@ -931,6 +931,8 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
err = hermes_write_wordrec(hw, USER_BAP,
HERMES_RID_CNFAUTHENTICATION_AGERE,
auth_flag);
if (err)
return err;
}
err = hermes_write_wordrec(hw, USER_BAP,
HERMES_RID_CNFWEPENABLED_AGERE,

View file

@ -48,7 +48,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv,
/* Free Tx and Rx packets */
spin_lock_irqsave(&priv->driver_lock, flags);
kfree_skb(priv->currenttxskb);
dev_kfree_skb_irq(priv->currenttxskb);
priv->currenttxskb = NULL;
priv->tx_pending_len = 0;
spin_unlock_irqrestore(&priv->driver_lock, flags);

View file

@ -637,7 +637,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN);
memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN,
priv->resp_len[i]);
kfree_skb(skb);
dev_kfree_skb_irq(skb);
lbs_notify_command_response(priv, i);
spin_unlock_irqrestore(&priv->driver_lock, flags);

View file

@ -216,7 +216,7 @@ int lbs_stop_iface(struct lbs_private *priv)
spin_lock_irqsave(&priv->driver_lock, flags);
priv->iface_running = false;
kfree_skb(priv->currenttxskb);
dev_kfree_skb_irq(priv->currenttxskb);
priv->currenttxskb = NULL;
priv->tx_pending_len = 0;
spin_unlock_irqrestore(&priv->driver_lock, flags);
@ -869,6 +869,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
if (ret) {
pr_err("Out of memory allocating event FIFO buffer\n");
lbs_free_cmd_buffer(priv);
goto out;
}

View file

@ -613,7 +613,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
spin_lock_irqsave(&priv->driver_lock, flags);
memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
recvlength - MESSAGE_HEADER_LEN);
kfree_skb(skb);
dev_kfree_skb_irq(skb);
lbtf_cmd_response_rx(priv);
spin_unlock_irqrestore(&priv->driver_lock, flags);
}

View file

@ -112,7 +112,7 @@ mt76_register_debugfs_fops(struct mt76_phy *phy,
if (!dir)
return NULL;
debugfs_create_u8("led_pin", 0600, dir, &dev->led_pin);
debugfs_create_u8("led_pin", 0600, dir, &phy->leds.pin);
debugfs_create_u32("regidx", 0600, dir, &dev->debugfs_reg);
debugfs_create_file_unsafe("regval", 0600, dir, dev, fops);
debugfs_create_file_unsafe("napi_threaded", 0600, dir, dev,

View file

@ -582,23 +582,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
return ret;
}
static struct page_frag_cache *
mt76_dma_rx_get_frag_cache(struct mt76_dev *dev, struct mt76_queue *q)
{
struct page_frag_cache *rx_page = &q->rx_page;
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
if ((q->flags & MT_QFLAG_WED) &&
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX)
rx_page = &dev->mmio.wed.rx_buf_ring.rx_page;
#endif
return rx_page;
}
static int
mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
{
struct page_frag_cache *rx_page = mt76_dma_rx_get_frag_cache(dev, q);
int len = SKB_WITH_OVERHEAD(q->buf_size);
int frames = 0, offset = q->buf_offset;
dma_addr_t addr;
@ -612,7 +598,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
struct mt76_queue_buf qbuf;
void *buf = NULL;
buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC);
buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
if (!buf)
break;

View file

@ -192,42 +192,48 @@ static const struct cfg80211_sar_capa mt76_sar_capa = {
.freq_ranges = &mt76_sar_freq_ranges[0],
};
static int mt76_led_init(struct mt76_dev *dev)
static int mt76_led_init(struct mt76_phy *phy)
{
struct device_node *np = dev->dev->of_node;
struct ieee80211_hw *hw = dev->hw;
int led_pin;
struct mt76_dev *dev = phy->dev;
struct ieee80211_hw *hw = phy->hw;
if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set)
if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set)
return 0;
snprintf(dev->led_name, sizeof(dev->led_name),
"mt76-%s", wiphy_name(hw->wiphy));
snprintf(phy->leds.name, sizeof(phy->leds.name), "mt76-%s",
wiphy_name(hw->wiphy));
dev->led_cdev.name = dev->led_name;
dev->led_cdev.default_trigger =
phy->leds.cdev.name = phy->leds.name;
phy->leds.cdev.default_trigger =
ieee80211_create_tpt_led_trigger(hw,
IEEE80211_TPT_LEDTRIG_FL_RADIO,
mt76_tpt_blink,
ARRAY_SIZE(mt76_tpt_blink));
np = of_get_child_by_name(np, "led");
if (np) {
if (!of_property_read_u32(np, "led-sources", &led_pin))
dev->led_pin = led_pin;
dev->led_al = of_property_read_bool(np, "led-active-low");
of_node_put(np);
if (phy == &dev->phy) {
struct device_node *np = dev->dev->of_node;
np = of_get_child_by_name(np, "led");
if (np) {
int led_pin;
if (!of_property_read_u32(np, "led-sources", &led_pin))
phy->leds.pin = led_pin;
phy->leds.al = of_property_read_bool(np,
"led-active-low");
of_node_put(np);
}
}
return led_classdev_register(dev->dev, &dev->led_cdev);
return led_classdev_register(dev->dev, &phy->leds.cdev);
}
static void mt76_led_cleanup(struct mt76_dev *dev)
static void mt76_led_cleanup(struct mt76_phy *phy)
{
if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set)
if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set)
return;
led_classdev_unregister(&dev->led_cdev);
led_classdev_unregister(&phy->leds.cdev);
}
static void mt76_init_stream_cap(struct mt76_phy *phy,
@ -517,6 +523,12 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht,
return ret;
}
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
ret = mt76_led_init(phy);
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);
@ -536,6 +548,8 @@ void mt76_unregister_phy(struct mt76_phy *phy)
{
struct mt76_dev *dev = phy->dev;
if (IS_ENABLED(CONFIG_MT76_LEDS))
mt76_led_cleanup(phy);
mt76_tx_status_check(dev, true);
ieee80211_unregister_hw(phy->hw);
dev->phys[phy->band_idx] = NULL;
@ -653,7 +667,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
mt76_check_sband(&dev->phy, &phy->sband_6g, NL80211_BAND_6GHZ);
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
ret = mt76_led_init(dev);
ret = mt76_led_init(phy);
if (ret)
return ret;
}
@ -674,7 +688,7 @@ void mt76_unregister_device(struct mt76_dev *dev)
struct ieee80211_hw *hw = dev->hw;
if (IS_ENABLED(CONFIG_MT76_LEDS))
mt76_led_cleanup(dev);
mt76_led_cleanup(&dev->phy);
mt76_tx_status_check(dev, true);
ieee80211_unregister_hw(hw);
}

View file

@ -731,6 +731,13 @@ struct mt76_phy {
} rx_amsdu[__MT_RXQ_MAX];
struct mt76_freq_range_power *frp;
struct {
struct led_classdev cdev;
char name[32];
bool al;
u8 pin;
} leds;
};
struct mt76_dev {
@ -812,11 +819,6 @@ struct mt76_dev {
u32 debugfs_reg;
struct led_classdev led_cdev;
char led_name[32];
bool led_al;
u8 led_pin;
u8 csa_complete;
u32 rxfilter;

View file

@ -330,10 +330,10 @@ static const struct ieee80211_iface_combination if_comb[] = {
}
};
static void mt7603_led_set_config(struct mt76_dev *mt76, u8 delay_on,
static void mt7603_led_set_config(struct mt76_phy *mphy, u8 delay_on,
u8 delay_off)
{
struct mt7603_dev *dev = container_of(mt76, struct mt7603_dev,
struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev,
mt76);
u32 val, addr;
@ -341,15 +341,15 @@ static void mt7603_led_set_config(struct mt76_dev *mt76, u8 delay_on,
FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
FIELD_PREP(MT_LED_STATUS_ON, delay_on);
addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mt76->led_pin));
addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mphy->leds.pin));
mt76_wr(dev, addr, val);
addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mt76->led_pin));
addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mphy->leds.pin));
mt76_wr(dev, addr, val);
val = MT_LED_CTRL_REPLAY(mt76->led_pin) |
MT_LED_CTRL_KICK(mt76->led_pin);
if (mt76->led_al)
val |= MT_LED_CTRL_POLARITY(mt76->led_pin);
val = MT_LED_CTRL_REPLAY(mphy->leds.pin) |
MT_LED_CTRL_KICK(mphy->leds.pin);
if (mphy->leds.al)
val |= MT_LED_CTRL_POLARITY(mphy->leds.pin);
addr = mt7603_reg_map(dev, MT_LED_CTRL);
mt76_wr(dev, addr, val);
}
@ -358,27 +358,27 @@ static int mt7603_led_set_blink(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
led_cdev);
struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
leds.cdev);
u8 delta_on, delta_off;
delta_off = max_t(u8, *delay_off / 10, 1);
delta_on = max_t(u8, *delay_on / 10, 1);
mt7603_led_set_config(mt76, delta_on, delta_off);
mt7603_led_set_config(mphy, delta_on, delta_off);
return 0;
}
static void mt7603_led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
led_cdev);
struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
leds.cdev);
if (!brightness)
mt7603_led_set_config(mt76, 0, 0xff);
mt7603_led_set_config(mphy, 0, 0xff);
else
mt7603_led_set_config(mt76, 0xff, 0);
mt7603_led_set_config(mphy, 0xff, 0);
}
static u32 __mt7603_reg_addr(struct mt7603_dev *dev, u32 addr)
@ -535,8 +535,8 @@ int mt7603_register_device(struct mt7603_dev *dev)
/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
dev->mt76.led_cdev.brightness_set = mt7603_led_set_brightness;
dev->mt76.led_cdev.blink_set = mt7603_led_set_blink;
dev->mphy.leds.cdev.brightness_set = mt7603_led_set_brightness;
dev->mphy.leds.cdev.blink_set = mt7603_led_set_blink;
}
wiphy->reg_notifier = mt7603_regd_notifier;

View file

@ -443,6 +443,85 @@ mt7615_cap_dbdc_disable(struct mt7615_dev *dev)
mt76_set_stream_caps(&dev->mphy, true);
}
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr)
{
u32 base, offset;
if (is_mt7663(&dev->mt76)) {
base = addr & MT7663_MCU_PCIE_REMAP_2_BASE;
offset = addr & MT7663_MCU_PCIE_REMAP_2_OFFSET;
} else {
base = addr & MT_MCU_PCIE_REMAP_2_BASE;
offset = addr & MT_MCU_PCIE_REMAP_2_OFFSET;
}
mt76_wr(dev, MT_MCU_PCIE_REMAP_2, base);
return MT_PCIE_REMAP_BASE_2 + offset;
}
EXPORT_SYMBOL_GPL(mt7615_reg_map);
static void
mt7615_led_set_config(struct led_classdev *led_cdev,
u8 delay_on, u8 delay_off)
{
struct mt7615_dev *dev;
struct mt76_phy *mphy;
u32 val, addr;
u8 index;
mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);
dev = container_of(mphy->dev, struct mt7615_dev, mt76);
if (!mt76_connac_pm_ref(mphy, &dev->pm))
return;
val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
FIELD_PREP(MT_LED_STATUS_ON, delay_on);
index = dev->dbdc_support ? mphy->band_idx : mphy->leds.pin;
addr = mt7615_reg_map(dev, MT_LED_STATUS_0(index));
mt76_wr(dev, addr, val);
addr = mt7615_reg_map(dev, MT_LED_STATUS_1(index));
mt76_wr(dev, addr, val);
val = MT_LED_CTRL_REPLAY(index) | MT_LED_CTRL_KICK(index);
if (dev->mphy.leds.al)
val |= MT_LED_CTRL_POLARITY(index);
if (mphy->band_idx)
val |= MT_LED_CTRL_BAND(index);
addr = mt7615_reg_map(dev, MT_LED_CTRL);
mt76_wr(dev, addr, val);
mt76_connac_pm_unref(mphy, &dev->pm);
}
int mt7615_led_set_blink(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
u8 delta_on, delta_off;
delta_off = max_t(u8, *delay_off / 10, 1);
delta_on = max_t(u8, *delay_on / 10, 1);
mt7615_led_set_config(led_cdev, delta_on, delta_off);
return 0;
}
EXPORT_SYMBOL_GPL(mt7615_led_set_blink);
void mt7615_led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
if (!brightness)
mt7615_led_set_config(led_cdev, 0, 0xff);
else
mt7615_led_set_config(led_cdev, 0xff, 0);
}
EXPORT_SYMBOL_GPL(mt7615_led_set_brightness);
int mt7615_register_ext_phy(struct mt7615_dev *dev)
{
struct mt7615_phy *phy = mt7615_ext_phy(dev);
@ -497,6 +576,12 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
for (i = 0; i <= MT_TXQ_PSD ; i++)
mphy->q_tx[i] = dev->mphy.q_tx[i];
/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
mphy->leds.cdev.brightness_set = mt7615_led_set_brightness;
mphy->leds.cdev.blink_set = mt7615_led_set_blink;
}
ret = mt76_register_phy(mphy, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)

View file

@ -63,22 +63,6 @@ const u32 mt7663e_reg_map[] = {
[MT_EFUSE_ADDR_BASE] = 0x78011000,
};
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr)
{
u32 base, offset;
if (is_mt7663(&dev->mt76)) {
base = addr & MT7663_MCU_PCIE_REMAP_2_BASE;
offset = addr & MT7663_MCU_PCIE_REMAP_2_OFFSET;
} else {
base = addr & MT_MCU_PCIE_REMAP_2_BASE;
offset = addr & MT_MCU_PCIE_REMAP_2_OFFSET;
}
mt76_wr(dev, MT_MCU_PCIE_REMAP_2, base);
return MT_PCIE_REMAP_BASE_2 + offset;
}
static void
mt7615_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
{

View file

@ -376,6 +376,12 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
int irq, const u32 *map);
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);
int mt7615_led_set_blink(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off);
void mt7615_led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness);
void mt7615_init_device(struct mt7615_dev *dev);
int mt7615_register_device(struct mt7615_dev *dev);
void mt7615_unregister_device(struct mt7615_dev *dev);

View file

@ -66,64 +66,6 @@ static int mt7615_init_hardware(struct mt7615_dev *dev)
return 0;
}
static void
mt7615_led_set_config(struct led_classdev *led_cdev,
u8 delay_on, u8 delay_off)
{
struct mt7615_dev *dev;
struct mt76_dev *mt76;
u32 val, addr;
mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
dev = container_of(mt76, struct mt7615_dev, mt76);
if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm))
return;
val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
FIELD_PREP(MT_LED_STATUS_ON, delay_on);
addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mt76->led_pin));
mt76_wr(dev, addr, val);
addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mt76->led_pin));
mt76_wr(dev, addr, val);
val = MT_LED_CTRL_REPLAY(mt76->led_pin) |
MT_LED_CTRL_KICK(mt76->led_pin);
if (mt76->led_al)
val |= MT_LED_CTRL_POLARITY(mt76->led_pin);
addr = mt7615_reg_map(dev, MT_LED_CTRL);
mt76_wr(dev, addr, val);
mt76_connac_pm_unref(&dev->mphy, &dev->pm);
}
static int
mt7615_led_set_blink(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
u8 delta_on, delta_off;
delta_off = max_t(u8, *delay_off / 10, 1);
delta_on = max_t(u8, *delay_on / 10, 1);
mt7615_led_set_config(led_cdev, delta_on, delta_off);
return 0;
}
static void
mt7615_led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
if (!brightness)
mt7615_led_set_config(led_cdev, 0, 0xff);
else
mt7615_led_set_config(led_cdev, 0xff, 0);
}
int mt7615_register_device(struct mt7615_dev *dev)
{
int ret;
@ -133,8 +75,8 @@ int mt7615_register_device(struct mt7615_dev *dev)
/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
dev->mt76.led_cdev.brightness_set = mt7615_led_set_brightness;
dev->mt76.led_cdev.blink_set = mt7615_led_set_blink;
dev->mphy.leds.cdev.brightness_set = mt7615_led_set_brightness;
dev->mphy.leds.cdev.blink_set = mt7615_led_set_blink;
}
ret = mt7622_wmac_init(dev);

View file

@ -544,6 +544,7 @@ enum mt7615_reg_base {
#define MT_LED_CTRL_POLARITY(_n) BIT(1 + (8 * (_n)))
#define MT_LED_CTRL_TX_BLINK_MODE(_n) BIT(2 + (8 * (_n)))
#define MT_LED_CTRL_TX_MANUAL_BLINK(_n) BIT(3 + (8 * (_n)))
#define MT_LED_CTRL_BAND(_n) BIT(4 + (8 * (_n)))
#define MT_LED_CTRL_TX_OVER_BLINK(_n) BIT(5 + (8 * (_n)))
#define MT_LED_CTRL_KICK(_n) BIT(7 + (8 * (_n)))

View file

@ -930,7 +930,7 @@ int mt76_connac2_reverse_frag0_hdr_trans(struct ieee80211_vif *vif,
ether_addr_copy(hdr.addr4, eth_hdr->h_source);
break;
default:
break;
return -EINVAL;
}
skb_pull(skb, hdr_offset + sizeof(struct ethhdr) - 2);

View file

@ -642,7 +642,12 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
if (tx_rate > 9)
return -EINVAL;
*target_power = cur_power + dev->rate_power.vht[tx_rate];
*target_power = cur_power;
if (tx_rate > 7)
*target_power += dev->rate_power.vht[tx_rate - 8];
else
*target_power += dev->rate_power.ht[tx_rate];
*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
break;
default:

View file

@ -87,10 +87,9 @@ static const struct ieee80211_iface_combination mt76x02u_if_comb[] = {
};
static void
mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on,
u8 delay_off)
mt76x02_led_set_config(struct mt76_phy *mphy, u8 delay_on, u8 delay_off)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev,
struct mt76x02_dev *dev = container_of(mphy->dev, struct mt76x02_dev,
mt76);
u32 val;
@ -98,13 +97,13 @@ mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on,
FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
FIELD_PREP(MT_LED_STATUS_ON, delay_on);
mt76_wr(dev, MT_LED_S0(mdev->led_pin), val);
mt76_wr(dev, MT_LED_S1(mdev->led_pin), val);
mt76_wr(dev, MT_LED_S0(mphy->leds.pin), val);
mt76_wr(dev, MT_LED_S1(mphy->leds.pin), val);
val = MT_LED_CTRL_REPLAY(mdev->led_pin) |
MT_LED_CTRL_KICK(mdev->led_pin);
if (mdev->led_al)
val |= MT_LED_CTRL_POLARITY(mdev->led_pin);
val = MT_LED_CTRL_REPLAY(mphy->leds.pin) |
MT_LED_CTRL_KICK(mphy->leds.pin);
if (mphy->leds.al)
val |= MT_LED_CTRL_POLARITY(mphy->leds.pin);
mt76_wr(dev, MT_LED_CTRL, val);
}
@ -113,14 +112,14 @@ mt76x02_led_set_blink(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev,
led_cdev);
struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
leds.cdev);
u8 delta_on, delta_off;
delta_off = max_t(u8, *delay_off / 10, 1);
delta_on = max_t(u8, *delay_on / 10, 1);
mt76x02_led_set_config(mdev, delta_on, delta_off);
mt76x02_led_set_config(mphy, delta_on, delta_off);
return 0;
}
@ -129,13 +128,13 @@ static void
mt76x02_led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev,
led_cdev);
struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
leds.cdev);
if (!brightness)
mt76x02_led_set_config(mdev, 0, 0xff);
mt76x02_led_set_config(mphy, 0, 0xff);
else
mt76x02_led_set_config(mdev, 0xff, 0);
mt76x02_led_set_config(mphy, 0xff, 0);
}
int mt76x02_init_device(struct mt76x02_dev *dev)
@ -167,9 +166,9 @@ int mt76x02_init_device(struct mt76x02_dev *dev)
/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
dev->mt76.led_cdev.brightness_set =
dev->mphy.leds.cdev.brightness_set =
mt76x02_led_set_brightness;
dev->mt76.led_cdev.blink_set = mt76x02_led_set_blink;
dev->mphy.leds.cdev.blink_set = mt76x02_led_set_blink;
}
}

View file

@ -811,7 +811,7 @@ mt7915_hw_queue_read(struct seq_file *s, u32 size,
if (val & BIT(map[i].index))
continue;
ctrl = BIT(31) | (map[i].pid << 10) | (map[i].qid << 24);
ctrl = BIT(31) | (map[i].pid << 10) | ((u32)map[i].qid << 24);
mt76_wr(dev, MT_FL_Q0_CTRL, ctrl);
head = mt76_get_field(dev, MT_FL_Q2_CTRL,
@ -996,7 +996,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr));
if (ret)
return ret;
goto out;
/* Txpower propagation path: TMAC -> TXV -> BBP */
len += scnprintf(buf + len, sz - len,
@ -1047,6 +1047,8 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER));
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
out:
kfree(buf);
return ret;
}

View file

@ -110,18 +110,23 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
} else {
u8 free_block_num;
u32 block_num, i;
u32 eeprom_blk_size = MT7915_EEPROM_BLOCK_SIZE;
mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);
/* efuse info not enough */
ret = mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);
if (ret < 0)
return ret;
/* efuse info isn't enough */
if (free_block_num >= 29)
return -EINVAL;
/* read eeprom data from efuse */
block_num = DIV_ROUND_UP(eeprom_size,
MT7915_EEPROM_BLOCK_SIZE);
for (i = 0; i < block_num; i++)
mt7915_mcu_get_eeprom(dev,
i * MT7915_EEPROM_BLOCK_SIZE);
block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);
for (i = 0; i < block_num; i++) {
ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size);
if (ret < 0)
return ret;
}
}
return mt7915_check_eeprom(dev);

View file

@ -209,30 +209,31 @@ static void mt7915_led_set_config(struct led_classdev *led_cdev,
u8 delay_on, u8 delay_off)
{
struct mt7915_dev *dev;
struct mt76_dev *mt76;
struct mt76_phy *mphy;
u32 val;
mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
dev = container_of(mt76, struct mt7915_dev, mt76);
mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);
dev = container_of(mphy->dev, struct mt7915_dev, mt76);
/* select TX blink mode, 2: only data frames */
mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2);
/* set PWM mode */
val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
FIELD_PREP(MT_LED_STATUS_ON, delay_on);
mt76_wr(dev, MT_LED_STATUS_0(mphy->band_idx), val);
mt76_wr(dev, MT_LED_STATUS_1(mphy->band_idx), val);
/* enable LED */
mt76_wr(dev, MT_LED_EN(0), 1);
/* set LED Tx blink on/off time */
val = FIELD_PREP(MT_LED_TX_BLINK_ON_MASK, delay_on) |
FIELD_PREP(MT_LED_TX_BLINK_OFF_MASK, delay_off);
mt76_wr(dev, MT_LED_TX_BLINK(0), val);
mt76_wr(dev, MT_LED_EN(mphy->band_idx), 1);
/* control LED */
val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
if (dev->mt76.led_al)
val = MT_LED_CTRL_KICK;
if (dev->mphy.leds.al)
val |= MT_LED_CTRL_POLARITY;
if (mphy->band_idx)
val |= MT_LED_CTRL_BAND;
mt76_wr(dev, MT_LED_CTRL(0), val);
mt76_clear(dev, MT_LED_CTRL(0), MT_LED_CTRL_KICK);
mt76_wr(dev, MT_LED_CTRL(mphy->band_idx), val);
mt76_clear(dev, MT_LED_CTRL(mphy->band_idx), MT_LED_CTRL_KICK);
}
static int mt7915_led_set_blink(struct led_classdev *led_cdev,
@ -319,9 +320,10 @@ mt7915_regd_notifier(struct wiphy *wiphy,
}
static void
mt7915_init_wiphy(struct ieee80211_hw *hw)
mt7915_init_wiphy(struct mt7915_phy *phy)
{
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt76_phy *mphy = phy->mt76;
struct ieee80211_hw *hw = mphy->hw;
struct mt76_dev *mdev = &phy->dev->mt76;
struct wiphy *wiphy = hw->wiphy;
struct mt7915_dev *dev = phy->dev;
@ -415,6 +417,12 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
wiphy->available_antennas_rx = phy->mt76->antenna_mask;
wiphy->available_antennas_tx = phy->mt76->antenna_mask;
/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
mphy->leds.cdev.brightness_set = mt7915_led_set_brightness;
mphy->leds.cdev.blink_set = mt7915_led_set_blink;
}
}
static void
@ -473,6 +481,72 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
}
static void
mt7915_init_led_mux(struct mt7915_dev *dev)
{
if (!IS_ENABLED(CONFIG_MT76_LEDS))
return;
if (dev->dbdc_support) {
switch (mt76_chip(&dev->mt76)) {
case 0x7915:
mt76_rmw_field(dev, MT_LED_GPIO_MUX2,
GENMASK(11, 8), 4);
mt76_rmw_field(dev, MT_LED_GPIO_MUX3,
GENMASK(11, 8), 4);
break;
case 0x7986:
mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
GENMASK(7, 4), 1);
mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
GENMASK(11, 8), 1);
break;
case 0x7916:
mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
GENMASK(27, 24), 3);
mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
GENMASK(31, 28), 3);
break;
default:
break;
}
} else if (dev->mphy.leds.pin) {
switch (mt76_chip(&dev->mt76)) {
case 0x7915:
mt76_rmw_field(dev, MT_LED_GPIO_MUX3,
GENMASK(11, 8), 4);
break;
case 0x7986:
mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
GENMASK(11, 8), 1);
break;
case 0x7916:
mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
GENMASK(31, 28), 3);
break;
default:
break;
}
} else {
switch (mt76_chip(&dev->mt76)) {
case 0x7915:
mt76_rmw_field(dev, MT_LED_GPIO_MUX2,
GENMASK(11, 8), 4);
break;
case 0x7986:
mt76_rmw_field(dev, MT_LED_GPIO_MUX0,
GENMASK(7, 4), 1);
break;
case 0x7916:
mt76_rmw_field(dev, MT_LED_GPIO_MUX1,
GENMASK(27, 24), 3);
break;
default:
break;
}
}
}
void mt7915_mac_init(struct mt7915_dev *dev)
{
int i;
@ -497,10 +571,7 @@ void mt7915_mac_init(struct mt7915_dev *dev)
for (i = 0; i < 2; i++)
mt7915_mac_init_band(dev, i);
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
i = dev->mt76.led_pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;
mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4);
}
mt7915_init_led_mux(dev);
}
int mt7915_txbf_init(struct mt7915_dev *dev)
@ -569,7 +640,7 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
mt76_eeprom_override(mphy);
/* init wiphy according to mphy and phy */
mt7915_init_wiphy(mphy->hw);
mt7915_init_wiphy(phy);
ret = mt76_register_phy(mphy, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
@ -1104,7 +1175,6 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
int mt7915_register_device(struct mt7915_dev *dev)
{
struct ieee80211_hw *hw = mt76_hw(dev);
struct mt7915_phy *phy2;
int ret;
@ -1133,18 +1203,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
if (ret)
goto free_phy2;
mt7915_init_wiphy(hw);
mt7915_init_wiphy(&dev->phy);
#ifdef CONFIG_NL80211_TESTMODE
dev->mt76.test_ops = &mt7915_testmode_ops;
#endif
/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
dev->mt76.led_cdev.brightness_set = mt7915_led_set_brightness;
dev->mt76.led_cdev.blink_set = mt7915_led_set_blink;
}
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)

View file

@ -232,8 +232,11 @@ mt7915_mcu_rx_csa_notify(struct mt7915_dev *dev, struct sk_buff *skb)
c = (struct mt7915_mcu_csa_notify *)skb->data;
if (c->band_idx > MT_BAND1)
return;
if ((c->band_idx && !dev->phy.mt76->band_idx) &&
dev->mt76.phys[MT_BAND1])
dev->mt76.phys[MT_BAND1])
mphy = dev->mt76.phys[MT_BAND1];
ieee80211_iterate_active_interfaces_atomic(mphy->hw,
@ -252,8 +255,11 @@ mt7915_mcu_rx_thermal_notify(struct mt7915_dev *dev, struct sk_buff *skb)
if (t->ctrl.ctrl_id != THERMAL_PROTECT_ENABLE)
return;
if (t->ctrl.band_idx > MT_BAND1)
return;
if ((t->ctrl.band_idx && !dev->phy.mt76->band_idx) &&
dev->mt76.phys[MT_BAND1])
dev->mt76.phys[MT_BAND1])
mphy = dev->mt76.phys[MT_BAND1];
phy = (struct mt7915_phy *)mphy->priv;
@ -268,8 +274,11 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
r = (struct mt7915_mcu_rdd_report *)skb->data;
if (r->band_idx > MT_BAND1)
return;
if ((r->band_idx && !dev->phy.mt76->band_idx) &&
dev->mt76.phys[MT_BAND1])
dev->mt76.phys[MT_BAND1])
mphy = dev->mt76.phys[MT_BAND1];
if (r->band_idx == MT_RX_SEL2)
@ -326,7 +335,11 @@ mt7915_mcu_rx_bcc_notify(struct mt7915_dev *dev, struct sk_buff *skb)
b = (struct mt7915_mcu_bcc_notify *)skb->data;
if ((b->band_idx && !dev->phy.mt76->band_idx) && dev->mt76.phys[MT_BAND1])
if (b->band_idx > MT_BAND1)
return;
if ((b->band_idx && !dev->phy.mt76->band_idx) &&
dev->mt76.phys[MT_BAND1])
mphy = dev->mt76.phys[MT_BAND1];
ieee80211_iterate_active_interfaces_atomic(mphy->hw,
@ -2792,8 +2805,9 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
int ret;
u8 *buf;
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_ACCESS), &req,
sizeof(req), true, &skb);
ret = mt76_mcu_send_and_get_msg(&dev->mt76,
MCU_EXT_QUERY(EFUSE_ACCESS),
&req, sizeof(req), true, &skb);
if (ret)
return ret;
@ -2818,8 +2832,9 @@ int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num)
struct sk_buff *skb;
int ret;
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_FREE_BLOCK), &req,
sizeof(req), true, &skb);
ret = mt76_mcu_send_and_get_msg(&dev->mt76,
MCU_EXT_QUERY(EFUSE_FREE_BLOCK),
&req, sizeof(req), true, &skb);
if (ret)
return ret;
@ -2974,38 +2989,42 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
{
/* strict order */
static const u32 offs[] = {
MIB_NON_WIFI_TIME,
MIB_TX_TIME,
MIB_RX_TIME,
MIB_OBSS_AIRTIME,
MIB_TXOP_INIT_COUNT,
/* v2 */
MIB_NON_WIFI_TIME_V2,
MIB_TX_TIME_V2,
MIB_RX_TIME_V2,
MIB_OBSS_AIRTIME_V2
};
struct mt76_channel_state *state = phy->mt76->chan_state;
struct mt76_channel_state *state_ts = &phy->state_ts;
struct mt7915_dev *dev = phy->dev;
struct mt7915_mcu_mib *res, req[5];
struct sk_buff *skb;
int i, ret, start = 0, ofs = 20;
static const u32 *offs;
int i, ret, len, offs_cc;
u64 cc_tx;
if (!is_mt7915(&dev->mt76)) {
start = 5;
ofs = 0;
/* strict order */
if (is_mt7915(&dev->mt76)) {
static const u32 chip_offs[] = {
MIB_NON_WIFI_TIME,
MIB_TX_TIME,
MIB_RX_TIME,
MIB_OBSS_AIRTIME,
MIB_TXOP_INIT_COUNT,
};
len = ARRAY_SIZE(chip_offs);
offs = chip_offs;
offs_cc = 20;
} else {
static const u32 chip_offs[] = {
MIB_NON_WIFI_TIME_V2,
MIB_TX_TIME_V2,
MIB_RX_TIME_V2,
MIB_OBSS_AIRTIME_V2
};
len = ARRAY_SIZE(chip_offs);
offs = chip_offs;
offs_cc = 0;
}
for (i = 0; i < 5; i++) {
for (i = 0; i < len; i++) {
req[i].band = cpu_to_le32(phy->mt76->band_idx);
req[i].offs = cpu_to_le32(offs[i + start]);
if (!is_mt7915(&dev->mt76) && i == 3)
break;
req[i].offs = cpu_to_le32(offs[i]);
}
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO),
@ -3013,7 +3032,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
if (ret)
return ret;
res = (struct mt7915_mcu_mib *)(skb->data + ofs);
res = (struct mt7915_mcu_mib *)(skb->data + offs_cc);
#define __res_u64(s) le64_to_cpu(res[s].data)
/* subtract Tx backoff time from Tx duration */

View file

@ -495,7 +495,7 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
if (dev_is_pci(dev->mt76.dev) &&
((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) ||
(addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END)))
addr >= MT_CBTOP2_PHY_START))
return mt7915_reg_map_l1(dev, addr);
/* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */
@ -594,10 +594,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
{
struct mt7915_dev *dev;
struct page *page;
u32 length;
int i;
dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
sizeof(struct skb_shared_info));
for (i = 0; i < dev->mt76.rx_token_size; i++) {
struct mt76_txwi_cache *t;
@ -607,18 +610,11 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
dma_unmap_single(dev->mt76.dma_dev, t->dma_addr,
wed->wlan.rx_size, DMA_FROM_DEVICE);
skb_free_frag(t->ptr);
__free_pages(virt_to_page(t->ptr), get_order(length));
t->ptr = NULL;
mt76_put_rxwi(&dev->mt76, t);
}
if (!wed->rx_buf_ring.rx_page.va)
return;
page = virt_to_page(wed->rx_buf_ring.rx_page.va);
__page_frag_cache_drain(page, wed->rx_buf_ring.rx_page.pagecnt_bias);
memset(&wed->rx_buf_ring.rx_page, 0, sizeof(wed->rx_buf_ring.rx_page));
}
static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
@ -635,19 +631,20 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
for (i = 0; i < size; i++) {
struct mt76_txwi_cache *t = mt76_get_rxwi(&dev->mt76);
dma_addr_t phy_addr;
struct page *page;
int token;
void *ptr;
ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
GFP_KERNEL);
if (!ptr)
page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
if (!page)
goto unmap;
ptr = page_address(page);
phy_addr = dma_map_single(dev->mt76.dma_dev, ptr,
wed->wlan.rx_size,
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
skb_free_frag(ptr);
__free_pages(page, get_order(length));
goto unmap;
}
@ -656,7 +653,7 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
if (token < 0) {
dma_unmap_single(dev->mt76.dma_dev, phy_addr,
wed->wlan.rx_size, DMA_TO_DEVICE);
skb_free_frag(ptr);
__free_pages(page, get_order(length));
goto unmap;
}

View file

@ -803,7 +803,6 @@ enum offs_rev {
#define MT_CBTOP1_PHY_START 0x70000000
#define MT_CBTOP1_PHY_END __REG(CBTOP1_PHY_END)
#define MT_CBTOP2_PHY_START 0xf0000000
#define MT_CBTOP2_PHY_END 0xffffffff
#define MT_INFRA_MCU_START 0x7c000000
#define MT_INFRA_MCU_END __REG(INFRA_MCU_ADDR_END)
#define MT_CONN_INFRA_OFFSET(p) ((p) - MT_INFRA_BASE)
@ -1055,6 +1054,7 @@ enum offs_rev {
#define MT_LED_CTRL(_n) MT_LED_PHYS(0x00 + ((_n) * 4))
#define MT_LED_CTRL_KICK BIT(7)
#define MT_LED_CTRL_BAND BIT(4)
#define MT_LED_CTRL_BLINK_MODE BIT(2)
#define MT_LED_CTRL_POLARITY BIT(1)
@ -1062,11 +1062,18 @@ enum offs_rev {
#define MT_LED_TX_BLINK_ON_MASK GENMASK(7, 0)
#define MT_LED_TX_BLINK_OFF_MASK GENMASK(15, 8)
#define MT_LED_STATUS_0(_n) MT_LED_PHYS(0x20 + ((_n) * 8))
#define MT_LED_STATUS_1(_n) MT_LED_PHYS(0x24 + ((_n) * 8))
#define MT_LED_STATUS_OFF GENMASK(31, 24)
#define MT_LED_STATUS_ON GENMASK(23, 16)
#define MT_LED_STATUS_DURATION GENMASK(15, 0)
#define MT_LED_EN(_n) MT_LED_PHYS(0x40 + ((_n) * 4))
#define MT_LED_GPIO_MUX0 0x70005050 /* GPIO 1 and GPIO 2 */
#define MT_LED_GPIO_MUX1 0x70005054 /* GPIO 14 and 15 */
#define MT_LED_GPIO_MUX2 0x70005058 /* GPIO 18 */
#define MT_LED_GPIO_MUX3 0x7000505C /* GPIO 26 */
#define MT_LED_GPIO_SEL_MASK GENMASK(11, 8)
#define MT_LED_GPIO_MUX3 0x7000505c /* GPIO 26 */
/* MT TOP */
#define MT_TOP_BASE 0x18060000

View file

@ -278,6 +278,7 @@ static int mt7986_wmac_coninfra_setup(struct mt7915_dev *dev)
return -EINVAL;
rmem = of_reserved_mem_lookup(np);
of_node_put(np);
if (!rmem)
return -EINVAL;

View file

@ -135,6 +135,22 @@ mt7921_asar_acpi_read_mtgs(struct mt7921_dev *dev, u8 **table, u8 version)
return ret;
}
/* MTFG : Flag Table */
static int
mt7921_asar_acpi_read_mtfg(struct mt7921_dev *dev, u8 **table)
{
int len, ret;
ret = mt7921_acpi_read(dev, MT7921_ACPI_MTFG, table, &len);
if (ret)
return ret;
if (len < MT7921_ASAR_MIN_FG)
ret = -EINVAL;
return ret;
}
int mt7921_init_acpi_sar(struct mt7921_dev *dev)
{
struct mt7921_acpi_sar *asar;
@ -162,6 +178,12 @@ int mt7921_init_acpi_sar(struct mt7921_dev *dev)
asar->geo = NULL;
}
/* MTFG is optional */
ret = mt7921_asar_acpi_read_mtfg(dev, (u8 **)&asar->fg);
if (ret) {
devm_kfree(dev->mt76.dev, asar->fg);
asar->fg = NULL;
}
dev->phy.acpisar = asar;
return 0;
@ -280,3 +302,36 @@ int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default)
return 0;
}
u8 mt7921_acpi_get_flags(struct mt7921_phy *phy)
{
struct mt7921_asar_fg *fg;
struct {
u8 acpi_idx;
u8 chip_idx;
} map[] = {
{1, 1},
{4, 2},
};
u8 flags = BIT(0);
int i, j;
if (!phy->acpisar)
return 0;
fg = phy->acpisar->fg;
if (!fg)
return flags;
/* pickup necessary settings per device and
* translate the index of bitmap for chip command.
*/
for (i = 0; i < fg->nr_flag; i++)
for (j = 0; j < ARRAY_SIZE(map); j++)
if (fg->flag[i] == map[j].acpi_idx) {
flags |= BIT(map[j].chip_idx);
break;
}
return flags;
}

View file

@ -8,10 +8,12 @@
#define MT7921_ASAR_MAX_DYN 8
#define MT7921_ASAR_MIN_GEO 3
#define MT7921_ASAR_MAX_GEO 8
#define MT7921_ASAR_MIN_FG 8
#define MT7921_ACPI_MTCL "MTCL"
#define MT7921_ACPI_MTDS "MTDS"
#define MT7921_ACPI_MTGS "MTGS"
#define MT7921_ACPI_MTFG "MTFG"
struct mt7921_asar_dyn_limit {
u8 idx;
@ -77,6 +79,15 @@ struct mt7921_asar_cl {
u8 cl6g[6];
} __packed;
struct mt7921_asar_fg {
u8 names[4];
u8 version;
u8 rsvd;
u8 nr_flag;
u8 rsvd1;
u8 flag[0];
} __packed;
struct mt7921_acpi_sar {
u8 ver;
union {
@ -88,6 +99,7 @@ struct mt7921_acpi_sar {
struct mt7921_asar_geo_v2 *geo_v2;
};
struct mt7921_asar_cl *countrylist;
struct mt7921_asar_fg *fg;
};
#endif

View file

@ -175,7 +175,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
dev_err(dev, "Invalid firmware\n");
return -EINVAL;
goto out;
}
data = fw->data;
@ -206,6 +206,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm)
data += le16_to_cpu(rel_info->len) + rel_info->pad_len;
}
out:
release_firmware(fw);
return features ? features->data : 0;

View file

@ -1184,13 +1184,15 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
__le16 len;
u8 idx;
u8 env;
u8 pad1[2];
u8 acpi_conf;
u8 pad1;
u8 alpha2[2];
u8 type[2];
u8 rsvd[64];
} __packed req = {
.idx = idx,
.env = env_cap,
.acpi_conf = mt7921_acpi_get_flags(&dev->phy),
};
int ret, valid_cnt = 0;
u8 i, *pos;

View file

@ -554,6 +554,7 @@ int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
#ifdef CONFIG_ACPI
int mt7921_init_acpi_sar(struct mt7921_dev *dev);
int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default);
u8 mt7921_acpi_get_flags(struct mt7921_phy *phy);
#else
static inline int
mt7921_init_acpi_sar(struct mt7921_dev *dev)
@ -566,6 +567,12 @@ mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default)
{
return 0;
}
static inline u8
mt7921_acpi_get_flags(struct mt7921_phy *phy)
{
return 0;
}
#endif
int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);

View file

@ -457,7 +457,7 @@ mt7996_hw_queue_read(struct seq_file *s, u32 size,
if (val & BIT(map[i].index))
continue;
ctrl = BIT(31) | (map[i].pid << 10) | (map[i].qid << 24);
ctrl = BIT(31) | (map[i].pid << 10) | ((u32)map[i].qid << 24);
mt76_wr(dev, MT_FL_Q0_CTRL, ctrl);
head = mt76_get_field(dev, MT_FL_Q2_CTRL,
@ -653,8 +653,9 @@ static int
mt7996_rf_regval_set(void *data, u64 val)
{
struct mt7996_dev *dev = data;
u32 val32 = val;
return mt7996_mcu_rf_regval(dev, dev->mt76.debugfs_reg, (u32 *)&val, true);
return mt7996_mcu_rf_regval(dev, dev->mt76.debugfs_reg, &val32, true);
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7996_rf_regval_get,

View file

@ -65,17 +65,23 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
} else {
u8 free_block_num;
u32 block_num, i;
u32 eeprom_blk_size = MT7996_EEPROM_BLOCK_SIZE;
/* TODO: check free block event */
mt7996_mcu_get_eeprom_free_block(dev, &free_block_num);
/* efuse info not enough */
ret = mt7996_mcu_get_eeprom_free_block(dev, &free_block_num);
if (ret < 0)
return ret;
/* efuse info isn't enough */
if (free_block_num >= 59)
return -EINVAL;
/* read eeprom data from efuse */
block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, MT7996_EEPROM_BLOCK_SIZE);
for (i = 0; i < block_num; i++)
mt7996_mcu_get_eeprom(dev, i * MT7996_EEPROM_BLOCK_SIZE);
block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size);
for (i = 0; i < block_num; i++) {
ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size);
if (ret < 0)
return ret;
}
}
return mt7996_check_eeprom(dev);

View file

@ -46,11 +46,11 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev,
u8 delay_on, u8 delay_off)
{
struct mt7996_dev *dev;
struct mt76_dev *mt76;
struct mt76_phy *mphy;
u32 val;
mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
dev = container_of(mt76, struct mt7996_dev, mt76);
mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);
dev = container_of(mphy->dev, struct mt7996_dev, mt76);
/* select TX blink mode, 2: only data frames */
mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2);
@ -65,7 +65,7 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev,
/* control LED */
val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
if (dev->mt76.led_al)
if (mphy->leds.al)
val |= MT_LED_CTRL_POLARITY;
mt76_wr(dev, MT_LED_CTRL(0), val);
@ -261,7 +261,7 @@ static void mt7996_mac_init(struct mt7996_dev *dev)
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
i = dev->mt76.led_pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;
i = dev->mphy.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;
mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4);
}
@ -787,8 +787,8 @@ int mt7996_register_device(struct mt7996_dev *dev)
/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
dev->mt76.led_cdev.brightness_set = mt7996_led_set_brightness;
dev->mt76.led_cdev.blink_set = mt7996_led_set_blink;
dev->mphy.leds.cdev.brightness_set = mt7996_led_set_brightness;
dev->mphy.leds.cdev.blink_set = mt7996_led_set_blink;
}
ret = mt76_register_device(&dev->mt76, true, mt76_rates,

View file

@ -335,6 +335,9 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
r = (struct mt7996_mcu_rdd_report *)skb->data;
if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
return;
mphy = dev->mt76.phys[r->band_idx];
if (!mphy)
return;
@ -412,6 +415,9 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
struct header *hdr = (struct header *)data;
struct tlv *tlv = (struct tlv *)(data + 4);
if (hdr->band >= ARRAY_SIZE(dev->mt76.phys))
return;
if (hdr->band && dev->mt76.phys[hdr->band])
mphy = dev->mt76.phys[hdr->band];
@ -903,8 +909,8 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
he = (struct sta_rec_he_v2 *)tlv;
for (i = 0; i < 11; i++) {
if (i < 6)
he->he_mac_cap[i] = cpu_to_le16(elem->mac_cap_info[i]);
he->he_phy_cap[i] = cpu_to_le16(elem->phy_cap_info[i]);
he->he_mac_cap[i] = elem->mac_cap_info[i];
he->he_phy_cap[i] = elem->phy_cap_info[i];
}
mcs_map = sta->deflink.he_cap.he_mcs_nss_supp;
@ -2921,8 +2927,9 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset)
bool valid;
int ret;
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL), &req,
sizeof(req), true, &skb);
ret = mt76_mcu_send_and_get_msg(&dev->mt76,
MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL),
&req, sizeof(req), true, &skb);
if (ret)
return ret;

View file

@ -149,7 +149,7 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
if (dev_is_pci(dev->mt76.dev) &&
((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) ||
(addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END)))
addr >= MT_CBTOP2_PHY_START))
return mt7996_reg_map_l1(dev, addr);
/* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */

View file

@ -463,7 +463,6 @@ enum base_rev {
#define MT_CBTOP1_PHY_START 0x70000000
#define MT_CBTOP1_PHY_END 0x77ffffff
#define MT_CBTOP2_PHY_START 0xf0000000
#define MT_CBTOP2_PHY_END 0xffffffff
#define MT_INFRA_MCU_START 0x7c000000
#define MT_INFRA_MCU_END 0x7c3fffff

View file

@ -254,6 +254,10 @@ static int mt76s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q)
if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state)) {
__skb_put_zero(e->skb, 4);
err = __skb_grow(e->skb, roundup(e->skb->len,
sdio->func->cur_blksize));
if (err)
return err;
err = __mt76s_xmit_queue(dev, e->skb->data,
e->skb->len);
if (err)

View file

@ -123,7 +123,8 @@ static u16 mt7601u_rx_next_seg_len(u8 *data, u32 data_len)
if (data_len < min_seg_len ||
WARN_ON_ONCE(!dma_len) ||
WARN_ON_ONCE(dma_len + MT_DMA_HDRS > data_len) ||
WARN_ON_ONCE(dma_len & 0x3))
WARN_ON_ONCE(dma_len & 0x3) ||
WARN_ON_ONCE(dma_len < min_seg_len))
return 0;
return MT_DMA_HDRS + dma_len;

View file

@ -730,6 +730,7 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
if (skb->dev != ndev) {
netdev_err(ndev, "Packet not destined to this device\n");
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@ -980,7 +981,7 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
ndev->name);
if (!wl->hif_workqueue) {
ret = -ENOMEM;
goto error;
goto unregister_netdev;
}
ndev->needs_free_netdev = true;
@ -995,6 +996,11 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
return vif;
unregister_netdev:
if (rtnl_locked)
cfg80211_unregister_netdevice(ndev);
else
unregister_netdev(ndev);
error:
free_netdev(ndev);
return ERR_PTR(ret);

View file

@ -8924,8 +8924,6 @@ static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev)
if (i < 2 && (bbptemp & 0x800000))
result = (bbptemp & 0xffffff) - 0x1000000;
else if (i == 4)
result = bbptemp;
else
result = bbptemp;

View file

@ -10,7 +10,7 @@ config RTL8XXXU
parts written to utilize the Linux mac80211 stack.
The driver is known to work with a number of RTL8723AU,
RL8188CU, RTL8188RU, RTL8191CU, RTL8192CU, RTL8723BU, RTL8192EU,
and RTL8188FU devices.
RTL8188FU, and RTL8188EU devices.
This driver is under development and has a limited feature
set. In particular it does not yet support 40MHz channels

View file

@ -2,4 +2,5 @@
obj-$(CONFIG_RTL8XXXU) += rtl8xxxu.o
rtl8xxxu-y := rtl8xxxu_core.o rtl8xxxu_8192e.o rtl8xxxu_8723b.o \
rtl8xxxu_8723a.o rtl8xxxu_8192c.o rtl8xxxu_8188f.o
rtl8xxxu_8723a.o rtl8xxxu_8192c.o rtl8xxxu_8188f.o \
rtl8xxxu_8188e.o

View file

@ -36,6 +36,7 @@
#define TX_TOTAL_PAGE_NUM 0xf8
#define TX_TOTAL_PAGE_NUM_8188F 0xf7
#define TX_TOTAL_PAGE_NUM_8188E 0xa9
#define TX_TOTAL_PAGE_NUM_8192E 0xf3
#define TX_TOTAL_PAGE_NUM_8723B 0xf7
/* (HPQ + LPQ + NPQ + PUBQ) = TX_TOTAL_PAGE_NUM */
@ -49,6 +50,11 @@
#define TX_PAGE_NUM_LO_PQ_8188F 0x02
#define TX_PAGE_NUM_NORM_PQ_8188F 0x02
#define TX_PAGE_NUM_PUBQ_8188E 0x47
#define TX_PAGE_NUM_HI_PQ_8188E 0x29
#define TX_PAGE_NUM_LO_PQ_8188E 0x1c
#define TX_PAGE_NUM_NORM_PQ_8188E 0x1c
#define TX_PAGE_NUM_PUBQ_8192E 0xe7
#define TX_PAGE_NUM_HI_PQ_8192E 0x08
#define TX_PAGE_NUM_LO_PQ_8192E 0x0c
@ -153,7 +159,8 @@ struct rtl8xxxu_rxdesc16 {
u32 htc:1;
u32 eosp:1;
u32 bssidfit:2;
u32 reserved1:16;
u32 rpt_sel:2; /* 8188e */
u32 reserved1:14;
u32 unicastwake:1;
u32 magicwake:1;
@ -211,7 +218,8 @@ struct rtl8xxxu_rxdesc16 {
u32 magicwake:1;
u32 unicastwake:1;
u32 reserved1:16;
u32 reserved1:14;
u32 rpt_sel:2; /* 8188e */
u32 bssidfit:2;
u32 eosp:1;
u32 htc:1;
@ -502,6 +510,8 @@ struct rtl8xxxu_txdesc40 {
#define TXDESC_AMPDU_DENSITY_SHIFT 20
#define TXDESC40_BT_INT BIT(23)
#define TXDESC40_GID_SHIFT 24
#define TXDESC_ANTENNA_SELECT_A BIT(24)
#define TXDESC_ANTENNA_SELECT_B BIT(25)
/* Word 3 */
#define TXDESC40_USE_DRIVER_RATE BIT(8)
@ -521,6 +531,7 @@ struct rtl8xxxu_txdesc40 {
#define TXDESC32_CTS_SELF_ENABLE BIT(11)
#define TXDESC32_RTS_CTS_ENABLE BIT(12)
#define TXDESC32_HW_RTS_ENABLE BIT(13)
#define TXDESC32_PT_STAGE_MASK GENMASK(17, 15)
#define TXDESC_PRIME_CH_OFF_LOWER BIT(20)
#define TXDESC_PRIME_CH_OFF_UPPER BIT(21)
#define TXDESC32_SHORT_PREAMBLE BIT(24)
@ -546,6 +557,10 @@ struct rtl8xxxu_txdesc40 {
/* Word 6 */
#define TXDESC_MAX_AGG_SHIFT 11
#define TXDESC_USB_TX_AGG_SHIT 24
/* Word 7 */
#define TXDESC_ANTENNA_SELECT_C BIT(29)
/* Word 8 */
#define TXDESC40_HW_SEQ_ENABLE BIT(15)
@ -562,6 +577,9 @@ struct phy_rx_agc_info {
#endif
};
#define CCK_AGC_RPT_LNA_IDX_MASK GENMASK(7, 5)
#define CCK_AGC_RPT_VGA_IDX_MASK GENMASK(4, 0)
struct rtl8723au_phy_stats {
struct phy_rx_agc_info path_agc[RTL8723A_MAX_RF_PATHS];
u8 ch_corr[RTL8723A_MAX_RF_PATHS];
@ -909,6 +927,42 @@ struct rtl8188fu_efuse {
u8 res11[0xc3];
};
struct rtl8188eu_efuse {
__le16 rtl_id;
u8 res0[0x0e];
struct rtl8192eu_efuse_tx_power tx_power_index_A; /* 0x10 */
u8 res1[0x7e]; /* 0x3a */
u8 channel_plan; /* 0xb8 */
u8 xtal_k;
u8 thermal_meter;
u8 iqk_lck;
u8 res2[5];
u8 rf_board_option;
u8 rf_feature_option;
u8 rf_bt_setting;
u8 eeprom_version;
u8 eeprom_customer_id;
u8 res3[3];
u8 rf_antenna_option; /* 0xc9 */
u8 res4[6];
u8 vid; /* 0xd0 */
u8 res5[1];
u8 pid; /* 0xd2 */
u8 res6[1];
u8 usb_optional_function;
u8 res7[2];
u8 mac_addr[ETH_ALEN]; /* 0xd7 */
u8 res8[2];
u8 vendor_name[7];
u8 res9[2];
u8 device_name[0x0b]; /* 0xe8 */
u8 res10[2];
u8 serial[0x0b]; /* 0xf5 */
u8 res11[0x30];
u8 unknown[0x0d]; /* 0x130 */
u8 res12[0xc3];
} __packed;
struct rtl8xxxu_reg8val {
u16 reg;
u8 val;
@ -1114,6 +1168,26 @@ struct h2c_cmd {
u8 cmd;
u8 data;
} __packed bt_grant;
struct {
u8 cmd;
u8 macid;
u8 unknown0;
u8 rssi;
/*
* [0] - is_rx
* [1] - stbc_en
* [2] - noisy_decision
* [6] - bf_en
*/
u8 data;
/*
* [0:6] - ra_th_offset
* [7] - ra_offset_direction
*/
u8 ra_th_offset;
u8 unknown1;
u8 unknown2;
} __packed rssi_report;
};
};
@ -1323,6 +1397,39 @@ struct rtl8xxxu_ra_report {
u8 desc_rate;
};
struct rtl8xxxu_ra_info {
u8 rate_id;
u32 rate_mask;
u32 ra_use_rate;
u8 rate_sgi;
u8 rssi_sta_ra; /* Percentage */
u8 pre_rssi_sta_ra;
u8 sgi_enable;
u8 decision_rate;
u8 pre_rate;
u8 highest_rate;
u8 lowest_rate;
u32 nsc_up;
u32 nsc_down;
u32 total;
u16 retry[5];
u16 drop;
u16 rpt_time;
u16 pre_min_rpt_time;
u8 dynamic_tx_rpt_timing_counter;
u8 ra_waiting_counter;
u8 ra_pending_counter;
u8 ra_drop_after_down;
u8 pt_try_state; /* 0 trying state, 1 for decision state */
u8 pt_stage; /* 0~6 */
u8 pt_stop_count; /* Stop PT counter */
u8 pt_pre_rate; /* if rate change do PT */
u8 pt_pre_rssi; /* if RSSI change 5% do PT */
u8 pt_mode_ss; /* decide which rate should do PT */
u8 ra_stage; /* StageRA, decide how many times RA will be done between PT */
u8 pt_smooth_factor;
};
#define CFO_TH_XTAL_HIGH 20 /* kHz */
#define CFO_TH_XTAL_LOW 10 /* kHz */
#define CFO_TH_ATC 80 /* kHz */
@ -1432,6 +1539,7 @@ struct rtl8xxxu_priv {
struct rtl8192cu_efuse efuse8192;
struct rtl8192eu_efuse efuse8192eu;
struct rtl8188fu_efuse efuse8188fu;
struct rtl8188eu_efuse efuse8188eu;
} efuse_wifi;
u32 adda_backup[RTL8XXXU_ADDA_REGS];
u32 mac_backup[RTL8XXXU_MAC_REGS];
@ -1455,6 +1563,7 @@ struct rtl8xxxu_priv {
struct rtl8xxxu_btcoex bt_coex;
struct rtl8xxxu_ra_report ra_report;
struct rtl8xxxu_cfo_tracking cfo_tracking;
struct rtl8xxxu_ra_info ra_info;
};
struct rtl8xxxu_rx_urb {
@ -1496,6 +1605,7 @@ struct rtl8xxxu_fileops {
u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
void (*report_connect) (struct rtl8xxxu_priv *priv,
u8 macid, bool connect);
void (*report_rssi) (struct rtl8xxxu_priv *priv, u8 macid, u8 rssi);
void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
struct ieee80211_tx_info *tx_info,
struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
@ -1523,6 +1633,7 @@ struct rtl8xxxu_fileops {
u8 page_num_hi;
u8 page_num_lo;
u8 page_num_norm;
u8 last_llt_entry;
};
extern int rtl8xxxu_debug;
@ -1560,7 +1671,7 @@ int rtl8xxxu_init_phy_rf(struct rtl8xxxu_priv *priv,
enum rtl8xxxu_rfpath path);
int rtl8xxxu_init_phy_regs(struct rtl8xxxu_priv *priv,
const struct rtl8xxxu_reg32val *array);
int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, char *fw_name);
int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name);
void rtl8xxxu_firmware_self_reset(struct rtl8xxxu_priv *priv);
void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv);
void rtl8xxxu_identify_vendor_1bit(struct rtl8xxxu_priv *priv, u32 vendor);
@ -1582,6 +1693,8 @@ void rtl8xxxu_gen1_phy_iq_calibrate(struct rtl8xxxu_priv *priv);
void rtl8xxxu_gen1_init_phy_bb(struct rtl8xxxu_priv *priv);
void rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv,
int channel, bool ht40);
void rtl8188f_set_tx_power(struct rtl8xxxu_priv *priv,
int channel, bool ht40);
void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw);
void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw);
void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv);
@ -1594,6 +1707,8 @@ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
u8 macid, bool connect);
void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
u8 macid, bool connect);
void rtl8xxxu_gen1_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi);
void rtl8xxxu_gen2_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi);
void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv);
void rtl8xxxu_gen1_enable_rf(struct rtl8xxxu_priv *priv);
void rtl8xxxu_gen1_disable_rf(struct rtl8xxxu_priv *priv);
@ -1602,6 +1717,8 @@ void rtl8xxxu_init_burst(struct rtl8xxxu_priv *priv);
int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
int rtl8xxxu_gen2_channel_to_group(int channel);
bool rtl8xxxu_simularity_compare(struct rtl8xxxu_priv *priv,
int result[][8], int c1, int c2);
bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv,
int result[][8], int c1, int c2);
void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
@ -1614,13 +1731,24 @@ void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
bool short_preamble, bool ampdu_enable,
u32 rts_rate);
void rtl8xxxu_fill_txdesc_v3(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
struct ieee80211_tx_info *tx_info,
struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
bool short_preamble, bool ampdu_enable,
u32 rts_rate);
void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5);
void rtl8723bu_phy_init_antenna_selection(struct rtl8xxxu_priv *priv);
void rtl8723a_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap);
void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap);
s8 rtl8723a_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt);
void rtl8xxxu_update_ra_report(struct rtl8xxxu_ra_report *rarpt,
u8 rate, u8 sgi, u8 bw);
void rtl8188e_ra_info_init_all(struct rtl8xxxu_ra_info *ra);
void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
extern struct rtl8xxxu_fileops rtl8188fu_fops;
extern struct rtl8xxxu_fileops rtl8188eu_fops;
extern struct rtl8xxxu_fileops rtl8192cu_fops;
extern struct rtl8xxxu_fileops rtl8192eu_fops;
extern struct rtl8xxxu_fileops rtl8723au_fops;

File diff suppressed because it is too large Load diff

View file

@ -370,7 +370,7 @@ static void rtl8188f_channel_to_group(int channel, int *group, int *cck_group)
*cck_group = *group;
}
static void
void
rtl8188f_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
{
u32 val32, ofdm, mcs;
@ -716,7 +716,6 @@ static void rtl8188fu_init_statistics(struct rtl8xxxu_priv *priv)
static int rtl8188fu_parse_efuse(struct rtl8xxxu_priv *priv)
{
struct rtl8188fu_efuse *efuse = &priv->efuse_wifi.efuse8188fu;
int i;
if (efuse->rtl_id != cpu_to_le16(0x8129))
return -EINVAL;
@ -738,22 +737,12 @@ static int rtl8188fu_parse_efuse(struct rtl8xxxu_priv *priv)
dev_info(&priv->udev->dev, "Vendor: %.7s\n", efuse->vendor_name);
dev_info(&priv->udev->dev, "Product: %.7s\n", efuse->device_name);
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
unsigned char *raw = priv->efuse_wifi.raw;
dev_info(&priv->udev->dev,
"%s: dumping efuse (0x%02zx bytes):\n",
__func__, sizeof(struct rtl8188fu_efuse));
for (i = 0; i < sizeof(struct rtl8188fu_efuse); i += 8)
dev_info(&priv->udev->dev, "%02x: %8ph\n", i, &raw[i]);
}
return 0;
}
static int rtl8188fu_load_firmware(struct rtl8xxxu_priv *priv)
{
char *fw_name;
const char *fw_name;
int ret;
fw_name = "rtlwifi/rtl8188fufw.bin";
@ -1122,7 +1111,7 @@ static void rtl8188fu_phy_iqcalibrate(struct rtl8xxxu_priv *priv,
if (t == 0) {
val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1);
priv->pi_enabled = val32 & FPGA0_HSSI_PARM1_PI;
priv->pi_enabled = u32_get_bits(val32, FPGA0_HSSI_PARM1_PI);
}
/* save RF path */
@ -1662,7 +1651,7 @@ static void rtl8188f_usb_quirks(struct rtl8xxxu_priv *priv)
#define XTAL1 GENMASK(22, 17)
#define XTAL0 GENMASK(16, 11)
static void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap)
void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap)
{
struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking;
u32 val32;
@ -1693,8 +1682,8 @@ static s8 rtl8188f_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt)
s8 rx_pwr_all = 0x00;
u8 vga_idx, lna_idx;
lna_idx = (cck_agc_rpt & 0xE0) >> 5;
vga_idx = cck_agc_rpt & 0x1F;
lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK);
vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK);
switch (lna_idx) {
case 7:
@ -1743,6 +1732,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops = {
.set_tx_power = rtl8188f_set_tx_power,
.update_rate_mask = rtl8xxxu_gen2_update_rate_mask,
.report_connect = rtl8xxxu_gen2_report_connect,
.report_rssi = rtl8xxxu_gen2_report_rssi,
.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
.set_crystal_cap = rtl8188f_set_crystal_cap,
.cck_rssi = rtl8188f_cck_rssi,

View file

@ -386,7 +386,7 @@ static int rtl8192cu_identify_chip(struct rtl8xxxu_priv *priv)
static int rtl8192cu_load_firmware(struct rtl8xxxu_priv *priv)
{
char *fw_name;
const char *fw_name;
int ret;
if (!priv->vendor_umc)
@ -404,7 +404,6 @@ static int rtl8192cu_load_firmware(struct rtl8xxxu_priv *priv)
static int rtl8192cu_parse_efuse(struct rtl8xxxu_priv *priv)
{
struct rtl8192cu_efuse *efuse = &priv->efuse_wifi.efuse8192;
int i;
if (efuse->rtl_id != cpu_to_le16(0x8129))
return -EINVAL;
@ -457,15 +456,6 @@ static int rtl8192cu_parse_efuse(struct rtl8xxxu_priv *priv)
priv->power_base = &rtl8188r_power_base;
}
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
unsigned char *raw = priv->efuse_wifi.raw;
dev_info(&priv->udev->dev,
"%s: dumping efuse (0x%02zx bytes):\n",
__func__, sizeof(struct rtl8192cu_efuse));
for (i = 0; i < sizeof(struct rtl8192cu_efuse); i += 8)
dev_info(&priv->udev->dev, "%02x: %8ph\n", i, &raw[i]);
}
return 0;
}
@ -619,6 +609,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = {
.set_tx_power = rtl8xxxu_gen1_set_tx_power,
.update_rate_mask = rtl8xxxu_update_rate_mask,
.report_connect = rtl8xxxu_gen1_report_connect,
.report_rssi = rtl8xxxu_gen1_report_rssi,
.fill_txdesc = rtl8xxxu_fill_txdesc_v1,
.cck_rssi = rtl8723a_cck_rssi,
.writeN_block_size = 128,

View file

@ -704,21 +704,12 @@ static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv)
rtl8192eu_log_next_device_info(priv, "Product", efuse->device_info, &record_offset);
rtl8192eu_log_next_device_info(priv, "Serial", efuse->device_info, &record_offset);
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
unsigned char *raw = priv->efuse_wifi.raw;
dev_info(&priv->udev->dev,
"%s: dumping efuse (0x%02zx bytes):\n",
__func__, sizeof(struct rtl8192eu_efuse));
for (i = 0; i < sizeof(struct rtl8192eu_efuse); i += 8)
dev_info(&priv->udev->dev, "%02x: %8ph\n", i, &raw[i]);
}
return 0;
}
static int rtl8192eu_load_firmware(struct rtl8xxxu_priv *priv)
{
char *fw_name;
const char *fw_name;
int ret;
fw_name = "rtlwifi/rtl8192eu_nic.bin";
@ -1744,6 +1735,11 @@ static void rtl8192e_enable_rf(struct rtl8xxxu_priv *priv)
val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1);
val8 &= ~BIT(0);
rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8);
/*
* Fix transmission failure of rtl8192e.
*/
rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
}
static s8 rtl8192e_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt)
@ -1755,8 +1751,8 @@ static s8 rtl8192e_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt)
u8 vga_idx, lna_idx;
s8 lna_gain = 0;
lna_idx = (cck_agc_rpt & 0xE0) >> 5;
vga_idx = cck_agc_rpt & 0x1F;
lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK);
vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK);
if (priv->cck_agc_report_type == 0)
lna_gain = lna_gain_table_0[lna_idx];
@ -1788,6 +1784,7 @@ struct rtl8xxxu_fileops rtl8192eu_fops = {
.set_tx_power = rtl8192e_set_tx_power,
.update_rate_mask = rtl8xxxu_gen2_update_rate_mask,
.report_connect = rtl8xxxu_gen2_report_connect,
.report_rssi = rtl8xxxu_gen2_report_rssi,
.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
.set_crystal_cap = rtl8723a_set_crystal_cap,
.cck_rssi = rtl8192e_cck_rssi,

View file

@ -231,7 +231,7 @@ static int rtl8723au_parse_efuse(struct rtl8xxxu_priv *priv)
static int rtl8723au_load_firmware(struct rtl8xxxu_priv *priv)
{
char *fw_name;
const char *fw_name;
int ret;
switch (priv->chip_cut) {
@ -478,6 +478,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = {
.set_tx_power = rtl8xxxu_gen1_set_tx_power,
.update_rate_mask = rtl8xxxu_update_rate_mask,
.report_connect = rtl8xxxu_gen1_report_connect,
.report_rssi = rtl8xxxu_gen1_report_rssi,
.fill_txdesc = rtl8xxxu_fill_txdesc_v1,
.set_crystal_cap = rtl8723a_set_crystal_cap,
.cck_rssi = rtl8723a_cck_rssi,

View file

@ -497,23 +497,12 @@ static int rtl8723bu_parse_efuse(struct rtl8xxxu_priv *priv)
dev_info(&priv->udev->dev, "Vendor: %.7s\n", efuse->vendor_name);
dev_info(&priv->udev->dev, "Product: %.41s\n", efuse->device_name);
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
int i;
unsigned char *raw = priv->efuse_wifi.raw;
dev_info(&priv->udev->dev,
"%s: dumping efuse (0x%02zx bytes):\n",
__func__, sizeof(struct rtl8723bu_efuse));
for (i = 0; i < sizeof(struct rtl8723bu_efuse); i += 8)
dev_info(&priv->udev->dev, "%02x: %8ph\n", i, &raw[i]);
}
return 0;
}
static int rtl8723bu_load_firmware(struct rtl8xxxu_priv *priv)
{
char *fw_name;
const char *fw_name;
int ret;
if (priv->enable_bluetooth)
@ -1691,8 +1680,8 @@ static s8 rtl8723b_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt)
s8 rx_pwr_all = 0x00;
u8 vga_idx, lna_idx;
lna_idx = (cck_agc_rpt & 0xE0) >> 5;
vga_idx = cck_agc_rpt & 0x1F;
lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK);
vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK);
switch (lna_idx) {
case 6:
@ -1738,6 +1727,7 @@ struct rtl8xxxu_fileops rtl8723bu_fops = {
.set_tx_power = rtl8723b_set_tx_power,
.update_rate_mask = rtl8xxxu_gen2_update_rate_mask,
.report_connect = rtl8xxxu_gen2_report_connect,
.report_rssi = rtl8xxxu_gen2_report_rssi,
.fill_txdesc = rtl8xxxu_fill_txdesc_v2,
.set_crystal_cap = rtl8723a_set_crystal_cap,
.cck_rssi = rtl8723b_cck_rssi,

View file

@ -34,7 +34,7 @@
#define DRIVER_NAME "rtl8xxxu"
int rtl8xxxu_debug = RTL8XXXU_DEBUG_EFUSE;
int rtl8xxxu_debug;
static bool rtl8xxxu_ht40_2g;
static bool rtl8xxxu_dma_aggregation;
static int rtl8xxxu_dma_agg_timeout = -1;
@ -46,6 +46,7 @@ MODULE_LICENSE("GPL");
MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin");
MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B.bin");
MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B_NoBT.bin");
MODULE_FIRMWARE("rtlwifi/rtl8188eufw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin");
MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin");
MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin");
@ -1581,10 +1582,11 @@ static void rtl8xxxu_print_chipinfo(struct rtl8xxxu_priv *priv)
cut = 'A' + priv->chip_cut;
dev_info(dev,
"RTL%s rev %c (%s) %iT%iR, TX queues %i, WiFi=%i, BT=%i, GPS=%i, HI PA=%i\n",
priv->chip_name, cut, priv->chip_vendor, priv->tx_paths,
priv->rx_paths, priv->ep_tx_count, priv->has_wifi,
priv->has_bluetooth, priv->has_gps, priv->hi_pa);
"RTL%s rev %c (%s) romver %d, %iT%iR, TX queues %i, WiFi=%i, BT=%i, GPS=%i, HI PA=%i\n",
priv->chip_name, cut, priv->chip_vendor, priv->rom_rev,
priv->tx_paths, priv->rx_paths, priv->ep_tx_count,
priv->has_wifi, priv->has_bluetooth, priv->has_gps,
priv->hi_pa);
dev_info(dev, "RTL%s MAC: %pM\n", priv->chip_name, priv->mac_addr);
}
@ -1813,6 +1815,16 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)
return ret;
}
static void rtl8xxxu_dump_efuse(struct rtl8xxxu_priv *priv)
{
dev_info(&priv->udev->dev,
"Dumping efuse for RTL%s (0x%02x bytes):\n",
priv->chip_name, EFUSE_MAP_LEN);
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
priv->efuse_wifi.raw, EFUSE_MAP_LEN, true);
}
void rtl8xxxu_reset_8051(struct rtl8xxxu_priv *priv)
{
u8 val8;
@ -1970,7 +1982,7 @@ static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
return ret;
}
int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, char *fw_name)
int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name)
{
struct device *dev = &priv->udev->dev;
const struct firmware *fw;
@ -2000,6 +2012,7 @@ int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, char *fw_name)
switch (signature & 0xfff0) {
case 0x92e0:
case 0x92c0:
case 0x88e0:
case 0x88c0:
case 0x5300:
case 0x2300:
@ -2071,10 +2084,20 @@ rtl8xxxu_init_mac(struct rtl8xxxu_priv *priv)
}
}
if (priv->rtl_chip != RTL8723B &&
priv->rtl_chip != RTL8192E &&
priv->rtl_chip != RTL8188F)
switch (priv->rtl_chip) {
case RTL8188C:
case RTL8188R:
case RTL8191C:
case RTL8192C:
case RTL8723A:
rtl8xxxu_write8(priv, REG_MAX_AGGR_NUM, 0x0a);
break;
case RTL8188E:
rtl8xxxu_write16(priv, REG_MAX_AGGR_NUM, 0x0707);
break;
default:
break;
}
return 0;
}
@ -2373,11 +2396,16 @@ static int rtl8xxxu_llt_write(struct rtl8xxxu_priv *priv, u8 address, u8 data)
int rtl8xxxu_init_llt_table(struct rtl8xxxu_priv *priv)
{
int ret;
int i;
int i, last_entry;
u8 last_tx_page;
last_tx_page = priv->fops->total_page_num;
if (priv->fops->last_llt_entry)
last_entry = priv->fops->last_llt_entry;
else
last_entry = 255;
for (i = 0; i < last_tx_page; i++) {
ret = rtl8xxxu_llt_write(priv, i, i + 1);
if (ret)
@ -2389,14 +2417,14 @@ int rtl8xxxu_init_llt_table(struct rtl8xxxu_priv *priv)
goto exit;
/* Mark remaining pages as a ring buffer */
for (i = last_tx_page + 1; i < 0xff; i++) {
for (i = last_tx_page + 1; i < last_entry; i++) {
ret = rtl8xxxu_llt_write(priv, i, (i + 1));
if (ret)
goto exit;
}
/* Let last entry point to the start entry of ring buffer */
ret = rtl8xxxu_llt_write(priv, 0xff, last_tx_page + 1);
ret = rtl8xxxu_llt_write(priv, last_entry, last_tx_page + 1);
if (ret)
goto exit;
@ -2704,8 +2732,8 @@ void rtl8xxxu_fill_iqk_matrix_b(struct rtl8xxxu_priv *priv, bool iqk_ok,
#define MAX_TOLERANCE 5
static bool rtl8xxxu_simularity_compare(struct rtl8xxxu_priv *priv,
int result[][8], int c1, int c2)
bool rtl8xxxu_simularity_compare(struct rtl8xxxu_priv *priv,
int result[][8], int c1, int c2)
{
u32 i, j, diff, simubitmap, bound = 0;
int candidate[2] = {-1, -1}; /* for path A and path B */
@ -3898,7 +3926,8 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
goto exit;
/* RFSW Control - clear bit 14 ?? */
if (priv->rtl_chip != RTL8723B && priv->rtl_chip != RTL8192E)
if (priv->rtl_chip != RTL8723B && priv->rtl_chip != RTL8192E &&
priv->rtl_chip != RTL8188E)
rtl8xxxu_write32(priv, REG_FPGA0_TX_INFO, 0x00000003);
val32 = FPGA0_RF_TRSW | FPGA0_RF_TRSWB | FPGA0_RF_ANTSW |
@ -3911,7 +3940,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32);
/* 0x860[6:5]= 00 - why? - this sets antenna B */
if (priv->rtl_chip != RTL8192E)
if (priv->rtl_chip != RTL8192E && priv->rtl_chip != RTL8188E)
rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, 0x66f60210);
if (!macpower) {
@ -3953,7 +3982,25 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
* Enable TX report and TX report timer for 8723bu/8188eu/...
*/
if (fops->has_tx_report) {
/*
* The RTL8188EU has two types of TX reports:
* rpt_sel=1:
* One report for one frame. We can use this for frames
* with IEEE80211_TX_CTL_REQ_TX_STATUS.
* rpt_sel=2:
* One report for many frames transmitted over a period
* of time. (This is what REG_TX_REPORT_TIME is for.) The
* report includes the number of frames transmitted
* successfully, and the number of unsuccessful
* transmissions. We use this for software rate control.
*
* Bit 0 of REG_TX_REPORT_CTRL is required for both types.
* Bit 1 (TX_REPORT_CTRL_TIMER_ENABLE) is required for
* type 2.
*/
val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL);
if (priv->rtl_chip == RTL8188E)
val8 |= BIT(0);
val8 |= TX_REPORT_CTRL_TIMER_ENABLE;
rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8);
/* Set MAX RPT MACID */
@ -3979,6 +4026,15 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
} else if (priv->rtl_chip == RTL8188F) {
rtl8xxxu_write32(priv, REG_HISR0, 0xffffffff);
rtl8xxxu_write32(priv, REG_HISR1, 0xffffffff);
} else if (priv->rtl_chip == RTL8188E) {
rtl8xxxu_write32(priv, REG_HISR0, 0xffffffff);
val32 = IMR0_PSTIMEOUT | IMR0_TBDER | IMR0_CPWM | IMR0_CPWM2;
rtl8xxxu_write32(priv, REG_HIMR0, val32);
val32 = IMR1_TXERR | IMR1_RXERR | IMR1_TXFOVW | IMR1_RXFOVW;
rtl8xxxu_write32(priv, REG_HIMR1, val32);
val8 = rtl8xxxu_read8(priv, REG_USB_SPECIAL_OPTION);
val8 |= USB_SPEC_INT_BULK_SELECT;
rtl8xxxu_write8(priv, REG_USB_SPECIAL_OPTION, val8);
} else {
/*
* Enable all interrupts - not obvious USB needs to do this
@ -4084,7 +4140,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
if (fops->init_aggregation)
fops->init_aggregation(priv);
if (priv->rtl_chip == RTL8188F) {
if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8188E) {
rtl8xxxu_write16(priv, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
rtl8xxxu_write16(priv, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
}
@ -4118,7 +4174,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
/* Disable BAR - not sure if this has any effect on USB */
rtl8xxxu_write32(priv, REG_BAR_MODE_CTRL, 0x0201ffff);
if (priv->rtl_chip != RTL8188F)
if (priv->rtl_chip != RTL8188F && priv->rtl_chip != RTL8188E)
rtl8xxxu_write16(priv, REG_FAST_EDCA_CTRL, 0);
if (fops->init_statistics)
@ -4136,9 +4192,9 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
* Reset USB mode switch setting
*/
rtl8xxxu_write8(priv, REG_ACLK_MON, 0x00);
} else if (priv->rtl_chip == RTL8188F) {
} else if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8188E) {
/*
* Init GPIO settings for 8188f
* Init GPIO settings for 8188f, 8188e
*/
val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG);
val8 &= ~GPIO_MUXCFG_IO_SEL_ENBT;
@ -4184,7 +4240,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
val32 |= FPGA_RF_MODE_CCK;
rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
}
} else if (priv->rtl_chip == RTL8192E) {
} else if (priv->rtl_chip == RTL8192E || priv->rtl_chip == RTL8188E) {
rtl8xxxu_write8(priv, REG_USB_HRPWM, 0x00);
}
@ -4208,10 +4264,12 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
* should be equal or CCK RSSI report may be incorrect
*/
val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM2);
priv->cck_agc_report_type = val32 & FPGA0_HSSI_PARM2_CCK_HIGH_PWR;
priv->cck_agc_report_type =
u32_get_bits(val32, FPGA0_HSSI_PARM2_CCK_HIGH_PWR);
val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_HSSI_PARM2);
if (priv->cck_agc_report_type != (bool)(val32 & FPGA0_HSSI_PARM2_CCK_HIGH_PWR)) {
if (priv->cck_agc_report_type !=
u32_get_bits(val32, FPGA0_HSSI_PARM2_CCK_HIGH_PWR)) {
if (priv->cck_agc_report_type)
val32 |= FPGA0_HSSI_PARM2_CCK_HIGH_PWR;
else
@ -4235,6 +4293,9 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
priv->cfo_tracking.crystal_cap = priv->default_crystal_cap;
}
if (priv->rtl_chip == RTL8188E)
rtl8188e_ra_info_init_all(&priv->ra_info);
exit:
return ret;
}
@ -4401,6 +4462,37 @@ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt));
}
void rtl8xxxu_gen1_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi)
{
struct h2c_cmd h2c;
const int h2c_size = 4;
memset(&h2c, 0, sizeof(struct h2c_cmd));
h2c.rssi_report.cmd = H2C_SET_RSSI;
h2c.rssi_report.macid = macid;
h2c.rssi_report.rssi = rssi;
rtl8xxxu_gen1_h2c_cmd(priv, &h2c, h2c_size);
}
void rtl8xxxu_gen2_report_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi)
{
struct h2c_cmd h2c;
int h2c_size = sizeof(h2c.rssi_report);
if (priv->rtl_chip == RTL8723B)
h2c_size = 4;
memset(&h2c, 0, sizeof(struct h2c_cmd));
h2c.rssi_report.cmd = H2C_8723B_RSSI_SETTING;
h2c.rssi_report.macid = macid;
h2c.rssi_report.rssi = rssi;
rtl8xxxu_gen2_h2c_cmd(priv, &h2c, h2c_size);
}
void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
{
u8 agg_ctrl, usb_spec, page_thresh, timeout;
@ -4598,8 +4690,8 @@ static void rtl8xxxu_set_aifs(struct rtl8xxxu_priv *priv, u8 slot_time)
}
}
static void rtl8xxxu_update_ra_report(struct rtl8xxxu_ra_report *rarpt,
u8 rate, u8 sgi, u8 bw)
void rtl8xxxu_update_ra_report(struct rtl8xxxu_ra_report *rarpt,
u8 rate, u8 sgi, u8 bw)
{
u8 mcs, nss;
@ -5069,6 +5161,98 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
}
}
/*
* Fill in v3 (gen1) specific TX descriptor bits.
* This format is a hybrid between the v1 and v2 formats, only seen
* on 8188eu devices so far.
*/
void
rtl8xxxu_fill_txdesc_v3(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
struct ieee80211_tx_info *tx_info,
struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
bool short_preamble, bool ampdu_enable, u32 rts_rate)
{
struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
struct rtl8xxxu_priv *priv = hw->priv;
struct device *dev = &priv->udev->dev;
struct rtl8xxxu_ra_info *ra = &priv->ra_info;
u8 *qc = ieee80211_get_qos_ctl(hdr);
u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
u32 rate;
u16 rate_flags = tx_info->control.rates[0].flags;
u16 seq_number;
if (rate_flags & IEEE80211_TX_RC_MCS &&
!ieee80211_is_mgmt(hdr->frame_control))
rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
else
rate = tx_rate->hw_value;
seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
if (ieee80211_is_data(hdr->frame_control)) {
rate = ra->decision_rate;
tx_desc->txdw5 = cpu_to_le32(rate);
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_USE_DRIVER_RATE);
tx_desc->txdw4 |= le32_encode_bits(ra->pt_stage, TXDESC32_PT_STAGE_MASK);
/* Data/RTS rate FB limit */
tx_desc->txdw5 |= cpu_to_le32(0x0001ff00);
}
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
dev_info(dev, "%s: TX rate: %d, pkt size %d\n",
__func__, rate, le16_to_cpu(tx_desc->pkt_size));
tx_desc->txdw3 = cpu_to_le32((u32)seq_number << TXDESC32_SEQ_SHIFT);
if (ampdu_enable && test_bit(tid, priv->tid_tx_operational))
tx_desc->txdw2 |= cpu_to_le32(TXDESC40_AGG_ENABLE);
else
tx_desc->txdw2 |= cpu_to_le32(TXDESC40_AGG_BREAK);
if (ieee80211_is_mgmt(hdr->frame_control)) {
tx_desc->txdw5 = cpu_to_le32(rate);
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_USE_DRIVER_RATE);
tx_desc->txdw5 |= cpu_to_le32(6 << TXDESC32_RETRY_LIMIT_SHIFT);
tx_desc->txdw5 |= cpu_to_le32(TXDESC32_RETRY_LIMIT_ENABLE);
}
if (ieee80211_is_data_qos(hdr->frame_control)) {
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_QOS);
if (conf_is_ht40(&hw->conf)) {
tx_desc->txdw4 |= cpu_to_le32(TXDESC_DATA_BW);
if (conf_is_ht40_minus(&hw->conf))
tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_UPPER);
else
tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_LOWER);
}
}
if (short_preamble)
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_SHORT_PREAMBLE);
if (sgi && ra->rate_sgi)
tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI);
/*
* rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
*/
tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT);
if (ampdu_enable || (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE);
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
} else if (rate_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE);
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
}
tx_desc->txdw2 |= cpu_to_le32(TXDESC_ANTENNA_SELECT_A |
TXDESC_ANTENNA_SELECT_B);
tx_desc->txdw7 |= cpu_to_le32(TXDESC_ANTENNA_SELECT_C);
}
static void rtl8xxxu_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
@ -5274,7 +5458,7 @@ static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv,
pending = priv->rx_urb_pending_count;
} else {
skb = (struct sk_buff *)rx_urb->urb.context;
dev_kfree_skb(skb);
dev_kfree_skb_irq(skb);
usb_free_urb(&rx_urb->urb);
}
@ -5550,9 +5734,6 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
btcoex = &priv->bt_coex;
rarpt = &priv->ra_report;
if (priv->rf_paths > 1)
goto out;
while (!skb_queue_empty(&priv->c2hcmd_queue)) {
skb = skb_dequeue(&priv->c2hcmd_queue);
@ -5585,10 +5766,9 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
default:
break;
}
}
out:
dev_kfree_skb(skb);
dev_kfree_skb(skb);
}
}
static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
@ -5640,6 +5820,44 @@ static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
schedule_work(&priv->c2hcmd_work);
}
static void rtl8188e_c2hcmd_callback(struct work_struct *work)
{
struct rtl8xxxu_priv *priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work);
struct device *dev = &priv->udev->dev;
struct sk_buff *skb = NULL;
struct rtl8xxxu_rxdesc16 *rx_desc;
while (!skb_queue_empty(&priv->c2hcmd_queue)) {
skb = skb_dequeue(&priv->c2hcmd_queue);
rx_desc = (struct rtl8xxxu_rxdesc16 *)(skb->data - sizeof(struct rtl8xxxu_rxdesc16));
switch (rx_desc->rpt_sel) {
case 1:
dev_dbg(dev, "C2H TX report type 1\n");
break;
case 2:
dev_dbg(dev, "C2H TX report type 2\n");
rtl8188e_handle_ra_tx_report2(priv, skb);
break;
case 3:
dev_dbg(dev, "C2H USB interrupt report\n");
break;
default:
dev_warn(dev, "%s: rpt_sel should not be %d\n",
__func__, rx_desc->rpt_sel);
break;
}
dev_kfree_skb(skb);
}
}
int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hw *hw = priv->hw;
@ -5695,39 +5913,46 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc16));
phy_stats = (struct rtl8723au_phy_stats *)skb->data;
skb_pull(skb, drvinfo_sz + desc_shift);
skb_trim(skb, pkt_len);
if (rx_desc->phy_stats)
rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
rx_desc->rxmcs, (struct ieee80211_hdr *)skb->data,
rx_desc->crc32 || rx_desc->icverr);
rx_status->mactime = rx_desc->tsfl;
rx_status->flag |= RX_FLAG_MACTIME_START;
if (!rx_desc->swdec)
rx_status->flag |= RX_FLAG_DECRYPTED;
if (rx_desc->crc32)
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (rx_desc->bw)
rx_status->bw = RATE_INFO_BW_40;
if (rx_desc->rxht) {
rx_status->encoding = RX_ENC_HT;
rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
if (rx_desc->rpt_sel) {
skb_queue_tail(&priv->c2hcmd_queue, skb);
schedule_work(&priv->c2hcmd_work);
} else {
rx_status->rate_idx = rx_desc->rxmcs;
phy_stats = (struct rtl8723au_phy_stats *)skb->data;
skb_pull(skb, drvinfo_sz + desc_shift);
skb_trim(skb, pkt_len);
if (rx_desc->phy_stats)
rtl8xxxu_rx_parse_phystats(
priv, rx_status, phy_stats,
rx_desc->rxmcs,
(struct ieee80211_hdr *)skb->data,
rx_desc->crc32 || rx_desc->icverr);
rx_status->mactime = rx_desc->tsfl;
rx_status->flag |= RX_FLAG_MACTIME_START;
if (!rx_desc->swdec)
rx_status->flag |= RX_FLAG_DECRYPTED;
if (rx_desc->crc32)
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (rx_desc->bw)
rx_status->bw = RATE_INFO_BW_40;
if (rx_desc->rxht) {
rx_status->encoding = RX_ENC_HT;
rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
} else {
rx_status->rate_idx = rx_desc->rxmcs;
}
rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->band = hw->conf.chandef.chan->band;
ieee80211_rx_irqsafe(hw, skb);
}
rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->band = hw->conf.chandef.chan->band;
ieee80211_rx_irqsafe(hw, skb);
skb = next_skb;
if (skb)
skb_pull(next_skb, pkt_offset);
@ -5956,7 +6181,6 @@ static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
{
struct rtl8xxxu_priv *priv = hw->priv;
struct device *dev = &priv->udev->dev;
u16 val16;
int ret = 0, channel;
bool ht40;
@ -5966,14 +6190,6 @@ static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
__func__, hw->conf.chandef.chan->hw_value,
changed, hw->conf.chandef.width);
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
val16 = ((hw->conf.long_frame_max_tx_count <<
RETRY_LIMIT_LONG_SHIFT) & RETRY_LIMIT_LONG_MASK) |
((hw->conf.short_frame_max_tx_count <<
RETRY_LIMIT_SHORT_SHIFT) & RETRY_LIMIT_SHORT_MASK);
rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16);
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
switch (hw->conf.chandef.width) {
case NL80211_CHAN_WIDTH_20_NOHT:
@ -6504,6 +6720,9 @@ static void rtl8xxxu_watchdog_callback(struct work_struct *work)
signal = ieee80211_ave_rssi(vif);
priv->fops->report_rssi(priv, 0,
rtl8xxxu_signal_to_snr(signal));
if (priv->fops->set_crystal_cap)
rtl8xxxu_track_cfo(priv);
@ -6587,7 +6806,10 @@ static int rtl8xxxu_start(struct ieee80211_hw *hw)
rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff);
rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0xffff);
rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, 0x6954341e);
if (priv->rtl_chip == RTL8188E)
rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, 0x6955341e);
else
rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, 0x6954341e);
return ret;
@ -6754,6 +6976,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
case 0x817f:
case 0x818b:
case 0xf179:
case 0x8179:
untested = 0;
break;
}
@ -6809,7 +7032,6 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
spin_lock_init(&priv->rx_urb_lock);
INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work);
INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback);
INIT_WORK(&priv->c2hcmd_work, rtl8xxxu_c2hcmd_callback);
skb_queue_head_init(&priv->c2hcmd_queue);
usb_set_intfdata(interface, hw);
@ -6827,6 +7049,11 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
hw->wiphy->available_antennas_tx = BIT(priv->tx_paths) - 1;
hw->wiphy->available_antennas_rx = BIT(priv->rx_paths) - 1;
if (priv->rtl_chip == RTL8188E)
INIT_WORK(&priv->c2hcmd_work, rtl8188e_c2hcmd_callback);
else
INIT_WORK(&priv->c2hcmd_work, rtl8xxxu_c2hcmd_callback);
ret = rtl8xxxu_read_efuse(priv);
if (ret) {
dev_err(&udev->dev, "Fatal - failed to read EFuse\n");
@ -6839,6 +7066,9 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
goto err_set_intfdata;
}
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE)
rtl8xxxu_dump_efuse(priv);
rtl8xxxu_print_chipinfo(priv);
ret = priv->fops->load_firmware(priv);
@ -6887,8 +7117,10 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
hw->extra_tx_headroom = priv->fops->tx_desc_size;
ieee80211_hw_set(hw, SIGNAL_DBM);
/*
* The firmware handles rate control
* The firmware handles rate control, except for RTL8188EU,
* where we handle the rate control in the driver.
*/
ieee80211_hw_set(hw, HAS_RATE_CONTROL);
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
@ -6973,6 +7205,50 @@ static const struct usb_device_id dev_table[] = {
/* RTL8188FU */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xf179, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188fu_fops},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8179, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* Tested by Hans de Goede - rtl8188etv */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x0179, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* Sitecom rtl8188eus */
{USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0076, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* D-Link USB-GO-N150 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3311, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* D-Link DWA-125 REV D1 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330f, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* D-Link DWA-123 REV D1 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3310, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* D-Link DWA-121 rev B1 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331b, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* Abocom - Abocom */
{USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8179, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* Elecom WDC-150SU2M */
{USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4008, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* TP-Link TL-WN722N v2 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010c, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* TP-Link TL-WN727N v5.21 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0111, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* MERCUSYS MW150US v2 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0102, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* ASUS USB-N10 Nano B1 */
{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x18f0, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* Edimax EW-7811Un V2 */
{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb811, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
/* Rosewill USB-N150 Nano */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xffef, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8188eu_fops},
#ifdef CONFIG_RTL8XXXU_UNTESTED
/* Still supported by rtlwifi */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8176, 0xff, 0xff, 0xff),

View file

@ -371,6 +371,11 @@
#define PBP_PAGE_SIZE_512 0x3
#define PBP_PAGE_SIZE_1024 0x4
/* 8188eu IOL magic */
#define REG_PKT_BUF_ACCESS_CTRL 0x0106
#define PKT_BUF_ACCESS_CTRL_TX 0x69
#define PKT_BUF_ACCESS_CTRL_RX 0xa5
#define REG_TRXDMA_CTRL 0x010c
#define TRXDMA_CTRL_RXDMA_AGG_EN BIT(2)
#define TRXDMA_CTRL_VOQ_SHIFT 4
@ -407,6 +412,8 @@
#define REG_MBIST_START 0x0174
#define REG_MBIST_DONE 0x0178
#define REG_MBIST_FAIL 0x017c
/* 8188EU */
#define REG_32K_CTRL 0x0194
#define REG_C2HEVT_MSG_NORMAL 0x01a0
/* 8192EU/8723BU/8812 */
#define REG_C2HEVT_CMD_ID_8723B 0x01ae
@ -942,6 +949,16 @@
#define REG_FPGA1_RF_MODE 0x0900
#define REG_FPGA1_TX_INFO 0x090c
#define FPGA1_TX_ANT_MASK 0x0000000f
#define FPGA1_TX_ANT_L_MASK 0x000000f0
#define FPGA1_TX_ANT_NON_HT_MASK 0x00000f00
#define FPGA1_TX_ANT_HT1_MASK 0x0000f000
#define FPGA1_TX_ANT_HT2_MASK 0x000f0000
#define FPGA1_TX_ANT_HT_S1_MASK 0x00f00000
#define FPGA1_TX_ANT_NON_HT_S1_MASK 0x0f000000
#define FPGA1_TX_OFDM_TXSC_MASK 0x30000000
#define REG_ANT_MAPPING1 0x0914
#define REG_DPDT_CTRL 0x092c /* 8723BU */
#define REG_RFE_CTRL_ANTA_SRC 0x0930 /* 8723BU */
#define REG_RFE_PATH_SELECT 0x0940 /* 8723BU */
@ -954,9 +971,25 @@
#define REG_CCK0_AFE_SETTING 0x0a04
#define CCK0_AFE_RX_MASK 0x0f000000
#define CCK0_AFE_RX_ANT_AB BIT(24)
#define CCK0_AFE_TX_MASK 0xf0000000
#define CCK0_AFE_RX_ANT_A 0
#define CCK0_AFE_RX_ANT_B (BIT(24) | BIT(26))
#define CCK0_AFE_RX_ANT_B BIT(26)
#define CCK0_AFE_RX_ANT_C BIT(27)
#define CCK0_AFE_RX_ANT_D (BIT(26) | BIT(27))
#define CCK0_AFE_RX_ANT_OPTION_A 0
#define CCK0_AFE_RX_ANT_OPTION_B BIT(24)
#define CCK0_AFE_RX_ANT_OPTION_C BIT(25)
#define CCK0_AFE_RX_ANT_OPTION_D (BIT(24) | BIT(25))
#define CCK0_AFE_TX_ANT_A BIT(31)
#define CCK0_AFE_TX_ANT_B BIT(30)
#define REG_CCK_ANTDIV_PARA2 0x0a04
#define REG_BB_POWER_SAVE4 0x0a74
/* 8188eu */
#define REG_LNA_SWITCH 0x0b2c
#define LNA_SWITCH_DISABLE_CSCG BIT(22)
#define LNA_SWITCH_OUTPUT_CG BIT(31)
#define REG_CCK_PD_THRESH 0x0a0a
#define CCK_PD_TYPE1_LV0_TH 0x40
@ -1020,6 +1053,9 @@
#define REG_OFDM0_RX_IQ_EXT_ANTA 0x0ca0
/* 8188eu */
#define REG_ANTDIV_PARA1 0x0ca4
/* 8723bu */
#define REG_OFDM0_TX_PSDO_NOISE_WEIGHT 0x0ce4

View file

@ -68,8 +68,10 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
struct sk_buff_head free_list;
unsigned long flags;
skb_queue_head_init(&free_list);
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
while (skb_queue_len(&ring->queue)) {
struct rtl_tx_desc *entry = &ring->desc[ring->idx];
@ -79,10 +81,12 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
true, HW_DESC_TXBUFF_ADDR),
skb->len, DMA_TO_DEVICE);
kfree_skb(skb);
__skb_queue_tail(&free_list, skb);
ring->idx = (ring->idx + 1) % ring->entries;
}
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
__skb_queue_purge(&free_list);
}
static void _rtl88ee_disable_bcn_sub_func(struct ieee80211_hw *hw)

View file

@ -116,7 +116,7 @@ void rtl8723e_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw);
long rtl8723e_dm_bt_get_rx_ss(struct ieee80211_hw *hw);
void rtl8723e_dm_bt_balance(struct ieee80211_hw *hw,
bool balance_on, u8 ms0, u8 ms1);
void rtl8723e_dm_bt_agc_table(struct ieee80211_hw *hw, u8 tyep);
void rtl8723e_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type);
void rtl8723e_dm_bt_bb_back_off_level(struct ieee80211_hw *hw, u8 type);
u8 rtl8723e_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
u8 level_num, u8 rssi_thresh,

View file

@ -30,8 +30,10 @@ static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
struct sk_buff_head free_list;
unsigned long flags;
skb_queue_head_init(&free_list);
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
while (skb_queue_len(&ring->queue)) {
struct rtl_tx_desc *entry = &ring->desc[ring->idx];
@ -41,10 +43,12 @@ static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
true, HW_DESC_TXBUFF_ADDR),
skb->len, DMA_TO_DEVICE);
kfree_skb(skb);
__skb_queue_tail(&free_list, skb);
ring->idx = (ring->idx + 1) % ring->entries;
}
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
__skb_queue_purge(&free_list);
}
static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,

View file

@ -26,8 +26,10 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
struct sk_buff_head free_list;
unsigned long flags;
skb_queue_head_init(&free_list);
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
while (skb_queue_len(&ring->queue)) {
struct rtl_tx_desc *entry = &ring->desc[ring->idx];
@ -37,10 +39,12 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
true, HW_DESC_TXBUFF_ADDR),
skb->len, DMA_TO_DEVICE);
kfree_skb(skb);
__skb_queue_tail(&free_list, skb);
ring->idx = (ring->idx + 1) % ring->entries;
}
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
__skb_queue_purge(&free_list);
}
static void _rtl8821ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw,

View file

@ -1598,18 +1598,6 @@ static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint)
return true;
}
static bool _rtl8812ae_eq_n_byte(const char *str1, const char *str2, u32 num)
{
if (num == 0)
return false;
while (num > 0) {
num--;
if (str1[num] != str2[num])
return false;
}
return true;
}
static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
u8 band, u8 channel)
{
@ -1659,42 +1647,42 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw,
power_limit = power_limit > MAX_POWER_INDEX ?
MAX_POWER_INDEX : power_limit;
if (_rtl8812ae_eq_n_byte(pregulation, "FCC", 3))
if (strcmp(pregulation, "FCC") == 0)
regulation = 0;
else if (_rtl8812ae_eq_n_byte(pregulation, "MKK", 3))
else if (strcmp(pregulation, "MKK") == 0)
regulation = 1;
else if (_rtl8812ae_eq_n_byte(pregulation, "ETSI", 4))
else if (strcmp(pregulation, "ETSI") == 0)
regulation = 2;
else if (_rtl8812ae_eq_n_byte(pregulation, "WW13", 4))
else if (strcmp(pregulation, "WW13") == 0)
regulation = 3;
if (_rtl8812ae_eq_n_byte(prate_section, "CCK", 3))
if (strcmp(prate_section, "CCK") == 0)
rate_section = 0;
else if (_rtl8812ae_eq_n_byte(prate_section, "OFDM", 4))
else if (strcmp(prate_section, "OFDM") == 0)
rate_section = 1;
else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) &&
_rtl8812ae_eq_n_byte(prf_path, "1T", 2))
else if (strcmp(prate_section, "HT") == 0 &&
strcmp(prf_path, "1T") == 0)
rate_section = 2;
else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) &&
_rtl8812ae_eq_n_byte(prf_path, "2T", 2))
else if (strcmp(prate_section, "HT") == 0 &&
strcmp(prf_path, "2T") == 0)
rate_section = 3;
else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) &&
_rtl8812ae_eq_n_byte(prf_path, "1T", 2))
else if (strcmp(prate_section, "VHT") == 0 &&
strcmp(prf_path, "1T") == 0)
rate_section = 4;
else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) &&
_rtl8812ae_eq_n_byte(prf_path, "2T", 2))
else if (strcmp(prate_section, "VHT") == 0 &&
strcmp(prf_path, "2T") == 0)
rate_section = 5;
if (_rtl8812ae_eq_n_byte(pbandwidth, "20M", 3))
if (strcmp(pbandwidth, "20M") == 0)
bandwidth = 0;
else if (_rtl8812ae_eq_n_byte(pbandwidth, "40M", 3))
else if (strcmp(pbandwidth, "40M") == 0)
bandwidth = 1;
else if (_rtl8812ae_eq_n_byte(pbandwidth, "80M", 3))
else if (strcmp(pbandwidth, "80M") == 0)
bandwidth = 2;
else if (_rtl8812ae_eq_n_byte(pbandwidth, "160M", 4))
else if (strcmp(pbandwidth, "160M") == 0)
bandwidth = 3;
if (_rtl8812ae_eq_n_byte(pband, "2.4G", 4)) {
if (strcmp(pband, "2.4G") == 0) {
ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
BAND_ON_2_4G,
channel);
@ -1718,7 +1706,7 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw,
regulation, bandwidth, rate_section, channel_index,
rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
[rate_section][channel_index][RF90_PATH_A]);
} else if (_rtl8812ae_eq_n_byte(pband, "5G", 2)) {
} else if (strcmp(pband, "5G") == 0) {
ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
BAND_ON_5G,
channel);

View file

@ -49,19 +49,23 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
sta = ieee80211_find_sta(vif, bssid);
if (!sta) {
rcu_read_unlock();
rtw_warn(rtwdev, "failed to find station entry for bss %pM\n",
bssid);
goto out_unlock;
return;
}
ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap;
vht_cap = &sta->deflink.vht_cap;
rcu_read_unlock();
if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) &&
(vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
if (bfinfo->bfer_mu_cnt >= chip->bfer_mu_max_num) {
rtw_dbg(rtwdev, RTW_DBG_BF, "mu bfer number over limit\n");
goto out_unlock;
return;
}
ether_addr_copy(bfee->mac_addr, bssid);
@ -75,7 +79,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
(vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
if (bfinfo->bfer_su_cnt >= chip->bfer_su_max_num) {
rtw_dbg(rtwdev, RTW_DBG_BF, "su bfer number over limit\n");
goto out_unlock;
return;
}
sound_dim = vht_cap->cap &
@ -98,9 +102,6 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true);
}
out_unlock:
rcu_read_unlock();
}
void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev,

View file

@ -737,7 +737,7 @@ static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev,
br_data.rtwdev = rtwdev;
br_data.vif = vif;
br_data.mask = mask;
rtw_iterate_stas_atomic(rtwdev, rtw_ra_mask_info_update_iter, &br_data);
rtw_iterate_stas(rtwdev, rtw_ra_mask_info_update_iter, &br_data);
}
static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw,
@ -746,7 +746,9 @@ static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw,
{
struct rtw_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
rtw_ra_mask_info_update(rtwdev, vif, mask);
mutex_unlock(&rtwdev->mutex);
return 0;
}

View file

@ -241,8 +241,10 @@ static void rtw_watch_dog_work(struct work_struct *work)
rtw_phy_dynamic_mechanism(rtwdev);
data.rtwdev = rtwdev;
/* use atomic version to avoid taking local->iflist_mtx mutex */
rtw_iterate_vifs_atomic(rtwdev, rtw_vif_watch_dog_iter, &data);
/* rtw_iterate_vifs internally uses an atomic iterator which is needed
* to avoid taking local->iflist_mtx mutex
*/
rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
/* fw supports only one station associated to enter lps, if there are
* more than two stations associated to the AP, then we can not enter

File diff suppressed because it is too large Load diff

View file

@ -164,6 +164,7 @@ void rtw89_coex_rfk_chk_work(struct work_struct *work);
void rtw89_coex_power_on(struct rtw89_dev *rtwdev);
void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev);
static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,

View file

@ -498,7 +498,8 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u16 lowest_rate;
if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE || vif->p2p)
if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE ||
(vif && vif->p2p))
lowest_rate = RTW89_HW_RATE_OFDM6;
else if (chan->band_type == RTW89_BAND_2G)
lowest_rate = RTW89_HW_RATE_CCK1;
@ -511,6 +512,21 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
return __ffs(vif->bss_conf.basic_rates) + lowest_rate;
}
static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
struct ieee80211_vif *vif = tx_req->vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_sta *sta = tx_req->sta;
struct rtw89_sta *rtwsta;
if (!sta)
return rtwvif->mac_id;
rtwsta = (struct rtw89_sta *)sta->drv_priv;
return rtwsta->mac_id;
}
static void
rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
@ -527,6 +543,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
desc_info->qsel = qsel;
desc_info->ch_dma = ch_dma;
desc_info->port = desc_info->hiq ? rtwvif->port : 0;
desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req);
desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL;
desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE;
@ -669,27 +686,14 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev,
desc_info->bk = true;
}
static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
struct ieee80211_vif *vif = tx_req->vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_sta *sta = tx_req->sta;
struct rtw89_sta *rtwsta;
if (!sta)
return rtwvif->mac_id;
rtwsta = (struct rtw89_sta *)sta->drv_priv;
return rtwsta->mac_id;
}
static void
rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
struct ieee80211_vif *vif = tx_req->vif;
struct ieee80211_sta *sta = tx_req->sta;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
@ -707,6 +711,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
desc_info->qsel = qsel;
desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req);
desc_info->port = desc_info->hiq ? rtwvif->port : 0;
desc_info->er_cap = rtwsta ? rtwsta->er_cap : false;
/* enable wd_info for AMPDU */
desc_info->en_wd_info = true;
@ -1006,7 +1011,9 @@ static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info)
static __le32 rtw89_build_txwd_info0_v1(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port);
FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port) |
FIELD_PREP(RTW89_TXWD_INFO0_DATA_ER, desc_info->er_cap) |
FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW_ER, 0);
return cpu_to_le32(dword);
}
@ -2585,6 +2592,12 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
rtw89_mac_bf_monitor_calc(rtwdev, sta, false);
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
if (bss_conf->he_support &&
!(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE))
rtwsta->er_cap = true;
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
BTC_ROLE_MSTS_STA_CONN_END);
rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template);
@ -3124,6 +3137,8 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work);
INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work);
rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0);
if (!rtwdev->txq_wq)
return -ENOMEM;
spin_lock_init(&rtwdev->ba_lock);
spin_lock_init(&rtwdev->rpwm_lock);
mutex_init(&rtwdev->mutex);
@ -3149,6 +3164,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
ret = rtw89_load_firmware(rtwdev);
if (ret) {
rtw89_warn(rtwdev, "no firmware loaded\n");
destroy_workqueue(rtwdev->txq_wq);
return ret;
}
rtw89_ser_init(rtwdev);

View file

@ -816,6 +816,7 @@ struct rtw89_tx_desc_info {
#define RTW89_MGMT_HW_SEQ_MODE 1
bool hiq;
u8 port;
bool er_cap;
};
struct rtw89_core_tx_request {
@ -1263,6 +1264,7 @@ union rtw89_btc_bt_state_map {
#define BTC_BT_RSSI_THMAX 4
#define BTC_BT_AFH_GROUP 12
#define BTC_BT_AFH_LE_GROUP 5
struct rtw89_btc_bt_link_info {
struct rtw89_btc_u8_sta_chg profile_cnt;
@ -1278,6 +1280,7 @@ struct rtw89_btc_bt_link_info {
u8 golden_rx_shift[BTC_PROFILE_MAX];
u8 rssi_state[BTC_BT_RSSI_THMAX];
u8 afh_map[BTC_BT_AFH_GROUP];
u8 afh_map_le[BTC_BT_AFH_LE_GROUP];
u32 role_sw: 1;
u32 slave_role: 1;
@ -1437,7 +1440,7 @@ struct rtw89_btc_cx {
};
struct rtw89_btc_fbtc_tdma {
u8 type; /* chip_info::fcxtdma_ver */
u8 type; /* btc_ver::fcxtdma */
u8 rxflctrl;
u8 txpause;
u8 wtgle_n;
@ -1447,13 +1450,18 @@ struct rtw89_btc_fbtc_tdma {
u8 option_ctrl;
} __packed;
struct rtw89_btc_fbtc_tdma_v1 {
u8 fver; /* chip_info::fcxtdma_ver */
struct rtw89_btc_fbtc_tdma_v3 {
u8 fver; /* btc_ver::fcxtdma */
u8 rsvd;
__le16 rsvd1;
struct rtw89_btc_fbtc_tdma tdma;
} __packed;
union rtw89_btc_fbtc_tdma_le32 {
struct rtw89_btc_fbtc_tdma v1;
struct rtw89_btc_fbtc_tdma_v3 v3;
};
#define CXMREG_MAX 30
#define FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/
#define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */
@ -1472,8 +1480,8 @@ enum rtw89_btc_bt_sta_counter {
BTC_BCNT_STA_MAX
};
struct rtw89_btc_fbtc_rpt_ctrl {
u16 fver; /* chip_info::fcxbtcrpt_ver */
struct rtw89_btc_fbtc_rpt_ctrl_v1 {
u16 fver; /* btc_ver::fcxbtcrpt */
u16 rpt_cnt; /* tmr counters */
u32 wl_fw_coex_ver; /* match which driver's coex version */
u32 wl_fw_cx_offload;
@ -1504,6 +1512,20 @@ struct rtw89_btc_fbtc_rpt_ctrl_info {
__le32 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */
} __packed;
struct rtw89_btc_fbtc_rpt_ctrl_info_v5 {
__le32 cx_ver; /* match which driver's coex version */
__le32 fw_ver;
__le32 en; /* report map */
__le16 cnt; /* fw report counter */
__le16 cnt_c2h; /* fw send c2h counter */
__le16 cnt_h2c; /* fw recv h2c counter */
__le16 len_c2h; /* The total length of the last C2H */
__le16 cnt_aoac_rf_on; /* rf-on counter for aoac switch notify */
__le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */
} __packed;
struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info {
__le32 cx_ver; /* match which driver's coex version */
__le32 cx_offload;
@ -1525,7 +1547,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox {
struct rtw89_btc_fbtc_rpt_ctrl_a2dp_empty a2dp;
} __packed;
struct rtw89_btc_fbtc_rpt_ctrl_v1 {
struct rtw89_btc_fbtc_rpt_ctrl_v4 {
u8 fver;
u8 rsvd;
__le16 rsvd1;
@ -1536,6 +1558,24 @@ struct rtw89_btc_fbtc_rpt_ctrl_v1 {
struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX];
} __packed;
struct rtw89_btc_fbtc_rpt_ctrl_v5 {
u8 fver;
u8 rsvd;
__le16 rsvd1;
u8 gnt_val[RTW89_PHY_MAX][4];
__le16 bt_cnt[BTC_BCNT_STA_MAX];
struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info;
struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
} __packed;
union rtw89_btc_fbtc_rpt_ctrl_ver_info {
struct rtw89_btc_fbtc_rpt_ctrl_v1 v1;
struct rtw89_btc_fbtc_rpt_ctrl_v4 v4;
struct rtw89_btc_fbtc_rpt_ctrl_v5 v5;
};
enum rtw89_fbtc_ext_ctrl_type {
CXECTL_OFF = 0x0, /* tdma off */
CXECTL_B2 = 0x1, /* allow B2 (beacon-early) */
@ -1571,6 +1611,36 @@ enum rtw89_btc_cxst_state {
CXST_MAX = 0x12,
};
enum rtw89_btc_cxevnt {
CXEVNT_TDMA_ENTRY = 0x0,
CXEVNT_WL_TMR,
CXEVNT_B1_TMR,
CXEVNT_B2_TMR,
CXEVNT_B3_TMR,
CXEVNT_B4_TMR,
CXEVNT_W2B_TMR,
CXEVNT_B2W_TMR,
CXEVNT_BCN_EARLY,
CXEVNT_A2DP_EMPTY,
CXEVNT_LK_END,
CXEVNT_RX_ISR,
CXEVNT_RX_FC0,
CXEVNT_RX_FC1,
CXEVNT_BT_RELINK,
CXEVNT_BT_RETRY,
CXEVNT_E2G,
CXEVNT_E5G,
CXEVNT_EBT,
CXEVNT_ENULL,
CXEVNT_DRV_WLK,
CXEVNT_BCN_OK,
CXEVNT_BT_CHANGE,
CXEVNT_EBT_EXTEND,
CXEVNT_E2G_NULL1,
CXEVNT_B1FDD_TMR,
CXEVNT_MAX
};
enum {
CXBCN_ALL = 0x0,
CXBCN_ALL_OK,
@ -1604,9 +1674,14 @@ enum { /* STEP TYPE */
CXSTEP_MAX,
};
enum rtw89_btc_afh_map_type { /*AFH MAP TYPE */
RPT_BT_AFH_SEQ_LEGACY = 0x10,
RPT_BT_AFH_SEQ_LE = 0x20
};
#define BTC_DBG_MAX1 32
struct rtw89_btc_fbtc_gpio_dbg {
u8 fver; /* chip_info::fcxgpiodbg_ver */
u8 fver; /* btc_ver::fcxgpiodbg */
u8 rsvd;
u16 rsvd2;
u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */
@ -1615,7 +1690,7 @@ struct rtw89_btc_fbtc_gpio_dbg {
} __packed;
struct rtw89_btc_fbtc_mreg_val {
u8 fver; /* chip_info::fcxmreg_ver */
u8 fver; /* btc_ver::fcxmreg */
u8 reg_num;
__le16 rsvd;
__le32 mreg_val[CXMREG_MAX];
@ -1638,7 +1713,7 @@ struct rtw89_btc_fbtc_slot {
} __packed;
struct rtw89_btc_fbtc_slots {
u8 fver; /* chip_info::fcxslots_ver */
u8 fver; /* btc_ver::fcxslots */
u8 tbl_num;
__le16 rsvd;
__le32 update_map;
@ -1651,8 +1726,8 @@ struct rtw89_btc_fbtc_step {
__le16 difft;
} __packed;
struct rtw89_btc_fbtc_steps {
u8 fver; /* chip_info::fcxstep_ver */
struct rtw89_btc_fbtc_steps_v2 {
u8 fver; /* btc_ver::fcxstep */
u8 rsvd;
__le16 cnt;
__le16 pos_old;
@ -1660,7 +1735,7 @@ struct rtw89_btc_fbtc_steps {
struct rtw89_btc_fbtc_step step[FCXMAX_STEP];
} __packed;
struct rtw89_btc_fbtc_steps_v1 {
struct rtw89_btc_fbtc_steps_v3 {
u8 fver;
u8 en;
__le16 rsvd;
@ -1668,8 +1743,13 @@ struct rtw89_btc_fbtc_steps_v1 {
struct rtw89_btc_fbtc_step step[FCXMAX_STEP];
} __packed;
struct rtw89_btc_fbtc_cysta { /* statistics for cycles */
u8 fver; /* chip_info::fcxcysta_ver */
union rtw89_btc_fbtc_steps_info {
struct rtw89_btc_fbtc_steps_v2 v2;
struct rtw89_btc_fbtc_steps_v3 v3;
};
struct rtw89_btc_fbtc_cysta_v2 { /* statistics for cycles */
u8 fver; /* btc_ver::fcxcysta */
u8 rsvd;
__le16 cycles; /* total cycle number */
__le16 cycles_a2dp[CXT_FLCTRL_MAX];
@ -1717,6 +1797,17 @@ struct rtw89_btc_fbtc_a2dp_trx_stat {
u8 rsvd2;
} __packed;
struct rtw89_btc_fbtc_a2dp_trx_stat_v4 {
u8 empty_cnt;
u8 retry_cnt;
u8 tx_rate;
u8 tx_cnt;
u8 ack_cnt;
u8 nack_cnt;
u8 no_empty_cnt;
u8 rsvd;
} __packed;
struct rtw89_btc_fbtc_cycle_a2dp_empty_info {
__le16 cnt; /* a2dp empty cnt */
__le16 cnt_timeout; /* a2dp empty timeout cnt*/
@ -1730,7 +1821,35 @@ struct rtw89_btc_fbtc_cycle_leak_info {
__le16 tmax; /* max leak-slot time */
} __packed;
struct rtw89_btc_fbtc_cysta_v1 { /* statistics for cycles */
#define RTW89_BTC_FDDT_PHASE_CYCLE GENMASK(9, 0)
#define RTW89_BTC_FDDT_TRAIN_STEP GENMASK(15, 10)
struct rtw89_btc_fbtc_cycle_fddt_info {
__le16 train_cycle;
__le16 tp;
s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */
s8 bt_tx_power; /* decrease Tx power (dB) */
s8 bt_rx_gain; /* LNA constrain level */
u8 no_empty_cnt;
u8 rssi; /* [7:4] -> bt_rssi_level, [3:0]-> wl_rssi_level */
u8 cn; /* condition_num */
u8 train_status; /* [7:4]-> train-state, [3:0]-> train-phase */
u8 train_result; /* refer to enum btc_fddt_check_map */
} __packed;
#define RTW89_BTC_FDDT_CELL_TRAIN_STATE GENMASK(3, 0)
#define RTW89_BTC_FDDT_CELL_TRAIN_PHASE GENMASK(7, 4)
struct rtw89_btc_fbtc_fddt_cell_status {
s8 wl_tx_pwr;
s8 bt_tx_pwr;
s8 bt_rx_gain;
u8 state_phase; /* [0:3] train state, [4:7] train phase */
} __packed;
struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */
u8 fver;
u8 rsvd;
__le16 cycles; /* total cycle number */
@ -1748,8 +1867,41 @@ struct rtw89_btc_fbtc_cysta_v1 { /* statistics for cycles */
__le32 except_map;
} __packed;
struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */
u8 fver; /* chip_info::fcxnullsta_ver */
#define FDD_TRAIN_WL_DIRECTION 2
#define FDD_TRAIN_WL_RSSI_LEVEL 5
#define FDD_TRAIN_BT_RSSI_LEVEL 5
struct rtw89_btc_fbtc_cysta_v4 { /* statistics for cycles */
u8 fver;
u8 rsvd;
u8 collision_cnt; /* counter for event/timer occur at the same time */
u8 except_cnt;
__le16 skip_cnt;
__le16 cycles; /* total cycle number */
__le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */
__le16 slot_cnt[CXST_MAX]; /* slot count */
__le16 bcn_cnt[CXBCN_MAX];
struct rtw89_btc_fbtc_cycle_time_info cycle_time;
struct rtw89_btc_fbtc_cycle_leak_info leak_slot;
struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept;
struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX];
struct rtw89_btc_fbtc_cycle_fddt_info fddt_trx[BTC_CYCLE_SLOT_MAX];
struct rtw89_btc_fbtc_fddt_cell_status fddt_cells[FDD_TRAIN_WL_DIRECTION]
[FDD_TRAIN_WL_RSSI_LEVEL]
[FDD_TRAIN_BT_RSSI_LEVEL];
__le32 except_map;
} __packed;
union rtw89_btc_fbtc_cysta_info {
struct rtw89_btc_fbtc_cysta_v2 v2;
struct rtw89_btc_fbtc_cysta_v3 v3;
struct rtw89_btc_fbtc_cysta_v4 v4;
};
struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */
u8 fver; /* btc_ver::fcxnullsta */
u8 rsvd;
__le16 rsvd2;
__le32 max_t[2]; /* max_t for 0:null0/1:null1 */
@ -1757,8 +1909,8 @@ struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */
__le32 result[2][4]; /* 0:fail, 1:ok, 2:on_time, 3:retry */
} __packed;
struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */
u8 fver; /* chip_info::fcxnullsta_ver */
struct rtw89_btc_fbtc_cynullsta_v2 { /* cycle null statistics */
u8 fver; /* btc_ver::fcxnullsta */
u8 rsvd;
__le16 rsvd2;
__le32 max_t[2]; /* max_t for 0:null0/1:null1 */
@ -1766,8 +1918,13 @@ struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */
__le32 result[2][5]; /* 0:fail, 1:ok, 2:on_time, 3:retry, 4:tx */
} __packed;
union rtw89_btc_fbtc_cynullsta_info {
struct rtw89_btc_fbtc_cynullsta_v1 v1; /* info from fw */
struct rtw89_btc_fbtc_cynullsta_v2 v2;
};
struct rtw89_btc_fbtc_btver {
u8 fver; /* chip_info::fcxbtver_ver */
u8 fver; /* btc_ver::fcxbtver */
u8 rsvd;
__le16 rsvd2;
__le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */
@ -1776,14 +1933,14 @@ struct rtw89_btc_fbtc_btver {
} __packed;
struct rtw89_btc_fbtc_btscan {
u8 fver; /* chip_info::fcxbtscan_ver */
u8 fver; /* btc_ver::fcxbtscan */
u8 rsvd;
__le16 rsvd2;
u8 scan[6];
} __packed;
struct rtw89_btc_fbtc_btafh {
u8 fver; /* chip_info::fcxbtafh_ver */
u8 fver; /* btc_ver::fcxbtafh */
u8 rsvd;
__le16 rsvd2;
u8 afh_l[4]; /*bit0:2402, bit1: 2403.... bit31:2433 */
@ -1791,8 +1948,20 @@ struct rtw89_btc_fbtc_btafh {
u8 afh_h[4]; /*bit0:2466, bit1:2467......bit14:2480 */
} __packed;
struct rtw89_btc_fbtc_btafh_v2 {
u8 fver; /* btc_ver::fcxbtafh */
u8 rsvd;
u8 rsvd2;
u8 map_type;
u8 afh_l[4];
u8 afh_m[4];
u8 afh_h[4];
u8 afh_le_a[4];
u8 afh_le_b[4];
} __packed;
struct rtw89_btc_fbtc_btdevinfo {
u8 fver; /* chip_info::fcxbtdevinfo_ver */
u8 fver; /* btc_ver::fcxbtdevinfo */
u8 rsvd;
__le16 vendor_id;
__le32 dev_name; /* only 24 bits valid */
@ -1911,20 +2080,19 @@ struct rtw89_btc_rpt_cmn_info {
u8 valid;
} __packed;
union rtw89_btc_fbtc_btafh_info {
struct rtw89_btc_fbtc_btafh v1;
struct rtw89_btc_fbtc_btafh_v2 v2;
};
struct rtw89_btc_report_ctrl_state {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
union {
struct rtw89_btc_fbtc_rpt_ctrl finfo; /* info from fw for 52A*/
struct rtw89_btc_fbtc_rpt_ctrl_v1 finfo_v1; /* info from fw for 52C*/
};
union rtw89_btc_fbtc_rpt_ctrl_ver_info finfo;
};
struct rtw89_btc_rpt_fbtc_tdma {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
union {
struct rtw89_btc_fbtc_tdma finfo; /* info from fw */
struct rtw89_btc_fbtc_tdma_v1 finfo_v1; /* info from fw for 52C*/
};
union rtw89_btc_fbtc_tdma_le32 finfo;
};
struct rtw89_btc_rpt_fbtc_slots {
@ -1934,26 +2102,17 @@ struct rtw89_btc_rpt_fbtc_slots {
struct rtw89_btc_rpt_fbtc_cysta {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
union {
struct rtw89_btc_fbtc_cysta finfo; /* info from fw for 52A*/
struct rtw89_btc_fbtc_cysta_v1 finfo_v1; /* info from fw for 52C*/
};
union rtw89_btc_fbtc_cysta_info finfo;
};
struct rtw89_btc_rpt_fbtc_step {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
union {
struct rtw89_btc_fbtc_steps finfo; /* info from fw */
struct rtw89_btc_fbtc_steps_v1 finfo_v1; /* info from fw */
};
union rtw89_btc_fbtc_steps_info finfo; /* info from fw */
};
struct rtw89_btc_rpt_fbtc_nullsta {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
union {
struct rtw89_btc_fbtc_cynullsta finfo; /* info from fw */
struct rtw89_btc_fbtc_cynullsta_v1 finfo_v1; /* info from fw */
};
union rtw89_btc_fbtc_cynullsta_info finfo;
};
struct rtw89_btc_rpt_fbtc_mreg {
@ -1978,7 +2137,7 @@ struct rtw89_btc_rpt_fbtc_btscan {
struct rtw89_btc_rpt_fbtc_btafh {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
struct rtw89_btc_fbtc_btafh finfo; /* info from fw */
union rtw89_btc_fbtc_btafh_info finfo;
};
struct rtw89_btc_rpt_fbtc_btdev {
@ -2018,9 +2177,35 @@ struct rtw89_btc_btf_fwinfo {
struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev;
};
struct rtw89_btc_ver {
enum rtw89_core_chip_id chip_id;
u32 fw_ver_code;
u8 fcxbtcrpt;
u8 fcxtdma;
u8 fcxslots;
u8 fcxcysta;
u8 fcxstep;
u8 fcxnullsta;
u8 fcxmreg;
u8 fcxgpiodbg;
u8 fcxbtver;
u8 fcxbtscan;
u8 fcxbtafh;
u8 fcxbtdevinfo;
u8 fwlrole;
u8 frptmap;
u8 fcxctrl;
u16 info_buf;
u8 max_role_num;
};
#define RTW89_BTC_POLICY_MAXLEN 512
struct rtw89_btc {
const struct rtw89_btc_ver *ver;
struct rtw89_btc_cx cx;
struct rtw89_btc_dm dm;
struct rtw89_btc_ctrl ctrl;
@ -2194,6 +2379,7 @@ struct rtw89_sec_cam_entry {
struct rtw89_sta {
u8 mac_id;
bool disassoc;
bool er_cap;
struct rtw89_dev *rtwdev;
struct rtw89_vif *rtwvif;
struct rtw89_ra_info ra;
@ -2728,20 +2914,6 @@ struct rtw89_chip_info {
u8 btcx_desired;
u8 scbd;
u8 mailbox;
u16 btc_fwinfo_buf;
u8 fcxbtcrpt_ver;
u8 fcxtdma_ver;
u8 fcxslots_ver;
u8 fcxcysta_ver;
u8 fcxstep_ver;
u8 fcxnullsta_ver;
u8 fcxmreg_ver;
u8 fcxgpiodbg_ver;
u8 fcxbtver_ver;
u8 fcxbtscan_ver;
u8 fcxbtafh_ver;
u8 fcxbtdevinfo_ver;
u8 afh_guard_ch;
const u8 *wl_rssi_thres;
@ -2771,6 +2943,7 @@ struct rtw89_chip_info {
u8 dcfo_comp_sft;
const struct rtw89_imr_info *imr_info;
const struct rtw89_rrsr_cfgs *rrsr_cfgs;
u32 bss_clr_map_reg;
u32 dma_ch_mask;
const struct wiphy_wowlan_support *wowlan_stub;
};

View file

@ -91,6 +91,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
const u8 *fwdynhdr;
const u8 *bin;
u32 base_hdr_len;
u32 mssc_len = 0;
u32 i;
if (!info)
@ -120,6 +121,14 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
fw += RTW89_FW_HDR_SIZE;
section_info = info->section_info;
for (i = 0; i < info->section_num; i++) {
section_info->type = GET_FWSECTION_HDR_SECTIONTYPE(fw);
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
section_info->mssc = GET_FWSECTION_HDR_MSSC(fw);
mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
} else {
section_info->mssc = 0;
}
section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw);
if (GET_FWSECTION_HDR_CHECKSUM(fw))
section_info->len += FWDL_SECTION_CHKSUM_LEN;
@ -132,7 +141,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
section_info++;
}
if (fw_end != bin) {
if (fw_end != bin + mssc_len) {
rtw89_err(rtwdev, "[ERR]fw bin size\n");
return -EINVAL;
}
@ -343,6 +352,8 @@ int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
rtw89_fw_recognize_features(rtwdev);
rtw89_coex_recognize_ver(rtwdev);
return 0;
}
@ -1807,33 +1818,36 @@ int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev)
#define PORT_DATA_OFFSET 4
#define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12
#define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR)
#define H2C_LEN_CXDRVINFO_ROLE_V1 (4 + 16 * RTW89_PORT_NUM + \
H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + \
H2C_LEN_CXDRVHDR)
#define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \
(4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR)
int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
struct rtw89_btc_wl_active_role *active = role_info->active_role;
struct sk_buff *skb;
u32 len;
u8 offset = 0;
u8 *cmd;
int ret;
int i;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE);
len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num);
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
return -ENOMEM;
}
skb_put(skb, H2C_LEN_CXDRVINFO_ROLE);
skb_put(skb, len);
cmd = skb->data;
RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
@ -1870,7 +1884,7 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
SET_DRV_INFO, 0, 0,
H2C_LEN_CXDRVINFO_ROLE);
len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@ -1885,28 +1899,35 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
return ret;
}
#define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \
(4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR)
int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
struct sk_buff *skb;
u32 len;
u8 *cmd, offset;
int ret;
int i;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE_V1);
len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num);
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
return -ENOMEM;
}
skb_put(skb, H2C_LEN_CXDRVINFO_ROLE_V1);
skb_put(skb, len);
cmd = skb->data;
RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVHDR);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
@ -1942,7 +1963,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
}
offset = H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
@ -1953,7 +1974,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
SET_DRV_INFO, 0, 0,
H2C_LEN_CXDRVINFO_ROLE_V1);
len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@ -1971,8 +1992,8 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
#define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_ctrl *ctrl = &btc->ctrl;
struct sk_buff *skb;
u8 *cmd;
@ -1992,7 +2013,7 @@ int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev)
RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual);
RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt);
RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun);
if (chip->chip_id == RTL8852A)
if (ver->fcxctrl == 0)
RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@ -2665,8 +2686,10 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
list_add_tail(&info->list, &scan_info->pkt_list[band]);
ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
if (ret)
if (ret) {
kfree_skb(new);
goto out;
}
kfree_skb(new);
}
@ -2738,7 +2761,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
if (ssid_num == 1 && req->ssids[0].ssid_len == 0) {
ch_info->tx_pkt = false;
if (!req->duration_mandatory)
ch_info->period -= RTW89_DWELL_TIME;
ch_info->period -= RTW89_DWELL_TIME_6G;
}
}
@ -2791,7 +2814,8 @@ static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
if (req->duration_mandatory)
ch_info->period = req->duration;
else if (channel->band == NL80211_BAND_6GHZ)
ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME;
ch_info->period = RTW89_CHANNEL_TIME_6G +
RTW89_DWELL_TIME_6G;
else
ch_info->period = RTW89_CHANNEL_TIME;

View file

@ -171,6 +171,8 @@ struct rtw89_fw_hdr_section_info {
const u8 *addr;
u32 len;
u32 dladdr;
u32 mssc;
u8 type;
};
struct rtw89_fw_bin_info {
@ -203,6 +205,7 @@ struct rtw89_h2creg_sch_tx_en {
#define RTW89_DFS_CHAN_TIME 105
#define RTW89_OFF_CHAN_TIME 100
#define RTW89_DWELL_TIME 20
#define RTW89_DWELL_TIME_6G 10
#define RTW89_SCAN_WIDTH 0
#define RTW89_SCANOFLD_MAX_SSID 8
#define RTW89_SCANOFLD_MAX_IE_LEN 512
@ -480,14 +483,21 @@ static inline void RTW89_SET_EDCA_PARAM(void *cmd, u32 val)
#define FW_EDCA_PARAM_CWMIN_MSK GENMASK(11, 8)
#define FW_EDCA_PARAM_AIFS_MSK GENMASK(7, 0)
#define FWDL_SECURITY_SECTION_TYPE 9
#define FWDL_SECURITY_SIGLEN 512
#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0))
#define GET_FWSECTION_HDR_SECTIONTYPE(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(27, 24))
#define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 0))
#define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(28))
#define GET_FWSECTION_HDR_REDL(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(29))
#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0))
#define GET_FWSECTION_HDR_MSSC(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 2), GENMASK(31, 0))
#define GET_FW_HDR_MAJOR_VERSION(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(7, 0))

View file

@ -4865,9 +4865,16 @@ EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v1);
bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev)
{
u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3);
const struct rtw89_chip_info *chip = rtwdev->chip;
u8 val = 0;
return FIELD_GET(B_AX_LTE_MUX_CTRL_PATH >> 24, val);
if (chip->chip_id == RTL8852C)
return false;
else if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B)
val = rtw89_read8_mask(rtwdev, R_AX_SYS_SDIO_CTRL + 3,
B_AX_LTE_MUX_CTRL_PATH >> 24);
return !!val;
}
u16 rtw89_mac_get_plt_cnt(struct rtw89_dev *rtwdev, u8 band)

View file

@ -1384,7 +1384,7 @@ static int rtw89_pci_ops_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx
return 0;
}
static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = {
const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM] = {
[RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2},
@ -1399,11 +1399,24 @@ static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = {
[RTW89_TXCH_CH11] = {.start_idx = 55, .max_num = 5, .min_num = 1},
[RTW89_TXCH_CH12] = {.start_idx = 60, .max_num = 4, .min_num = 1},
};
EXPORT_SYMBOL(rtw89_bd_ram_table_dual);
const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM] = {
[RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2},
[RTW89_TXCH_ACH3] = {.start_idx = 15, .max_num = 5, .min_num = 2},
[RTW89_TXCH_CH8] = {.start_idx = 20, .max_num = 4, .min_num = 1},
[RTW89_TXCH_CH9] = {.start_idx = 24, .max_num = 4, .min_num = 1},
[RTW89_TXCH_CH12] = {.start_idx = 28, .max_num = 4, .min_num = 1},
};
EXPORT_SYMBOL(rtw89_bd_ram_table_single);
static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_pci_info *info = rtwdev->pci_info;
const struct rtw89_pci_bd_ram *bd_ram_table = *info->bd_ram_table;
struct rtw89_pci_tx_ring *tx_ring;
struct rtw89_pci_rx_ring *rx_ring;
struct rtw89_pci_dma_ring *bd_ring;

View file

@ -750,6 +750,12 @@ struct rtw89_pci_ch_dma_addr_set {
struct rtw89_pci_ch_dma_addr rx[RTW89_RXCH_NUM];
};
struct rtw89_pci_bd_ram {
u8 start_idx;
u8 max_num;
u8 min_num;
};
struct rtw89_pci_info {
enum mac_ax_bd_trunc_mode txbd_trunc_mode;
enum mac_ax_bd_trunc_mode rxbd_trunc_mode;
@ -785,6 +791,7 @@ struct rtw89_pci_info {
u32 tx_dma_ch_mask;
const struct rtw89_pci_bd_idx_addr *bd_idx_addr_low_power;
const struct rtw89_pci_ch_dma_addr_set *dma_addr_set;
const struct rtw89_pci_bd_ram (*bd_ram_table)[RTW89_TXCH_NUM];
int (*ltr_set)(struct rtw89_dev *rtwdev, bool en);
u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev,
@ -798,12 +805,6 @@ struct rtw89_pci_info {
struct rtw89_pci_isrs *isrs);
};
struct rtw89_pci_bd_ram {
u8 start_idx;
u8 max_num;
u8 min_num;
};
struct rtw89_pci_tx_data {
dma_addr_t dma;
};
@ -1057,6 +1058,8 @@ static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val)
extern const struct dev_pm_ops rtw89_pm_ops;
extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set;
extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1;
extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM];
extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM];
struct pci_device_id;

View file

@ -367,6 +367,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
}
ra->bw_cap = bw_mode;
ra->er_cap = rtwsta->er_cap;
ra->mode_ctrl = mode;
ra->macid = rtwsta->mac_id;
ra->stbc_cap = stbc_en;
@ -4116,6 +4117,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
u8 bss_color;
@ -4124,11 +4126,11 @@ void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif
bss_color = vif->bss_conf.he_bss_color.color;
rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0, 0x1,
rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_VLD0, 0x1,
phy_idx);
rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_TGT, bss_color,
phy_idx);
rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_STAID,
rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_TGT,
bss_color, phy_idx);
rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_STAID,
vif->cfg.aid, phy_idx);
}

View file

@ -3559,6 +3559,7 @@
#define RR_MOD_IQK GENMASK(19, 4)
#define RR_MOD_DPK GENMASK(19, 5)
#define RR_MOD_MASK GENMASK(19, 16)
#define RR_MOD_DCK GENMASK(14, 10)
#define RR_MOD_RGM GENMASK(13, 4)
#define RR_MOD_V_DOWN 0x0
#define RR_MOD_V_STANDBY 0x1
@ -3572,6 +3573,7 @@
#define RR_MOD_NBW GENMASK(15, 14)
#define RR_MOD_M_RXG GENMASK(13, 4)
#define RR_MOD_M_RXBB GENMASK(9, 5)
#define RR_MOD_LO_SEL BIT(1)
#define RR_MODOPT 0x01
#define RR_MODOPT_M_TXPWR GENMASK(5, 0)
#define RR_WLSEL 0x02
@ -3638,6 +3640,7 @@
#define RR_LUTWA_M2 GENMASK(4, 0)
#define RR_LUTWD1 0x3e
#define RR_LUTWD0 0x3f
#define RR_LUTWD0_MB GENMASK(11, 6)
#define RR_LUTWD0_LB GENMASK(5, 0)
#define RR_TM 0x42
#define RR_TM_TRI BIT(19)
@ -3671,6 +3674,8 @@
#define RR_TXRSV_GAPK BIT(19)
#define RR_BIAS 0x5e
#define RR_BIAS_GAPK BIT(19)
#define RR_TXAC 0x5f
#define RR_TXAC_IQG GENMASK(3, 0)
#define RR_BIASA 0x60
#define RR_BIASA_TXG GENMASK(15, 12)
#define RR_BIASA_TXA GENMASK(19, 16)
@ -3729,10 +3734,14 @@
#define RR_XALNA2_SW2 GENMASK(9, 8)
#define RR_XALNA2_SW GENMASK(1, 0)
#define RR_DCK 0x92
#define RR_DCK_S1 GENMASK(19, 16)
#define RR_DCK_TIA GENMASK(15, 9)
#define RR_DCK_DONE GENMASK(7, 5)
#define RR_DCK_FINE BIT(1)
#define RR_DCK_LV BIT(0)
#define RR_DCK1 0x93
#define RR_DCK1_S1 GENMASK(19, 16)
#define RR_DCK1_TIA GENMASK(15, 9)
#define RR_DCK1_DONE BIT(5)
#define RR_DCK1_CLR GENMASK(3, 0)
#define RR_DCK1_SEL BIT(3)
@ -3781,11 +3790,14 @@
#define RR_LUTDBG 0xdf
#define RR_LUTDBG_TIA BIT(12)
#define RR_LUTDBG_LOK BIT(2)
#define RR_LUTPLL 0xec
#define RR_CAL_RW BIT(19)
#define RR_LUTWE2 0xee
#define RR_LUTWE2_RTXBW BIT(2)
#define RR_LUTWE 0xef
#define RR_LUTWE_LOK BIT(2)
#define RR_RFC 0xf0
#define RR_WCAL BIT(16)
#define RR_RFC_CKEN BIT(1)
#define R_UPD_P0 0x0000
@ -4090,12 +4102,13 @@
#define R_MUIC 0x40F8
#define B_MUIC_EN BIT(0)
#define R_DCFO 0x4264
#define B_DCFO GENMASK(1, 0)
#define B_DCFO GENMASK(7, 0)
#define R_SEG0CSI 0x42AC
#define B_SEG0CSI_IDX GENMASK(11, 0)
#define B_SEG0CSI_IDX GENMASK(10, 0)
#define R_SEG0CSI_EN 0x42C4
#define B_SEG0CSI_EN BIT(23)
#define R_BSS_CLR_MAP 0x43ac
#define R_BSS_CLR_MAP_V1 0x43B0
#define B_BSS_CLR_MAP_VLD0 BIT(28)
#define B_BSS_CLR_MAP_TGT GENMASK(27, 22)
#define B_BSS_CLR_MAP_STAID GENMASK(21, 11)
@ -4725,6 +4738,7 @@
#define R_DRCK_FH 0xC094
#define B_DRCK_LAT BIT(9)
#define R_DRCK 0xC0C4
#define B_DRCK_MUL GENMASK(21, 17)
#define B_DRCK_IDLE BIT(9)
#define B_DRCK_EN BIT(6)
#define B_DRCK_VAL GENMASK(4, 0)
@ -4742,9 +4756,13 @@
#define B_PATH0_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26)
#define R_P0_CFCH_BW0 0xC0D4
#define B_P0_CFCH_BW0 GENMASK(27, 26)
#define B_P0_CFCH_EN GENMASK(14, 11)
#define B_P0_CFCH_CTL GENMASK(10, 7)
#define R_P0_CFCH_BW1 0xC0D8
#define B_P0_CFCH_EX BIT(13)
#define B_P0_CFCH_BW1 GENMASK(8, 5)
#define R_ADCMOD 0xC0E8
#define B_ADCMOD_LP GENMASK(31, 16)
#define R_ADDCK0D 0xC0F0
#define B_ADDCK0D_VAL2 GENMASK(31, 26)
#define B_ADDCK0D_VAL GENMASK(25, 16)

View file

@ -1035,7 +1035,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch)
0x210);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL,
0x210);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x7c0);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x7c0);
rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX,
B_P0_NBIIDX_NOTCH_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX,
@ -1047,7 +1047,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch)
0x210);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL,
0x210);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x40);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x40);
rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX,
B_P0_NBIIDX_NOTCH_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX,
@ -1059,7 +1059,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch)
0x2d0);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL,
0x2d0);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x740);
rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x740);
rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX,
B_P0_NBIIDX_NOTCH_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX,
@ -1878,9 +1878,13 @@ static
void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_cx *cx = &btc->cx;
u32 val;
if (ver->fcxbtcrpt != 1)
return;
val = rtw89_read32(rtwdev, R_AX_BT_STAST_HIGH);
cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val);
cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val);
@ -2106,20 +2110,6 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,
.btc_fwinfo_buf = 1024,
.fcxbtcrpt_ver = 1,
.fcxtdma_ver = 1,
.fcxslots_ver = 1,
.fcxcysta_ver = 2,
.fcxstep_ver = 2,
.fcxnullsta_ver = 1,
.fcxmreg_ver = 1,
.fcxgpiodbg_ver = 1,
.fcxbtver_ver = 1,
.fcxbtscan_ver = 1,
.fcxbtafh_ver = 1,
.fcxbtdevinfo_ver = 1,
.afh_guard_ch = 6,
.wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres,
@ -2149,6 +2139,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.dcfo_comp_sft = 3,
.imr_info = &rtw8852a_imr_info,
.rrsr_cfgs = &rtw8852a_rrsr_cfgs,
.bss_clr_map_reg = R_BSS_CLR_MAP,
.dma_ch_mask = 0,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852a,

View file

@ -1643,7 +1643,7 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[IQK]==========IQK strat!!!!!==========\n");
"[IQK]==========IQK start!!!!!==========\n");
iqk_info->iqk_times++;
iqk_info->kcount = 0;
iqk_info->version = RTW8852A_IQK_VER;

View file

@ -44,6 +44,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set,
.bd_ram_table = &rtw89_bd_ram_table_dual,
.ltr_set = rtw89_pci_ltr_set,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info,

View file

@ -2423,7 +2423,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
.btc_update_bt_cnt = rtw8852b_btc_update_bt_cnt,
.btc_wl_s1_standby = rtw8852b_btc_wl_s1_standby,
.btc_set_wl_rx_gain = rtw8852b_btc_set_wl_rx_gain,
.btc_set_policy = rtw89_btc_set_policy,
.btc_set_policy = rtw89_btc_set_policy_v1,
};
const struct rtw89_chip_info rtw8852b_chip_info = {
@ -2437,6 +2437,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.rsvd_ple_ofst = 0x2f800,
.hfc_param_ini = rtw8852b_hfc_param_ini_pcie,
.dle_mem = rtw8852b_dle_mem_pcie,
.wde_qempty_acq_num = 4,
.wde_qempty_mgq_sel = 4,
.rf_base_addr = {0xe000, 0xf000},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
@ -2483,20 +2485,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.btcx_desired = 0x5,
.scbd = 0x1,
.mailbox = 0x1,
.btc_fwinfo_buf = 1024,
.fcxbtcrpt_ver = 1,
.fcxtdma_ver = 1,
.fcxslots_ver = 1,
.fcxcysta_ver = 2,
.fcxstep_ver = 2,
.fcxnullsta_ver = 1,
.fcxmreg_ver = 1,
.fcxgpiodbg_ver = 1,
.fcxbtver_ver = 1,
.fcxbtscan_ver = 1,
.fcxbtafh_ver = 1,
.fcxbtdevinfo_ver = 1,
.afh_guard_ch = 6,
.wl_rssi_thres = rtw89_btc_8852b_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8852b_bt_rssi_thres,
@ -2525,6 +2514,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.dcfo_comp_sft = 3,
.imr_info = &rtw8852b_imr_info,
.rrsr_cfgs = &rtw8852b_rrsr_cfgs,
.bss_clr_map_reg = R_BSS_CLR_MAP_V1,
.dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),

View file

@ -46,6 +46,7 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11),
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set,
.bd_ram_table = &rtw89_bd_ram_table_single,
.ltr_set = rtw89_pci_ltr_set,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info,

View file

@ -2915,20 +2915,6 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,
.btc_fwinfo_buf = 1280,
.fcxbtcrpt_ver = 4,
.fcxtdma_ver = 3,
.fcxslots_ver = 1,
.fcxcysta_ver = 3,
.fcxstep_ver = 3,
.fcxnullsta_ver = 2,
.fcxmreg_ver = 1,
.fcxgpiodbg_ver = 1,
.fcxbtver_ver = 1,
.fcxbtscan_ver = 1,
.fcxbtafh_ver = 1,
.fcxbtdevinfo_ver = 1,
.afh_guard_ch = 6,
.wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres,
@ -2959,6 +2945,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.dcfo_comp_sft = 5,
.imr_info = &rtw8852c_imr_info,
.rrsr_cfgs = &rtw8852c_rrsr_cfgs,
.bss_clr_map_reg = R_BSS_CLR_MAP,
.dma_ch_mask = 0,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852c,

View file

@ -11,6 +11,15 @@
#include "rtw8852c_rfk_table.h"
#include "rtw8852c_table.h"
struct rxck_def {
u32 ctl;
u32 en;
u32 bw0;
u32 bw1;
u32 mul;
u32 lp;
};
#define _TSSI_DE_MASK GENMASK(21, 12)
static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852C] = {0x5858, 0x7858};
static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852C] = {0x5860, 0x7860};
@ -26,7 +35,7 @@ static const u32 rtw8852c_backup_bb_regs[] = {
};
static const u32 rtw8852c_backup_rf_regs[] = {
0xdf, 0x8f, 0x97, 0xa3, 0x5, 0x10005
0xdf, 0x5f, 0x8f, 0x97, 0xa3, 0x5, 0x10005
};
#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852c_backup_bb_regs)
@ -59,6 +68,13 @@ static const u32 dpk_par_regs[RTW89_DPK_RF_PATH][4] = {
{0x81a8, 0x81c4, 0x81c8, 0x81e8},
};
static const u8 _dck_addr_bs[RF_PATH_NUM_8852C] = {0x0, 0x10};
static const u8 _dck_addr[RF_PATH_NUM_8852C] = {0xc, 0x1c};
static const struct rxck_def _ck480M = {0x8, 0x2, 0x3, 0xf, 0x0, 0x9};
static const struct rxck_def _ck960M = {0x8, 0x2, 0x2, 0x8, 0x0, 0x9};
static const struct rxck_def _ck1920M = {0x8, 0x0, 0x2, 0x4, 0x6, 0x9};
static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n",
@ -337,7 +353,7 @@ static void _dack_reload_by_path(struct rtw89_dev *rtwdev,
(dack->dadck_d[path][index] << 14);
addr = 0xc210 + offset;
rtw89_phy_write32(rtwdev, addr, val32);
rtw89_phy_write32_set(rtwdev, addr, BIT(1));
rtw89_phy_write32_set(rtwdev, addr, BIT(0));
}
static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
@ -437,6 +453,8 @@ static void rtw8852c_txck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
enum adc_ck ck)
{
const struct rxck_def *def;
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0);
if (!force)
@ -444,6 +462,26 @@ static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force,
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1);
switch (ck) {
case ADC_480M:
def = &_ck480M;
break;
case ADC_960M:
def = &_ck960M;
break;
case ADC_1920M:
default:
def = &_ck1920M;
break;
}
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_CTL, def->ctl);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_EN, def->en);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, def->bw0);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, def->bw1);
rtw89_phy_write32_mask(rtwdev, R_DRCK | (path << 8), B_DRCK_MUL, def->mul);
rtw89_phy_write32_mask(rtwdev, R_ADCMOD | (path << 8), B_ADCMOD_LP, def->lp);
}
static bool _check_dack_done(struct rtw89_dev *rtwdev, bool s0)
@ -627,8 +665,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1);
rtw8852c_rxck_force(rtwdev, path, true, ADC_480M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x3);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xf);
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1);
break;
@ -636,8 +672,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1);
rtw8852c_rxck_force(rtwdev, path, true, ADC_960M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xd);
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1);
break;
@ -645,8 +679,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1);
rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb);
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1);
break;
@ -1410,8 +1442,6 @@ static void _iqk_macbb_setting(struct rtw89_dev *rtwdev,
rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_ACK_VAL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xb);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW | (path << 13), B_P0_NRBW_DBG, 0x1);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13);
@ -1536,6 +1566,155 @@ static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool forc
}
}
static void _rx_dck_value_rewrite(struct rtw89_dev *rtwdev, u8 path, u8 addr,
u8 val_i, u8 val_q)
{
u32 ofst_val;
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] rewrite val_i = 0x%x, val_q = 0x%x\n", val_i, val_q);
/* val_i and val_q are 7 bits, and target is 6 bits. */
ofst_val = u32_encode_bits(val_q >> 1, RR_LUTWD0_MB) |
u32_encode_bits(val_i >> 1, RR_LUTWD0_LB);
rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x1);
rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x1);
rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x1);
rtw89_write_rf(rtwdev, path, RR_LUTWA, MASKBYTE0, addr);
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val);
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val);
rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0);
rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x0);
rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x0);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] Final val_i = 0x%x, val_q = 0x%x\n",
u32_get_bits(ofst_val, RR_LUTWD0_LB) << 1,
u32_get_bits(ofst_val, RR_LUTWD0_MB) << 1);
}
static bool _rx_dck_rek_check(struct rtw89_dev *rtwdev, u8 path)
{
u8 i_even_bs, q_even_bs;
u8 i_odd_bs, q_odd_bs;
u8 i_even, q_even;
u8 i_odd, q_odd;
const u8 th = 10;
u8 i;
for (i = 0; i < RF_PATH_NUM_8852C; i++) {
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]);
i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i], i_even_bs, q_even_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]);
i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n",
_dck_addr[i], i_even, q_even);
if (abs(i_even_bs - i_even) > th || abs(q_even_bs - q_even) > th)
return true;
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1);
i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1);
i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n",
_dck_addr[i] + 1, i_odd, q_odd);
if (abs(i_odd_bs - i_odd) > th || abs(q_odd_bs - q_odd) > th)
return true;
}
return false;
}
static void _rx_dck_fix_if_need(struct rtw89_dev *rtwdev, u8 path, u8 addr,
u8 val_i_bs, u8 val_q_bs, u8 val_i, u8 val_q)
{
const u8 th = 10;
if ((abs(val_i_bs - val_i) < th) && (abs(val_q_bs - val_q) <= th)) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] offset check PASS!!\n");
return;
}
if (abs(val_i_bs - val_i) > th) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] val_i over TH (0x%x / 0x%x)\n", val_i_bs, val_i);
val_i = val_i_bs;
}
if (abs(val_q_bs - val_q) > th) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] val_q over TH (0x%x / 0x%x)\n", val_q_bs, val_q);
val_q = val_q_bs;
}
_rx_dck_value_rewrite(rtwdev, path, addr, val_i, val_q);
}
static void _rx_dck_recover(struct rtw89_dev *rtwdev, u8 path)
{
u8 i_even_bs, q_even_bs;
u8 i_odd_bs, q_odd_bs;
u8 i_even, q_even;
u8 i_odd, q_odd;
u8 i;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] ===> recovery\n");
for (i = 0; i < RF_PATH_NUM_8852C; i++) {
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]);
i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1);
i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i], i_even_bs, q_even_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]);
i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n",
_dck_addr[i], i_even, q_even);
_rx_dck_fix_if_need(rtwdev, path, _dck_addr[i],
i_even_bs, q_even_bs, i_even, q_even);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n",
_dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1);
i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA);
q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n",
_dck_addr[i] + 1, i_odd, q_odd);
_rx_dck_fix_if_need(rtwdev, path, _dck_addr[i] + 1,
i_odd_bs, q_odd_bs, i_odd, q_odd);
}
}
static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path)
{
int ret;
@ -1573,11 +1752,42 @@ static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 pat
}
}
static
u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan)
{
u8 target_ch = 0;
if (chan->band_type == RTW89_BAND_5G) {
if (chan->channel >= 36 && chan->channel <= 64) {
target_ch = 100;
} else if (chan->channel >= 100 && chan->channel <= 144) {
target_ch = chan->channel + 32;
if (target_ch > 144)
target_ch = chan->channel + 33;
} else if (chan->channel >= 149 && chan->channel <= 177) {
target_ch = chan->channel - 33;
}
} else if (chan->band_type == RTW89_BAND_6G) {
if (chan->channel >= 1 && chan->channel <= 125)
target_ch = chan->channel + 32;
else
target_ch = chan->channel - 32;
} else {
target_ch = chan->channel;
}
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] cur_ch / target_ch = %d / %d\n",
chan->channel, target_ch);
return target_ch;
}
#define RTW8852C_RF_REL_VERSION 34
#define RTW8852C_DPK_VER 0x10
#define RTW8852C_DPK_VER 0xf
#define RTW8852C_DPK_TH_AVG_NUM 4
#define RTW8852C_DPK_RF_PATH 2
#define RTW8852C_DPK_KIP_REG_NUM 5
#define RTW8852C_DPK_KIP_REG_NUM 7
#define RTW8852C_DPK_RXSRAM_DBG 0
enum rtw8852c_dpk_id {
@ -1614,6 +1824,12 @@ enum dpk_agc_step {
DPK_AGC_STEP_SET_TX_GAIN,
};
enum dpk_pas_result {
DPK_PAS_NOR,
DPK_PAS_GT,
DPK_PAS_LT,
};
static void _rf_direct_cntrl(struct rtw89_dev *rtwdev,
enum rtw89_rf_path path, bool is_bybb)
{
@ -1730,8 +1946,6 @@ static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev,
/*4. Set ADC clk*/
rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13),
B_P0_NRBW_DBG, 0x1);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x1f);
@ -1872,12 +2086,11 @@ static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain,
0x50101 | BIT(rtwdev->dbcc_en));
rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK);
if (dpk->bp[path][kidx].band == RTW89_BAND_6G && dpk->bp[path][kidx].ch >= 161) {
if (dpk->bp[path][kidx].band == RTW89_BAND_6G && dpk->bp[path][kidx].ch >= 161)
rtw89_write_rf(rtwdev, path, RR_IQGEN, RR_IQGEN_BIAS, 0x8);
rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd);
} else {
rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd);
}
rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd);
rtw89_write_rf(rtwdev, path, RR_TXAC, RR_TXAC_IQG, 0x8);
rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_ATT, 0x0);
rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT2, 0x3);
@ -2024,9 +2237,10 @@ static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
return _dpk_gainloss_read(rtwdev);
}
static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
static enum dpk_pas_result _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
{
u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0;
u32 val1_sqrt_sum, val2_sqrt_sum;
u8 i;
rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06);
@ -2057,15 +2271,25 @@ static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
}
}
if (val1_i * val1_i + val1_q * val1_q >= (val2_i * val2_i + val2_q * val2_q) * 8 / 5)
return true;
val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q;
val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q;
if (val1_sqrt_sum < val2_sqrt_sum)
return DPK_PAS_LT;
else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5)
return DPK_PAS_GT;
else
return false;
return DPK_PAS_NOR;
}
static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path, u8 kidx)
{
_dpk_kip_control_rfc(rtwdev, path, false);
rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD,
rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK));
_dpk_kip_control_rfc(rtwdev, path, true);
_dpk_one_shot(rtwdev, phy, path, D_RXAGC);
return _dpk_sync_check(rtwdev, path, kidx);
@ -2103,6 +2327,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0;
u8 tmp_rxbb;
u8 goout = 0, agc_cnt = 0;
enum dpk_pas_result pas;
u16 dgain = 0;
bool is_fail = false;
int limit = 200;
@ -2138,9 +2363,13 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
case DPK_AGC_STEP_GAIN_LOSS_IDX:
tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx);
pas = _dpk_pas_read(rtwdev, true);
if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) ||
tmp_gl_idx >= 7)
if (pas == DPK_PAS_LT && tmp_gl_idx > 0)
step = DPK_AGC_STEP_GL_LT_CRITERION;
else if (pas == DPK_PAS_GT && tmp_gl_idx == 0)
step = DPK_AGC_STEP_GL_GT_CRITERION;
else if (tmp_gl_idx >= 7)
step = DPK_AGC_STEP_GL_GT_CRITERION;
else if (tmp_gl_idx == 0)
step = DPK_AGC_STEP_GL_LT_CRITERION;
@ -2467,12 +2696,14 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
enum rtw89_phy_idx phy, u8 kpath)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8};
static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0c4, 0xc0e8, 0xc0d4, 0xc0d8};
u32 backup_rf_val[RTW8852C_DPK_RF_PATH][BACKUP_RF_REGS_NR];
u32 kip_bkup[RTW8852C_DPK_RF_PATH][RTW8852C_DPK_KIP_REG_NUM] = {};
u8 path;
bool is_fail = true, reloaded[RTW8852C_DPK_RF_PATH] = {false};
static_assert(ARRAY_SIZE(kip_reg) == RTW8852C_DPK_KIP_REG_NUM);
if (dpk->is_dpk_reload_en) {
for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) {
if (!(kpath & BIT(path)))
@ -3875,11 +4106,14 @@ void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
#define RXDCK_VER_8852C 0xe
void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe)
static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
bool is_afe, u8 retry_limit)
{
struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck;
u8 path, kpath;
u32 rf_reg5;
bool is_fail;
u8 rek_cnt;
kpath = _kpath(rtwdev, phy);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
@ -3896,7 +4130,27 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a
B_P0_TSSI_TRK_EN, 0x1);
rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
_set_rx_dck(rtwdev, phy, path, is_afe);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_LO_SEL, rtwdev->dbcc_en);
for (rek_cnt = 0; rek_cnt < retry_limit; rek_cnt++) {
_set_rx_dck(rtwdev, phy, path, is_afe);
/* To reduce IO of dck_rek_check(), the last try is seen
* as failure always, and then do recovery procedure.
*/
if (rek_cnt == retry_limit - 1) {
_rx_dck_recover(rtwdev, path);
break;
}
is_fail = _rx_dck_rek_check(rtwdev, path);
if (!is_fail)
break;
}
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] rek_cnt[%d]=%d",
path, rek_cnt);
rx_dck->thermal[path] = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
@ -3906,15 +4160,31 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a
}
}
#define RTW8852C_RX_DCK_TH 8
void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe)
{
_rx_dck(rtwdev, phy, is_afe, 1);
}
#define RTW8852C_RX_DCK_TH 12
void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck;
enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
u8 dck_channel;
u8 cur_thermal;
u32 tx_en;
int delta;
int path;
if (chan->band_type == RTW89_BAND_2G)
return;
if (rtwdev->scanning)
return;
for (path = 0; path < RF_PATH_NUM_8852C; path++) {
cur_thermal =
ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
@ -3924,11 +4194,28 @@ void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev)
"[RX_DCK] path=%d current thermal=0x%x delta=0x%x\n",
path, cur_thermal, delta);
if (delta >= RTW8852C_RX_DCK_TH) {
rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
return;
}
if (delta >= RTW8852C_RX_DCK_TH)
goto trigger_rx_dck;
}
return;
trigger_rx_dck:
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
for (path = 0; path < RF_PATH_NUM_8852C; path++) {
dck_channel = _rx_dck_channel_calc(rtwdev, chan);
_ctrl_ch(rtwdev, RTW89_PHY_0, dck_channel, chan->band_type);
}
_rx_dck(rtwdev, RTW89_PHY_0, false, 20);
for (path = 0; path < RF_PATH_NUM_8852C; path++)
_ctrl_ch(rtwdev, RTW89_PHY_0, chan->channel, chan->band_type);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
}
void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)

View file

@ -53,6 +53,7 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = &rtw8852c_bd_idx_addr_low_power,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1,
.bd_ram_table = &rtw89_bd_ram_table_dual,
.ltr_set = rtw89_pci_ltr_set_v1,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1,

View file

@ -75,7 +75,9 @@
#define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28)
#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25)
#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16)
#define RTW89_TXWD_INFO0_DATA_ER BIT(15)
#define RTW89_TXWD_INFO0_DISDATAFB BIT(10)
#define RTW89_TXWD_INFO0_DATA_BW_ER BIT(8)
#define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4)
/* TX WD INFO DWORD 1 */

View file

@ -160,6 +160,7 @@ int rsi_coex_attach(struct rsi_common *common)
rsi_coex_scheduler_thread,
"Coex-Tx-Thread")) {
rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
kfree(coex_cb);
return -EINVAL;
}
return 0;

View file

@ -1328,7 +1328,7 @@ static netdev_tx_t wl3501_hard_start_xmit(struct sk_buff *skb,
} else {
++dev->stats.tx_packets;
dev->stats.tx_bytes += skb->len;
kfree_skb(skb);
dev_kfree_skb_irq(skb);
if (this->tx_buffer_cnt < 2)
netif_stop_queue(dev);

View file

@ -115,6 +115,32 @@
((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
})
#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
/**
* FIELD_PREP_CONST() - prepare a constant bitfield element
* @_mask: shifted mask defining the field's length and position
* @_val: value to put in the field
*
* FIELD_PREP_CONST() masks and shifts up the value. The result should
* be combined with other fields of the bitfield using logical OR.
*
* Unlike FIELD_PREP() this is a constant expression and can therefore
* be used in initializers. Error checking is less comfortable for this
* version, and non-constant masks cannot be used.
*/
#define FIELD_PREP_CONST(_mask, _val) \
( \
/* mask must be non-zero */ \
BUILD_BUG_ON_ZERO((_mask) == 0) + \
/* check if value fits */ \
BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \
/* check if mask is contiguous */ \
__BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \
/* and create the value */ \
(((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \
)
/**
* FIELD_GET() - extract a bitfield element
* @_mask: shifted mask defining the field's length and position

View file

@ -103,7 +103,6 @@ struct mtk_wed_device {
struct {
int size;
struct page_frag_cache rx_page;
struct mtk_rxbm_desc *desc;
dma_addr_t desc_phys;
} rx_buf_ring;

View file

@ -1075,7 +1075,6 @@ struct survey_info {
s8 noise;
};
#define CFG80211_MAX_WEP_KEYS 4
#define CFG80211_MAX_NUM_AKM_SUITES 10
/**
@ -1099,9 +1098,6 @@ struct survey_info {
* port frames over NL80211 instead of the network interface.
* @control_port_no_preauth: disables pre-auth rx over the nl80211 control
* port for mac80211
* @wep_keys: static WEP keys, if not NULL points to an array of
* CFG80211_MAX_WEP_KEYS WEP keys
* @wep_tx_key: key index (0..3) of the default TX static WEP key
* @psk: PSK (for devices supporting 4-way-handshake offload)
* @sae_pwd: password for SAE authentication (for devices supporting SAE
* offload)
@ -1134,8 +1130,6 @@ struct cfg80211_crypto_settings {
bool control_port_no_encrypt;
bool control_port_over_nl80211;
bool control_port_no_preauth;
struct key_params *wep_keys;
int wep_tx_key;
const u8 *psk;
const u8 *sae_pwd;
u8 sae_pwd_len;
@ -4683,13 +4677,12 @@ struct cfg80211_ops {
* @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels.
* @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in
* beaconing mode (AP, IBSS, Mesh, ...).
* @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation
* before connection.
* @WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK: The device supports bigger kek and kck keys
* @WIPHY_FLAG_SUPPORTS_MLO: This is a temporary flag gating the MLO APIs,
* in order to not have them reachable in normal drivers, until we have
* complete feature/interface combinations/etc. advertisement. No driver
* should set this flag for now.
* @WIPHY_FLAG_SUPPORTS_EXT_KCK_32: The device supports 32-byte KCK keys.
*/
enum wiphy_flags {
WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0),
@ -4702,7 +4695,7 @@ enum wiphy_flags {
WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
WIPHY_FLAG_IBSS_RSN = BIT(8),
WIPHY_FLAG_MESH_AUTH = BIT(10),
/* use hole at 11 */
WIPHY_FLAG_SUPPORTS_EXT_KCK_32 = BIT(11),
/* use hole at 12 */
WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13),
WIPHY_FLAG_AP_UAPSD = BIT(14),
@ -4715,7 +4708,6 @@ enum wiphy_flags {
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23),
WIPHY_FLAG_HAS_STATIC_WEP = BIT(24),
};
/**
@ -7783,7 +7775,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
/**
* cfg80211_del_sta_sinfo - notify userspace about deletion of a station
* @dev: the netdev
* @mac_addr: the station's address
* @mac_addr: the station's address. For MLD station, MLD address is used.
* @sinfo: the station information/statistics
* @gfp: allocation flags
*/
@ -7794,7 +7786,7 @@ void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
* cfg80211_del_sta - notify userspace about deletion of a station
*
* @dev: the netdev
* @mac_addr: the station's address
* @mac_addr: the station's address. For MLD station, MLD address is used.
* @gfp: allocation flags
*/
static inline void cfg80211_del_sta(struct net_device *dev,

View file

@ -653,6 +653,23 @@ struct ieee80211_fils_discovery {
* write-protected by sdata_lock and local->mtx so holding either is fine
* for read access.
* @color_change_color: the bss color that will be used after the change.
* @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU
* beamformer
* @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU
* beamformee
* @vht_mu_beamformer: in AP mode, does this BSS support operation as an VHT MU
* beamformer
* @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU
* beamformee
* @he_su_beamformer: in AP-mode, does this BSS support operation as an HE SU
* beamformer
* @he_su_beamformee: in AP-mode, does this BSS support operation as an HE SU
* beamformee
* @he_mu_beamformer: in AP-mode, does this BSS support operation as an HE MU
* beamformer
* @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission
* (non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU
* bandwidth
*/
struct ieee80211_bss_conf {
const u8 *bssid;
@ -726,6 +743,15 @@ struct ieee80211_bss_conf {
bool color_change_active;
u8 color_change_color;
bool vht_su_beamformer;
bool vht_su_beamformee;
bool vht_mu_beamformer;
bool vht_mu_beamformee;
bool he_su_beamformer;
bool he_su_beamformee;
bool he_mu_beamformer;
bool he_full_ul_mumimo;
};
/**
@ -1436,6 +1462,7 @@ enum mac80211_rx_encoding {
RX_ENC_HT,
RX_ENC_VHT,
RX_ENC_HE,
RX_ENC_EHT,
};
/**
@ -1469,7 +1496,7 @@ enum mac80211_rx_encoding {
* @antenna: antenna used
* @rate_idx: index of data rate into band's supported rates or MCS index if
* HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
* @nss: number of streams (VHT and HE only)
* @nss: number of streams (VHT, HE and EHT only)
* @flag: %RX_FLAG_\*
* @encoding: &enum mac80211_rx_encoding
* @bw: &enum rate_info_bw
@ -1477,6 +1504,9 @@ enum mac80211_rx_encoding {
* @he_ru: HE RU, from &enum nl80211_he_ru_alloc
* @he_gi: HE GI, from &enum nl80211_he_gi
* @he_dcm: HE DCM value
* @eht: EHT specific rate information
* @eht.ru: EHT RU, from &enum nl80211_eht_ru_alloc
* @eht.gi: EHT GI, from &enum nl80211_eht_gi
* @rx_flags: internal RX flags for mac80211
* @ampdu_reference: A-MPDU reference number, must be a different value for
* each A-MPDU but the same for each subframe within one A-MPDU
@ -1498,8 +1528,18 @@ struct ieee80211_rx_status {
u32 flag;
u16 freq: 13, freq_offset: 1;
u8 enc_flags;
u8 encoding:2, bw:3, he_ru:3;
u8 he_gi:2, he_dcm:1;
u8 encoding:3, bw:4;
union {
struct {
u8 he_ru:3;
u8 he_gi:2;
u8 he_dcm:1;
};
struct {
u8 ru:4;
u8 gi:2;
} eht;
};
u8 rate_idx;
u8 nss;
u8 rx_flags;
@ -5884,9 +5924,6 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
* This function iterates over the interfaces associated with a given
* hardware that are currently active and calls the callback for them.
* This version can only be used while holding the wiphy mutex.
* The driver must not call this with a lock held that it can also take in
* response to callbacks from mac80211, and it must not call this within
* callbacks made by mac80211 - both would result in deadlocks.
*
* @hw: the hardware struct of which the interfaces should be iterated over
* @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
@ -5900,24 +5937,6 @@ void ieee80211_iterate_active_interfaces_mtx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif),
void *data);
/**
* ieee80211_iterate_stations - iterate stations
*
* This function iterates over all stations associated with a given
* hardware that are currently uploaded to the driver and calls the callback
* function for them.
* This function allows the iterator function to sleep, when the iterator
* function is atomic @ieee80211_iterate_stations_atomic can be used.
*
* @hw: the hardware struct of which the interfaces should be iterated over
* @iterator: the iterator function to call, cannot sleep
* @data: first argument of the iterator function
*/
void ieee80211_iterate_stations(struct ieee80211_hw *hw,
void (*iterator)(void *data,
struct ieee80211_sta *sta),
void *data);
/**
* ieee80211_iterate_stations_atomic - iterate stations
*
@ -7191,7 +7210,7 @@ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
/**
* ieeee80211_obss_color_collision_notify - notify userland about a BSS color
* ieee80211_obss_color_collision_notify - notify userland about a BSS color
* collision.
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
@ -7200,8 +7219,8 @@ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
* @gfp: allocation flags
*/
void
ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
u64 color_bitmap, gfp_t gfp);
ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
u64 color_bitmap, gfp_t gfp);
/**
* ieee80211_is_tx_data - check if frame is a data frame

View file

@ -424,7 +424,8 @@
* interface identified by %NL80211_ATTR_IFINDEX.
* @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
* or, if no MAC address given, all stations, on the interface identified
* by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and
* by %NL80211_ATTR_IFINDEX. For MLD station, MLD address is used in
* %NL80211_ATTR_MAC. %NL80211_ATTR_MGMT_SUBTYPE and
* %NL80211_ATTR_REASON_CODE can optionally be used to specify which type
* of disconnection indication should be sent to the station
* (Deauthentication or Disassociation frame and reason code for that
@ -5869,6 +5870,7 @@ enum plink_actions {
#define NL80211_KEK_LEN 16
#define NL80211_KCK_EXT_LEN 24
#define NL80211_KEK_EXT_LEN 32
#define NL80211_KCK_EXT_LEN_32 32
#define NL80211_REPLAY_CTR_LEN 8
/**

View file

@ -1252,6 +1252,21 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
prev_beacon_int = link_conf->beacon_int;
link_conf->beacon_int = params->beacon_interval;
if (params->vht_cap) {
link_conf->vht_su_beamformer =
params->vht_cap->vht_cap_info &
cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
link_conf->vht_su_beamformee =
params->vht_cap->vht_cap_info &
cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
link_conf->vht_mu_beamformer =
params->vht_cap->vht_cap_info &
cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
link_conf->vht_mu_beamformee =
params->vht_cap->vht_cap_info &
cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
}
if (params->he_cap && params->he_oper) {
link_conf->he_support = true;
link_conf->htc_trig_based_pkt_ext =
@ -1266,6 +1281,21 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
changed |= BSS_CHANGED_HE_BSS_COLOR;
}
if (params->he_cap) {
link_conf->he_su_beamformer =
params->he_cap->phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
link_conf->he_su_beamformee =
params->he_cap->phy_cap_info[4] &
IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE;
link_conf->he_mu_beamformer =
params->he_cap->phy_cap_info[4] &
IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
link_conf->he_full_ul_mumimo =
params->he_cap->phy_cap_info[2] &
IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO;
}
if (sdata->vif.type == NL80211_IFTYPE_AP &&
params->mbssid_config.tx_wdev) {
err = ieee80211_set_ap_mbssid_options(sdata,
@ -2734,7 +2764,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
* If the scan has been forced (and the driver supports
* forcing), don't care about being beaconing already.
* This will create problems to the attached stations (e.g. all
* the frames sent while scanning on other channel will be
* the frames sent while scanning on other channel will be
* lost)
*/
if (sdata->deflink.u.ap.beacon &&
@ -4632,7 +4662,7 @@ void ieee80211_color_change_finish(struct ieee80211_vif *vif)
EXPORT_SYMBOL_GPL(ieee80211_color_change_finish);
void
ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
u64 color_bitmap, gfp_t gfp)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@ -4642,7 +4672,7 @@ ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
cfg80211_obss_color_collision_notify(sdata->dev, color_bitmap, gfp);
}
EXPORT_SYMBOL_GPL(ieeee80211_obss_color_collision_notify);
EXPORT_SYMBOL_GPL(ieee80211_obss_color_collision_notify);
static int
ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,

View file

@ -3219,9 +3219,9 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
color = le32_get_bits(he_oper->he_oper_params,
IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
if (color == bss_conf->he_bss_color.color)
ieeee80211_obss_color_collision_notify(&rx->sdata->vif,
BIT_ULL(color),
GFP_ATOMIC);
ieee80211_obss_color_collision_notify(&rx->sdata->vif,
BIT_ULL(color),
GFP_ATOMIC);
}
}
@ -5194,6 +5194,15 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
status->rate_idx, status->nss))
goto drop;
break;
case RX_ENC_EHT:
if (WARN_ONCE(status->rate_idx > 15 ||
!status->nss ||
status->nss > 8 ||
status->eht.gi > NL80211_RATE_INFO_EHT_GI_3_2,
"Rate marked as an EHT rate but data is invalid: MCS:%d, NSS:%d, GI:%d\n",
status->rate_idx, status->nss, status->eht.gi))
goto drop;
break;
default:
WARN_ON_ONCE(1);
fallthrough;

View file

@ -4,7 +4,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*/
#include <linux/module.h>
@ -2406,6 +2406,13 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
rinfo->he_ru_alloc = STA_STATS_GET(HE_RU, rate);
rinfo->he_dcm = STA_STATS_GET(HE_DCM, rate);
break;
case STA_STATS_RATE_TYPE_EHT:
rinfo->flags = RATE_INFO_FLAGS_EHT_MCS;
rinfo->mcs = STA_STATS_GET(EHT_MCS, rate);
rinfo->nss = STA_STATS_GET(EHT_NSS, rate);
rinfo->eht_gi = STA_STATS_GET(EHT_GI, rate);
rinfo->eht_ru_alloc = STA_STATS_GET(EHT_RU, rate);
break;
}
}

View file

@ -936,6 +936,7 @@ enum sta_stats_type {
STA_STATS_RATE_TYPE_VHT,
STA_STATS_RATE_TYPE_HE,
STA_STATS_RATE_TYPE_S1G,
STA_STATS_RATE_TYPE_EHT,
};
#define STA_STATS_FIELD_HT_MCS GENMASK( 7, 0)
@ -945,12 +946,16 @@ enum sta_stats_type {
#define STA_STATS_FIELD_VHT_NSS GENMASK( 7, 4)
#define STA_STATS_FIELD_HE_MCS GENMASK( 3, 0)
#define STA_STATS_FIELD_HE_NSS GENMASK( 7, 4)
#define STA_STATS_FIELD_BW GENMASK(11, 8)
#define STA_STATS_FIELD_SGI GENMASK(12, 12)
#define STA_STATS_FIELD_TYPE GENMASK(15, 13)
#define STA_STATS_FIELD_HE_RU GENMASK(18, 16)
#define STA_STATS_FIELD_HE_GI GENMASK(20, 19)
#define STA_STATS_FIELD_HE_DCM GENMASK(21, 21)
#define STA_STATS_FIELD_EHT_MCS GENMASK( 3, 0)
#define STA_STATS_FIELD_EHT_NSS GENMASK( 7, 4)
#define STA_STATS_FIELD_BW GENMASK(12, 8)
#define STA_STATS_FIELD_SGI GENMASK(13, 13)
#define STA_STATS_FIELD_TYPE GENMASK(16, 14)
#define STA_STATS_FIELD_HE_RU GENMASK(19, 17)
#define STA_STATS_FIELD_HE_GI GENMASK(21, 20)
#define STA_STATS_FIELD_HE_DCM GENMASK(22, 22)
#define STA_STATS_FIELD_EHT_RU GENMASK(20, 17)
#define STA_STATS_FIELD_EHT_GI GENMASK(22, 21)
#define STA_STATS_FIELD(_n, _v) FIELD_PREP(STA_STATS_FIELD_ ## _n, _v)
#define STA_STATS_GET(_n, _v) FIELD_GET(STA_STATS_FIELD_ ## _n, _v)
@ -989,6 +994,13 @@ static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s)
r |= STA_STATS_FIELD(HE_RU, s->he_ru);
r |= STA_STATS_FIELD(HE_DCM, s->he_dcm);
break;
case RX_ENC_EHT:
r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_EHT);
r |= STA_STATS_FIELD(EHT_NSS, s->nss);
r |= STA_STATS_FIELD(EHT_MCS, s->rate_idx);
r |= STA_STATS_FIELD(EHT_GI, s->eht.gi);
r |= STA_STATS_FIELD(EHT_RU, s->eht.ru);
break;
default:
WARN_ON(1);
return STA_STATS_RATE_INVALID;

View file

@ -832,19 +832,6 @@ static void __iterate_stations(struct ieee80211_local *local,
}
}
void ieee80211_iterate_stations(struct ieee80211_hw *hw,
void (*iterator)(void *data,
struct ieee80211_sta *sta),
void *data)
{
struct ieee80211_local *local = hw_to_local(hw);
mutex_lock(&local->sta_mtx);
__iterate_stations(local, iterator, data);
mutex_unlock(&local->sta_mtx);
}
EXPORT_SYMBOL_GPL(ieee80211_iterate_stations);
void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
void (*iterator)(void *data,
struct ieee80211_sta *sta),
@ -4033,6 +4020,19 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
/* Fill cfg80211 rate info */
switch (status->encoding) {
case RX_ENC_EHT:
ri.flags |= RATE_INFO_FLAGS_EHT_MCS;
ri.mcs = status->rate_idx;
ri.nss = status->nss;
ri.eht_ru_alloc = status->eht.ru;
if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
/* TODO/FIXME: is this right? handle other PPDUs */
if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
mpdu_offset += 2;
ts += 36;
}
break;
case RX_ENC_HE:
ri.flags |= RATE_INFO_FLAGS_HE_MCS;
ri.mcs = status->rate_idx;

View file

@ -75,6 +75,8 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
{
struct rfkill_gpio_data *rfkill;
struct gpio_desc *gpio;
const char *name_property;
const char *type_property;
const char *type_name;
int ret;
@ -82,8 +84,15 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
if (!rfkill)
return -ENOMEM;
device_property_read_string(&pdev->dev, "name", &rfkill->name);
device_property_read_string(&pdev->dev, "type", &type_name);
if (dev_of_node(&pdev->dev)) {
name_property = "label";
type_property = "radio-type";
} else {
name_property = "name";
type_property = "type";
}
device_property_read_string(&pdev->dev, name_property, &rfkill->name);
device_property_read_string(&pdev->dev, type_property, &type_name);
if (!rfkill->name)
rfkill->name = dev_name(&pdev->dev);
@ -157,12 +166,19 @@ static const struct acpi_device_id rfkill_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rfkill_acpi_match);
#endif
static const struct of_device_id rfkill_of_match[] __maybe_unused = {
{ .compatible = "rfkill-gpio", },
{ },
};
MODULE_DEVICE_TABLE(of, rfkill_of_match);
static struct platform_driver rfkill_gpio_driver = {
.probe = rfkill_gpio_probe,
.remove = rfkill_gpio_remove,
.driver = {
.name = "rfkill_gpio",
.acpi_match_table = ACPI_PTR(rfkill_acpi_match),
.of_match_table = of_match_ptr(rfkill_of_match),
},
};

Some files were not shown because too many files have changed in this diff Show more