Re: pull request: mt76 2018-10-01

2018-10-03 Thread Kalle Valo
Felix Fietkau  writes:

> Here's another large batch of mt76 code cleanup / deduplication / fixes
>
> - Felix
>
> The following changes since commit 93ed990e3a6e722b7b1e1d59b3ceb8d91e36e682:
>
>   qtnfmac: remove set but not used variable 'vif' (2018-09-20 15:12:13 +0300)
>
> are available in the Git repository at:
>
>   https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-10-01
>
> for you to fetch changes up to 5289976ad887deb07c76df7eecf553c264aeebed:
>
>   mt76: mt76x2: fix multi-interface beacon configuration (2018-10-01 13:26:21 
> +0200)
>
> 
> mt76 patches for 4.20
>
> * unify code between mt76x0, mt76x2
> * mt76x0 fixes
> * tx power configuration fix for 76x2
> * more progress on mt76x0e support
> * support for getting firmware version via ethtool
> * fix for rx buffer allocation regression on usb
> * fix for handling powersave responses
> * fix for mt76x2 beacon transmission
>
> 

Pulled, thanks.

-- 
Kalle Valo


[PATCH] mac80211: support FTM responder configuration/statistics

2018-10-03 Thread Pradeep Kumar Chitrapu
New bss param ftm_responder is used to notify the driver to
enable fine timing request (FTM) responder role in AP mode.

Plumb the new cfg80211 API for FTM responder statistics through to
the driver API in mac80211.

