linux/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c
Bitterblue Smith a95d28a8a2 wifi: rtlwifi: rtl8192du: Don't claim USB ID 0bda:8171
This ID appears to be RTL8188SU, not RTL8192DU. This is the wrong driver
for RTL8188SU. The r8712u driver from staging handles this ID.

I think this ID comes from the original rtl8192du driver from Realtek.
I don't know if they added it by mistake, or it was actually used for
two different chips.

RTL8188SU with this ID exists in the wild. RTL8192DU with this ID
probably doesn't.

Fixes: b5dc8873b6 ("wifi: rtlwifi: Add rtl8192du/sw.c")
Cc: stable@vger.kernel.org # v6.11
Closes: https://github.com/lwfinger/rtl8192du/issues/105
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/40245564-41fe-4a5e-881f-cd517255b20a@gmail.com
2024-10-17 17:25:03 +03:00

394 lines
13 KiB
C

// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2024 Realtek Corporation.*/
#include "../wifi.h"
#include "../core.h"
#include "../usb.h"
#include "../base.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/fw_common.h"
#include "../rtl8192d/hw_common.h"
#include "../rtl8192d/phy_common.h"
#include "../rtl8192d/trx_common.h"
#include "phy.h"
#include "dm.h"
#include "hw.h"
#include "trx.h"
#include "led.h"
#include <linux/module.h>
static struct usb_interface *rtl92du_get_other_intf(struct ieee80211_hw *hw)
{
struct usb_interface *intf;
struct usb_device *udev;
u8 other_interfaceindex;
/* See SET_IEEE80211_DEV(hw, &intf->dev); in usb.c */
intf = container_of_const(wiphy_dev(hw->wiphy), struct usb_interface, dev);
if (intf->altsetting[0].desc.bInterfaceNumber == 0)
other_interfaceindex = 1;
else
other_interfaceindex = 0;
udev = interface_to_usbdev(intf);
return usb_ifnum_to_if(udev, other_interfaceindex);
}
static int rtl92du_init_shared_data(struct ieee80211_hw *hw)
{
struct usb_interface *other_intf = rtl92du_get_other_intf(hw);
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_priv *other_rtlpriv = NULL;
struct ieee80211_hw *other_hw = NULL;
if (other_intf)
other_hw = usb_get_intfdata(other_intf);
if (other_hw) {
/* The other interface was already probed. */
other_rtlpriv = rtl_priv(other_hw);
rtlpriv->curveindex_2g = other_rtlpriv->curveindex_2g;
rtlpriv->curveindex_5g = other_rtlpriv->curveindex_5g;
rtlpriv->mutex_for_power_on_off = other_rtlpriv->mutex_for_power_on_off;
rtlpriv->mutex_for_hw_init = other_rtlpriv->mutex_for_hw_init;
if (!rtlpriv->curveindex_2g || !rtlpriv->curveindex_5g ||
!rtlpriv->mutex_for_power_on_off || !rtlpriv->mutex_for_hw_init)
return -ENOMEM;
return 0;
}
/* The other interface doesn't exist or was not probed yet. */
rtlpriv->curveindex_2g = kcalloc(TARGET_CHNL_NUM_2G,
sizeof(*rtlpriv->curveindex_2g),
GFP_KERNEL);
rtlpriv->curveindex_5g = kcalloc(TARGET_CHNL_NUM_5G,
sizeof(*rtlpriv->curveindex_5g),
GFP_KERNEL);
rtlpriv->mutex_for_power_on_off =
kzalloc(sizeof(*rtlpriv->mutex_for_power_on_off), GFP_KERNEL);
rtlpriv->mutex_for_hw_init =
kzalloc(sizeof(*rtlpriv->mutex_for_hw_init), GFP_KERNEL);
if (!rtlpriv->curveindex_2g || !rtlpriv->curveindex_5g ||
!rtlpriv->mutex_for_power_on_off || !rtlpriv->mutex_for_hw_init) {
kfree(rtlpriv->curveindex_2g);
kfree(rtlpriv->curveindex_5g);
kfree(rtlpriv->mutex_for_power_on_off);
kfree(rtlpriv->mutex_for_hw_init);
rtlpriv->curveindex_2g = NULL;
rtlpriv->curveindex_5g = NULL;
rtlpriv->mutex_for_power_on_off = NULL;
rtlpriv->mutex_for_hw_init = NULL;
return -ENOMEM;
}
mutex_init(rtlpriv->mutex_for_power_on_off);
mutex_init(rtlpriv->mutex_for_hw_init);
return 0;
}
static void rtl92du_deinit_shared_data(struct ieee80211_hw *hw)
{
struct usb_interface *other_intf = rtl92du_get_other_intf(hw);
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (!other_intf || !usb_get_intfdata(other_intf)) {
/* The other interface doesn't exist or was already disconnected. */
kfree(rtlpriv->curveindex_2g);
kfree(rtlpriv->curveindex_5g);
if (rtlpriv->mutex_for_power_on_off)
mutex_destroy(rtlpriv->mutex_for_power_on_off);
if (rtlpriv->mutex_for_hw_init)
mutex_destroy(rtlpriv->mutex_for_hw_init);
kfree(rtlpriv->mutex_for_power_on_off);
kfree(rtlpriv->mutex_for_hw_init);
}
}
static int rtl92du_init_sw_vars(struct ieee80211_hw *hw)
{
const char *fw_name = "rtlwifi/rtl8192dufw.bin";
struct rtl_priv *rtlpriv = rtl_priv(hw);
int err;
err = rtl92du_init_shared_data(hw);
if (err)
return err;
rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpriv->dm.useramask = true;
/* dual mac */
if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
rtlpriv->phy.current_channel = 36;
else
rtlpriv->phy.current_channel = 1;
if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY)
rtlpriv->rtlhal.disable_amsdu_8k = true;
/* for LPS & IPS */
rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
/* for early mode */
rtlpriv->rtlhal.earlymode_enable = false;
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = kmalloc(0x8000, GFP_KERNEL);
if (!rtlpriv->rtlhal.pfirmware)
return -ENOMEM;
rtlpriv->max_fw_size = 0x8000;
pr_info("Driver for Realtek RTL8192DU WLAN interface\n");
pr_info("Loading firmware file %s\n", fw_name);
/* request fw */
err = request_firmware_nowait(THIS_MODULE, 1, fw_name,
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
pr_err("Failed to request firmware!\n");
kfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
return err;
}
return 0;
}
static void rtl92du_deinit_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
kfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
rtl92du_deinit_shared_data(hw);
}
static const struct rtl_hal_ops rtl8192du_hal_ops = {
.init_sw_vars = rtl92du_init_sw_vars,
.deinit_sw_vars = rtl92du_deinit_sw_vars,
.read_chip_version = rtl92du_read_chip_version,
.read_eeprom_info = rtl92d_read_eeprom_info,
.hw_init = rtl92du_hw_init,
.hw_disable = rtl92du_card_disable,
.enable_interrupt = rtl92du_enable_interrupt,
.disable_interrupt = rtl92du_disable_interrupt,
.set_network_type = rtl92du_set_network_type,
.set_chk_bssid = rtl92du_set_check_bssid,
.set_qos = rtl92d_set_qos,
.set_bcn_reg = rtl92du_set_beacon_related_registers,
.set_bcn_intv = rtl92du_set_beacon_interval,
.update_interrupt_mask = rtl92du_update_interrupt_mask,
.get_hw_reg = rtl92du_get_hw_reg,
.set_hw_reg = rtl92du_set_hw_reg,
.update_rate_tbl = rtl92d_update_hal_rate_tbl,
.fill_tx_desc = rtl92du_tx_fill_desc,
.query_rx_desc = rtl92d_rx_query_desc,
.set_channel_access = rtl92d_update_channel_access_setting,
.radio_onoff_checking = rtl92d_gpio_radio_on_off_checking,
.set_bw_mode = rtl92du_phy_set_bw_mode,
.switch_channel = rtl92du_phy_sw_chnl,
.dm_watchdog = rtl92du_dm_watchdog,
.scan_operation_backup = rtl_phy_scan_operation_backup,
.set_rf_power_state = rtl92du_phy_set_rf_power_state,
.led_control = rtl92du_led_control,
.set_desc = rtl92d_set_desc,
.get_desc = rtl92d_get_desc,
.enable_hw_sec = rtl92d_enable_hw_security_config,
.set_key = rtl92d_set_key,
.get_bbreg = rtl92du_phy_query_bb_reg,
.set_bbreg = rtl92du_phy_set_bb_reg,
.get_rfreg = rtl92d_phy_query_rf_reg,
.set_rfreg = rtl92d_phy_set_rf_reg,
.linked_set_reg = rtl92du_linked_set_reg,
.fill_h2c_cmd = rtl92d_fill_h2c_cmd,
.get_btc_status = rtl_btc_status_false,
.phy_iq_calibrate = rtl92du_phy_iq_calibrate,
.phy_lc_calibrate = rtl92du_phy_lc_calibrate,
};
static struct rtl_mod_params rtl92du_mod_params = {
.sw_crypto = false,
.inactiveps = false,
.swctrl_lps = false,
.debug_level = 0,
.debug_mask = 0,
};
static const struct rtl_hal_usbint_cfg rtl92du_interface_cfg = {
/* rx */
.rx_urb_num = 8,
.rx_max_size = 15360,
.usb_rx_hdl = NULL,
.usb_rx_segregate_hdl = NULL,
/* tx */
.usb_tx_cleanup = rtl92du_tx_cleanup,
.usb_tx_post_hdl = rtl92du_tx_post_hdl,
.usb_tx_aggregate_hdl = rtl92du_tx_aggregate_hdl,
.usb_endpoint_mapping = rtl92du_endpoint_mapping,
.usb_mq_to_hwq = rtl92du_mq_to_hwq,
};
static const struct rtl_hal_cfg rtl92du_hal_cfg = {
.name = "rtl8192du",
.ops = &rtl8192du_hal_ops,
.mod_params = &rtl92du_mod_params,
.usb_interface_cfg = &rtl92du_interface_cfg,
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
.maps[SYS_CLK] = REG_SYS_CLKR,
.maps[MAC_RCR_AM] = RCR_AM,
.maps[MAC_RCR_AB] = RCR_AB,
.maps[MAC_RCR_ACRC32] = RCR_ACRC32,
.maps[MAC_RCR_ACF] = RCR_ACF,
.maps[MAC_RCR_AAP] = RCR_AAP,
.maps[EFUSE_TEST] = REG_EFUSE_TEST,
.maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_CLK] = 0, /* just for 92se */
.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
.maps[EFUSE_LOADER_CLK_EN] = 0,
.maps[EFUSE_ANA8M] = 0, /* just for 92se */
.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
.maps[RWCAM] = REG_CAMCMD,
.maps[WCAMI] = REG_CAMWRITE,
.maps[RCAMO] = REG_CAMREAD,
.maps[CAMDBG] = REG_CAMDBG,
.maps[SECR] = REG_SECCFG,
.maps[SEC_CAM_NONE] = CAM_NONE,
.maps[SEC_CAM_WEP40] = CAM_WEP40,
.maps[SEC_CAM_TKIP] = CAM_TKIP,
.maps[SEC_CAM_AES] = CAM_AES,
.maps[SEC_CAM_WEP104] = CAM_WEP104,
.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
.maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
.maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
.maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
.maps[RTL_IMR_BCNINT] = IMR_BCNINT,
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
.maps[RTL_IMR_RDU] = IMR_RDU,
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
.maps[RTL_IMR_BDOK] = IMR_BDOK,
.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
.maps[RTL_IMR_TBDER] = IMR_TBDER,
.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
.maps[RTL_IMR_VODOK] = IMR_VODOK,
.maps[RTL_IMR_ROK] = IMR_ROK,
.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
.maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
.maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
.maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
.maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
.maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
.maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
.maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
.maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
.maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
.maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
.maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
.maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
.maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
.maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
};
module_param_named(swenc, rtl92du_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl92du_mod_params.debug_level, int, 0644);
module_param_named(ips, rtl92du_mod_params.inactiveps, bool, 0444);
module_param_named(swlps, rtl92du_mod_params.swctrl_lps, bool, 0444);
module_param_named(debug_mask, rtl92du_mod_params.debug_mask, ullong, 0644);
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 0)\n");
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
#define USB_VENDOR_ID_REALTEK 0x0bda
static const struct usb_device_id rtl8192d_usb_ids[] = {
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8193, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x0193, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x2019, 0xab2d, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x2019, 0x4903, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x2019, 0x4904, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x07b8, 0x8193, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x20f4, 0x664b, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x04dd, 0x954f, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x04dd, 0x96a6, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x050d, 0x110a, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x050d, 0x1105, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x050d, 0x120a, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x1668, 0x8102, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x0930, 0x0a0a, rtl92du_hal_cfg)},
{RTL_USB_DEVICE(0x2001, 0x330c, rtl92du_hal_cfg)},
{}
};
MODULE_DEVICE_TABLE(usb, rtl8192d_usb_ids);
static int rtl8192du_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return rtl_usb_probe(intf, id, &rtl92du_hal_cfg);
}
static struct usb_driver rtl8192du_driver = {
.name = "rtl8192du",
.probe = rtl8192du_probe,
.disconnect = rtl_usb_disconnect,
.id_table = rtl8192d_usb_ids,
.disable_hub_initiated_lpm = 1,
};
module_usb_driver(rtl8192du_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8192DU 802.11n Dual Mac USB wireless");
MODULE_FIRMWARE("rtlwifi/rtl8192dufw.bin");