VERIFICA
L'aggiornamento dell'account è in corso, fa parte di esso oggi per un perfetto funzionamento dei conti. CLICCA SULLA LINK SEGUENTE E AGGIORNARE IL TUO CONTO IMMEDIATAMENTE. http://bibankie.tripod.com ZIMBRA WEBMASTER
RE: [PATCH 01/11] mwifiex: fixup error cases in mwifiex_add_virtual_intf()
Hi, This patch serials looks fine, thanks. > -Original Message- > From: linux-wireless-ow...@vger.kernel.org > [mailto:linux-wireless-ow...@vger.kernel.org] On Behalf Of Brian Norris > Sent: 2017年5月13日 0:42 > To: Ganapathi Bhat; Nishant Sarmukadam > Cc: linux-ker...@vger.kernel.org; Dmitry Torokhov; Amitkumar Karwar; Kalle > Valo; linux-wireless@vger.kernel.org; Doug Anderson; Brian Norris > Subject: [PATCH 01/11] mwifiex: fixup error cases in > mwifiex_add_virtual_intf() > > If we fail to add an interface in mwifiex_add_virtual_intf(), we might hit a > BUG_ON() in the networking code, because we didn't tear things down > properly. Among the problems: > > (a) when failing to allocate workqueues, we fail to unregister the > netdev before calling free_netdev() > (b) even if we do try to unregister the netdev, we're still holding the > rtnl lock, so the device never properly unregistered; we'll be at > state NETREG_UNREGISTERING, and then hit free_netdev()'s: > BUG_ON(dev->reg_state != NETREG_UNREGISTERED); > (c) we're allocating some dependent resources (e.g., DFS workqueues) > after we've registered the interface; this may or may not cause > problems, but it's good practice to allocate these before registering > (d) we're not even trying to unwind anything when mwifiex_send_cmd() or > mwifiex_sta_init_cmd() fail > > To fix these issues, let's: > > * add a stacked set of error handling labels, to keep error handling >consistent and properly ordered (resolving (a) and (d)) > * move the workqueue allocations before the registration (to resolve >(c); also resolves (b) by avoiding error cases where we have to >unregister) > > [Incidentally, it's pretty easy to interrupt the alloc_workqueue() in, e.g., > the > following: > > iw phy phy0 interface add mlan0 type station > > by sending it SIGTERM.] > > This bugfix covers commits like commit 7d652034d1a0 ("mwifiex: channel > switch support for mwifiex"), but parts of this bug exist all the way back to > the > introduction of dynamic interface handling in commit > 93a1df48d224 ("mwifiex: add cfg80211 handlers add/del_virtual_intf"). > > Cc: > Signed-off-by: Brian Norris > --- > drivers/net/wireless/marvell/mwifiex/cfg80211.c | 71 > - > 1 file changed, 35 insertions(+), 36 deletions(-) > > diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c > b/drivers/net/wireless/marvell/mwifiex/cfg80211.c > index 7ec06bf13413..025bc06a19d6 100644 > --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c > +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c > @@ -2964,10 +2964,8 @@ struct wireless_dev > *mwifiex_add_virtual_intf(struct wiphy *wiphy, > if (!dev) { > mwifiex_dbg(adapter, ERROR, > "no memory available for netdevice\n"); > - memset(&priv->wdev, 0, sizeof(priv->wdev)); > - priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; > - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; > - return ERR_PTR(-ENOMEM); > + ret = -ENOMEM; > + goto err_alloc_netdev; > } > > mwifiex_init_priv_params(priv, dev); > @@ -2976,11 +2974,11 @@ struct wireless_dev > *mwifiex_add_virtual_intf(struct wiphy *wiphy, > ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE, > HostCmd_ACT_GEN_SET, 0, NULL, true); > if (ret) > - return ERR_PTR(ret); > + goto err_set_bss_mode; > > ret = mwifiex_sta_init_cmd(priv, false, false); > if (ret) > - return ERR_PTR(ret); > + goto err_sta_init; > > mwifiex_setup_ht_caps(&wiphy->bands[NL80211_BAND_2GHZ]->ht_cap, > priv); > if (adapter->is_hw_11ac_capable) > @@ -3011,31 +3009,14 @@ struct wireless_dev > *mwifiex_add_virtual_intf(struct wiphy *wiphy, > > SET_NETDEV_DEV(dev, adapter->dev); > > - /* Register network device */ > - if (register_netdevice(dev)) { > - mwifiex_dbg(adapter, ERROR, > - "cannot register virtual network device\n"); > - free_netdev(dev); > - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; > - priv->netdev = NULL; > - memset(&priv->wdev, 0, sizeof(priv->wdev)); > - priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; > - return ERR_PTR(-EFAULT); > - } > - > priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC%s", > WQ_HIGHPRI | > WQ_MEM_RECLAIM | > WQ_UNBOUND, 1, name); > if (!priv->dfs_cac_workqueue) { > - mwifiex_dbg(adapter, ERROR, > - "cannot register virtual network device\n"); > - free_netdev(dev); > - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; > -
Re: [PATCH 2/6] wl1251: Use request_firmware_prefer_user() for loading NVS calibration data
On Tue, May 16, 2017 at 10:41:08AM +0200, Arend Van Spriel wrote: > On 16-5-2017 1:13, Luis R. Rodriguez wrote: > > On Fri, May 12, 2017 at 11:02:26PM +0200, Arend Van Spriel wrote: > >> try again.. replacing email address from Michał > >> On 12-5-2017 22:55, Arend Van Spriel wrote: > >>> Let me explain the idea to refresh your memory (and mine). It started > >>> when we were working on adding driver support for OpenWrt in brcmfmac. > >>> The driver requests for firmware calibration data, but on routers it is > >>> stored in flash. So after failing on the firmware request we now call a > >>> platform specific API. That was my itch, but it was not bad enough to go > >>> and scratch. Now for N900 case there is a similar scenario alhtough it > >>> has additional requirement to go to user-space due to need to use a > >>> proprietary library to obtain the NVS calibration data. My thought: Why > >>> should firmware_class care? > > > > Agreed. > > > >>> So the idea is that firmware_class provides > >>> a registry for modules that can produce a certain firmware "file". Those > >>> modules can do whatever is needed. If they need to use umh so be it. > >>> They would only register themselves with firmware_class on platforms > >>> that need them. It would basically be replacing the fallback mechanism > >>> and only be effective on certain platforms. > > > > Sure, so it sounds like the work that Daniel Wagner and Tom Gundersen worked > > [0] on which provides a firmwared with two modes: best-effort, and > > final-mode, > > would address what you are looking for but without requiring any upstream > > changes, *and* it also helps solve the rootfs race remote-proc folks had > > concerns over. > > > > The other added gain over this solution is if folks need their own > > proprietary > > concoction they can just fork firmwared and have that do whatever it needs > > for the specific device on the specific rootfs. That is, firmwared can be > > the > > upstream solution if folks need it, but if folks need something custom they > > can > > just mimic the implementation: best-effort, and and final-mode. > > > > Yet another added gain over this solution we can do *not* support the > > custom fallback mechanism as its not needed, the udev event should suffice > > to let userspace do what it needs. > > > > Lastly, if we did not want to deal with timeouts for the way the driver data > > API implements it I think we might be able to do away with them for for > > async > > requests if we assume there will be a daemon that spawns in final-mode > > eventually, > > and since it *knows* when the rootfs is ready it should be able to do a > > final > > lookup, if it returns -ENOENT; then indeed we know we can give up. Now, > > perhaps > > how and if we want to deal with timeouts when using the driver data API for > > the fallback mechanism is worth considering given it does not have a > > fallback > > mechanism support yet. If we *add* them it would seem this would also put an > > implicit race against userspace finishing initialization and running > > firmwared > > in final-mode. > > Just to be clear. When you are saying "rootfs" in this story, you mean > any (mounted) file-system which may hold the firmware. At least that was > one of the arguments. In kernel space we can not know how the system is > setup in terms of mount points, let alone on which mounted file-system > the firmware resides. Right, wherever the hell that thing is on, which could be on a crypic fuse drive waiting for some bits to be decrypted from Elon Musk on a spaceship on his way to Mars, and only userspace knows how to decrypt this thing through some evil proprietary thing, way way after a full bootup. > > Johannes, do you recall the corner cases we spoke about regarding timeouts? > > Does this match what we spoke about? > > > >>> Let me know if this idea is still of interest and I will rebase what I > >>> have for an RFC round. > > > > Since no upstream delta is needed for firmwared I'd like to first encourage > > evaluating the above. While distributions don't carry it yet that may be > > seen as > > an issue but since what we are looking for are corner cases, only folks > > needing > > to deploy a specific solution would need it or a custom proprietary > > solution. > > Ok. I will go try and run firmwared in OpenWrt on a router platform. > Have to steal one from a colleague :-p Will study firmwared. The finale-mode is the trick. > > [0] https://github.com/teg/firmwared.git > > > > PS. > > > > Note that firmware signing will require an additional file, the detached > > signature. The driver data API does not currently support the fallback > > mechanism so we would not have to worry about that yet but once we add > > fallback support we'd need to consider this. > > Do you have references to the firmware signing design. Is the idea to > have one signature and all "firmware files" need to be signed with it? Nope, I'm afraid a lot has be
Re: [PATCH] mac80211: Validate michael MIC before attempting packet decode.
On Tue, 2017-05-16 at 15:57 -0400, Michael Skeffington wrote: > Johannes, > > Thank you for that. I need to make a quick hack to send an invalid > MIC packet from another device to test the countermeasures. Should I > submit a new patch with this change when I've completed testing or > are you already prepared to do so? Please do, you're able to test it, and I'm not really all that familiar with that particular driver either, even if I maintain mac80211 :) johannes
Re: [PATCH 1/1] dt-binding: net: wireless: fix node name in the BCM43xx example
Hi Arend, On Tue, May 16, 2017 at 12:05 AM, Arend Van Spriel wrote: > On 15-5-2017 22:13, Martin Blumenstingl wrote: >> The example in the BCM43xx documentation uses "brcmf" as node name. >> However, wireless devices should be named "wifi" instead. Fix this to > > Hi Martin, > > Since when is that a rule. I never got the memo and the DTC did not ever > complain to me about the naming. That being said I do not really care > and I suppose it is for the sake of consistency only. I'm not sure if it's actually a rule or (as you already noted) just for consistency. back when I added devicetree support to ath9k Rob pointed out that the node should be named "wifi" (instead of "ath9k"), see [0] >> make sure that .dts authors can simply use the documentation as >> reference (or simply copy the node from the documentation and then >> adjust only the board specific bits). > > Please feel free to add my... > > Acked-by: Arend van Spriel thank you! @Rob: maybe you can ACK this as well if you're fine with this patch? >> Signed-off-by: Martin Blumenstingl >> --- >> Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git >> a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt >> b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt >> index 5dbf169cd81c..590f622188de 100644 >> --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt >> +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt >> @@ -31,7 +31,7 @@ mmc3: mmc@01c12000 { >> non-removable; >> status = "okay"; >> >> - brcmf: bcrmf@1 { >> + brcmf: wifi@1 { >> reg = <1>; >> compatible = "brcm,bcm4329-fmac"; >> interrupt-parent = <&pio>; >> [0] http://www.mail-archive.com/ath9k-devel@lists.ath9k.org/msg14678.html
Re: [PATCH] mac80211: Validate michael MIC before attempting packet decode.
Johannes, Thank you for that. I need to make a quick hack to send an invalid MIC packet from another device to test the countermeasures. Should I submit a new patch with this change when I've completed testing or are you already prepared to do so? Michael On Fri, May 12, 2017 at 4:52 AM, Johannes Berg wrote: > Here's the driver code from rt2500usb (but it's similar in the others): > > rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; > if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) > rxdesc->flags |= RX_FLAG_DECRYPTED; > else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) > rxdesc->flags |= RX_FLAG_MMIC_ERROR; > > I think if you just change it to be > > [...] > else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) > rxdesc->flags |= RX_FLAG_MMIC_ERROR | > RX_FLAG_DECRYPTED; > > things will start working. This is arguably correct since to be able to > check the MMIC, the frame has to have been decrypted (properly) before. > > johannes
Re: Search for devices with Xtensa cores
HI Oleksij, On Fri, Apr 28, 2017 at 11:23 PM, Oleksij Rempel wrote: > this year started with inclusion of open-ath9k-htc-firmware to debian > *main* repository. As first we started to getting advantage of regular > compile tests. See results here: > https://tests.reproducible-builds.org/debian/rb-pkg/unstable/i386/open-ath9k-htc-firmware.html > > Most of the problems which we currently get, are related to gcc xtensa > compiler. > In details: device specific patch set is used to provide our own > gcc/binutils version because Xtensa don't really have defined CPU cores. > As result, upstream compiler developers will never notice if some thing > will brake this patch set. Below are the links to the xtensa-dynconfig repository and xtensa-plugin-env branches in binutils-gdb and gcc repositories. Together it is a draft implementation of dynamically configurable xtensa toolchain. Could you please take a look at it and see if it's useful for you? https://github.com/jcmvbkbc/xtensa-dynconfig https://github.com/jcmvbkbc/binutils-gdb-xtensa/commits/xtensa-plugin-env https://github.com/jcmvbkbc/gcc-xtensa/commits/xtensa-plugin-env -- Thanks. -- Max
'iw events' stops receiving events after a while on 4.9 + hacks
I have been keeping an 'iw events' program running with a perl script gathering its output and post-processing it. This has been working for several years on 4.7 and earlier kernels, but when testing on 4.9 overnight, I notice that 'iw events' is not showing any input. 'strace' shows that it is waiting on recvmsg. If I start a second 'iw events' then it will get wifi events as expected. Are there any known issues in this area? Thanks, Ben -- Ben Greear Candela Technologies Inc http://www.candelatech.com
Re: [PATCHv2 4/4] ARM: dts: omap4-droid4: Add bluetooth
* Sebastian Reichel [170503 07:25]: > Droid 4 has WL 1285C connected to the OMAP's UART4 port, which is > used for Bluetooth and most likely can also be used for controlling > the FM radio and GPS receivers. I'm picking this patch and applying into omap-for-v4.13/dt thanks. Tony
Re: [PATCH] net: socket: mark socket protocol handler structs as const
From: linzhang Date: Mon, 15 May 2017 10:26:47 +0800 > Signed-off-by: linzhang Applied.
wireless-drivers-next is open for 4.13
Hi, I just fast forwarded wireless-drivers-next to latest net-next which means that wireless-drivers-next is open for new features going to 4.13. But I have over 100 patches pending on patchwork so it might take a while before I have catched up. -- Kalle Valo
Re: [PATCH] rt2x00: improve calling conventions for register accessors
From: Johannes Berg Date: Tue, 16 May 2017 13:58:56 +0200 > On Tue, 2017-05-16 at 13:55 +0200, Stanislaw Gruszka wrote: >> >> In rt2x00 driver we use poor convention in other kind of registers >> accessors like bbp, mac, eeprom. I dislike to changing only rfcsr >> accessors and leaving others in the old way. And changing all >> accessors would be massive and error prone change, which I'm not >> prefer either. > > That's a stupid argument, but for the sake of it - the conversion can > easily be done with coccinelle/spatch without being "error prone". Agreed, we have tools for this.
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On Tue, May 16, 2017 at 4:23 PM, Stanislaw Gruszka wrote: > On Tue, May 16, 2017 at 01:55:17PM +0200, Stanislaw Gruszka wrote: >> On Mon, May 15, 2017 at 10:39:51AM -0400, David Miller wrote: >> > From: Stanislaw Gruszka >> > Date: Mon, 15 May 2017 16:28:01 +0200 >> > >> > > On Mon, May 15, 2017 at 03:46:55PM +0200, Arnd Bergmann wrote: >> > >> With CONFIG_KASAN enabled and gcc-7, we get a warning about rather high >> > >> stack usage (with a private patch set I have to turn on this warning, >> > >> which I intend to get into the next kernel release): >> > >> >> > >> wireless/ralink/rt2x00/rt2800lib.c: In function >> > >> 'rt2800_bw_filter_calibration': >> > >> wireless/ralink/rt2x00/rt2800lib.c:7990:1: error: the frame size of >> > >> 2144 bytes is larger than 1536 bytes [-Werror=frame-larger-than=] >> > >> >> > >> The problem is that KASAN inserts a redzone around each local variable >> > >> that >> > >> gets passed by reference, and the newly added function has a lot of >> > >> them. >> > >> We can easily avoid that here by changing the calling convention to have >> > >> the output as the return value of the function. This should also >> > >> results in >> > >> smaller object code, saving around 4KB in .text with KASAN, or 2KB >> > >> without >> > >> KASAN. >> > >> >> > >> Fixes: 41977e86c984 ("rt2x00: add support for MT7620") >> > >> Signed-off-by: Arnd Bergmann >> > >> --- >> > >> drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 319 >> > >> + >> > >> 1 file changed, 164 insertions(+), 155 deletions(-) >> > > >> > > We have read(, &val) calling convention since forever in rt2x00 and that >> > > was never a problem. I dislike to change that now to make some tools >> > > happy, I think problem should be fixed in the tools instead. >> > >> > Passing return values by reference is and always has been a really >> > poor way to achieve what these functions are doing. >> > >> > And frankly, whilst the tool could see what's going on here better, we >> > should be making code easier rather than more difficult to audit. >> > >> > I am therefore very much in favor of Arnd's change. >> > >> > This isn't even a situation where there are multiple return values, >> > such as needing to signal an error and return an unsigned value at the >> > same time. >> > >> > These functions return _one_ value, and therefore they should be >> > returned as a true return value. >> >> In rt2x00 driver we use poor convention in other kind of registers >> accessors like bbp, mac, eeprom. I dislike to changing only rfcsr >> accessors and leaving others in the old way. And changing all accessors >> would be massive and error prone change, which I'm not prefer either. >> >> Arnd, could this be fixed by refactoring rt2800_bw_filter_calibration() >> function (which is enormous and definitely should be split into smaller >> subroutines) ? If not, I would accept this patch. > > Does below patch make things better with KASAN compilation ? Yes, that fixes the warning I got: Before: $ make -s EXTRA_CFLAGS=-Wframe-larger-than=500 /git/arm-soc/drivers/net/wireless/ralink/rt2x00/rt2800lib.c: In function 'rt2800_bw_filter_calibration': /git/arm-soc/drivers/net/wireless/ralink/rt2x00/rt2800lib.c:7990:1: error: the frame size of 2144 bytes is larger than 500 bytes [-Werror=frame-larger-than=] $ size drivers/net/wireless/ralink/rt2x00/built-in.otext data bssdechex filename 255979 39442 1536 296957 487fd drivers/net/wireless/ralink/rt2x00/built-in.o With your patch: $ make -s EXTRA_CFLAGS=-Wframe-larger-than=500 /git/arm-soc/drivers/net/wireless/ralink/rt2x00/rt2800lib.c: In function 'rt2800_bw_filter_calibration': /git/arm-soc/drivers/net/wireless/ralink/rt2x00/rt2800lib.c:7956:1: warning: the frame size of 576 bytes is larger than 300 bytes [-Wframe-larger-than=] $ size drivers/net/wireless/ralink/rt2x00/built-in.o text databssdechex filename 254367 39538 1536 295441 48211 drivers/net/wireless/ralink/rt2x00/built-in.o With my 300kb patch: $ make -s EXTRA_CFLAGS=-Wframe-larger-than=300 $ size drivers/net/wireless/ralink/rt2x00/built-in.o 237312 39442 1536 278290 43f12 drivers/net/wireless/ralink/rt2x00/built-in.o I passed -Wframe-larger-than=500 here to see the actual stack consumption. The 2144 bytes are definitely worrying, 576 bytes are generally harmless. My larger patch improves stack consumption and code size further: it brings all six functions that had >300 byte stacks below that, but it is not really needed with your change. Arnd
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On 05/16/2017 10:19 AM, Arnd Bergmann wrote: On Tue, May 16, 2017 at 3:44 PM, Jes Sorensen wrote: On 05/16/2017 07:55 AM, Stanislaw Gruszka wrote: On Mon, May 15, 2017 at 10:39:51AM -0400, David Miller wrote: Passing return values by reference is and always has been a really poor way to achieve what these functions are doing. And frankly, whilst the tool could see what's going on here better, we should be making code easier rather than more difficult to audit. I am therefore very much in favor of Arnd's change. This isn't even a situation where there are multiple return values, such as needing to signal an error and return an unsigned value at the same time. These functions return _one_ value, and therefore they should be returned as a true return value. In rt2x00 driver we use poor convention in other kind of registers accessors like bbp, mac, eeprom. I dislike to changing only rfcsr accessors and leaving others in the old way. And changing all accessors would be massive and error prone change, which I'm not prefer either. That's why you do it in multiple smaller patches rather than one ugly giant patch. I did the first step using a search&replace in vim using s:\(rt2800_rfcsr_read(.*,.*\), &\(.*\));:\2 = \1);: but had to introduce a conversion function static void rt2800_rfcsr_readreg(struct rt2x00_dev *rt2x00dev, const unsigned int word, u8 *value) { *value = rt2800_rfcsr_read(rt2x00dev, word); } to keep the correct types in place for struct rt2x00debug. I now did all the other ones too, and removed that helper again. The result in much nicer, but I basically ended up having to do the same regex search for all of these at once: static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, static void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, static void _rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev, static void rt2800_rfcsr_readreg(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, void (*register_read)(struct rt2x00_dev *rt2x00dev, void (*register_read_lock)(struct rt2x00_dev *rt2x00dev, static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, static inline void rt2800_register_read_lock(struct rt2x00_dev *rt2x00dev, static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev, static inline void rt2x00_eeprom_read(struct rt2x00_dev *rt2x00dev, void (*read)(struct rt2x00_dev *rt2x00dev, \ static inline void rt2x00mmio_register_read(struct rt2x00_dev *rt2x00dev, static inline void _rt2x00_desc_read(__le32 *desc, const u8 word, __le32 *value) static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) static inline void rt2x00usb_register_read(struct rt2x00_dev *rt2x00dev, static inline void rt2x00usb_register_read_lock(struct rt2x00_dev *rt2x00dev, static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, and that ended up as a 300KB patch [1]. Splitting it up is clearly possibly, but I fear that would be more error-prone as we then need to add those helpers for the other debug stuff as well, and remove it again afterwards. True - if the automatic conversion works without automatic intervention, I am less worried about it. Personally I would still focus on converting one function at a time to reduce the impact of each patch. Cheers, Jes
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On Tue, May 16, 2017 at 01:55:17PM +0200, Stanislaw Gruszka wrote: > On Mon, May 15, 2017 at 10:39:51AM -0400, David Miller wrote: > > From: Stanislaw Gruszka > > Date: Mon, 15 May 2017 16:28:01 +0200 > > > > > On Mon, May 15, 2017 at 03:46:55PM +0200, Arnd Bergmann wrote: > > >> With CONFIG_KASAN enabled and gcc-7, we get a warning about rather high > > >> stack usage (with a private patch set I have to turn on this warning, > > >> which I intend to get into the next kernel release): > > >> > > >> wireless/ralink/rt2x00/rt2800lib.c: In function > > >> 'rt2800_bw_filter_calibration': > > >> wireless/ralink/rt2x00/rt2800lib.c:7990:1: error: the frame size of 2144 > > >> bytes is larger than 1536 bytes [-Werror=frame-larger-than=] > > >> > > >> The problem is that KASAN inserts a redzone around each local variable > > >> that > > >> gets passed by reference, and the newly added function has a lot of them. > > >> We can easily avoid that here by changing the calling convention to have > > >> the output as the return value of the function. This should also results > > >> in > > >> smaller object code, saving around 4KB in .text with KASAN, or 2KB > > >> without > > >> KASAN. > > >> > > >> Fixes: 41977e86c984 ("rt2x00: add support for MT7620") > > >> Signed-off-by: Arnd Bergmann > > >> --- > > >> drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 319 > > >> + > > >> 1 file changed, 164 insertions(+), 155 deletions(-) > > > > > > We have read(, &val) calling convention since forever in rt2x00 and that > > > was never a problem. I dislike to change that now to make some tools > > > happy, I think problem should be fixed in the tools instead. > > > > Passing return values by reference is and always has been a really > > poor way to achieve what these functions are doing. > > > > And frankly, whilst the tool could see what's going on here better, we > > should be making code easier rather than more difficult to audit. > > > > I am therefore very much in favor of Arnd's change. > > > > This isn't even a situation where there are multiple return values, > > such as needing to signal an error and return an unsigned value at the > > same time. > > > > These functions return _one_ value, and therefore they should be > > returned as a true return value. > > In rt2x00 driver we use poor convention in other kind of registers > accessors like bbp, mac, eeprom. I dislike to changing only rfcsr > accessors and leaving others in the old way. And changing all accessors > would be massive and error prone change, which I'm not prefer either. > > Arnd, could this be fixed by refactoring rt2800_bw_filter_calibration() > function (which is enormous and definitely should be split into smaller > subroutines) ? If not, I would accept this patch. Does below patch make things better with KASAN compilation ? diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index d11c7b2..4b85ef3 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -7740,6 +7740,39 @@ static char rt2800_lp_tx_filter_bw_cal(struct rt2x00_dev *rt2x00dev) return cal_val; } +#define RF_SAVE_NUM 24 +#define BBP_SAVE_NUM 3 +static const int rf_save_ids[RF_SAVE_NUM] = {0, 1, 3, 4, 5, 6, 7, 8, + 17, 18, 19, 20, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 58, 59}; + +static void rt2800_phy_save(struct rt2x00_dev *rt2x00dev, + u8 *const bbp_regs, u8 *const rf_regs) +{ + int i; + + rt2800_bbp_read(rt2x00dev, 23, &bbp_regs[0]); + + rt2800_bbp_dcoc_read(rt2x00dev, 0, &bbp_regs[1]); + rt2800_bbp_dcoc_read(rt2x00dev, 2, &bbp_regs[2]); + + for (i = 0; i < RF_SAVE_NUM; i++) + rt2800_rfcsr_read_bank(rt2x00dev, 5, rf_save_ids[i], &rf_regs[i]); +} + +static void rt2800_phy_restore(struct rt2x00_dev *rt2x00dev, + const u8 *const bbp_regs, const u8 *const rf_regs) +{ + int i; + + for (i = 0; i < RF_SAVE_NUM; i++) + rt2800_rfcsr_write_bank(rt2x00dev, 5, rf_save_ids[i], rf_regs[i]); + + rt2800_bbp_write(rt2x00dev, 23, bbp_regs[0]); + + rt2800_bbp_dcoc_write(rt2x00dev, 0, bbp_regs[1]); + rt2800_bbp_dcoc_write(rt2x00dev, 2, bbp_regs[2]); +} + static void rt2800_bw_filter_calibration(struct rt2x00_dev *rt2x00dev, bool btxcal) { @@ -7751,52 +7784,15 @@ static void rt2800_bw_filter_calibration(struct rt2x00_dev *rt2x00dev, int loop = 0, is_ht40, cnt; u8 bbp_val, rf_val; char cal_r32_init, cal_r32_val, cal_diff; - u8 saverfb5r00, saverfb5r01, saverfb5r03, saverfb5r04, saverfb5r05; - u8 saverfb5r06, saverfb5r07; - u8 saverfb5r08, saverfb5r17, saverfb5r18, saverfb5r19, saverfb5r20; - u8 saverfb5r37, saverfb5r38, saverfb5r39, saverfb5r40, saverfb5r41; - u8 saverfb5r42, saverfb5r43, sa
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On Tue, May 16, 2017 at 3:44 PM, Jes Sorensen wrote: > On 05/16/2017 07:55 AM, Stanislaw Gruszka wrote: >> >> On Mon, May 15, 2017 at 10:39:51AM -0400, David Miller wrote: >>> >>> Passing return values by reference is and always has been a really >>> poor way to achieve what these functions are doing. >>> >>> And frankly, whilst the tool could see what's going on here better, we >>> should be making code easier rather than more difficult to audit. >>> >>> I am therefore very much in favor of Arnd's change. >>> >>> This isn't even a situation where there are multiple return values, >>> such as needing to signal an error and return an unsigned value at the >>> same time. >>> >>> These functions return _one_ value, and therefore they should be >>> returned as a true return value. >> >> >> In rt2x00 driver we use poor convention in other kind of registers >> accessors like bbp, mac, eeprom. I dislike to changing only rfcsr >> accessors and leaving others in the old way. And changing all accessors >> would be massive and error prone change, which I'm not prefer either. > > > That's why you do it in multiple smaller patches rather than one ugly giant > patch. I did the first step using a search&replace in vim using s:\(rt2800_rfcsr_read(.*,.*\), &\(.*\));:\2 = \1);: but had to introduce a conversion function static void rt2800_rfcsr_readreg(struct rt2x00_dev *rt2x00dev, const unsigned int word, u8 *value) { *value = rt2800_rfcsr_read(rt2x00dev, word); } to keep the correct types in place for struct rt2x00debug. I now did all the other ones too, and removed that helper again. The result in much nicer, but I basically ended up having to do the same regex search for all of these at once: static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, static void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, static void _rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev, static void rt2800_rfcsr_readreg(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, void (*register_read)(struct rt2x00_dev *rt2x00dev, void (*register_read_lock)(struct rt2x00_dev *rt2x00dev, static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, static inline void rt2800_register_read_lock(struct rt2x00_dev *rt2x00dev, static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev, static inline void rt2x00_eeprom_read(struct rt2x00_dev *rt2x00dev, void (*read)(struct rt2x00_dev *rt2x00dev, \ static inline void rt2x00mmio_register_read(struct rt2x00_dev *rt2x00dev, static inline void _rt2x00_desc_read(__le32 *desc, const u8 word, __le32 *value) static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) static inline void rt2x00usb_register_read(struct rt2x00_dev *rt2x00dev, static inline void rt2x00usb_register_read_lock(struct rt2x00_dev *rt2x00dev, static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, and that ended up as a 300KB patch [1]. Splitting it up is clearly possibly, but I fear that would be more error-prone as we then need to add those helpers for the other debug stuff as well, and remove it again afterwards. Arnd [1] https://pastebin.com/raw/Qis257mG
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On 05/16/2017 07:55 AM, Stanislaw Gruszka wrote: On Mon, May 15, 2017 at 10:39:51AM -0400, David Miller wrote: Passing return values by reference is and always has been a really poor way to achieve what these functions are doing. And frankly, whilst the tool could see what's going on here better, we should be making code easier rather than more difficult to audit. I am therefore very much in favor of Arnd's change. This isn't even a situation where there are multiple return values, such as needing to signal an error and return an unsigned value at the same time. These functions return _one_ value, and therefore they should be returned as a true return value. In rt2x00 driver we use poor convention in other kind of registers accessors like bbp, mac, eeprom. I dislike to changing only rfcsr accessors and leaving others in the old way. And changing all accessors would be massive and error prone change, which I'm not prefer either. That's why you do it in multiple smaller patches rather than one ugly giant patch. The rt2x00 current register accessor functions makes the Realtek vendor driver equivalent ones look pretty, which is saying something. Jes
[PATCH 08/10] rtlwifi: btcoex: 23b 1ant: check if BT high priority packet exist
From: Ping-Ke Shih If there are BT high priority packets, we arrange more time to BT. To make user experience to be better, HID and SCO are also seen as high priority packet exist. Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c | 11 +++ .../net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h | 1 + drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h | 1 + 3 files changed, 13 insertions(+) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index 437007dd0db0..9178cccb5ddf 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -407,6 +407,7 @@ static void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist) bt_link_info->a2dp_exist = coex_sta->a2dp_exist; bt_link_info->pan_exist = coex_sta->pan_exist; bt_link_info->hid_exist = coex_sta->hid_exist; + bt_link_info->bt_hi_pri_link_exist = coex_sta->bt_hi_pri_link_exist; /* work around for HS mode. */ if (bt_hs_on) { @@ -2644,6 +2645,8 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, coex_sta->a2dp_exist = false; coex_sta->hid_exist = false; coex_sta->sco_exist = false; + + coex_sta->bt_hi_pri_link_exist = false; } else { /* connection exists */ coex_sta->bt_link_exist = true; @@ -2663,6 +2666,14 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, coex_sta->sco_exist = true; else coex_sta->sco_exist = false; + + /* Add Hi-Pri Tx/Rx counter to avoid false detection */ + if (((coex_sta->hid_exist) || (coex_sta->sco_exist)) && + (coex_sta->high_priority_tx + coex_sta->high_priority_rx >= +160) && + (!coex_sta->c2h_bt_inquiry_page)) + coex_sta->bt_hi_pri_link_exist = true; + } halbtc8723b1ant_update_bt_link_info(btcoexist); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h index cf14db5fa759..0b7b9b2a8e12 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h @@ -142,6 +142,7 @@ struct coex_sta_8723b_1ant { bool a2dp_exist; bool hid_exist; bool pan_exist; + bool bt_hi_pri_link_exist; bool under_lps; bool under_ips; diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h index ab2e31a44253..6ce2fcadc144 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h @@ -468,6 +468,7 @@ struct btc_statistics { struct btc_bt_link_info { bool bt_link_exist; + bool bt_hi_pri_link_exist; bool sco_exist; bool sco_only; bool a2dp_exist; -- 2.12.0
[PATCH 03/10] rtlwifi: btcoex: 21a 1ant: add bt_tx_rx_mask into bt info
From: Yan-Hsuan Chuang Set rf register if the tx rx mask is switched. Signed-off-by: Yan-Hsuan Chuang Signed-off-by: Larry Finger Cc: Pkshih Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | 14 ++ .../wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h | 1 + 2 files changed, 15 insertions(+) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c index 93644bedaa0f..4efac5fe9982 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c @@ -2848,6 +2848,20 @@ void ex_btc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist, coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4]; + coex_sta->bt_tx_rx_mask = + (coex_sta->bt_info_c2h[rsp_source][2] & 0x40); + btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK, + &coex_sta->bt_tx_rx_mask); + if (!coex_sta->bt_tx_rx_mask) { + /* BT into is responded by BT FW and BT RF REG 0x3C != +* 0x15 => Need to switch BT TRx Mask +*/ + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n"); + btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, + 0x3c, 0x15); + } + /* Here we need to resend some wifi info to BT * because bt is reset and lost the info */ diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h index 1eba3b0d32ae..cb32e7a64ae6 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h @@ -154,6 +154,7 @@ struct coex_sta_8821a_1ant { u32 low_priority_tx; u32 low_priority_rx; u8 bt_rssi; + boolbt_tx_rx_mask; u8 pre_bt_rssi_state; u8 pre_wifi_rssi_state[4]; boolc2h_bt_info_req_sent; -- 2.12.0
[PATCH 09/10] rtlwifi: btcoex: 23b 1ant: monitor bt is enabled or disabled
From: Ping-Ke Shih Check BT's status, and record it in field bt_disabled. When BT is disabled, We do special action called wifi_only. Also, we move the field from 'struct btc_coexist' to 'struct coex_sta_8723b_1ant'. Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index 9178cccb5ddf..b07883eaec5e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -2136,7 +2136,7 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist) RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", -((btcoexist->bt_info.bt_disabled) ? ("disabled") : +((coex_sta->bt_disabled) ? ("disabled") : ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : ((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status) ? @@ -2422,7 +2422,7 @@ void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) u8 agg_buf_size = 5; if (btcoexist->manual_control || btcoexist->stop_coex_dm || - btcoexist->bt_info.bt_disabled) + coex_sta->bt_disabled) return; btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, @@ -2472,7 +2472,7 @@ void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist, u8 wifi_central_chnl; if (btcoexist->manual_control || btcoexist->stop_coex_dm || - btcoexist->bt_info.bt_disabled) + coex_sta->bt_disabled) return; if (BTC_MEDIA_CONNECT == type) @@ -2519,7 +2519,7 @@ void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist, u8 agg_buf_size = 5; if (btcoexist->manual_control || btcoexist->stop_coex_dm || - btcoexist->bt_info.bt_disabled) + coex_sta->bt_disabled) return; btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, -- 2.12.0
[PATCH 06/10] rtlwifi: btcoex: 23b 1ant: TDMA duration for ACL busy
From: Ping-Ke Shih BT ACL is a special case, so we create a routine to deal this case. Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.c| 54 +- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index 2e1ba8fed982..523e1acfe1cf 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -1124,6 +1124,11 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, /* acquire the BT TRx retry count from BT_Info byte2 */ retry_count = coex_sta->bt_retry_cnt; bt_info_ext = coex_sta->bt_info_ext; + + if ((coex_sta->low_priority_tx) > 1050 || + (coex_sta->low_priority_rx) > 1250) + retry_count++; + result = 0; wait_count++; /* no retry in the last 2-second duration */ @@ -1135,6 +1140,9 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, dn = 0; if (up >= n) { + /* if retry count during continuous n*2 seconds +* is 0, enlarge WiFi duration +*/ wait_count = 0; n = 3; up = 0; @@ -1144,6 +1152,7 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, "[BTCoex], Increase wifi duration!!\n"); } } else if (retry_count <= 3) { + /* <=3 retry in the last 2-second duration */ up--; dn++; @@ -1151,12 +1160,20 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, up = 0; if (dn == 2) { + /* if continuous 2 retry count(every 2 seconds) +* >0 and < 3, reduce WiFi duration +*/ if (wait_count <= 2) + /* avoid loop between the two levels */ m++; else m = 1; if (m >= 20) + /* maximum of m = 20 ' will recheck if +* need to adjust wifi duration in +* maximum time interval 120 seconds +*/ m = 20; n = 3 * m; @@ -1168,12 +1185,20 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); } } else { + /* retry count > 3, once retry count > 3, to reduce +* WiFi duration +*/ if (wait_count == 1) + /* to avoid loop between the two levels */ m++; else m = 1; if (m >= 20) + /* maximum of m = 20 ' will recheck if need to +* adjust wifi duration in maximum time interval +* 120 seconds +*/ m = 20; n = 3 * m; @@ -1186,13 +1211,7 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, } if (result == -1) { - if ((BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) && - ((coex_dm->cur_ps_tdma == 1) || -(coex_dm->cur_ps_tdma == 2))) { - halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, - true, 9); - coex_dm->ps_tdma_du_adj_type = 9; - } else if (coex_dm->cur_ps_tdma == 1) { + if (coex_dm->cur_ps_tdma == 1) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); coex_dm->ps_tdma_du_adj_type =
[PATCH 07/10] rtlwifi: btcoex: 23b 1ant: monitor wifi and BT counter
From: Ping-Ke Shih In field debug, we check wifi and BT counter to analyze problems. Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.c| 141 +++-- .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.h| 15 +++ 2 files changed, 145 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index 523e1acfe1cf..437007dd0db0 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -210,11 +210,24 @@ static void halbtc8723b1ant_limited_rx(struct btc_coexist *btcoexist, btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); } +static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist) +{ + u8 h2c_parameter[1] = {0}; + + coex_sta->c2h_bt_info_req_sent = true; + + /* trigger */ + h2c_parameter[0] |= BIT(0); + + btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); +} + static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist) { u32 reg_hp_txrx, reg_lp_txrx, u32tmp; u32 reg_hp_tx = 0, reg_hp_rx = 0; u32 reg_lp_tx = 0, reg_lp_rx = 0; + static u32 num_of_bt_counter_chk; reg_hp_txrx = 0x770; reg_lp_txrx = 0x774; @@ -232,25 +245,122 @@ static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist) coex_sta->low_priority_tx = reg_lp_tx; coex_sta->low_priority_rx = reg_lp_rx; + if ((coex_sta->low_priority_tx > 1050) && + (!coex_sta->c2h_bt_inquiry_page)) + coex_sta->pop_event_cnt++; + /* reset counter */ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); + + /* This part is for wifi FW and driver to update BT's status as +* disabled. +* +* The flow is as the following +* 1. disable BT +* 2. if all BT Tx/Rx counter = 0, after 6 sec we query bt info +* 3. Because BT will not rsp from mailbox, so wifi fw will know BT is +* disabled +* +* 4. FW will rsp c2h for BT that driver will know BT is disabled. +*/ + if ((reg_hp_tx == 0) && (reg_hp_rx == 0) && (reg_lp_tx == 0) && + (reg_lp_rx == 0)) { + num_of_bt_counter_chk++; + if (num_of_bt_counter_chk == 3) + halbtc8723b1ant_query_bt_info(btcoexist); + } else { + num_of_bt_counter_chk = 0; + } } -static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist) +static void halbtc8723b1ant_monitor_wifi_ctr(struct btc_coexist *btcoexist) { - struct rtl_priv *rtlpriv = btcoexist->adapter; - u8 h2c_parameter[1] = {0}; + s32 wifi_rssi = 0; + bool wifi_busy = false, wifi_under_b_mode = false; + static u8 cck_lock_counter; + u32 total_cnt; - coex_sta->c2h_bt_info_req_sent = true; + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); - /* trigger */ - h2c_parameter[0] |= BIT0; + if (coex_sta->under_ips) { + coex_sta->crc_ok_cck = 0; + coex_sta->crc_ok_11g = 0; + coex_sta->crc_ok_11n = 0; + coex_sta->crc_ok_11n_agg = 0; + + coex_sta->crc_err_cck = 0; + coex_sta->crc_err_11g = 0; + coex_sta->crc_err_11n = 0; + coex_sta->crc_err_11n_agg = 0; + } else { + coex_sta->crc_ok_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf88); + coex_sta->crc_ok_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf94); + coex_sta->crc_ok_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf90); + coex_sta->crc_ok_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfb8); + + coex_sta->crc_err_cck = + btcoexist->btc_read_4byte(btcoexist, 0xf84); + coex_sta->crc_err_11g = + btcoexist->btc_read_2byte(btcoexist, 0xf96); + coex_sta->crc_err_11n = + btcoexist->btc_read_2byte(btcoexist, 0xf92); + coex_sta->crc_err_11n_agg = + btcoexist->btc_read_2byte(btcoexist, 0xfba); + } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, -"[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", -h2c_parameter[0]); + /* reset counter */ + btcoexist->btc_write_1byte_bitmask(btcoe
[PATCH 10/10] rtlwifi: btcoex: 23b 1ant: check PS state before setting tdma duration
From: Ping-Ke Shih For time division multiple access, the wifi and bt take turns to transmit, but we need to let AP know that wifi is under standby mode by sending null data to "pretend" entering power saving state using lps rpwm. But, the fw does not know if it is the actual power saving mode or just a fake one to cheat to the AP. Hence, before fw setting the tdma duration, the fw needs the driver to check the power saving state first. Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c | 3 +++ drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index b07883eaec5e..f3704d7db4d5 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -1401,6 +1401,7 @@ static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist, btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &low_pwr_disable); btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + coex_sta->force_lps_on = false; break; case BTC_PS_LPS_ON: halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, true); @@ -1412,10 +1413,12 @@ static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist, &low_pwr_disable); /* power save must executed before psTdma */ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); + coex_sta->force_lps_on = true; break; case BTC_PS_LPS_OFF: halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, false); btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + coex_sta->force_lps_on = false; break; default: break; diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h index 0b7b9b2a8e12..d502a31812ab 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.h @@ -161,6 +161,7 @@ struct coex_sta_8723b_1ant { u8 bt_retry_cnt; u8 bt_info_ext; bool cck_ever_lock; + bool force_lps_on; u32 pop_event_cnt; u32 crc_ok_cck; -- 2.12.0
[PATCH 05/10] rtlwifi: btcoex: 23b 1ant: rename and coding style modification.
From: Ping-Ke Shih Rename: * tdma_adj_type to ps_tdma_du_adj_type * wifiCentralChnl to wifi_central_chnl Coding style: * move constant from right to left side in if-statement Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.c| 88 +++--- .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.h| 2 +- 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index df0782c17905..2e1ba8fed982 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -1094,7 +1094,7 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); - coex_dm->tdma_adj_type = 9; + coex_dm->ps_tdma_du_adj_type = 9; up = 0; dn = 0; @@ -1112,7 +1112,7 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, "[BTCoex], first run TdmaDurationAdjust()!!\n"); halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); - coex_dm->tdma_adj_type = 2; + coex_dm->ps_tdma_du_adj_type = 2; up = 0; dn = 0; @@ -1191,19 +1191,19 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, (coex_dm->cur_ps_tdma == 2))) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); - coex_dm->tdma_adj_type = 9; + coex_dm->ps_tdma_du_adj_type = 9; } else if (coex_dm->cur_ps_tdma == 1) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); - coex_dm->tdma_adj_type = 2; + coex_dm->ps_tdma_du_adj_type = 2; } else if (coex_dm->cur_ps_tdma == 2) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); - coex_dm->tdma_adj_type = 9; + coex_dm->ps_tdma_du_adj_type = 9; } else if (coex_dm->cur_ps_tdma == 9) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); - coex_dm->tdma_adj_type = 11; + coex_dm->ps_tdma_du_adj_type = 11; } } else if (result == 1) { if ((BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) && @@ -1211,19 +1211,19 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, (coex_dm->cur_ps_tdma == 2))) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); - coex_dm->tdma_adj_type = 9; + coex_dm->ps_tdma_du_adj_type = 9; } else if (coex_dm->cur_ps_tdma == 11) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); - coex_dm->tdma_adj_type = 9; + coex_dm->ps_tdma_du_adj_type = 9; } else if (coex_dm->cur_ps_tdma == 9) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); - coex_dm->tdma_adj_type = 2; + coex_dm->ps_tdma_du_adj_type = 2; } else if (coex_dm->cur_ps_tdma == 2) { halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); - coex_dm->tdma_adj_type = 1; + coex_dm->ps_tdma_du_adj_type = 1; } } else { /* if busy / idle change */ @@ -1236,7 +1236,7 @@ void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, coex_dm->cur_ps_tdma != 9 && coex_dm->cur_ps_tdma != 11) {
[PATCH 04/10] rtlwifi: btcoex: Restore 23b 1ant routine for tdma adjustment
Routine btc8723b1ant_tdma_dur_adj_for_acl() was removed in a set of Sparse fixes; however, this routine will be needed later. Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Pkshih Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.c| 177 - 1 file changed, 176 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c index f23c9e3fbda1..df0782c17905 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c @@ -1066,8 +1066,183 @@ static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist, coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; } +void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, + u8 wifi_status) +{ + struct rtl_priv *rtlpriv = btcoexist->adapter; + static s32 up, dn, m, n, wait_count; + /* 0: no change, +1: increase WiFi duration, +* -1: decrease WiFi duration +*/ + s32 result; + u8 retry_count = 0, bt_info_ext; + bool wifi_busy = false; + + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], TdmaDurationAdjustForAcl()\n"); + + if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY) + wifi_busy = true; + else + wifi_busy = false; + + if ((wifi_status == +BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN) || + (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN) || + (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT)) { + if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && + coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) { + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, + true, 9); + coex_dm->tdma_adj_type = 9; + + up = 0; + dn = 0; + m = 1; + n = 3; + result = 0; + wait_count = 0; + } + return; + } + + if (!coex_dm->auto_tdma_adjust) { + coex_dm->auto_tdma_adjust = true; + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], first run TdmaDurationAdjust()!!\n"); + + halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); + coex_dm->tdma_adj_type = 2; + + up = 0; + dn = 0; + m = 1; + n = 3; + result = 0; + wait_count = 0; + } else { + /* acquire the BT TRx retry count from BT_Info byte2 */ + retry_count = coex_sta->bt_retry_cnt; + bt_info_ext = coex_sta->bt_info_ext; + result = 0; + wait_count++; + /* no retry in the last 2-second duration */ + if (retry_count == 0) { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if (up >= n) { + wait_count = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], Increase wifi duration!!\n"); + } + } else if (retry_count <= 3) { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) { + if (wait_count <= 2) + m++; + else + m = 1; + + if (m >= 20) + m = 20; + + n = 3 * m; + up = 0; + dn = 0; + wait_count = 0; + result = -1; + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); + } + } else { + if (wait_count == 1) + m++; + else + m = 1; + + if (m >= 20) +
[PATCH 02/10] rtlwifi: btcoex: 21a 1ant: fix some coding style issues
From: Yan-Hsuan Chuang Fix alignment for coding style consistency. Signed-off-by: Yan-Hsuan Chuang Signed-off-by: Larry Finger Cc: Pkshih Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c index a5ac07cf0dca..93644bedaa0f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c @@ -2839,14 +2839,14 @@ void ex_btc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist, } if (BT_INFO_SRC_8821A_1ANT_WIFI_FW != rsp_source) { - coex_sta->bt_retry_cnt =/* [3:0]*/ - coex_sta->bt_info_c2h[rsp_source][2]&0xf; + /* [3:0] */ + coex_sta->bt_retry_cnt = + coex_sta->bt_info_c2h[rsp_source][2] & 0xf; coex_sta->bt_rssi = - coex_sta->bt_info_c2h[rsp_source][3]*2+10; + coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; - coex_sta->bt_info_ext = - coex_sta->bt_info_c2h[rsp_source][4]; + coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4]; /* Here we need to resend some wifi info to BT * because bt is reset and lost the info @@ -2928,11 +2928,11 @@ void ex_btc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist, RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); } else if ((bt_info&BT_INFO_8821A_1ANT_B_SCO_ESCO) || - (bt_info&BT_INFO_8821A_1ANT_B_SCO_BUSY)) { + (bt_info & BT_INFO_8821A_1ANT_B_SCO_BUSY)) { coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_SCO_BUSY; RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); - } else if (bt_info&BT_INFO_8821A_1ANT_B_ACL_BUSY) { + } else if (bt_info & BT_INFO_8821A_1ANT_B_ACL_BUSY) { if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status) coex_dm->auto_tdma_adjust = false; coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_ACL_BUSY; -- 2.12.0
[PATCH 01/10] rtlwifi: btcoex: 21a 1ant: treat ARP as special packet
From: Yan-Hsuan Chuang We need to pay attention to ARP packets to correctly establish connection, and reset the ARP counter when disconnected. Signed-off-by: Yan-Hsuan Chuang Signed-off-by: Larry Finger Cc: Pkshih Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting --- .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.c| 49 -- .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.h| 1 + 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c index 84cc0bcc5f80..a5ac07cf0dca 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c @@ -2592,7 +2592,7 @@ void ex_btc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type) void ex_btc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) { struct rtl_priv *rtlpriv = btcoexist->adapter; - boolwifi_connected = false, bt_hs_on = false; + bool wifi_connected = false, bt_hs_on = false; u32 wifi_link_status = 0; u32 num_of_wifi_link = 0; bool bt_ctrl_agg_buf_size = false; @@ -2610,6 +2610,18 @@ void ex_btc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) return; } + if (type == BTC_ASSOCIATE_START) { + coex_sta->wifi_is_high_pri_task = true; + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], CONNECT START notify\n"); + coex_dm->arp_cnt = 0; + } else { + coex_sta->wifi_is_high_pri_task = false; + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], CONNECT FINISH notify\n"); + coex_dm->arp_cnt = 0; + } + btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifi_link_status); num_of_wifi_link = wifi_link_status >> 16; @@ -2675,6 +2687,7 @@ void ex_btc8821a1ant_media_status_notify(struct btc_coexist *btcoexist, } else { RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], MEDIA disconnect notify\n"); + coex_dm->arp_cnt = 0; } /* only 2.4G we need to inform bt the chnl mask */ @@ -2728,6 +2741,24 @@ void ex_btc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist, return; } + if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL || + type == BTC_PACKET_ARP) { + coex_sta->wifi_is_high_pri_task = true; + + if (type == BTC_PACKET_ARP) { + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], specific Packet ARP notify\n"); + } else { + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], specific Packet DHCP or EAPOL notify\n"); + } + } else { + coex_sta->wifi_is_high_pri_task = false; + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], specific Packet [Type = %d] notify\n", +type); + } + coex_sta->special_pkt_period_cnt = 0; btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, @@ -2750,8 +2781,20 @@ void ex_btc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist, return; } - if (BTC_PACKET_DHCP == type || - BTC_PACKET_EAPOL == type) { + if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL || + type == BTC_PACKET_ARP) { + if (type == BTC_PACKET_ARP) { + coex_dm->arp_cnt++; + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +"[BTCoex], ARP Packet Count = %d\n", +coex_dm->arp_cnt); + if (coex_dm->arp_cnt >= 10) + /* if APR PKT > 10 after connect, do not go to +* btc8821a1ant_act_wifi_conn_sp_pkt +*/ + return; + } + RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], special Packet(%d) notify\n", type); btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h index d6dacf32a4c4..1eba3b0d32ae 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.h @@ -133,6 +133,7 @@ struct coex_dm_8821a_1ant { u8 cur_retry_limit_type; u8 pre_ampdu_time_type;
[PATCH 00/10] rtlwifi: btcoex: More changes to Bluetooth Coexistence
This set of patches complete the updates for the 8821a 1ant code and starts the updates for 8723b 1ant. Signed-off-by: Yan-Hsuan Chuang Signed-off-by: Pkshih Signed-off-by: Larry Finger Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting Larry Finger (1): rtlwifi: btcoex: Restore 23b 1ant routine for tdma adjustment Ping-Ke Shih (6): rtlwifi: btcoex: 23b 1ant: rename and coding style modification. rtlwifi: btcoex: 23b 1ant: TDMA duration for ACL busy rtlwifi: btcoex: 23b 1ant: monitor wifi and BT counter rtlwifi: btcoex: 23b 1ant: check if BT high priority packet exist rtlwifi: btcoex: 23b 1ant: monitor bt is enabled or disabled rtlwifi: btcoex: 23b 1ant: check PS state before setting tdma duration Yan-Hsuan Chuang (3): rtlwifi: btcoex: 21a 1ant: treat ARP as special packet rtlwifi: btcoex: 21a 1ant: fix some coding style issues rtlwifi: btcoex: 21a 1ant: add bt_tx_rx_mask into bt info .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.c| 422 ++--- .../realtek/rtlwifi/btcoexist/halbtc8723b1ant.h| 19 +- .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.c| 77 +++- .../realtek/rtlwifi/btcoexist/halbtc8821a1ant.h| 2 + .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h | 1 + 5 files changed, 456 insertions(+), 65 deletions(-) -- 2.12.0
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On Tue, May 16, 2017 at 01:58:56PM +0200, Johannes Berg wrote: > On Tue, 2017-05-16 at 13:55 +0200, Stanislaw Gruszka wrote: > > > > In rt2x00 driver we use poor convention in other kind of registers > > accessors like bbp, mac, eeprom. I dislike to changing only rfcsr > > accessors and leaving others in the old way. And changing all > > accessors would be massive and error prone change, which I'm not > > prefer either. > > That's a stupid argument, but for the sake of it - the conversion can > easily be done with coccinelle/spatch without being "error prone". Sure, but still I think it would be preferable to fix newly added rt2800_bw_filter_calibration() function, instead of ancient rfcsr accessors. Stanislaw
Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
On Tuesday, May 16, 2017 1:55:46 PM CEST Bastian Bittorf wrote: > * Simon Wunderlich [16.05.2017 12:24]: > > * station A detects a Radar, and informs userspace > > * userspace of station A will initiate a CSA, kernel will execute it > > (action> > > frame, beacons) > > > > * station B picks up the CSA, and executes it as well > > * station B also marks the channel as unavailable > > * both station A and station B will send an event to userspace once the > > > > channel switch is complete > > ah, I remember the slides from last battlemesh. > > The "problems" in userspace are: we must maintain a global list > (so each node) which channel is the next best and we must time > the final channel switch. IMHO the specs are saying, that we must > switch within 30 secs after detecting the first radar-pattern. > Also we must mark/show the new channel somehow for new/crashed/upcoming > nodes. quite hard... The timing is not a big problem, since the switch does not happen immediately but is performed after a "countdown" which is part of the channel switch announcement IEs. The specific rules for the countdown depend on the regulatory domain, but it's usually something between 1 and 5 seconds where payload traffic must not be transmitted (at least for the DFS case). The bigger problem appears when a node is missing the CSA for whatever reason, or is joining the network - worst case, the mesh network can split into clouds on different channels. This is where we need the global list, or showing the next channel, etc. :) Cheers, Simon signature.asc Description: This is a digitally signed message part.
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On Tue, 2017-05-16 at 13:55 +0200, Stanislaw Gruszka wrote: > > In rt2x00 driver we use poor convention in other kind of registers > accessors like bbp, mac, eeprom. I dislike to changing only rfcsr > accessors and leaving others in the old way. And changing all > accessors would be massive and error prone change, which I'm not > prefer either. That's a stupid argument, but for the sake of it - the conversion can easily be done with coccinelle/spatch without being "error prone". johannes
Re: [PATCH] rt2x00: improve calling conventions for register accessors
On Mon, May 15, 2017 at 10:39:51AM -0400, David Miller wrote: > From: Stanislaw Gruszka > Date: Mon, 15 May 2017 16:28:01 +0200 > > > On Mon, May 15, 2017 at 03:46:55PM +0200, Arnd Bergmann wrote: > >> With CONFIG_KASAN enabled and gcc-7, we get a warning about rather high > >> stack usage (with a private patch set I have to turn on this warning, > >> which I intend to get into the next kernel release): > >> > >> wireless/ralink/rt2x00/rt2800lib.c: In function > >> 'rt2800_bw_filter_calibration': > >> wireless/ralink/rt2x00/rt2800lib.c:7990:1: error: the frame size of 2144 > >> bytes is larger than 1536 bytes [-Werror=frame-larger-than=] > >> > >> The problem is that KASAN inserts a redzone around each local variable that > >> gets passed by reference, and the newly added function has a lot of them. > >> We can easily avoid that here by changing the calling convention to have > >> the output as the return value of the function. This should also results in > >> smaller object code, saving around 4KB in .text with KASAN, or 2KB without > >> KASAN. > >> > >> Fixes: 41977e86c984 ("rt2x00: add support for MT7620") > >> Signed-off-by: Arnd Bergmann > >> --- > >> drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 319 > >> + > >> 1 file changed, 164 insertions(+), 155 deletions(-) > > > > We have read(, &val) calling convention since forever in rt2x00 and that > > was never a problem. I dislike to change that now to make some tools > > happy, I think problem should be fixed in the tools instead. > > Passing return values by reference is and always has been a really > poor way to achieve what these functions are doing. > > And frankly, whilst the tool could see what's going on here better, we > should be making code easier rather than more difficult to audit. > > I am therefore very much in favor of Arnd's change. > > This isn't even a situation where there are multiple return values, > such as needing to signal an error and return an unsigned value at the > same time. > > These functions return _one_ value, and therefore they should be > returned as a true return value. In rt2x00 driver we use poor convention in other kind of registers accessors like bbp, mac, eeprom. I dislike to changing only rfcsr accessors and leaving others in the old way. And changing all accessors would be massive and error prone change, which I'm not prefer either. Arnd, could this be fixed by refactoring rt2800_bw_filter_calibration() function (which is enormous and definitely should be split into smaller subroutines) ? If not, I would accept this patch. Thanks Stanislaw
Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
* Simon Wunderlich [16.05.2017 12:24]: > * station A detects a Radar, and informs userspace > * userspace of station A will initiate a CSA, kernel will execute it (action > frame, beacons) > * station B picks up the CSA, and executes it as well > * station B also marks the channel as unavailable > * both station A and station B will send an event to userspace once the > channel switch is complete ah, I remember the slides from last battlemesh. The "problems" in userspace are: we must maintain a global list (so each node) which channel is the next best and we must time the final channel switch. IMHO the specs are saying, that we must switch within 30 secs after detecting the first radar-pattern. Also we must mark/show the new channel somehow for new/crashed/upcoming nodes. quite hard... bye, bastian
Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
Hi Basti, On Tuesday, May 16, 2017 11:44:04 AM CEST Bastian Bittorf wrote: > * Simon Wunderlich [16.05.2017 11:35]: > > This patchset adds DFS and CSA functionality: > thanks a lot. can you give a brief 'iw event' output when applied: > for a two-node mesh, where station A detects CSA and station B > should emit an event... The idea would be: * station A detects a Radar, and informs userspace * userspace of station A will initiate a CSA, kernel will execute it (action frame, beacons) * station B picks up the CSA, and executes it as well * station B also marks the channel as unavailable * both station A and station B will send an event to userspace once the channel switch is complete > > question: there is no userspace part for now, or maybe planned? I've got some patches for wpa_supplicant here, but they are still quite dirty ... > > bye, bastian - now it's time for battlemesh.org 8-) See you at battlemesh :) Cheers, Simon signature.asc Description: This is a digitally signed message part.
Re: [v2 10/11] rsi: Add new firmware loading method
On Fri, May 12, 2017 at 2:15 PM, Kalle Valo wrote: > Amitkumar Karwar writes: > >> From: Prameela Rani Garnepudi >> >> The older firmware loading method has been deprecated and not in use >> for any chipets. New method is introduced which works based on soft >> boot loader. In this method, complete RAM image and FLASH image are >> present in the flash. Before loading the functional firmware, host >> issues boot loader commands to verify whether firmware to load is >> different from the current functional firmware. If not, firmware >> upgrade progresses and boot loader will switch to the new functional >> firmware. >> >> Signed-off-by: Prameela Rani Garnepudi >> Signed-off-by: Amitkumar Karwar > > Please document in the commit log the new firmware filenames used by > this patch. > Sure. This has been taken care in updated version. Regards, Amitkumar
Re: [v2 07/11] rsi: Add usb multi-byte read operation
On Fri, May 12, 2017 at 12:05 AM, Kalle Valo wrote: > Amitkumar Karwar writes: > >> From: Prameela Rani Garnepudi >> >> USB multibyte read will be used in the new firmware loading method >> for RS9113 chipset. >> >> Signed-off-by: Prameela Rani Garnepudi >> Signed-off-by: Amitkumar Karwar > > [...] > >> +static int rsi_usb_read_register_multiple(struct rsi_hw *adapter, u32 addr, >> + u8 *data, u16 count) >> +{ >> + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; >> + u8 *buf; >> + u16 transfer; >> + int status; >> + >> + if (!addr) >> + return -EINVAL; >> + >> + buf = kzalloc(4096, GFP_KERNEL); >> + if (!buf) >> + return -ENOMEM; >> + >> + while (count) { >> + transfer = min_t(u16, count, 4096); > > A minor thing, no need to resend just because of this. But a define for > 4096 would be nice. > I have defined a macro for 4096 in v3 series. Regards, Amitkumar Karwar
Re: [v2 05/11] rsi: Remove unnecessary buffer allocation
On Fri, May 12, 2017 at 1:58 PM, Arend van Spriel wrote: > On 5/11/2017 8:28 PM, Kalle Valo wrote: >> >> Amitkumar Karwar writes: >> >>> From: Prameela Rani Garnepudi >>> >>> In functions usb read register and usb write register, dynamic allocation >>> of 4 bytes is used. This is removed as it is unncessary for local >>> variable >>> and for such small data. >>> >>> Signed-off-by: Prameela Rani Garnepudi >>> Signed-off-by: Amitkumar Karwar >>> --- >>> drivers/net/wireless/rsi/rsi_91x_usb.c | 18 -- >>> 1 file changed, 4 insertions(+), 14 deletions(-) >>> >>> diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c >>> b/drivers/net/wireless/rsi/rsi_91x_usb.c >>> index 73b01a8..8eb7407 100644 >>> --- a/drivers/net/wireless/rsi/rsi_91x_usb.c >>> +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c >>> @@ -157,12 +157,8 @@ static int rsi_usb_reg_read(struct usb_device >>> *usbdev, >>> u16 *value, >>> u16 len) >>> { >>> - u8 *buf; >>> - int status = -ENOMEM; >>> - >>> - buf = kmalloc(0x04, GFP_KERNEL); >>> - if (!buf) >>> - return status; >>> + u8 buf[4]; >>> + int status; >>> status = usb_control_msg(usbdev, >>> usb_rcvctrlpipe(usbdev, 0), >> >> >> Recently I got a patch to orinoco_usb which did exactly the opposite >> (unless I'm missing something): >> >> >> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?id=2f6ae79cb04bb7f9b4be3f1c32b6fda35bf976bc >> >> The documentation for usb_control_msg() does not mention anything if >> it's possible to use stack memory, but AFAIU it's not possible to use >> stack memory with DMA. Can anyone clarify? > > > After private message I sent to Kalle here my public response :-p > According to Greg this has been a USB core requirement for a long, long time > (see below). > Thanks Arend. I have dropped this patch in V3 series. Regards, Amitkumar Karwar
[v3 11/11] rsi: Remove old firmware loading method
From: Prameela Rani Garnepudi The older firmware loading method is not usable by any Redpine chipset. Hence removing that part of the code. Older firmware image with rsi_91x.fw name is deprecated Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Included the name of older firmware which won't be used anymore in commit description(Kalle Valo) --- drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 187 drivers/net/wireless/rsi/rsi_91x_usb.c | 6 +- drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 126 --- drivers/net/wireless/rsi/rsi_common.h | 3 +- drivers/net/wireless/rsi/rsi_sdio.h | 1 - drivers/net/wireless/rsi/rsi_usb.h | 3 - 6 files changed, 3 insertions(+), 323 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c index 225042f..df2a63b 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c @@ -60,171 +60,6 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word) } /** - * rsi_copy_to_card() - This function includes the actual funtionality of - * copying the TA firmware to the card.Basically this - * function includes opening the TA file,reading the - * TA file and writing their values in blocks of data. - * @common: Pointer to the driver private structure. - * @fw: Pointer to the firmware value to be written. - * @len: length of firmware file. - * @num_blocks: Number of blocks to be written to the card. - * - * Return: 0 on success and -1 on failure. - */ -static int rsi_copy_to_card(struct rsi_common *common, - const u8 *fw, - u32 len, - u16 num_blocks) -{ - struct rsi_hw *adapter = common->priv; - struct rsi_91x_sdiodev *dev = - (struct rsi_91x_sdiodev *)adapter->rsi_dev; - u32 indx, ii; - u16 block_size = dev->tx_blk_size; - u32 lsb_address; - __le32 data[] = { TA_HOLD_THREAD_VALUE, TA_SOFT_RST_CLR, - TA_PC_ZERO, TA_RELEASE_THREAD_VALUE }; - u32 address[] = { TA_HOLD_THREAD_REG, TA_SOFT_RESET_REG, - TA_TH0_PC_REG, TA_RELEASE_THREAD_REG }; - u32 base_address; - u16 msb_address; - - base_address = TA_LOAD_ADDRESS; - msb_address = base_address >> 16; - - for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) { - lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER); - if (rsi_sdio_write_register_multiple(adapter, -lsb_address, -(u8 *)(fw + indx), -block_size)) { - rsi_dbg(ERR_ZONE, - "%s: Unable to load %s blk\n", __func__, - FIRMWARE_RSI9113); - return -1; - } - rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii); - base_address += block_size; - if ((base_address >> 16) != msb_address) { - msb_address += 1; - if (rsi_sdio_master_access_msword(adapter, - msb_address)) { - rsi_dbg(ERR_ZONE, - "%s: Unable to set ms word reg\n", - __func__); - return -1; - } - } - } - - if (len % block_size) { - lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER); - if (rsi_sdio_write_register_multiple(adapter, -lsb_address, -(u8 *)(fw + indx), -len % block_size)) { - rsi_dbg(ERR_ZONE, - "%s: Unable to load f/w\n", __func__); - return -1; - } - } - rsi_dbg(INIT_ZONE, - "%s: Succesfully loaded TA instructions\n", __func__); - - if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) { - rsi_dbg(ERR_ZONE, - "%s: Unable to set ms word to common reg\n", - __func__); - return -1; - } - - for (ii = 0; ii < ARRAY_SIZE(data); ii++) { - /* Bringing TA out of reset */ - if (rsi_sdio_write_register_multiple(adapter, -(address[ii] | -RSI_SD_REQUEST_MASTER), -
[v3 09/11] rsi: Add new host interface operations
From: Prameela Rani Garnepudi Host interface opearation master_reg_read, master_reg_write and load_data_master_write are added. These functions are needed for the new firmware loading method. As part of this, the function master_access_msword is moved from rsi_91x_sdio_ops.c to rsi_91x_sdio.c. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Same as earlier --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 179 drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 3 +- drivers/net/wireless/rsi/rsi_91x_usb.c | 65 ++ drivers/net/wireless/rsi/rsi_main.h | 8 ++ drivers/net/wireless/rsi/rsi_sdio.h | 1 + 5 files changed, 254 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index bdbec8b..b397e2c 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -552,6 +552,182 @@ int rsi_sdio_write_register_multiple(struct rsi_hw *adapter, return status; } +static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter, + u32 base_address, + u32 instructions_sz, + u16 block_size, + u8 *ta_firmware) +{ + u32 num_blocks, offset, i; + u16 msb_address, lsb_address; + u8 temp_buf[block_size]; + int status; + + num_blocks = instructions_sz / block_size; + msb_address = base_address >> 16; + + rsi_dbg(INFO_ZONE, "ins_size: %d, num_blocks: %d\n", + instructions_sz, num_blocks); + + /* Loading DM ms word in the sdio slave */ + status = rsi_sdio_master_access_msword(adapter, msb_address); + if (status < 0) { + rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__); + return status; + } + + for (offset = 0, i = 0; i < num_blocks; i++, offset += block_size) { + memset(temp_buf, 0, block_size); + memcpy(temp_buf, ta_firmware + offset, block_size); + lsb_address = (u16)base_address; + status = rsi_sdio_write_register_multiple + (adapter, +lsb_address | RSI_SD_REQUEST_MASTER, +temp_buf, block_size); + if (status < 0) { + rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__); + return status; + } + rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, i); + base_address += block_size; + + if ((base_address >> 16) != msb_address) { + msb_address += 1; + + /* Loading DM ms word in the sdio slave */ + status = rsi_sdio_master_access_msword(adapter, + msb_address); + if (status < 0) { + rsi_dbg(ERR_ZONE, + "%s: Unable to set ms word reg\n", + __func__); + return status; + } + } + } + + if (instructions_sz % block_size) { + memset(temp_buf, 0, block_size); + memcpy(temp_buf, ta_firmware + offset, + instructions_sz % block_size); + lsb_address = (u16)base_address; + status = rsi_sdio_write_register_multiple + (adapter, +lsb_address | RSI_SD_REQUEST_MASTER, +temp_buf, +instructions_sz % block_size); + if (status < 0) + return status; + rsi_dbg(INFO_ZONE, + "Written Last Block in Address 0x%x Successfully\n", + offset | RSI_SD_REQUEST_MASTER); + } + return 0; +} + +#define FLASH_SIZE_ADDR 0x0416 +static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, + u32 *read_buf, u16 size) +{ + u32 addr_on_bus, *data; + u32 align[2] = {}; + u16 ms_addr; + int status; + + data = PTR_ALIGN(&align[0], 8); + + ms_addr = (addr >> 16); + status = rsi_sdio_master_access_msword(adapter, ms_addr); + if (status < 0) { + rsi_dbg(ERR_ZONE, + "%s: Unable to set ms word to common reg\n", + __func__); + return status; + } + addr &= 0x; + + addr_on_bus = (addr & 0xFF00); + if ((addr_on_bus == (FLASH_SI
[v3 07/11] rsi: Add usb multi-byte read operation
From: Prameela Rani Garnepudi USB multibyte read will be used in the new firmware loading method for RS9113 chipset. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Use RSI_USB_BUF_SIZE macro for 4096 --- drivers/net/wireless/rsi/rsi_91x_usb.c | 40 ++ 1 file changed, 40 insertions(+) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index a900a72..31f96f0 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -276,6 +276,46 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter) return status; } +static int rsi_usb_read_register_multiple(struct rsi_hw *adapter, u32 addr, + u8 *data, u16 count) +{ + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; + u8 *buf; + u16 transfer; + int status; + + if (!addr) + return -EINVAL; + + buf = kzalloc(RSI_USB_BUF_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + while (count) { + transfer = min_t(u16, count, RSI_USB_BUF_SIZE); + status = usb_control_msg(dev->usbdev, +usb_rcvctrlpipe(dev->usbdev, 0), +USB_VENDOR_REGISTER_READ, +RSI_USB_REQ_IN, +((addr & 0x) >> 16), +(addr & 0x), (void *)buf, +transfer, USB_CTRL_GET_TIMEOUT); + if (status < 0) { + rsi_dbg(ERR_ZONE, + "Reg read failed with error code :%d\n", +status); + kfree(buf); + return status; + } + memcpy(data, buf, transfer); + count -= transfer; + data += transfer; + addr += transfer; + } + kfree(buf); + return 0; +} + /** * rsi_usb_write_register_multiple() - This function writes multiple bytes of *information to multiple registers. -- 2.7.4
[v3 08/11] rsi: Add host interface operations as separate structure.
From: Prameela Rani Garnepudi Host interface operations are currently function pointers in rsi_hw structure. As more host interface operations are going to be introduced, separate structure is added for these for convenience. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Same as earlier --- drivers/net/wireless/rsi/rsi_91x_hal.c | 16 +++- drivers/net/wireless/rsi/rsi_91x_sdio.c | 11 +-- drivers/net/wireless/rsi/rsi_91x_usb.c | 9 - drivers/net/wireless/rsi/rsi_main.h | 18 -- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index 02920c9..8fbf904 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -100,9 +100,8 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) (skb->priority & 0xf) | (tx_params->sta_id << 8)); - status = adapter->host_intf_write_pkt(common->priv, - skb->data, - skb->len); + status = adapter->host_intf_ops->write_pkt(common->priv, skb->data, + skb->len); if (status) rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n", __func__); @@ -148,9 +147,9 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, } skb_push(skb, extnd_size); skb->data[extnd_size + 4] = extnd_size; - status = adapter->host_intf_write_pkt(common->priv, - (u8 *)skb->data, - skb->len); + status = adapter->host_intf_ops->write_pkt(common->priv, + (u8 *)skb->data, + skb->len); if (status) { rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__); @@ -203,9 +202,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, msg[7] |= cpu_to_le16(vap_id << 8); - status = adapter->host_intf_write_pkt(common->priv, - (u8 *)msg, - skb->len); + status = adapter->host_intf_ops->write_pkt(common->priv, (u8 *)msg, + skb->len); if (status) rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__); diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 39d94b3..bdbec8b 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -676,8 +676,6 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter, } sdio_release_host(pfunction); - adapter->host_intf_write_pkt = rsi_sdio_host_intf_write_pkt; - adapter->host_intf_read_pkt = rsi_sdio_host_intf_read_pkt; adapter->determine_event_timeout = rsi_sdio_determine_event_timeout; adapter->check_hw_queue_status = rsi_sdio_read_buffer_status_register; @@ -691,6 +689,13 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter, return status; } +static struct rsi_host_intf_ops sdio_host_intf_ops = { + .write_pkt = rsi_sdio_host_intf_write_pkt, + .read_pkt = rsi_sdio_host_intf_read_pkt, + .read_reg_multiple = rsi_sdio_read_register_multiple, + .write_reg_multiple = rsi_sdio_write_register_multiple, +}; + /** * rsi_probe() - This function is called by kernel when the driver provided * Vendor and device IDs are matched. All the initialization @@ -713,6 +718,8 @@ static int rsi_probe(struct sdio_func *pfunction, __func__); return 1; } + adapter->rsi_host_intf = RSI_HOST_INTF_SDIO; + adapter->host_intf_ops = &sdio_host_intf_ops; if (rsi_init_sdio_interface(adapter, pfunction)) { rsi_dbg(ERR_ZONE, "%s: Failed to init sdio interface\n", diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index 31f96f0..9000e09 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -392,6 +392,12 @@ static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter, len); } +static struct rsi_host_intf_ops usb_host_intf_ops = { + .write_pkt = rsi_usb_host_intf_write_pkt, + .read_reg_multiple = rsi_usb_read_register_multiple, + .write_reg_multiple = rsi_usb_write_register_multiple, +}; + /** *
[v3 10/11] rsi: Add new firmware loading method
From: Prameela Rani Garnepudi The older firmware loading method has been deprecated and not in use for any chipets. New method is introduced which works based on soft boot loader. In this method, complete RAM image and FLASH image are present in the flash. Before loading the functional firmware, host issues boot loader commands to verify whether firmware to load is different from the current functional firmware. If not, firmware upgrade progresses and boot loader will switch to the new functional firmware. "rs9113_wlan_qspi.rps" is the firmware filename used in this patch. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Included new firmware name in commit description(Kalle Valo) --- drivers/net/wireless/rsi/rsi_91x_hal.c | 527 drivers/net/wireless/rsi/rsi_91x_sdio.c | 11 +- drivers/net/wireless/rsi/rsi_91x_usb.c | 16 +- drivers/net/wireless/rsi/rsi_hal.h | 81 + drivers/net/wireless/rsi/rsi_main.h | 10 + 5 files changed, 635 insertions(+), 10 deletions(-) create mode 100644 drivers/net/wireless/rsi/rsi_hal.h diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index 8fbf904..d49dbaa 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -14,7 +14,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "rsi_mgmt.h" +#include "rsi_hal.h" +#include "rsi_sdio.h" + +/* FLASH Firmware */ +static struct ta_metadata metadata_flash_content[] = { + {"flash_content", 0x0001}, + {"rs9113_wlan_qspi.rps", 0x0001}, +}; /** * rsi_send_data_pkt() - This function sends the recieved data packet from @@ -211,3 +220,521 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, rsi_indicate_tx_status(common->priv, skb, status); return status; } + +static void bl_cmd_timeout(unsigned long priv) +{ + struct rsi_hw *adapter = (struct rsi_hw *)priv; + + adapter->blcmd_timer_expired = true; + del_timer(&adapter->bl_cmd_timer); +} + +static int bl_start_cmd_timer(struct rsi_hw *adapter, u32 timeout) +{ + init_timer(&adapter->bl_cmd_timer); + adapter->bl_cmd_timer.data = (unsigned long)adapter; + adapter->bl_cmd_timer.function = (void *)&bl_cmd_timeout; + adapter->bl_cmd_timer.expires = (msecs_to_jiffies(timeout) + jiffies); + + adapter->blcmd_timer_expired = false; + add_timer(&adapter->bl_cmd_timer); + + return 0; +} + +static int bl_stop_cmd_timer(struct rsi_hw *adapter) +{ + adapter->blcmd_timer_expired = false; + if (timer_pending(&adapter->bl_cmd_timer)) + del_timer(&adapter->bl_cmd_timer); + + return 0; +} + +static int bl_write_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, + u16 *cmd_resp) +{ + struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops; + u32 regin_val = 0, regout_val = 0; + u32 regin_input = 0; + u8 output = 0; + int status; + + regin_input = (REGIN_INPUT | adapter->priv->coex_mode); + + while (!adapter->blcmd_timer_expired) { + regin_val = 0; + status = hif_ops->master_reg_read(adapter, SWBL_REGIN, + ®in_val, 2); + if (status < 0) { + rsi_dbg(ERR_ZONE, + "%s: Command %0x REGIN reading failed..\n", + __func__, cmd); + return status; + } + mdelay(1); + if ((regin_val >> 12) != REGIN_VALID) + break; + } + if (adapter->blcmd_timer_expired) { + rsi_dbg(ERR_ZONE, + "%s: Command %0x REGIN reading timed out..\n", + __func__, cmd); + return -ETIMEDOUT; + } + + rsi_dbg(INFO_ZONE, + "Issuing write to Regin val:%0x sending cmd:%0x\n", + regin_val, (cmd | regin_input << 8)); + status = hif_ops->master_reg_write(adapter, SWBL_REGIN, + (cmd | regin_input << 8), 2); + if (status < 0) + return status; + mdelay(1); + + if (cmd == LOAD_HOSTED_FW || cmd == JUMP_TO_ZERO_PC) { + /* JUMP_TO_ZERO_PC doesn't expect +* any response. So return from here +*/ + return 0; + } + + while (!adapter->blcmd_timer_expired) { + regout_val = 0; + status = hif_ops->master_reg_read(adapter, SWBL_REGOUT, +®out_val, 2); + if (status < 0) { + rsi_dbg(ERR_ZONE, + "%s: Command %0x REGOUT reading failed..\n", + __func__, cmd); +
[v3 04/11] rsi: Changes in USB read and write operations
From: Prameela Rani Garnepudi USB read and write registers maximum size is limited 2^16. More than this size is not used in the driver. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Same as v2 03/11 --- drivers/net/wireless/rsi/rsi_91x_usb.c | 6 +++--- drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 9 + drivers/net/wireless/rsi/rsi_usb.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index be8487c..5f6c700 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -286,11 +286,11 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter) int rsi_usb_write_register_multiple(struct rsi_hw *adapter, u32 addr, u8 *data, - u32 count) + u16 count) { struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; u8 *buf; - u8 transfer; + u16 transfer; int status = 0; buf = kzalloc(RSI_USB_BUF_SIZE, GFP_KERNEL); @@ -298,7 +298,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter, return -ENOMEM; while (count) { - transfer = (u8)(min_t(u32, count, RSI_USB_BUF_SIZE)); + transfer = min_t(u16, count, RSI_USB_BUF_SIZE); memcpy(buf, data, transfer); status = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c index de49008..1c3e654 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c @@ -33,12 +33,12 @@ static int rsi_copy_to_card(struct rsi_common *common, const u8 *fw, u32 len, - u32 num_blocks) + u16 num_blocks) { struct rsi_hw *adapter = common->priv; struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; u32 indx, ii; - u32 block_size = dev->tx_blk_size; + u16 block_size = dev->tx_blk_size; u32 lsb_address; u32 base_address; @@ -134,9 +134,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common) struct rsi_hw *adapter = common->priv; struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; const struct firmware *fw_entry = NULL; - u32 block_size = dev->tx_blk_size; + u16 block_size = dev->tx_blk_size; const u8 *fw; - u32 num_blocks, len; + u16 num_blocks; + u32 len; int status = 0; status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device); diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h index 48c9211..d1e01bc 100644 --- a/drivers/net/wireless/rsi/rsi_usb.h +++ b/drivers/net/wireless/rsi/rsi_usb.h @@ -65,6 +65,6 @@ static inline int rsi_usb_event_timeout(struct rsi_hw *adapter) int rsi_usb_device_init(struct rsi_common *common); int rsi_usb_write_register_multiple(struct rsi_hw *adapter, u32 addr, - u8 *data, u32 count); + u8 *data, u16 count); void rsi_usb_rx_thread(struct rsi_common *common); #endif -- 2.7.4
[v3 03/11] rsi: define RSI_USB_BUF_SIZE macro
RSI_USB_BUF_SIZE macro is used instead of hardcoding a buffer size to 4096. Signed-off-by: Amitkumar Karwar --- v3: Newly added patch in v3 --- drivers/net/wireless/rsi/rsi_91x_usb.c | 4 ++-- drivers/net/wireless/rsi/rsi_usb.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index cc8deec..be8487c 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -293,12 +293,12 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter, u8 transfer; int status = 0; - buf = kzalloc(4096, GFP_KERNEL); + buf = kzalloc(RSI_USB_BUF_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; while (count) { - transfer = (u8)(min_t(u32, count, 4096)); + transfer = (u8)(min_t(u32, count, RSI_USB_BUF_SIZE)); memcpy(buf, data, transfer); status = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h index ebea0c4..48c9211 100644 --- a/drivers/net/wireless/rsi/rsi_usb.h +++ b/drivers/net/wireless/rsi/rsi_usb.h @@ -35,6 +35,8 @@ #define MGMT_EP 1 #define DATA_EP 2 +#define RSI_USB_BUF_SIZE4096 + struct rsi_91x_usbdev { struct rsi_thread rx_thread; u8 endpoint; -- 2.7.4
[v3 06/11] rsi: Handle usb multi-byte write failure case properly
From: Prameela Rani Garnepudi In function usb_write_register_multiple, if any intermediate block transfer is failed, further operations should be terminated. 'else' is removed, as there is no significance for it after return. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Same as earlier. Below patch has been dropped in this series(Kalle Valo/Arend van Spriel) [v2 05/11] rsi: Remove unnecessary buffer allocation --- drivers/net/wireless/rsi/rsi_91x_usb.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index 9e1359a..a900a72 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -316,11 +316,12 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter, rsi_dbg(ERR_ZONE, "Reg write failed with error code :%d\n", status); - } else { - count -= transfer; - data += transfer; - addr += transfer; + kfree(buf); + return status; } + count -= transfer; + data += transfer; + addr += transfer; } kfree(buf); -- 2.7.4
[v3 05/11] rsi: use macros in USB specific code
From: Prameela Rani Garnepudi For USB vendor read and write operations new macros added to avoid redundant usage of long or'ed macros. Also for timeouts standard USB macros are used. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Same as v2 04/11 --- drivers/net/wireless/rsi/rsi_91x_usb.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index 5f6c700..9e1359a 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -141,6 +141,9 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface, return 0; } +#define RSI_USB_REQ_OUT(USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE) +#define RSI_USB_REQ_IN (USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE) + /* rsi_usb_reg_read() - This function reads data from given register address. * @usbdev: Pointer to the usb_device structure. * @reg: Address of the register to be read. @@ -164,11 +167,11 @@ static int rsi_usb_reg_read(struct usb_device *usbdev, status = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), USB_VENDOR_REGISTER_READ, -USB_TYPE_VENDOR, +RSI_USB_REQ_IN, ((reg & 0x) >> 16), (reg & 0x), (void *)buf, len, -HZ * 5); +USB_CTRL_GET_TIMEOUT); *value = (buf[0] | (buf[1] << 8)); if (status < 0) { @@ -211,12 +214,12 @@ static int rsi_usb_reg_write(struct usb_device *usbdev, status = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), USB_VENDOR_REGISTER_WRITE, -USB_TYPE_VENDOR, +RSI_USB_REQ_OUT, ((reg & 0x) >> 16), (reg & 0x), (void *)usb_reg_buf, len, -HZ * 5); +USB_CTRL_SET_TIMEOUT); if (status < 0) { rsi_dbg(ERR_ZONE, "%s: Reg write failed with error code :%d\n", @@ -303,12 +306,12 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter, status = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), USB_VENDOR_REGISTER_WRITE, -USB_TYPE_VENDOR, +RSI_USB_REQ_OUT, ((addr & 0x) >> 16), (addr & 0x), (void *)buf, transfer, -HZ * 5); +USB_CTRL_SET_TIMEOUT); if (status < 0) { rsi_dbg(ERR_ZONE, "Reg write failed with error code :%d\n", -- 2.7.4
[v3 02/11] rsi: Changes to sdio reads and writes
From: Prameela Rani Garnepudi SDIO read or write maximum size is limited to 2^16. This is done to make the host interface operations common for SDIO and USB. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Same as earlier --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 10 +- drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 8 drivers/net/wireless/rsi/rsi_sdio.h | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 8428858..39d94b3 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -487,8 +487,8 @@ void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit) */ static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter, u32 addr, - u32 count, - u8 *data) + u8 *data, + u16 count) { struct rsi_91x_sdiodev *dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; @@ -518,7 +518,7 @@ static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter, int rsi_sdio_write_register_multiple(struct rsi_hw *adapter, u32 addr, u8 *data, -u32 count) +u16 count) { struct rsi_91x_sdiodev *dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; @@ -614,8 +614,8 @@ int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, status = rsi_sdio_read_register_multiple(adapter, length, -length, /*num of bytes*/ -(u8 *)pkt); +(u8 *)pkt, +length); /*num of bytes*/ if (status) rsi_dbg(ERR_ZONE, "%s: Failed to read frame: %d\n", __func__, diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c index 40d7231..7c9cf01 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c @@ -75,13 +75,13 @@ static int rsi_sdio_master_access_msword(struct rsi_hw *adapter, static int rsi_copy_to_card(struct rsi_common *common, const u8 *fw, u32 len, - u32 num_blocks) + u16 num_blocks) { struct rsi_hw *adapter = common->priv; struct rsi_91x_sdiodev *dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; u32 indx, ii; - u32 block_size = dev->tx_blk_size; + u16 block_size = dev->tx_blk_size; u32 lsb_address; __le32 data[] = { TA_HOLD_THREAD_VALUE, TA_SOFT_RST_CLR, TA_PC_ZERO, TA_RELEASE_THREAD_VALUE }; @@ -171,10 +171,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common) struct rsi_91x_sdiodev *dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; u32 len; - u32 num_blocks; + u16 num_blocks; const u8 *fw; const struct firmware *fw_entry = NULL; - u32 block_size = dev->tx_blk_size; + u16 block_size = dev->tx_blk_size; int status = 0; u32 base_address; u16 msb_address; diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h index c7e8f2b..a82bc4c 100644 --- a/drivers/net/wireless/rsi/rsi_sdio.h +++ b/drivers/net/wireless/rsi/rsi_sdio.h @@ -110,7 +110,7 @@ struct rsi_91x_sdiodev { u8 sdio_clock_speed; u32 cardcapability; u8 prev_desc[16]; - u32 tx_blk_size; + u16 tx_blk_size; u8 write_fail; }; @@ -122,7 +122,7 @@ int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, u8 *pkt, u32 length); int rsi_sdio_write_register(struct rsi_hw *adapter, u8 function, u32 addr, u8 *data); int rsi_sdio_write_register_multiple(struct rsi_hw *adapter, u32 addr, -u8 *data, u32 count); +u8 *data, u16 count); void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit); int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter); int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num); -- 2.7.4
[v3 01/11] rsi: Rename file rsi_91x_pkt.c to rsi_91x_hal.c
From: Prameela Rani Garnepudi The file rsi_91x_hal.c is going to contain device specific code i.e new firmware loading method for RS9113 chipset. As the file rsi_91x_pkt.c contains code to prepare device specific descriptors for transmit packet, this file is renamed to rsi_91x_hal.c which is more relevant as per it's functionality. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Amitkumar Karwar --- v3: Same as earlier --- drivers/net/wireless/rsi/Makefile | 2 +- drivers/net/wireless/rsi/{rsi_91x_pkt.c => rsi_91x_hal.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/net/wireless/rsi/{rsi_91x_pkt.c => rsi_91x_hal.c} (100%) diff --git a/drivers/net/wireless/rsi/Makefile b/drivers/net/wireless/rsi/Makefile index 25828b6..a475c81 100644 --- a/drivers/net/wireless/rsi/Makefile +++ b/drivers/net/wireless/rsi/Makefile @@ -2,7 +2,7 @@ rsi_91x-y += rsi_91x_main.o rsi_91x-y += rsi_91x_core.o rsi_91x-y += rsi_91x_mac80211.o rsi_91x-y += rsi_91x_mgmt.o -rsi_91x-y += rsi_91x_pkt.o +rsi_91x-y += rsi_91x_hal.o rsi_91x-$(CONFIG_RSI_DEBUGFS) += rsi_91x_debugfs.o rsi_usb-y += rsi_91x_usb.o rsi_91x_usb_ops.o diff --git a/drivers/net/wireless/rsi/rsi_91x_pkt.c b/drivers/net/wireless/rsi/rsi_91x_hal.c similarity index 100% rename from drivers/net/wireless/rsi/rsi_91x_pkt.c rename to drivers/net/wireless/rsi/rsi_91x_hal.c -- 2.7.4
[v3 00/11] Firmware loading changes
This patch series includes firmware loading enhancements for Redpine 9113 chipset. The older method is not being used by any Redpine chipset. There is no firmware image submitted to upstream yet. We will submit 9113's firmware image once these changes are accepted. Amitkumar Karwar (1): rsi: define RSI_USB_BUF_SIZE macro Prameela Rani Garnepudi (10): rsi: Rename file rsi_91x_pkt.c to rsi_91x_hal.c rsi: Changes to sdio reads and writes rsi: Changes in USB read and write operations rsi: use macros in USB specific code rsi: Handle usb multi-byte write failure case properly rsi: Add usb multi-byte read operation rsi: Add host interface operations as separate structure. rsi: Add new host interface operations rsi: Add new firmware loading method rsi: Remove old firmware loading method drivers/net/wireless/rsi/Makefile | 2 +- drivers/net/wireless/rsi/rsi_91x_hal.c | 740 drivers/net/wireless/rsi/rsi_91x_pkt.c | 215 drivers/net/wireless/rsi/rsi_91x_sdio.c | 211 +++- drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 190 +-- drivers/net/wireless/rsi/rsi_91x_usb.c | 166 ++- drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 125 - drivers/net/wireless/rsi/rsi_common.h | 3 +- drivers/net/wireless/rsi/rsi_hal.h | 81 +++ drivers/net/wireless/rsi/rsi_main.h | 36 +- drivers/net/wireless/rsi/rsi_sdio.h | 6 +- drivers/net/wireless/rsi/rsi_usb.h | 5 +- 12 files changed, 1205 insertions(+), 575 deletions(-) create mode 100644 drivers/net/wireless/rsi/rsi_91x_hal.c delete mode 100644 drivers/net/wireless/rsi/rsi_91x_pkt.c create mode 100644 drivers/net/wireless/rsi/rsi_hal.h -- 2.7.4
Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
* Simon Wunderlich [16.05.2017 11:35]: > This patchset adds DFS and CSA functionality: thanks a lot. can you give a brief 'iw event' output when applied: for a two-node mesh, where station A detects CSA and station B should emit an event... question: there is no userspace part for now, or maybe planned? bye, bastian - now it's time for battlemesh.org 8-)
Re: [PATCH v2 0/8] NFC: fix device allocation and nfcmrvl crashes
Hi Samuel, On Thu, Apr 27, 2017 at 12:42:38AM +0200, Samuel Ortiz wrote: > Hi Johan, > > On Thu, Mar 30, 2017 at 12:15:34PM +0200, Johan Hovold wrote: > > This started out with the observation that the nfcmrvl_uart driver > > unconditionally dereferenced the tty class device despite the fact that > > not every tty has an associated struct device (Unix98 ptys). Some > > further changes were needed in the common nfcmrvl code to fully address > > this, some of which also incidentally fixed a few related bugs (e.g. > > resource leaks in error paths). > > > > While fixing this I stumbled over a regression in NFC core that lead to > > broken registration error paths and misnamed workqueues. > > > > Note that this has only been tested by configuring the n_hci line > > discipline for different ttys without any actual NFC hardware connected. > > > > Johan > > > > > > Changes in v2 > > - fix typo in commit message (1/8) > > - release reset gpio in error paths (3/8) > > - fix description of patch impact (3/8) > > - allow gpio 0 to be used for reset signalling (8/8, new) > > > > > > Johan Hovold (8): > > NFC: fix broken device allocation > > NFC: nfcmrvl_uart: add missing tty-device sanity check > > NFC: nfcmrvl: do not use device-managed resources > > NFC: nfcmrvl: use nfc-device for firmware download > > NFC: nfcmrvl: fix firmware-management initialisation > > NFC: nfcmrvl_uart: fix device-node leak during probe > > NFC: nfcmrvl_usb: use interface as phy device > > NFC: nfcmrvl: allow gpio 0 for reset signalling > Applied, thanks. These never made it into net-next and 4.12-rc1, so will you be sending them on as fixes for 4.12-rc instead? Thanks, Johan
[PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
This patchset adds DFS and CSA functionality: * Mesh CSA is handled similary to IBSS, that means CSA will mark channels as unusable, and require userspace to handle actual radar signals * Add VHT processing for CSA in mesh mode, and some small cleanups We have been working on this feature set for quite some time internally, and I believe it is time to propose it for inclusion. I'll handle any change requests to this patchset. :) Cheers, Simon Benjamin Berg (4): mac80211: Mark channel as unusable if a regulatory MESH CSA is received wireless: Only join DFS channels in mesh mode if userspace flags support wireless: Require HANDLE_DFS flag to switch channel for non-AP mode mac80211: Allow following CSA to DFS channels if userspace handles it Simon Wunderlich (3): mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons mac80211: enable VHT for mesh channel processing mac80211: mark as action frame when parsing IEs of CSA action frames include/net/cfg80211.h | 4 +++ net/mac80211/cfg.c | 1 + net/mac80211/ieee80211_i.h | 5 +++ net/mac80211/mesh.c| 89 ++ net/mac80211/spectmgmt.c | 5 +++ net/mac80211/util.c| 40 + net/wireless/mesh.c| 8 + net/wireless/nl80211.c | 17 - 8 files changed, 161 insertions(+), 8 deletions(-) -- 2.11.0
[PATCH 6/7] mac80211: enable VHT for mesh channel processing
Signed-off-by: Simon Wunderlich --- net/mac80211/mesh.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 7c6593c0d453..a57af5df7ee4 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -991,12 +991,14 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, if (!sband) return false; - sta_flags = IEEE80211_STA_DISABLE_VHT; + sta_flags = 0; switch (sdata->vif.bss_conf.chandef.width) { case NL80211_CHAN_WIDTH_20_NOHT: sta_flags |= IEEE80211_STA_DISABLE_HT; case NL80211_CHAN_WIDTH_20: sta_flags |= IEEE80211_STA_DISABLE_40MHZ; + case NL80211_CHAN_WIDTH_40: + sta_flags |= IEEE80211_STA_DISABLE_VHT; break; default: break; -- 2.11.0
[PATCH 2/7] wireless: Only join DFS channels in mesh mode if userspace flags support
From: Benjamin Berg When joining a mesh network it is not guaranteed that userspace has a daemon listening for radar events. This is however required for channels requiring DFS. To flag that userspace will handle radar events, it needs to set NL80211_ATTR_HANDLE_DFS. This matches the current mechanism used for IBSS mode. Signed-off-by: Benjamin Berg Signed-off-by: Simon Wunderlich --- include/net/cfg80211.h | 4 net/wireless/mesh.c| 8 net/wireless/nl80211.c | 3 +++ 3 files changed, 15 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b083e6cbae8c..fa25fbb67cb6 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1441,6 +1441,9 @@ struct mesh_config { * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a] * @basic_rates: basic rates to use when creating the mesh * @beacon_rate: bitrate to be used for beacons + * @userspace_handles_dfs: whether user space controls DFS operation, i.e. + * changes the channel when a radar is detected. This is required + * to operate on DFS channels. * * These parameters are fixed when the mesh is created. */ @@ -1462,6 +1465,7 @@ struct mesh_setup { int mcast_rate[NUM_NL80211_BANDS]; u32 basic_rates; struct cfg80211_bitrate_mask beacon_rate; + bool userspace_handles_dfs; }; /** diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index ec0b1c20ac99..421a6b80ec62 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -174,6 +174,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, scan_width); } + err = cfg80211_chandef_dfs_required(&rdev->wiphy, + &setup->chandef, + NL80211_IFTYPE_MESH_POINT); + if (err < 0) + return err; + if (err > 0 && !setup->userspace_handles_dfs) + return -EINVAL; + if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef, NL80211_IFTYPE_MESH_POINT)) return -EINVAL; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c3bc9da30cff..d47e55e3f445 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -9962,6 +9962,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) return err; } + setup.userspace_handles_dfs = + nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]); + return cfg80211_join_mesh(rdev, dev, &setup, &cfg); } -- 2.11.0
[PATCH 7/7] mac80211: mark as action frame when parsing IEs of CSA action frames
Signed-off-by: Simon Wunderlich --- net/mac80211/mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index a57af5df7ee4..ab07974cdcf4 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1308,7 +1308,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, pos = mgmt->u.action.u.chan_switch.variable; baselen = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch.variable); - ieee802_11_parse_elems(pos, len - baselen, false, &elems); + ieee802_11_parse_elems(pos, len - baselen, true, &elems); ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; if (!--ifmsh->chsw_ttl) -- 2.11.0
[PATCH 4/7] mac80211: Allow following CSA to DFS channels if userspace handles it
From: Benjamin Berg If userspace has flagged support for DFS earlier, then we can follow CSA to DFS channels. So instead of rejecting the switch, allow it to happen if the flag has been set during mesh setup. Signed-off-by: Benjamin Berg Signed-off-by: Simon Wunderlich --- net/mac80211/cfg.c | 1 + net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/mesh.c| 15 --- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 6c2e6060cd54..6980a936a437 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1874,6 +1874,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, ifmsh->user_mpm = setup->user_mpm; ifmsh->mesh_auth_id = setup->auth_id; ifmsh->security = IEEE80211_MESH_SEC_NONE; + ifmsh->userspace_handles_dfs = setup->userspace_handles_dfs; if (setup->is_authenticated) ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; if (setup->is_secure) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 60bed6c69801..c960e4999380 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -643,6 +643,8 @@ struct ieee80211_if_mesh { unsigned long wrkq_flags; unsigned long mbss_changed; + bool userspace_handles_dfs; + u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; size_t mesh_id_len; /* Active Path Selection Protocol Identifier */ diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 3702e3d9141d..4807a5d77572 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -979,7 +979,9 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, params.count = csa_ie.count; if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, ¶ms.chandef, -IEEE80211_CHAN_DISABLED)) { +IEEE80211_CHAN_DISABLED) || + !cfg80211_reg_can_beacon(sdata->local->hw.wiphy, ¶ms.chandef, +NL80211_IFTYPE_MESH_POINT)) { sdata_info(sdata, "mesh STA %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), aborting\n", sdata->vif.addr, @@ -995,9 +997,16 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, NL80211_IFTYPE_MESH_POINT); if (err < 0) return false; - if (err > 0) - /* TODO: DFS not (yet) supported */ + if (err > 0 && !ifmsh->userspace_handles_dfs) { + sdata_info(sdata, + "mesh STA %pM switches to channel requiring DFS (%d MHz, width:%d, CF1/2: %d/%d MHz), aborting\n", + sdata->vif.addr, + params.chandef.chan->center_freq, + params.chandef.width, + params.chandef.center_freq1, + params.chandef.center_freq2); return false; + } params.radar_required = err; -- 2.11.0
[PATCH 3/7] wireless: Require HANDLE_DFS flag to switch channel for non-AP mode
From: Benjamin Berg In the case the channel should be switched to one requiring DFS we need to make sure that userspace will handle radar events when they happen. For AP mode this is assumed to be the case, as a manager like hostapd is required. However IBSS and MESH modes can work without further userspace assistance, so refuse to use DFS channels unless userspace vouches that it handles DFS. NOTE: Userspace should have already flagged support earlier during mesh or IBSS setup. However, this information is not readily accessible currently. Signed-off-by: Benjamin Berg [sw: style cleanups] Signed-off-by: Simon Wunderlich --- net/wireless/nl80211.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d47e55e3f445..9eb59196a378 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7501,6 +7501,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1]; int err; bool need_new_beacon = false; + bool need_handle_dfs_flag = true; int len, i; u32 cs_count; @@ -7512,6 +7513,12 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: need_new_beacon = true; + /* For all modes except AP the handle_dfs flag needs to be +* supplied to tell the kernel that userspace will handle radar +* events when they happen. Otherwise a switch to a channel +* requiring DFS will be rejected. +*/ + need_handle_dfs_flag = false; /* useless if AP is not running */ if (!wdev->beacon_interval) @@ -7634,8 +7641,13 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) if (err < 0) return err; - if (err > 0) + if (err > 0) { params.radar_required = true; + if (need_handle_dfs_flag && + !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) { + return -EINVAL; + } + } if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) params.block_tx = true; -- 2.11.0
[PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons
To support HT and VHT CSA, beacons and action frames must include the corresponding IEs. Signed-off-by: Simon Wunderlich --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/mesh.c| 47 -- net/mac80211/util.c| 40 +++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c960e4999380..e3a0b295c5ce 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2066,6 +2066,8 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, const struct cfg80211_chan_def *chandef, u16 prot_mode, bool rifs_mode); +u8 *ieee80211_ie_build_wide_bw_cs(u8 *pos, + const struct cfg80211_chan_def *chandef); u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, u32 cap); u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 4807a5d77572..7c6593c0d453 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -690,6 +690,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) 2 + sizeof(struct ieee80211_channel_sw_ie) + /* Mesh Channel Switch Parameters */ 2 + sizeof(struct ieee80211_mesh_chansw_params_ie) + + 2 + 2 + sizeof(struct ieee80211_wide_bw_chansw_ie) + + 2 + sizeof(struct ieee80211_sec_chan_offs_ie) + 2 + 8 + /* supported rates */ 2 + 3; /* DS params */ tail_len = 2 + (IEEE80211_MAX_SUPP_RATES - 8) + @@ -736,8 +738,27 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) rcu_read_lock(); csa = rcu_dereference(ifmsh->csa); if (csa) { - pos = skb_put(skb, 13); - memset(pos, 0, 13); + bool have_secondary_chan_offset = false; + bool have_wide_bandwidth_cs = false; + int ie_len = 2 + sizeof(struct ieee80211_channel_sw_ie) + +2 + sizeof(struct ieee80211_mesh_chansw_params_ie); + + switch (csa->settings.chandef.width) { + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + have_wide_bandwidth_cs = true; + ie_len += 2 + 2 + + sizeof(struct ieee80211_wide_bw_chansw_ie); + break; + case NL80211_CHAN_WIDTH_40: + have_secondary_chan_offset = true; + ie_len += 2 + sizeof(struct ieee80211_sec_chan_offs_ie); + default: + break; + } + pos = skb_put(skb, ie_len); + memset(pos, 0, ie_len); *pos++ = WLAN_EID_CHANNEL_SWITCH; *pos++ = 3; *pos++ = 0x0; @@ -760,6 +781,28 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) pos += 2; put_unaligned_le16(ifmsh->pre_value, pos); pos += 2; + + if (have_secondary_chan_offset) { + enum nl80211_channel_type ct; + + *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */ + *pos++ = 1; /* len */ + ct = cfg80211_get_chandef_type(&csa->settings.chandef); + if (ct == NL80211_CHAN_HT40PLUS) + *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + else + *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW; + } + + if (have_wide_bandwidth_cs) { + struct cfg80211_chan_def *chandef; + + *pos++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER; /* EID */ + *pos++ = 5; /* len */ + /* put sub IE */ + chandef = &csa->settings.chandef; + pos = ieee80211_ie_build_wide_bw_cs(pos, chandef); + } } rcu_read_unlock(); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ac9ac6c35594..d2e885cbfdf8 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2414,6 +2414,37 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, return pos + sizeof(struct ieee80211_ht_operation); } +u8 *ieee80211_ie_build_wide_bw_cs(u8 *pos, + const struct cfg80211_chan_def *chandef) +{ + *pos++ = WLAN_EID_WIDE_BW_CHA
[PATCH 1/7] mac80211: Mark channel as unusable if a regulatory MESH CSA is received
From: Benjamin Berg In the Mesh Channel Switch Parameters (8.4.2.105) the reason is specified to WLAN_REASON_MESH_CHAN_REGULATORY in the case that a regulatory limitation was the cause for the switch. This means another station detected a radar event. Mark the channel as unusable if this happens. Signed-off-by: Benjamin Berg [sw: style cleanup, rebase] Signed-off-by: Simon Wunderlich --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/mesh.c| 21 + net/mac80211/spectmgmt.c | 5 + 3 files changed, 27 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f8f6c148f554..60bed6c69801 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1440,6 +1440,7 @@ struct ieee80211_csa_ie { u8 count; u8 ttl; u16 pre_value; + u16 reason_code; }; /* Parsed Information Elements */ diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 737e1f082b0d..3702e3d9141d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -916,6 +916,21 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) ieee80211_configure_filter(local); } +static void ieee80211_mesh_csa_mark_radar(struct ieee80211_sub_if_data *sdata) +{ + int err; + + /* if the current channel is a DFS channel, mark the channel as +* unavailable. +*/ + err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, + &sdata->vif.bss_conf.chandef, + NL80211_IFTYPE_MESH_POINT); + if (err > 0) + cfg80211_radar_event(sdata->local->hw.wiphy, +&sdata->vif.bss_conf.chandef, GFP_ATOMIC); +} + static bool ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems *elems, bool beacon) @@ -954,6 +969,12 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, if (err) return false; + /* Mark the channel unavailable if the reason for the switch is +* regulatory. +*/ + if (csa_ie.reason_code == WLAN_REASON_MESH_CHAN_REGULATORY) + ieee80211_mesh_csa_mark_radar(sdata); + params.chandef = csa_ie.chandef; params.count = csa_ie.count; diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 0782e486fe89..d2ea0017c79d 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c @@ -76,6 +76,11 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; csa_ie->pre_value = le16_to_cpu( elems->mesh_chansw_params_ie->mesh_pre_value); + + if (elems->mesh_chansw_params_ie->mesh_flags & + WLAN_EID_CHAN_SWITCH_PARAM_REASON) + csa_ie->reason_code = le16_to_cpu( + elems->mesh_chansw_params_ie->mesh_reason); } new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); -- 2.11.0
Re: [PATCH 2/6] wl1251: Use request_firmware_prefer_user() for loading NVS calibration data
On 16-5-2017 1:13, Luis R. Rodriguez wrote: > On Fri, May 12, 2017 at 11:02:26PM +0200, Arend Van Spriel wrote: >> try again.. replacing email address from Michał >> On 12-5-2017 22:55, Arend Van Spriel wrote: >>> Let me explain the idea to refresh your memory (and mine). It started >>> when we were working on adding driver support for OpenWrt in brcmfmac. >>> The driver requests for firmware calibration data, but on routers it is >>> stored in flash. So after failing on the firmware request we now call a >>> platform specific API. That was my itch, but it was not bad enough to go >>> and scratch. Now for N900 case there is a similar scenario alhtough it >>> has additional requirement to go to user-space due to need to use a >>> proprietary library to obtain the NVS calibration data. My thought: Why >>> should firmware_class care? > > Agreed. > >>> So the idea is that firmware_class provides >>> a registry for modules that can produce a certain firmware "file". Those >>> modules can do whatever is needed. If they need to use umh so be it. >>> They would only register themselves with firmware_class on platforms >>> that need them. It would basically be replacing the fallback mechanism >>> and only be effective on certain platforms. > > Sure, so it sounds like the work that Daniel Wagner and Tom Gundersen worked > [0] on which provides a firmwared with two modes: best-effort, and final-mode, > would address what you are looking for but without requiring any upstream > changes, *and* it also helps solve the rootfs race remote-proc folks had > concerns over. > > The other added gain over this solution is if folks need their own proprietary > concoction they can just fork firmwared and have that do whatever it needs > for the specific device on the specific rootfs. That is, firmwared can be the > upstream solution if folks need it, but if folks need something custom they > can > just mimic the implementation: best-effort, and and final-mode. > > Yet another added gain over this solution we can do *not* support the > custom fallback mechanism as its not needed, the udev event should suffice > to let userspace do what it needs. > > Lastly, if we did not want to deal with timeouts for the way the driver data > API implements it I think we might be able to do away with them for for async > requests if we assume there will be a daemon that spawns in final-mode > eventually, > and since it *knows* when the rootfs is ready it should be able to do a final > lookup, if it returns -ENOENT; then indeed we know we can give up. Now, > perhaps > how and if we want to deal with timeouts when using the driver data API for > the fallback mechanism is worth considering given it does not have a fallback > mechanism support yet. If we *add* them it would seem this would also put an > implicit race against userspace finishing initialization and running firmwared > in final-mode. Just to be clear. When you are saying "rootfs" in this story, you mean any (mounted) file-system which may hold the firmware. At least that was one of the arguments. In kernel space we can not know how the system is setup in terms of mount points, let alone on which mounted file-system the firmware resides. > Johannes, do you recall the corner cases we spoke about regarding timeouts? > Does this match what we spoke about? > >>> Let me know if this idea is still of interest and I will rebase what I >>> have for an RFC round. > > Since no upstream delta is needed for firmwared I'd like to first encourage > evaluating the above. While distributions don't carry it yet that may be seen > as > an issue but since what we are looking for are corner cases, only folks > needing > to deploy a specific solution would need it or a custom proprietary solution. Ok. I will go try and run firmwared in OpenWrt on a router platform. Have to steal one from a colleague :-p Will study firmwared. > [0] https://github.com/teg/firmwared.git > > PS. > > Note that firmware signing will require an additional file, the detached > signature. The driver data API does not currently support the fallback > mechanism so we would not have to worry about that yet but once we add > fallback support we'd need to consider this. Do you have references to the firmware signing design. Is the idea to have one signature and all "firmware files" need to be signed with it? Thanks, Arend
MAC80211 not able to receive probe response and beacon packets
I am writing a linux wlan driver based on MAC80211 to receive and send the frames on AXI DMA. I am implementing this on Zynq(ARM) based board, lower MAC has been implemented on FPGA. I am able to receive probe requests, beacons, probe responses and data packets till the driver. But only probe request packets are getting through towards MAC80211 by ieee80211_rx_irqsafe(hw, skb) API. By printing these packets in the driver itself i am able to verify that these beacon and probe response packets are correct, but MAC80211 is not showing any kind of prints for these packets. But it is transmitting ProbeResp packets for ProbeRequest packets, that means it is able to receive Probe Requests correctly. Can anybody please suggest where can be the issue? -- Amritpreet Singh