Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH] rtlwifi: rtl8723bs: Add firmware for new driver
From: Larry Finger @ 2017-01-19 21:04 UTC (permalink / raw)
  To: linux-firmware; +Cc: linux-wireless, Larry Finger, netdev

This driver is being added for Fedora users, and will then be added
to the mainline kernel.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
c: Hans de Goede <hdegoede@redhat.com>
---
 WHENCE                          |  13 +++++++++++++
 rtlwifi/rtl8723bs_ap_wowlan.bin | Bin 0 -> 20886 bytes
 rtlwifi/rtl8723bs_bt.bin        | Bin 0 -> 9120 bytes
 rtlwifi/rtl8723bs_nic.bin       | Bin 0 -> 32108 bytes
 rtlwifi/rtl8723bs_wowlan.bin    | Bin 0 -> 26398 bytes
 5 files changed, 13 insertions(+)
 create mode 100644 rtlwifi/rtl8723bs_ap_wowlan.bin
 create mode 100644 rtlwifi/rtl8723bs_bt.bin
 create mode 100644 rtlwifi/rtl8723bs_nic.bin
 create mode 100644 rtlwifi/rtl8723bs_wowlan.bin

diff --git a/WHENCE b/WHENCE
index fd68b71..21c1b68 100644
--- a/WHENCE
+++ b/WHENCE
@@ -2402,6 +2402,19 @@ Licence: Redistributable. See LICENCE.rtlwifi_firmware.txt for details.
 
 --------------------------------------------------------------------------
 
+Driver: rtl8723bs - Realtek 802.11n WLAN driver for RTL8723BS
+
+Info: Firmware files extracted from data statements in Realtek driver
+      v4.3.5.5_12290.20140916_BTCOEX20140507-4E40.
+File: rtlwifi/rtl8723bs_bt.bin
+File: rtlwifi/rtl8723bs_nic.bin
+File: rtlwifi/rtl8723bs_ap_wowlan.bin
+File: rtlwifi/rtl8723bs_wowlan.bin
+
+Licence: Redistributable. See LICENCE.rtlwifi_firmware.txt for details.
+
+--------------------------------------------------------------------------
+
 Driver: rtl8xxxu - Realtek 802.11n WLAN driver for RTL8XXX USB devices
 
 Info: rtl8723au taken from Realtek driver
diff --git a/rtlwifi/rtl8723bs_ap_wowlan.bin b/rtlwifi/rtl8723bs_ap_wowlan.bin
new file mode 100644
index 0000000000000000000000000000000000000000..944bc16c3d55d495c1660710dac1a59a7e60868a
GIT binary patch
literal 20886
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
BtC#=)

literal 0
HcmV?d00001

diff --git a/rtlwifi/rtl8723bs_bt.bin b/rtlwifi/rtl8723bs_bt.bin
new file mode 100644
index 0000000000000000000000000000000000000000..f29df42f93347813a18df81767acfd3adcbc1f72
GIT binary patch
literal 9120
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

literal 0
HcmV?d00001

diff --git a/rtlwifi/rtl8723bs_nic.bin b/rtlwifi/rtl8723bs_nic.bin
new file mode 100644
index 0000000000000000000000000000000000000000..8d534053823e47ba4e49c8600463af47fbec7306
GIT binary patch
literal 32108
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

literal 0
HcmV?d00001

diff --git a/rtlwifi/rtl8723bs_wowlan.bin b/rtlwifi/rtl8723bs_wowlan.bin
new file mode 100644
index 0000000000000000000000000000000000000000..473e29c3217fb06046aa0df7a22b2e613b331235
GIT binary patch
literal 26398
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%0D9(z1wjTOY@OzRPq2uwrhby&7hjG
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

literal 0
HcmV?d00001

-- 
2.10.2

^ permalink raw reply related

* Re: [PATCH v2 13/14] rt2x00: rt2800lib: add support for RT3352 with 20MHz crystal
From: Daniel Golle @ 2017-01-19 20:52 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: linux-mips, linux-wireless, michel.stempin, Kalle Valo,
	Felix Fietkau, John Crispin, Gabor Juhos
In-Reply-To: <20170119133010.GH1798@makrotopia.org>

On Thu, Jan 19, 2017 at 02:30:14PM +0100, Daniel Golle wrote:
> Hi Stanislaw,
> 
> On Wed, Jan 18, 2017 at 03:30:02PM +0100, Stanislaw Gruszka wrote:
> > On Mon, Jan 16, 2017 at 04:15:56AM +0100, Daniel Golle wrote:
> > > Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> > > Signed-off-by: Mathias Kresin <dev@kresin.me>
> > > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > > ---
> > >  drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 50 +++++++++++++++++++++++++-
> > >  drivers/net/wireless/ralink/rt2x00/rt2x00.h    |  2 ++
> > >  2 files changed, 51 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > > index 93c97eade334..cb1457595f05 100644
> > > --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > > +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > > @@ -36,6 +36,7 @@
> > >  #include <linux/kernel.h>
> > >  #include <linux/module.h>
> > >  #include <linux/slab.h>
> > > +#include <linux/clk.h>
> > >  
> > >  #include "rt2x00.h"
> > >  #include "rt2800lib.h"
> > > @@ -7675,6 +7676,27 @@ static const struct rf_channel rf_vals_5592_xtal40[] = {
> > >  	{196, 83, 0, 12, 1},
> > >  };
> > >  
> > > +/*
> > > + * RF value list for rt3xxx with Xtal20MHz
> > > + * Supports: 2.4 GHz (all) (RF3322)
> > > + */
> > > +static const struct rf_channel rf_vals_xtal20mhz_3x[] = {
> > Please locate this values in alphabetical order (i.e. after _3x and 
> > before _5592 ).
> 
> Sure, sorry, that ended up in the wrong order when rebase the patches.
> 
> > 
> > >  	struct hw_mode_spec *spec = &rt2x00dev->spec;
> > > @@ -7764,7 +7786,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> > >  	case RF5390:
> > >  	case RF5392:
> > >  		spec->num_channels = 14;
> > > -		spec->channels = rf_vals_3x;
> > > +		if (spec->clk_is_20mhz)
> > > +			spec->channels = rf_vals_xtal20mhz_3x;
> > > +		else
> > > +			spec->channels = rf_vals_3x;
> > >  		break;
> > 
> > How does vendor drivers recognize xtal (I assume rf_vals_xtal20mhz_3x 
> > values were taken from vendor driver) ? It should be possible to get
> > clock frequency from device register like is is done on RF5592, without
> > adding additional clock recognition code. But if such code is needed
> > I prefer that low level board/platform routines do it and place clock
> > frequency for rt2x00 in rt2x00dev->dev->platform_data.

I researched and found this has already been implemented in the ramips
platform code, see

https://git.kernel.org/cgit/linux/kernel/git/kvalo/wireless-drivers-next.git/tree/arch/mips/ralink/rt305x.c#n194

The patch submitted uses this existing infrastructure which *does*
auto-probe the clock from the SoC's SYSCTRL register.
I'll re-submit a v3 with the alphabetic order above fixed, ok?


Cheers


Daniel

^ permalink raw reply

* Re: [PATCH v3] rt2x00: add support for RT5350 WiSoC
From: Daniel Golle @ 2017-01-19 20:37 UTC (permalink / raw)
  To: Kalle Valo
  Cc: linux-wireless, Johannes Berg, Stanislaw Gruszka, roman,
	michel.stempin, c.mignanti, evaxige, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <87d1fioojx.fsf@kamboji.qca.qualcomm.com>

On Thu, Jan 19, 2017 at 09:08:34PM +0200, Kalle Valo wrote:
> Daniel Golle <daniel@makrotopia.org> writes:
> 
> > From: Michel Stempin <michel.stempin@wanadoo.fr>
> >
> > Support for the RT5350 WiSoC was added to OpenWrt after having a
> > lengthy debate about the legality of the original submission, see
> > https://lists.openwrt.org/pipermail/openwrt-devel/2013-January/018224.html
> > MTK/Ralink Acked replied and says we can merge this patch under the GPL.
> > https://dev.openwrt.org/changeset/36177
> >
> > Signed-off-by: Serge Vasilugin <vasilugin@yandex.ru>
> > Tested-by: Michel Stempin <michel.stempin@wanadoo.fr>
> > Acked-by: John Crispin <blogic@openwrt.org>
> > [daniel@makrotopia.org: added commit message, cleaned up code]
> >
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> > v2: reordered patches to breakout RT3883 from the original series
> > v3: remove superflus EEPROM_NIC_CONF0 mangeling from RT5350 patch
> 
> As this is not part of the patch series I assume this patch doesn't have
> any dependencies and can be applied separately (if Stanislaw acks it).

Well, oops, it does depend on
https://patchwork.kernel.org/patch/9518023/
being merged first, at least partially.
Sorry for the mess...


Cheers


Daniel

^ permalink raw reply

* [PATCH v2 1/3] rtlwifi: Download firmware as bytes rather than as dwords
From: Larry Finger @ 2017-01-19 20:28 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih
In-Reply-To: <20170119202808.27752-1-Larry.Finger@lwfinger.net>

The firmware is read from disk as a little-endian byte string. The code
that loads the firmware into the device transfers it as 4-byte quantities.
The routines that write multi-byte quantities on BE hardware assume that
the data are in CPU order, and automatically do the conversion to the LE
order required by the device. As a result, the firmware is transmitted
incorrectly. Rather than do multiple byte swaps on the data, the download
routine is revised to transmit bytes rather than dwords. Although the
number of I/O operations is increased, the firmware is not often loaded.

All drivers have the same bug, and use essentially the same code to
download firmware. These routines have been moved into rtlwifi.

Some CamelCase variables have been renamed.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>
---
V2 - No functional changes. Merge conflict resolved.
---
 drivers/net/wireless/realtek/rtlwifi/efuse.c       | 45 ++++++++++++++
 drivers/net/wireless/realtek/rtlwifi/efuse.h       |  4 ++
 .../net/wireless/realtek/rtlwifi/rtl8188ee/fw.c    | 67 ++-------------------
 .../wireless/realtek/rtlwifi/rtl8192c/fw_common.c  | 70 +++-------------------
 .../net/wireless/realtek/rtlwifi/rtl8192de/fw.c    | 70 +++-------------------
 .../net/wireless/realtek/rtlwifi/rtl8192ee/fw.c    | 68 ++-------------------
 .../realtek/rtlwifi/rtl8723com/fw_common.c         | 69 ++-------------------
 .../realtek/rtlwifi/rtl8723com/fw_common.h         |  6 --
 .../net/wireless/realtek/rtlwifi/rtl8821ae/fw.c    | 67 ++-------------------
 9 files changed, 85 insertions(+), 381 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c
index afc7550..eb58633 100644
--- a/drivers/net/wireless/realtek/rtlwifi/efuse.c
+++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c
@@ -31,6 +31,9 @@ static const u8 MAX_PGPKT_SIZE = 9;
 static const u8 PGPKT_DATA_SIZE = 8;
 static const int EFUSE_MAX_SIZE = 512;
 
+#define START_ADDRESS		0x1000
+#define REG_MCUFWDL		0x0080
+
 static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
 	{0, 0, 0, 2},
 	{0, 1, 0, 2},
@@ -1320,3 +1323,45 @@ int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rtl_get_hwinfo);
+
+void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 *pu4byteptr = (u8 *)buffer;
+	u32 i;
+
+	for (i = 0; i < size; i++)
+		rtl_write_byte(rtlpriv, (START_ADDRESS + i), *(pu4byteptr + i));
+}
+EXPORT_SYMBOL_GPL(rtl_fw_block_write);
+
+void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
+		       u32 size)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 value8;
+	u8 u8page = (u8)(page & 0x07);
+
+	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
+
+	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
+	rtl_fw_block_write(hw, buffer, size);
+}
+EXPORT_SYMBOL_GPL(rtl_fw_page_write);
+
+void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
+{
+	u32 fwlen = *pfwlen;
+	u8 remain = (u8)(fwlen % 4);
+
+	remain = (remain == 0) ? 0 : (4 - remain);
+
+	while (remain > 0) {
+		pfwbuf[fwlen] = 0;
+		fwlen++;
+		remain--;
+	}
+
+	*pfwlen = fwlen;
+}
+EXPORT_SYMBOL_GPL(rtl_fill_dummy);
diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.h b/drivers/net/wireless/realtek/rtlwifi/efuse.h
index 51aa121..1338ae6 100644
--- a/drivers/net/wireless/realtek/rtlwifi/efuse.h
+++ b/drivers/net/wireless/realtek/rtlwifi/efuse.h
@@ -111,5 +111,9 @@ void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
 void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
 int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
 		   int max_size, u8 *hwinfo, int *params);
+void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen);
+void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
+		       u32 size);
+void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size);
 
 #endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
index afa784a..21ed9ad 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -53,63 +54,6 @@ static void _rtl88e_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 	}
 }
 
-static void _rtl88e_fw_block_write(struct ieee80211_hw *hw,
-				   const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u32 blocksize = sizeof(u32);
-	u8 *bufferptr = (u8 *)buffer;
-	u32 *pu4BytePtr = (u32 *)buffer;
-	u32 i, offset, blockcount, remainsize;
-
-	blockcount = size / blocksize;
-	remainsize = size % blocksize;
-
-	for (i = 0; i < blockcount; i++) {
-		offset = i * blocksize;
-		rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-				*(pu4BytePtr + i));
-	}
-
-	if (remainsize) {
-		offset = blockcount * blocksize;
-		bufferptr += offset;
-		for (i = 0; i < remainsize; i++) {
-			rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
-						 offset + i), *(bufferptr + i));
-		}
-	}
-}
-
-static void _rtl88e_fw_page_write(struct ieee80211_hw *hw,
-				  u32 page, const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u8 value8;
-	u8 u8page = (u8) (page & 0x07);
-
-	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-	_rtl88e_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-	u32 fwlen = *pfwlen;
-	u8 remain = (u8) (fwlen % 4);
-
-	remain = (remain == 0) ? 0 : (4 - remain);
-
-	while (remain > 0) {
-		pfwbuf[fwlen] = 0;
-		fwlen++;
-		remain--;
-	}
-
-	*pfwlen = fwlen;
-}
-
 static void _rtl88e_write_fw(struct ieee80211_hw *hw,
 			     enum version_8188e version, u8 *buffer, u32 size)
 {
@@ -120,7 +64,7 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw,
 
 	RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
 
-	_rtl88e_fill_dummy(bufferptr, &size);
+	rtl_fill_dummy(bufferptr, &size);
 
 	pagenums = size / FW_8192C_PAGE_SIZE;
 	remainsize = size % FW_8192C_PAGE_SIZE;
@@ -130,15 +74,14 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw,
 
 	for (page = 0; page < pagenums; page++) {
 		offset = page * FW_8192C_PAGE_SIZE;
-		_rtl88e_fw_page_write(hw, page, (bufferptr + offset),
-				      FW_8192C_PAGE_SIZE);
+		rtl_fw_page_write(hw, page, (bufferptr + offset),
+				  FW_8192C_PAGE_SIZE);
 	}
 
 	if (remainsize) {
 		offset = pagenums * FW_8192C_PAGE_SIZE;
 		page = pagenums;
-		_rtl88e_fw_page_write(hw, page, (bufferptr + offset),
-				      remainsize);
+		rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
 	}
 }
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
index 433ab7f..c7a7746 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "../rtl8192ce/reg.h"
 #include "../rtl8192ce/def.h"
 #include "fw_common.h"