Signed-off-by: David Spinadel 
Signed-off-by: Johannes Berg 
Signed-off-by: Pradeep Kumar Chitrapu 
---
 include/net/mac80211.h| 28 
 net/mac80211/cfg.c| 85 +++
 net/mac80211/driver-ops.h | 16 +
 net/mac80211/trace.h  | 23 +
 net/mac80211/util.c   |  5 +++
 5 files changed, 157 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index c4fadbafbf21..2ccd4d1bef89 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -309,6 +309,8 @@ struct ieee80211_vif_chanctx_switch {
  * @BSS_CHANGED_KEEP_ALIVE: keep alive options (idle period or protected
  * keep alive) changed.
  * @BSS_CHANGED_MCAST_RATE: Multicast Rate setting changed for this interface
+ * @BSS_CHANGED_FTM_RESPONDER: fime timing reasurement request responder
+ * functionality changed for this BSS (AP mode).
  *
  */
 enum ieee80211_bss_change {
@@ -338,6 +340,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_MU_GROUPS   = 1<<23,
BSS_CHANGED_KEEP_ALIVE  = 1<<24,
BSS_CHANGED_MCAST_RATE  = 1<<25,
+   BSS_CHANGED_FTM_RESPONDER   = 1<<26,
 
/* when adding here, make sure to change ieee80211_reconfig */
 };
@@ -464,6 +467,21 @@ struct ieee80211_mu_group_data {
 };
 
 /**
+ * ieee80211_ftm_responder_params - FTM responder parameters
+ *
+ * @lci: LCI subelement content
+ * @civicloc: CIVIC location subelement content
+ * @lci_len: LCI data length
+ * @civicloc_len: Civic data length
+ */
+struct ieee80211_ftm_responder_params {
+   const u8 *lci;
+   const u8 *civicloc;
+   size_t lci_len;
+   size_t civicloc_len;
+};
+
+/**
  * struct ieee80211_bss_conf - holds the BSS's changing parameters
  *
  * This structure keeps information about a BSS (and an association
@@ -562,6 +580,9 @@ struct ieee80211_mu_group_data {
  * @protected_keep_alive: if set, indicates that the station should send an RSN
  * protected frame to the AP to reset the idle timer at the AP for the
  * station.
+ * @ftm_responder: whether to enable or disable fine timing measurement FTM
+ * responder functionality.
+ * @ftmr_params: configurable lci/civic parameter when enabling FTM responder.
  */
 struct ieee80211_bss_conf {
const u8 *bssid;
@@ -612,6 +633,8 @@ struct ieee80211_bss_conf {
bool allow_p2p_go_ps;
u16 max_idle_period;
bool protected_keep_alive;
+   bool ftm_responder;
+   struct ieee80211_ftm_responder_params *ftmr_params;
 };
 
 /**
@@ -3598,6 +3621,8 @@ enum ieee80211_reconfig_type {
  * aggregating two specific frames in the same A-MSDU. The relation
  * between the skbs should be symmetric and transitive. Note that while
  * skb is always a real frame, head may or may not be an A-MSDU.
+ * @get_ftm_responder_stats: Retrieve FTM responder statistics, if available.
+ * Statistics should be cumulative, currently no way to reset is provided.
  */
 struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -3883,6 +3908,9 @@ struct ieee80211_ops {
bool (*can_aggregate_in_amsdu)(struct ieee80211_hw *hw,
   struct sk_buff *head,
   struct sk_buff *skb);
+   int (*get_ftm_responder_stats)(struct ieee80211_hw *hw,
+  struct ieee80211_vif *vif,
+  struct cfg80211_ftm_responder_stats 
*ftm_stats);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 504627e2117f..c3904d45e82a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -790,6 +790,48 @@ static int ieee80211_set_probe_resp(struct 
ieee80211_sub_if_data *sdata,
return 0;
 }
 
+static int ieee80211_set_ftm_responder_params(
+   struct ieee80211_sub_if_data *sdata,
+   const u8 *lci, size_t lci_len,
+   const u8 *civicloc, size_t civicloc_len)
+{
+   struct ieee80211_ftm_responder_params *new, *old;
+   struct ieee80211_bss_conf *bss_conf;
+   u8 *pos;
+   int len;
+
+   if ((!lci || !lci_len) && (!civicloc || !civicloc_len))
+   return 1;
+
+   bss_conf = >vif.bss_conf;
+   old = bss_conf->ftmr_params;
+   len = lci_len + civicloc_len;
+
+   new = kzalloc(sizeof(*new) + len, GFP_KERNEL);
+   if (!new)
+   return -ENOMEM;
+
+   pos = (u8 *)(new + 1);
+   if (lci_len) {
+   new->lci_len = lci_len;
+   new->lci = pos;
+   memcpy(pos, lci, lci_len);
+   pos += lci_len;
+   }
+
+   if (civicloc_len) {
+   

Re: Tool to debug wifi pkt sniffs?

2018-10-03 Thread Dave Taht
On Wed, Oct 3, 2018 at 1:16 PM Toke Høiland-Jørgensen  wrote:
>
> Ben Greear  writes:
>
> > Hello,
> >
> > I often find myself wanting to figure out what equipment is to blame (and 
> > why)
> > in a wifi environment.
> >
> > I am thinking writing a tool that would parse a pcap file and look at frames
> > in enough detail to flag block-ack bugs, rate-ctrl bugs, guess at the 
> > sniffer's
> > capture ability, etc.
> >
> > Does anyone have anything already written that they would like to share, or 
> > know
> > of projects that might already do some of this?
>
> Not sure if this fits your criteria, but Sven's tool to create airtime
> charts from packet sniffing data immediately came to mind:
>
> https://github.com/cloudtrax/airtime-pie-chart

I have used that. Oy, it's a PITA. Some of kathie's code over here
(example: https://github.com/pollere/pping ) uses the slightly less
painful http://libtins.github.io/ library for parsing packets.


>
> -Toke



-- 

Dave Täht
CEO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-669-226-2619


Re: Tool to debug wifi pkt sniffs?

2018-10-03 Thread Toke Høiland-Jørgensen
Ben Greear  writes:

> Hello,
>
> I often find myself wanting to figure out what equipment is to blame (and why)
> in a wifi environment.
>
> I am thinking writing a tool that would parse a pcap file and look at frames
> in enough detail to flag block-ack bugs, rate-ctrl bugs, guess at the 
> sniffer's
> capture ability, etc.
>
> Does anyone have anything already written that they would like to share, or 
> know
> of projects that might already do some of this?

Not sure if this fits your criteria, but Sven's tool to create airtime
charts from packet sniffing data immediately came to mind:

https://github.com/cloudtrax/airtime-pie-chart

-Toke


Tool to debug wifi pkt sniffs?

2018-10-03 Thread Ben Greear

Hello,

I often find myself wanting to figure out what equipment is to blame (and why)
in a wifi environment.

I am thinking writing a tool that would parse a pcap file and look at frames
in enough detail to flag block-ack bugs, rate-ctrl bugs, guess at the sniffer's
capture ability, etc.

Does anyone have anything already written that they would like to share, or know
of projects that might already do some of this?

Thanks,
Ben

--
Ben Greear 
Candela Technologies Inc  http://www.candelatech.com



Re: [RFC v2 00/12] rtw88: mac80211 driver for Realtek 802.11ac wireless network chips

2018-10-03 Thread Larry Finger

On 10/3/18 11:57 AM, Sid Hayn wrote:

On Wed, Oct 3, 2018 at 12:52 PM Larry Finger  wrote:


On 10/3/18 11:15 AM, Sid Hayn wrote:

Is there a public repository where I can track development for this driver?


For the moment, this is it. Once the driver is accepted into the
wireless-drivers-next tree, I will create a new rtw88 branch in
http://github.com/lwfinger.git with this driver to accomodate people that want


I think you lost part of that link.


Yes. http://github.com/lwfinger/rtlwifi_new.git is the correct one.



Re: [RFC v2 00/12] rtw88: mac80211 driver for Realtek 802.11ac wireless network chips

2018-10-03 Thread Sid Hayn
On Wed, Oct 3, 2018 at 12:52 PM Larry Finger  wrote:
>
> On 10/3/18 11:15 AM, Sid Hayn wrote:
> > Is there a public repository where I can track development for this driver?
>
> For the moment, this is it. Once the driver is accepted into the
> wireless-drivers-next tree, I will create a new rtw88 branch in
> http://github.com/lwfinger.git with this driver to accomodate people that want

I think you lost part of that link.

Thanks,
Zero

> to use the driver with an older kernel.. At the moment, it is still in too 
> much
> of a flux.
>
> Larry
>
>


Re: [RFC v2 00/12] rtw88: mac80211 driver for Realtek 802.11ac wireless network chips

2018-10-03 Thread Larry Finger

On 10/3/18 11:15 AM, Sid Hayn wrote:

Is there a public repository where I can track development for this driver?


For the moment, this is it. Once the driver is accepted into the 
wireless-drivers-next tree, I will create a new rtw88 branch in 
http://github.com/lwfinger.git with this driver to accomodate people that want 
to use the driver with an older kernel.. At the moment, it is still in too much 
of a flux.


Larry




[PATCH v4] brcmsmac: AP mode: update beacon when TIM changes

2018-10-03 Thread Ali MJ Al-Nasrawy
Beacons are not updated to reflect TIM changes. This is not compliant with
power-saving client stations as the beacons do not have valid TIM and can
cause the network to stall at random occasions and to have highly variable
latencies.
Fix it by updating beacon templates on mac80211 set_tim callback.

Addresses an issue described in:
https://marc.info/?i=20180911163534.21312d08%20()%20manjaro

Signed-off-by: Ali MJ Al-Nasrawy 
---

v3 -> v4:
-set vif to NULL on remove_interface callback to prevent dangling
pointers.
-access vif from within >lock context only.
-perform null pointer check before passing vif to
ieee80211_beacon_get_tim.

v2 -> v3:
- remove tabs from blank lines
- extend the commit message to answer "Why"

v1 -> v2:
-remove FIXME comment
-remove blank line before 'vif' member declaration

 .../broadcom/brcm80211/brcmsmac/mac80211_if.c | 26 +++
 .../broadcom/brcm80211/brcmsmac/main.h|  1 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
index ddfdfe1..257968f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
@@ -502,6 +502,7 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
}
 
spin_lock_bh(>lock);
+   wl->wlc->vif = vif;
wl->mute_tx = false;
brcms_c_mute(wl->wlc, false);
if (vif->type == NL80211_IFTYPE_STATION)
@@ -519,6 +520,11 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
 static void
 brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
+   struct brcms_info *wl = hw->priv;
+
+   spin_lock_bh(>lock);
+   wl->wlc->vif = NULL;
+   spin_unlock_bh(>lock);
 }
 
 static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
@@ -937,6 +943,25 @@ static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
spin_unlock_bh(>lock);
 }
 
+static int brcms_ops_beacon_set_tim(struct ieee80211_hw *hw,
+struct ieee80211_sta *sta, bool set)
+{
+   struct brcms_info *wl = hw->priv;
+   struct sk_buff *beacon = NULL;
+   u16 tim_offset = 0;
+
+   spin_lock_bh(>lock);
+   if (wl->wlc->vif)
+   beacon = ieee80211_beacon_get_tim(hw, wl->wlc->vif,
+ _offset, NULL);
+   if (beacon)
+   brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
+  wl->wlc->vif->bss_conf.dtim_period);
+   spin_unlock_bh(>lock);
+
+   return 0;
+}
+
 static const struct ieee80211_ops brcms_ops = {
.tx = brcms_ops_tx,
.start = brcms_ops_start,
@@ -955,6 +980,7 @@ static const struct ieee80211_ops brcms_ops = {
.flush = brcms_ops_flush,
.get_tsf = brcms_ops_get_tsf,
.set_tsf = brcms_ops_set_tsf,
+   .set_tim = brcms_ops_beacon_set_tim,
 };
 
 void brcms_dpc(unsigned long data)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
index c4d135c..9f76b88 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h
@@ -563,6 +563,7 @@ struct brcms_c_info {
 
struct wiphy *wiphy;
struct scb pri_scb;
+   struct ieee80211_vif *vif;
 
struct sk_buff *beacon;
u16 beacon_tim_offset;
-- 
2.18.0



Re: [RFC v2 00/12] rtw88: mac80211 driver for Realtek 802.11ac wireless network chips

2018-10-03 Thread Sid Hayn
Is there a public repository where I can track development for this driver?

Thanks,
Zero
On Wed, Oct 3, 2018 at 4:04 AM  wrote:
>
> From: Yan-Hsuan Chuang 
>
> This is a new mac80211 driver for Realtek 802.11ac wireless network chips.
> rtwlan supports 8822BE and 8822CE chips, and will be able to support
> multi-vif combinations in run-time.
>
> For now, only PCI bus is supported, but rtwlan was originally designed
> to optionally support three buses includes USB & SDIO. USB & SDIO modules
> will soon be supported by rtwlan, with configurable core module to fit
> with different bus modules in the same time.
>
> For example, if we choose 8822BE and 8822CU, only PCI & USB modules will
> be selected, built, loaded into kernel. This is one of the major
> difference from rtlwifi, which can only support specific combinations.
>
> Another difference from rtlwifi is that rtwlan is designed to support
> the latest Realtek 802.11ac wireless network chips like 8822B and
> 8822C series. Compared to the earlier chips supported by rtlwifi like
> the 802.11n 8192EE chipset or 802.11ac 8821AE/8812AE chips, newer ICs
> have different MAC & PHY settings, such as new multi-port feature for the
> MAC layer design and Jaguar2/Jaguar3 PHY layer IPs.
>
> Multi-Port feature is also supported under rtwlan's software architecture.
> rtlwifi can only support one vif in the same time, most because of the
> hardware limitations for early chips, hence the original design of it
> also restricts the usage of multi-vif support, so latest chipset seems not
> take advantages from its new MAC engine.
>
> However, rtwlan can run multiple vifs concurrently by holding them on
> hardware ports provided by MAC engine, hence can easily start different
> roles on a single device.
>
> Based on the reasons mentioned before, we implemented rtwlan. It had many
> authors, they are listed here alphabetically:
>
> Ping-Ke Shih 
> Tzu-En Huang 
> Yan-Hsuan Chuang 
>
>
> v2
>
>  - rename from rtwlan to rtw88
>  - remove lots of magic numbers
>  - add pci null entry for auto load on boot
>  - add rtwdev->mutex to protect against mac80211 callbacks
>  - add rcu lock protection for vif_list and sta_list
>  - refine bits & endian macros to use helper functions provided by kernel
>instead of create new ones
>  - ieee80211_free_txskb for tx path dropped packets
>  - not register iface_combination since now only one vif is allowed
>  - some fixes suggested by Stanislaw
>
>
> Yan-Hsuan Chuang (12):
>   rtw88: main files
>   rtw88: core files
>   rtw88: hci files
>   rtw88: trx files
>   rtw88: mac files
>   rtw88: fw and efuse files
>   rtw88: phy files
>   rtw88: debug files
>   rtw88: chip files
>   rtw88: 8822B init table
>   rtw88: 8822C init table
>   rtw88: Kconfig & Makefile
>
>  drivers/net/wireless/realtek/Kconfig   | 1 +
>  drivers/net/wireless/realtek/Makefile  | 1 +
>  drivers/net/wireless/realtek/rtw88/Kconfig |57 +
>  drivers/net/wireless/realtek/rtw88/Makefile|19 +
>  drivers/net/wireless/realtek/rtw88/debug.c |   652 +
>  drivers/net/wireless/realtek/rtw88/debug.h |45 +
>  drivers/net/wireless/realtek/rtw88/efuse.c |   150 +
>  drivers/net/wireless/realtek/rtw88/efuse.h |53 +
>  drivers/net/wireless/realtek/rtw88/fw.c|   638 +
>  drivers/net/wireless/realtek/rtw88/fw.h|   182 +
>  drivers/net/wireless/realtek/rtw88/hci.h   |   212 +
>  drivers/net/wireless/realtek/rtw88/mac.c   |  1045 +
>  drivers/net/wireless/realtek/rtw88/mac.h   |35 +
>  drivers/net/wireless/realtek/rtw88/mac80211.c  |   482 +
>  drivers/net/wireless/realtek/rtw88/main.c  |  1133 +
>  drivers/net/wireless/realtek/rtw88/main.h  |  1200 ++
>  drivers/net/wireless/realtek/rtw88/pci.c   |  1220 ++
>  drivers/net/wireless/realtek/rtw88/pci.h   |   228 +
>  drivers/net/wireless/realtek/rtw88/phy.c   |  1675 ++
>  drivers/net/wireless/realtek/rtw88/phy.h   |   125 +
>  drivers/net/wireless/realtek/rtw88/ps.c|   198 +
>  drivers/net/wireless/realtek/rtw88/ps.h|21 +
>  drivers/net/wireless/realtek/rtw88/reg.h   |   404 +
>  drivers/net/wireless/realtek/rtw88/regd.c  |   462 +
>  drivers/net/wireless/realtek/rtw88/regd.h  |40 +
>  drivers/net/wireless/realtek/rtw88/rtw8822b.c  |  1593 ++
>  drivers/net/wireless/realtek/rtw88/rtw8822b.h  |   271 +
>  .../net/wireless/realtek/rtw88/rtw8822b_table.c| 20783 
> +++
>  .../net/wireless/realtek/rtw88/rtw8822b_table.h|18 +
>  drivers/net/wireless/realtek/rtw88/rtw8822c.c  |  1170 ++
>  drivers/net/wireless/realtek/rtw88/rtw8822c.h  |   416 +
>  .../net/wireless/realtek/rtw88/rtw8822c_table.c|  4150 
>  .../net/wireless/realtek/rtw88/rtw8822c_table.h|16 +
>  drivers/net/wireless/realtek/rtw88/rx.c|   144 +
>  

Re: new mt76 usb crashes on device removal

2018-10-03 Thread Lorenzo Bianconi
>
> On Wed, Oct 03, 2018 at 04:09:06PM +0200, Lorenzo Bianconi wrote:
> > > It still crashes. You can not reproduce the problem ?
> > > It's 100% reproducible for me, when I unplug mt76x0u or mt76x2 device.
> >
> > Hi Stanislaw,
> >
> > any news about the latest patchset I sent to fix that issue?
>
> It fixed the problem, I thought you tested that by yourself.

Yes, I did. I would like to have even a confirmation from you. Thanks.

Regards,
Lorenzo

>
> Regards
> Stanislaw


Re: new mt76 usb crashes on device removal

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 04:09:06PM +0200, Lorenzo Bianconi wrote:
> > It still crashes. You can not reproduce the problem ?
> > It's 100% reproducible for me, when I unplug mt76x0u or mt76x2 device.
> 
> Hi Stanislaw,
> 
> any news about the latest patchset I sent to fix that issue?

It fixed the problem, I thought you tested that by yourself.

Regards
Stanislaw


Re: new mt76 usb crashes on device removal

2018-10-03 Thread Lorenzo Bianconi
> On Wed, Oct 03, 2018 at 11:15:37AM +0200, Lorenzo Bianconi wrote:
> > > After
> > > 
> > > b11e19694dc9 "mt76x0: add ieee80211_ops ops pointer to 
> > > mt76x0_alloc_device signature"
> > > 
> > > I have new crashs when remove mt76x0u and mt76x2u devices. 
> > > I can not provide calltrace because some other warning/traces
> > > show up instantly after the problem happen and mask prints
> > > for initall problem. Then the machine hungs.
> > > 
> > > Anyway bisection blame b11e19694dc9 commit and I confirm that problem
> > > not happen before this commit. I also applied the fix with I just
> > > posted, so this is diffrent issue.
> > 
> > Hi Stanislaw,
> > 
> > I do not know if it is related or not, but could you please try following 
> > patch:
> > 
> > Regards,
> > Lorenzo
> > 
> > --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
> > @@ -179,11 +179,11 @@ static int mt76x0u_register_device(struct mt76x0_dev 
> > *dev)
> > struct ieee80211_hw *hw = dev->mt76.hw;
> > int err;
> >  
> > -   err = mt76u_mcu_init_rx(>mt76);
> > +   err = mt76u_alloc_queues(>mt76);
> > if (err < 0)
> > return err;
> >  
> > -   err = mt76u_alloc_queues(>mt76);
> > +   err = mt76u_mcu_init_rx(>mt76);
> > if (err < 0)
> > return err;
> 
> It still crashes. You can not reproduce the problem ?
> It's 100% reproducible for me, when I unplug mt76x0u or mt76x2 device.

Hi Stanislaw,

any news about the latest patchset I sent to fix that issue?

Regards,
Lorenzo

> 
> Thanks
> Stanislaw


Re: [PATCH 06/10] mt76x2: move mt76x2_dev in mt76x02_util.h

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 03:51:32PM +0200, Felix Fietkau wrote:
> >> > }
> >> > 
> >> > put them into mt76xN_dev and still remove dupicated code ?
> >> Quite often, mt76_dev would be needed as well for register access, which 
> >> means extra parameters for a lot of functions.
> >> I think Lorenzo’s approach makes the code a lot more concise, and makes it 
> >> easier to share more code between mt76x0 and mt76x2.
> > 
> > I think this could be solved very easly by container_of() macro if
> > there will be one mt76x02_dev struct just after mt76_dev.
> That's possible, yes. But given how much code can still be unified
> between mt76x0 and mt76x2, I don't think there will be much need for a
> x0 or x2 specific device struct. And in that case, the code will be more
> readable if we avoid putting a lot of unnecessary >mt76x02 or
> container_of in the code.

Ok, I guess can live with mt76x02_dev :-)

Thanks
Stanislaw


Re: [PATCH 06/10] mt76x2: move mt76x2_dev in mt76x02_util.h

2018-10-03 Thread Felix Fietkau
On 2018-10-03 15:32, Stanislaw Gruszka wrote:
> On Wed, Oct 03, 2018 at 01:49:23PM +0200, Felix Fietkau wrote:
>> 
>> 
>> > On 3. Oct 2018, at 13:12, Stanislaw Gruszka  wrote:
>> > 
>> > On Wed, Oct 03, 2018 at 01:01:40PM +0200, Lorenzo Bianconi wrote:
>> >>> 
>> >>> On Tue, Oct 02, 2018 at 12:19:04AM +0200, Lorenzo Bianconi wrote:
>>  Move mt76x2_dev in mt76x02_util.h and rename it in mt76x02_dev
>>  in order to be shared between mt76x2 and mt76x0 driver
>> >>> 
>>  +struct mt76x02_dev {
>>  + struct mt76_dev mt76; /* must be first */
>>  +
>>  + struct mac_address macaddr_list[8];
>>  +
>>  + struct mutex mutex;
>>  +
>>  + u8 txdone_seq;
>>  + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
>>  +
>>  + struct sk_buff *rx_head;
>>  +
>>  + struct tasklet_struct tx_tasklet;
>>  + struct tasklet_struct pre_tbtt_tasklet;
>>  + struct delayed_work cal_work;
>>  + struct delayed_work mac_work;
>>  +
>>  + u32 aggr_stats[32];
>>  +
>>  + struct sk_buff *beacons[8];
>>  + u8 beacon_mask;
>>  + u8 beacon_data_mask;
>>  +
>>  + u8 tbtt_count;
>>  + u16 beacon_int;
>>  +
>>  + struct mt76x02_calibration cal;
>>  +
>>  + s8 target_power;
>>  + s8 target_power_delta[2];
>>  + bool enable_tpc;
>>  +
>>  + u8 coverage_class;
>>  + u8 slottime;
>>  +
>>  + struct mt76x02_dfs_pattern_detector dfs_pd;
>>  +};
>>  +
>> >>> 
>>  static bool
>>  -mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
>>  +mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
>> >>> 
>> >>> I don't think this is right approach. I would rather prefer to have
>> >>> common data structures embeded in mt76x2_dev and mt76x0_dev
>> >>> structures to have chip sepcific fields/data separated.
>> >>> 
>> >> 
>> >> The reason of this patch is that mt76x0_dev fields are already in 
>> >> mt76x2_dev
>> >> so I guess there is no need to have different structures. Moreover in
>> >> this way we can
>> >> remove a lot of duplicated code between mt76x0 and mt76x2 drivers.
>> > 
>> > But you can still create additional structures i.e.
>> > 
>> > mt76x02_power {
>> >s8 target_power;
>> >s8 target_power_delta[2];
>> >bool enable_tpc;
>> > }
>> > 
>> > mt76x02_conf {
>> >u8 coverage_class;
>> > u8 slottime;
>> > }
>> > 
>> > put them into mt76xN_dev and still remove dupicated code ?
>> Quite often, mt76_dev would be needed as well for register access, which 
>> means extra parameters for a lot of functions.
>> I think Lorenzo’s approach makes the code a lot more concise, and makes it 
>> easier to share more code between mt76x0 and mt76x2.
> 
> I think this could be solved very easly by container_of() macro if
> there will be one mt76x02_dev struct just after mt76_dev.
That's possible, yes. But given how much code can still be unified
between mt76x0 and mt76x2, I don't think there will be much need for a
x0 or x2 specific device struct. And in that case, the code will be more
readable if we avoid putting a lot of unnecessary >mt76x02 or
container_of in the code.

- Felix


Re: [PATCH 06/10] mt76x2: move mt76x2_dev in mt76x02_util.h

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 01:49:23PM +0200, Felix Fietkau wrote:
> 
> 
> > On 3. Oct 2018, at 13:12, Stanislaw Gruszka  wrote:
> > 
> > On Wed, Oct 03, 2018 at 01:01:40PM +0200, Lorenzo Bianconi wrote:
> >>> 
> >>> On Tue, Oct 02, 2018 at 12:19:04AM +0200, Lorenzo Bianconi wrote:
>  Move mt76x2_dev in mt76x02_util.h and rename it in mt76x02_dev
>  in order to be shared between mt76x2 and mt76x0 driver
> >>> 
>  +struct mt76x02_dev {
>  + struct mt76_dev mt76; /* must be first */
>  +
>  + struct mac_address macaddr_list[8];
>  +
>  + struct mutex mutex;
>  +
>  + u8 txdone_seq;
>  + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
>  +
>  + struct sk_buff *rx_head;
>  +
>  + struct tasklet_struct tx_tasklet;
>  + struct tasklet_struct pre_tbtt_tasklet;
>  + struct delayed_work cal_work;
>  + struct delayed_work mac_work;
>  +
>  + u32 aggr_stats[32];
>  +
>  + struct sk_buff *beacons[8];
>  + u8 beacon_mask;
>  + u8 beacon_data_mask;
>  +
>  + u8 tbtt_count;
>  + u16 beacon_int;
>  +
>  + struct mt76x02_calibration cal;
>  +
>  + s8 target_power;
>  + s8 target_power_delta[2];
>  + bool enable_tpc;
>  +
>  + u8 coverage_class;
>  + u8 slottime;
>  +
>  + struct mt76x02_dfs_pattern_detector dfs_pd;
>  +};
>  +
> >>> 
>  static bool
>  -mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
>  +mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
> >>> 
> >>> I don't think this is right approach. I would rather prefer to have
> >>> common data structures embeded in mt76x2_dev and mt76x0_dev
> >>> structures to have chip sepcific fields/data separated.
> >>> 
> >> 
> >> The reason of this patch is that mt76x0_dev fields are already in 
> >> mt76x2_dev
> >> so I guess there is no need to have different structures. Moreover in
> >> this way we can
> >> remove a lot of duplicated code between mt76x0 and mt76x2 drivers.
> > 
> > But you can still create additional structures i.e.
> > 
> > mt76x02_power {
> >s8 target_power;
> >s8 target_power_delta[2];
> >bool enable_tpc;
> > }
> > 
> > mt76x02_conf {
> >u8 coverage_class;
> > u8 slottime;
> > }
> > 
> > put them into mt76xN_dev and still remove dupicated code ?
> Quite often, mt76_dev would be needed as well for register access, which 
> means extra parameters for a lot of functions.
> I think Lorenzo’s approach makes the code a lot more concise, and makes it 
> easier to share more code between mt76x0 and mt76x2.

I think this could be solved very easly by container_of() macro if
there will be one mt76x02_dev struct just after mt76_dev.

Regerds
Stanislaw


Re: [PATCH 06/10] mt76x2: move mt76x2_dev in mt76x02_util.h

2018-10-03 Thread Felix Fietkau



> On 3. Oct 2018, at 13:12, Stanislaw Gruszka  wrote:
> 
> On Wed, Oct 03, 2018 at 01:01:40PM +0200, Lorenzo Bianconi wrote:
>>> 
>>> On Tue, Oct 02, 2018 at 12:19:04AM +0200, Lorenzo Bianconi wrote:
 Move mt76x2_dev in mt76x02_util.h and rename it in mt76x02_dev
 in order to be shared between mt76x2 and mt76x0 driver
>>> 
 +struct mt76x02_dev {
 + struct mt76_dev mt76; /* must be first */
 +
 + struct mac_address macaddr_list[8];
 +
 + struct mutex mutex;
 +
 + u8 txdone_seq;
 + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
 +
 + struct sk_buff *rx_head;
 +
 + struct tasklet_struct tx_tasklet;
 + struct tasklet_struct pre_tbtt_tasklet;
 + struct delayed_work cal_work;
 + struct delayed_work mac_work;
 +
 + u32 aggr_stats[32];
 +
 + struct sk_buff *beacons[8];
 + u8 beacon_mask;
 + u8 beacon_data_mask;
 +
 + u8 tbtt_count;
 + u16 beacon_int;
 +
 + struct mt76x02_calibration cal;
 +
 + s8 target_power;
 + s8 target_power_delta[2];
 + bool enable_tpc;
 +
 + u8 coverage_class;
 + u8 slottime;
 +
 + struct mt76x02_dfs_pattern_detector dfs_pd;
 +};
 +
>>> 
 static bool
 -mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
 +mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
>>> 
>>> I don't think this is right approach. I would rather prefer to have
>>> common data structures embeded in mt76x2_dev and mt76x0_dev
>>> structures to have chip sepcific fields/data separated.
>>> 
>> 
>> The reason of this patch is that mt76x0_dev fields are already in mt76x2_dev
>> so I guess there is no need to have different structures. Moreover in
>> this way we can
>> remove a lot of duplicated code between mt76x0 and mt76x2 drivers.
> 
> But you can still create additional structures i.e.
> 
> mt76x02_power {
>s8 target_power;
>s8 target_power_delta[2];
>bool enable_tpc;
> }
> 
> mt76x02_conf {
>u8 coverage_class;
> u8 slottime;
> }
> 
> put them into mt76xN_dev and still remove dupicated code ?
Quite often, mt76_dev would be needed as well for register access, which means 
extra parameters for a lot of functions.
I think Lorenzo’s approach makes the code a lot more concise, and makes it 
easier to share more code between mt76x0 and mt76x2.

- Felix


[RFC v3 09/12] rtw88: chip files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

chip files Realtek 802.11ac wireless network chips
8822B & 8822C series files

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/rtw8822b.c  | 1593 
 drivers/net/wireless/realtek/rtw88/rtw8822b.h  |  271 
 .../net/wireless/realtek/rtw88/rtw8822b_table.h|   18 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c  | 1170 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.h  |  416 +
 .../net/wireless/realtek/rtw88/rtw8822c_table.h|   16 +
 6 files changed, 3484 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b_table.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c_table.h

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c 
b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
new file mode 100644
index 000..f051075
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -0,0 +1,1593 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "fw.h"
+#include "tx.h"
+#include "rx.h"
+#include "phy.h"
+#include "rtw8822b.h"
+#include "rtw8822b_table.h"
+#include "mac.h"
+#include "reg.h"
+#include "debug.h"
+
+static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
+u8 rx_path, bool is_tx2_path);
+
+static void rtw8822be_efuse_parsing(struct rtw_efuse *efuse,
+   struct rtw8822b_efuse *map)
+{
+   ether_addr_copy(efuse->addr, map->e.mac_addr);
+}
+
+static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+   struct rtw_efuse *efuse = >efuse;
+   struct rtw8822b_efuse *map;
+   int i;
+
+   map = (struct rtw8822b_efuse *)log_map;
+
+   efuse->rfe_option = map->rfe_option;
+   efuse->crystal_cap = map->xtal_k;
+   efuse->pa_type_2g = map->pa_type;
+   efuse->pa_type_5g = map->pa_type;
+   efuse->lna_type_2g = map->lna_type_2g[0];
+   efuse->lna_type_5g = map->lna_type_5g[0];
+   efuse->channel_plan = map->channel_plan;
+   efuse->bt_setting = map->rf_bt_setting;
+   efuse->regd = map->rf_board_option & 0x7;
+
+   for (i = 0; i < 4; i++)
+   efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
+
+   switch (rtw_hci_type(rtwdev)) {
+   case RTW_HCI_TYPE_PCIE:
+   rtw8822be_efuse_parsing(efuse, map);
+   break;
+   default:
+   /* unsupported now */
+   return -ENOTSUPP;
+   }
+
+   return 0;
+}
+
+static void rtw8822b_phy_rfe_init(struct rtw_dev *rtwdev)
+{
+   /* chip top mux */
+   rtw_write32_mask(rtwdev, 0x64, BIT(29) | BIT(28), 0x3);
+   rtw_write32_mask(rtwdev, 0x4c, BIT(26) | BIT(25), 0x0);
+   rtw_write32_mask(rtwdev, 0x40, BIT(2), 0x1);
+
+   /* from s0 or s1 */
+   rtw_write32_mask(rtwdev, 0x1990, 0x3f, 0x30);
+   rtw_write32_mask(rtwdev, 0x1990, (BIT(11) | BIT(10)), 0x3);
+
+   /* input or output */
+   rtw_write32_mask(rtwdev, 0x974, 0x3f, 0x3f);
+   rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3);
+}
+
+static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev)
+{
+   struct rtw_hal *hal = >hal;
+   u8 crystal_cap;
+   bool is_tx2_path;
+
+   /* power on BB/RF domain */
+   rtw_write8_set(rtwdev, REG_SYS_FUNC_EN,
+  BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
+   rtw_write8_set(rtwdev, REG_RF_CTRL,
+  BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
+   rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN);
+
+   /* pre init before header files config */
+   rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+
+   rtw_phy_load_tables(rtwdev);
+
+   crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
+   rtw_write32_mask(rtwdev, 0x24, 0x7e00, crystal_cap);
+   rtw_write32_mask(rtwdev, 0x28, 0x7e, crystal_cap);
+
+   /* post init after header files config */
+   rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+
+   is_tx2_path = false;
+   rtw8822b_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx,
+is_tx2_path);
+   rtw_phy_init(rtwdev);
+
+   rtw8822b_phy_rfe_init(rtwdev);
+
+   /* wifi path controller */
+   rtw_write32_mask(rtwdev, 0x70, 0x400, 1);
+   /* BB control */
+   rtw_write32_mask(rtwdev, 0x4c, 0x0180, 0x2);
+   /* antenna mux switch */
+   rtw_write8(rtwdev, 0x974, 0xff);
+   rtw_write32_mask(rtwdev, 0x1990, 0x300, 0);
+   rtw_write32_mask(rtwdev, 0xcbc, 0x8, 0x0);
+   /* SW control */
+   rtw_write8(rtwdev, 0xcb4, 

[RFC v3 08/12] rtw88: debug files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

debug files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/debug.c | 652 +
 drivers/net/wireless/realtek/rtw88/debug.h |  45 ++
 2 files changed, 697 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/debug.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/debug.h

diff --git a/drivers/net/wireless/realtek/rtw88/debug.c 
b/drivers/net/wireless/realtek/rtw88/debug.c
new file mode 100644
index 000..e00c602
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -0,0 +1,652 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include 
+#include 
+#include "main.h"
+#include "sec.h"
+#include "fw.h"
+#include "debug.h"
+
+#ifdef CONFIG_RTW88_DEBUGFS
+
+struct rtw_debugfs_priv {
+   struct rtw_dev *rtwdev;
+   int (*cb_read)(struct seq_file *m, void *v);
+   ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
+   size_t count, loff_t *loff);
+   union {
+   u32 cb_data;
+   u8 *buf;
+   struct {
+   u32 page_offset;
+   u32 page_num;
+   } rsvd_page;
+   struct {
+   u8 rf_path;
+   u32 rf_addr;
+   u32 rf_mask;
+   };
+   struct {
+   u32 addr;
+   u32 len;
+   } read_reg;
+   };
+};
+
+static int rtw_debugfs_single_show(struct seq_file *m, void *v)
+{
+   struct rtw_debugfs_priv *debugfs_priv = m->private;
+
+   return debugfs_priv->cb_read(m, v);
+}
+
+static ssize_t rtw_debugfs_common_write(struct file *filp,
+   const char __user *buffer,
+   size_t count, loff_t *loff)
+{
+   struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
+
+   return debugfs_priv->cb_write(filp, buffer, count, loff);
+}
+
+static ssize_t rtw_debugfs_single_write(struct file *filp,
+   const char __user *buffer,
+   size_t count, loff_t *loff)
+{
+   struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
+   struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
+
+   return debugfs_priv->cb_write(filp, buffer, count, loff);
+}
+
+static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp)
+{
+   return single_open(filp, rtw_debugfs_single_show, inode->i_private);
+}
+
+static int rtw_debugfs_close(struct inode *inode, struct file *filp)
+{
+   return 0;
+}
+
+static const struct file_operations file_ops_single_r = {
+   .owner = THIS_MODULE,
+   .open = rtw_debugfs_single_open_rw,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = seq_release,
+};
+
+static const struct file_operations file_ops_single_rw = {
+   .owner = THIS_MODULE,
+   .open = rtw_debugfs_single_open_rw,
+   .release = single_release,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .write = rtw_debugfs_single_write,
+};
+
+static const struct file_operations file_ops_common_write = {
+   .owner = THIS_MODULE,
+   .write = rtw_debugfs_common_write,
+   .open = simple_open,
+   .release = rtw_debugfs_close,
+};
+
+static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v)
+{
+   struct rtw_debugfs_priv *debugfs_priv = m->private;
+   struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+   u32 val, len, addr;
+
+   len = debugfs_priv->read_reg.len;
+   addr = debugfs_priv->read_reg.addr;
+   switch (len) {
+   case 1:
+   val = rtw_read8(rtwdev, addr);
+   seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val);
+   break;
+   case 2:
+   val = rtw_read16(rtwdev, addr);
+   seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val);
+   break;
+   case 4:
+   val = rtw_read32(rtwdev, addr);
+   seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val);
+   break;
+   }
+   return 0;
+}
+
+static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)
+{
+   struct rtw_debugfs_priv *debugfs_priv = m->private;
+   struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+   u32 val, addr, mask;
+   u8 path;
+
+   path = debugfs_priv->rf_path;
+   addr = debugfs_priv->rf_addr;
+   mask = debugfs_priv->rf_mask;
+
+   val = rtw_read_rf(rtwdev, path, addr, mask);
+
+   seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
+  path, addr, mask, val);
+
+   return 0;
+}
+
+static int rtw_debugfs_copy_from_user(char tmp[], int size,
+ const char __user *buffer, size_t count,
+   

[RFC v3 03/12] rtw88: hci files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

hci files for Realtek 802.11ac wireless network chips

For now there is only PCI bus supported by rtwlan, in the future it
will also have USB/SDIO

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/hci.h |  212 ++
 drivers/net/wireless/realtek/rtw88/pci.c | 1220 ++
 drivers/net/wireless/realtek/rtw88/pci.h |  228 ++
 3 files changed, 1660 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/hci.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/pci.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/pci.h

diff --git a/drivers/net/wireless/realtek/rtw88/hci.h 
b/drivers/net/wireless/realtek/rtw88/hci.h
new file mode 100644
index 000..e1f200b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/hci.h
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#ifndef__RTW_HCI_H__
+#define __RTW_HCI_H__
+
+/* ops for PCI, USB and SDIO */
+struct rtw_hci_ops {
+   int (*tx)(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ struct sk_buff *skb);
+   int (*setup)(struct rtw_dev *rtwdev);
+   int (*start)(struct rtw_dev *rtwdev);
+   void (*stop)(struct rtw_dev *rtwdev);
+
+   int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
+   int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
+
+   u8 (*read8)(struct rtw_dev *rtwdev, u32 addr);
+   u16 (*read16)(struct rtw_dev *rtwdev, u32 addr);
+   u32 (*read32)(struct rtw_dev *rtwdev, u32 addr);
+   void (*write8)(struct rtw_dev *rtwdev, u32 addr, u8 val);
+   void (*write16)(struct rtw_dev *rtwdev, u32 addr, u16 val);
+   void (*write32)(struct rtw_dev *rtwdev, u32 addr, u32 val);
+   int (*check_avail_desc)(struct rtw_dev *rtwdev, struct sk_buff *skb);
+};
+
+static inline int rtw_hci_tx(struct rtw_dev *rtwdev,
+struct rtw_tx_pkt_info *pkt_info,
+struct sk_buff *skb)
+{
+   return rtwdev->hci.ops->tx(rtwdev, pkt_info, skb);
+}
+
+static inline int rtw_hci_setup(struct rtw_dev *rtwdev)
+{
+   return rtwdev->hci.ops->setup(rtwdev);
+}
+
+static inline int rtw_hci_start(struct rtw_dev *rtwdev)
+{
+   return rtwdev->hci.ops->start(rtwdev);
+}
+
+static inline void rtw_hci_stop(struct rtw_dev *rtwdev)
+{
+   rtwdev->hci.ops->stop(rtwdev);
+}
+
+static inline int
+rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
+{
+   return rtwdev->hci.ops->write_data_rsvd_page(rtwdev, buf, size);
+}
+
+static inline int
+rtw_hci_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
+{
+   return rtwdev->hci.ops->write_data_h2c(rtwdev, buf, size);
+}
+
+static inline u8 rtw_read8(struct rtw_dev *rtwdev, u32 addr)
+{
+   return rtwdev->hci.ops->read8(rtwdev, addr);
+}
+
+static inline u16 rtw_read16(struct rtw_dev *rtwdev, u32 addr)
+{
+   return rtwdev->hci.ops->read16(rtwdev, addr);
+}
+
+static inline u32 rtw_read32(struct rtw_dev *rtwdev, u32 addr)
+{
+   return rtwdev->hci.ops->read32(rtwdev, addr);
+}
+
+static inline void rtw_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
+{
+   rtwdev->hci.ops->write8(rtwdev, addr, val);
+}
+
+static inline void rtw_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
+{
+   rtwdev->hci.ops->write16(rtwdev, addr, val);
+}
+
+static inline void rtw_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
+{
+   rtwdev->hci.ops->write32(rtwdev, addr, val);
+}
+
+static inline void rtw_write8_set(struct rtw_dev *rtwdev, u32 addr, u8 bit)
+{
+   u8 val;
+
+   val = rtw_read8(rtwdev, addr);
+   rtw_write8(rtwdev, addr, val | bit);
+}
+
+static inline void rtw_writ16_set(struct rtw_dev *rtwdev, u32 addr, u16 bit)
+{
+   u16 val;
+
+   val = rtw_read16(rtwdev, addr);
+   rtw_write16(rtwdev, addr, val | bit);
+}
+
+static inline void rtw_write32_set(struct rtw_dev *rtwdev, u32 addr, u32 bit)
+{
+   u32 val;
+
+   val = rtw_read32(rtwdev, addr);
+   rtw_write32(rtwdev, addr, val | bit);
+}
+
+static inline void rtw_write8_clr(struct rtw_dev *rtwdev, u32 addr, u8 bit)
+{
+   u8 val;
+
+   val = rtw_read8(rtwdev, addr);
+   rtw_write8(rtwdev, addr, val & ~bit);
+}
+
+static inline void rtw_write16_clr(struct rtw_dev *rtwdev, u32 addr, u16 bit)
+{
+   u16 val;
+
+   val = rtw_read16(rtwdev, addr);
+   rtw_write16(rtwdev, addr, val & ~bit);
+}
+
+static inline void rtw_write32_clr(struct rtw_dev *rtwdev, u32 addr, u32 bit)
+{
+   u32 val;
+
+   val = rtw_read32(rtwdev, addr);
+   rtw_write32(rtwdev, addr, val & ~bit);
+}
+
+static inline u32
+rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
+   u32 addr, u32 mask)
+{
+   unsigned long flags;
+   u32 val;
+
+   spin_lock_irqsave(>rf_lock, flags);
+   val = 

[RFC v3 04/12] rtw88: trx files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

trx files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/rx.c | 144 +
 drivers/net/wireless/realtek/rtw88/rx.h |  30 
 drivers/net/wireless/realtek/rtw88/tx.c | 271 
 drivers/net/wireless/realtek/rtw88/tx.h |  81 ++
 4 files changed, 526 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rx.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rx.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/tx.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/tx.h

diff --git a/drivers/net/wireless/realtek/rtw88/rx.c 
b/drivers/net/wireless/realtek/rtw88/rx.c
new file mode 100644
index 000..83214db
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rx.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "rx.h"
+#include "ps.h"
+
+void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
+ struct sk_buff *skb)
+{
+   struct ieee80211_hdr *hdr;
+   struct rtw_vif *rtwvif;
+
+   hdr = (struct ieee80211_hdr *)skb->data;
+
+   if (!ieee80211_is_data(hdr->frame_control))
+   return;
+
+   if (!is_broadcast_ether_addr(hdr->addr1) &&
+   !is_multicast_ether_addr(hdr->addr1)) {
+   rtwdev->stats.rx_unicast += skb->len;
+   rtwdev->stats.rx_cnt++;
+   if (vif) {
+   rtwvif = (struct rtw_vif *)vif->drv_priv;
+   rtwvif->stats.rx_unicast += skb->len;
+   rtwvif->stats.rx_cnt++;
+   if (rtwvif->stats.rx_cnt > RTW_LPS_THRESHOLD)
+   rtw_leave_lps_irqsafe(rtwdev, rtwvif);
+   }
+   }
+}
+EXPORT_SYMBOL(rtw_rx_stats);
+
+static void rtw_rx_rssi_add(struct rtw_dev *rtwdev,
+   struct rtw_rx_pkt_stat *pkt_stat,
+   struct ieee80211_hdr *hdr)
+{
+   struct ieee80211_vif *vif;
+   struct rtw_vif *rtwvif;
+   struct rtw_sta_info *si;
+   __le16 fc = hdr->frame_control;
+   u8 *bssid;
+   u8 macid = RTW_BC_MC_MACID;
+   bool match_bssid = false;
+   bool is_packet_match_bssid;
+   bool if_addr_match;
+   bool hw_err;
+   bool ctl;
+
+   rcu_read_lock();
+
+   bssid = get_hdr_bssid(hdr);
+   rtwvif = get_hdr_vif(rtwdev, hdr);
+   vif = rtwvif ? rtwvif->vif : NULL;
+   pkt_stat->vif = vif;
+   if (unlikely(is_broadcast_ether_addr(hdr->addr1) ||
+is_multicast_ether_addr(hdr->addr1)))
+   match_bssid = get_hdr_match_bssid(rtwdev, hdr, bssid);
+   else if (vif)
+   match_bssid = ether_addr_equal(vif->bss_conf.bssid, bssid);
+   si = get_hdr_sta(rtwdev, vif, hdr);
+   macid = si ? si->mac_id : RTW_BC_MC_MACID;
+   pkt_stat->mac_id = macid;
+   pkt_stat->si = si;
+
+   if_addr_match = !!vif;
+   hw_err = pkt_stat->crc_err || pkt_stat->icv_err;
+   ctl = ieee80211_is_ctl(fc);
+   is_packet_match_bssid = !hw_err && !ctl && match_bssid;
+
+   if (((match_bssid && if_addr_match) || ieee80211_is_beacon(fc)) &&
+   (!hw_err && !ctl) && (pkt_stat->phy_status && pkt_stat->si))
+   ewma_rssi_add(_stat->si->avg_rssi, pkt_stat->rssi);
+
+   rcu_read_unlock();
+}
+
+void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
+  struct rtw_rx_pkt_stat *pkt_stat,
+  struct ieee80211_hdr *hdr,
+  struct ieee80211_rx_status *rx_status,
+  u8 *phy_status)
+{
+   struct ieee80211_hw *hw = rtwdev->hw;
+
+   memset(rx_status, 0, sizeof(*rx_status));
+   rx_status->freq = hw->conf.chandef.chan->center_freq;
+   rx_status->band = hw->conf.chandef.chan->band;
+   if (pkt_stat->crc_err)
+   rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+   if (pkt_stat->decrypted)
+   rx_status->flag |= RX_FLAG_DECRYPTED;
+
+   if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0)
+   rx_status->encoding = RX_ENC_VHT;
+   else if (pkt_stat->rate >= DESC_RATEMCS0)
+   rx_status->encoding = RX_ENC_HT;
+
+   if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0 &&
+   pkt_stat->rate <= DESC_RATEVHT1SS_MCS9) {
+   rx_status->nss = 1;
+   rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT1SS_MCS0;
+   } else if (pkt_stat->rate >= DESC_RATEVHT2SS_MCS0 &&
+  pkt_stat->rate <= DESC_RATEVHT2SS_MCS9) {
+   rx_status->nss = 2;
+   rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT2SS_MCS0;
+   } else if (pkt_stat->rate >= DESC_RATEVHT3SS_MCS0 &&
+  pkt_stat->rate <= DESC_RATEVHT3SS_MCS9) {
+   rx_status->nss = 3;
+

[RFC v3 00/12] rtw88: mac80211 driver for Realtek 802.11ac wireless network chips

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

This is a new mac80211 driver for Realtek 802.11ac wireless network chips.
rtwlan supports 8822BE and 8822CE chips, and will be able to support
multi-vif combinations in run-time.

For now, only PCI bus is supported, but rtwlan was originally designed
to optionally support three buses includes USB & SDIO. USB & SDIO modules
will soon be supported by rtwlan, with configurable core module to fit
with different bus modules in the same time.

For example, if we choose 8822BE and 8822CU, only PCI & USB modules will
be selected, built, loaded into kernel. This is one of the major
difference from rtlwifi, which can only support specific combinations.

Another difference from rtlwifi is that rtwlan is designed to support
the latest Realtek 802.11ac wireless network chips like 8822B and
8822C series. Compared to the earlier chips supported by rtlwifi like
the 802.11n 8192EE chipset or 802.11ac 8821AE/8812AE chips, newer ICs
have different MAC & PHY settings, such as new multi-port feature for the
MAC layer design and Jaguar2/Jaguar3 PHY layer IPs.

Multi-Port feature is also supported under rtwlan's software architecture.
rtlwifi can only support one vif in the same time, most because of the
hardware limitations for early chips, hence the original design of it
also restricts the usage of multi-vif support, so latest chipset seems not
take advantages from its new MAC engine.

However, rtwlan can run multiple vifs concurrently by holding them on
hardware ports provided by MAC engine, hence can easily start different
roles on a single device.

Based on the reasons mentioned before, we implemented rtwlan. It had many
authors, they are listed here alphabetically:

Ping-Ke Shih 
Tzu-En Huang 
Yan-Hsuan Chuang 


v3

 - missing rcu list traverse for vif_list

v2

 - rename from rtwlan to rtw88
 - remove lots of magic numbers
 - add pci null entry for auto load on boot
 - add rtwdev->mutex to protect against mac80211 callbacks
 - add rcu lock protection for vif_list and sta_list
 - refine bits & endian macros to use helper functions provided by kernel
   instead of create new ones
 - ieee80211_free_txskb for tx path dropped packets
 - not register iface_combination since now only one vif is allowed
 - some fixes suggested by Stanislaw

Yan-Hsuan Chuang (12):
  rtw88: main files
  rtw88: core files
  rtw88: hci files
  rtw88: trx files
  rtw88: mac files
  rtw88: fw and efuse files
  rtw88: phy files
  rtw88: debug files
  rtw88: chip files
  rtw88: 8822B init table
  rtw88: 8822C init table
  rtw88: Kconfig & Makefile

 drivers/net/wireless/realtek/Kconfig   | 1 +
 drivers/net/wireless/realtek/Makefile  | 1 +
 drivers/net/wireless/realtek/rtw88/Kconfig |57 +
 drivers/net/wireless/realtek/rtw88/Makefile|19 +
 drivers/net/wireless/realtek/rtw88/debug.c |   652 +
 drivers/net/wireless/realtek/rtw88/debug.h |45 +
 drivers/net/wireless/realtek/rtw88/efuse.c |   150 +
 drivers/net/wireless/realtek/rtw88/efuse.h |53 +
 drivers/net/wireless/realtek/rtw88/fw.c|   638 +
 drivers/net/wireless/realtek/rtw88/fw.h|   182 +
 drivers/net/wireless/realtek/rtw88/hci.h   |   212 +
 drivers/net/wireless/realtek/rtw88/mac.c   |  1045 +
 drivers/net/wireless/realtek/rtw88/mac.h   |35 +
 drivers/net/wireless/realtek/rtw88/mac80211.c  |   482 +
 drivers/net/wireless/realtek/rtw88/main.c  |  1133 +
 drivers/net/wireless/realtek/rtw88/main.h  |  1200 ++
 drivers/net/wireless/realtek/rtw88/pci.c   |  1220 ++
 drivers/net/wireless/realtek/rtw88/pci.h   |   228 +
 drivers/net/wireless/realtek/rtw88/phy.c   |  1675 ++
 drivers/net/wireless/realtek/rtw88/phy.h   |   125 +
 drivers/net/wireless/realtek/rtw88/ps.c|   198 +
 drivers/net/wireless/realtek/rtw88/ps.h|21 +
 drivers/net/wireless/realtek/rtw88/reg.h   |   404 +
 drivers/net/wireless/realtek/rtw88/regd.c  |   462 +
 drivers/net/wireless/realtek/rtw88/regd.h  |40 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c  |  1593 ++
 drivers/net/wireless/realtek/rtw88/rtw8822b.h  |   271 +
 .../net/wireless/realtek/rtw88/rtw8822b_table.c| 20783 +++
 .../net/wireless/realtek/rtw88/rtw8822b_table.h|18 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c  |  1170 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.h  |   416 +
 .../net/wireless/realtek/rtw88/rtw8822c_table.c|  4150 
 .../net/wireless/realtek/rtw88/rtw8822c_table.h|16 +
 drivers/net/wireless/realtek/rtw88/rx.c|   144 +
 drivers/net/wireless/realtek/rtw88/rx.h|30 +
 drivers/net/wireless/realtek/rtw88/sec.c   |   135 +
 drivers/net/wireless/realtek/rtw88/sec.h   |40 +
 drivers/net/wireless/realtek/rtw88/tx.c|   271 +
 drivers/net/wireless/realtek/rtw88/tx.h

[RFC v3 05/12] rtw88: mac files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

mac files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/mac.c | 1045 ++
 drivers/net/wireless/realtek/rtw88/mac.h |   35 +
 2 files changed, 1080 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/mac.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/mac.h

diff --git a/drivers/net/wireless/realtek/rtw88/mac.c 
b/drivers/net/wireless/realtek/rtw88/mac.c
new file mode 100644
index 000..f960890
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -0,0 +1,1045 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "mac.h"
+#include "reg.h"
+#include "fw.h"
+#include "debug.h"
+
+void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+u8 primary_ch_idx)
+{
+   u8 txsc40 = 0, txsc20 = 0;
+   u32 value32;
+   u8 value8;
+
+   txsc20 = primary_ch_idx;
+   if (txsc20 == 1 || txsc20 == 3)
+   txsc40 = 9;
+   else
+   txsc40 = 10;
+   rtw_write8(rtwdev, REG_DATA_SC,
+  BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40));
+
+   value32 = rtw_read32(rtwdev, REG_WMAC_TRXPTCL_CTL);
+   value32 &= ~BIT_RFMOD;
+   switch (bw) {
+   case RTW_CHANNEL_WIDTH_80:
+   value32 |= BIT_RFMOD_80M;
+   break;
+   case RTW_CHANNEL_WIDTH_40:
+   value32 |= BIT_RFMOD_40M;
+   break;
+   case RTW_CHANNEL_WIDTH_20:
+   default:
+   break;
+   }
+   rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32);
+
+   value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL);
+   value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
+   rtw_write32(rtwdev, REG_AFE_CTRL1, value32);
+
+   rtw_write8(rtwdev, REG_USTIME_TSF, MAC_CLK_SPEED);
+   rtw_write8(rtwdev, REG_USTIME_EDCA, MAC_CLK_SPEED);
+
+   value8 = rtw_read8(rtwdev, REG_CCK_CHECK);
+   value8 = value8 & ~BIT_CHECK_CCK_EN;
+   if (channel > 35)
+   value8 |= BIT_CHECK_CCK_EN;
+   rtw_write8(rtwdev, REG_CCK_CHECK, value8);
+}
+
+static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
+{
+   u32 value32;
+   u8 value8;
+
+   rtw_write8(rtwdev, REG_RSV_CTRL, 0);
+
+   switch (rtw_hci_type(rtwdev)) {
+   case RTW_HCI_TYPE_PCIE:
+   rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN);
+   break;
+   case RTW_HCI_TYPE_USB:
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   /* config PIN Mux */
+   value32 = rtw_read32(rtwdev, REG_PAD_CTRL1);
+   value32 |= BIT_PAPE_WLBT_SEL | BIT_LNAON_WLBT_SEL;
+   rtw_write32_set(rtwdev, REG_PAD_CTRL1, value32);
+
+   value32 = rtw_read32(rtwdev, REG_LED_CFG);
+   value32 &= ~(BIT_PAPE_SEL_EN | BIT_LNAON_SEL_EN);
+   rtw_write32(rtwdev, REG_LED_CFG, value32);
+
+   value32 = rtw_read32(rtwdev, REG_GPIO_MUXCFG);
+   value32 |= BIT_WLRFE_4_5_EN;
+   rtw_write32(rtwdev, REG_GPIO_MUXCFG, value32);
+
+   /* disable BB/RF */
+   value8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
+   value8 &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
+   rtw_write8(rtwdev, REG_SYS_FUNC_EN, value8);
+
+   value8 = rtw_read8(rtwdev, REG_RF_CTRL);
+   value8 &= ~(BIT_RF_SDM_RSTB | BIT_RF_RSTB | BIT_RF_EN);
+   rtw_write8(rtwdev, REG_RF_CTRL, value8);
+
+   value32 = rtw_read32(rtwdev, REG_WLRF1);
+   value32 &= ~BIT_WLRF1_BBRF_EN;
+   rtw_write32(rtwdev, REG_WLRF1, value32);
+
+   return 0;
+}
+
+static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev,
+  struct rtw_pwr_seq_cmd *cmd)
+{
+   u8 value;
+   u8 flag = 0;
+   u32 offset;
+   u32 cnt = RTW_PWR_POLLING_CNT;
+
+   if (cmd->base == RTW_PWR_ADDR_SDIO)
+   offset = cmd->offset | SDIO_LOCAL_OFFSET;
+   else
+   offset = cmd->offset;
+
+   do {
+   cnt--;
+   value = rtw_read8(rtwdev, offset);
+   value &= cmd->mask;
+   if (value == (cmd->value & cmd->mask))
+   return 0;
+   if (cnt == 0) {
+   if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE &&
+   flag == 0) {
+   value = rtw_read8(rtwdev, REG_SYS_PW_CTRL);
+   value |= BIT(3);
+   rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+   value &= ~BIT(3);
+   rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+   cnt = RTW_PWR_POLLING_CNT;
+   flag = 1;
+   } else {
+   return -EBUSY;
+   }
+

[RFC v3 02/12] rtw88: core files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

core files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/ps.c   | 198 +
 drivers/net/wireless/realtek/rtw88/ps.h   |  21 ++
 drivers/net/wireless/realtek/rtw88/regd.c | 462 ++
 drivers/net/wireless/realtek/rtw88/regd.h |  40 +++
 drivers/net/wireless/realtek/rtw88/sec.c  | 135 +
 drivers/net/wireless/realtek/rtw88/sec.h  |  40 +++
 6 files changed, 896 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/ps.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/ps.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/regd.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/regd.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/sec.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/sec.h

diff --git a/drivers/net/wireless/realtek/rtw88/ps.c 
b/drivers/net/wireless/realtek/rtw88/ps.c
new file mode 100644
index 000..549c4f4
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/ps.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "fw.h"
+#include "ps.h"
+#include "mac.h"
+#include "debug.h"
+
+static int rtw_ips_pwr_up(struct rtw_dev *rtwdev)
+{
+   int ret;
+
+   ret = rtw_core_start(rtwdev);
+   if (ret)
+   rtw_err(rtwdev, "leave idle state failed\n");
+
+   rtw_flag_clear(rtwdev, RTW_FLAG_INACTIVE_PS);
+
+   return ret;
+}
+
+int rtw_enter_ips(struct rtw_dev *rtwdev)
+{
+   rtw_flag_set(rtwdev, RTW_FLAG_INACTIVE_PS);
+
+   rtw_core_stop(rtwdev);
+
+   return 0;
+}
+
+static void rtw_restore_port_cfg(struct rtw_dev *rtwdev)
+{
+   struct rtw_vif *rtwvif;
+   u32 config = ~0;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(rtwvif, >vif_list, list)
+   rtw_vif_port_config(rtwdev, rtwvif, config);
+   rcu_read_unlock();
+}
+
+int rtw_leave_ips(struct rtw_dev *rtwdev)
+{
+   int ret;
+
+   ret = rtw_ips_pwr_up(rtwdev);
+   if (ret) {
+   rtw_err(rtwdev, "fail to leave ips state");
+   return ret;
+   }
+
+   rtw_restore_port_cfg(rtwdev);
+
+   return 0;
+}
+
+void rtw_lps_enter_check(struct rtw_dev *rtwdev)
+{
+   struct rtw_vif *rtwvif, *lps_if;
+   u8 assoc_cnt = 0;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(rtwvif, >vif_list, list) {
+   /* only station mode supports lps */
+   if (rtwvif->vif->type != NL80211_IFTYPE_STATION)
+   goto unlock;
+   /* take the station associated into account */
+   if (rtwvif->vif->bss_conf.assoc) {
+   lps_if = rtwvif;
+   assoc_cnt++;
+   }
+   }
+
+   /* fw supports only one station associated to enter lps, if there are
+* more than two stations associated to the AP, then we can not enter
+* lps, because fw does not handle the overlapped beacon interval
+*/
+   if (assoc_cnt != 1)
+   goto unlock;
+
+   /* the remained interface is the one we want to enter lps */
+   if (lps_if->stats.tx_cnt <= RTW_LPS_THRESHOLD &&
+   lps_if->stats.rx_cnt <= RTW_LPS_THRESHOLD)
+   rtw_enter_lps(rtwdev, lps_if);
+unlock:
+   rcu_read_unlock();
+}
+
+static void rtw_leave_lps_core(struct rtw_dev *rtwdev)
+{
+   struct rtw_lps_conf *conf = >lps_conf;
+
+   conf->state = RTW_ALL_ON;
+   conf->awake_interval = 1;
+   conf->rlbm = 0;
+   conf->smart_ps = 0;
+
+   rtw_fw_set_pwr_mode(rtwdev);
+   rtw_flag_clear(rtwdev, RTW_FLAG_LEISURE_PS);
+}
+
+static void rtw_enter_lps_core(struct rtw_dev *rtwdev)
+{
+   struct rtw_lps_conf *conf = >lps_conf;
+
+   conf->state = RTW_RF_OFF;
+   conf->awake_interval = 1;
+   conf->rlbm = 1;
+   conf->smart_ps = 2;
+
+   rtw_fw_set_pwr_mode(rtwdev);
+   rtw_flag_set(rtwdev, RTW_FLAG_LEISURE_PS);
+}
+
+void rtw_lps_work(struct work_struct *work)
+{
+   struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
+ lps_work.work);
+   struct rtw_lps_conf *conf = >lps_conf;
+   struct rtw_vif *rtwvif = conf->rtwvif;
+
+   if (WARN_ON(!rtwvif))
+   return;
+
+   if (conf->mode == RTW_MODE_LPS)
+   rtw_enter_lps_core(rtwdev);
+   else
+   rtw_leave_lps_core(rtwdev);
+}
+
+void rtw_enter_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
+{
+   struct rtw_lps_conf *conf = >lps_conf;
+
+   if (rtwvif->in_lps)
+   return;
+
+   conf->mode = RTW_MODE_LPS;
+   conf->rtwvif = rtwvif;
+   rtwvif->in_lps = true;
+
+   ieee80211_queue_delayed_work(rtwdev->hw, >lps_work, 0);
+}
+
+void rtw_leave_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
+{
+   

[RFC v3 11/12] rtw88: 8822C init table

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

8822C init table for chip files Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 .../net/wireless/realtek/rtw88/rtw8822c_table.c| 4150 
 1 file changed, 4150 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c_table.c

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c 
b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c
new file mode 100644
index 000..e95ad82
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c
@@ -0,0 +1,4150 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "phy.h"
+#include "rtw8822c_table.h"
+
+static const u32 rtw8822c_mac[] = {
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8822c_mac, rtw_phy_cfg_mac);
+
+static const u32 rtw8822c_agc[] = {
+   0x1D90, 0x31FF,
+   0x1D90, 0x300101FF,
+   0x1D90, 0x300201FF,
+   0x1D90, 0x300301FF,
+   0x1D90, 0x300401FF,
+   0x1D90, 0x300501FF,
+   0x1D90, 0x300601FE,
+   0x1D90, 0x300701FD,
+   0x1D90, 0x300801FC,
+   0x1D90, 0x300901FB,
+   0x1D90, 0x300A01FA,
+   0x1D90, 0x300B01F9,
+   0x1D90, 0x300C01F8,
+   0x1D90, 0x300D01F7,
+   0x1D90, 0x300E01F6,
+   0x1D90, 0x300F01F5,
+   0x1D90, 0x301001F4,
+   0x1D90, 0x301101F3,
+   0x1D90, 0x301201F2,
+   0x1D90, 0x301301F1,
+   0x1D90, 0x301401F0,
+   0x1D90, 0x301501EF,
+   0x1D90, 0x301601AF,
+   0x1D90, 0x301701AE,
+   0x1D90, 0x301801AD,
+   0x1D90, 0x301901AC,
+   0x1D90, 0x301A01AB,
+   0x1D90, 0x301B01AA,
+   0x1D90, 0x301C01A9,
+   0x1D90, 0x301D0188,
+   0x1D90, 0x301E0187,
+   0x1D90, 0x301F0186,
+   0x1D90, 0x30200185,
+   0x1D90, 0x30210168,
+   0x1D90, 0x30220167,
+   0x1D90, 0x30230166,
+   0x1D90, 0x30240108,
+   0x1D90, 0x30250107,
+   0x1D90, 0x30260106,
+   0x1D90, 0x30270144,
+   0x1D90, 0x30280143,
+   0x1D90, 0x30290142,
+   0x1D90, 0x302A0141,
+   0x1D90, 0x302B0140,
+   0x1D90, 0x302C00C9,
+   0x1D90, 0x302D00C8,
+   0x1D90, 0x302E00C7,
+   0x1D90, 0x302F00C6,
+   0x1D90, 0x303000C5,
+   0x1D90, 0x303100C4,
+   0x1D90, 0x303200C3,
+   0x1D90, 0x30330088,
+   0x1D90, 0x30340087,
+   0x1D90, 0x30350086,
+   0x1D90, 0x30360045,
+   0x1D90, 0x30370044,
+   0x1D90, 0x30380043,
+   0x1D90, 0x30390023,
+   0x1D90, 0x303A0022,
+   0x1D90, 0x303B0021,
+   0x1D90, 0x303C0020,
+   0x1D90, 0x303D0002,
+   0x1D90, 0x303E0001,
+   0x1D90, 0x303F,
+   0x1D90, 0x304000FF,
+   0x1D90, 0x304100FF,
+   0x1D90, 0x304200FF,
+   0x1D90, 0x304300FF,
+   0x1D90, 0x304400FF,
+   0x1D90, 0x304500FE,
+   0x1D90, 0x304600FD,
+   0x1D90, 0x304700FC,
+   0x1D90, 0x304800FB,
+   0x1D90, 0x304900FA,
+   0x1D90, 0x304A00F9,
+   0x1D90, 0x304B00F8,
+   0x1D90, 0x304C00F7,
+   0x1D90, 0x304D00F6,
+   0x1D90, 0x304E00F5,
+   0x1D90, 0x304F00F4,
+   0x1D90, 0x305000F3,
+   0x1D90, 0x305100F2,
+   0x1D90, 0x305200F1,
+   0x1D90, 0x305300F0,
+   0x1D90, 0x305400EF,
+   0x1D90, 0x305500EE,
+   0x1D90, 0x305600ED,
+   0x1D90, 0x305700EC,
+   0x1D90, 0x305800EB,
+   0x1D90, 0x305900EA,
+   0x1D90, 0x305A00E9,
+   0x1D90, 0x305B00E8,
+   0x1D90, 0x305C00E7,
+   0x1D90, 0x305D00E6,
+   0x1D90, 0x305E00E5,
+   0x1D90, 0x305F00E4,
+   0x1D90, 0x306000E3,
+   0x1D90, 0x306100C3,
+   0x1D90, 0x306200C2,
+   0x1D90, 0x306300C1,
+   0x1D90, 0x30640088,
+   0x1D90, 0x30650087,
+   0x1D90, 0x30660086,
+   0x1D90, 0x30670085,
+   0x1D90, 0x30680084,
+   0x1D90, 0x30690083,
+   0x1D90, 0x306A0082,
+   0x1D90, 0x306B0081,
+   0x1D90, 0x306C0068,
+   0x1D90, 0x306D0067,
+   0x1D90, 0x306E0066,
+   0x1D90, 0x306F0065,
+   0x1D90, 0x30700064,
+   0x1D90, 0x30710063,
+   

[RFC v3 01/12] rtw88: main files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

main files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/mac80211.c |  482 ++
 drivers/net/wireless/realtek/rtw88/main.c | 1133 +++
 drivers/net/wireless/realtek/rtw88/main.h | 1200 +
 drivers/net/wireless/realtek/rtw88/reg.h  |  404 +
 4 files changed, 3219 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/mac80211.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/main.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/main.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/reg.h

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c 
b/drivers/net/wireless/realtek/rtw88/mac80211.c
new file mode 100644
index 000..b3d9ab1
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "sec.h"
+#include "tx.h"
+#include "fw.h"
+#include "mac.h"
+#include "ps.h"
+#include "reg.h"
+#include "debug.h"
+
+static void rtw_ops_tx(struct ieee80211_hw *hw,
+  struct ieee80211_tx_control *control,
+  struct sk_buff *skb)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   struct rtw_tx_pkt_info pkt_info = {0};
+
+   if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING))
+   goto out;
+
+   rtw_tx_pkt_info_update(rtwdev, _info, control, skb);
+   if (rtw_hci_tx(rtwdev, _info, skb))
+   goto out;
+
+   return;
+
+out:
+   ieee80211_free_txskb(hw, skb);
+}
+
+static int rtw_ops_start(struct ieee80211_hw *hw)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   int ret;
+
+   mutex_lock(>mutex);
+   ret = rtw_core_start(rtwdev);
+   mutex_unlock(>mutex);
+
+   return ret;
+}
+
+static void rtw_ops_stop(struct ieee80211_hw *hw)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+
+   mutex_lock(>mutex);
+   rtw_core_stop(rtwdev);
+   mutex_unlock(>mutex);
+}
+
+static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   int ret = 0;
+
+   mutex_lock(>mutex);
+
+   if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+   if (hw->conf.flags & IEEE80211_CONF_IDLE) {
+   rtw_enter_ips(rtwdev);
+   } else {
+   ret = rtw_leave_ips(rtwdev);
+   if (ret) {
+   rtw_err(rtwdev, "failed to leave idle state\n");
+   goto out;
+   }
+   }
+   }
+
+   if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+   rtw_set_channel(rtwdev);
+
+out:
+   mutex_unlock(>mutex);
+   return ret;
+}
+
+static struct rtw_vif_port rtw_vif_port[] = {
+   [0] = {
+   .mac_addr   = {.addr = 0x0610},
+   .bssid  = {.addr = 0x0618},
+   .net_type   = {.addr = 0x0100, .mask = 0x3},
+   .aid= {.addr = 0x06a8, .mask = 0x7ff},
+   },
+   [1] = {
+   .mac_addr   = {.addr = 0x0700},
+   .bssid  = {.addr = 0x0708},
+   .net_type   = {.addr = 0x0100, .mask = 0xc},
+   .aid= {.addr = 0x0710, .mask = 0x7ff},
+   },
+   [2] = {
+   .mac_addr   = {.addr = 0x1620},
+   .bssid  = {.addr = 0x1628},
+   .net_type   = {.addr = 0x1100, .mask = 0x3},
+   .aid= {.addr = 0x1600, .mask = 0x7ff},
+   },
+   [3] = {
+   .mac_addr   = {.addr = 0x1630},
+   .bssid  = {.addr = 0x1638},
+   .net_type   = {.addr = 0x1100, .mask = 0xc},
+   .aid= {.addr = 0x1604, .mask = 0x7ff},
+   },
+   [4] = {
+   .mac_addr   = {.addr = 0x1640},
+   .bssid  = {.addr = 0x1648},
+   .net_type   = {.addr = 0x1100, .mask = 0x30},
+   .aid= {.addr = 0x1608, .mask = 0x7ff},
+   },
+};
+
+static int rtw_ops_add_interface(struct ieee80211_hw *hw,
+struct ieee80211_vif *vif)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+   enum rtw_net_type net_type;
+   u32 config = 0;
+   u8 port = 0;
+
+   vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+   rtwvif->port = port;
+   rtwvif->vif = vif;
+   rtwvif->stats.tx_unicast = 0;
+   rtwvif->stats.rx_unicast = 0;
+   rtwvif->stats.tx_cnt = 0;
+   rtwvif->stats.rx_cnt = 0;
+   rtwvif->in_lps = false;
+   rtwvif->conf = _vif_port[port];
+   INIT_LIST_HEAD(>sta_list);
+
+   mutex_lock(>mutex);
+
+   

