Search Linux Wireless

Re: [PATCH 2/3] wifi: rtlwifi: Adjust rtl8192d-common for USB

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux