summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2026-04-13 22:26:11 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2026-04-13 22:26:11 +0000
commit29163571ee4d00c3f15d26136c73587b3c537cff (patch)
treee56521b6dc744f94c4f35220adacbce2a033ac80
parent225a2dcb02943b5ed98b90f4a5c53b2a9b50f5a9 (diff)
-rw-r--r--fw.c2
-rw-r--r--main.c54
-rw-r--r--main.h2
-rw-r--r--phy.c20
-rw-r--r--phy.h2
-rw-r--r--rtw8723cs.c2
-rw-r--r--rtw8723ds.c2
-rw-r--r--rtw8821cs.c2
-rw-r--r--rtw8821cu.c2
-rw-r--r--rtw8822b.c3
-rw-r--r--rtw8822bs.c2
-rw-r--r--rtw8822cs.c2
-rw-r--r--sdio.c6
-rw-r--r--sdio.h2
-rw-r--r--usb.c5
-rw-r--r--util.c4
16 files changed, 78 insertions, 34 deletions
diff --git a/fw.c b/fw.c
index c68a9fff6808..48207052e3f8 100644
--- a/fw.c
+++ b/fw.c
@@ -1331,7 +1331,7 @@ static struct rtw_rsvd_page *rtw_alloc_rsvd_page(struct rtw_dev *rtwdev,
{
struct rtw_rsvd_page *rsvd_pkt = NULL;
- rsvd_pkt = kzalloc(sizeof(*rsvd_pkt), GFP_KERNEL);
+ rsvd_pkt = kzalloc_obj(*rsvd_pkt);
if (!rsvd_pkt)
return NULL;
diff --git a/main.c b/main.c
index fa0ed39cb199..c4f9758b4e96 100644
--- a/main.c
+++ b/main.c
@@ -730,10 +730,10 @@ void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel)
}
EXPORT_SYMBOL(rtw_set_rx_freq_band);
-void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period)
+void rtw_set_dtim_period(struct rtw_dev *rtwdev, u8 dtim_period)
{
rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_TIMIE);
- rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period - 1);
+ rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period ? dtim_period - 1 : 0);
}
void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel,
@@ -1483,6 +1483,8 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
set_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags);
set_bit(RTW_FLAG_SCANNING, rtwdev->flags);
+
+ rtw_phy_dig_set_max_coverage(rtwdev);
}
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
@@ -1494,6 +1496,7 @@ void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
if (!rtwvif)
return;
+ rtw_phy_dig_reset(rtwdev);
clear_bit(RTW_FLAG_SCANNING, rtwdev->flags);
clear_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags);
@@ -1658,14 +1661,41 @@ static u16 rtw_get_max_scan_ie_len(struct rtw_dev *rtwdev)
return len;
}
+static struct ieee80211_supported_band *
+rtw_sband_dup(struct rtw_dev *rtwdev,
+ const struct ieee80211_supported_band *sband)
+{
+ struct ieee80211_supported_band *dup;
+
+ dup = devm_kmemdup(rtwdev->dev, sband, sizeof(*sband), GFP_KERNEL);
+ if (!dup)
+ return NULL;
+
+ dup->channels = devm_kmemdup_array(rtwdev->dev, sband->channels,
+ sband->n_channels,
+ sizeof(*sband->channels),
+ GFP_KERNEL);
+ if (!dup->channels)
+ return NULL;
+
+ dup->bitrates = devm_kmemdup_array(rtwdev->dev, sband->bitrates,
+ sband->n_bitrates,
+ sizeof(*sband->bitrates),
+ GFP_KERNEL);
+ if (!dup->bitrates)
+ return NULL;
+
+ return dup;
+}
+
static void rtw_set_supported_band(struct ieee80211_hw *hw,
const struct rtw_chip_info *chip)
{
- struct rtw_dev *rtwdev = hw->priv;
struct ieee80211_supported_band *sband;
+ struct rtw_dev *rtwdev = hw->priv;
if (chip->band & RTW_BAND_2G) {
- sband = kmemdup(&rtw_band_2ghz, sizeof(*sband), GFP_KERNEL);
+ sband = rtw_sband_dup(rtwdev, &rtw_band_2ghz);
if (!sband)
goto err_out;
if (chip->ht_supported)
@@ -1674,7 +1704,7 @@ static void rtw_set_supported_band(struct ieee80211_hw *hw,
}
if (chip->band & RTW_BAND_5G) {
- sband = kmemdup(&rtw_band_5ghz, sizeof(*sband), GFP_KERNEL);
+ sband = rtw_sband_dup(rtwdev, &rtw_band_5ghz);
if (!sband)
goto err_out;
if (chip->ht_supported)
@@ -1690,13 +1720,6 @@ err_out:
rtw_err(rtwdev, "failed to set supported band\n");
}
-static void rtw_unset_supported_band(struct ieee80211_hw *hw,
- const struct rtw_chip_info *chip)
-{
- kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]);
- kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]);
-}
-
static void rtw_vif_smps_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
@@ -2320,10 +2343,7 @@ EXPORT_SYMBOL(rtw_register_hw);
void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
{
- const struct rtw_chip_info *chip = rtwdev->chip;
-
ieee80211_unregister_hw(hw);
- rtw_unset_supported_band(hw, chip);
rtw_debugfs_deinit(rtwdev);
rtw_led_deinit(rtwdev);
}
@@ -2444,10 +2464,10 @@ void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable)
if (enable) {
rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
- rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
+ rtw_write8_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
} else {
rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
- rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
+ rtw_write8_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
}
}
diff --git a/main.h b/main.h
index 43ed6d6b4291..1ab70214ce36 100644
--- a/main.h
+++ b/main.h
@@ -2226,7 +2226,7 @@ enum nl80211_band rtw_hw_to_nl80211_band(enum rtw_supported_band hw_band)
}
void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel);
-void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period);
+void rtw_set_dtim_period(struct rtw_dev *rtwdev, u8 dtim_period);
void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
struct rtw_channel_params *ch_param);
bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target);
diff --git a/phy.c b/phy.c
index 55be0d8e0c28..e2ac5c6fd500 100644
--- a/phy.c
+++ b/phy.c
@@ -370,6 +370,26 @@ static void rtw_phy_statistics(struct rtw_dev *rtwdev)
#define DIG_CVRG_MIN 0x1c
#define DIG_RSSI_GAIN_OFFSET 15
+void rtw_phy_dig_set_max_coverage(struct rtw_dev *rtwdev)
+{
+ /* Lower values result in greater coverage. */
+ rtw_dbg(rtwdev, RTW_DBG_PHY, "Setting IGI=%#x for max coverage\n",
+ DIG_CVRG_MIN);
+
+ rtw_phy_dig_write(rtwdev, DIG_CVRG_MIN);
+}
+
+void rtw_phy_dig_reset(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 last_igi;
+
+ last_igi = dm_info->igi_history[0];
+ rtw_dbg(rtwdev, RTW_DBG_PHY, "Resetting IGI=%#x\n", last_igi);
+
+ rtw_phy_dig_write(rtwdev, last_igi);
+}
+
static bool
rtw_phy_dig_check_damping(struct rtw_dm_info *dm_info)
{
diff --git a/phy.h b/phy.h
index c9e6b869661d..8449936497bb 100644
--- a/phy.h
+++ b/phy.h
@@ -146,6 +146,8 @@ static inline int rtw_check_supported_rfe(struct rtw_dev *rtwdev)
}
void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi);
+void rtw_phy_dig_reset(struct rtw_dev *rtwdev);
+void rtw_phy_dig_set_max_coverage(struct rtw_dev *rtwdev);
struct rtw_power_params {
u8 pwr_base;
diff --git a/rtw8723cs.c b/rtw8723cs.c
index 1f98d35a8dd1..2018c9d76dd1 100644
--- a/rtw8723cs.c
+++ b/rtw8723cs.c
@@ -23,9 +23,9 @@ static struct sdio_driver rtw_8723cs_driver = {
.id_table = rtw_8723cs_id_table,
.probe = rtw_sdio_probe,
.remove = rtw_sdio_remove,
+ .shutdown = rtw_sdio_shutdown,
.drv = {
.pm = &rtw_sdio_pm_ops,
- .shutdown = rtw_sdio_shutdown
}};
module_sdio_driver(rtw_8723cs_driver);
diff --git a/rtw8723ds.c b/rtw8723ds.c
index 206b77e5b98e..e38c90b769a2 100644
--- a/rtw8723ds.c
+++ b/rtw8723ds.c
@@ -28,10 +28,10 @@ static struct sdio_driver rtw_8723ds_driver = {
.name = KBUILD_MODNAME,
.probe = rtw_sdio_probe,
.remove = rtw_sdio_remove,
+ .shutdown = rtw_sdio_shutdown,
.id_table = rtw_8723ds_id_table,
.drv = {
.pm = &rtw_sdio_pm_ops,
- .shutdown = rtw_sdio_shutdown,
}
};
module_sdio_driver(rtw_8723ds_driver);
diff --git a/rtw8821cs.c b/rtw8821cs.c
index 6d94162213c6..58e0ef219cdc 100644
--- a/rtw8821cs.c
+++ b/rtw8821cs.c
@@ -23,10 +23,10 @@ static struct sdio_driver rtw_8821cs_driver = {
.name = KBUILD_MODNAME,
.probe = rtw_sdio_probe,
.remove = rtw_sdio_remove,
+ .shutdown = rtw_sdio_shutdown,
.id_table = rtw_8821cs_id_table,
.drv = {
.pm = &rtw_sdio_pm_ops,
- .shutdown = rtw_sdio_shutdown,
}
};
module_sdio_driver(rtw_8821cs_driver);
diff --git a/rtw8821cu.c b/rtw8821cu.c
index 7a0fffc359e2..8cd09d66655d 100644
--- a/rtw8821cu.c
+++ b/rtw8821cu.c
@@ -37,6 +37,8 @@ static const struct usb_device_id rtw_8821cu_id_table[] = {
.driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd811, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0105, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Mercusys */
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table);
diff --git a/rtw8822b.c b/rtw8822b.c
index 89b6485b229a..4d88cc2f4148 100644
--- a/rtw8822b.c
+++ b/rtw8822b.c
@@ -1005,7 +1005,8 @@ static int rtw8822b_set_antenna(struct rtw_dev *rtwdev,
hal->antenna_tx = antenna_tx;
hal->antenna_rx = antenna_rx;
- rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
+ if (test_bit(RTW_FLAG_POWERON, rtwdev->flags))
+ rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
return 0;
}
diff --git a/rtw8822bs.c b/rtw8822bs.c
index 744781dcb419..2de9b11540c5 100644
--- a/rtw8822bs.c
+++ b/rtw8822bs.c
@@ -23,10 +23,10 @@ static struct sdio_driver rtw_8822bs_driver = {
.name = KBUILD_MODNAME,
.probe = rtw_sdio_probe,
.remove = rtw_sdio_remove,
+ .shutdown = rtw_sdio_shutdown,
.id_table = rtw_8822bs_id_table,
.drv = {
.pm = &rtw_sdio_pm_ops,
- .shutdown = rtw_sdio_shutdown,
}
};
module_sdio_driver(rtw_8822bs_driver);
diff --git a/rtw8822cs.c b/rtw8822cs.c
index 322281e07eb8..b00ef4173962 100644
--- a/rtw8822cs.c
+++ b/rtw8822cs.c
@@ -23,10 +23,10 @@ static struct sdio_driver rtw_8822cs_driver = {
.name = KBUILD_MODNAME,
.probe = rtw_sdio_probe,
.remove = rtw_sdio_remove,
+ .shutdown = rtw_sdio_shutdown,
.id_table = rtw_8822cs_id_table,
.drv = {
.pm = &rtw_sdio_pm_ops,
- .shutdown = rtw_sdio_shutdown,
}
};
module_sdio_driver(rtw_8822cs_driver);
diff --git a/sdio.c b/sdio.c
index e35de52d8eb4..1318e94f8524 100644
--- a/sdio.c
+++ b/sdio.c
@@ -1290,8 +1290,7 @@ static int rtw_sdio_init_tx(struct rtw_dev *rtwdev)
for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
skb_queue_head_init(&rtwsdio->tx_queue[i]);
- rtwsdio->tx_handler_data = kmalloc(sizeof(*rtwsdio->tx_handler_data),
- GFP_KERNEL);
+ rtwsdio->tx_handler_data = kmalloc_obj(*rtwsdio->tx_handler_data);
if (!rtwsdio->tx_handler_data)
goto err_destroy_wq;
@@ -1414,9 +1413,8 @@ void rtw_sdio_remove(struct sdio_func *sdio_func)
}
EXPORT_SYMBOL(rtw_sdio_remove);
-void rtw_sdio_shutdown(struct device *dev)
+void rtw_sdio_shutdown(struct sdio_func *sdio_func)
{
- struct sdio_func *sdio_func = dev_to_sdio_func(dev);
const struct rtw_chip_info *chip;
struct ieee80211_hw *hw;
struct rtw_dev *rtwdev;
diff --git a/sdio.h b/sdio.h
index 3c659ed180f0..457e8b02380e 100644
--- a/sdio.h
+++ b/sdio.h
@@ -166,7 +166,7 @@ extern const struct dev_pm_ops rtw_sdio_pm_ops;
int rtw_sdio_probe(struct sdio_func *sdio_func,
const struct sdio_device_id *id);
void rtw_sdio_remove(struct sdio_func *sdio_func);
-void rtw_sdio_shutdown(struct device *dev);
+void rtw_sdio_shutdown(struct sdio_func *sdio_func);
static inline bool rtw_sdio_is_sdio30_supported(struct rtw_dev *rtwdev)
{
diff --git a/usb.c b/usb.c
index 3b5126ffc81a..433b06c8d8a6 100644
--- a/usb.c
+++ b/usb.c
@@ -403,7 +403,7 @@ static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list
if (skb_queue_empty(list))
return false;
- txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
+ txcb = kmalloc_obj(*txcb, GFP_ATOMIC);
if (!txcb)
return false;
@@ -965,7 +965,8 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
struct sk_buff *rx_skb;
int i;
- rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0);
+ rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH | WQ_PERCPU,
+ 0);
if (!rtwusb->rxwq) {
rtw_err(rtwdev, "failed to create RX work queue\n");
return -ENOMEM;
diff --git a/util.c b/util.c
index 66819f694405..fcd6eb1ab32a 100644
--- a/util.c
+++ b/util.c
@@ -122,7 +122,7 @@ static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta)
struct rtw_iter_stas_data *iter_stas = data;
struct rtw_stas_entry *stas_entry;
- stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC);
+ stas_entry = kmalloc_obj(*stas_entry, GFP_ATOMIC);
if (!stas_entry)
return;
@@ -172,7 +172,7 @@ static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
struct rtw_iter_vifs_data *iter_stas = data;
struct rtw_vifs_entry *vifs_entry;
- vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC);
+ vifs_entry = kmalloc_obj(*vifs_entry, GFP_ATOMIC);
if (!vifs_entry)
return;