[RFC v3 06/12] rtw88: fw and efuse files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

fw and efuse files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/efuse.c | 150 +++
 drivers/net/wireless/realtek/rtw88/efuse.h |  53 +++
 drivers/net/wireless/realtek/rtw88/fw.c| 638 +
 drivers/net/wireless/realtek/rtw88/fw.h| 182 
 4 files changed, 1023 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/efuse.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/efuse.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/fw.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/fw.h

diff --git a/drivers/net/wireless/realtek/rtw88/efuse.c 
b/drivers/net/wireless/realtek/rtw88/efuse.c
new file mode 100644
index 000..7c1b782
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/efuse.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "efuse.h"
+#include "reg.h"
+#include "debug.h"
+
+#define RTW_EFUSE_BANK_WIFI0x0
+
+static void switch_efuse_bank(struct rtw_dev *rtwdev)
+{
+   rtw_write32_mask(rtwdev, REG_LDO_EFUSE_CTRL, BIT_MASK_EFUSE_BANK_SEL,
+RTW_EFUSE_BANK_WIFI);
+}
+
+static int rtw_dump_logical_efuse_map(struct rtw_dev *rtwdev, u8 *phy_map,
+ u8 *log_map)
+{
+   u32 physical_size = rtwdev->efuse.physical_size;
+   u32 protect_size = rtwdev->efuse.protect_size;
+   u32 logical_size = rtwdev->efuse.logical_size;
+   u32 phy_idx, log_idx;
+   u8 hdr1, hdr2;
+   u8 blk_idx;
+   u8 valid;
+   u8 word_en;
+   int i;
+
+   phy_idx = 0;
+
+   do {
+   hdr1 = *(phy_map + phy_idx);
+   if ((hdr1 & 0x1f) == 0xf) {
+   phy_idx++;
+   hdr2 = *(phy_map + phy_idx);
+   if (hdr2 == 0xff)
+   break;
+   blk_idx = ((hdr2 & 0xf0) >> 1) | ((hdr1 >> 5) & 0x07);
+   word_en = hdr2 & 0x0f;
+   } else {
+   blk_idx = (hdr1 & 0xf0) >> 4;
+   word_en = hdr1 & 0x0f;
+   }
+
+   if (hdr1 == 0xff)
+   break;
+
+   phy_idx++;
+   for (i = 0; i < 4; i++) {
+   valid = (~(word_en >> i)) & 0x1;
+   if (valid != 0x1)
+   continue;
+   log_idx = (blk_idx << 3) + (i << 1);
+   *(log_map + log_idx) = *(phy_map + phy_idx);
+   log_idx++;
+   phy_idx++;
+   *(log_map + log_idx) = *(phy_map + phy_idx);
+   phy_idx++;
+   if (phy_idx > physical_size - protect_size ||
+   log_idx > logical_size)
+   return -EINVAL;
+   }
+   } while (1);
+
+   return 0;
+}
+
+static int rtw_dump_physical_efuse_map(struct rtw_dev *rtwdev, u8 *map)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   u32 size = rtwdev->efuse.physical_size;
+   u32 efuse_ctl;
+   u32 addr;
+   u32 cnt;
+
+   switch_efuse_bank(rtwdev);
+
+   /* disable 2.5V LDO */
+   chip->ops->cfg_ldo25(rtwdev, false);
+
+   efuse_ctl = rtw_read32(rtwdev, REG_EFUSE_CTRL);
+
+   for (addr = 0; addr < size; addr++) {
+   efuse_ctl &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
+   efuse_ctl |= (addr & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR;
+   rtw_write32(rtwdev, REG_EFUSE_CTRL, efuse_ctl & (~BIT_EF_FLAG));
+
+   cnt = 100;
+   do {
+   udelay(1);
+   efuse_ctl = rtw_read32(rtwdev, REG_EFUSE_CTRL);
+   if (--cnt == 0)
+   return -EBUSY;
+   } while (!(efuse_ctl & BIT_EF_FLAG));
+
+   *(map + addr) = (u8)(efuse_ctl & BIT_MASK_EF_DATA);
+   }
+
+   return 0;
+}
+
+int rtw_parse_efuse_map(struct rtw_dev *rtwdev)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   struct rtw_efuse *efuse = >efuse;
+   u32 phy_size = efuse->physical_size;
+   u32 log_size = efuse->logical_size;
+   u8 *phy_map = NULL;
+   u8 *log_map = NULL;
+   int ret = 0;
+
+   phy_map = kmalloc(phy_size, GFP_KERNEL);
+   log_map = kmalloc(log_size, GFP_KERNEL);
+   if (!phy_map || !log_map) {
+   ret = -ENOMEM;
+   goto out_free;
+   }
+
+   ret = rtw_dump_physical_efuse_map(rtwdev, phy_map);
+   if (ret) {
+   rtw_err(rtwdev, "failed to dump efuse physical map\n");
+   goto out_free;
+   }
+
+   memset(log_map, 0xff, log_size);
+   ret = rtw_dump_logical_efuse_map(rtwdev, phy_map, 

[RFC v3 12/12] rtw88: Kconfig & Makefile

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

Kconfig & Makefile for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/Kconfig|  1 +
 drivers/net/wireless/realtek/Makefile   |  1 +
 drivers/net/wireless/realtek/rtw88/Kconfig  | 57 +
 drivers/net/wireless/realtek/rtw88/Makefile | 19 ++
 4 files changed, 78 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/Kconfig
 create mode 100644 drivers/net/wireless/realtek/rtw88/Makefile

diff --git a/drivers/net/wireless/realtek/Kconfig 
b/drivers/net/wireless/realtek/Kconfig
index 3db988e..9189fd6 100644
--- a/drivers/net/wireless/realtek/Kconfig
+++ b/drivers/net/wireless/realtek/Kconfig
@@ -14,5 +14,6 @@ if WLAN_VENDOR_REALTEK
 source "drivers/net/wireless/realtek/rtl818x/Kconfig"
 source "drivers/net/wireless/realtek/rtlwifi/Kconfig"
 source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig"
+source "drivers/net/wireless/realtek/rtw88/Kconfig"
 
 endif # WLAN_VENDOR_REALTEK
diff --git a/drivers/net/wireless/realtek/Makefile 
b/drivers/net/wireless/realtek/Makefile
index 9c78deb..118af99 100644
--- a/drivers/net/wireless/realtek/Makefile
+++ b/drivers/net/wireless/realtek/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_RTL8180)   += rtl818x/
 obj-$(CONFIG_RTL8187)  += rtl818x/
 obj-$(CONFIG_RTLWIFI)  += rtlwifi/
 obj-$(CONFIG_RTL8XXXU) += rtl8xxxu/
+obj-$(CONFIG_RTW88)+= rtw88/
 
diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig 
b/drivers/net/wireless/realtek/rtw88/Kconfig
new file mode 100644
index 000..9bc9698
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -0,0 +1,57 @@
+menuconfig RTW88
+   tristate "Realtek 802.11ac wireless chips support"
+   depends on MAC80211
+   default y
+   help
+ This module adds support for mac80211-based wireless drivers that
+ enables Realtek IEEE 802.11ac wireless chipsets.
+
+ If you choose to build a module, it'll be called rtw88.
+
+if RTW88
+
+config RTW88_CORE
+   tristate
+   depends on RTW88
+
+config RTW88_PCI
+   tristate
+   depends on RTW88_CORE && PCI
+
+config RTW88_8822BE
+   bool "Realtek 8822BE PCI wireless network adapter"
+   depends on PCI
+   select RTW88_CORE
+   select RTW88_PCI
+   help
+ Select this option will enable support for 8822BE chipset
+
+ 802.11ac PCIe wireless network adapter
+
+config RTW88_8822CE
+   bool "Realtek 8822CE PCI wireless network adapter"
+   depends on PCI
+   select RTW88_CORE
+   select RTW88_PCI
+   help
+ Select this option will enable support for 8822CE chipset
+
+ 802.11ac PCIe wireless network adapter
+
+config RTW88_DEBUG
+   bool "Realtek rtw88 debug support"
+   depends on RTW88_CORE
+   help
+ Enable debug support
+
+ If unsure, say Y to simplify debug problems
+
+config RTW88_DEBUGFS
+   bool "Realtek rtw88 debugfs support"
+   depends on RTW88_CORE
+   help
+ Enable debug support
+
+ If unsure, say Y to simplify debug problems
+
+endif
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile 
b/drivers/net/wireless/realtek/rtw88/Makefile
new file mode 100644
index 000..d70782a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -0,0 +1,19 @@
+obj-$(CONFIG_RTW88_CORE)   += rtw88.o
+rtw88-y += main.o \
+  mac80211.o \
+  debug.o \
+  tx.o \
+  rx.o \
+  mac.o \
+  phy.o \
+  efuse.o \
+  fw.o \
+  ps.o \
+  sec.o \
+  regd.o
+
+rtw88-$(CONFIG_RTW88_8822BE)   += rtw8822b.o rtw8822b_table.o
+rtw88-$(CONFIG_RTW88_8822CE)   += rtw8822c.o rtw8822c_table.o
+
+obj-$(CONFIG_RTW88_PCI)+= rtwpci.o
+rtwpci-objs:= pci.o
-- 
2.7.4



[RFC v3 07/12] rtw88: phy files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

phy files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/phy.c | 1675 ++
 drivers/net/wireless/realtek/rtw88/phy.h |  125 +++
 2 files changed, 1800 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/phy.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/phy.h

diff --git a/drivers/net/wireless/realtek/rtw88/phy.c 
b/drivers/net/wireless/realtek/rtw88/phy.c
new file mode 100644
index 000..7048d29
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -0,0 +1,1675 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "fw.h"
+#include "phy.h"
+#include "debug.h"
+
+struct phy_cfg_pair {
+   u32 addr;
+   u32 data;
+};
+
+union phy_table_tile {
+   struct rtw_phy_cond cond;
+   struct phy_cfg_pair cfg;
+};
+
+struct phy_pg_cfg_pair {
+   u32 band;
+   u32 rf_path;
+   u32 tx_num;
+   u32 addr;
+   u32 bitmask;
+   u32 data;
+};
+
+struct txpwr_lmt_cfg_pair {
+   u8 regd;
+   u8 band;
+   u8 bw;
+   u8 rs;
+   u8 ch;
+   s8 txpwr_lmt;
+};
+
+static const u32 db_invert_table[12][8] = {
+   {10,13, 16, 20,
+25,32, 40, 50},
+   {64,80, 101,128,
+160,   201,256,318},
+   {401,   505,635,800,
+1007,  1268,   1596,   2010},
+   {316,   398,501,631,
+794,   1000,   1259,   1585},
+   {1995,  2512,   3162,   3981,
+5012,  6310,   7943,   1},
+   {12589, 15849,  19953,  25119,
+31623, 39811,  50119,  63098},
+   {79433, 10, 125893, 158489,
+199526,251189, 316228, 398107},
+   {501187,630957, 794328, 100,
+1258925,   1584893,1995262,2511886},
+   {3162278,   3981072,5011872,6309573,
+7943282,   100,12589254,   15848932},
+   {19952623,  25118864,   31622777,   39810717,
+50118723,  63095734,   79432823,   1},
+   {125892541, 158489319,  199526232,  251188643,
+316227766, 398107171,  501187234,  630957345},
+   {794328235, 10, 1258925412, 1584893192,
+1995262315,2511886432U,3162277660U,3981071706U}
+};
+
+enum rtw_phy_band_type {
+   PHY_BAND_2G = 0,
+   PHY_BAND_5G = 1,
+};
+
+void rtw_phy_init(struct rtw_dev *rtwdev)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   struct rtw_dm_info *dm_info = >dm_info;
+   u32 addr, mask;
+
+   dm_info->fa_history[3] = 0;
+   dm_info->fa_history[2] = 0;
+   dm_info->fa_history[1] = 0;
+   dm_info->fa_history[0] = 0;
+   dm_info->igi_bitmap = 0;
+   dm_info->igi_history[3] = 0;
+   dm_info->igi_history[2] = 0;
+   dm_info->igi_history[1] = 0;
+
+   addr = chip->dig[0].addr;
+   mask = chip->dig[0].mask;
+   dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask);
+}
+
+void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   struct rtw_hal *hal = >hal;
+   u32 addr, mask;
+   u8 path;
+
+   for (path = 0; path < hal->rf_path_num; path++) {
+   addr = chip->dig[path].addr;
+   mask = chip->dig[path].mask;
+   rtw_write32_mask(rtwdev, addr, mask, igi);
+   }
+}
+
+static void rtw_phy_stat_false_alarm(struct rtw_dev *rtwdev)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+
+   chip->ops->false_alarm_statistics(rtwdev);
+}
+
+#define RA_FLOOR_TABLE_SIZE7
+#define RA_FLOOR_UP_GAP3
+
+static u8 rtw_phy_get_rssi_level(u8 old_level, u8 rssi)
+{
+   u8 table[RA_FLOOR_TABLE_SIZE] = {20, 34, 38, 42, 46, 50, 100};
+   u8 new_level = 0;
+   int i;
+
+   for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++)
+   if (i >= old_level)
+   table[i] += RA_FLOOR_UP_GAP;
+
+   for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
+   if (rssi < table[i]) {
+   new_level = i;
+   break;
+   }
+   }
+
+   return new_level;
+}
+
+static void rtw_phy_stat_rssi(struct rtw_dev *rtwdev)
+{
+   struct rtw_dm_info *dm_info = >dm_info;
+   struct rtw_vif *rtwvif;
+   struct rtw_sta_info *si;
+   u8 min_rssi = U8_MAX;
+   u8 rssi;
+   u8 rssi_level;
+
+   rcu_read_lock();

Re: [PATCH 06/10] mt76x2: move mt76x2_dev in mt76x02_util.h

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 01:01:40PM +0200, Lorenzo Bianconi wrote:
> >
> > On Tue, Oct 02, 2018 at 12:19:04AM +0200, Lorenzo Bianconi wrote:
> > > Move mt76x2_dev in mt76x02_util.h and rename it in mt76x02_dev
> > > in order to be shared between mt76x2 and mt76x0 driver
> > 
> > > +struct mt76x02_dev {
> > > + struct mt76_dev mt76; /* must be first */
> > > +
> > > + struct mac_address macaddr_list[8];
> > > +
> > > + struct mutex mutex;
> > > +
> > > + u8 txdone_seq;
> > > + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
> > > +
> > > + struct sk_buff *rx_head;
> > > +
> > > + struct tasklet_struct tx_tasklet;
> > > + struct tasklet_struct pre_tbtt_tasklet;
> > > + struct delayed_work cal_work;
> > > + struct delayed_work mac_work;
> > > +
> > > + u32 aggr_stats[32];
> > > +
> > > + struct sk_buff *beacons[8];
> > > + u8 beacon_mask;
> > > + u8 beacon_data_mask;
> > > +
> > > + u8 tbtt_count;
> > > + u16 beacon_int;
> > > +
> > > + struct mt76x02_calibration cal;
> > > +
> > > + s8 target_power;
> > > + s8 target_power_delta[2];
> > > + bool enable_tpc;
> > > +
> > > + u8 coverage_class;
> > > + u8 slottime;
> > > +
> > > + struct mt76x02_dfs_pattern_detector dfs_pd;
> > > +};
> > > +
> > 
> > >  static bool
> > > -mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
> > > +mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
> >
> > I don't think this is right approach. I would rather prefer to have
> > common data structures embeded in mt76x2_dev and mt76x0_dev
> > structures to have chip sepcific fields/data separated.
> >
> 
> The reason of this patch is that mt76x0_dev fields are already in mt76x2_dev
> so I guess there is no need to have different structures. Moreover in
> this way we can
> remove a lot of duplicated code between mt76x0 and mt76x2 drivers.

But you can still create additional structures i.e.

mt76x02_power {
s8 target_power;
s8 target_power_delta[2];
bool enable_tpc;
}

mt76x02_conf {
u8 coverage_class;
u8 slottime;
}

put them into mt76xN_dev and still remove dupicated code ?

Thanks
Stanislaw



Re: [PATCH 06/10] mt76x2: move mt76x2_dev in mt76x02_util.h

2018-10-03 Thread Lorenzo Bianconi
>
> On Tue, Oct 02, 2018 at 12:19:04AM +0200, Lorenzo Bianconi wrote:
> > Move mt76x2_dev in mt76x02_util.h and rename it in mt76x02_dev
> > in order to be shared between mt76x2 and mt76x0 driver
> 
> > +struct mt76x02_dev {
> > + struct mt76_dev mt76; /* must be first */
> > +
> > + struct mac_address macaddr_list[8];
> > +
> > + struct mutex mutex;
> > +
> > + u8 txdone_seq;
> > + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
> > +
> > + struct sk_buff *rx_head;
> > +
> > + struct tasklet_struct tx_tasklet;
> > + struct tasklet_struct pre_tbtt_tasklet;
> > + struct delayed_work cal_work;
> > + struct delayed_work mac_work;
> > +
> > + u32 aggr_stats[32];
> > +
> > + struct sk_buff *beacons[8];
> > + u8 beacon_mask;
> > + u8 beacon_data_mask;
> > +
> > + u8 tbtt_count;
> > + u16 beacon_int;
> > +
> > + struct mt76x02_calibration cal;
> > +
> > + s8 target_power;
> > + s8 target_power_delta[2];
> > + bool enable_tpc;
> > +
> > + u8 coverage_class;
> > + u8 slottime;
> > +
> > + struct mt76x02_dfs_pattern_detector dfs_pd;
> > +};
> > +
> 
> >  static bool
> > -mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
> > +mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
>
> I don't think this is right approach. I would rather prefer to have
> common data structures embeded in mt76x2_dev and mt76x0_dev
> structures to have chip sepcific fields/data separated.
>

The reason of this patch is that mt76x0_dev fields are already in mt76x2_dev
so I guess there is no need to have different structures. Moreover in
this way we can
remove a lot of duplicated code between mt76x0 and mt76x2 drivers.

Regards,
Lorenzo

> Regards
> Stanislaw
>


[PATCH 3/3] mt76x0: usb: stop cal/mac workqueues at hw stop

2018-10-03 Thread Lorenzo Bianconi
Stop mac and calibration work stopping the hw even if the
device has been removed

Fixes: b11e19694dc9 ("mt76x0: add ieee80211_ops ops pointer to
mt76x0_alloc_device signature")

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index dd437e77009f..57862cacf22a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -86,14 +86,14 @@ static void mt76x0u_cleanup(struct mt76x0_dev *dev)
 
 static void mt76x0u_mac_stop(struct mt76x0_dev *dev)
 {
-   if (test_bit(MT76_REMOVED, >mt76.state))
-   return;
-
clear_bit(MT76_STATE_RUNNING, >mt76.state);
cancel_delayed_work_sync(>cal_work);
cancel_delayed_work_sync(>mac_work);
mt76u_stop_stat_wk(>mt76);
 
+   if (test_bit(MT76_REMOVED, >mt76.state))
+   return;
+
mt76_clear(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_TIMER_EN |
   MT_BEACON_TIME_CFG_SYNC_MODE | MT_BEACON_TIME_CFG_TBTT_EN |
   MT_BEACON_TIME_CFG_BEACON_TX);
-- 
2.17.1



[PATCH 0/3] fix mt76x0u driver hw stop sequence

2018-10-03 Thread Lorenzo Bianconi
Fix two issue introduced in mt76x0u driver with latest rework to
share hw initialization between mt760 and mt76x2 drivers

Lorenzo Bianconi (2):
  mt76: usb: fix hw initialization sequence
  mt76x0: usb: stop cal/mac workqueues at hw stop

Stanislaw Gruszka (1):
  mt76: fix frag length allocation for usb

 .../net/wireless/mediatek/mt76/mt76x0/usb.c   | 24 +--
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  |  2 +-
 drivers/net/wireless/mediatek/mt76/usb.c  |  2 +-
 3 files changed, 14 insertions(+), 14 deletions(-)

-- 
2.17.1



[PATCH 1/3] mt76: fix frag length allocation for usb

2018-10-03 Thread Lorenzo Bianconi
From: Stanislaw Gruszka 

This is correct fix for c12128ce44b0 ("mt76: use a per rx queue page
fragment cache"). We use wrong length when we allocate segments for
MCU transmissions, which require bigger segment size than e->buf_size.

Commit 481bb0432414 ("mt76: usb: make rx page_frag_cache access atomic")
partially solved the problem or actually mask it by changing
mt76u_mcu_init_rx() and mt76u_alloc_queues() sequence, so e->buf_size
become non zero any longer, but still not big enough to handle MCU data.

Patch fixes memory corruption which can manifest itself as random,
not easy to reproduce crashes, during mt76 driver load or unload.

Fixes: c12128ce44b0 ("mt76: use a per rx queue page fragment cache")
Signed-off-by: Stanislaw Gruszka 
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/usb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index de7785c4f6af..6b643ea701e3 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -286,7 +286,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf 
*buf,
void *data;
int offset;
 
-   data = page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
+   data = page_frag_alloc(>rx_page, len, GFP_ATOMIC);
if (!data)
break;
 
-- 
2.17.1



[PATCH 2/3] mt76: usb: fix hw initialization sequence

2018-10-03 Thread Lorenzo Bianconi
mt76u_alloc_queues need to be called before mt76u_mcu_init_rx
since it initializes rx_page_lock spinlock used in mt76u_buf_alloc
routine.

Fixes: b11e19694dc9 ("mt76x0: add ieee80211_ops ops pointer to
mt76x0_alloc_device signature")

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/usb.c| 18 +-
 .../wireless/mediatek/mt76/mt76x2/usb_init.c   |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index a76043213f55..dd437e77009f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -179,28 +179,28 @@ static int mt76x0u_register_device(struct mt76x0_dev *dev)
struct ieee80211_hw *hw = dev->mt76.hw;
int err;
 
-   err = mt76u_mcu_init_rx(>mt76);
+   err = mt76u_alloc_queues(>mt76);
if (err < 0)
-   return err;
+   goto out_err;
 
-   err = mt76u_alloc_queues(>mt76);
+   err = mt76u_mcu_init_rx(>mt76);
if (err < 0)
-   return err;
+   goto out_err;
 
mt76x0_chip_onoff(dev, true, true);
if (!mt76x02_wait_for_mac(>mt76)) {
err = -ETIMEDOUT;
-   goto err;
+   goto out_err;
}
 
err = mt76x0u_mcu_init(dev);
if (err < 0)
-   goto err;
+   goto out_err;
 
mt76x0_init_usb_dma(dev);
err = mt76x0_init_hardware(dev);
if (err < 0)
-   goto err;
+   goto out_err;
 
mt76_rmw(dev, MT_US_CYC_CFG, MT_US_CYC_CNT, 0x1e);
mt76_wr(dev, MT_TXOP_CTRL_CFG,
@@ -209,7 +209,7 @@ static int mt76x0u_register_device(struct mt76x0_dev *dev)
 
err = mt76x0_register_device(dev);
if (err < 0)
-   goto err;
+   goto out_err;
 
/* check hw sg support in order to enable AMSDU */
if (mt76u_check_sg(>mt76))
@@ -221,7 +221,7 @@ static int mt76x0u_register_device(struct mt76x0_dev *dev)
 
return 0;
 
-err:
+out_err:
mt76x0u_cleanup(dev);
return err;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
index 55e0dea568b8..a8222447d805 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
@@ -262,7 +262,7 @@ int mt76x2u_register_device(struct mt76x2_dev *dev)
 
err = mt76u_mcu_init_rx(>mt76);
if (err < 0)
-   return err;
+   goto fail;
 
err = mt76x2u_init_hardware(dev);
if (err < 0)
-- 
2.17.1



Re: [RFC 2/2] mt76: make frag_cache global per cpu structure

2018-10-03 Thread Felix Fietkau


> On 3. Oct 2018, at 11:17, Stanislaw Gruszka  wrote:
> 
> Make mt76 frag cache similar to netdev frag cache. This should
> make frag allocation safe regarding concurrent access and also
> be more efficient since we will use pages that most likely are
> hot on particular cpu.
> 
> And we don't need to clean up the cache up during device removal.
The problem with feeding multiple queues with buffers from the same fragment 
cache is the fact that this re-introduces the problem of large compound pages 
staying pinned in memory (often with only one or two fragments actually being 
used) far too long, leading to excessive RAM usage.
That is much more critical than the spinlock on alloc issue.
Please keep allocation the way it is now.

- Felix


Re: [PATCH 06/10] mt76x2: move mt76x2_dev in mt76x02_util.h

2018-10-03 Thread Stanislaw Gruszka
On Tue, Oct 02, 2018 at 12:19:04AM +0200, Lorenzo Bianconi wrote:
> Move mt76x2_dev in mt76x02_util.h and rename it in mt76x02_dev
> in order to be shared between mt76x2 and mt76x0 driver

> +struct mt76x02_dev {
> + struct mt76_dev mt76; /* must be first */
> +
> + struct mac_address macaddr_list[8];
> +
> + struct mutex mutex;
> +
> + u8 txdone_seq;
> + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
> +
> + struct sk_buff *rx_head;
> +
> + struct tasklet_struct tx_tasklet;
> + struct tasklet_struct pre_tbtt_tasklet;
> + struct delayed_work cal_work;
> + struct delayed_work mac_work;
> +
> + u32 aggr_stats[32];
> +
> + struct sk_buff *beacons[8];
> + u8 beacon_mask;
> + u8 beacon_data_mask;
> +
> + u8 tbtt_count;
> + u16 beacon_int;
> +
> + struct mt76x02_calibration cal;
> +
> + s8 target_power;
> + s8 target_power_delta[2];
> + bool enable_tpc;
> +
> + u8 coverage_class;
> + u8 slottime;
> +
> + struct mt76x02_dfs_pattern_detector dfs_pd;
> +};
> +
 
>  static bool
> -mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
> +mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)

I don't think this is right approach. I would rather prefer to have
common data structures embeded in mt76x2_dev and mt76x0_dev
structures to have chip sepcific fields/data separated.

Regards
Stanislaw



Re: new mt76 usb crashes on device removal

2018-10-03 Thread Lorenzo Bianconi
On Oct 03, Stanislaw Gruszka wrote:
> On Wed, Oct 03, 2018 at 11:15:37AM +0200, Lorenzo Bianconi wrote:
> > > After
> > > 
> > > b11e19694dc9 "mt76x0: add ieee80211_ops ops pointer to 
> > > mt76x0_alloc_device signature"
> > > 
> > > I have new crashs when remove mt76x0u and mt76x2u devices. 
> > > I can not provide calltrace because some other warning/traces
> > > show up instantly after the problem happen and mask prints
> > > for initall problem. Then the machine hungs.
> > > 
> > > Anyway bisection blame b11e19694dc9 commit and I confirm that problem
> > > not happen before this commit. I also applied the fix with I just
> > > posted, so this is diffrent issue.
> > 
> > Hi Stanislaw,
> > 
> > I do not know if it is related or not, but could you please try following 
> > patch:
> > 
> > Regards,
> > Lorenzo
> > 
> > --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
> > @@ -179,11 +179,11 @@ static int mt76x0u_register_device(struct mt76x0_dev 
> > *dev)
> > struct ieee80211_hw *hw = dev->mt76.hw;
> > int err;
> >  
> > -   err = mt76u_mcu_init_rx(>mt76);
> > +   err = mt76u_alloc_queues(>mt76);
> > if (err < 0)
> > return err;
> >  
> > -   err = mt76u_alloc_queues(>mt76);
> > +   err = mt76u_mcu_init_rx(>mt76);
> > if (err < 0)
> > return err;
> 
> It still crashes. You can not reproduce the problem ?
> It's 100% reproducible for me, when I unplug mt76x0u or mt76x2 device.

I think I get it, I will send you a series to test. Thanks

Regards,
Lorenzo

> 
> Thanks
> Stanislaw


Re: [PATCH] mt76: fix frag length allocation for usb

2018-10-03 Thread Lorenzo Bianconi
> > 
> > Hi Stanislaw,
> > 
> > I agree that we should use len in page_frag_alloc() instead of q->buf_size, 
> > so
> > 
> > Acked-by: Lorenzo Bianconi 
> > 
> > but reviewing the code I guess the real issue is not q->buf_size (since it 
> > should
> > be bigger than MCU_RESP_URB_SIZE) but it is the sequence of calls in
> 
> I added printk and there are allocations where len is bigger then
> q->buf_size even with correct mt76u_alloc_queues, mt76u_mcu_init_rx
> sequence for mt76x0u:
> 
> [16426.606090] q->buf_size 2048 len 2048 nsgs 8sglen 1728
> [16426.606131] q->buf_size 2048 len 2048 nsgs 8sglen 1728
> [16426.606134] q->buf_size 2048 len 2048 nsgs 8sglen 1728
> 
> [16426.606464] q->buf_size 2048 len 2048 nsgs 8sglen 1728
> [16426.607517] q->buf_size 2048 len 1024 nsgs 1sglen 1024
> [16426.939268] q->buf_size 2048 len 14584 nsgs 1sglen 14584
> [16426.984955] q->buf_size 2048 len 14584 nsgs 1sglen 14584
> 
> Not sure where it come from, but it's after MCU init (which is 1024
> third line from end).
> 
> > mt76x0u_register_device() since mt76u_alloc_queues need to be called before
> > mt76u_mcu_init_rx()
> 
> Ok, so this was already fixed in 
> 
> commit 481bb0432414f790066205fe77226b7d1877385d
> Author: Lorenzo Bianconi 
> Date:   Wed Sep 26 13:07:39 2018 +0200
> 
> mt76: usb: make rx page_frag_cache access atomic
> 
> but then the sequence was changed again in
> 
> commit faa605bdfaa1322ea8e85791abdb3382a8cb4e0c
> Author: Lorenzo Bianconi 
> Date:   Fri Sep 28 13:39:00 2018 +0200
> 
> mt76x0: usb: move initialization code in usb.c

That is an issue introduce in this commit, I am working on a fix.
Probably I got also the other reported issue. I will send a series to
test soon. Thanks.

Regards,
Lorenzo

> 
> Thanks
> Stanislaw
>  


Re: new mt76 usb crashes on device removal

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 11:15:37AM +0200, Lorenzo Bianconi wrote:
> > After
> > 
> > b11e19694dc9 "mt76x0: add ieee80211_ops ops pointer to mt76x0_alloc_device 
> > signature"
> > 
> > I have new crashs when remove mt76x0u and mt76x2u devices. 
> > I can not provide calltrace because some other warning/traces
> > show up instantly after the problem happen and mask prints
> > for initall problem. Then the machine hungs.
> > 
> > Anyway bisection blame b11e19694dc9 commit and I confirm that problem
> > not happen before this commit. I also applied the fix with I just
> > posted, so this is diffrent issue.
> 
> Hi Stanislaw,
> 
> I do not know if it is related or not, but could you please try following 
> patch:
> 
> Regards,
> Lorenzo
> 
> --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
> @@ -179,11 +179,11 @@ static int mt76x0u_register_device(struct mt76x0_dev 
> *dev)
>   struct ieee80211_hw *hw = dev->mt76.hw;
>   int err;
>  
> - err = mt76u_mcu_init_rx(>mt76);
> + err = mt76u_alloc_queues(>mt76);
>   if (err < 0)
>   return err;
>  
> - err = mt76u_alloc_queues(>mt76);
> + err = mt76u_mcu_init_rx(>mt76);
>   if (err < 0)
>   return err;

It still crashes. You can not reproduce the problem ?
It's 100% reproducible for me, when I unplug mt76x0u or mt76x2 device.

Thanks
Stanislaw


Re: [RFC 2/2] mt76: make frag_cache global per cpu structure

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 11:38:54AM +0200, Lorenzo Bianconi wrote:
> > +static DEFINE_PER_CPU(struct page_frag_cache, mt76_frag_cache);
> > +
> > +void *mt76_alloc_frag(unsigned int fragsz)
> > +{
> > +   struct page_frag_cache *fc;
> > +   unsigned long flags;
> > +   void *data;
> > +
> > +   local_irq_save(flags);
> 
> I like this approach since we will avoid a cache miss for the spinlock :)
> Do we still need to disable local_irq here since (not considering fw upload)
> I guess there is no contention for mt76_frag_cache

I think is needed if we have more than one device, but I think we can
change to local_irq_disable() / local_irq_enable() . 

Thanks
Stanislaw 


Re: [PATCH] mt76: fix frag length allocation for usb

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 11:12:07AM +0200, Lorenzo Bianconi wrote:
> > This is correct fix for c12128ce44b0 ("mt76: use a per rx queue page
> > fragment cache"). We use wrong length when we allocate segments for
> > MCU transmissions, which require bigger segment size than e->buf_size.
> > 
> > Commit 481bb0432414 ("mt76: usb: make rx page_frag_cache access atomic")
> > partially solved the problem or actually mask it by changing
> > mt76u_mcu_init_rx() and mt76u_alloc_queues() sequence, so e->buf_size
> > become non zero any longer, but still not big enough to handle MCU data.
> 
> Hi Stanislaw,
> 
> I agree that we should use len in page_frag_alloc() instead of q->buf_size, so
> 
> Acked-by: Lorenzo Bianconi 
> 
> but reviewing the code I guess the real issue is not q->buf_size (since it 
> should
> be bigger than MCU_RESP_URB_SIZE) but it is the sequence of calls in

I added printk and there are allocations where len is bigger then
q->buf_size even with correct mt76u_alloc_queues, mt76u_mcu_init_rx
sequence for mt76x0u:

[16426.606090] q->buf_size 2048 len 2048 nsgs 8sglen 1728
[16426.606131] q->buf_size 2048 len 2048 nsgs 8sglen 1728
[16426.606134] q->buf_size 2048 len 2048 nsgs 8sglen 1728

[16426.606464] q->buf_size 2048 len 2048 nsgs 8sglen 1728
[16426.607517] q->buf_size 2048 len 1024 nsgs 1sglen 1024
[16426.939268] q->buf_size 2048 len 14584 nsgs 1sglen 14584
[16426.984955] q->buf_size 2048 len 14584 nsgs 1sglen 14584

Not sure where it come from, but it's after MCU init (which is 1024
third line from end).

> mt76x0u_register_device() since mt76u_alloc_queues need to be called before
> mt76u_mcu_init_rx()

Ok, so this was already fixed in 

commit 481bb0432414f790066205fe77226b7d1877385d
Author: Lorenzo Bianconi 
Date:   Wed Sep 26 13:07:39 2018 +0200

mt76: usb: make rx page_frag_cache access atomic

but then the sequence was changed again in

commit faa605bdfaa1322ea8e85791abdb3382a8cb4e0c
Author: Lorenzo Bianconi 
Date:   Fri Sep 28 13:39:00 2018 +0200

mt76x0: usb: move initialization code in usb.c

Thanks
Stanislaw
 


Re: [RFC 2/2] mt76: make frag_cache global per cpu structure

2018-10-03 Thread Lorenzo Bianconi
> +static DEFINE_PER_CPU(struct page_frag_cache, mt76_frag_cache);
> +
> +void *mt76_alloc_frag(unsigned int fragsz)
> +{
> + struct page_frag_cache *fc;
> + unsigned long flags;
> + void *data;
> +
> + local_irq_save(flags);

I like this approach since we will avoid a cache miss for the spinlock :)
Do we still need to disable local_irq here since (not considering fw upload)
I guess there is no contention for mt76_frag_cache

Regards,
Lorenzo

> + fc = this_cpu_ptr(_frag_cache);
> + data = page_frag_alloc(fc, fragsz, GFP_ATOMIC);
> + local_irq_restore(flags);
> + return data;
> +}
> +EXPORT_SYMBOL_GPL(mt76_alloc_frag);
> +
>  MODULE_LICENSE("Dual BSD/GPL");
> diff --git a/drivers/net/wireless/mediatek/mt76/util.h 
> b/drivers/net/wireless/mediatek/mt76/util.h
> index 018d475504a2..6cb6c0e993c4 100644
> --- a/drivers/net/wireless/mediatek/mt76/util.h
> +++ b/drivers/net/wireless/mediatek/mt76/util.h
> @@ -41,4 +41,5 @@ mt76_skb_set_moredata(struct sk_buff *skb, bool enable)
>   hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
>  }
>  
> +void *mt76_alloc_frag(unsigned int fragsz);
>  #endif
> -- 
> 2.7.5
> 


[RFC 2/2] mt76: make frag_cache global per cpu structure

2018-10-03 Thread Stanislaw Gruszka
Make mt76 frag cache similar to netdev frag cache. This should
make frag allocation safe regarding concurrent access and also
be more efficient since we will use pages that most likely are
hot on particular cpu.

And we don't need to clean up the cache up during device removal.

Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/dma.c  |  2 +-
 drivers/net/wireless/mediatek/mt76/usb.c  | 10 +-
 drivers/net/wireless/mediatek/mt76/util.c | 16 
 drivers/net/wireless/mediatek/mt76/util.h |  1 +
 4 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index f7fbd7016403..59453a7781c5 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -328,7 +328,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue 
*q, bool napi)
while (q->queued < q->ndesc - 1) {
struct mt76_queue_buf qbuf;
 
-   buf = page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
+   buf = mt76_alloc_frag(q->buf_size);
if (!buf)
break;
 
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index a103b77ae8c4..a892f59a32d8 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -276,7 +276,6 @@ static int
 mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
 int nsgs, int len, int sglen)
 {
-   struct mt76_queue *q = >q_rx[MT_RXQ_MAIN];
struct urb *urb = buf->urb;
int i;
 
@@ -285,7 +284,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf 
*buf,
void *data;
int offset;
 
-   data = page_frag_alloc(>rx_page, len, GFP_ATOMIC);
+   data = mt76_alloc_frag(len);
if (!data)
break;
 
@@ -557,13 +556,6 @@ static void mt76u_free_rx(struct mt76_dev *dev)
 
for (i = 0; i < q->ndesc; i++)
mt76u_buf_free(>entry[i].ubuf);
-
-   if (!q->rx_page.va)
-   return;
-
-   page = virt_to_page(q->rx_page.va);
-   __page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
-   memset(>rx_page, 0, sizeof(q->rx_page));
 }
 
 static void mt76u_stop_rx(struct mt76_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/util.c 
b/drivers/net/wireless/mediatek/mt76/util.c
index 0c35b8db58cd..def2a1b841b9 100644
--- a/drivers/net/wireless/mediatek/mt76/util.c
+++ b/drivers/net/wireless/mediatek/mt76/util.c
@@ -75,4 +75,20 @@ int mt76_wcid_alloc(unsigned long *mask, int size)
 }
 EXPORT_SYMBOL_GPL(mt76_wcid_alloc);
 
+static DEFINE_PER_CPU(struct page_frag_cache, mt76_frag_cache);
+
+void *mt76_alloc_frag(unsigned int fragsz)
+{
+   struct page_frag_cache *fc;
+   unsigned long flags;
+   void *data;
+
+   local_irq_save(flags);
+   fc = this_cpu_ptr(_frag_cache);
+   data = page_frag_alloc(fc, fragsz, GFP_ATOMIC);
+   local_irq_restore(flags);
+   return data;
+}
+EXPORT_SYMBOL_GPL(mt76_alloc_frag);
+
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/util.h 
b/drivers/net/wireless/mediatek/mt76/util.h
index 018d475504a2..6cb6c0e993c4 100644
--- a/drivers/net/wireless/mediatek/mt76/util.h
+++ b/drivers/net/wireless/mediatek/mt76/util.h
@@ -41,4 +41,5 @@ mt76_skb_set_moredata(struct sk_buff *skb, bool enable)
hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
 }
 
+void *mt76_alloc_frag(unsigned int fragsz);
 #endif
-- 
2.7.5



[RFC 1/2] mt76: remove rx_page_lock

2018-10-03 Thread Stanislaw Gruszka
Extra serializaion for protecting q->rx_page is not needed,
we stop rx_tasklet before we nulify it in mt76u_free_rx().

Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/mt76.h | 1 -
 drivers/net/wireless/mediatek/mt76/usb.c  | 8 +---
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index f2dd4d87e355..2ab524c8f14f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -122,7 +122,6 @@ struct mt76_queue {
dma_addr_t desc_dma;
struct sk_buff *rx_head;
struct page_frag_cache rx_page;
-   spinlock_t rx_page_lock;
 };
 
 struct mt76_mcu_ops {
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index 6b643ea701e3..a103b77ae8c4 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -280,7 +280,6 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf 
*buf,
struct urb *urb = buf->urb;
int i;
 
-   spin_lock_bh(>rx_page_lock);
for (i = 0; i < nsgs; i++) {
struct page *page;
void *data;
@@ -294,7 +293,6 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf 
*buf,
offset = data - page_address(page);
sg_set_page(>sg[i], page, sglen, offset);
}
-   spin_unlock_bh(>rx_page_lock);
 
if (i < nsgs) {
int j;
@@ -523,7 +521,6 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
struct mt76_queue *q = >q_rx[MT_RXQ_MAIN];
int i, err, nsgs;
 
-   spin_lock_init(>rx_page_lock);
spin_lock_init(>lock);
q->entry = devm_kzalloc(dev->dev,
MT_NUM_RX_ENTRIES * sizeof(*q->entry),
@@ -561,15 +558,12 @@ static void mt76u_free_rx(struct mt76_dev *dev)
for (i = 0; i < q->ndesc; i++)
mt76u_buf_free(>entry[i].ubuf);
 
-   spin_lock_bh(>rx_page_lock);
if (!q->rx_page.va)
-   goto out;
+   return;
 
page = virt_to_page(q->rx_page.va);
__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
memset(>rx_page, 0, sizeof(q->rx_page));
-out:
-   spin_unlock_bh(>rx_page_lock);
 }
 
 static void mt76u_stop_rx(struct mt76_dev *dev)
-- 
2.7.5



Re: new mt76 usb crashes on device removal

2018-10-03 Thread Lorenzo Bianconi
> After
> 
> b11e19694dc9 "mt76x0: add ieee80211_ops ops pointer to mt76x0_alloc_device 
> signature"
> 
> I have new crashs when remove mt76x0u and mt76x2u devices. 
> I can not provide calltrace because some other warning/traces
> show up instantly after the problem happen and mask prints
> for initall problem. Then the machine hungs.
> 
> Anyway bisection blame b11e19694dc9 commit and I confirm that problem
> not happen before this commit. I also applied the fix with I just
> posted, so this is diffrent issue.

Hi Stanislaw,

I do not know if it is related or not, but could you please try following patch:

Regards,
Lorenzo

--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -179,11 +179,11 @@ static int mt76x0u_register_device(struct mt76x0_dev *dev)
struct ieee80211_hw *hw = dev->mt76.hw;
int err;
 
-   err = mt76u_mcu_init_rx(>mt76);
+   err = mt76u_alloc_queues(>mt76);
if (err < 0)
return err;
 
-   err = mt76u_alloc_queues(>mt76);
+   err = mt76u_mcu_init_rx(>mt76);
if (err < 0)
return err;

> 
> Thanks
> Stanislaw 


Re: [PATCH] mt76: fix frag length allocation for usb

2018-10-03 Thread Lorenzo Bianconi
> This is correct fix for c12128ce44b0 ("mt76: use a per rx queue page
> fragment cache"). We use wrong length when we allocate segments for
> MCU transmissions, which require bigger segment size than e->buf_size.
> 
> Commit 481bb0432414 ("mt76: usb: make rx page_frag_cache access atomic")
> partially solved the problem or actually mask it by changing
> mt76u_mcu_init_rx() and mt76u_alloc_queues() sequence, so e->buf_size
> become non zero any longer, but still not big enough to handle MCU data.

Hi Stanislaw,

I agree that we should use len in page_frag_alloc() instead of q->buf_size, so

Acked-by: Lorenzo Bianconi 

but reviewing the code I guess the real issue is not q->buf_size (since it 
should
be bigger than MCU_RESP_URB_SIZE) but it is the sequence of calls in
mt76x0u_register_device() since mt76u_alloc_queues need to be called before
mt76u_mcu_init_rx()

Regards,
Lorenzo

> 
> Patch fixes memory corruption which can manifest itself as random,
> not easy to reproduce crashes, during mt76 driver load or unload.
> 
> Fixes: c12128ce44b0 ("mt76: use a per rx queue page fragment cache")
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/usb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
> b/drivers/net/wireless/mediatek/mt76/usb.c
> index de7785c4f6af..6b643ea701e3 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -286,7 +286,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf 
> *buf,
>   void *data;
>   int offset;
>  
> - data = page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
> + data = page_frag_alloc(>rx_page, len, GFP_ATOMIC);
>   if (!data)
>   break;
>  
> -- 
> 2.7.5
> 


Re: [Make-wifi-fast] [PATCH RFC v4 3/4] mac80211: Add airtime accounting and scheduling to TXQs

2018-10-03 Thread Toke Høiland-Jørgensen
Rajkumar Manoharan  writes:

> On 2018-10-02 16:07, Rajkumar Manoharan wrote:
>> On 2018-10-02 12:00, Toke Høiland-Jørgensen wrote:
>>> Rajkumar Manoharan  writes:
 I noticed a race condition b/w sta cleanup and kick_airtime tasklet.
>> How do you plan to exit kick_airtime gracefully during sta_cleanup?
> 
> Ah, right, there's a lot of stuff going on before we get to 
> purge_txq.
> Hmm, I guess we should either make sure we remove the station from
> active_txqs earlier in the sta cleanup process, or maybe it'd enough 
> to
> just check the removed flag in the tasklet?
> 
> Does the below patch fix the issue?
> 
 
 No. Attaching backtrace. Any clue?
>>> 
>>> Ah, that's my bad. Just having a 'continue' there can make the 
>>> function
>>> loop forever. Oops. Try something like this instead?
>>> 
>> 
>> But 'continue' also used in other places. Will give a try but I think 
>> that
>> calling drv_wake_tx_queue within iteration is dangerous as it alters
>> the list. no?
>> 
> How about below change? Just schedule first txq and remaining will be
> scheduled later by driver upon tx-compl.

Your mail client seems to be mangling the patch somewhat, but I think I
see what your intention is. And yeah, just waking a single TXQ and
letting TX-completion do the rest is a good idea; will fold that into
the next version :)

-Toke


new mt76 usb crashes on device removal

2018-10-03 Thread Stanislaw Gruszka
After

b11e19694dc9 "mt76x0: add ieee80211_ops ops pointer to mt76x0_alloc_device 
signature"

I have new crashs when remove mt76x0u and mt76x2u devices. 
I can not provide calltrace because some other warning/traces
show up instantly after the problem happen and mask prints
for initall problem. Then the machine hungs.

Anyway bisection blame b11e19694dc9 commit and I confirm that problem
not happen before this commit. I also applied the fix with I just
posted, so this is diffrent issue.

Thanks
Stanislaw 


[PATCH] mt76: fix frag length allocation for usb

2018-10-03 Thread Stanislaw Gruszka
This is correct fix for c12128ce44b0 ("mt76: use a per rx queue page
fragment cache"). We use wrong length when we allocate segments for
MCU transmissions, which require bigger segment size than e->buf_size.

Commit 481bb0432414 ("mt76: usb: make rx page_frag_cache access atomic")
partially solved the problem or actually mask it by changing
mt76u_mcu_init_rx() and mt76u_alloc_queues() sequence, so e->buf_size
become non zero any longer, but still not big enough to handle MCU data.

Patch fixes memory corruption which can manifest itself as random,
not easy to reproduce crashes, during mt76 driver load or unload.

Fixes: c12128ce44b0 ("mt76: use a per rx queue page fragment cache")
Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/usb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index de7785c4f6af..6b643ea701e3 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -286,7 +286,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf 
*buf,
void *data;
int offset;
 
-   data = page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
+   data = page_frag_alloc(>rx_page, len, GFP_ATOMIC);
if (!data)
break;
 
-- 
2.7.5



[RFC v2 12/12] rtw88: Kconfig & Makefile

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

Kconfig & Makefile for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/Kconfig|  1 +
 drivers/net/wireless/realtek/Makefile   |  1 +
 drivers/net/wireless/realtek/rtw88/Kconfig  | 57 +
 drivers/net/wireless/realtek/rtw88/Makefile | 19 ++
 4 files changed, 78 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/Kconfig
 create mode 100644 drivers/net/wireless/realtek/rtw88/Makefile

diff --git a/drivers/net/wireless/realtek/Kconfig 
b/drivers/net/wireless/realtek/Kconfig
index 3db988e..9189fd6 100644
--- a/drivers/net/wireless/realtek/Kconfig
+++ b/drivers/net/wireless/realtek/Kconfig
@@ -14,5 +14,6 @@ if WLAN_VENDOR_REALTEK
 source "drivers/net/wireless/realtek/rtl818x/Kconfig"
 source "drivers/net/wireless/realtek/rtlwifi/Kconfig"
 source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig"
+source "drivers/net/wireless/realtek/rtw88/Kconfig"
 
 endif # WLAN_VENDOR_REALTEK
diff --git a/drivers/net/wireless/realtek/Makefile 
b/drivers/net/wireless/realtek/Makefile
index 9c78deb..118af99 100644
--- a/drivers/net/wireless/realtek/Makefile
+++ b/drivers/net/wireless/realtek/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_RTL8180)   += rtl818x/
 obj-$(CONFIG_RTL8187)  += rtl818x/
 obj-$(CONFIG_RTLWIFI)  += rtlwifi/
 obj-$(CONFIG_RTL8XXXU) += rtl8xxxu/
+obj-$(CONFIG_RTW88)+= rtw88/
 
diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig 
b/drivers/net/wireless/realtek/rtw88/Kconfig
new file mode 100644
index 000..9bc9698
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -0,0 +1,57 @@
+menuconfig RTW88
+   tristate "Realtek 802.11ac wireless chips support"
+   depends on MAC80211
+   default y
+   help
+ This module adds support for mac80211-based wireless drivers that
+ enables Realtek IEEE 802.11ac wireless chipsets.
+
+ If you choose to build a module, it'll be called rtw88.
+
+if RTW88
+
+config RTW88_CORE
+   tristate
+   depends on RTW88
+
+config RTW88_PCI
+   tristate
+   depends on RTW88_CORE && PCI
+
+config RTW88_8822BE
+   bool "Realtek 8822BE PCI wireless network adapter"
+   depends on PCI
+   select RTW88_CORE
+   select RTW88_PCI
+   help
+ Select this option will enable support for 8822BE chipset
+
+ 802.11ac PCIe wireless network adapter
+
+config RTW88_8822CE
+   bool "Realtek 8822CE PCI wireless network adapter"
+   depends on PCI
+   select RTW88_CORE
+   select RTW88_PCI
+   help
+ Select this option will enable support for 8822CE chipset
+
+ 802.11ac PCIe wireless network adapter
+
+config RTW88_DEBUG
+   bool "Realtek rtw88 debug support"
+   depends on RTW88_CORE
+   help
+ Enable debug support
+
+ If unsure, say Y to simplify debug problems
+
+config RTW88_DEBUGFS
+   bool "Realtek rtw88 debugfs support"
+   depends on RTW88_CORE
+   help
+ Enable debug support
+
+ If unsure, say Y to simplify debug problems
+
+endif
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile 
b/drivers/net/wireless/realtek/rtw88/Makefile
new file mode 100644
index 000..d70782a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -0,0 +1,19 @@
+obj-$(CONFIG_RTW88_CORE)   += rtw88.o
+rtw88-y += main.o \
+  mac80211.o \
+  debug.o \
+  tx.o \
+  rx.o \
+  mac.o \
+  phy.o \
+  efuse.o \
+  fw.o \
+  ps.o \
+  sec.o \
+  regd.o
+
+rtw88-$(CONFIG_RTW88_8822BE)   += rtw8822b.o rtw8822b_table.o
+rtw88-$(CONFIG_RTW88_8822CE)   += rtw8822c.o rtw8822c_table.o
+
+obj-$(CONFIG_RTW88_PCI)+= rtwpci.o
+rtwpci-objs:= pci.o
-- 
2.7.4



[RFC v2 05/12] rtw88: mac files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

mac files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/mac.c | 1045 ++
 drivers/net/wireless/realtek/rtw88/mac.h |   35 +
 2 files changed, 1080 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/mac.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/mac.h

diff --git a/drivers/net/wireless/realtek/rtw88/mac.c 
b/drivers/net/wireless/realtek/rtw88/mac.c
new file mode 100644
index 000..f960890
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -0,0 +1,1045 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "mac.h"
+#include "reg.h"
+#include "fw.h"
+#include "debug.h"
+
+void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+u8 primary_ch_idx)
+{
+   u8 txsc40 = 0, txsc20 = 0;
+   u32 value32;
+   u8 value8;
+
+   txsc20 = primary_ch_idx;
+   if (txsc20 == 1 || txsc20 == 3)
+   txsc40 = 9;
+   else
+   txsc40 = 10;
+   rtw_write8(rtwdev, REG_DATA_SC,
+  BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40));
+
+   value32 = rtw_read32(rtwdev, REG_WMAC_TRXPTCL_CTL);
+   value32 &= ~BIT_RFMOD;
+   switch (bw) {
+   case RTW_CHANNEL_WIDTH_80:
+   value32 |= BIT_RFMOD_80M;
+   break;
+   case RTW_CHANNEL_WIDTH_40:
+   value32 |= BIT_RFMOD_40M;
+   break;
+   case RTW_CHANNEL_WIDTH_20:
+   default:
+   break;
+   }
+   rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32);
+
+   value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL);
+   value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
+   rtw_write32(rtwdev, REG_AFE_CTRL1, value32);
+
+   rtw_write8(rtwdev, REG_USTIME_TSF, MAC_CLK_SPEED);
+   rtw_write8(rtwdev, REG_USTIME_EDCA, MAC_CLK_SPEED);
+
+   value8 = rtw_read8(rtwdev, REG_CCK_CHECK);
+   value8 = value8 & ~BIT_CHECK_CCK_EN;
+   if (channel > 35)
+   value8 |= BIT_CHECK_CCK_EN;
+   rtw_write8(rtwdev, REG_CCK_CHECK, value8);
+}
+
+static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
+{
+   u32 value32;
+   u8 value8;
+
+   rtw_write8(rtwdev, REG_RSV_CTRL, 0);
+
+   switch (rtw_hci_type(rtwdev)) {
+   case RTW_HCI_TYPE_PCIE:
+   rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN);
+   break;
+   case RTW_HCI_TYPE_USB:
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   /* config PIN Mux */
+   value32 = rtw_read32(rtwdev, REG_PAD_CTRL1);
+   value32 |= BIT_PAPE_WLBT_SEL | BIT_LNAON_WLBT_SEL;
+   rtw_write32_set(rtwdev, REG_PAD_CTRL1, value32);
+
+   value32 = rtw_read32(rtwdev, REG_LED_CFG);
+   value32 &= ~(BIT_PAPE_SEL_EN | BIT_LNAON_SEL_EN);
+   rtw_write32(rtwdev, REG_LED_CFG, value32);
+
+   value32 = rtw_read32(rtwdev, REG_GPIO_MUXCFG);
+   value32 |= BIT_WLRFE_4_5_EN;
+   rtw_write32(rtwdev, REG_GPIO_MUXCFG, value32);
+
+   /* disable BB/RF */
+   value8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
+   value8 &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
+   rtw_write8(rtwdev, REG_SYS_FUNC_EN, value8);
+
+   value8 = rtw_read8(rtwdev, REG_RF_CTRL);
+   value8 &= ~(BIT_RF_SDM_RSTB | BIT_RF_RSTB | BIT_RF_EN);
+   rtw_write8(rtwdev, REG_RF_CTRL, value8);
+
+   value32 = rtw_read32(rtwdev, REG_WLRF1);
+   value32 &= ~BIT_WLRF1_BBRF_EN;
+   rtw_write32(rtwdev, REG_WLRF1, value32);
+
+   return 0;
+}
+
+static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev,
+  struct rtw_pwr_seq_cmd *cmd)
+{
+   u8 value;
+   u8 flag = 0;
+   u32 offset;
+   u32 cnt = RTW_PWR_POLLING_CNT;
+
+   if (cmd->base == RTW_PWR_ADDR_SDIO)
+   offset = cmd->offset | SDIO_LOCAL_OFFSET;
+   else
+   offset = cmd->offset;
+
+   do {
+   cnt--;
+   value = rtw_read8(rtwdev, offset);
+   value &= cmd->mask;
+   if (value == (cmd->value & cmd->mask))
+   return 0;
+   if (cnt == 0) {
+   if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE &&
+   flag == 0) {
+   value = rtw_read8(rtwdev, REG_SYS_PW_CTRL);
+   value |= BIT(3);
+   rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+   value &= ~BIT(3);
+   rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+   cnt = RTW_PWR_POLLING_CNT;
+   flag = 1;
+   } else {
+   return -EBUSY;
+   }
+

[RFC v2 11/12] rtw88: 8822C init table

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

8822C init table for chip files Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 .../net/wireless/realtek/rtw88/rtw8822c_table.c| 4150 
 1 file changed, 4150 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c_table.c

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c 
b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c
new file mode 100644
index 000..e95ad82
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c
@@ -0,0 +1,4150 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "phy.h"
+#include "rtw8822c_table.h"
+
+static const u32 rtw8822c_mac[] = {
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8822c_mac, rtw_phy_cfg_mac);
+
+static const u32 rtw8822c_agc[] = {
+   0x1D90, 0x31FF,
+   0x1D90, 0x300101FF,
+   0x1D90, 0x300201FF,
+   0x1D90, 0x300301FF,
+   0x1D90, 0x300401FF,
+   0x1D90, 0x300501FF,
+   0x1D90, 0x300601FE,
+   0x1D90, 0x300701FD,
+   0x1D90, 0x300801FC,
+   0x1D90, 0x300901FB,
+   0x1D90, 0x300A01FA,
+   0x1D90, 0x300B01F9,
+   0x1D90, 0x300C01F8,
+   0x1D90, 0x300D01F7,
+   0x1D90, 0x300E01F6,
+   0x1D90, 0x300F01F5,
+   0x1D90, 0x301001F4,
+   0x1D90, 0x301101F3,
+   0x1D90, 0x301201F2,
+   0x1D90, 0x301301F1,
+   0x1D90, 0x301401F0,
+   0x1D90, 0x301501EF,
+   0x1D90, 0x301601AF,
+   0x1D90, 0x301701AE,
+   0x1D90, 0x301801AD,
+   0x1D90, 0x301901AC,
+   0x1D90, 0x301A01AB,
+   0x1D90, 0x301B01AA,
+   0x1D90, 0x301C01A9,
+   0x1D90, 0x301D0188,
+   0x1D90, 0x301E0187,
+   0x1D90, 0x301F0186,
+   0x1D90, 0x30200185,
+   0x1D90, 0x30210168,
+   0x1D90, 0x30220167,
+   0x1D90, 0x30230166,
+   0x1D90, 0x30240108,
+   0x1D90, 0x30250107,
+   0x1D90, 0x30260106,
+   0x1D90, 0x30270144,
+   0x1D90, 0x30280143,
+   0x1D90, 0x30290142,
+   0x1D90, 0x302A0141,
+   0x1D90, 0x302B0140,
+   0x1D90, 0x302C00C9,
+   0x1D90, 0x302D00C8,
+   0x1D90, 0x302E00C7,
+   0x1D90, 0x302F00C6,
+   0x1D90, 0x303000C5,
+   0x1D90, 0x303100C4,
+   0x1D90, 0x303200C3,
+   0x1D90, 0x30330088,
+   0x1D90, 0x30340087,
+   0x1D90, 0x30350086,
+   0x1D90, 0x30360045,
+   0x1D90, 0x30370044,
+   0x1D90, 0x30380043,
+   0x1D90, 0x30390023,
+   0x1D90, 0x303A0022,
+   0x1D90, 0x303B0021,
+   0x1D90, 0x303C0020,
+   0x1D90, 0x303D0002,
+   0x1D90, 0x303E0001,
+   0x1D90, 0x303F,
+   0x1D90, 0x304000FF,
+   0x1D90, 0x304100FF,
+   0x1D90, 0x304200FF,
+   0x1D90, 0x304300FF,
+   0x1D90, 0x304400FF,
+   0x1D90, 0x304500FE,
+   0x1D90, 0x304600FD,
+   0x1D90, 0x304700FC,
+   0x1D90, 0x304800FB,
+   0x1D90, 0x304900FA,
+   0x1D90, 0x304A00F9,
+   0x1D90, 0x304B00F8,
+   0x1D90, 0x304C00F7,
+   0x1D90, 0x304D00F6,
+   0x1D90, 0x304E00F5,
+   0x1D90, 0x304F00F4,
+   0x1D90, 0x305000F3,
+   0x1D90, 0x305100F2,
+   0x1D90, 0x305200F1,
+   0x1D90, 0x305300F0,
+   0x1D90, 0x305400EF,
+   0x1D90, 0x305500EE,
+   0x1D90, 0x305600ED,
+   0x1D90, 0x305700EC,
+   0x1D90, 0x305800EB,
+   0x1D90, 0x305900EA,
+   0x1D90, 0x305A00E9,
+   0x1D90, 0x305B00E8,
+   0x1D90, 0x305C00E7,
+   0x1D90, 0x305D00E6,
+   0x1D90, 0x305E00E5,
+   0x1D90, 0x305F00E4,
+   0x1D90, 0x306000E3,
+   0x1D90, 0x306100C3,
+   0x1D90, 0x306200C2,
+   0x1D90, 0x306300C1,
+   0x1D90, 0x30640088,
+   0x1D90, 0x30650087,
+   0x1D90, 0x30660086,
+   0x1D90, 0x30670085,
+   0x1D90, 0x30680084,
+   0x1D90, 0x30690083,
+   0x1D90, 0x306A0082,
+   0x1D90, 0x306B0081,
+   0x1D90, 0x306C0068,
+   0x1D90, 0x306D0067,
+   0x1D90, 0x306E0066,
+   0x1D90, 0x306F0065,
+   0x1D90, 0x30700064,
+   0x1D90, 0x30710063,
+   

[RFC v2 06/12] rtw88: fw and efuse files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

fw and efuse files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/efuse.c | 150 +++
 drivers/net/wireless/realtek/rtw88/efuse.h |  53 +++
 drivers/net/wireless/realtek/rtw88/fw.c| 638 +
 drivers/net/wireless/realtek/rtw88/fw.h| 182 
 4 files changed, 1023 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/efuse.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/efuse.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/fw.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/fw.h

diff --git a/drivers/net/wireless/realtek/rtw88/efuse.c 
b/drivers/net/wireless/realtek/rtw88/efuse.c
new file mode 100644
index 000..7c1b782
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/efuse.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "efuse.h"
+#include "reg.h"
+#include "debug.h"
+
+#define RTW_EFUSE_BANK_WIFI0x0
+
+static void switch_efuse_bank(struct rtw_dev *rtwdev)
+{
+   rtw_write32_mask(rtwdev, REG_LDO_EFUSE_CTRL, BIT_MASK_EFUSE_BANK_SEL,
+RTW_EFUSE_BANK_WIFI);
+}
+
+static int rtw_dump_logical_efuse_map(struct rtw_dev *rtwdev, u8 *phy_map,
+ u8 *log_map)
+{
+   u32 physical_size = rtwdev->efuse.physical_size;
+   u32 protect_size = rtwdev->efuse.protect_size;
+   u32 logical_size = rtwdev->efuse.logical_size;
+   u32 phy_idx, log_idx;
+   u8 hdr1, hdr2;
+   u8 blk_idx;
+   u8 valid;
+   u8 word_en;
+   int i;
+
+   phy_idx = 0;
+
+   do {
+   hdr1 = *(phy_map + phy_idx);
+   if ((hdr1 & 0x1f) == 0xf) {
+   phy_idx++;
+   hdr2 = *(phy_map + phy_idx);
+   if (hdr2 == 0xff)
+   break;
+   blk_idx = ((hdr2 & 0xf0) >> 1) | ((hdr1 >> 5) & 0x07);
+   word_en = hdr2 & 0x0f;
+   } else {
+   blk_idx = (hdr1 & 0xf0) >> 4;
+   word_en = hdr1 & 0x0f;
+   }
+
+   if (hdr1 == 0xff)
+   break;
+
+   phy_idx++;
+   for (i = 0; i < 4; i++) {
+   valid = (~(word_en >> i)) & 0x1;
+   if (valid != 0x1)
+   continue;
+   log_idx = (blk_idx << 3) + (i << 1);
+   *(log_map + log_idx) = *(phy_map + phy_idx);
+   log_idx++;
+   phy_idx++;
+   *(log_map + log_idx) = *(phy_map + phy_idx);
+   phy_idx++;
+   if (phy_idx > physical_size - protect_size ||
+   log_idx > logical_size)
+   return -EINVAL;
+   }
+   } while (1);
+
+   return 0;
+}
+
+static int rtw_dump_physical_efuse_map(struct rtw_dev *rtwdev, u8 *map)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   u32 size = rtwdev->efuse.physical_size;
+   u32 efuse_ctl;
+   u32 addr;
+   u32 cnt;
+
+   switch_efuse_bank(rtwdev);
+
+   /* disable 2.5V LDO */
+   chip->ops->cfg_ldo25(rtwdev, false);
+
+   efuse_ctl = rtw_read32(rtwdev, REG_EFUSE_CTRL);
+
+   for (addr = 0; addr < size; addr++) {
+   efuse_ctl &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
+   efuse_ctl |= (addr & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR;
+   rtw_write32(rtwdev, REG_EFUSE_CTRL, efuse_ctl & (~BIT_EF_FLAG));
+
+   cnt = 100;
+   do {
+   udelay(1);
+   efuse_ctl = rtw_read32(rtwdev, REG_EFUSE_CTRL);
+   if (--cnt == 0)
+   return -EBUSY;
+   } while (!(efuse_ctl & BIT_EF_FLAG));
+
+   *(map + addr) = (u8)(efuse_ctl & BIT_MASK_EF_DATA);
+   }
+
+   return 0;
+}
+
+int rtw_parse_efuse_map(struct rtw_dev *rtwdev)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   struct rtw_efuse *efuse = >efuse;
+   u32 phy_size = efuse->physical_size;
+   u32 log_size = efuse->logical_size;
+   u8 *phy_map = NULL;
+   u8 *log_map = NULL;
+   int ret = 0;
+
+   phy_map = kmalloc(phy_size, GFP_KERNEL);
+   log_map = kmalloc(log_size, GFP_KERNEL);
+   if (!phy_map || !log_map) {
+   ret = -ENOMEM;
+   goto out_free;
+   }
+
+   ret = rtw_dump_physical_efuse_map(rtwdev, phy_map);
+   if (ret) {
+   rtw_err(rtwdev, "failed to dump efuse physical map\n");
+   goto out_free;
+   }
+
+   memset(log_map, 0xff, log_size);
+   ret = rtw_dump_logical_efuse_map(rtwdev, phy_map, 

[RFC v2 01/12] rtw88: main files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

main files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/mac80211.c |  482 ++
 drivers/net/wireless/realtek/rtw88/main.c | 1133 +++
 drivers/net/wireless/realtek/rtw88/main.h | 1200 +
 drivers/net/wireless/realtek/rtw88/reg.h  |  404 +
 4 files changed, 3219 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/mac80211.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/main.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/main.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/reg.h

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c 
b/drivers/net/wireless/realtek/rtw88/mac80211.c
new file mode 100644
index 000..b3d9ab1
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "sec.h"
+#include "tx.h"
+#include "fw.h"
+#include "mac.h"
+#include "ps.h"
+#include "reg.h"
+#include "debug.h"
+
+static void rtw_ops_tx(struct ieee80211_hw *hw,
+  struct ieee80211_tx_control *control,
+  struct sk_buff *skb)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   struct rtw_tx_pkt_info pkt_info = {0};
+
+   if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING))
+   goto out;
+
+   rtw_tx_pkt_info_update(rtwdev, _info, control, skb);
+   if (rtw_hci_tx(rtwdev, _info, skb))
+   goto out;
+
+   return;
+
+out:
+   ieee80211_free_txskb(hw, skb);
+}
+
+static int rtw_ops_start(struct ieee80211_hw *hw)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   int ret;
+
+   mutex_lock(>mutex);
+   ret = rtw_core_start(rtwdev);
+   mutex_unlock(>mutex);
+
+   return ret;
+}
+
+static void rtw_ops_stop(struct ieee80211_hw *hw)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+
+   mutex_lock(>mutex);
+   rtw_core_stop(rtwdev);
+   mutex_unlock(>mutex);
+}
+
+static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   int ret = 0;
+
+   mutex_lock(>mutex);
+
+   if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+   if (hw->conf.flags & IEEE80211_CONF_IDLE) {
+   rtw_enter_ips(rtwdev);
+   } else {
+   ret = rtw_leave_ips(rtwdev);
+   if (ret) {
+   rtw_err(rtwdev, "failed to leave idle state\n");
+   goto out;
+   }
+   }
+   }
+
+   if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+   rtw_set_channel(rtwdev);
+
+out:
+   mutex_unlock(>mutex);
+   return ret;
+}
+
+static struct rtw_vif_port rtw_vif_port[] = {
+   [0] = {
+   .mac_addr   = {.addr = 0x0610},
+   .bssid  = {.addr = 0x0618},
+   .net_type   = {.addr = 0x0100, .mask = 0x3},
+   .aid= {.addr = 0x06a8, .mask = 0x7ff},
+   },
+   [1] = {
+   .mac_addr   = {.addr = 0x0700},
+   .bssid  = {.addr = 0x0708},
+   .net_type   = {.addr = 0x0100, .mask = 0xc},
+   .aid= {.addr = 0x0710, .mask = 0x7ff},
+   },
+   [2] = {
+   .mac_addr   = {.addr = 0x1620},
+   .bssid  = {.addr = 0x1628},
+   .net_type   = {.addr = 0x1100, .mask = 0x3},
+   .aid= {.addr = 0x1600, .mask = 0x7ff},
+   },
+   [3] = {
+   .mac_addr   = {.addr = 0x1630},
+   .bssid  = {.addr = 0x1638},
+   .net_type   = {.addr = 0x1100, .mask = 0xc},
+   .aid= {.addr = 0x1604, .mask = 0x7ff},
+   },
+   [4] = {
+   .mac_addr   = {.addr = 0x1640},
+   .bssid  = {.addr = 0x1648},
+   .net_type   = {.addr = 0x1100, .mask = 0x30},
+   .aid= {.addr = 0x1608, .mask = 0x7ff},
+   },
+};
+
+static int rtw_ops_add_interface(struct ieee80211_hw *hw,
+struct ieee80211_vif *vif)
+{
+   struct rtw_dev *rtwdev = hw->priv;
+   struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+   enum rtw_net_type net_type;
+   u32 config = 0;
+   u8 port = 0;
+
+   vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+   rtwvif->port = port;
+   rtwvif->vif = vif;
+   rtwvif->stats.tx_unicast = 0;
+   rtwvif->stats.rx_unicast = 0;
+   rtwvif->stats.tx_cnt = 0;
+   rtwvif->stats.rx_cnt = 0;
+   rtwvif->in_lps = false;
+   rtwvif->conf = _vif_port[port];
+   INIT_LIST_HEAD(>sta_list);
+
+   mutex_lock(>mutex);
+
+   

[RFC v2 03/12] rtw88: hci files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

hci files for Realtek 802.11ac wireless network chips

For now there is only PCI bus supported by rtwlan, in the future it
will also have USB/SDIO

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/hci.h |  212 ++
 drivers/net/wireless/realtek/rtw88/pci.c | 1220 ++
 drivers/net/wireless/realtek/rtw88/pci.h |  228 ++
 3 files changed, 1660 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/hci.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/pci.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/pci.h

diff --git a/drivers/net/wireless/realtek/rtw88/hci.h 
b/drivers/net/wireless/realtek/rtw88/hci.h
new file mode 100644
index 000..e1f200b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/hci.h
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#ifndef__RTW_HCI_H__
+#define __RTW_HCI_H__
+
+/* ops for PCI, USB and SDIO */
+struct rtw_hci_ops {
+   int (*tx)(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ struct sk_buff *skb);
+   int (*setup)(struct rtw_dev *rtwdev);
+   int (*start)(struct rtw_dev *rtwdev);
+   void (*stop)(struct rtw_dev *rtwdev);
+
+   int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
+   int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
+
+   u8 (*read8)(struct rtw_dev *rtwdev, u32 addr);
+   u16 (*read16)(struct rtw_dev *rtwdev, u32 addr);
+   u32 (*read32)(struct rtw_dev *rtwdev, u32 addr);
+   void (*write8)(struct rtw_dev *rtwdev, u32 addr, u8 val);
+   void (*write16)(struct rtw_dev *rtwdev, u32 addr, u16 val);
+   void (*write32)(struct rtw_dev *rtwdev, u32 addr, u32 val);
+   int (*check_avail_desc)(struct rtw_dev *rtwdev, struct sk_buff *skb);
+};
+
+static inline int rtw_hci_tx(struct rtw_dev *rtwdev,
+struct rtw_tx_pkt_info *pkt_info,
+struct sk_buff *skb)
+{
+   return rtwdev->hci.ops->tx(rtwdev, pkt_info, skb);
+}
+
+static inline int rtw_hci_setup(struct rtw_dev *rtwdev)
+{
+   return rtwdev->hci.ops->setup(rtwdev);
+}
+
+static inline int rtw_hci_start(struct rtw_dev *rtwdev)
+{
+   return rtwdev->hci.ops->start(rtwdev);
+}
+
+static inline void rtw_hci_stop(struct rtw_dev *rtwdev)
+{
+   rtwdev->hci.ops->stop(rtwdev);
+}
+
+static inline int
+rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
+{
+   return rtwdev->hci.ops->write_data_rsvd_page(rtwdev, buf, size);
+}
+
+static inline int
+rtw_hci_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
+{
+   return rtwdev->hci.ops->write_data_h2c(rtwdev, buf, size);
+}
+
+static inline u8 rtw_read8(struct rtw_dev *rtwdev, u32 addr)
+{
+   return rtwdev->hci.ops->read8(rtwdev, addr);
+}
+
+static inline u16 rtw_read16(struct rtw_dev *rtwdev, u32 addr)
+{
+   return rtwdev->hci.ops->read16(rtwdev, addr);
+}
+
+static inline u32 rtw_read32(struct rtw_dev *rtwdev, u32 addr)
+{
+   return rtwdev->hci.ops->read32(rtwdev, addr);
+}
+
+static inline void rtw_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
+{
+   rtwdev->hci.ops->write8(rtwdev, addr, val);
+}
+
+static inline void rtw_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
+{
+   rtwdev->hci.ops->write16(rtwdev, addr, val);
+}
+
+static inline void rtw_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
+{
+   rtwdev->hci.ops->write32(rtwdev, addr, val);
+}
+
+static inline void rtw_write8_set(struct rtw_dev *rtwdev, u32 addr, u8 bit)
+{
+   u8 val;
+
+   val = rtw_read8(rtwdev, addr);
+   rtw_write8(rtwdev, addr, val | bit);
+}
+
+static inline void rtw_writ16_set(struct rtw_dev *rtwdev, u32 addr, u16 bit)
+{
+   u16 val;
+
+   val = rtw_read16(rtwdev, addr);
+   rtw_write16(rtwdev, addr, val | bit);
+}
+
+static inline void rtw_write32_set(struct rtw_dev *rtwdev, u32 addr, u32 bit)
+{
+   u32 val;
+
+   val = rtw_read32(rtwdev, addr);
+   rtw_write32(rtwdev, addr, val | bit);
+}
+
+static inline void rtw_write8_clr(struct rtw_dev *rtwdev, u32 addr, u8 bit)
+{
+   u8 val;
+
+   val = rtw_read8(rtwdev, addr);
+   rtw_write8(rtwdev, addr, val & ~bit);
+}
+
+static inline void rtw_write16_clr(struct rtw_dev *rtwdev, u32 addr, u16 bit)
+{
+   u16 val;
+
+   val = rtw_read16(rtwdev, addr);
+   rtw_write16(rtwdev, addr, val & ~bit);
+}
+
+static inline void rtw_write32_clr(struct rtw_dev *rtwdev, u32 addr, u32 bit)
+{
+   u32 val;
+
+   val = rtw_read32(rtwdev, addr);
+   rtw_write32(rtwdev, addr, val & ~bit);
+}
+
+static inline u32
+rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
+   u32 addr, u32 mask)
+{
+   unsigned long flags;
+   u32 val;
+
+   spin_lock_irqsave(>rf_lock, flags);
+   val = 

[RFC v2 04/12] rtw88: trx files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

trx files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/rx.c | 144 +
 drivers/net/wireless/realtek/rtw88/rx.h |  30 
 drivers/net/wireless/realtek/rtw88/tx.c | 271 
 drivers/net/wireless/realtek/rtw88/tx.h |  81 ++
 4 files changed, 526 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rx.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rx.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/tx.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/tx.h

diff --git a/drivers/net/wireless/realtek/rtw88/rx.c 
b/drivers/net/wireless/realtek/rtw88/rx.c
new file mode 100644
index 000..83214db
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rx.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "rx.h"
+#include "ps.h"
+
+void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
+ struct sk_buff *skb)
+{
+   struct ieee80211_hdr *hdr;
+   struct rtw_vif *rtwvif;
+
+   hdr = (struct ieee80211_hdr *)skb->data;
+
+   if (!ieee80211_is_data(hdr->frame_control))
+   return;
+
+   if (!is_broadcast_ether_addr(hdr->addr1) &&
+   !is_multicast_ether_addr(hdr->addr1)) {
+   rtwdev->stats.rx_unicast += skb->len;
+   rtwdev->stats.rx_cnt++;
+   if (vif) {
+   rtwvif = (struct rtw_vif *)vif->drv_priv;
+   rtwvif->stats.rx_unicast += skb->len;
+   rtwvif->stats.rx_cnt++;
+   if (rtwvif->stats.rx_cnt > RTW_LPS_THRESHOLD)
+   rtw_leave_lps_irqsafe(rtwdev, rtwvif);
+   }
+   }
+}
+EXPORT_SYMBOL(rtw_rx_stats);
+
+static void rtw_rx_rssi_add(struct rtw_dev *rtwdev,
+   struct rtw_rx_pkt_stat *pkt_stat,
+   struct ieee80211_hdr *hdr)
+{
+   struct ieee80211_vif *vif;
+   struct rtw_vif *rtwvif;
+   struct rtw_sta_info *si;
+   __le16 fc = hdr->frame_control;
+   u8 *bssid;
+   u8 macid = RTW_BC_MC_MACID;
+   bool match_bssid = false;
+   bool is_packet_match_bssid;
+   bool if_addr_match;
+   bool hw_err;
+   bool ctl;
+
+   rcu_read_lock();
+
+   bssid = get_hdr_bssid(hdr);
+   rtwvif = get_hdr_vif(rtwdev, hdr);
+   vif = rtwvif ? rtwvif->vif : NULL;
+   pkt_stat->vif = vif;
+   if (unlikely(is_broadcast_ether_addr(hdr->addr1) ||
+is_multicast_ether_addr(hdr->addr1)))
+   match_bssid = get_hdr_match_bssid(rtwdev, hdr, bssid);
+   else if (vif)
+   match_bssid = ether_addr_equal(vif->bss_conf.bssid, bssid);
+   si = get_hdr_sta(rtwdev, vif, hdr);
+   macid = si ? si->mac_id : RTW_BC_MC_MACID;
+   pkt_stat->mac_id = macid;
+   pkt_stat->si = si;
+
+   if_addr_match = !!vif;
+   hw_err = pkt_stat->crc_err || pkt_stat->icv_err;
+   ctl = ieee80211_is_ctl(fc);
+   is_packet_match_bssid = !hw_err && !ctl && match_bssid;
+
+   if (((match_bssid && if_addr_match) || ieee80211_is_beacon(fc)) &&
+   (!hw_err && !ctl) && (pkt_stat->phy_status && pkt_stat->si))
+   ewma_rssi_add(_stat->si->avg_rssi, pkt_stat->rssi);
+
+   rcu_read_unlock();
+}
+
+void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
+  struct rtw_rx_pkt_stat *pkt_stat,
+  struct ieee80211_hdr *hdr,
+  struct ieee80211_rx_status *rx_status,
+  u8 *phy_status)
+{
+   struct ieee80211_hw *hw = rtwdev->hw;
+
+   memset(rx_status, 0, sizeof(*rx_status));
+   rx_status->freq = hw->conf.chandef.chan->center_freq;
+   rx_status->band = hw->conf.chandef.chan->band;
+   if (pkt_stat->crc_err)
+   rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+   if (pkt_stat->decrypted)
+   rx_status->flag |= RX_FLAG_DECRYPTED;
+
+   if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0)
+   rx_status->encoding = RX_ENC_VHT;
+   else if (pkt_stat->rate >= DESC_RATEMCS0)
+   rx_status->encoding = RX_ENC_HT;
+
+   if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0 &&
+   pkt_stat->rate <= DESC_RATEVHT1SS_MCS9) {
+   rx_status->nss = 1;
+   rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT1SS_MCS0;
+   } else if (pkt_stat->rate >= DESC_RATEVHT2SS_MCS0 &&
+  pkt_stat->rate <= DESC_RATEVHT2SS_MCS9) {
+   rx_status->nss = 2;
+   rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT2SS_MCS0;
+   } else if (pkt_stat->rate >= DESC_RATEVHT3SS_MCS0 &&
+  pkt_stat->rate <= DESC_RATEVHT3SS_MCS9) {
+   rx_status->nss = 3;
+

[RFC v2 08/12] rtw88: debug files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

debug files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/debug.c | 652 +
 drivers/net/wireless/realtek/rtw88/debug.h |  45 ++
 2 files changed, 697 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/debug.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/debug.h

diff --git a/drivers/net/wireless/realtek/rtw88/debug.c 
b/drivers/net/wireless/realtek/rtw88/debug.c
new file mode 100644
index 000..e00c602
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -0,0 +1,652 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include 
+#include 
+#include "main.h"
+#include "sec.h"
+#include "fw.h"
+#include "debug.h"
+
+#ifdef CONFIG_RTW88_DEBUGFS
+
+struct rtw_debugfs_priv {
+   struct rtw_dev *rtwdev;
+   int (*cb_read)(struct seq_file *m, void *v);
+   ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
+   size_t count, loff_t *loff);
+   union {
+   u32 cb_data;
+   u8 *buf;
+   struct {
+   u32 page_offset;
+   u32 page_num;
+   } rsvd_page;
+   struct {
+   u8 rf_path;
+   u32 rf_addr;
+   u32 rf_mask;
+   };
+   struct {
+   u32 addr;
+   u32 len;
+   } read_reg;
+   };
+};
+
+static int rtw_debugfs_single_show(struct seq_file *m, void *v)
+{
+   struct rtw_debugfs_priv *debugfs_priv = m->private;
+
+   return debugfs_priv->cb_read(m, v);
+}
+
+static ssize_t rtw_debugfs_common_write(struct file *filp,
+   const char __user *buffer,
+   size_t count, loff_t *loff)
+{
+   struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
+
+   return debugfs_priv->cb_write(filp, buffer, count, loff);
+}
+
+static ssize_t rtw_debugfs_single_write(struct file *filp,
+   const char __user *buffer,
+   size_t count, loff_t *loff)
+{
+   struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
+   struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
+
+   return debugfs_priv->cb_write(filp, buffer, count, loff);
+}
+
+static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp)
+{
+   return single_open(filp, rtw_debugfs_single_show, inode->i_private);
+}
+
+static int rtw_debugfs_close(struct inode *inode, struct file *filp)
+{
+   return 0;
+}
+
+static const struct file_operations file_ops_single_r = {
+   .owner = THIS_MODULE,
+   .open = rtw_debugfs_single_open_rw,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = seq_release,
+};
+
+static const struct file_operations file_ops_single_rw = {
+   .owner = THIS_MODULE,
+   .open = rtw_debugfs_single_open_rw,
+   .release = single_release,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .write = rtw_debugfs_single_write,
+};
+
+static const struct file_operations file_ops_common_write = {
+   .owner = THIS_MODULE,
+   .write = rtw_debugfs_common_write,
+   .open = simple_open,
+   .release = rtw_debugfs_close,
+};
+
+static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v)
+{
+   struct rtw_debugfs_priv *debugfs_priv = m->private;
+   struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+   u32 val, len, addr;
+
+   len = debugfs_priv->read_reg.len;
+   addr = debugfs_priv->read_reg.addr;
+   switch (len) {
+   case 1:
+   val = rtw_read8(rtwdev, addr);
+   seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val);
+   break;
+   case 2:
+   val = rtw_read16(rtwdev, addr);
+   seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val);
+   break;
+   case 4:
+   val = rtw_read32(rtwdev, addr);
+   seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val);
+   break;
+   }
+   return 0;
+}
+
+static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)
+{
+   struct rtw_debugfs_priv *debugfs_priv = m->private;
+   struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+   u32 val, addr, mask;
+   u8 path;
+
+   path = debugfs_priv->rf_path;
+   addr = debugfs_priv->rf_addr;
+   mask = debugfs_priv->rf_mask;
+
+   val = rtw_read_rf(rtwdev, path, addr, mask);
+
+   seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
+  path, addr, mask, val);
+
+   return 0;
+}
+
+static int rtw_debugfs_copy_from_user(char tmp[], int size,
+ const char __user *buffer, size_t count,
+   

[RFC v2 00/12] rtw88: mac80211 driver for Realtek 802.11ac wireless network chips

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

This is a new mac80211 driver for Realtek 802.11ac wireless network chips.
rtwlan supports 8822BE and 8822CE chips, and will be able to support
multi-vif combinations in run-time.

For now, only PCI bus is supported, but rtwlan was originally designed
to optionally support three buses includes USB & SDIO. USB & SDIO modules
will soon be supported by rtwlan, with configurable core module to fit
with different bus modules in the same time.

For example, if we choose 8822BE and 8822CU, only PCI & USB modules will
be selected, built, loaded into kernel. This is one of the major
difference from rtlwifi, which can only support specific combinations.

Another difference from rtlwifi is that rtwlan is designed to support
the latest Realtek 802.11ac wireless network chips like 8822B and
8822C series. Compared to the earlier chips supported by rtlwifi like
the 802.11n 8192EE chipset or 802.11ac 8821AE/8812AE chips, newer ICs
have different MAC & PHY settings, such as new multi-port feature for the
MAC layer design and Jaguar2/Jaguar3 PHY layer IPs.

Multi-Port feature is also supported under rtwlan's software architecture.
rtlwifi can only support one vif in the same time, most because of the
hardware limitations for early chips, hence the original design of it
also restricts the usage of multi-vif support, so latest chipset seems not
take advantages from its new MAC engine.

However, rtwlan can run multiple vifs concurrently by holding them on
hardware ports provided by MAC engine, hence can easily start different
roles on a single device.

Based on the reasons mentioned before, we implemented rtwlan. It had many
authors, they are listed here alphabetically:

Ping-Ke Shih 
Tzu-En Huang 
Yan-Hsuan Chuang 


v2

 - rename from rtwlan to rtw88
 - remove lots of magic numbers
 - add pci null entry for auto load on boot
 - add rtwdev->mutex to protect against mac80211 callbacks
 - add rcu lock protection for vif_list and sta_list
 - refine bits & endian macros to use helper functions provided by kernel
   instead of create new ones
 - ieee80211_free_txskb for tx path dropped packets
 - not register iface_combination since now only one vif is allowed
 - some fixes suggested by Stanislaw


Yan-Hsuan Chuang (12):
  rtw88: main files
  rtw88: core files
  rtw88: hci files
  rtw88: trx files
  rtw88: mac files
  rtw88: fw and efuse files
  rtw88: phy files
  rtw88: debug files
  rtw88: chip files
  rtw88: 8822B init table
  rtw88: 8822C init table
  rtw88: Kconfig & Makefile

 drivers/net/wireless/realtek/Kconfig   | 1 +
 drivers/net/wireless/realtek/Makefile  | 1 +
 drivers/net/wireless/realtek/rtw88/Kconfig |57 +
 drivers/net/wireless/realtek/rtw88/Makefile|19 +
 drivers/net/wireless/realtek/rtw88/debug.c |   652 +
 drivers/net/wireless/realtek/rtw88/debug.h |45 +
 drivers/net/wireless/realtek/rtw88/efuse.c |   150 +
 drivers/net/wireless/realtek/rtw88/efuse.h |53 +
 drivers/net/wireless/realtek/rtw88/fw.c|   638 +
 drivers/net/wireless/realtek/rtw88/fw.h|   182 +
 drivers/net/wireless/realtek/rtw88/hci.h   |   212 +
 drivers/net/wireless/realtek/rtw88/mac.c   |  1045 +
 drivers/net/wireless/realtek/rtw88/mac.h   |35 +
 drivers/net/wireless/realtek/rtw88/mac80211.c  |   482 +
 drivers/net/wireless/realtek/rtw88/main.c  |  1133 +
 drivers/net/wireless/realtek/rtw88/main.h  |  1200 ++
 drivers/net/wireless/realtek/rtw88/pci.c   |  1220 ++
 drivers/net/wireless/realtek/rtw88/pci.h   |   228 +
 drivers/net/wireless/realtek/rtw88/phy.c   |  1675 ++
 drivers/net/wireless/realtek/rtw88/phy.h   |   125 +
 drivers/net/wireless/realtek/rtw88/ps.c|   198 +
 drivers/net/wireless/realtek/rtw88/ps.h|21 +
 drivers/net/wireless/realtek/rtw88/reg.h   |   404 +
 drivers/net/wireless/realtek/rtw88/regd.c  |   462 +
 drivers/net/wireless/realtek/rtw88/regd.h  |40 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c  |  1593 ++
 drivers/net/wireless/realtek/rtw88/rtw8822b.h  |   271 +
 .../net/wireless/realtek/rtw88/rtw8822b_table.c| 20783 +++
 .../net/wireless/realtek/rtw88/rtw8822b_table.h|18 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c  |  1170 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.h  |   416 +
 .../net/wireless/realtek/rtw88/rtw8822c_table.c|  4150 
 .../net/wireless/realtek/rtw88/rtw8822c_table.h|16 +
 drivers/net/wireless/realtek/rtw88/rx.c|   144 +
 drivers/net/wireless/realtek/rtw88/rx.h|30 +
 drivers/net/wireless/realtek/rtw88/sec.c   |   135 +
 drivers/net/wireless/realtek/rtw88/sec.h   |40 +
 drivers/net/wireless/realtek/rtw88/tx.c|   271 +
 drivers/net/wireless/realtek/rtw88/tx.h|81 +
 39 files changed, 39396 

[RFC v2 07/12] rtw88: phy files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

phy files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/phy.c | 1675 ++
 drivers/net/wireless/realtek/rtw88/phy.h |  125 +++
 2 files changed, 1800 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/phy.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/phy.h

diff --git a/drivers/net/wireless/realtek/rtw88/phy.c 
b/drivers/net/wireless/realtek/rtw88/phy.c
new file mode 100644
index 000..a8b2de2
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -0,0 +1,1675 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "fw.h"
+#include "phy.h"
+#include "debug.h"
+
+struct phy_cfg_pair {
+   u32 addr;
+   u32 data;
+};
+
+union phy_table_tile {
+   struct rtw_phy_cond cond;
+   struct phy_cfg_pair cfg;
+};
+
+struct phy_pg_cfg_pair {
+   u32 band;
+   u32 rf_path;
+   u32 tx_num;
+   u32 addr;
+   u32 bitmask;
+   u32 data;
+};
+
+struct txpwr_lmt_cfg_pair {
+   u8 regd;
+   u8 band;
+   u8 bw;
+   u8 rs;
+   u8 ch;
+   s8 txpwr_lmt;
+};
+
+static const u32 db_invert_table[12][8] = {
+   {10,13, 16, 20,
+25,32, 40, 50},
+   {64,80, 101,128,
+160,   201,256,318},
+   {401,   505,635,800,
+1007,  1268,   1596,   2010},
+   {316,   398,501,631,
+794,   1000,   1259,   1585},
+   {1995,  2512,   3162,   3981,
+5012,  6310,   7943,   1},
+   {12589, 15849,  19953,  25119,
+31623, 39811,  50119,  63098},
+   {79433, 10, 125893, 158489,
+199526,251189, 316228, 398107},
+   {501187,630957, 794328, 100,
+1258925,   1584893,1995262,2511886},
+   {3162278,   3981072,5011872,6309573,
+7943282,   100,12589254,   15848932},
+   {19952623,  25118864,   31622777,   39810717,
+50118723,  63095734,   79432823,   1},
+   {125892541, 158489319,  199526232,  251188643,
+316227766, 398107171,  501187234,  630957345},
+   {794328235, 10, 1258925412, 1584893192,
+1995262315,2511886432U,3162277660U,3981071706U}
+};
+
+enum rtw_phy_band_type {
+   PHY_BAND_2G = 0,
+   PHY_BAND_5G = 1,
+};
+
+void rtw_phy_init(struct rtw_dev *rtwdev)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   struct rtw_dm_info *dm_info = >dm_info;
+   u32 addr, mask;
+
+   dm_info->fa_history[3] = 0;
+   dm_info->fa_history[2] = 0;
+   dm_info->fa_history[1] = 0;
+   dm_info->fa_history[0] = 0;
+   dm_info->igi_bitmap = 0;
+   dm_info->igi_history[3] = 0;
+   dm_info->igi_history[2] = 0;
+   dm_info->igi_history[1] = 0;
+
+   addr = chip->dig[0].addr;
+   mask = chip->dig[0].mask;
+   dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask);
+}
+
+void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+   struct rtw_hal *hal = >hal;
+   u32 addr, mask;
+   u8 path;
+
+   for (path = 0; path < hal->rf_path_num; path++) {
+   addr = chip->dig[path].addr;
+   mask = chip->dig[path].mask;
+   rtw_write32_mask(rtwdev, addr, mask, igi);
+   }
+}
+
+static void rtw_phy_stat_false_alarm(struct rtw_dev *rtwdev)
+{
+   struct rtw_chip_info *chip = rtwdev->chip;
+
+   chip->ops->false_alarm_statistics(rtwdev);
+}
+
+#define RA_FLOOR_TABLE_SIZE7
+#define RA_FLOOR_UP_GAP3
+
+static u8 rtw_phy_get_rssi_level(u8 old_level, u8 rssi)
+{
+   u8 table[RA_FLOOR_TABLE_SIZE] = {20, 34, 38, 42, 46, 50, 100};
+   u8 new_level = 0;
+   int i;
+
+   for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++)
+   if (i >= old_level)
+   table[i] += RA_FLOOR_UP_GAP;
+
+   for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
+   if (rssi < table[i]) {
+   new_level = i;
+   break;
+   }
+   }
+
+   return new_level;
+}
+
+static void rtw_phy_stat_rssi(struct rtw_dev *rtwdev)
+{
+   struct rtw_dm_info *dm_info = >dm_info;
+   struct rtw_vif *rtwvif;
+   struct rtw_sta_info *si;
+   u8 min_rssi = U8_MAX;
+   u8 rssi;
+   u8 rssi_level;
+
+   rcu_read_lock();

[RFC v2 09/12] rtw88: chip files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

chip files Realtek 802.11ac wireless network chips
8822B & 8822C series files

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/rtw8822b.c  | 1593 
 drivers/net/wireless/realtek/rtw88/rtw8822b.h  |  271 
 .../net/wireless/realtek/rtw88/rtw8822b_table.h|   18 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c  | 1170 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.h  |  416 +
 .../net/wireless/realtek/rtw88/rtw8822c_table.h|   16 +
 6 files changed, 3484 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822b_table.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822c_table.h

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c 
b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
new file mode 100644
index 000..f051075
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -0,0 +1,1593 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "fw.h"
+#include "tx.h"
+#include "rx.h"
+#include "phy.h"
+#include "rtw8822b.h"
+#include "rtw8822b_table.h"
+#include "mac.h"
+#include "reg.h"
+#include "debug.h"
+
+static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
+u8 rx_path, bool is_tx2_path);
+
+static void rtw8822be_efuse_parsing(struct rtw_efuse *efuse,
+   struct rtw8822b_efuse *map)
+{
+   ether_addr_copy(efuse->addr, map->e.mac_addr);
+}
+
+static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+   struct rtw_efuse *efuse = >efuse;
+   struct rtw8822b_efuse *map;
+   int i;
+
+   map = (struct rtw8822b_efuse *)log_map;
+
+   efuse->rfe_option = map->rfe_option;
+   efuse->crystal_cap = map->xtal_k;
+   efuse->pa_type_2g = map->pa_type;
+   efuse->pa_type_5g = map->pa_type;
+   efuse->lna_type_2g = map->lna_type_2g[0];
+   efuse->lna_type_5g = map->lna_type_5g[0];
+   efuse->channel_plan = map->channel_plan;
+   efuse->bt_setting = map->rf_bt_setting;
+   efuse->regd = map->rf_board_option & 0x7;
+
+   for (i = 0; i < 4; i++)
+   efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
+
+   switch (rtw_hci_type(rtwdev)) {
+   case RTW_HCI_TYPE_PCIE:
+   rtw8822be_efuse_parsing(efuse, map);
+   break;
+   default:
+   /* unsupported now */
+   return -ENOTSUPP;
+   }
+
+   return 0;
+}
+
+static void rtw8822b_phy_rfe_init(struct rtw_dev *rtwdev)
+{
+   /* chip top mux */
+   rtw_write32_mask(rtwdev, 0x64, BIT(29) | BIT(28), 0x3);
+   rtw_write32_mask(rtwdev, 0x4c, BIT(26) | BIT(25), 0x0);
+   rtw_write32_mask(rtwdev, 0x40, BIT(2), 0x1);
+
+   /* from s0 or s1 */
+   rtw_write32_mask(rtwdev, 0x1990, 0x3f, 0x30);
+   rtw_write32_mask(rtwdev, 0x1990, (BIT(11) | BIT(10)), 0x3);
+
+   /* input or output */
+   rtw_write32_mask(rtwdev, 0x974, 0x3f, 0x3f);
+   rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3);
+}
+
+static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev)
+{
+   struct rtw_hal *hal = >hal;
+   u8 crystal_cap;
+   bool is_tx2_path;
+
+   /* power on BB/RF domain */
+   rtw_write8_set(rtwdev, REG_SYS_FUNC_EN,
+  BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
+   rtw_write8_set(rtwdev, REG_RF_CTRL,
+  BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
+   rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN);
+
+   /* pre init before header files config */
+   rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+
+   rtw_phy_load_tables(rtwdev);
+
+   crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
+   rtw_write32_mask(rtwdev, 0x24, 0x7e00, crystal_cap);
+   rtw_write32_mask(rtwdev, 0x28, 0x7e, crystal_cap);
+
+   /* post init after header files config */
+   rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+
+   is_tx2_path = false;
+   rtw8822b_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx,
+is_tx2_path);
+   rtw_phy_init(rtwdev);
+
+   rtw8822b_phy_rfe_init(rtwdev);
+
+   /* wifi path controller */
+   rtw_write32_mask(rtwdev, 0x70, 0x400, 1);
+   /* BB control */
+   rtw_write32_mask(rtwdev, 0x4c, 0x0180, 0x2);
+   /* antenna mux switch */
+   rtw_write8(rtwdev, 0x974, 0xff);
+   rtw_write32_mask(rtwdev, 0x1990, 0x300, 0);
+   rtw_write32_mask(rtwdev, 0xcbc, 0x8, 0x0);
+   /* SW control */
+   rtw_write8(rtwdev, 0xcb4, 

[RFC v2 02/12] rtw88: core files

2018-10-03 Thread yhchuang
From: Yan-Hsuan Chuang 

core files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang 
---
 drivers/net/wireless/realtek/rtw88/ps.c   | 198 +
 drivers/net/wireless/realtek/rtw88/ps.h   |  21 ++
 drivers/net/wireless/realtek/rtw88/regd.c | 462 ++
 drivers/net/wireless/realtek/rtw88/regd.h |  40 +++
 drivers/net/wireless/realtek/rtw88/sec.c  | 135 +
 drivers/net/wireless/realtek/rtw88/sec.h  |  40 +++
 6 files changed, 896 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtw88/ps.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/ps.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/regd.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/regd.h
 create mode 100644 drivers/net/wireless/realtek/rtw88/sec.c
 create mode 100644 drivers/net/wireless/realtek/rtw88/sec.h

diff --git a/drivers/net/wireless/realtek/rtw88/ps.c 
b/drivers/net/wireless/realtek/rtw88/ps.c
new file mode 100644
index 000..9fd0906
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/ps.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "fw.h"
+#include "ps.h"
+#include "mac.h"
+#include "debug.h"
+
+static int rtw_ips_pwr_up(struct rtw_dev *rtwdev)
+{
+   int ret;
+
+   ret = rtw_core_start(rtwdev);
+   if (ret)
+   rtw_err(rtwdev, "leave idle state failed\n");
+
+   rtw_flag_clear(rtwdev, RTW_FLAG_INACTIVE_PS);
+
+   return ret;
+}
+
+int rtw_enter_ips(struct rtw_dev *rtwdev)
+{
+   rtw_flag_set(rtwdev, RTW_FLAG_INACTIVE_PS);
+
+   rtw_core_stop(rtwdev);
+
+   return 0;
+}
+
+static void rtw_restore_port_cfg(struct rtw_dev *rtwdev)
+{
+   struct rtw_vif *rtwvif;
+   u32 config = ~0;
+
+   rcu_read_lock();
+   list_for_each_entry(rtwvif, >vif_list, list)
+   rtw_vif_port_config(rtwdev, rtwvif, config);
+   rcu_read_unlock();
+}
+
+int rtw_leave_ips(struct rtw_dev *rtwdev)
+{
+   int ret;
+
+   ret = rtw_ips_pwr_up(rtwdev);
+   if (ret) {
+   rtw_err(rtwdev, "fail to leave ips state");
+   return ret;
+   }
+
+   rtw_restore_port_cfg(rtwdev);
+
+   return 0;
+}
+
+void rtw_lps_enter_check(struct rtw_dev *rtwdev)
+{
+   struct rtw_vif *rtwvif, *lps_if;
+   u8 assoc_cnt = 0;
+
+   rcu_read_lock();
+   list_for_each_entry(rtwvif, >vif_list, list) {
+   /* only station mode supports lps */
+   if (rtwvif->vif->type != NL80211_IFTYPE_STATION)
+   goto unlock;
+   /* take the station associated into account */
+   if (rtwvif->vif->bss_conf.assoc) {
+   lps_if = rtwvif;
+   assoc_cnt++;
+   }
+   }
+
+   /* fw supports only one station associated to enter lps, if there are
+* more than two stations associated to the AP, then we can not enter
+* lps, because fw does not handle the overlapped beacon interval
+*/
+   if (assoc_cnt != 1)
+   goto unlock;
+
+   /* the remained interface is the one we want to enter lps */
+   if (lps_if->stats.tx_cnt <= RTW_LPS_THRESHOLD &&
+   lps_if->stats.rx_cnt <= RTW_LPS_THRESHOLD)
+   rtw_enter_lps(rtwdev, lps_if);
+unlock:
+   rcu_read_unlock();
+}
+
+static void rtw_leave_lps_core(struct rtw_dev *rtwdev)
+{
+   struct rtw_lps_conf *conf = >lps_conf;
+
+   conf->state = RTW_ALL_ON;
+   conf->awake_interval = 1;
+   conf->rlbm = 0;
+   conf->smart_ps = 0;
+
+   rtw_fw_set_pwr_mode(rtwdev);
+   rtw_flag_clear(rtwdev, RTW_FLAG_LEISURE_PS);
+}
+
+static void rtw_enter_lps_core(struct rtw_dev *rtwdev)
+{
+   struct rtw_lps_conf *conf = >lps_conf;
+
+   conf->state = RTW_RF_OFF;
+   conf->awake_interval = 1;
+   conf->rlbm = 1;
+   conf->smart_ps = 2;
+
+   rtw_fw_set_pwr_mode(rtwdev);
+   rtw_flag_set(rtwdev, RTW_FLAG_LEISURE_PS);
+}
+
+void rtw_lps_work(struct work_struct *work)
+{
+   struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
+ lps_work.work);
+   struct rtw_lps_conf *conf = >lps_conf;
+   struct rtw_vif *rtwvif = conf->rtwvif;
+
+   if (WARN_ON(!rtwvif))
+   return;
+
+   if (conf->mode == RTW_MODE_LPS)
+   rtw_enter_lps_core(rtwdev);
+   else
+   rtw_leave_lps_core(rtwdev);
+}
+
+void rtw_enter_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
+{
+   struct rtw_lps_conf *conf = >lps_conf;
+
+   if (rtwvif->in_lps)
+   return;
+
+   conf->mode = RTW_MODE_LPS;
+   conf->rtwvif = rtwvif;
+   rtwvif->in_lps = true;
+
+   ieee80211_queue_delayed_work(rtwdev->hw, >lps_work, 0);
+}
+
+void rtw_leave_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
+{
+   

[RFC 7/9] mt76: move tx_tasklet management in mt76x02-lib moudle

2018-10-03 Thread Lorenzo Bianconi
Move tx_tasklet management in mt76x02_mmio.c in order to
be reused by mt76x0 driver and remove duplicated code

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  2 +-
 .../net/wireless/mediatek/mt76/mt76x02_dma.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 42 ++-
 .../wireless/mediatek/mt76/mt76x2/Makefile|  2 +-
 .../net/wireless/mediatek/mt76/mt76x2/mac.h   |  2 -
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  3 --
 .../wireless/mediatek/mt76/mt76x2/pci_dma.c   | 37 
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  | 11 +
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   |  9 
 9 files changed, 45 insertions(+), 64 deletions(-)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_dma.c

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index f817c870587d..87997cddf0d6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -166,7 +166,7 @@ static void mt76x0e_cleanup(struct mt76x02_dev *dev)
clear_bit(MT76_STATE_INITIALIZED, >mt76.state);
mt76x0_chip_onoff(dev, false, false);
mt76x0e_stop_hw(dev);
-   mt76_dma_cleanup(>mt76);
+   mt76x02_dma_cleanup(dev);
mt76x02_mcu_cleanup(>mt76);
 }
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h
index aa38ef9ec7d0..6394010a565f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h
@@ -72,5 +72,6 @@ mt76x02_wait_for_wpdma(struct mt76_dev *dev, int timeout)
 
 int mt76x02_dma_init(struct mt76x02_dev *dev);
 void mt76x02_dma_disable(struct mt76x02_dev *dev);
+void mt76x02_dma_cleanup(struct mt76x02_dev *dev);
 
 #endif /* __MT76x02_DMA_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 98aeb64d9c37..bb609b775de9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -57,16 +57,49 @@ mt76x02_init_rx_queue(struct mt76x02_dev *dev, struct 
mt76_queue *q,
return 0;
 }
 