@@ -68,63 +69,6 @@ static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 	}
 }
 
-static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
-				   const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u32 blocksize = sizeof(u32);
-	u8 *bufferptr = (u8 *)buffer;
-	u32 *pu4byteptr = (u32 *)buffer;
-	u32 i, offset, blockcount, remainsize;
-
-	blockcount = size / blocksize;
-	remainsize = size % blocksize;
-
-	for (i = 0; i < blockcount; i++) {
-		offset = i * blocksize;
-		rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-				*(pu4byteptr + i));
-	}
-
-	if (remainsize) {
-		offset = blockcount * blocksize;
-		bufferptr += offset;
-		for (i = 0; i < remainsize; i++) {
-			rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
-						 offset + i), *(bufferptr + i));
-		}
-	}
-}
-
-static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
-				  u32 page, const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u8 value8;
-	u8 u8page = (u8) (page & 0x07);
-
-	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-	_rtl92c_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-	u32 fwlen = *pfwlen;
-	u8 remain = (u8) (fwlen % 4);
-
-	remain = (remain == 0) ? 0 : (4 - remain);
-
-	while (remain > 0) {
-		pfwbuf[fwlen] = 0;
-		fwlen++;
-		remain--;
-	}
-
-	*pfwlen = fwlen;
-}
-
 static void _rtl92c_write_fw(struct ieee80211_hw *hw,
 			     enum version_8192c version, u8 *buffer, u32 size)
 {
@@ -140,7 +84,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
 		u32 page, offset;
 
 		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
-			_rtl92c_fill_dummy(bufferptr, &size);
+			rtl_fill_dummy(bufferptr, &size);
 
 		pageNums = size / FW_8192C_PAGE_SIZE;
 		remainsize = size % FW_8192C_PAGE_SIZE;
@@ -150,18 +94,18 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
 
 		for (page = 0; page < pageNums; page++) {
 			offset = page * FW_8192C_PAGE_SIZE;
-			_rtl92c_fw_page_write(hw, page, (bufferptr + offset),
-					      FW_8192C_PAGE_SIZE);
+			rtl_fw_page_write(hw, page, (bufferptr + offset),
+					  FW_8192C_PAGE_SIZE);
 		}
 
 		if (remainsize) {
 			offset = pageNums * FW_8192C_PAGE_SIZE;
 			page = pageNums;
-			_rtl92c_fw_page_write(hw, page, (bufferptr + offset),
-					      remainsize);
+			rtl_fw_page_write(hw, page, (bufferptr + offset),
+					  remainsize);
 		}
 	} else {
-		_rtl92c_fw_block_write(hw, buffer, size);
+		rtl_fw_block_write(hw, buffer, size);
 	}
 }
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c
index 569d572..88faeab 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -59,84 +60,31 @@ static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 	}
 }
 
-static void _rtl92d_fw_block_write(struct ieee80211_hw *hw,
-				   const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u32 blocksize = sizeof(u32);
-	u8 *bufferptr = (u8 *) buffer;
-	u32 *pu4BytePtr = (u32 *) buffer;
-	u32 i, offset, blockCount, remainSize;
-
-	blockCount = size / blocksize;
-	remainSize = size % blocksize;
-	for (i = 0; i < blockCount; i++) {
-		offset = i * blocksize;
-		rtl_write_dword(rtlpriv, (FW_8192D_START_ADDRESS + offset),
-				*(pu4BytePtr + i));
-	}
-	if (remainSize) {
-		offset = blockCount * blocksize;
-		bufferptr += offset;
-		for (i = 0; i < remainSize; i++) {
-			rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS +
-						 offset + i), *(bufferptr + i));
-		}
-	}
-}
-
-static void _rtl92d_fw_page_write(struct ieee80211_hw *hw,
-				  u32 page, const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u8 value8;
-	u8 u8page = (u8) (page & 0x07);
-
-	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-	_rtl92d_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-	u32 fwlen = *pfwlen;
-	u8 remain = (u8) (fwlen % 4);
-
-	remain = (remain == 0) ? 0 : (4 - remain);
-	while (remain > 0) {
-		pfwbuf[fwlen] = 0;
-		fwlen++;
-		remain--;
-	}
-	*pfwlen = fwlen;
-}
-
 static void _rtl92d_write_fw(struct ieee80211_hw *hw,
 			     enum version_8192d version, u8 *buffer, u32 size)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	u8 *bufferPtr = buffer;
-	u32 pagenums, remainSize;
+	u8 *bufferptr = buffer;
+	u32 pagenums, remainsize;
 	u32 page, offset;
 
 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
-		_rtl92d_fill_dummy(bufferPtr, &size);
+		rtl_fill_dummy(bufferptr, &size);
 	pagenums = size / FW_8192D_PAGE_SIZE;
-	remainSize = size % FW_8192D_PAGE_SIZE;
+	remainsize = size % FW_8192D_PAGE_SIZE;
 	if (pagenums > 8)
 		pr_err("Page numbers should not greater then 8\n");
 	for (page = 0; page < pagenums; page++) {
 		offset = page * FW_8192D_PAGE_SIZE;
-		_rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
-				      FW_8192D_PAGE_SIZE);
+		rtl_fw_page_write(hw, page, (bufferptr + offset),
+				  FW_8192D_PAGE_SIZE);
 	}
-	if (remainSize) {
+	if (remainsize) {
 		offset = pagenums * FW_8192D_PAGE_SIZE;
 		page = pagenums;
-		_rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
-				      remainSize);
+		rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
 	}
 }
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
index 78ee6e1..9d7a16c 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -48,64 +49,6 @@ static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 	}
 }
 
-static void _rtl92ee_fw_block_write(struct ieee80211_hw *hw,
-				    const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u32 blocksize = sizeof(u32);
-	u8 *bufferptr = (u8 *)buffer;
-	u32 *pu4byteptr = (u32 *)buffer;
-	u32 i, offset, blockcount, remainsize;
-
-	blockcount = size / blocksize;
-	remainsize = size % blocksize;
-
-	for (i = 0; i < blockcount; i++) {
-		offset = i * blocksize;
-		rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-				*(pu4byteptr + i));
-	}
-
-	if (remainsize) {
-		offset = blockcount * blocksize;
-		bufferptr += offset;
-		for (i = 0; i < remainsize; i++) {
-			rtl_write_byte(rtlpriv,
-				       (FW_8192C_START_ADDRESS + offset + i),
-				       *(bufferptr + i));
-		}
-	}
-}
-
-static void _rtl92ee_fw_page_write(struct ieee80211_hw *hw, u32 page,
-				   const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u8 value8;
-	u8 u8page = (u8)(page & 0x07);
-
-	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-
-	_rtl92ee_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl92ee_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-	u32 fwlen = *pfwlen;
-	u8 remain = (u8)(fwlen % 4);
-
-	remain = (remain == 0) ? 0 : (4 - remain);
-
-	while (remain > 0) {
-		pfwbuf[fwlen] = 0;
-		fwlen++;
-		remain--;
-	}
-
-	*pfwlen = fwlen;
-}
-
 static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
 			      enum version_8192e version,
 			      u8 *buffer, u32 size)
@@ -117,7 +60,7 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
 
 	RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "FW size is %d bytes,\n", size);
 
-	_rtl92ee_fill_dummy(bufferptr, &size);
+	rtl_fill_dummy(bufferptr, &size);
 
 	pagenums = size / FW_8192C_PAGE_SIZE;
 	remainsize = size % FW_8192C_PAGE_SIZE;
@@ -127,16 +70,15 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
 
 	for (page = 0; page < pagenums; page++) {
 		offset = page * FW_8192C_PAGE_SIZE;
-		_rtl92ee_fw_page_write(hw, page, (bufferptr + offset),
-				       FW_8192C_PAGE_SIZE);
+		rtl_fw_page_write(hw, page, (bufferptr + offset),
+				  FW_8192C_PAGE_SIZE);
 		udelay(2);
 	}
 
 	if (remainsize) {
 		offset = pagenums * FW_8192C_PAGE_SIZE;
 		page = pagenums;
-		_rtl92ee_fw_page_write(hw, page, (bufferptr + offset),
-				       remainsize);
+		rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
 	}
 }
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c
index 8e0d038..ac573d6 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../efuse.h"
 #include "fw_common.h"
 #include <linux/module.h>
 
@@ -53,65 +54,6 @@ void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 }
 EXPORT_SYMBOL_GPL(rtl8723_enable_fw_download);
 
-void rtl8723_fw_block_write(struct ieee80211_hw *hw,
-			    const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u32 blocksize = sizeof(u32);
-	u8 *bufferptr = (u8 *)buffer;
-	u32 *pu4byteptr = (u32 *)buffer;
-	u32 i, offset, blockcount, remainsize;
-
-	blockcount = size / blocksize;
-	remainsize = size % blocksize;
-
-	for (i = 0; i < blockcount; i++) {
-		offset = i * blocksize;
-		rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-				*(pu4byteptr + i));
-	}
-	if (remainsize) {
-		offset = blockcount * blocksize;
-		bufferptr += offset;
-		for (i = 0; i < remainsize; i++) {
-			rtl_write_byte(rtlpriv,
-				       (FW_8192C_START_ADDRESS + offset + i),
-				       *(bufferptr + i));
-		}
-	}
-}
-EXPORT_SYMBOL_GPL(rtl8723_fw_block_write);
-
-void rtl8723_fw_page_write(struct ieee80211_hw *hw,
-			   u32 page, const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u8 value8;
-	u8 u8page = (u8) (page & 0x07);
-
-	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-	rtl8723_fw_block_write(hw, buffer, size);
-}
-EXPORT_SYMBOL_GPL(rtl8723_fw_page_write);
-
-void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-	u32 fwlen = *pfwlen;
-	u8 remain = (u8) (fwlen % 4);
-
-	remain = (remain == 0) ? 0 : (4 - remain);
-
-	while (remain > 0) {
-		pfwbuf[fwlen] = 0;
-		fwlen++;
-		remain--;
-	}
-	*pfwlen = fwlen;
-}
-EXPORT_SYMBOL(rtl8723_fill_dummy);
-
 void rtl8723_write_fw(struct ieee80211_hw *hw,
 		      enum version_8723e version,
 		      u8 *buffer, u32 size, u8 max_page)
@@ -123,7 +65,7 @@ void rtl8723_write_fw(struct ieee80211_hw *hw,
 
 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
 
-	rtl8723_fill_dummy(bufferptr, &size);
+	rtl_fill_dummy(bufferptr, &size);
 
 	page_nums = size / FW_8192C_PAGE_SIZE;
 	remain_size = size % FW_8192C_PAGE_SIZE;
@@ -134,15 +76,14 @@ void rtl8723_write_fw(struct ieee80211_hw *hw,
 	}
 	for (page = 0; page < page_nums; page++) {
 		offset = page * FW_8192C_PAGE_SIZE;
-		rtl8723_fw_page_write(hw, page, (bufferptr + offset),
-				      FW_8192C_PAGE_SIZE);
+		rtl_fw_page_write(hw, page, (bufferptr + offset),
+				  FW_8192C_PAGE_SIZE);
 	}
 
 	if (remain_size) {
 		offset = page_nums * FW_8192C_PAGE_SIZE;
 		page = page_nums;
-		rtl8723_fw_page_write(hw, page, (bufferptr + offset),
-				      remain_size);
+		rtl_fw_page_write(hw, page, (bufferptr + offset), remain_size);
 	}
 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n");
 }
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h
index 8ea372d..77c25a9 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h
@@ -28,7 +28,6 @@
 
 #define REG_SYS_FUNC_EN				0x0002
 #define REG_MCUFWDL				0x0080
-#define FW_8192C_START_ADDRESS			0x1000
 #define FW_8192C_PAGE_SIZE			4096
 #define FW_8723A_POLLING_TIMEOUT_COUNT		1000
 #define FW_8723B_POLLING_TIMEOUT_COUNT		6000
@@ -84,10 +83,6 @@ enum rtl8723be_cmd {
 void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
 void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw);
 void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable);
-void rtl8723_fw_block_write(struct ieee80211_hw *hw,
-			    const u8 *buffer, u32 size);
-void rtl8723_fw_page_write(struct ieee80211_hw *hw,
-			   u32 page, const u8 *buffer, u32 size);
 void rtl8723_write_fw(struct ieee80211_hw *hw,
 		      enum version_8723e version,
 		      u8 *buffer, u32 size, u8 max_page);
@@ -95,6 +90,5 @@ int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be, int count);
 int rtl8723_download_fw(struct ieee80211_hw *hw, bool is_8723be, int count);
 bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw,
 			     struct sk_buff *skb);
-void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen);
 
 #endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
index 94e97dc..328c64d 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -51,63 +52,6 @@ static void _rtl8821ae_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 	}
 }
 
-static void _rtl8821ae_fw_block_write(struct ieee80211_hw *hw,
-				      const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u32 blocksize = sizeof(u32);
-	u8 *bufferptr = (u8 *)buffer;
-	u32 *pu4byteptr = (u32 *)buffer;
-	u32 i, offset, blockcount, remainsize;
-
-	blockcount = size / blocksize;
-	remainsize = size % blocksize;
-
-	for (i = 0; i < blockcount; i++) {
-		offset = i * blocksize;
-		rtl_write_dword(rtlpriv, (FW_8821AE_START_ADDRESS + offset),
-				*(pu4byteptr + i));
-	}
-
-	if (remainsize) {
-		offset = blockcount * blocksize;
-		bufferptr += offset;
-		for (i = 0; i < remainsize; i++) {
-			rtl_write_byte(rtlpriv, (FW_8821AE_START_ADDRESS +
-					offset + i), *(bufferptr + i));
-		}
-	}
-}
-
-static void _rtl8821ae_fw_page_write(struct ieee80211_hw *hw,
-				     u32 page, const u8 *buffer, u32 size)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u8 value8;
-	u8 u8page = (u8)(page & 0x07);
-
-	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-	_rtl8821ae_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl8821ae_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-	u32 fwlen = *pfwlen;
-	u8 remain = (u8)(fwlen % 4);
-
-	remain = (remain == 0) ? 0 : (4 - remain);
-
-	while (remain > 0) {
-		pfwbuf[fwlen] = 0;
-		fwlen++;
-		remain--;
-	}
-
-	*pfwlen = fwlen;
-}
-
 static void _rtl8821ae_write_fw(struct ieee80211_hw *hw,
 				enum version_8821ae version,
 				u8 *buffer, u32 size)
@@ -119,7 +63,7 @@ static void _rtl8821ae_write_fw(struct ieee80211_hw *hw,
 
 	RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
 
-	_rtl8821ae_fill_dummy(bufferptr, &size);
+	rtl_fill_dummy(bufferptr, &size);
 
 	pagenums = size / FW_8821AE_PAGE_SIZE;
 	remainsize = size % FW_8821AE_PAGE_SIZE;
@@ -129,15 +73,14 @@ static void _rtl8821ae_write_fw(struct ieee80211_hw *hw,
 
 	for (page = 0; page < pagenums; page++) {
 		offset = page * FW_8821AE_PAGE_SIZE;
-		_rtl8821ae_fw_page_write(hw, page, (bufferptr + offset),
-					 FW_8821AE_PAGE_SIZE);
+		rtl_fw_page_write(hw, page, (bufferptr + offset),
+				  FW_8821AE_PAGE_SIZE);
 	}
 
 	if (remainsize) {
 		offset = pagenums * FW_8821AE_PAGE_SIZE;
 		page = pagenums;
-		_rtl8821ae_fw_page_write(hw, page, (bufferptr + offset),
-					 remainsize);
+		rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
 	}
 }
 
-- 
2.10.2

^ permalink raw reply related

* [PATCH v2 3/3] rtlwifi: rtl8192cu: Convert driver to use common macros
From: Larry Finger @ 2017-01-19 20:28 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih
In-Reply-To: <20170119202808.27752-1-Larry.Finger@lwfinger.net>

These drivers use a set of complicated macros to extract and insert
information for the RX and TX descriptors. Driver rtl8192cu had a
different set than was used for the PCI-based drivers. To simplify
the code, rtl8192cu is switched to use the common version. In the
process, two errors in those common macros were found and fixed.

Besides simplifying the code, there is an additional benefit. We have
no BE hardware to test the PCI driver, but using the common macros
provides an additional test for the validity of many endian-sensitive
operations.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>
---
V2 - No functional changes. Merge conflict resolved.
---
 .../net/wireless/realtek/rtlwifi/rtl8192cu/trx.h   | 272 ++++++++++-----------
 drivers/net/wireless/realtek/rtlwifi/wifi.h        |  23 +-
 2 files changed, 132 insertions(+), 163 deletions(-)

Index: wireless-drivers-next/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h
===================================================================
--- wireless-drivers-next.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h
+++ wireless-drivers-next/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h
@@ -92,129 +92,107 @@ struct rx_drv_info_92c {
 	u8 reserve:4;
 } __packed;
 
-/* Define a macro that takes a le32 word, converts it to host ordering,
- * right shifts by a specified count, creates a mask of the specified
- * bit count, and extracts that number of bits.
- */
-
-#define SHIFT_AND_MASK_LE(__pdesc, __shift, __bits)		\
-	((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) &	\
-	BIT_LEN_MASK_32(__bits))
-
-/* Define a macro that clears a bit field in an le32 word and
- * sets the specified value into that bit field. The resulting
- * value remains in le32 ordering; however, it is properly converted
- * to host ordering for the clear and set operations before conversion
- * back to le32.
- */
-
-#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val)	\
-	(*(__le32 *)(__pdesc) = 				\
-	(cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) &	\
-	(~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) |		\
-	(((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
-
 /* macros to read various fields in RX descriptor */
 
 /* DWORD 0 */
 #define GET_RX_DESC_PKT_LEN(__rxdesc)		\
-	SHIFT_AND_MASK_LE((__rxdesc), 0, 14)
+	LE_BITS_TO_4BYTE((__rxdesc), 0, 14)
 #define GET_RX_DESC_CRC32(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 14, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 14, 1)
 #define GET_RX_DESC_ICV(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 15, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 15, 1)
 #define GET_RX_DESC_DRVINFO_SIZE(__rxdesc)	\
-	SHIFT_AND_MASK_LE(__rxdesc, 16, 4)
+	LE_BITS_TO_4BYTE(__rxdesc, 16, 4)
 #define GET_RX_DESC_SECURITY(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 20, 3)
+	LE_BITS_TO_4BYTE(__rxdesc, 20, 3)
 #define GET_RX_DESC_QOS(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 23, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 23, 1)
 #define GET_RX_DESC_SHIFT(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 24, 2)
+	LE_BITS_TO_4BYTE(__rxdesc, 24, 2)
 #define GET_RX_DESC_PHY_STATUS(__rxdesc)	\
-	SHIFT_AND_MASK_LE(__rxdesc, 26, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 26, 1)
 #define GET_RX_DESC_SWDEC(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 27, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 27, 1)
 #define GET_RX_DESC_LAST_SEG(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 28, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 28, 1)
 #define GET_RX_DESC_FIRST_SEG(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 29, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 29, 1)
 #define GET_RX_DESC_EOR(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 30, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 30, 1)
 #define GET_RX_DESC_OWN(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc, 31, 1)
+	LE_BITS_TO_4BYTE(__rxdesc, 31, 1)
 
 /* DWORD 1 */
 #define GET_RX_DESC_MACID(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 0, 5)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 0, 5)
 #define GET_RX_DESC_TID(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 5, 4)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 5, 4)
 #define GET_RX_DESC_PAGGR(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 14, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 14, 1)
 #define GET_RX_DESC_FAGGR(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 15, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 15, 1)
 #define GET_RX_DESC_A1_FIT(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 16, 4)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 16, 4)
 #define GET_RX_DESC_A2_FIT(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 20, 4)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 20, 4)
 #define GET_RX_DESC_PAM(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 24, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 24, 1)
 #define GET_RX_DESC_PWR(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 25, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 25, 1)
 #define GET_RX_DESC_MORE_DATA(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 26, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 26, 1)
 #define GET_RX_DESC_MORE_FRAG(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 27, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 27, 1)
 #define GET_RX_DESC_TYPE(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 28, 2)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 28, 2)
 #define GET_RX_DESC_MC(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 30, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 30, 1)
 #define GET_RX_DESC_BC(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+4, 31, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 4, 31, 1)
 
 /* DWORD 2 */
 #define GET_RX_DESC_SEQ(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+8, 0, 12)
+	LE_BITS_TO_4BYTE(__rxdesc + 8, 0, 12)
 #define GET_RX_DESC_FRAG(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+8, 12, 4)
+	LE_BITS_TO_4BYTE(__rxdesc + 8, 12, 4)
 #define GET_RX_DESC_USB_AGG_PKTNUM(__rxdesc)	\
-	SHIFT_AND_MASK_LE(__rxdesc+8, 16, 8)
+	LE_BITS_TO_4BYTE(__rxdesc + 8, 16, 8)
 #define GET_RX_DESC_NEXT_IND(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+8, 30, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 8, 30, 1)
 
 /* DWORD 3 */
 #define GET_RX_DESC_RX_MCS(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 0, 6)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 0, 6)
 #define GET_RX_DESC_RX_HT(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 6, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 6, 1)
 #define GET_RX_DESC_AMSDU(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 7, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 7, 1)
 #define GET_RX_DESC_SPLCP(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 8, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 8, 1)
 #define GET_RX_DESC_BW(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 9, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 9, 1)
 #define GET_RX_DESC_HTC(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 10, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 10, 1)
 #define GET_RX_DESC_TCP_CHK_RPT(__rxdesc)	\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 11, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 11, 1)
 #define GET_RX_DESC_IP_CHK_RPT(__rxdesc)	\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 12, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 12, 1)
 #define GET_RX_DESC_TCP_CHK_VALID(__rxdesc)	\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 13, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 13, 1)
 #define GET_RX_DESC_HWPC_ERR(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 14, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 14, 1)
 #define GET_RX_DESC_HWPC_IND(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 15, 1)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 15, 1)
 #define GET_RX_DESC_IV0(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+12, 16, 16)
+	LE_BITS_TO_4BYTE(__rxdesc + 12, 16, 16)
 
 /* DWORD 4 */
 #define GET_RX_DESC_IV1(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+16, 0, 32)
+	LE_BITS_TO_4BYTE(__rxdesc + 16, 0, 32)
 
 /* DWORD 5 */
 #define GET_RX_DESC_TSFL(__rxdesc)		\
-	SHIFT_AND_MASK_LE(__rxdesc+20, 0, 32)
+	LE_BITS_TO_4BYTE(__rxdesc + 20, 0, 32)
 
 /*======================= tx desc ============================================*/
 
@@ -222,182 +200,182 @@ struct rx_drv_info_92c {
 
 /* Dword 0 */
 #define SET_TX_DESC_PKT_SIZE(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 0, 16, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 0, 16, __value)
 #define SET_TX_DESC_OFFSET(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 16, 8, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 16, 8, __value)
 #define SET_TX_DESC_BMC(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 24, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 24, 1, __value)
 #define SET_TX_DESC_HTC(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 25, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 25, 1, __value)
 #define SET_TX_DESC_LAST_SEG(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 26, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 26, 1, __value)
 #define SET_TX_DESC_FIRST_SEG(__txdesc, __value)	\
-	 SET_BITS_OFFSET_LE(__txdesc, 27, 1, __value)
+	 SET_BITS_TO_LE_4BYTE(__txdesc, 27, 1, __value)
 #define SET_TX_DESC_LINIP(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 28, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 28, 1, __value)
 #define SET_TX_DESC_NO_ACM(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 29, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 29, 1, __value)
 #define SET_TX_DESC_GF(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 30, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 30, 1, __value)
 #define SET_TX_DESC_OWN(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc, 31, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc, 31, 1, __value)
 
 
 /* Dword 1 */
 #define SET_TX_DESC_MACID(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+4, 0, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 0, 5, __value)
 #define SET_TX_DESC_AGG_ENABLE(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 5, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 5, 1, __value)
 #define SET_TX_DESC_AGG_BREAK(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 6, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 6, 1, __value)
 #define SET_TX_DESC_RDG_ENABLE(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 7, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 7, 1, __value)
 #define SET_TX_DESC_QUEUE_SEL(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 8, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 8, 5, __value)
 #define SET_TX_DESC_RDG_NAV_EXT(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 13, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 13, 1, __value)
 #define SET_TX_DESC_LSIG_TXOP_EN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 14, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 14, 1, __value)
 #define SET_TX_DESC_PIFS(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+4, 15, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 15, 1, __value)
 #define SET_TX_DESC_RATE_ID(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 16, 4, __value)
 #define SET_TX_DESC_RA_BRSR_ID(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 16, 4, __value)
 #define SET_TX_DESC_NAV_USE_HDR(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 20, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 20, 1, __value)
 #define SET_TX_DESC_EN_DESC_ID(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 21, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 21, 1, __value)
 #define SET_TX_DESC_SEC_TYPE(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+4, 22, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 22, 2, __value)
 #define SET_TX_DESC_PKT_OFFSET(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+4, 26, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 4, 26, 5, __value)
 
 /* Dword 2 */
 #define SET_TX_DESC_RTS_RC(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+8, 0, 6, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 0, 6, __value)
 #define SET_TX_DESC_DATA_RC(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+8, 6, 6, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 6, 6, __value)
 #define SET_TX_DESC_BAR_RTY_TH(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+8, 14, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 14, 2, __value)
 #define SET_TX_DESC_MORE_FRAG(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+8, 17, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 17, 1, __value)
 #define SET_TX_DESC_RAW(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+8, 18, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 18, 1, __value)
 #define SET_TX_DESC_CCX(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+8, 19, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 19, 1, __value)
 #define SET_TX_DESC_AMPDU_DENSITY(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+8, 20, 3, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 20, 3, __value)
 #define SET_TX_DESC_ANTSEL_A(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+8, 24, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 24, 1, __value)
 #define SET_TX_DESC_ANTSEL_B(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+8, 25, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 25, 1, __value)
 #define SET_TX_DESC_TX_ANT_CCK(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+8, 26, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 26, 2, __value)
 #define SET_TX_DESC_TX_ANTL(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+8, 28, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 28, 2, __value)
 #define SET_TX_DESC_TX_ANT_HT(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+8, 30, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 8, 30, 2, __value)
 
 /* Dword 3 */
 #define SET_TX_DESC_NEXT_HEAP_PAGE(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+12, 0, 8, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 12, 0, 8, __value)
 #define SET_TX_DESC_TAIL_PAGE(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+12, 8, 8, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 12, 8, 8, __value)
 #define SET_TX_DESC_SEQ(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+12, 16, 12, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 12, 16, 12, __value)
 #define SET_TX_DESC_PKT_ID(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+12, 28, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 12, 28, 4, __value)
 
 /* Dword 4 */
 #define SET_TX_DESC_RTS_RATE(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 0, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 0, 5, __value)
 #define SET_TX_DESC_AP_DCFE(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 5, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 5, 1, __value)
 #define SET_TX_DESC_QOS(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 6, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 6, 1, __value)
 #define SET_TX_DESC_HWSEQ_EN(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 7, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 7, 1, __value)
 #define SET_TX_DESC_USE_RATE(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 8, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 8, 1, __value)
 #define SET_TX_DESC_DISABLE_RTS_FB(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 9, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 9, 1, __value)
 #define SET_TX_DESC_DISABLE_FB(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 10, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 10, 1, __value)
 #define SET_TX_DESC_CTS2SELF(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 11, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 11, 1, __value)
 #define SET_TX_DESC_RTS_ENABLE(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 12, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 12, 1, __value)
 #define SET_TX_DESC_HW_RTS_ENABLE(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 13, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 13, 1, __value)
 #define SET_TX_DESC_WAIT_DCTS(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 18, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 18, 1, __value)
 #define SET_TX_DESC_CTS2AP_EN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 19, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 19, 1, __value)
 #define SET_TX_DESC_DATA_SC(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 20, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 20, 2, __value)
 #define SET_TX_DESC_DATA_STBC(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 22, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 22, 2, __value)
 #define SET_TX_DESC_DATA_SHORT(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 24, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 24, 1, __value)
 #define SET_TX_DESC_DATA_BW(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 25, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 25, 1, __value)
 #define SET_TX_DESC_RTS_SHORT(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+16, 26, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 26, 1, __value)
 #define SET_TX_DESC_RTS_BW(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 27, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 27, 1, __value)
 #define SET_TX_DESC_RTS_SC(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 28, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 28, 2, __value)
 #define SET_TX_DESC_RTS_STBC(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+16, 30, 2, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 16, 30, 2, __value)
 
 /* Dword 5 */
 #define SET_TX_DESC_TX_RATE(__pdesc, __val)		\
-	SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
+	SET_BITS_TO_LE_4BYTE(__pdesc + 20, 0, 6, __val)
 #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val)	\
-	SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
+	SET_BITS_TO_LE_4BYTE(__pdesc + 20, 6, 1, __val)
 #define SET_TX_DESC_CCX_TAG(__pdesc, __val)		\
-	SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
+	SET_BITS_TO_LE_4BYTE(__pdesc + 20, 7, 1, __val)
 #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__txdesc, __value) \
-	SET_BITS_OFFSET_LE(__txdesc+20, 8, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 20, 8, 5, __value)
 #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__txdesc, __value) \
-	SET_BITS_OFFSET_LE(__txdesc+20, 13, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 20, 13, 4, __value)
 #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__txdesc, __value) \
-	SET_BITS_OFFSET_LE(__txdesc+20, 17, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 20, 17, 1, __value)
 #define SET_TX_DESC_DATA_RETRY_LIMIT(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+20, 18, 6, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 20, 18, 6, __value)
 #define SET_TX_DESC_USB_TXAGG_NUM(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+20, 24, 8, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 20, 24, 8, __value)
 
 /* Dword 6 */
 #define SET_TX_DESC_TXAGC_A(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+24, 0, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 0, 5, __value)
 #define SET_TX_DESC_TXAGC_B(__txdesc, __value)		\
-	SET_BITS_OFFSET_LE(__txdesc+24, 5, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 5, 5, __value)
 #define SET_TX_DESC_USB_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+24, 10, 1, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 10, 1, __value)
 #define SET_TX_DESC_MAX_AGG_NUM(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+24, 11, 5, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 11, 5, __value)
 #define SET_TX_DESC_MCSG1_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+24, 16, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 16, 4, __value)
 #define SET_TX_DESC_MCSG2_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+24, 20, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 20, 4, __value)
 #define SET_TX_DESC_MCSG3_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+24, 24, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 24, 4, __value)
 #define SET_TX_DESC_MCSG7_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+24, 28, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 24, 28, 4, __value)
 
 /* Dword 7 */
 #define SET_TX_DESC_TX_DESC_CHECKSUM(__txdesc, __value) \
-	SET_BITS_OFFSET_LE(__txdesc+28, 0, 16, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 28, 0, 16, __value)
 #define SET_TX_DESC_MCSG4_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+28, 16, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 28, 16, 4, __value)
 #define SET_TX_DESC_MCSG5_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+28, 20, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 28, 20, 4, __value)
 #define SET_TX_DESC_MCSG6_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+28, 24, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 28, 24, 4, __value)
 #define SET_TX_DESC_MCSG15_MAX_LEN(__txdesc, __value)	\
-	SET_BITS_OFFSET_LE(__txdesc+28, 28, 4, __value)
+	SET_BITS_TO_LE_4BYTE(__txdesc + 28, 28, 4, __value)
 
 
 int  rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw);
Index: wireless-drivers-next/drivers/net/wireless/realtek/rtlwifi/wifi.h
===================================================================
--- wireless-drivers-next.orig/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ wireless-drivers-next/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2704,23 +2704,14 @@ enum bt_radio_shared {
 	(le32_to_cpu(_val))
 
 /* Read data from memory */
-#define READEF1BYTE(_ptr)	\
+#define READEF1BYTE(_ptr)      \
 	EF1BYTE(*((u8 *)(_ptr)))
 /* Read le16 data from memory and convert to host ordering */
-#define READEF2BYTE(_ptr)	\
+#define READEF2BYTE(_ptr)      \
 	EF2BYTE(*(_ptr))
-#define READEF4BYTE(_ptr)	\
+#define READEF4BYTE(_ptr)      \
 	EF4BYTE(*(_ptr))
 
-/* Write data to memory */
-#define WRITEEF1BYTE(_ptr, _val)	\
-	(*((u8 *)(_ptr))) = EF1BYTE(_val)
-/* Write le16 data to memory in host ordering */
-#define WRITEEF2BYTE(_ptr, _val)	\
-	(*((u16 *)(_ptr))) = EF2BYTE(_val)
-#define WRITEEF4BYTE(_ptr, _val)	\
-	(*((u32 *)(_ptr))) = EF2BYTE(_val)
-
 /* Create a bit mask
  * Examples:
  * BIT_LEN_MASK_32(0) => 0x00000000
@@ -2801,14 +2792,14 @@ value to host byte ordering.*/
  * Set subfield of little-endian 4-byte value to specified value.
  */
 #define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
-	*((u32 *)(__pstart)) = \
-	( \
+	*((__le32 *)(__pstart)) = \
+	cpu_to_le32( \
 		LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
 		((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \
 	);
 #define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
-	*((u16 *)(__pstart)) = \
-	( \
+	*((__le16 *)(__pstart)) = \
+	cpu_to_le16( \
 		LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
 		((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \
 	);

^ permalink raw reply

* [PATCH 0/3 v2] rtlwifi: Patches for proper operation on big-endian hardware
From: Larry Finger @ 2017-01-19 20:28 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih

Although these drivers do not have any Sparse messages indication
problems with endian operations, there are two places where the
information being processed is little endian, but was being processed
in cpu order. The first of these is in downloading firmware. Rather
than do a double conversion for BE hosts, I converted the firmware
download routines to send bytes rather than 32-bit quantities. The
number of I/O operations in increased, but firmware download is usually
done only once.

A second problem is that the USB driver requires that the descriptors
be checksummed before transmission to the device so that critical info
such as DMA addresses are not garbled in transmission. The original
code was calculating the checksum in cpu order.

There is also a third change that causes the USB driver rtl8192cu to use
the same set of macros to read and write the descriptors. This change was
no necessary; however, it simplifies the code, and did identify an endian
problem in the macros. Using identical macros for PCI- and USB-based
hardware increases the likelihood that the PCI devices will work with BE
hardware. At the moment, we do not have such hardware for testing.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>

V2 - No functional changes. Merge conflict resolved.

Larry Finger (3):
  rtlwifi: Download firmware as bytes rather than as dwords
  rtlwifi: rtl8192cu: Calculate descriptor checksum correctly for BE
  rtlwifi: rtl8192cu: Convert driver to use common macros

 drivers/net/wireless/realtek/rtlwifi/efuse.c       |  45 ++++
 drivers/net/wireless/realtek/rtlwifi/efuse.h       |   4 +
 .../net/wireless/realtek/rtlwifi/rtl8188ee/fw.c    |  67 +----
 .../wireless/realtek/rtlwifi/rtl8192c/fw_common.c  |  70 +-----
 .../net/wireless/realtek/rtlwifi/rtl8192cu/trx.c   |   4 +-
 .../net/wireless/realtek/rtlwifi/rtl8192cu/trx.h   | 272 ++++++++++-----------
 .../net/wireless/realtek/rtlwifi/rtl8192de/fw.c    |  70 +-----
 .../net/wireless/realtek/rtlwifi/rtl8192ee/fw.c    |  68 +-----
 .../realtek/rtlwifi/rtl8723com/fw_common.c         |  69 +-----
 .../realtek/rtlwifi/rtl8723com/fw_common.h         |   6 -
 .../net/wireless/realtek/rtlwifi/rtl8821ae/fw.c    |  67 +----
 drivers/net/wireless/realtek/rtlwifi/wifi.h        |  23 +-
 12 files changed, 219 insertions(+), 546 deletions(-)

-- 
2.10.2

^ permalink raw reply

* [PATCH v2 2/3] rtlwifi: rtl8192cu: Calculate descriptor checksum correctly for BE
From: Larry Finger @ 2017-01-19 20:28 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih
In-Reply-To: <20170119202808.27752-1-Larry.Finger@lwfinger.net>

This driver requires a checksum for the descriptors so that the wifi
chip is assured that the USB transmission was correct. These entries
are little-endian, but the driver was always using cpu order in the
calculation. As a result, the driver failed on BE hardware.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>
---
V2 - No functional changes. Merge conflict resolved.
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
index 6da6e2a..1611e42 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
@@ -477,14 +477,14 @@ static void _rtl_fill_usb_tx_desc(u8 *txdesc)
  */
 static void _rtl_tx_desc_checksum(u8 *txdesc)
 {
-	u16 *ptr = (u16 *)txdesc;
+	__le16 *ptr = (__le16 *)txdesc;
 	u16	checksum = 0;
 	u32 index;
 
 	/* Clear first */
 	SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0);
 	for (index = 0; index < 16; index++)
-		checksum = checksum ^ (*(ptr + index));
+		checksum = checksum ^ le16_to_cpu(*(ptr + index));
 	SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum);
 }
 
-- 
2.10.2

^ permalink raw reply related

* Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: Ulf Hansson @ 2017-01-19 20:30 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Matt Ranostay, linux-wireless@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org,
	devicetree@vger.kernel.org, Tony Lindgren, Shawn Lin
In-Reply-To: <87efzyhkup.fsf@purkki.adurom.net>

On 19 January 2017 at 21:10, Kalle Valo <kvalo@codeaurora.org> wrote:
> Ulf Hansson <ulf.hansson@linaro.org> writes:
>
>> Twisting my head around how this could be integrated smoothly into
>> pwrseq simple. No, I just can find a good way forward without messing
>> up pwrseq simple itself.
>>
>> So, for now I decided (once more :-), that let's keep this as separate driver!
>>
>> Perhaps, following device specific mmc pwrseq drivers will needs
>> something similar, but in such case we can look into that then.
>> Thinking about cw1200 for example.
>>
>> Let's get Rob's ack for the DT bindings, seems almost there, then I
>> will queue this.
>
> Just to confirm, you will take the whole set (including the bindings
> patch)?

Yes, correct.

Kind regards
Uffe

^ permalink raw reply

* Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: Kalle Valo @ 2017-01-19 20:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Matt Ranostay, linux-wireless@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org,
	devicetree@vger.kernel.org, Tony Lindgren, Shawn Lin
In-Reply-To: <CAPDyKFpcKuybQmhqCkaAkOM5d+ubU8O8=adLm+PXwc=+N87vng@mail.gmail.com>

Ulf Hansson <ulf.hansson@linaro.org> writes:

> Twisting my head around how this could be integrated smoothly into
> pwrseq simple. No, I just can find a good way forward without messing
> up pwrseq simple itself.
>
> So, for now I decided (once more :-), that let's keep this as separate driver!
>
> Perhaps, following device specific mmc pwrseq drivers will needs
> something similar, but in such case we can look into that then.
> Thinking about cw1200 for example.
>
> Let's get Rob's ack for the DT bindings, seems almost there, then I
> will queue this.

Just to confirm, you will take the whole set (including the bindings
patch)?

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH] net: ethtool: avoid allocation failure for dump_regs
From: David Miller @ 2017-01-19 19:22 UTC (permalink / raw)
  To: kvalo; +Cc: linville, darcari, netdev, johannes.berg, linux-wireless
In-Reply-To: <87h94uorc1.fsf@kamboji.qca.qualcomm.com>

From: Kalle Valo <kvalo@codeaurora.org>
Date: Thu, 19 Jan 2017 20:08:30 +0200

> "John W. Linville" <linville@tuxdriver.com> writes:
> 
>> I forgot to Cc Johannes and Kalle...
> 
> Also adding linux-wireless.
> 
>> On Thu, Jan 19, 2017 at 09:15:09AM -0500, John W. Linville wrote:
>>> On Thu, Jan 19, 2017 at 07:35:22AM -0500, David Arcari wrote:
>>> > On 01/18/2017 11:45 AM, David Miller wrote:
>>> > > From: David Arcari <darcari@redhat.com>
>>> > > Date: Wed, 18 Jan 2017 08:34:05 -0500
>>> > >
>>> > >> If the user executes 'ethtool -d' for an interface and the associated
>>> > >> get_regs_len() function returns 0, the user will see a call trace from
>>> > >> the vmalloc() call in ethtool_get_regs().  This patch modifies
>>> > >> ethtool_get_regs() to avoid the call to vmalloc when the size is zero.
>>> > >>
>>> > >> Signed-off-by: David Arcari <darcari@redhat.com>
>>> > > I think when the driver indicates this, it is equivalent to saying that
>>> > > the operation isn't supported.
>>> > >
>>> > > Also, this guards us against ->get_regs() methods that don't handle
>>> > > zero length requests properly.  I see many which are going to do
>>> > > really terrible things in that situation.
>>> > >
>>> > > Therefore, if get_regs_len() returns zero, treat it the safe as if the
>>> > > ethtool operations were NULL.
>>> > >
>>> > > Thanks.
>>> > 
>>> > That was actually the fix that I was originally considering, but it
>>> > turns out
>>> > there is a problem with it.
>>> > 
>>> > I found that the vmalloc error was occurring because
>>> > ieee80211_get_regs_len() in
>>> > net/mac80211/ethtool.c was returning zero.  The ieee80211_get_regs in
>>> > the same
>>> > file returns the hw version. It turns out that this information is used
>>> > by the
>>> > at76c50x-usb driver in the user space ethtool to report which HW variant
>>> > is in
>>> > use.  Returning an error when regs_len() returns zero would break this
>>> > functionality.
>>> > 
>>> > -Dave
>>> 
>>> I'm responsible for this mess. The original idea was for various
>>> mac80211-based drivers to override the ethtool operation and provide
>>> their own dump operation, but the mac80211 crowd never embraced
>>> the idea.
>>> 
>>> In the meantime, I added the default implementation which just
>>> passed-up wdev->wiphy->hw_version as the version info for a 0-length
>>> register dump. I then implemented a driver-specific regiser dump
>>> handler for userland ethtool that would interpret the hardware version
>>> information for the at76c50x-usb driver.
>>> 
>>> So the net of it is, if we treat a return of 0 from get_regs_len()
>>> as "not supported", we break this one driver-specific feature for
>>> userland ethtool. Realistically, there are probably very few users
>>> to care. But I can't guarantee that the number is zero.
> 
> I know the number is not zero, because I remember using it years back
> with something else than at76c50x-usb. But is the number more than one,
> I don't know :)

I'm trying to dig down and figure out why this problem is showing up now.
ethtool_get_regs() has been using vzalloc() since 2011, and before that it
used plain vmalloc().

This code has therefore been using v{m,z}alloc() forever.  What changed?

The zero size check has been in the vmalloc implementation since at least
2009.

I don't understand why this is all triggering and being noticed now.  The
whole ieee80211 "return zero length regs and return hw version in get_regs"
thing should have been failing for at least 7 years now.

^ permalink raw reply

* Re: [PATCH net-next v4] bridge: multicast to unicast
From: Stephen Hemminger @ 2017-01-19 19:05 UTC (permalink / raw)
  To: Linus Lüssing
  Cc: netdev, David S . Miller, Felix Fietkau, Nikolay Aleksandrov,
	bridge, linux-kernel, linux-wireless
In-Reply-To: <20170119024510.3284-1-linus.luessing@c0d3.blue>

On Thu, 19 Jan 2017 03:45:10 +0100
Linus L=C3=BCssing <linus.luessing@c0d3.blue> wrote:

> From: Felix Fietkau <nbd@nbd.name>
>=20
> Implements an optional, per bridge port flag and feature to deliver
> multicast packets to any host on the according port via unicast
> individually. This is done by copying the packet per host and
> changing the multicast destination MAC to a unicast one accordingly.
>=20
> multicast-to-unicast works on top of the multicast snooping feature of
> the bridge. Which means unicast copies are only delivered to hosts which
> are interested in it and signalized this via IGMP/MLD reports
> previously.
>=20
> This feature is intended for interface types which have a more reliable
> and/or efficient way to deliver unicast packets than broadcast ones
> (e.g. wifi).
>=20
> However, it should only be enabled on interfaces where no IGMPv2/MLDv1
> report suppression takes place. This feature is disabled by default.
>=20
> The initial patch and idea is from Felix Fietkau.
>=20
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
> [linus.luessing@c0d3.blue: various bug + style fixes, commit message]
> Signed-off-by: Linus L=C3=BCssing <linus.luessing@c0d3.blue>
>=20

In general this looks good.

One issue I see is how existing entries are handled when the bridge port fl=
ags
are changed dynamically. It might be better to always record the necessary =
data
in the bridge_port_group and not have a per-entry flag bit. In your current
patch the API changes the response to future IGMP but does not take instant
effect. Code would be simpler if there was less logic to handle per-entry f=
lags.

Also, you might want to add sysfs interface for the attribute as well.

^ permalink raw reply

* Re: [PATCH v3] rt2x00: add support for RT5350 WiSoC
From: Kalle Valo @ 2017-01-19 19:08 UTC (permalink / raw)
  To: Daniel Golle
  Cc: linux-wireless, Johannes Berg, Stanislaw Gruszka, roman,
	michel.stempin, c.mignanti, evaxige, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <20170119133834.GA17398@makrotopia.org>

Daniel Golle <daniel@makrotopia.org> writes:

> From: Michel Stempin <michel.stempin@wanadoo.fr>
>
> Support for the RT5350 WiSoC was added to OpenWrt after having a
> lengthy debate about the legality of the original submission, see
> https://lists.openwrt.org/pipermail/openwrt-devel/2013-January/018224.html
> MTK/Ralink Acked replied and says we can merge this patch under the GPL.
> https://dev.openwrt.org/changeset/36177
>
> Signed-off-by: Serge Vasilugin <vasilugin@yandex.ru>
> Tested-by: Michel Stempin <michel.stempin@wanadoo.fr>
> Acked-by: John Crispin <blogic@openwrt.org>
> [daniel@makrotopia.org: added commit message, cleaned up code]
>
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
> v2: reordered patches to breakout RT3883 from the original series
> v3: remove superflus EEPROM_NIC_CONF0 mangeling from RT5350 patch

As this is not part of the patch series I assume this patch doesn't have
any dependencies and can be applied separately (if Stanislaw acks it).

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH] net: ethtool: avoid allocation failure for dump_regs
From: Kalle Valo @ 2017-01-19 18:08 UTC (permalink / raw)
  To: John W. Linville
  Cc: David Arcari, David Miller, netdev, Johannes Berg, linux-wireless
In-Reply-To: <20170119155620.GD6245@tuxdriver.com>

"John W. Linville" <linville@tuxdriver.com> writes:

> I forgot to Cc Johannes and Kalle...

Also adding linux-wireless.

> On Thu, Jan 19, 2017 at 09:15:09AM -0500, John W. Linville wrote:
>> On Thu, Jan 19, 2017 at 07:35:22AM -0500, David Arcari wrote:
>> > On 01/18/2017 11:45 AM, David Miller wrote:
>> > > From: David Arcari <darcari@redhat.com>
>> > > Date: Wed, 18 Jan 2017 08:34:05 -0500
>> > >
>> > >> If the user executes 'ethtool -d' for an interface and the associated
>> > >> get_regs_len() function returns 0, the user will see a call trace from
>> > >> the vmalloc() call in ethtool_get_regs().  This patch modifies
>> > >> ethtool_get_regs() to avoid the call to vmalloc when the size is zero.
>> > >>
>> > >> Signed-off-by: David Arcari <darcari@redhat.com>
>> > > I think when the driver indicates this, it is equivalent to saying that
>> > > the operation isn't supported.
>> > >
>> > > Also, this guards us against ->get_regs() methods that don't handle
>> > > zero length requests properly.  I see many which are going to do
>> > > really terrible things in that situation.
>> > >
>> > > Therefore, if get_regs_len() returns zero, treat it the safe as if the
>> > > ethtool operations were NULL.
>> > >
>> > > Thanks.
>> > 
>> > That was actually the fix that I was originally considering, but it
>> > turns out
>> > there is a problem with it.
>> > 
>> > I found that the vmalloc error was occurring because
>> > ieee80211_get_regs_len() in
>> > net/mac80211/ethtool.c was returning zero.  The ieee80211_get_regs in
>> > the same
>> > file returns the hw version. It turns out that this information is used
>> > by the
>> > at76c50x-usb driver in the user space ethtool to report which HW variant
>> > is in
>> > use.  Returning an error when regs_len() returns zero would break this
>> > functionality.
>> > 
>> > -Dave
>> 
>> I'm responsible for this mess. The original idea was for various
>> mac80211-based drivers to override the ethtool operation and provide
>> their own dump operation, but the mac80211 crowd never embraced
>> the idea.
>> 
>> In the meantime, I added the default implementation which just
>> passed-up wdev->wiphy->hw_version as the version info for a 0-length
>> register dump. I then implemented a driver-specific regiser dump
>> handler for userland ethtool that would interpret the hardware version
>> information for the at76c50x-usb driver.
>> 
>> So the net of it is, if we treat a return of 0 from get_regs_len()
>> as "not supported", we break this one driver-specific feature for
>> userland ethtool. Realistically, there are probably very few users
>> to care. But I can't guarantee that the number is zero.

I know the number is not zero, because I remember using it years back
with something else than at76c50x-usb. But is the number more than one,
I don't know :)

>> Possible solutions:
>> 
>> 	-- break userland ethtool for at76c50x-usb
>> 	-- avoid 0-len allocation attempt (David Arcari's patch)
>> 	-- make allocator accept a 0 length value w/o oops'ing
>> 	-- change mac8011 code to return non-zero from get_regs_len()
>> 
>> Thoughts? The last option holds a certain attraction, but I'm not
>> sure how to make it useful...?

If it were only about at76c50x-usb I would say go for it, nobody sane
should use that device anymore. But on the other hand I'm worried that
this interface might be used by other (proprietary) user space tools
with other, more important, drivers. A difficult situation.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH] rtlwifi: rtl8192x: Enabling and disabling hardware interrupts after enabling local irq flags
From: Larry Finger @ 2017-01-19 18:08 UTC (permalink / raw)
  To: Lino Sanfilippo, Bharat Kumar Gogada
  Cc: chaoming_li, linux-wireless, linux-kernel, kvalo, netdev, rgummal,
	Bharat Kumar Gogada
In-Reply-To: <trinity-12e38a0e-85af-457b-9d4e-3c40ab1f6fd1-1484836538110@3capp-gmx-bs75>

On 01/19/2017 08:35 AM, Lino Sanfilippo wrote:
> Hi,
>
> altek/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
>> index a47be73..143766c4 100644
>> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
>> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
>> @@ -1306,9 +1306,9 @@ void rtl92ce_enable_interrupt(struct ieee80211_hw *hw)
>>  	struct rtl_priv *rtlpriv = rtl_priv(hw);
>>  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
>>
>> +	rtlpci->irq_enabled = true;
>>  	rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
>>  	rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
>> -	rtlpci->irq_enabled = true;
>>  }
>>
>>  void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
>> @@ -1316,9 +1316,9 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
>>  	struct rtl_priv *rtlpriv = rtl_priv(hw);
>>  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
>>
>> +	rtlpci->irq_enabled = false;
>>  	rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
>>  	rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
>> -	rtlpci->irq_enabled = false;
>>  }
>>
>
> AFAIK you also have to use memory barriers here to ensure that
> the concerning instructions are not reordered, and both irq handler
> and process have a consistent perception of irq_enabled, e.g:
>
> rtlpci->irq_enabled = true;
> smp_wmb();
> rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
>
> and in the irq handler
>
> if (rtlpci->irq_enabled == 0) {
>         smp_rmb();
> 	return ret;
> }

I can see the potential race condition between setting interrupts and setting 
the flag, and I will likely accept Bharat's patch after testing.

I am likely displaying my ignorance regarding instruction reordering, but what 
compiler/cpu combination is likely to move a simple set operation after a call 
to an external routine? Is the smp_wmb() operation really needed? I am also 
unsure of the smp_rmb() call in the interrupt handler. Neither instruction 
should cause any problems, but I'm not sure they are needed.

Larry

^ permalink raw reply

* [PATCH v2 1/3] rtlwifi: Redo debugging macros RTPRINT and RT_PRINT_DATA
From: Larry Finger @ 2017-01-19 17:25 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih
In-Reply-To: <20170119172521.32643-1-Larry.Finger@lwfinger.net>

These two debugging formss implement debugging using rather complicated
macro constructions. These are replaced with compiled code that is easier
to understand.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>
---
V2 - No changes.
---
 drivers/net/wireless/realtek/rtlwifi/debug.c | 42 ++++++++++++++++++++++++----
 drivers/net/wireless/realtek/rtlwifi/debug.h | 33 ++++++++++------------
 2 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c
index 33905bb..cd2efac 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.c
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.c
@@ -51,7 +51,7 @@ EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init);
 
 #ifdef CONFIG_RTLWIFI_DEBUG
 void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
-		    const char *modname, const char *fmt, ...)
+		    const char *fmt, ...)
 {
 	if (unlikely((comp & rtlpriv->dbg.global_debugcomponents) &&
 		     (level <= rtlpriv->dbg.global_debuglevel))) {
@@ -63,13 +63,45 @@ void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
 		vaf.fmt = fmt;
 		vaf.va = &args;
 
-		printk(KERN_DEBUG "%s:%ps:<%lx-%x> %pV",
-		       modname, __builtin_return_address(0),
-		       in_interrupt(), in_atomic(),
-		       &vaf);
+		pr_debug(":<%lx> %pV", in_interrupt(), &vaf);
 
 		va_end(args);
 	}
 }
 EXPORT_SYMBOL_GPL(_rtl_dbg_trace);
+
+void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
+		    const char *fmt, ...)
+{
+	if (unlikely((comp & rtlpriv->dbg.global_debugcomponents) &&
+		     (level <= rtlpriv->dbg.global_debuglevel))) {
+		struct va_format vaf;
+		va_list args;
+
+		va_start(args, fmt);
+
+		vaf.fmt = fmt;
+		vaf.va = &args;
+
+		pr_debug("%pV", &vaf);
+
+		va_end(args);
+	}
+}
+EXPORT_SYMBOL_GPL(_rtl_dbg_print);
+
+void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
+			 const char *titlestring,
+			 const void *hexdata, int hexdatalen)
+{
+	if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) &&
+		     ((level) <= rtlpriv->dbg.global_debuglevel))) {
+		pr_debug("In process \"%s\" (pid %i): %s\n",
+			 current->comm, current->pid, titlestring);
+		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
+				     hexdata, hexdatalen);
+	}
+}
+EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
+
 #endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h
index a6cc3ca..90c670b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.h
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.h
@@ -168,34 +168,29 @@ enum dbgp_flag_e {
 
 struct rtl_priv;
 
-__printf(5, 6)
+__printf(4, 5)
 void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
-		    const char *modname, const char *fmt, ...);
+		    const char *fmt, ...);
+
+__printf(4, 5)
+void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
+		    const char *fmt, ...);
+
+void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
+			 const char *titlestring,
+			 const void *hexdata, int hexdatalen);
 
 #define RT_TRACE(rtlpriv, comp, level, fmt, ...)			\
 	_rtl_dbg_trace(rtlpriv, comp, level,				\
-		       KBUILD_MODNAME, fmt, ##__VA_ARGS__)
+		       fmt, ##__VA_ARGS__)
 
 #define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...)			\
-do {									\
-	if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) {	\
-		printk(KERN_DEBUG KBUILD_MODNAME ": " fmt,		\
-		       ##__VA_ARGS__);					\
-	}								\
-} while (0)
+	_rtl_dbg_print(rtlpriv, dbgtype, dbgflag, fmt, ##__VA_ARGS__)
 
 #define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata,	\
 		      _hexdatalen)					\
-do {									\
-	if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&	\
-		     (_level <= rtlpriv->dbg.global_debuglevel))) {	\
-		printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \
-		       KBUILD_MODNAME, current->comm, current->pid,	\
-		       _titlestring);					\
-		print_hex_dump_bytes("", DUMP_PREFIX_NONE,		\
-				     _hexdata, _hexdatalen);		\
-	}								\
-} while (0)
+	_rtl_dbg_print_data(rtlpriv, _comp, _level,			\
+			    _titlestring, _hexdata, _hexdatalen)
 
 #else
 
