On Wed, 2024-03-13 at 00:20 +0200, Bitterblue Smith wrote: > > A few of the shared functions need small changes for the USB driver. > > Also, add a few macros to wifi.h and initialise rtlhal.interfaceindex > for USB devices. Please run checkpatch.pl that reports "total: 0 errors, 11 warnings, 27 checks, 8045 lines checked" I think these are newly introduced by this patch. > > Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx> > --- > .../wireless/realtek/rtlwifi/rtl8192d/def.h | 2 + > .../realtek/rtlwifi/rtl8192d/fw_common.c | 19 +++ > .../realtek/rtlwifi/rtl8192d/hw_common.c | 46 ++++-- > .../realtek/rtlwifi/rtl8192d/phy_common.c | 26 ++- > .../realtek/rtlwifi/rtl8192d/phy_common.h | 6 + > .../wireless/realtek/rtlwifi/rtl8192d/reg.h | 156 +++++++++++++++--- > drivers/net/wireless/realtek/rtlwifi/usb.c | 3 + > drivers/net/wireless/realtek/rtlwifi/wifi.h | 5 + > 8 files changed, 222 insertions(+), 41 deletions(-) > > diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h > b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h > index 21726d9b4aef..ee45f51fcf71 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h > +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/def.h > @@ -116,6 +116,8 @@ enum version_8192d { > #define IS_92D_E_CUT(version) ((IS_92D(version)) ? \ > ((GET_CVID_CUT_VERSION(version) == \ > CHIP_92D_E_CUT) ? true : false) : false) > +#define IS_NORMAL_CHIP(version) \ > + ((version & NORMAL_CHIP) ? true : false) #define IS_NORMAL_CHIP(version) !!(version & NORMAL_CHIP) > > enum rf_optype { > RF_OP_BY_SW_3WIRE = 0, > diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c > b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c > index e333275c51c3..ac48bd9dcc9f 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c > +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/fw_common.c > @@ -94,9 +94,22 @@ EXPORT_SYMBOL_GPL(rtl92d_fw_free_to_go); > void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) > { > struct rtl_priv *rtlpriv = rtl_priv(hw); > + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); > u8 u1b_tmp; > u8 delay = 100; > > + if (rtlhal->interface == INTF_USB) { > + delay *= 60; Out of curiosity, how did you decide this factor 60? Let's define a name such as RTL_USB_DELAY_FACTOR to be clear. > + > + rtl_write_byte(rtlpriv, REG_FSIMR, 0); > + > + /* We need to disable other HRCV INT to influence 8051 reset. */ > + rtl_write_byte(rtlpriv, REG_FWIMR, 0x20); > + > + /* Close mask to prevent incorrect FW write operation. */ > + rtl_write_byte(rtlpriv, REG_FTIMR, 0); > + } > + > /* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */ > rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); > u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); > @@ -107,6 +120,12 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) > udelay(50); > u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); > } > + > + if (rtlhal->interface == INTF_USB) { > + if ((u1b_tmp & BIT(2)) && delay == 0) #define BIT_FEN_CPUEN BIT(10) Because BIT(2) of REG_SYS_FUNC_EN + 1 is BIT(10) > + rtl_write_byte(rtlpriv, REG_FWIMR, 0); > + } > + > WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n"); > rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, > "=====> 8051 reset success (%d)\n", delay); > diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c > b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c > index ada08f82adff..b9bc2fdde5e2 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c > +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/hw_common.c > @@ -622,9 +622,14 @@ static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw, > { > struct rtl_priv *rtlpriv = rtl_priv(hw); > struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); > - u8 macphy_crvalue = content[EEPROM_MAC_FUNCTION]; > + bool is_single_mac = true; > > - if (macphy_crvalue & BIT(3)) { > + if (rtlhal->interface == INTF_PCI) > + is_single_mac = !!(content[EEPROM_MAC_FUNCTION] & BIT(3)); > + else if (rtlhal->interface == INTF_USB) > + is_single_mac = !(content[EEPROM_ENDPOINT_SETTING] & BIT(0)); > + > + if (is_single_mac) { > rtlhal->macphymode = SINGLEMAC_SINGLEPHY; > rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, > "MacPhyMode SINGLEMAC_SINGLEPHY\n"); > @@ -663,6 +668,7 @@ static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw) > rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n"); > break; > case 0xCC33: > + case 0x33CC: > chipver |= CHIP_92D_E_CUT; > rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "E-CUT!!!\n"); > break; > @@ -679,14 +685,22 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) > struct rtl_priv *rtlpriv = rtl_priv(hw); > struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); > struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); > - int params[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, > - EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR_MAC0_92D, > - EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, > - COUNTRY_CODE_WORLD_WIDE_13}; > + int params_pci[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, > + EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR_MAC0_92D, > + EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, > + COUNTRY_CODE_WORLD_WIDE_13}; > + int params_usb[] = {RTL8190_EEPROM_ID, EEPROM_VID_USB, EEPROM_PID_USB, > + EEPROM_VID_USB, EEPROM_PID_USB, EEPROM_MAC_ADDR_MAC0_92DU, > + EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, > + COUNTRY_CODE_WORLD_WIDE_13}; static const int params_xxx[], and the const should propagate into rtl_get_hwinfo(). > + int *params = params_pci; > int i; > u16 usvalue; > u8 *hwinfo; > > + if (rtlhal->interface == INTF_USB) > + params = params_usb; > + > hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); > if (!hwinfo) > return; > @@ -858,7 +872,7 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, > 1 : 0; > enum wireless_mode wirelessmode = 0; > bool shortgi = false; > - u32 value[2]; > + u8 rate_mask[5]; > u8 macid = 0; > u8 mimo_ps = IEEE80211_SMPS_OFF; > > @@ -966,12 +980,17 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, > break; > } > > - value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); > - value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80; > + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | > + (ratr_index << 28); 'u32' is weird to me. Shouldn't it be __le32? But I prefer a struct of rate_mask. > + rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; > rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, > - "ratr_bitmap :%x value0:%x value1:%x\n", > - ratr_bitmap, value[0], value[1]); > - rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value); > + "Rate_index:%x, ratr_val:%x, %5phC\n", > + ratr_index, ratr_bitmap, rate_mask); > + memcpy(rtlpriv->rate_mask, rate_mask, 5); 5 ==> sizeof(rtlpriv->rate_mask) > + /* rtl92d_fill_h2c_cmd() does USB I/O and will result in a > + * "scheduled while atomic" if called directly > + */ > + schedule_work(&rtlpriv->works.fill_h2c_cmd); > if (macid != 0) > sta_entry->ratr_index = ratr_index; > } > @@ -1015,7 +1034,8 @@ bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) > bool actuallyset = false; > unsigned long flag; > > - if (rtlpci->being_init_adapter) > + if (rtlpriv->rtlhal.interface == INTF_PCI && > + rtlpci->being_init_adapter) > return false; > if (ppsc->swrf_processing) > return false; > diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c > b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c > index 487628ac491b..1e39940a3ba7 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c > +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.c > @@ -81,11 +81,13 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, > rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, > "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", > regaddr, rfpath, bitmask); > - spin_lock(&rtlpriv->locks.rf_lock); > + if (rtlpriv->rtlhal.interface == INTF_PCI) > + spin_lock(&rtlpriv->locks.rf_lock); Does it mean USB never read/write RF registers simultaneously? How can you ensure that? > original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); > bitshift = calculate_bit_shift(bitmask); > readback_value = (original_value & bitmask) >> bitshift; > - spin_unlock(&rtlpriv->locks.rf_lock); > + if (rtlpriv->rtlhal.interface == INTF_PCI) > + spin_unlock(&rtlpriv->locks.rf_lock); > rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, > "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", > regaddr, rfpath, bitmask, original_value); > @@ -105,7 +107,8 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, > regaddr, bitmask, data, rfpath); > if (bitmask == 0) > return; > - spin_lock(&rtlpriv->locks.rf_lock); > + if (rtlpriv->rtlhal.interface == INTF_PCI) > + spin_lock(&rtlpriv->locks.rf_lock); > if (rtlphy->rf_mode != RF_OP_BY_FW) { > if (bitmask != RFREG_OFFSET_MASK) { > original_value = _rtl92d_phy_rf_serial_read(hw, > @@ -116,7 +119,8 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, > } > _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data); > } > - spin_unlock(&rtlpriv->locks.rf_lock); > + if (rtlpriv->rtlhal.interface == INTF_PCI) > + spin_unlock(&rtlpriv->locks.rf_lock); > rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, > "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", > regaddr, bitmask, data, rfpath); > @@ -642,6 +646,8 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) > case IO_CMD_PAUSE_DM_BY_SCAN: > rtlphy->initgain_backup.xaagccore1 = de_digtable->cur_igvalue; > de_digtable->cur_igvalue = 0x37; > + if (rtlpriv->rtlhal.interface == INTF_USB) > + de_digtable->cur_igvalue = 0x17; > rtl92d_dm_write_dig(hw); > break; > default: > @@ -698,22 +704,28 @@ void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw) > struct rtl_priv *rtlpriv = rtl_priv(hw); > struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); > u8 offset = REG_MAC_PHY_CTRL_NORMAL; > + u8 temp = 0xf0; 'tmp' instead. Or 'phy_ctrl', or 'ctrl' would be clear. > + > + if (rtlhal->interface == INTF_USB) { > + temp = rtl_read_byte(rtlpriv, offset); > + temp &= ~(BIT(0) | BIT(1) | BIT(2)); > + } > > switch (rtlhal->macphymode) { > case DUALMAC_DUALPHY: > rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, > "MacPhyMode: DUALMAC_DUALPHY\n"); > - rtl_write_byte(rtlpriv, offset, 0xF3); > + rtl_write_byte(rtlpriv, offset, temp | BIT(0) | BIT(1)); > break; > case SINGLEMAC_SINGLEPHY: > rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, > "MacPhyMode: SINGLEMAC_SINGLEPHY\n"); > - rtl_write_byte(rtlpriv, offset, 0xF4); > + rtl_write_byte(rtlpriv, offset, temp | BIT(2)); > break; > case DUALMAC_SINGLEPHY: > rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, > "MacPhyMode: DUALMAC_SINGLEPHY\n"); > - rtl_write_byte(rtlpriv, offset, 0xF1); > + rtl_write_byte(rtlpriv, offset, temp | BIT(0)); > break; > } > } > diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h > b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h > index 071776d05eb9..5649a11f4405 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h > +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/phy_common.h > @@ -41,6 +41,9 @@ static inline void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw, > { > struct rtl_priv *rtlpriv = rtl_priv(hw); > > + if (rtlpriv->rtlhal.interface == INTF_USB) > + return; > + > if (rtlpriv->rtlhal.interfaceindex == 1) > spin_lock_irqsave(&rtlpriv->locks.cck_and_rw_pagea_lock, *flag); > } > @@ -50,6 +53,9 @@ static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw, > { > struct rtl_priv *rtlpriv = rtl_priv(hw); > > + if (rtlpriv->rtlhal.interface == INTF_USB) > + return; > + Why USB doesn't need the lock? I guess USB could be "scheduled while atomic", but this lock is to ensure read/write as expected. If you have explanation, please add them to commit message. > if (rtlpriv->rtlhal.interfaceindex == 1) > spin_unlock_irqrestore(&rtlpriv->locks.cck_and_rw_pagea_lock, > *flag); > diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h > b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h > index 2783d7e7b227..1f2daf779539 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h > +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h > [...] > + > +#define _TXDMA_HIQ_MAP(x) (((x) & 0x3) << 14) GENMASK(15, 14) ? > +#define _TXDMA_MGQ_MAP(x) (((x) & 0x3) << 12) > +#define _TXDMA_BKQ_MAP(x) (((x) & 0x3) << 10) > +#define _TXDMA_BEQ_MAP(x) (((x) & 0x3) << 8) > +#define _TXDMA_VIQ_MAP(x) (((x) & 0x3) << 6) > +#define _TXDMA_VOQ_MAP(x) (((x) & 0x3) << 4) > + > +#define QUEUE_LOW 1 > +#define QUEUE_NORMAL 2 > +#define QUEUE_HIGH 3 > + > +#define _HPQ(x) ((x) & 0xFF) #define HPQ_MASK GENMASK(7, 0) u32_get_bits(x, HPQ_MASK) ? > +#define _LPQ(x) (((x) & 0xFF) << 8) > +#define _PUBQ(x) (((x) & 0xFF) << 16) > +#define _NPQ(x) ((x) & 0xFF) > +#define LD_RQPN BIT(31) > + > [...] > diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c > b/drivers/net/wireless/realtek/rtlwifi/usb.c > index 6e8c87a2fae4..2ea72d9e3957 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/usb.c > +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c > @@ -979,6 +979,9 @@ int rtl_usb_probe(struct usb_interface *intf, > usb_priv->dev.intf = intf; > usb_priv->dev.udev = udev; > usb_set_intfdata(intf, hw); > + /* For dual MAC RTL8192DU, which has two interfaces. */ > + rtlpriv->rtlhal.interfaceindex = > + intf->altsetting[0].desc.bInterfaceNumber; So, you will see two USB adapters when you plug 8192DU? > /* init cfg & intf_ops */ > rtlpriv->rtlhal.interface = INTF_USB; > rtlpriv->cfg = rtl_hal_cfg; > diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h > b/drivers/net/wireless/realtek/rtlwifi/wifi.h > index 9fabf597cfd6..c45463744f16 100644 > --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h > +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h > @@ -20,6 +20,7 @@ > #define MASKBYTE1 0xff00 > #define MASKBYTE2 0xff0000 > #define MASKBYTE3 0xff000000 > +#define MASKH3BYTES 0xffffff00 > #define MASKHWORD 0xffff0000 > #define MASKLWORD 0x0000ffff > #define MASKDWORD 0xffffffff > @@ -48,6 +49,10 @@ > #define MASK20BITS 0xfffff > #define RFREG_OFFSET_MASK 0xfffff > > +/* For dual MAC RTL8192DU */ > +#define MAC0_ACCESS_PHY1 0x4000 > +#define MAC1_ACCESS_PHY0 0x2000 > + > #define RF_CHANGE_BY_INIT 0 > #define RF_CHANGE_BY_IPS BIT(28) > #define RF_CHANGE_BY_PS BIT(29) > -- > 2.43.2