+static void mt76x02_process_tx_status_fifo(struct mt76x02_dev *dev)
+{
+   struct mt76x02_tx_status stat;
+   u8 update = 1;
+
+   while (kfifo_get(>txstatus_fifo, ))
+   mt76x02_send_tx_status(>mt76, , );
+}
+
+static void mt76x02_tx_tasklet(unsigned long data)
+{
+   struct mt76x02_dev *dev = (struct mt76x02_dev *)data;
+   int i;
+
+   mt76x02_process_tx_status_fifo(dev);
+
+   for (i = MT_TXQ_MCU; i >= 0; i--)
+   mt76_queue_tx_cleanup(dev, i, false);
+
+   mt76x02_mac_poll_tx_status(dev, false);
+   mt76x02_irq_enable(dev, MT_INT_TX_DONE_ALL);
+}
+
 int mt76x02_dma_init(struct mt76x02_dev *dev)
 {
struct mt76_txwi_cache __maybe_unused *t;
+   int i, ret, fifo_size;
struct mt76_queue *q;
-   int i, ret;
+   void *status_fifo;
 
BUILD_BUG_ON(sizeof(t->txwi) < sizeof(struct mt76x02_txwi));
BUILD_BUG_ON(sizeof(struct mt76x02_rxwi) > MT_RX_HEADROOM);
 
+   fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x02_tx_status));
+   status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL);
+   if (!status_fifo)
+   return -ENOMEM;
+
+   tasklet_init(>tx_tasklet, mt76x02_tx_tasklet, (unsigned long) dev);
+   kfifo_init(>txstatus_fifo, status_fifo, fifo_size);
+
mt76_dma_attach(>mt76);
+
mt76_wr(dev, MT_WPDMA_RST_IDX, ~0);
 
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
@@ -132,6 +165,13 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)
 }
 EXPORT_SYMBOL_GPL(mt76x02_dma_enable);
 
+void mt76x02_dma_cleanup(struct mt76x02_dev *dev)
+{
+   tasklet_kill(>tx_tasklet);
+   mt76_dma_cleanup(>mt76);
+}
+EXPORT_SYMBOL_GPL(mt76x02_dma_cleanup);
+
 void mt76x02_dma_disable(struct mt76x02_dev *dev)
 {
u32 val = mt76_rr(dev, MT_WPDMA_GLO_CFG);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile 
b/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile
index 2e6ef73944ed..66f8b8ee6bc4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile
@@ -6,7 +6,7 @@ mt76x2-common-y := \
eeprom.o mac.o init.o phy.o debugfs.o mcu.o
 
 mt76x2e-y := \
-   pci.o pci_dma.o pci_main.o pci_init.o pci_tx.o \
+   pci.o pci_main.o pci_init.o pci_tx.o \
pci_core.o pci_mac.o pci_mcu.o pci_phy.o \
pci_dfs.o pci_trace.o
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
index b13d629053d6..a31bd49ae6cb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
@@ -32,8 +32,6 @@ int 

[RFC 9/9] mt76x0: pci: add mt76x0_register_device in mt76x0e_register_device

2018-10-03 Thread Lorenzo Bianconi
Run mt76x0_register_device routine in mt76x0e_register_device
in order to register the device to the mac80211 layer.
Moreover init mt76_driver_ops data structure and register
interrupt line

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   | 20 ++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 87997cddf0d6..5c1045fbf699 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -118,12 +118,25 @@ static int mt76x0e_register_device(struct mt76x02_dev 
*dev)
mt76_clear(dev, 0x110, BIT(9));
mt76_set(dev, MT_MAX_LEN_CFG, BIT(13));
 
+   err = mt76x0_register_device(dev);
+   if (err < 0)
+   return err;
+
+   set_bit(MT76_STATE_INITIALIZED, >mt76.state);
+
return 0;
 }
 
 static int
 mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
+   static const struct mt76_driver_ops drv_ops = {
+   .txwi_size = sizeof(struct mt76x02_txwi),
+   .tx_prepare_skb = mt76x02_tx_prepare_skb,
+   .tx_complete_skb = mt76x02_tx_complete_skb,
+   .rx_skb = mt76x02_queue_rx_skb,
+   .rx_poll_complete = mt76x02_rx_poll_complete,
+   };
struct mt76x02_dev *dev;
int ret;
 
@@ -141,7 +154,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
if (ret)
return ret;
 
-   dev = mt76x0_alloc_device(>dev, NULL, _ops);
+   dev = mt76x0_alloc_device(>dev, _ops, _ops);
if (!dev)
return -ENOMEM;
 
@@ -150,6 +163,11 @@ mt76x0e_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION);
dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev);
 
+   ret = devm_request_irq(dev->mt76.dev, pdev->irq, mt76x02_irq_handler,
+  IRQF_SHARED, KBUILD_MODNAME, dev);
+   if (ret)
+   goto error;
+
ret = mt76x0e_register_device(dev);
if (ret < 0)
goto error;
-- 
2.17.1



[RFC 8/9] mt76: move irq handler in mt76x02-lib moudle

2018-10-03 Thread Lorenzo Bianconi
Move mt76x02_irq_handler handler in mt76x02_mmio.c in order to be
reused in mt76x0 driver. Move mt76x02_rx_poll_complete routine in
mt76x02-lib module. Moreover remove pci_core.c and mt76x2/trace.{c,h}
since are empty files

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  2 +
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 62 +++
 .../wireless/mediatek/mt76/mt76x02_trace.h| 23 ++
 .../wireless/mediatek/mt76/mt76x2/Makefile|  3 +-
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  3 -
 .../net/wireless/mediatek/mt76/mt76x2/pci.c   |  3 +-
 .../wireless/mediatek/mt76/mt76x2/pci_core.c  | 78 ---
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   |  1 -
 .../wireless/mediatek/mt76/mt76x2/pci_trace.c | 23 --
 .../net/wireless/mediatek/mt76/mt76x2/trace.h | 67 
 11 files changed, 90 insertions(+), 177 deletions(-)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_core.c
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_trace.c
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/trace.h

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index d4dd4547bb06..65174817ebc4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -146,6 +146,8 @@ void mt76x02_tx_complete(struct mt76_dev *dev, struct 
sk_buff *skb);
 bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update);
 void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
  struct sk_buff *skb);
+void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
+irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance);
 void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct sk_buff *skb);
 int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index bb609b775de9..1b945079c802 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -16,8 +16,10 @@
  */
 
 #include 
+#include 
 
 #include "mt76x02.h"
+#include "mt76x02_trace.h"
 
 static int
 mt76x02_init_tx_queue(struct mt76x02_dev *dev, struct mt76_queue *q,
@@ -136,6 +138,66 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
 }
 EXPORT_SYMBOL_GPL(mt76x02_dma_init);
 
+void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
+{
+   struct mt76x02_dev *dev;
+
+   dev = container_of(mdev, struct mt76x02_dev, mt76);
+   mt76x02_irq_enable(dev, MT_INT_RX_DONE(q));
+}
+EXPORT_SYMBOL_GPL(mt76x02_rx_poll_complete);
+
+irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
+{
+   struct mt76x02_dev *dev = dev_instance;
+   u32 intr;
+
+   intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
+   mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
+
+   if (!test_bit(MT76_STATE_INITIALIZED, >mt76.state))
+   return IRQ_NONE;
+
+   trace_dev_irq(dev, intr, dev->mt76.mmio.irqmask);
+
+   intr &= dev->mt76.mmio.irqmask;
+
+   if (intr & MT_INT_TX_DONE_ALL) {
+   mt76x02_irq_disable(dev, MT_INT_TX_DONE_ALL);
+   tasklet_schedule(>tx_tasklet);
+   }
+
+   if (intr & MT_INT_RX_DONE(0)) {
+   mt76x02_irq_disable(dev, MT_INT_RX_DONE(0));
+   napi_schedule(>mt76.napi[0]);
+   }
+
+   if (intr & MT_INT_RX_DONE(1)) {
+   mt76x02_irq_disable(dev, MT_INT_RX_DONE(1));
+   napi_schedule(>mt76.napi[1]);
+   }
+
+   if (intr & MT_INT_PRE_TBTT)
+   tasklet_schedule(>pre_tbtt_tasklet);
+
+   /* send buffered multicast frames now */
+   if (intr & MT_INT_TBTT)
+   mt76_queue_kick(dev, >mt76.q_tx[MT_TXQ_PSD]);
+
+   if (intr & MT_INT_TX_STAT) {
+   mt76x02_mac_poll_tx_status(dev, true);
+   tasklet_schedule(>tx_tasklet);
+   }
+
+   if (intr & MT_INT_GPTIMER) {
+   mt76x02_irq_disable(dev, MT_INT_GPTIMER);
+   tasklet_schedule(>dfs_pd.dfs_tasklet);
+   }
+
+   return IRQ_HANDLED;
+}
+EXPORT_SYMBOL_GPL(mt76x02_irq_handler);
+
 void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set)
 {
unsigned long flags;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h
index a18f26d857e4..713f12d3c8de 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h
@@ -110,6 +110,29 @@ TRACE_EVENT(mac_txstat_fetch,
)
 );
 
+TRACE_EVENT(dev_irq,
+   TP_PROTO(struct mt76x02_dev *dev, u32 val, u32 mask),
+
+   TP_ARGS(dev, val, mask),
+
+   TP_STRUCT__entry(
+  

[RFC 5/9] mt76: move mt76x02_tx_complete in mt76x02-lib module

2018-10-03 Thread Lorenzo Bianconi
Move mt76x02_tx_complete mt76x02-lib module in order to
be reused by mt76x0 drivers for irq unification.

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 29 +++
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  | 19 
 .../wireless/mediatek/mt76/mt76x02_trace.h| 22 ++
 .../net/wireless/mediatek/mt76/mt76x2/mac.h   | 17 ---
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  2 --
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   | 28 --
 .../net/wireless/mediatek/mt76/mt76x2/trace.h | 22 --
 8 files changed, 71 insertions(+), 70 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index a39c10b61df9..244245418ebb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -714,3 +714,32 @@ void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, 
bool irq)
}
 }
 EXPORT_SYMBOL_GPL(mt76x02_mac_poll_tx_status);
+
+static void
+mt76x02_mac_queue_txdone(struct mt76x02_dev *dev, struct sk_buff *skb,
+void *txwi_ptr)
+{
+   struct mt76x02_tx_info *txi = mt76x02_skb_tx_info(skb);
+   struct mt76x02_txwi *txwi = txwi_ptr;
+
+   mt76x02_mac_poll_tx_status(dev, false);
+
+   txi->tries = 0;
+   txi->jiffies = jiffies;
+   txi->wcid = txwi->wcid;
+   txi->pktid = txwi->pktid;
+   trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid);
+   mt76x02_tx_complete(>mt76, skb);
+}
+
+void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
+struct mt76_queue_entry *e, bool flush)
+{
+   struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
+
+   if (e->txwi)
+   mt76x02_mac_queue_txdone(dev, e->skb, >txwi->txwi);
+   else
+   dev_kfree_skb_any(e->skb);
+}
+EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index 426e68041642..4f7ee4620ab5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -42,6 +42,15 @@ struct mt76x02_vif {
struct mt76_wcid group_wcid;
 };
 
+struct mt76x02_tx_info {
+   unsigned long jiffies;
+   u8 tries;
+
+   u8 wcid;
+   u8 pktid;
+   u8 retry;
+};
+
 DECLARE_EWMA(signal, 10, 8);
 
 struct mt76x02_sta {
@@ -181,6 +190,14 @@ static inline bool mt76x02_wait_for_mac(struct mt76_dev 
*dev)
return false;
 }
 
+static inline struct mt76x02_tx_info *
+mt76x02_skb_tx_info(struct sk_buff *skb)
+{
+   struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+   return (void *)info->status.status_driver_data;
+}
+
 void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq);
 enum mt76x02_cipher_type
 mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data);
@@ -206,4 +223,6 @@ void mt76x02_mac_write_txwi(struct mt76_dev *dev, struct 
mt76x02_txwi *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, int len);
 void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq);
+void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
+struct mt76_queue_entry *e, bool flush);
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h
index 98580dd22e78..a18f26d857e4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_trace.h
@@ -46,6 +46,28 @@ DECLARE_EVENT_CLASS(dev_evt,
TP_printk(DEV_PR_FMT, DEV_PR_ARG)
 );
 
+DECLARE_EVENT_CLASS(dev_txid_evt,
+   TP_PROTO(struct mt76x02_dev *dev, u8 wcid, u8 pktid),
+   TP_ARGS(dev, wcid, pktid),
+   TP_STRUCT__entry(
+   DEV_ENTRY
+   TXID_ENTRY
+   ),
+   TP_fast_assign(
+   DEV_ASSIGN;
+   TXID_ASSIGN;
+   ),
+   TP_printk(
+   DEV_PR_FMT TXID_PR_FMT,
+   DEV_PR_ARG, TXID_PR_ARG
+   )
+);
+
+DEFINE_EVENT(dev_txid_evt, mac_txdone_add,
+   TP_PROTO(struct mt76x02_dev *dev, u8 wcid, u8 pktid),
+   TP_ARGS(dev, wcid, pktid)
+);
+
 DEFINE_EVENT(dev_evt, mac_txstat_poll,
TP_PROTO(struct mt76x02_dev *dev),
TP_ARGS(dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
index 6a6761050035..b13d629053d6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
@@ -23,23 +23,6 @@ struct mt76x02_dev;
 struct mt76x2_sta;
 struct mt76x02_vif;
 
-struct mt76x2_tx_info {
-   unsigned long 

[RFC 6/9] mt76: use mt76x02_dev instead of mt76_dev in mt76x02_mmio.c

2018-10-03 Thread Lorenzo Bianconi
Use mt76x02_dev data structure as reference in mt76x02_mmio.c
instead of mt76_dev

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76.h |  4 +-
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  6 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  8 +--
 .../net/wireless/mediatek/mt76/mt76x02_dma.h  |  7 +-
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 70 +--
 .../wireless/mediatek/mt76/mt76x2/pci_core.c  | 13 ++--
 .../wireless/mediatek/mt76/mt76x2/pci_dfs.c   |  6 +-
 .../wireless/mediatek/mt76/mt76x2/pci_dma.c   |  2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  6 +-
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   |  4 +-
 10 files changed, 64 insertions(+), 62 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index c47ad67ce2ff..f723a07cab29 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -517,8 +517,8 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
 #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76))
 #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76))
 
-#define __mt76_init_queues(dev)(dev)->queue_ops->init((dev))
-#define __mt76_queue_alloc(dev, ...)   (dev)->queue_ops->alloc((dev), 
__VA_ARGS__)
+#define mt76_init_queues(dev)  
(dev)->mt76.queue_ops->init(&((dev)->mt76))
+#define mt76_queue_alloc(dev, ...) 
(dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__)
 #define mt76_queue_add_buf(dev, ...)   
(dev)->mt76.queue_ops->add_buf(&((dev)->mt76), __VA_ARGS__)
 #define mt76_queue_rx_reset(dev, ...)  
(dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__)
 #define mt76_queue_tx_cleanup(dev, ...)
(dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 55c62e40499b..f817c870587d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -27,7 +27,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
 
mutex_lock(>mt76.mutex);
 
-   mt76x02_mac_start(>mt76);
+   mt76x02_mac_start(dev);
ieee80211_queue_delayed_work(dev->mt76.hw, >mac_work,
 MT_CALIBRATE_INTERVAL);
ieee80211_queue_delayed_work(dev->mt76.hw, >cal_work,
@@ -85,12 +85,12 @@ static int mt76x0e_register_device(struct mt76x02_dev *dev)
if (!mt76x02_wait_for_mac(>mt76))
return -ETIMEDOUT;
 
-   mt76x02_dma_disable(>mt76);
+   mt76x02_dma_disable(dev);
err = mt76x0e_mcu_init(dev);
if (err < 0)
return err;
 
-   err = mt76x02_dma_init(>mt76);
+   err = mt76x02_dma_init(dev);
if (err < 0)
return err;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 3f76754b139f..d4dd4547bb06 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -155,15 +155,15 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void 
*txwi,
 
 extern const u16 mt76x02_beacon_offsets[16];
 void mt76x02_set_beacon_offsets(struct mt76_dev *dev);
-void mt76x02_set_irq_mask(struct mt76_dev *dev, u32 clear, u32 set);
-void mt76x02_mac_start(struct mt76_dev *dev);
+void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set);
+void mt76x02_mac_start(struct mt76x02_dev *dev);
 
-static inline void mt76x02_irq_enable(struct mt76_dev *dev, u32 mask)
+static inline void mt76x02_irq_enable(struct mt76x02_dev *dev, u32 mask)
 {
mt76x02_set_irq_mask(dev, 0, mask);
 }
 
-static inline void mt76x02_irq_disable(struct mt76_dev *dev, u32 mask)
+static inline void mt76x02_irq_disable(struct mt76x02_dev *dev, u32 mask)
 {
mt76x02_set_irq_mask(dev, mask, 0);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h
index 65b97f5713d3..aa38ef9ec7d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h
@@ -17,8 +17,8 @@
 #ifndef __MT76x02_DMA_H
 #define __MT76x02_DMA_H
 
+#include "mt76x02.h"
 #include "dma.h"
-#include "mt76x02_regs.h"
 
 #define MT_TXD_INFO_LENGENMASK(15, 0)
 #define MT_TXD_INFO_NEXT_VLD   BIT(16)
@@ -70,8 +70,7 @@ mt76x02_wait_for_wpdma(struct mt76_dev *dev, int timeout)
   0, timeout);
 }
 
-int mt76x02_dma_init(struct mt76_dev *dev);
-void mt76x02_dma_enable(struct mt76_dev *dev);
-void mt76x02_dma_disable(struct mt76_dev *dev);
+int mt76x02_dma_init(struct mt76x02_dev *dev);
+void mt76x02_dma_disable(struct mt76x02_dev *dev);
 
 #endif /* __MT76x02_DMA_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 

[RFC 2/9] mt76: move mt76x02_tx_prepare_skb in mt76x02_txrx.c

2018-10-03 Thread Lorenzo Bianconi
Move mt76x02_tx_prepare_skb routine in mt76x02-lib module in order
to be reused by mt76x0 driver in tx datapath

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  4 +++
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c | 32 +++
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  4 ---
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_tx.c| 31 --
 5 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index f7325ee10a1e..2905bd964dc2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -150,6 +150,10 @@ void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum 
mt76_rxq_id q,
  struct sk_buff *skb);
 void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct sk_buff *skb);
+int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
+  struct sk_buff *skb, struct mt76_queue *q,
+  struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+  u32 *tx_info);
 
 extern const u16 mt76x02_beacon_offsets[16];
 void mt76x02_set_beacon_offsets(struct mt76_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index ebd61c0e40c5..ab7877a07b6c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -187,3 +187,35 @@ bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 
*update)
return true;
 }
 EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);
+
+int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
+  struct sk_buff *skb, struct mt76_queue *q,
+  struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+  u32 *tx_info)
+{
+   struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
+   struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+   int qsel = MT_QSEL_EDCA;
+   int ret;
+
+   if (q == >mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128)
+   mt76x02_mac_wcid_set_drop(>mt76, wcid->idx, false);
+
+   mt76x02_mac_write_txwi(mdev, txwi, skb, wcid, sta, skb->len);
+
+   ret = mt76x02_insert_hdr_pad(skb);
+   if (ret < 0)
+   return ret;
+
+   if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
+   qsel = MT_QSEL_MGMT;
+
+   *tx_info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
+  MT_TXD_INFO_80211;
+
+   if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv)
+   *tx_info |= MT_TXD_INFO_WIV;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mt76x02_tx_prepare_skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
index 26c1a24c4a2d..e29ce8d23a4f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
@@ -86,10 +86,6 @@ void mt76x2_dma_cleanup(struct mt76x02_dev *dev);
 
 void mt76x2_cleanup(struct mt76x02_dev *dev);
 
-int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
- struct sk_buff *skb, struct mt76_queue *q,
- struct mt76_wcid *wcid, struct ieee80211_sta *sta,
- u32 *tx_info);
 void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
struct mt76_queue_entry *e, bool flush);
 void mt76x2_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index 194181275611..055c90b1e522 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -355,7 +355,7 @@ struct mt76x02_dev *mt76x2_alloc_device(struct device *pdev)
static const struct mt76_driver_ops drv_ops = {
.txwi_size = sizeof(struct mt76x02_txwi),
.update_survey = mt76x2_update_channel,
-   .tx_prepare_skb = mt76x2_tx_prepare_skb,
+   .tx_prepare_skb = mt76x02_tx_prepare_skb,
.tx_complete_skb = mt76x2_tx_complete_skb,
.rx_skb = mt76x02_queue_rx_skb,
.rx_poll_complete = mt76x2_rx_poll_complete,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c
index cfc9d3d207df..3a2ec86d3e88 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c
@@ -22,37 +22,6 @@ struct beacon_bc_data {
struct sk_buff *tail[8];
 };
 
-int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void 

[RFC 3/9] mt76: usb: move mt76x02u_tx_complete_skb in mt76x02_usb_core.c

2018-10-03 Thread Lorenzo Bianconi
Move mt76x02u_tx_complete_skb and mt76x02u_remove_dma_hdr since they
are used just by usb code

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/usb.c|  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h   |  2 --
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c  | 18 --
 .../net/wireless/mediatek/mt76/mt76x02_usb.h   |  2 ++
 .../wireless/mediatek/mt76/mt76x02_usb_core.c  | 18 ++
 .../wireless/mediatek/mt76/mt76x2/usb_init.c   |  2 +-
 6 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 2080933efa2e..d2e10fa53a0e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -215,7 +215,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
 {
static const struct mt76_driver_ops drv_ops = {
.tx_prepare_skb = mt76x02u_tx_prepare_skb,
-   .tx_complete_skb = mt76x02_tx_complete_skb,
+   .tx_complete_skb = mt76x02u_tx_complete_skb,
.tx_status_data = mt76x02_tx_status_data,
.rx_skb = mt76x02_queue_rx_skb,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 2905bd964dc2..3f76754b139f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -143,8 +143,6 @@ void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 
txpwr);
 int mt76x02_insert_hdr_pad(struct sk_buff *skb);
 void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len);
 void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb);
-void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
-   struct mt76_queue_entry *e, bool flush);
 bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update);
 void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
  struct sk_buff *skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index ab7877a07b6c..830377221739 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -142,16 +142,6 @@ void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 
txpwr)
 }
 EXPORT_SYMBOL_GPL(mt76x02_tx_set_txpwr_auto);
 
-static void mt76x02_remove_dma_hdr(struct sk_buff *skb)
-{
-   int hdr_len;
-
-   skb_pull(skb, sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN);
-   hdr_len = ieee80211_get_hdrlen_from_skb(skb);
-   if (hdr_len % 4)
-   mt76x02_remove_hdr_pad(skb, 2);
-}
-
 void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb)
 {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -167,14 +157,6 @@ void mt76x02_tx_complete(struct mt76_dev *dev, struct 
sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(mt76x02_tx_complete);
 
-void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
-struct mt76_queue_entry *e, bool flush)
-{
-   mt76x02_remove_dma_hdr(e->skb);
-   mt76x02_tx_complete(mdev, e->skb);
-}
-EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
-
 bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update)
 {
struct mt76x02_tx_status stat;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
index e70ba4f97761..6b2138328eb2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
@@ -29,4 +29,6 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *dev, void *data,
struct sk_buff *skb, struct mt76_queue *q,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info);
+void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
+ struct mt76_queue_entry *e, bool flush);
 #endif /* __MT76x02_USB_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index a0cd77ddaef3..7c6c973af386 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -16,6 +16,24 @@
 
 #include "mt76x02.h"
 
+static void mt76x02u_remove_dma_hdr(struct sk_buff *skb)
+{
+   int hdr_len;
+
+   skb_pull(skb, sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN);
+   hdr_len = ieee80211_get_hdrlen_from_skb(skb);
+   if (hdr_len % 4)
+   mt76x02_remove_hdr_pad(skb, 2);
+}
+
+void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
+ struct mt76_queue_entry *e, bool flush)
+{
+   mt76x02u_remove_dma_hdr(e->skb);
+   mt76x02_tx_complete(mdev, e->skb);

[RFC 1/9] mt76: move tpc routines in mt76x02-lib module

2018-10-03 Thread Lorenzo Bianconi
Move mt76x02_tx_get_txpwr_adj and mt76x02_tx_set_txpwr_auto routines
in mt76x02-lib module since they are shared between mt76x0 and mt76x2
drivers. Moreover remove get_txpwr_adj function pointer

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 -
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  2 +
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  8 ++-
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c | 30 
 .../wireless/mediatek/mt76/mt76x2/Makefile|  2 +-
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  4 --
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  1 -
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |  2 +-
 .../net/wireless/mediatek/mt76/mt76x2/tx.c| 49 ---
 9 files changed, 37 insertions(+), 63 deletions(-)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/tx.c

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 422b09a42bf6..c47ad67ce2ff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -262,8 +262,6 @@ struct mt76_driver_ops {
 
void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
   bool ps);
-   s8 (*get_tx_txpwr_adj)(struct mt76_dev *dev, s8 txpwr,
-  s8 max_txpwr_adj);
 };
 
 struct mt76_channel_state {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index fe68cf33aef4..f7325ee10a1e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -138,6 +138,8 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
struct ieee80211_sta *sta);
 s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev,
const struct ieee80211_tx_rate *rate);
+s8 mt76x02_tx_get_txpwr_adj(struct mt76_dev *mdev, s8 txpwr, s8 max_txpwr_adj);
+void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr);
 int mt76x02_insert_hdr_pad(struct sk_buff *skb);
 void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len);
 void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 07b3217ecb51..a5058e4a9b14 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -384,11 +384,9 @@ void mt76x02_mac_write_txwi(struct mt76_dev *dev, struct 
mt76x02_txwi *txwi,
}
spin_unlock_bh(>lock);
 
-   if (dev->drv->get_tx_txpwr_adj) {
-   txpwr_adj = dev->drv->get_tx_txpwr_adj(dev, dev->txpower_conf,
-  max_txpwr_adj);
-   txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj);
-   }
+   txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, dev->txpower_conf,
+max_txpwr_adj);
+   txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj);
 
if (nstreams > 1 && mt76_rev(dev) >= MT76XX_REV_E4)
txwi->txstream = 0x13;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 24298b7ddd7d..ebd61c0e40c5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -112,6 +112,36 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev,
 }
 EXPORT_SYMBOL_GPL(mt76x02_tx_get_max_txpwr_adj);
 
+s8 mt76x02_tx_get_txpwr_adj(struct mt76_dev *mdev, s8 txpwr, s8 max_txpwr_adj)
+{
+   struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
+
+   txpwr = min_t(s8, txpwr, dev->mt76.txpower_conf);
+   txpwr -= (dev->target_power + dev->target_power_delta[0]);
+   txpwr = min_t(s8, txpwr, max_txpwr_adj);
+
+   if (!dev->enable_tpc)
+   return 0;
+   else if (txpwr >= 0)
+   return min_t(s8, txpwr, 7);
+   else
+   return (txpwr < -16) ? 8 : (txpwr + 32) / 2;
+}
+EXPORT_SYMBOL_GPL(mt76x02_tx_get_txpwr_adj);
+
+void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr)
+{
+   s8 txpwr_adj;
+
+   txpwr_adj = mt76x02_tx_get_txpwr_adj(>mt76, txpwr,
+dev->mt76.rate_power.ofdm[4]);
+   mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
+  MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj);
+   mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
+  MT_PROT_AUTO_TX_CFG_AUTO_PADJ, txpwr_adj);
+}
+EXPORT_SYMBOL_GPL(mt76x02_tx_set_txpwr_auto);
+
 static void mt76x02_remove_dma_hdr(struct sk_buff *skb)
 {
int hdr_len;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile 
b/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile
index 043bfd737edf..2e6ef73944ed 100644
--- 

[RFC 4/9] mt76: move mt76x02_mac_poll_tx_status in mt76x02-lib moudle

2018-10-03 Thread Lorenzo Bianconi
Move mt76x02_mac_poll_tx_status in mt76x02_mac.c in order to
be reused by mt76x0 drivers for irq unification.
Moreover introduce mt76x02_trace source file to define mt76x02
trace points

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/Makefile   |  3 +-
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 33 +++
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  1 +
 .../wireless/mediatek/mt76/mt76x02_trace.c| 23 +
 .../wireless/mediatek/mt76/mt76x02_trace.h| 98 +++
 .../net/wireless/mediatek/mt76/mt76x2/mac.h   |  1 -
 .../wireless/mediatek/mt76/mt76x2/pci_core.c  |  2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_dma.c   |  2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   | 33 +--
 .../net/wireless/mediatek/mt76/mt76x2/trace.h | 55 ---
 10 files changed, 160 insertions(+), 91 deletions(-)
 create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_trace.c
 create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_trace.h

diff --git a/drivers/net/wireless/mediatek/mt76/Makefile 
b/drivers/net/wireless/mediatek/mt76/Makefile
index 09c90eef61a4..9b8d7488c545 100644
--- a/drivers/net/wireless/mediatek/mt76/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/Makefile
@@ -10,10 +10,11 @@ mt76-usb-y := usb.o usb_trace.o usb_mcu.o
 
 CFLAGS_trace.o := -I$(src)
 CFLAGS_usb_trace.o := -I$(src)
+CFLAGS_mt76x02_trace.o := -I$(src)
 
 mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
 mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o \
-mt76x02_txrx.o
+mt76x02_txrx.o mt76x02_trace.o
 
 mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index a5058e4a9b14..a39c10b61df9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -16,6 +16,7 @@
  */
 
 #include "mt76x02.h"
+#include "mt76x02_trace.h"
 
 enum mt76x02_cipher_type
 mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
@@ -681,3 +682,35 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct 
sk_buff *skb,
 
return mt76x02_mac_process_rate(status, rate);
 }
+
+void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq)
+{
+   struct mt76x02_tx_status stat = {};
+   unsigned long flags;
+   u8 update = 1;
+   bool ret;
+
+   if (!test_bit(MT76_STATE_RUNNING, >mt76.state))
+   return;
+
+   trace_mac_txstat_poll(dev);
+
+   while (!irq || !kfifo_is_full(>txstatus_fifo)) {
+   spin_lock_irqsave(>mt76.mmio.irq_lock, flags);
+   ret = mt76x02_mac_load_tx_status(>mt76, );
+   spin_unlock_irqrestore(>mt76.mmio.irq_lock, flags);
+
+   if (!ret)
+   break;
+
+   trace_mac_txstat_fetch(dev, );
+
+   if (!irq) {
+   mt76x02_send_tx_status(>mt76, , );
+   continue;
+   }
+
+   kfifo_put(>txstatus_fifo, stat);
+   }
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_poll_tx_status);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index 857ab2308e8b..426e68041642 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -205,4 +205,5 @@ void mt76x02_mac_setaddr(struct mt76_dev *dev, u8 *addr);
 void mt76x02_mac_write_txwi(struct mt76_dev *dev, struct mt76x02_txwi *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, int len);
+void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq);
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_trace.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_trace.c
new file mode 100644
index ..5b42d2c87937
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_trace.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau 
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "mt76x02_trace.h"
+
+#endif
diff --git 

[RFC 0/9] unify rx datapath between mt76x0 and mt76x2 drivers

2018-10-03 Thread Lorenzo Bianconi
Move mt76x02_irq_handler irq handler in mt76x02-lib module in order
to unify rx datapath between mt76x0 and mt76x2 drivers and remove
duplicated code

Lorenzo Bianconi (9):
  mt76: move tpc routines in mt76x02-lib module
  mt76: move mt76x02_tx_prepare_skb in mt76x02_txrx.c
  mt76: usb: move mt76x02u_tx_complete_skb in mt76x02_usb_core.c
  mt76: move mt76x02_mac_poll_tx_status in mt76x02-lib moudle
  mt76: move mt76x02_tx_complete in mt76x02-lib module
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_mmio.c
  mt76: move tx_tasklet management in mt76x02-lib moudle
  mt76: move irq handler in mt76x02-lib moudle
  mt76x0: pci: add mt76x0_register_device in mt76x0e_register_device

 drivers/net/wireless/mediatek/mt76/Makefile   |   3 +-
 drivers/net/wireless/mediatek/mt76/mt76.h |   6 +-
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  28 ++-
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |   2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  18 +-
 .../net/wireless/mediatek/mt76/mt76x02_dma.h  |   8 +-
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  70 ++-
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  20 ++
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 174 ++
 .../{mt76x2/pci_trace.c => mt76x02_trace.c}   |   2 +-
 .../mt76/{mt76x2/trace.h => mt76x02_trace.h}  |  21 +--
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c |  72 ++--
 .../net/wireless/mediatek/mt76/mt76x02_usb.h  |   2 +
 .../wireless/mediatek/mt76/mt76x02_usb_core.c |  18 ++
 .../wireless/mediatek/mt76/mt76x2/Makefile|   7 +-
 .../net/wireless/mediatek/mt76/mt76x2/mac.h   |  20 --
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  16 --
 .../net/wireless/mediatek/mt76/mt76x2/pci.c   |   3 +-
 .../wireless/mediatek/mt76/mt76x2/pci_core.c  |  75 
 .../wireless/mediatek/mt76/mt76x2/pci_dfs.c   |   6 +-
 .../wireless/mediatek/mt76/mt76x2/pci_dma.c   |  37 
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  24 +--
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   |  73 +---
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |   2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_tx.c|  31 
 .../net/wireless/mediatek/mt76/mt76x2/tx.c|  49 -
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  |   2 +-
 27 files changed, 374 insertions(+), 415 deletions(-)
 rename drivers/net/wireless/mediatek/mt76/{mt76x2/pci_trace.c => 
mt76x02_trace.c} (97%)
 rename drivers/net/wireless/mediatek/mt76/{mt76x2/trace.h => mt76x02_trace.h} 
(94%)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_core.c
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_dma.c
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/tx.c

-- 
2.17.1



pull-request: iwlwifi firmwares update 2018-10-03

2018-10-03 Thread Luca Coelho
Hi,

We have updated all the firmwares we currently support.

Please pull or let me know if there are any issues.

Cheers,
Luca.


The following changes since commit 7c81f23ad903f72e87e2102d8f52408305c0f7a2:

  ti-connectivity: add firmware for CC2560(A) Bluetooth (2018-10-01 10:08:30 
-0400)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware.git 
tags/iwlwifi-fw-2018-10-03

for you to fetch changes up to da110f2f392ab0f9a4e3cc35402b1f3e2c58127f:

  iwlwifi: add -41.ucode firmwares for 9000 series (2018-10-03 10:08:09 +0300)


iwlwifi: updata all currently supported FWs

* Update FWs for 3160, 7260 and 7265;
* Update FWs for 3168 and 7265D;
* Update FWs for 8000C and 8265;
* Update FWs for 9000 and 9260.


Emmanuel Grumbach (2):
  iwlwifi: update firmwares for 9000 series
  iwlwifi: add -41.ucode firmwares for 9000 series

Luca Coelho (1):
  iwlwifi: update firmwares for 7000, 8000 and 9000 series

 WHENCE|  20 +---
 iwlwifi-3160-17.ucode | Bin 918268 -> 918268 bytes
 iwlwifi-7260-17.ucode | Bin 1049340 -> 1049340 bytes
 iwlwifi-7265-17.ucode | Bin 1180412 -> 1180412 bytes
 iwlwifi-8000C-36.ucode| Bin 2486572 -> 2486572 bytes
 iwlwifi-8265-36.ucode | Bin 2498044 -> 2498044 bytes
 iwlwifi-9000-pu-b0-jf-b0-38.ucode | Bin 2520568 -> 2520568 bytes
 iwlwifi-9000-pu-b0-jf-b0-41.ucode | Bin 0 -> 2961864 bytes
 iwlwifi-9260-th-b0-jf-b0-38.ucode | Bin 2521412 -> 2521412 bytes
 iwlwifi-9260-th-b0-jf-b0-41.ucode | Bin 0 -> 2620368 bytes
 10 files changed, 13 insertions(+), 7 deletions(-)
 create mode 100644 iwlwifi-9000-pu-b0-jf-b0-41.ucode
 create mode 100644 iwlwifi-9260-th-b0-jf-b0-41.ucode


signature.asc
Description: This is a digitally signed message part


Re: [Make-wifi-fast] [PATCH RFC v4 3/4] mac80211: Add airtime accounting and scheduling to TXQs

2018-10-03 Thread Rajkumar Manoharan

On 2018-10-02 22:53, Rajkumar Manoharan wrote:

Shouldn't have to call next_txq(). It should be as below.
Anyway drv_wake_tx_queue is just an indication to driver and
driver will always dequeue first node from list.

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 2dbfd1d8eb5f..74ac0b19cd54 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -242,7 +242,7 @@ EXPORT_SYMBOL(ieee80211_ctstoself_duration);

 static void __ieee80211_kick_airtime(struct ieee80211_local *local, int 
ac)

 {
-   struct ieee80211_txq *txq;
+   struct ieee80211_txq *txq = NULL;
bool seen_eligible = false;
struct txq_info *txqi;
struct sta_info *sta;
@@ -263,6 +263,7 @@ static void __ieee80211_kick_airtime(struct 
ieee80211_local *local, int ac)

if (sta->airtime[ac].deficit >= 0) {
seen_eligible = true;
clear_bit(IEEE80211_TXQ_AIRTIME_THROTTLE, 
>flags);

+   txq = >txq;
}
}

@@ -283,7 +284,6 @@ static void __ieee80211_kick_airtime(struct 
ieee80211_local *local, int ac)

}
  out:
rcu_read_unlock();
-   txq = ieee80211_next_txq(>hw, ac);
spin_unlock_bh(>active_txq_lock[ac]);

-Rajkumar


Re: [PATCH 01/12] rtwlan: main files

2018-10-03 Thread Stanislaw Gruszka
On Wed, Oct 03, 2018 at 03:25:37AM +, Tony Chuang wrote:
> Can I add you as Reviewed-by in RFCv2 ?

Not yet :-) I'm going to review all (v2) patches in detail,
not just first one, but this will take time. I'll post
Reviewed-by tag when done and if I will have no remarks.

> You helped me a lot :)
You welcome ;-)

Thanks
Stanislaw