-- 
2.10.2

^ permalink raw reply related

* [PATCH v2 3/3] rtlwifi: Remove debugging entry in sysfs
From: Larry Finger @ 2017-01-19 17:25 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih
In-Reply-To: <20170119172521.32643-1-Larry.Finger@lwfinger.net>

As the kernel provides access to module parameters through entries in
/sys/module/<driver>/parameters/, there is no need for a private
interface. Thus the existing code for setting the debug level is
removed.

Reported-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>
---
V2 - Switched the dynamic debug entries from a private sysfs entry
---
 drivers/net/wireless/realtek/rtlwifi/base.c | 59 -----------------------------
 drivers/net/wireless/realtek/rtlwifi/base.h |  1 -
 drivers/net/wireless/realtek/rtlwifi/pci.c  |  8 ----
 3 files changed, 68 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 1b23b24..01cf0a9 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -2083,65 +2083,6 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
 }
 EXPORT_SYMBOL_GPL(rtl_recognize_peer);
 
-/*********************************************************
- *
- * sysfs functions
- *
- *********************************************************/
-static ssize_t rtl_show_debug_level(struct device *d,
-				    struct device_attribute *attr, char *buf)
-{
-	struct ieee80211_hw *hw = dev_get_drvdata(d);
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-
-	return sprintf(buf, "0x%08X\n", rtlpriv->cfg->mod_params->debug_level);
-}
-
-static ssize_t rtl_store_debug_level(struct device *d,
-				     struct device_attribute *attr,
-				     const char *buf, size_t count)
-{
-	struct ieee80211_hw *hw = dev_get_drvdata(d);
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	unsigned long val;
-	int ret;
-
-	ret = kstrtoul(buf, 0, &val);
-	if (ret) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
-			 "%s is not in hex or decimal form.\n", buf);
-	} else {
-		rtlpriv->cfg->mod_params->debug_level = val;
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
-			 "debuglevel:%x\n",
-			 rtlpriv->cfg->mod_params->debug_level);
-	}
-
-	return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
-		   rtl_show_debug_level, rtl_store_debug_level);
-
-static struct attribute *rtl_sysfs_entries[] = {
-
-	&dev_attr_debug_level.attr,
-
-	NULL
-};
-
-/*
- * "name" is folder name witch will be
- * put in device directory like :
- * sys/devices/pci0000:00/0000:00:1c.4/
- * 0000:06:00.0/rtl_sysfs
- */
-struct attribute_group rtl_attribute_group = {
-	.name = "rtlsysfs",
-	.attrs = rtl_sysfs_entries,
-};
-EXPORT_SYMBOL_GPL(rtl_attribute_group);
-
 MODULE_AUTHOR("lizhaoming	<chaoming_li@realsil.com.cn>");
 MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>");
 MODULE_AUTHOR("Larry Finger	<Larry.FInger@lwfinger.net>");
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h
index 74233d6..6c770aec 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.h
+++ b/drivers/net/wireless/realtek/rtlwifi/base.h
@@ -148,7 +148,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
 u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
 void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
 u8 rtl_tid_to_ac(u8 tid);
