Date: Wed, 22 Apr 2026 21:09:04 +0000 From: Bjoern A. Zeeb <bz@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: bcdf750def1d - stable/15 - rtw88: update Realtek's rtw88 driver Message-ID: <69e938f0.275fb.738f6d4f@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch stable/15 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=bcdf750def1d5776140e1114ef155f9b018beac3 commit bcdf750def1d5776140e1114ef155f9b018beac3 Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2026-04-18 14:21:04 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2026-04-22 20:57:11 +0000 rtw88: update Realtek's rtw88 driver This version is based on git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 028ef9c96e96197026887c0f092424679298aae8 ( tag: v7.0 ). Sponsored by: The FreeBSD Foundation (cherry picked from commit 41b641cc0537d1288cc05332bb4c5de3dcb12589) --- sys/contrib/dev/rtw88/fw.c | 2 +- sys/contrib/dev/rtw88/main.c | 54 +++++++++++++++++++++++++++------------ sys/contrib/dev/rtw88/main.h | 2 +- sys/contrib/dev/rtw88/phy.c | 20 +++++++++++++++ sys/contrib/dev/rtw88/phy.h | 2 ++ sys/contrib/dev/rtw88/rtw8723cs.c | 2 +- sys/contrib/dev/rtw88/rtw8723ds.c | 2 +- sys/contrib/dev/rtw88/rtw8821cs.c | 2 +- sys/contrib/dev/rtw88/rtw8821cu.c | 2 ++ sys/contrib/dev/rtw88/rtw8822b.c | 3 ++- sys/contrib/dev/rtw88/rtw8822bs.c | 2 +- sys/contrib/dev/rtw88/rtw8822cs.c | 2 +- sys/contrib/dev/rtw88/sdio.c | 6 ++--- sys/contrib/dev/rtw88/sdio.h | 2 +- sys/contrib/dev/rtw88/usb.c | 5 ++-- sys/contrib/dev/rtw88/util.c | 4 +-- 16 files changed, 78 insertions(+), 34 deletions(-) diff --git a/sys/contrib/dev/rtw88/fw.c b/sys/contrib/dev/rtw88/fw.c index 5ce4a6bcffb6..1574b2422240 100644 --- a/sys/contrib/dev/rtw88/fw.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/main.c b/sys/contrib/dev/rtw88/main.c index b38709b180fd..43d537d0daba 100644 --- a/sys/contrib/dev/rtw88/main.c +++ b/sys/contrib/dev/rtw88/main.c @@ -811,10 +811,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, @@ -1568,6 +1568,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, @@ -1579,6 +1581,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); @@ -1743,14 +1746,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 defined(__linux__) @@ -1763,7 +1793,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 defined(__linux__) @@ -1787,13 +1817,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) { @@ -2425,10 +2448,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); } @@ -2549,10 +2569,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/sys/contrib/dev/rtw88/main.h b/sys/contrib/dev/rtw88/main.h index d1e4f3e41ba1..212f5150e012 100644 --- a/sys/contrib/dev/rtw88/main.h +++ b/sys/contrib/dev/rtw88/main.h @@ -2235,7 +2235,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/sys/contrib/dev/rtw88/phy.c b/sys/contrib/dev/rtw88/phy.c index 55be0d8e0c28..e2ac5c6fd500 100644 --- a/sys/contrib/dev/rtw88/phy.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/phy.h b/sys/contrib/dev/rtw88/phy.h index c9e6b869661d..8449936497bb 100644 --- a/sys/contrib/dev/rtw88/phy.h +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/rtw8723cs.c b/sys/contrib/dev/rtw88/rtw8723cs.c index 1f98d35a8dd1..2018c9d76dd1 100644 --- a/sys/contrib/dev/rtw88/rtw8723cs.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/rtw8723ds.c b/sys/contrib/dev/rtw88/rtw8723ds.c index 206b77e5b98e..e38c90b769a2 100644 --- a/sys/contrib/dev/rtw88/rtw8723ds.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/rtw8821cs.c b/sys/contrib/dev/rtw88/rtw8821cs.c index 6d94162213c6..58e0ef219cdc 100644 --- a/sys/contrib/dev/rtw88/rtw8821cs.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/rtw8821cu.c b/sys/contrib/dev/rtw88/rtw8821cu.c index 0f42819f787c..47ecd0394960 100644 --- a/sys/contrib/dev/rtw88/rtw8821cu.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/rtw8822b.c b/sys/contrib/dev/rtw88/rtw8822b.c index b37b301fc866..f9097bc337df 100644 --- a/sys/contrib/dev/rtw88/rtw8822b.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/rtw8822bs.c b/sys/contrib/dev/rtw88/rtw8822bs.c index 744781dcb419..2de9b11540c5 100644 --- a/sys/contrib/dev/rtw88/rtw8822bs.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/rtw8822cs.c b/sys/contrib/dev/rtw88/rtw8822cs.c index 322281e07eb8..b00ef4173962 100644 --- a/sys/contrib/dev/rtw88/rtw8822cs.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/sdio.c b/sys/contrib/dev/rtw88/sdio.c index e35de52d8eb4..1318e94f8524 100644 --- a/sys/contrib/dev/rtw88/sdio.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/sdio.h b/sys/contrib/dev/rtw88/sdio.h index 3c659ed180f0..457e8b02380e 100644 --- a/sys/contrib/dev/rtw88/sdio.h +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/usb.c b/sys/contrib/dev/rtw88/usb.c index 69a4cb60184f..1c2a1a328f09 100644 --- a/sys/contrib/dev/rtw88/usb.c +++ b/sys/contrib/dev/rtw88/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/sys/contrib/dev/rtw88/util.c b/sys/contrib/dev/rtw88/util.c index 66819f694405..fcd6eb1ab32a 100644 --- a/sys/contrib/dev/rtw88/util.c +++ b/sys/contrib/dev/rtw88/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;home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69e938f0.275fb.738f6d4f>