-extern struct attribute_group rtl_attribute_group;
 void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
 extern struct rtl_global_var rtl_global_var;
 void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index f6d4dbe..b402f43 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -2289,12 +2289,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
 	}
 	rtlpriv->mac80211.mac80211_registered = 1;
 
-	err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
-	if (err) {
-		pr_err("failed to create sysfs device attributes\n");
-		goto fail3;
-	}
-
 	/*init rfkill */
 	rtl_init_rfkill(hw);	/* Init PCI sw */
 
@@ -2344,8 +2338,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
 	wait_for_completion(&rtlpriv->firmware_loading_complete);
 	clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 
-	sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
-
 	/*ieee80211_unregister_hw will call ops_stop */
 	if (rtlmac->mac80211_registered == 1) {
 		ieee80211_unregister_hw(hw);
-- 
2.10.2

^ permalink raw reply related

* [PATCH v2 0/3] rtlwifi: Rework debug system
From: Larry Finger @ 2017-01-19 17:25 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih

This set of patches modifies the debug system by replacing some
complicated macros with the equivalent operations in C. Then, the
COMP_XX component debugging is converted into a debug mask. Finally,
code that allows the dynamic setting of the debug level is removed.
All that functionality is already provided by
/sys/module/<driver>/parameters/.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>

---
V2 - Remove sysfs private interface rather than adding a new one

Larry Finger (3):
  rtlwifi: Redo debugging macros RTPRINT and RT_PRINT_DATA
  rtlwifi: Convert COMP_XX entries into a proper debugging mask
  rtlwifi: Remove debugging entry in sysfs

 drivers/net/wireless/realtek/rtlwifi/base.c        | 59 ----------------------
 drivers/net/wireless/realtek/rtlwifi/base.h        |  1 -
 drivers/net/wireless/realtek/rtlwifi/debug.c       | 55 +++++++++++++-------
 drivers/net/wireless/realtek/rtlwifi/debug.h       | 33 +++++-------
 drivers/net/wireless/realtek/rtlwifi/pci.c         |  8 ---
 .../net/wireless/realtek/rtlwifi/rtl8188ee/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8192ce/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8192cu/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8192de/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8192ee/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8192se/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8723ae/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8723be/sw.c    |  5 ++
 .../net/wireless/realtek/rtlwifi/rtl8821ae/sw.c    |  5 ++
 drivers/net/wireless/realtek/rtlwifi/wifi.h        |  4 +-
 15 files changed, 100 insertions(+), 105 deletions(-)

-- 
2.10.2

^ permalink raw reply

* [PATCH v2 2/3] rtlwifi: Convert COMP_XX entries into a proper debugging mask
From: Larry Finger @ 2017-01-19 17:25 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Larry Finger, Ping-Ke Shih
In-Reply-To: <20170119172521.32643-1-Larry.Finger@lwfinger.net>

The debugging macros contain a parameter COMP_XX that could be used as a
mask; however, the code turns all these various bits on at the same time.
This change implements them as a proper mask, and adds module parameters
to set the mask at load time.

The current name "debug" for the debug level has been changed to
"debug_level" to better differentiate it from "debug_mask".

The debug routines have also been changed to interrogate the structure
that is loaded at entry time. As a result, the structure rtl_debug is no
longer needed, and all references to it are deleted.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Ping-Ke Shih <pkshih@realtek.com>
---
V2 - renamed debug module parameter
     deleted struct rtl_debug
---
 drivers/net/wireless/realtek/rtlwifi/base.c        |  6 +--
 drivers/net/wireless/realtek/rtlwifi/debug.c       | 43 +++++-----------------
 drivers/net/wireless/realtek/rtlwifi/debug.h       |  2 -
 drivers/net/wireless/realtek/rtlwifi/pci.c         | 10 -----
 .../net/wireless/realtek/rtlwifi/rtl8188ee/sw.c    | 11 +++---
 .../net/wireless/realtek/rtlwifi/rtl8192ce/sw.c    | 11 +++---
 .../net/wireless/realtek/rtlwifi/rtl8192cu/sw.c    | 10 +++--
 .../net/wireless/realtek/rtlwifi/rtl8192de/sw.c    | 11 +++---
 .../net/wireless/realtek/rtlwifi/rtl8192ee/sw.c    | 11 +++---
 .../net/wireless/realtek/rtlwifi/rtl8192se/sw.c    | 11 +++---
 .../net/wireless/realtek/rtlwifi/rtl8723ae/sw.c    | 11 +++---
 .../net/wireless/realtek/rtlwifi/rtl8723be/sw.c    | 11 +++---
 .../net/wireless/realtek/rtlwifi/rtl8821ae/sw.c    | 11 +++---
 drivers/net/wireless/realtek/rtlwifi/usb.c         |  1 -
 drivers/net/wireless/realtek/rtlwifi/wifi.h        | 15 ++------
 15 files changed, 70 insertions(+), 105 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 13325e1..1b23b24 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -2094,7 +2094,7 @@ static ssize_t rtl_show_debug_level(struct device *d,
 	struct ieee80211_hw *hw = dev_get_drvdata(d);
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel);
+	return sprintf(buf, "0x%08X\n", rtlpriv->cfg->mod_params->debug_level);
 }
 
 static ssize_t rtl_store_debug_level(struct device *d,
@@ -2111,10 +2111,10 @@ static ssize_t rtl_store_debug_level(struct device *d,
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
 			 "%s is not in hex or decimal form.\n", buf);
 	} else {
-		rtlpriv->dbg.global_debuglevel = val;
+		rtlpriv->cfg->mod_params->debug_level = val;
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
 			 "debuglevel:%x\n",
-			 rtlpriv->dbg.global_debuglevel);
+			 rtlpriv->cfg->mod_params->debug_level);
 	}
 
 	return strnlen(buf, count);
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c
index cd2efac..7ecac611 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.c
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.c
@@ -26,35 +26,12 @@
 
 #include <linux/moduleparam.h>
 
-void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u8 i;
-
-	rtlpriv->dbg.global_debugcomponents =
-	    COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
-	    COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
-	    COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
-	    COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
-	    COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
-	    COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN |
-	    COMP_EASY_CONCURRENT | COMP_EFUSE | COMP_QOS | COMP_MAC80211 |
-	    COMP_REGD | COMP_CHAN | COMP_BT_COEXIST;
-
-
-	for (i = 0; i < DBGP_TYPE_MAX; i++)
-		rtlpriv->dbg.dbgp_type[i] = 0;
-
-	/*Init Debug flag enable condition */
-}
-EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init);
-
 #ifdef CONFIG_RTLWIFI_DEBUG
 void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
 		    const char *fmt, ...)
 {
-	if (unlikely((comp & rtlpriv->dbg.global_debugcomponents) &&
-		     (level <= rtlpriv->dbg.global_debuglevel))) {
+	if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
+		     (level <= rtlpriv->cfg->mod_params->debug_level))) {
 		struct va_format vaf;
 		va_list args;
 
@@ -63,7 +40,7 @@ void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
 		vaf.fmt = fmt;
 		vaf.va = &args;
 
-		pr_debug(":<%lx> %pV", in_interrupt(), &vaf);
+		pr_info(":<%lx> %pV", in_interrupt(), &vaf);
 
 		va_end(args);
 	}
@@ -73,8 +50,8 @@ EXPORT_SYMBOL_GPL(_rtl_dbg_trace);
 void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
 		    const char *fmt, ...)
 {
-	if (unlikely((comp & rtlpriv->dbg.global_debugcomponents) &&
-		     (level <= rtlpriv->dbg.global_debuglevel))) {
+	if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
+		     (level <= rtlpriv->cfg->mod_params->debug_level))) {
 		struct va_format vaf;
 		va_list args;
 
@@ -83,7 +60,7 @@ void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
 		vaf.fmt = fmt;
 		vaf.va = &args;
 
-		pr_debug("%pV", &vaf);
+		pr_info("%pV", &vaf);
 
 		va_end(args);
 	}
@@ -94,10 +71,10 @@ void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
 			 const char *titlestring,
 			 const void *hexdata, int hexdatalen)
 {
-	if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) &&
-		     ((level) <= rtlpriv->dbg.global_debuglevel))) {
-		pr_debug("In process \"%s\" (pid %i): %s\n",
-			 current->comm, current->pid, titlestring);
+	if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) &&
+		     ((level) <= rtlpriv->cfg->mod_params->debug_level))) {
+		pr_info("In process \"%s\" (pid %i): %s\n",
+			current->comm, current->pid, titlestring);
 		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
 				     hexdata, hexdatalen);
 	}
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h
index 90c670b..bf5339f 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.h
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.h
@@ -218,6 +218,4 @@ static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv,
 }
 
 #endif
-
-void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
 #endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 81ac0b3..f6d4dbe 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -2212,16 +2212,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
 	rtlpriv->intf_ops = &rtl_pci_ops;
 	rtlpriv->glb_var = &rtl_global_var;
 
-	/*
-	 *init dbgp flags before all
-	 *other functions, because we will
-	 *use it in other funtions like
-	 *RT_TRACE/RT_PRINT/RTL_PRINT_DATA
-	 *you can not use these macro
-	 *before this
-	 */
-	rtl_dbgp_flag_init(hw);
-
 	/* MEM map */
 	err = pci_request_regions(pdev, KBUILD_MODNAME);
 	if (err) {
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
index 276c745..7661cfa 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
@@ -131,8 +131,6 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpci->irq_mask[1] = (u32) (IMR_RXFOVW | 0);
 	rtlpci->sys_irq_mask = (u32) (HSIMR_PDN_INT_EN | HSIMR_RON_INT_EN);
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -276,7 +274,8 @@ static struct rtl_mod_params rtl88ee_mod_params = {
 	.swctrl_lps = false,
 	.fwctrl_lps = false,
 	.msi_support = true,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl88ee_hal_cfg = {
@@ -392,7 +391,8 @@ MODULE_DESCRIPTION("Realtek 8188E 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8188efw.bin");
 
 module_param_named(swenc, rtl88ee_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl88ee_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl88ee_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl88ee_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444);
@@ -404,7 +404,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
index 9bd2bff6..efedd91 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
@@ -130,8 +130,6 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 
 	rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -247,7 +245,8 @@ static struct rtl_mod_params rtl92ce_mod_params = {
 	.inactiveps = true,
 	.swctrl_lps = false,
 	.fwctrl_lps = true,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl92ce_hal_cfg = {
@@ -364,7 +363,8 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cfwU.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8192cfwU_B.bin");
 
 module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92ce_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92ce_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92ce_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);
@@ -372,7 +372,8 @@ 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 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
index 935e830..96c923b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
@@ -61,7 +61,6 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpriv->dm.dm_flag = 0;
 	rtlpriv->dm.disable_framebursting = false;
 	rtlpriv->dm.thermalvalue = 0;
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	rtlpriv->cfg->mod_params->sw_crypto =
 		rtlpriv->cfg->mod_params->sw_crypto;
 
@@ -157,13 +156,16 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
 
 static struct rtl_mod_params rtl92cu_mod_params = {
 	.sw_crypto = 0,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 };
 
 module_param_named(swenc, rtl92cu_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92cu_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92cu_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92cu_mod_params.debug_mask, ullong, 0644);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = {
 	/* rx */
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
index 51463d7..16132c6 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
@@ -140,8 +140,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
 
 	rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD);
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -254,7 +252,8 @@ static struct rtl_mod_params rtl92de_mod_params = {
 	.inactiveps = true,
 	.swctrl_lps = true,
 	.fwctrl_lps = false,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl92de_hal_cfg = {
@@ -364,15 +363,17 @@ MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin");
 
 module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92de_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92de_mod_params.debug_level, int, 0644);
 module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444);
+module_param_named(debug_mask, rtl92de_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 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c
index eddc704..554f2dc 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c
@@ -133,8 +133,6 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw)
 				     0);
 	rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0);
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -258,7 +256,8 @@ static struct rtl_mod_params rtl92ee_mod_params = {
 	.swctrl_lps = false,
 	.fwctrl_lps = true,
 	.msi_support = true,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl92ee_hal_cfg = {
@@ -368,7 +367,8 @@ MODULE_DESCRIPTION("Realtek 8192EE 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8192eefw.bin");
 
 module_param_named(swenc, rtl92ee_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92ee_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92ee_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92ee_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl92ee_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92ee_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92ee_mod_params.fwctrl_lps, bool, 0444);
@@ -380,7 +380,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
index 3c66d00..2006b09 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
@@ -178,8 +178,6 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
 
 	rtlpci->first_init = true;
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -297,7 +295,8 @@ static struct rtl_mod_params rtl92se_mod_params = {
 	.inactiveps = true,
 	.swctrl_lps = true,
 	.fwctrl_lps = false,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 };
 
 /* Because memory R/W bursting will cause system hang/crash
@@ -416,7 +415,8 @@ MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin");
 
 module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92se_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92se_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92se_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444);
@@ -424,7 +424,8 @@ 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 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
index 401f542..7bf9f25 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
@@ -145,8 +145,6 @@ int rtl8723e_init_sw_vars(struct ieee80211_hw *hw)
 		 (u32)(PHIMR_RXFOVW |
 				0);
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -268,7 +266,8 @@ static struct rtl_mod_params rtl8723e_mod_params = {
 	.inactiveps = true,
 	.swctrl_lps = false,
 	.fwctrl_lps = true,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 	.msi_support = false,
 	.disable_watchdog = false,
 };
@@ -382,7 +381,8 @@ MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8723efw.bin");
 
 module_param_named(swenc, rtl8723e_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl8723e_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl8723e_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl8723e_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl8723e_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8723e_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8723e_mod_params.fwctrl_lps, bool, 0444);
@@ -394,7 +394,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
index dd42c1a..e571b87 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
@@ -144,8 +144,6 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
 				     HSIMR_RON_INT_EN	|
 				     0);
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -271,7 +269,8 @@ static struct rtl_mod_params rtl8723be_mod_params = {
 	.fwctrl_lps = true,
 	.msi_support = false,
 	.disable_watchdog = false,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 	.ant_sel = 0,
 };
 
@@ -386,7 +385,8 @@ MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin");
 
 module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl8723be_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl8723be_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl8723be_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
@@ -399,7 +399,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog,
 		 "Set to 1 to disable the watchdog (default 0)\n");
 MODULE_PARM_DESC(ant_sel, "Set to 1 or 2 to force antenna number (default 0)\n");
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
index 220de5f..cd2a53b7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
@@ -160,8 +160,6 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpriv->psc.wo_wlan_mode = WAKE_ON_MAGIC_PACKET |
 				    WAKE_ON_PATTERN_MATCH;
 
-	/* for debug level */
-	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
 	/* for LPS & IPS */
 	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -309,7 +307,8 @@ static struct rtl_mod_params rtl8821ae_mod_params = {
 	.fwctrl_lps = true,
 	.msi_support = true,
 	.int_clear = true,
-	.debug = 0,
+	.debug_level = 0,
+	.debug_mask = 0,
 	.disable_watchdog = 0,
 };
 
@@ -430,7 +429,8 @@ MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
 
 module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl8821ae_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl8821ae_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl8821ae_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl8821ae_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8821ae_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
@@ -443,7 +443,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 MODULE_PARM_DESC(int_clear, "Set to 0 to disable interrupt clear before set (default 1)\n");
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c
index b2b62ef..20d3fcc 100644
--- a/drivers/net/wireless/realtek/rtlwifi/usb.c
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c
@@ -1073,7 +1073,6 @@ int rtl_usb_probe(struct usb_interface *intf,
 	rtlpriv->rtlhal.interface = INTF_USB;
 	rtlpriv->cfg = rtl_hal_cfg;
 	rtlpriv->intf_ops = &rtl_usb_ops;
-	rtl_dbgp_flag_init(hw);
 	/* Init IO handler */
 	_rtl_usb_io_handler_init(&udev->dev, hw);
 	rtlpriv->cfg->ops->read_chip_version(hw);
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index dafe486..262c02a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2221,11 +2221,13 @@ struct rtl_intf_ops {
 };
 
 struct rtl_mod_params {
+	/* default: 0,0 */
+	u64 debug_mask;
 	/* default: 0 = using hardware encryption */
 	bool sw_crypto;
 
 	/* default: 0 = DBG_EMERG (0)*/
-	int debug;
+	int debug_level;
 
 	/* default: 1 = using no linked power save */
 	bool inactiveps;
@@ -2345,16 +2347,6 @@ struct rtl_works {
 	struct work_struct fill_h2c_cmd;
 };
 
-struct rtl_debug {
-	u32 dbgp_type[DBGP_TYPE_MAX];
-	int global_debuglevel;
-	u64 global_debugcomponents;
-
-	/* add for proc debug */
-	struct proc_dir_entry *proc_dir;
-	char proc_name[20];
-};
-
 #define MIMO_PS_STATIC			0
 #define MIMO_PS_DYNAMIC			1
 #define MIMO_PS_NOLIMIT			3
@@ -2583,7 +2575,6 @@ struct rtl_priv {
 	/* sta entry list for ap adhoc or mesh */
 	struct list_head entry_list;
 
-	struct rtl_debug dbg;
 	int max_fw_size;
 
 	/*
-- 
2.10.2

^ permalink raw reply related

* Re: [PATCH] rtlwifi: rtl8192x: Enabling and disabling hardware interrupts after enabling local irq flags
From: Lino Sanfilippo @ 2017-01-19 14:35 UTC (permalink / raw)
  To: Bharat Kumar Gogada
  Cc: Larry.Finger, chaoming_li, linux-wireless, linux-kernel, kvalo,
	netdev, rgummal, Bharat Kumar Gogada
In-Reply-To: <1484820854-16719-1-git-send-email-bharatku@xilinx.com>

Hi,

altek/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
> index a47be73..143766c4 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
> @@ -1306,9 +1306,9 @@ void rtl92ce_enable_interrupt(struct ieee80211_hw *hw)
>  	struct rtl_priv *rtlpriv = rtl_priv(hw);
>  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
>  
> +	rtlpci->irq_enabled = true;
>  	rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
>  	rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
> -	rtlpci->irq_enabled = true;
>  }
>  
>  void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
> @@ -1316,9 +1316,9 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
>  	struct rtl_priv *rtlpriv = rtl_priv(hw);
>  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
>  
> +	rtlpci->irq_enabled = false;
>  	rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
>  	rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
> -	rtlpci->irq_enabled = false;
>  }
>  

AFAIK you also have to use memory barriers here to ensure that
the concerning instructions are not reordered, and both irq handler
and process have a consistent perception of irq_enabled, e.g:

rtlpci->irq_enabled = true;
smp_wmb();
rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);

and in the irq handler

if (rtlpci->irq_enabled == 0) {
        smp_rmb();
	return ret;
}


Regards,
Lino

^ permalink raw reply

* Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: Ulf Hansson @ 2017-01-19 14:13 UTC (permalink / raw)
  To: Matt Ranostay
  Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-mmc@vger.kernel.org, devicetree@vger.kernel.org,
	Tony Lindgren, Shawn Lin
In-Reply-To: <20170113052937.12538-3-matt@ranostay.consulting>

+Shawn

On 13 January 2017 at 06:29, Matt Ranostay <matt@ranostay.consulting> wrote:
> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
> This can be abstracted to other chipsets if needed in the future.
>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
> ---
>  drivers/mmc/core/Kconfig         |  10 ++++
>  drivers/mmc/core/Makefile        |   1 +
>  drivers/mmc/core/pwrseq_sd8787.c | 117 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 128 insertions(+)
>  create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index cdfa8520a4b1..fc1ecdaaa9ca 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>           This driver can also be built as a module. If so, the module
>           will be called pwrseq_emmc.
>
> +config PWRSEQ_SD8787
> +       tristate "HW reset support for SD8787 BT + Wifi module"
> +       depends on OF && (MWIFIEX || BT_MRVL_SDIO)
> +       help
> +         This selects hardware reset support for the SD8787 BT + Wifi
> +         module. By default this option is set to n.
> +
> +         This driver can also be built as a module. If so, the module
> +         will be called pwrseq_sd8787.
> +
>  config PWRSEQ_SIMPLE
>         tristate "Simple HW reset support for MMC"
>         default y
> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
> index b2a257dc644f..0f81464fa824 100644
> --- a/drivers/mmc/core/Makefile
> +++ b/drivers/mmc/core/Makefile
> @@ -10,6 +10,7 @@ mmc_core-y                    := core.o bus.o host.o \
>                                    quirks.o slot-gpio.o
>  mmc_core-$(CONFIG_OF)          += pwrseq.o
>  obj-$(CONFIG_PWRSEQ_SIMPLE)    += pwrseq_simple.o
> +obj-$(CONFIG_PWRSEQ_SD8787)    += pwrseq_sd8787.o
>  obj-$(CONFIG_PWRSEQ_EMMC)      += pwrseq_emmc.o
>  mmc_core-$(CONFIG_DEBUG_FS)    += debugfs.o
>  obj-$(CONFIG_MMC_BLOCK)                += mmc_block.o
> diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
> new file mode 100644
> index 000000000000..f4080fe6439e
> --- /dev/null
> +++ b/drivers/mmc/core/pwrseq_sd8787.c
> @@ -0,0 +1,117 @@
> +/*
> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip
> + *
> + * Copyright (C) 2016 Matt Ranostay <matt@ranostay.consulting>
> + *
> + * Based on the original work pwrseq_simple.c
> + *  Copyright (C) 2014 Linaro Ltd
> + *  Author: Ulf Hansson <ulf.hansson@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gpio/consumer.h>
> +
> +#include <linux/mmc/host.h>
> +
> +#include "pwrseq.h"
> +
> +struct mmc_pwrseq_sd8787 {
> +       struct mmc_pwrseq pwrseq;
> +       struct gpio_desc *reset_gpio;
> +       struct gpio_desc *pwrdn_gpio;
> +};
> +
> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
> +
> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
> +{
> +       struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
> +
> +       gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
> +
> +       msleep(300);
> +       gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
> +}
> +
> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
> +{
> +       struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
> +
> +       gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
> +       gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
> +}
> +
> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
> +       .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
> +       .power_off = mmc_pwrseq_sd8787_power_off,
> +};
> +
> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
> +       { .compatible = "mmc-pwrseq-sd8787",},
> +       {/* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
> +
> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
> +{
> +       struct mmc_pwrseq_sd8787 *pwrseq;
> +       struct device *dev = &pdev->dev;
> +
> +       pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
> +       if (!pwrseq)
> +               return -ENOMEM;
> +
> +       pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
> +       if (IS_ERR(pwrseq->pwrdn_gpio))
> +               return PTR_ERR(pwrseq->pwrdn_gpio);
> +
> +       pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> +       if (IS_ERR(pwrseq->reset_gpio))
> +               return PTR_ERR(pwrseq->reset_gpio);
> +
> +       pwrseq->pwrseq.dev = dev;
> +       pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
> +       pwrseq->pwrseq.owner = THIS_MODULE;
> +       platform_set_drvdata(pdev, pwrseq);
> +
> +       return mmc_pwrseq_register(&pwrseq->pwrseq);
> +}
> +
> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
> +{
> +       struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
> +
> +       mmc_pwrseq_unregister(&pwrseq->pwrseq);
> +
> +       return 0;
> +}
> +
> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
> +       .probe = mmc_pwrseq_sd8787_probe,
> +       .remove = mmc_pwrseq_sd8787_remove,
> +       .driver = {
> +               .name = "pwrseq_sd8787",
> +               .of_match_table = mmc_pwrseq_sd8787_of_match,
> +       },
> +};
> +
> +module_platform_driver(mmc_pwrseq_sd8787_driver);
> +MODULE_LICENSE("GPL v2");
> --
> 2.10.2
>

Twisting my head around how this could be integrated smoothly into
pwrseq simple. No, I just can find a good way forward without messing
up pwrseq simple itself.

So, for now I decided (once more :-), that let's keep this as separate driver!

Perhaps, following device specific mmc pwrseq drivers will needs
something similar, but in such case we can look into that then.
Thinking about cw1200 for example.

Let's get Rob's ack for the DT bindings, seems almost there, then I
will queue this.

Kind regards
Uffe

^ permalink raw reply

* Re: [PATCH 2/4] cfg80211: Add new NL80211_CMD_SET_BTCOEX_PRIORITY to support BTCOEX
From: Tamizh chelvam @ 2017-01-19 13:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: c_traja, linux-wireless, ath10k
In-Reply-To: <1483958190.17582.15.camel@sipsolutions.net>

Hi Johannes,

Sorry for the late response:(

On 2017-01-09 16:06, Johannes Berg wrote:
>> Is it fine to have something like this
>> 
>> 1) We can have this btcoex_priority value as a optional value in
>> btcoex enable command like below
>> 
>> iw phyX btcoex_state <enable| disable> [prirority(vendor spcific
>> value)]
>> 
>> 2) Or we can have seperate command for btcoex_priority as below
>> 
>> iw phyX set btcoex_priority <priority (vendor spcific value)>
>> 
>> Hopefully this will get rid off all the nl80211 bits.
> 
> That makes no sense.
> 
> If the bits are vendor specific, then there's no value in having this
> as an nl80211 command (rather than a vendor command) to start with.
> 
> You need to understand that I'm differentiating between *capability*
> bits and actual *priority setting* bits - please re-read the thread
> with that in mind.
> 
Those are for priority and not for capability purpose. Hardware is 
capable of
transmitting all the frames when there is a bt traffic. This is just 
setting priority for the wlan
frame, when there is a contention with BT traffic which one has to go 
out first.
Other than that hardware has the capability of sending all the frames.

This priority field is optional, if users does not want to set any 
priority then driver will force the
default priorities when bt_coex is enabled

iw phyX btcoex_state <enable| disable> [prirority]

^ permalink raw reply

* [PATCH v3] rt2x00: add support for RT5350 WiSoC
From: Daniel Golle @ 2017-01-19 13:38 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <20170118144719.GB22837@redhat.com>

From: Michel Stempin <michel.stempin@wanadoo.fr>

Support for the RT5350 WiSoC was added to OpenWrt after having a
lengthy debate about the legality of the original submission, see
https://lists.openwrt.org/pipermail/openwrt-devel/2013-January/018224.html
MTK/Ralink Acked replied and says we can merge this patch under the GPL.
https://dev.openwrt.org/changeset/36177

Signed-off-by: Serge Vasilugin <vasilugin@yandex.ru>
Tested-by: Michel Stempin <michel.stempin@wanadoo.fr>
Acked-by: John Crispin <blogic@openwrt.org>
[daniel@makrotopia.org: added commit message, cleaned up code]

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: reordered patches to breakout RT3883 from the original series
v3: remove superflus EEPROM_NIC_CONF0 mangeling from RT5350 patch

 drivers/net/wireless/ralink/rt2x00/rt2800.h    |   1 +
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 125 +++++++++++++++++++++++--
 drivers/net/wireless/ralink/rt2x00/rt2x00.h    |   1 +
 3 files changed, 120 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
index 18096903e20f..256496bfbafb 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
@@ -72,6 +72,7 @@
 #define RF5592				0x000f
 #define RF3070				0x3070
 #define RF3290				0x3290
+#define RF5350				0x5350
 #define RF5360				0x5360
 #define RF5362				0x5362
 #define RF5370				0x5370
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index c33298baecc3..b4b28caff39d 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -2759,6 +2759,13 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
 
 				rt2800_rfcsr_write(rt2x00dev, 59,
 						   r59_non_bt[idx]);
+			} else if (rt2x00_rt(rt2x00dev, RT5350)) {
+				static const char r59_non_bt[] = {0x0b, 0x0b,
+					0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a,
+					0x0a, 0x09, 0x08, 0x07, 0x07, 0x06};
+
+				rt2800_rfcsr_write(rt2x00dev, 59,
+						   r59_non_bt[idx]);
 			}
 		}
 	}
@@ -3196,6 +3203,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
 		break;
 	case RF3070:
+	case RF5350:
 	case RF5360:
 	case RF5362:
 	case RF5370:
@@ -3214,6 +3222,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 	if (rt2x00_rf(rt2x00dev, RF3070) ||
 	    rt2x00_rf(rt2x00dev, RF3290) ||
 	    rt2x00_rf(rt2x00dev, RF3322) ||
+	    rt2x00_rf(rt2x00dev, RF5350) ||
 	    rt2x00_rf(rt2x00dev, RF5360) ||
 	    rt2x00_rf(rt2x00dev, RF5362) ||
 	    rt2x00_rf(rt2x00dev, RF5370) ||
@@ -3471,7 +3480,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Clear update flag
 	 */
-	if (rt2x00_rt(rt2x00dev, RT3352)) {
+	if (rt2x00_rt(rt2x00dev, RT3352) ||
+	    rt2x00_rt(rt2x00dev, RT5350)) {
 		rt2800_bbp_read(rt2x00dev, 49, &bbp);
 		rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
 		rt2800_bbp_write(rt2x00dev, 49, bbp);
@@ -4352,6 +4362,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
 	case RF3053:
 	case RF3070:
 	case RF3290:
+	case RF5350:
 	case RF5360:
 	case RF5362:
 	case RF5370:
@@ -4734,6 +4745,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+	} else if (rt2x00_rt(rt2x00dev, RT5350)) {
+		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
 	} else {
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -5379,9 +5392,13 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
 
 	rt2800_bbp_write(rt2x00dev, 82, 0x62);
 
-	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
-
-	rt2800_bbp_write(rt2x00dev, 84, 0x99);
+	if (rt2x00_rt(rt2x00dev, RT5350)) {
+		rt2800_bbp_write(rt2x00dev, 83, 0x7a);
+		rt2800_bbp_write(rt2x00dev, 84, 0x9a);
+	} else {
+		rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+		rt2800_bbp_write(rt2x00dev, 84, 0x99);
+	}
 
 	rt2800_bbp_write(rt2x00dev, 86, 0x38);
 
@@ -5395,9 +5412,13 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
 
 	rt2800_bbp_write(rt2x00dev, 104, 0x92);
 
-	rt2800_bbp_write(rt2x00dev, 105, 0x34);
-
-	rt2800_bbp_write(rt2x00dev, 106, 0x05);
+	if (rt2x00_rt(rt2x00dev, RT5350)) {
+		rt2800_bbp_write(rt2x00dev, 105, 0x3c);
+		rt2800_bbp_write(rt2x00dev, 106, 0x03);
+	} else {
+		rt2800_bbp_write(rt2x00dev, 105, 0x34);
+		rt2800_bbp_write(rt2x00dev, 106, 0x05);
+	}
 
 	rt2800_bbp_write(rt2x00dev, 120, 0x50);
 
@@ -5422,6 +5443,16 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
 	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
 
 	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+
+	if (rt2x00_rt(rt2x00dev, RT5350)) {
+		/* Antenna Software OFDM */
+		rt2800_bbp_write(rt2x00dev, 150, 0x40);
+		/* Antenna Software CCK */
+		rt2800_bbp_write(rt2x00dev, 151, 0x30);
+		rt2800_bbp_write(rt2x00dev, 152, 0xa3);
+		/* Clear previously selected antenna */
+		rt2800_bbp_write(rt2x00dev, 154, 0);
+	}
 }
 
 static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
@@ -5722,6 +5753,7 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 		rt2800_init_bbp_3290(rt2x00dev);
 		break;
 	case RT3352:
+	case RT5350:
 		rt2800_init_bbp_3352(rt2x00dev);
 		break;
 	case RT3390:
@@ -6532,6 +6564,76 @@ static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
 	/* TODO: enable stream mode support */
 }
 
+static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
+	rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
+	rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
+	rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
+	rt2800_rfcsr_write(rt2x00dev, 4, 0x49);
+	rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
+	rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
+	rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
+	rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
+	rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
+	rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
+	rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
+	if (rt2x00dev->spec.clk_is_20mhz)
+		rt2800_rfcsr_write(rt2x00dev, 13, 0x1f);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
+	rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 16, 0xc0);
+	rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
+	rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
+	rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
+	rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
+	rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 29, 0xd0);
+	rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
+	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
+	rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
+	rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
+	rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
+	rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
+	rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
+	rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
+	rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
+	rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
+	rt2800_rfcsr_write(rt2x00dev, 44, 0x0c);
+	rt2800_rfcsr_write(rt2x00dev, 45, 0xa6);
+	rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
+	rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
+	rt2800_rfcsr_write(rt2x00dev, 49, 0x80);
+	rt2800_rfcsr_write(rt2x00dev, 50, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 51, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
+	rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
+	rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
+	rt2800_rfcsr_write(rt2x00dev, 56, 0x82);
+	rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
+	rt2800_rfcsr_write(rt2x00dev, 59, 0x0b);
+	rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
+	rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
+	rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
+}
+
 static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
 {
 	rt2800_rf_init_calibration(rt2x00dev, 2);
@@ -6769,6 +6871,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 	case RT3593:
 		rt2800_init_rfcsr_3593(rt2x00dev);
 		break;
+	case RT5350:
+		rt2800_init_rfcsr_5350(rt2x00dev);
+		break;
 	case RT5390:
 		rt2800_init_rfcsr_5390(rt2x00dev);
 		break;
@@ -7148,6 +7253,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
 		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
 	else if (rt2x00_rt(rt2x00dev, RT3352))
 		rf = RF3322;
+	else if (rt2x00_rt(rt2x00dev, RT5350))
+		rf = RF5350;
 	else
 		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
 
@@ -7166,6 +7273,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	case RF3290:
 	case RF3320:
 	case RF3322:
+	case RF5350:
 	case RF5360:
 	case RF5362:
 	case RF5370:
@@ -7669,6 +7777,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	case RF3290:
 	case RF3320:
 	case RF3322:
+	case RF5350:
 	case RF5360:
 	case RF5362:
 	case RF5370:
@@ -7805,6 +7914,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	case RF3053:
 	case RF3070:
 	case RF3290:
+	case RF5350:
 	case RF5360:
 	case RF5362:
 	case RF5370:
@@ -7845,6 +7955,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
 	case RT3390:
 	case RT3572:
 	case RT3593:
+	case RT5350:
 	case RT5390:
 	case RT5392:
 	case RT5592:
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
index 4b3dd1163653..7ac265fd879e 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -169,6 +169,7 @@ struct rt2x00_chip {
 #define RT3572		0x3572
 #define RT3593		0x3593
 #define RT3883		0x3883	/* WSOC */
+#define RT5350		0x5350  /* WSOC 2.4GHz */
 #define RT5390		0x5390  /* 2.4GHz */
 #define RT5392		0x5392  /* 2.4GHz */
 #define RT5592		0x5592
-- 
2.11.0

^ permalink raw reply related

* Re: [net-next] ath6kl: fix warning for using 0 as NULL
From: Kalle Valo @ 2017-01-19 13:15 UTC (permalink / raw)
  To: Wei Yongjun; +Cc: Wei Yongjun, linux-wireless
In-Reply-To: <20170111163130.19087-1-weiyj.lk@gmail.com>

Wei Yongjun <weiyj.lk@gmail.com> wrote:
> From: Wei Yongjun <weiyongjun1@huawei.com>
> 
> Fixes the following sparse warning:
> 
> drivers/net/wireless/ath/ath6kl/sdio.c:716:55: warning:
>  Using plain integer as NULL pointer
> 
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>

Patch applied to ath-next branch of ath.git, thanks.

96d179b517a9 ath6kl: fix warning for using 0 as NULL

-- 
https://patchwork.kernel.org/patch/9510615/

Documentation about submitting wireless patches and checking status
from patchwork:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply

* Re: [PATCH v2 13/14] rt2x00: rt2800lib: add support for RT3352 with 20MHz crystal
From: Daniel Golle @ 2017-01-19 13:30 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: linux-mips, linux-wireless, michel.stempin, Kalle Valo,
	Felix Fietkau, John Crispin, Gabor Juhos
In-Reply-To: <20170118142958.GA14573@redhat.com>

Hi Stanislaw,

On Wed, Jan 18, 2017 at 03:30:02PM +0100, Stanislaw Gruszka wrote:
> On Mon, Jan 16, 2017 at 04:15:56AM +0100, Daniel Golle wrote:
> > Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> > Signed-off-by: Mathias Kresin <dev@kresin.me>
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> >  drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 50 +++++++++++++++++++++++++-
> >  drivers/net/wireless/ralink/rt2x00/rt2x00.h    |  2 ++
> >  2 files changed, 51 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > index 93c97eade334..cb1457595f05 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> > @@ -36,6 +36,7 @@
> >  #include <linux/kernel.h>
> >  #include <linux/module.h>
> >  #include <linux/slab.h>
> > +#include <linux/clk.h>
> >  
> >  #include "rt2x00.h"
> >  #include "rt2800lib.h"
> > @@ -7675,6 +7676,27 @@ static const struct rf_channel rf_vals_5592_xtal40[] = {
> >  	{196, 83, 0, 12, 1},
> >  };
> >  
> > +/*
> > + * RF value list for rt3xxx with Xtal20MHz
> > + * Supports: 2.4 GHz (all) (RF3322)
> > + */
> > +static const struct rf_channel rf_vals_xtal20mhz_3x[] = {
> Please locate this values in alphabetical order (i.e. after _3x and 
> before _5592 ).

Sure, sorry, that ended up in the wrong order when rebase the patches.

> 
> >  	struct hw_mode_spec *spec = &rt2x00dev->spec;
> > @@ -7764,7 +7786,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> >  	case RF5390:
> >  	case RF5392:
> >  		spec->num_channels = 14;
> > -		spec->channels = rf_vals_3x;
> > +		if (spec->clk_is_20mhz)
> > +			spec->channels = rf_vals_xtal20mhz_3x;
> > +		else
> > +			spec->channels = rf_vals_3x;
> >  		break;
> 
> How does vendor drivers recognize xtal (I assume rf_vals_xtal20mhz_3x 
> values were taken from vendor driver) ? It should be possible to get
> clock frequency from device register like is is done on RF5592, without
> adding additional clock recognition code. But if such code is needed
> I prefer that low level board/platform routines do it and place clock
> frequency for rt2x00 in rt2x00dev->dev->platform_data.

Recent vendor drivers probe the clock by reading a SYSCTL register:
---
// Programming channel parameters
Value = (*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x10)));
if(Value & (1<<20)) { //Xtal=40M
	RT30xxWriteRFRegister(pAd, RF_R08, FreqItems3020[index].N);
	RT30xxWriteRFRegister(pAd, RF_R09, FreqItems3020[index].K);
}else {
	RT30xxWriteRFRegister(pAd, RF_R08, FreqItems3020_Xtal20M[index].N);
	RT30xxWriteRFRegister(pAd, RF_R09, FreqItems3020_Xtal20M[index].K);
}
---

>From what I can see, most other drivers which need to touch SYSCTL
currently do that by defining a local precompiler macro:
---
#ifdef CONFIG_SOC_MT7621
#define RALINK_SYSCTL_BASE             0xbe000000
#else
#define RALINK_SYSCTL_BASE             0xb0000000
#endif
---

That's obviously not very elegant and probably we should define SYSCTL
in the device tree of each SoC and we should write/adapt a syscon mfd
driver which other drivers may then use to read/write stuff to/from
SYSCTL. The clock could then be provided by a clk driver sitting on top
of that and rt2x00 would use that clock.
In the meantime, why not just define a static clock in the device-tree
and already have rt2x00 consume that clock? That would already be the
way things will most likely look like from rt2x00 point of view once
syscon and clk drivers are in place.


Cheers


Daniel

^ permalink raw reply

* Re: ath10k: dump Copy Engine registers during firmware crash
From: Kalle Valo @ 2017-01-19 13:19 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <148458066842.22029.11182008791835649945.stgit@potku.adurom.net>

Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
> 
> Dump Copy Engine source and destination ring addresses.
> This is useful information to debug firmware crashes, assertes or hangs over long run
> assessing the Copy Engine Register status. This also enables dumping CE
> register status in debugfs Crash Dump file.
> 
> Screenshot:
> 
> ath10k_pci 0000:02:00.0: simulating hard firmware crash
> ath10k_pci 0000:02:00.0: firmware crashed! (uuid 84901ff5-d33c-456e-93ee-0165dea643cf)
> ath10k_pci 0000:02:00.0: qca988x hw2.0 target 0x4100016c chip_id 0x043202ff sub 0000:0000
> ath10k_pci 0000:02:00.0: kconfig debug 1 debugfs 1 tracing 1 dfs 1 testmode 1
> ath10k_pci 0000:02:00.0: firmware ver 10.2.4.70.59-2 api 5 features no-p2p,raw-mode,mfp,allows-mesh-bcast crc32 4159f498
> ath10k_pci 0000:02:00.0: board_file api 1 bmi_id N/A crc32 bebc7c08
> ath10k_pci 0000:02:00.0: htt-ver 2.1 wmi-op 5 htt-op 2 cal otp max-sta 128 raw 0 hwcrypto 1
> ath10k_pci 0000:02:00.0: firmware register dump:
> ath10k_pci 0000:02:00.0: [00]: 0x4100016C 0x00000000 0x009A0F2A 0x00000000
> ath10k_pci 0000:02:00.0: [04]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [08]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [12]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [16]: 0x00000000 0x00000000 0x00000000 0x009A0F2A
> ath10k_pci 0000:02:00.0: [20]: 0x00000000 0x00401930 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [24]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [28]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [32]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [36]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [40]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [44]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [48]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [52]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: [56]: 0x00000000 0x00000000 0x00000000 0x00000000
> ath10k_pci 0000:02:00.0: Copy Engine register dump:
> ath10k_pci 0000:02:00.0: [00]: 0x00057400   7   7   3   3
> ath10k_pci 0000:02:00.0: [01]: 0x00057800  18  18  85  86
> ath10k_pci 0000:02:00.0: [02]: 0x00057c00  49  49  48  49
> ath10k_pci 0000:02:00.0: [03]: 0x00058000  16  16  17  16
> ath10k_pci 0000:02:00.0: [04]: 0x00058400   4   4  44   4
> ath10k_pci 0000:02:00.0: [05]: 0x00058800  12  12  11  12
> ath10k_pci 0000:02:00.0: [06]: 0x00058c00   3   3   3   3
> ath10k_pci 0000:02:00.0: [07]: 0x00059000   0   0   0   0
> ieee80211 phy0: Hardware restart was requested
> ath10k_pci 0000:02:00.0: device successfully recovered
> 
> Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
> [kvalo@qca.qualcomm.com: simplify the implementation]
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>

Patch applied to ath-next branch of ath.git, thanks.

c75c398be6ed ath10k: dump Copy Engine registers during firmware crash

-- 
https://patchwork.kernel.org/patch/9518985/

Documentation about submitting wireless patches and checking status
from patchwork:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox