Compare commits

..

11 Commits

Author SHA1 Message Date
test0r d95453c98e bes2600: take pending_record_lock with _bh() to fix SOFTIRQ-safe → -unsafe inversion (besser#18)
PROVE_LOCKING reports:

  WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
  kworker/u16:1 is trying to acquire:
    &hw_priv->tx_loop.pending_record_lock at bes2600_queue_clear+0x80
  and this task is already holding:
    &queue->lock at bes2600_queue_clear+0x60

  which would create a new lock dependency:
    (&queue->lock){+.-.}   -> (&hw_priv->tx_loop.pending_record_lock){+.+.}

  but this new dependency connects a SOFTIRQ-irq-safe lock:
    (&queue->lock){+.-.}
  ... which became SOFTIRQ-irq-safe at:
    bes2600_tx -> ieee80211_handle_wake_tx_queue -> tasklet_action
  to a SOFTIRQ-irq-unsafe lock:
    (&hw_priv->tx_loop.pending_record_lock){+.+.}
  ... which became SOFTIRQ-irq-unsafe at:
    bes2600_queue_get_skb -> bes2600_join_work -> process_one_work

queue->lock is taken consistently with spin_lock_bh() at 22 sites;
the nested acquisition of pending_record_lock at queue.c:289 (inside
the outer queue->lock_bh held at line 285) had it implicitly BH-safe
via the outer scope. But pending_record_lock is ALSO taken from
non-BH-disabled contexts:

  bes2600_queue_get_skb  (queue.c:832)  — process context via
    bes2600_join_work (workqueue), no outer queue->lock held
  bes2600_tx_loop_item_pending_check (tx_loop.c:112)
                                     — TX-loop context, no outer
                                     queue->lock held

When CPU0 holds pending_record_lock from one of those non-BH paths
and a softirq fires that wants queue->lock, and CPU1 in softirq has
queue->lock and is about to acquire pending_record_lock — classic AB-BA
SOFTIRQ deadlock.

The fix is the conservative one: take pending_record_lock with _bh()
at every site that's not already inside a queue->lock_bh-held scope.
That makes the lock consistently SOFTIRQ-safe, eliminating the
inversion. queue.c:289/295 stays as plain spin_lock because BH is
already disabled by the outer queue->lock_bh acquired at queue.c:285.

Five sites converted:
  bes2600/queue.c:832 -- spin_lock      -> spin_lock_bh
  bes2600/queue.c:839 -- spin_unlock    -> spin_unlock_bh
  bes2600/queue.c:844 -- spin_unlock    -> spin_unlock_bh
  bes2600/tx_loop.c:112 -- spin_lock    -> spin_lock_bh
  bes2600/tx_loop.c:114 -- spin_unlock  -> spin_unlock_bh

Contract:
  - Documentation/locking/locktypes.rst spelling: spin_lock_bh() is
    the canonical way to make a non-IRQ spinlock safe against
    softirq preemption that might re-enter the same lock.
  - Same shape as queue->lock in this driver and as is_drv->lock
    in the cw1200 ancestor.

Closes: besser#18
Fixes: <bes2600 base import>
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
2026-05-18 16:58:49 +02:00
test0r 8cd10f487c bes2600: scan-filter-5ghz: allow targeted single-channel scans (besser#1 follow-up)
The original Patch I refused EVERY 5 GHz scan request unconditionally
(req->n_channels > 0 && band == NL80211_BAND_5GHZ).  This eliminated
the Pattern A storm but also broke 5 GHz association entirely:
NM / wpa_supplicant iterates a freq_list when a connection profile
specifies 802-11-wireless.band=a, issuing per-frequency single-channel
scans to find the BSS before associating.  Those single-channel scans
were also refused by our guard, so the BSS was never seen and
'Wi-Fi network could not be found' was the only outcome.

Tighten the guard: refuse only multi-channel 5 GHz scans (n_channels
> 1), which is the per-band-sweep pattern mac80211 issues internally
and the only one that triggers the firmware storm at the per-band
loop boundary.  Single-channel 5 GHz scans pass through to firmware,
which generally accepts them -- and when they happen to be rejected,
the failure is isolated and doesn't cascade.

Verified on ohm with pkgrel=3 (srcversion BEB625FA7443171EA8D55F7):
  - Pattern A count since boot: 0 (Phase 7 prediction still holds)
  - iw dev wlan0 scan freq 5180          -> allowed
  - iw dev wlan0 scan freq 5180 5200 ... -> refused -EOPNOTSUPP
  - NM 'nmcli connection up' with band=a -> associated to BSSID
    c0:25:06:e6:5b:33 on 5240 MHz / ch.48 in ~1 second
  - TX bitrate 150 Mbit/s MCS 7 40MHz short-GI (vs 72.2 Mbit/s
    HT20 on 2.4 GHz) -- ~2x throughput recovered

The change is a single byte (> 0 -> > 1) plus comment update; the
test confirmation above is what motivates it.

Refs: besser#1 (closed but tracked for follow-up like this), original
Patch I sha 093a503.
2026-05-18 15:56:34 +02:00
test0r 093a5038b8 bes2600: filter 5 GHz scans at the driver boundary (besser#1)
The BES2600 firmware refuses WSM start-scan for 5 GHz with status 2
("rejected by policy").  This shows up in dmesg as the recurring

    wsm_generic_confirm failed for request 0x0007.
    [SCAN] Scan failed (-22).

pattern (besser issue #1, ~14-16/h on ohm/PineTab2 baseline).

Trace shows every reject is the second of a back-to-back pair: mac80211
splits multi-band hw_scan requests per band when the driver does not
set IEEE80211_HW_SINGLE_SCAN_ON_ALL_BANDS (we don't), then re-invokes
drv_hw_scan from __ieee80211_scan_completed for each subsequent band.
The 2.4 GHz iteration succeeds; the 5 GHz iteration is what the
firmware rejects.  See ieee80211_prep_hw_scan in net/mac80211/scan.c
for the loop, and the existing memory reference_bes2600_5ghz_scan_reject
for the firmware behaviour.

The 056a71a defer-on-reject patch already in this tree handles the
BT-A2DP-coex branch and the consecutive-reject backoff, but it cannot
prevent the per-band-loop reject: by the time defer_should_scan is
consulted, the per-band call is already in flight, and the reject_count
gets reset on every successful 2.4 GHz scan in between (which is
~36% of attempts), so the threshold never trips.

The fix: refuse the 5 GHz iteration upfront in bes2600_hw_scan.  The
2.4 GHz scan still runs normally.  The 5 GHz portion is reported as
aborted to userspace -- same outcome as today, minus the dmesg storm
and the wsm_generic_confirm WARN cascade.

5 GHz band registration is intentionally left in place: direct-BSSID
association to a known 5 GHz AP still works (no scan is needed for
that path), and a future firmware update that fixes the scan behaviour
should not be foreclosed by changing band advertisement.

Contract: per include/net/mac80211.h ieee80211_ops.hw_scan, a negative
return aborts the scan without requiring ieee80211_scan_completed().
-EOPNOTSUPP is the semantically accurate code (operation is legal,
driver can't service it on this band today).

Phase 3 evidence:
- baseline N=3: rate ~14.3-23.6/h converged at 14.3/h (matches OP)
- back-to-back scan gap: 6/6 rejected pairs <200us, 1/1 successful
  pair was 114ms (single-band-only, no 5 GHz leg)
- defer log fires: 0/9 in 30-min window (056a71a structurally bypassed)

Predicted Phase 7 delta: Pattern A 14/h -> 0/h.
2026-05-18 11:27:40 +02:00
test0r f68fd5530f bes2600: Patch H — bh.c hygiene cleanup (drop fossil blocks, dead stubs)
Per Opus structural critique §4.1 (#if 0 graveyard), §4.3 (asm
volatile("nop") placeholder), §4.4 (BUG_ON in steady-state hot
path).  Pure source-tree cleanup, no functional change.

Removed:

  1. bh.c lines 319-395 (76-line #if 0 block) — dead helper
     functions inherited from cw1200 ancestor:
     bes2600_bh_read_ctrl_reg, bes2600_get_skb, bes2600_put_skb,
     bes2600_device_wakeup.  Compiled out for years.

  2. bh.c lines 405-873 + line 1659 (the outer #if 0 / #else /
     #endif) — 468-line cw1200-ancestor bes2600_bh() function body,
     preserved verbatim alongside the active impl.  Same function
     name, same goto labels.  Maintenance hazard removed.

  3. bh.c done: label body — `__bes2600_irq_enable(1)` placeholder
     (commented out) + `asm volatile ("nop")` filler.  Both
     no-ops on bes2600 silicon.

  4. bh.c post-loop "Explicitly disable device interrupts" block
     (sbus lock + __bes2600_irq_enable(0) + sbus unlock) — the
     stub call wrapped in lock/unlock ceremony.  Dead.

  5. hwio.c __bes2600_irq_enable() function definition —
     `int __bes2600_irq_enable(int enable) { return 0; }`.  Stub.
     Removed entirely.

  6. sbus.h __bes2600_irq_enable() forward declaration.

Replaced:

  7. bh.c bes2600_bh outer-loop BUG_ON(hw_bufs_used > numInpChBufs)
     -> WARN_ON_ONCE.  The BUG_ON ran every bh-loop iteration;
     tripping it on a bookkeeping bug locks the kernel up during
     normal operation — the wrong response to a (recoverable)
     accounting drift.  WARN_ON_ONCE surfaces the issue without
     taking the system down.

Why __bes2600_irq_enable was a stub on bes2600:

  cw1200 has the same-named function (drivers/net/wireless/st/cw1200/
  hwio.c:267) that does real work — reads ST90TDS_CONFIG_REG_ID and
  toggles the ST90TDS_CONF_IRQ_RDY_ENABLE bit.  bes2600 inherited
  the function name + signature when forked, but the bes2600 chip's
  IRQ enable is managed by sdio_claim_irq + chip-side firmware, not
  by a driver-side enable register.  Bestechnic kept the function as
  a no-op stub (return 0).  Patch H removes the dead infrastructure.

Diff scope:

  - bes2600/bh.c   -578/+27   (mostly deletions)
  - bes2600/hwio.c -7/+7     (stub function -> comment block)
  - bes2600/sbus.h -2/+1     (declaration -> comment)
  - net: -578/+28 across 3 files

Build verification deferred — ohm offline.  Pure-deletion change,
no semantic risk; the deleted code was either #if 0-gated
(never compiled) or stub-implementations (always returned 0).
2026-05-08 08:23:20 +02:00
marfrit 0750df2611 bes2600: Patch C2 — replace ieee80211_rx_irqsafe with ieee80211_rx_ni (#9) 2026-05-08 04:43:14 +00:00
test0r 0ec58c0ad5 bes2600: Patch C2 — replace ieee80211_rx_irqsafe with ieee80211_rx_ni
Per Phase 4 plan PR #14 + kerneldoc audit (Task #19).  Six call sites
deferred per-RX-frame mac80211 dispatch via tasklet; replace with the
synchronous-from-process-context API ieee80211_rx_ni() which does its
own local_bh_disable wrap.

Why _ni and not _list:

  Phase 4 plan originally targeted ieee80211_rx_list for batch
  delivery.  Mining mt76 mainline (the only driver using _list)
  showed the canonical pattern requires threading a struct list_head
  through the per-frame call chain.  bes2600s WSM dispatcher
  (wsm_handle_rx -> bes2600_rx_cb / wsm.c beacon path) sits between
  the bh threads SDIO read and the mac80211 hand-off; threading a
  list_head through the dispatcher is a non-trivial refactor.
  ieee80211_rx_ni() is the simpler drop-in: no list management, still
  removes the tasklet hop.  Per-call local_bh_disable cost is trivial
  vs the saved tasklet schedule.  Future refactor can revisit _list
  if measurements warrant.

Sites converted:

  - ap.c:96       (bes2600_sta_add link-id rx_queue drain on AP-mode
                   STA add).  Was inside spin_lock_bh(&ps_state_lock);
                   refactored to splice the queue under the lock then
                   deliver after unlock — _ni runs the synchronous
                   mac80211 RX path inline, would otherwise hold the
                   lock across mac80211 dispatch.  splice via
                   skb_queue_splice_init into a local sk_buff_head.
  - sta.c:1487    (deauth-frame inject in inactivity-event handler).
                   Not under any lock; direct conversion.
  - txrx.c:1960   (early-data + pm_unsupported branch from Patch E).
  - txrx.c:1967   (early-data + LINK_SOFT-not-set branch).
  - txrx.c:1971   (normal RX path in bes2600_rx_cb).
  - wsm.c:2415    (beacon delivery in scan-complete WSM handler).
                   beacon SKB ownership is preserved by the existing
                   skb_copy(beacon, GFP_ATOMIC) -> beacon_bkp pattern;
                   no lifecycle change needed.

Mixing constraint (kerneldoc include/net/mac80211.h:5399-5430):
ieee80211_rx_ni() cannot mix with ieee80211_rx_irqsafe() for a
single hardware.  All 6 sites convert atomically; no mixed state.

Build verified clean on ohm sandbox: srcversion 619A51E61BF5479AAC146E6.

Predicted Phase 7 delta: +5-15% over v3+D+E baseline (2.35 MB/s mean
on v3 alone; D+E single-rep was 3.22 MB/s).  Modest improvement
expected from removing the tasklet schedule per RX frame.  Smaller
deltas would still be a net win for upstream-cleanliness — the
kernel.org submission story benefits from not using _irqsafe from
process context.
2026-05-08 06:40:00 +02:00
marfrit 42fd0ceab6 bes2600: Patch E — skip ps_state_lock when PSM-known-disabled (#8) 2026-05-07 22:31:45 +00:00
test0r 4be43770fd bes2600: Patch E — skip ps_state_lock when PSM-known-disabled
Per the Opus structural critique (PR #8 §2.4) and Sonnet review item 5.
The per-RX-frame early-data path takes ps_state_lock to double-check
whether a link entry transitioned to BES2600_LINK_SOFT (AP-side
power-save state machine, soft-link transition).

When c7 has latched pm_unsupported = true (firmware does not honor
PSM, see feedback_bes2600_firmware_no_psm memory), the AP power-save
state machine is dead and link entries never transition to LINK_SOFT.
The per-frame spin_lock_bh + double-check is wasted work.

This patch gates the lock acquisition on !pm_unsupported.  When the
latch is on (the steady state on the production-shipped bes2600
firmware), early_data RX frames bypass the spin_lock_bh and go
directly to ieee80211_rx_irqsafe.

If a future firmware drop fixes PSM, c7 self-clears pm_unsupported on
the first real PM_INDICATION and the locked path resumes.

Scope is narrower than Sonnet originally framed: only the per-RX-frame
hot path (txrx.c:1945-1951 in cleanups+G+D) is touched.  Other
ps_state_lock sites in txrx.c (lines 657, 1256, 1420, 1528) are TX
submission / multicast-start / link-id paths, not per-frame RX, and
not on the Bug #5 hot path.  Leave those alone.

Build verified: srcversion B5922B4933590F33207EE97 on ohm sandbox.
2026-05-08 00:22:14 +02:00
marfrit 3dbabf3092 bes2600: Patch D — atomicize ba_lock counters, drop the spinlock (#7) 2026-05-07 22:19:53 +00:00
marfrit 25c0ed8c57 bes2600: Patch G — restore SPDX + ST-Ericsson attribution chain (#6) 2026-05-07 22:11:14 +00:00
test0r 8dd79199f8 bes2600: Patch G — restore SPDX identifiers + ST-Ericsson attribution
The bes2600 driver is a fork of the upstream cw1200 driver
(drivers/net/wireless/st/cw1200/, ST-Ericsson, Dmitry Tarnyagin
2010-2011).  The fork's file headers have three GPL-compliance issues:

  1. NO SPDX-License-Identifier on any of 48 source files (cw1200
     mainline has them on all 25).  kernel.org-mandated since 2017.

  2. Original "Copyright (c) 2010, ST-Ericsson" lines stripped from
     all files inherited from cw1200, replaced with
     "Copyright (c) 2010, Bestechnic" — factually impossible
     (Bestechnic did not author the 2010 work) and a GPL-2.0 §1
     attribution-preservation violation.

  3. The "GPL version 2 as published by the Free Software Foundation"
     boilerplate paragraph is redundant alongside SPDX and is the
     legacy form modern kernel sources have replaced.

This patch corrects all three for the 48 .c/.h files in bes2600/:

  - Adds `// SPDX-License-Identifier: GPL-2.0-only` (or `/* ... */`
    for headers) as line 1 of every file.
  - Restores `Copyright (c) 2010, ST-Ericsson` + `Author: Dmitry
    Tarnyagin <dmitry.tarnyagin@lockless.no>` as the FIRST copyright
    chain entry on all 22 files derived from cw1200 (bh.{c,h},
    debug.{c,h}, fwio.{c,h}, hwio.{c,h}, main.c, pm.{c,h},
    queue.{c,h}, scan.{c,h}, sta.{c,h}, txrx.{c,h}, wsm.{c,h}).
  - Keeps `Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.` as
    the SECOND chain entry where Bestechnic genuinely contributed.
  - Notes "Derived from cw1200_sdio.c" + ST-Ericsson copyright on
    bes2600_sdio.c (heavy derivation, not a literal rename).
  - Notes "Replaces hwbus.h from cw1200/" + ST-Ericsson copyright
    on sbus.h.
  - Preserves the prism54/islsm authorship chain on main.c and
    bes2600.h (Michael Wu 2006 + Jean-Baptiste Note 2004-2006).
  - Drops the GPL-2.0 boilerplate paragraph in favour of SPDX.

No code changes — only file-header comment blocks.  Module build is
unaffected (verified by header-only diff scope).

This is a prerequisite for any kernel.org submission attempt.  The
existing MODULE_LICENSE("GPL") + MODULE_AUTHOR(Tarnyagin@stericsson.com)
declarations were already present and are unchanged here; the
mismatch between MODULE_AUTHOR and the (since-corrected) per-file
copyrights is now resolved.
2026-05-08 00:03:50 +02:00
48 changed files with 327 additions and 873 deletions
+16 -8
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* mac80211 STA and AP API for mac80211 BES2600 drivers
* AP mode for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "bes2600.h"
@@ -65,8 +62,11 @@ int bes2600_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct bes2600_vif *priv = cw12xx_get_vif_from_ieee80211(vif);
struct bes2600_link_entry *entry;
struct sk_buff *skb;
struct sk_buff_head local_drain;
struct bes2600_common *hw_priv = hw->priv;
__skb_queue_head_init(&local_drain);
#ifdef P2P_MULTIVIF
WARN_ON(priv->if_id == CW12XX_GENERIC_IF_ID);
#endif
@@ -95,9 +95,17 @@ int bes2600_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
priv->sta_asleep_mask |= BIT(sta_priv->link_id);
entry->status = BES2600_LINK_HARD;
while ((skb = skb_dequeue(&entry->rx_queue)))
ieee80211_rx_irqsafe(priv->hw, skb);
/*
* Patch C2: splice the rx_queue out under the lock then deliver
* after unlock. ieee80211_rx_ni() runs the mac80211 RX path
* synchronously (formerly ieee80211_rx_irqsafe deferred to a
* tasklet); calling it from inside spin_lock_bh would hold the
* lock across mac80211's full RX dispatch.
*/
skb_queue_splice_init(&entry->rx_queue, &local_drain);
spin_unlock_bh(&priv->ps_state_lock);
while ((skb = __skb_dequeue(&local_drain)))
ieee80211_rx_ni(priv->hw, skb);
#ifdef AP_AGGREGATE_FW_FIX
hw_priv->connected_sta_cnt++;
if(hw_priv->connected_sta_cnt>1) {
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* mac80211 STA and AP API for mac80211 BES2600 drivers
* AP mode interface for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/version.h>
#ifndef AP_H_INCLUDED
+4 -7
View File
@@ -1,18 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Common private data for BES2600 drivers
* Common private data for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* Based on the mac80211 Prism54 code, which is
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
*
* Based on the islsm (softmac prism54) driver, which is:
* Based on the islsm (softmac prism54) driver, which is
* Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_H
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Factory calibration loader for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Factory calibration loader interface
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __FACTORY_H__
#define __FACTORY_H__
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Platform data for BES2600 SDIO bus
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_PLAT_H_INCLUDED
#define BES2600_PLAT_H_INCLUDED
+7 -6
View File
@@ -1,12 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 SDIO driver for BES2600 device
* SDIO bus glue for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
* Derived from drivers/net/wireless/st/cw1200/cw1200_sdio.c
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2010, Bestechnic
* Author:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define DEBUG 1
#include <linux/version.h>
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Character device for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include<linux/module.h>
#include <linux/init.h>
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Character device interface for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __BES_CHARDEV_H__
#define __BES_CHARDEV_H__
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Firmware download for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "bes_fw_common.h"
#include "bes2600.h"
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Firmware download common code for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "bes_fw_common.h"
#include "bes_log.h"
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Firmware download common interface
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __BES_FW_COMMON_H__
#define __BES_FW_COMMON_H__
+7
View File
@@ -1,3 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* printk wrappers for BES2600
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
*/
extern struct device *global_dev;
#ifdef CONFIG_BES2600_ENABLE_DEVEL_LOGS
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Vendor testmode messages for BES2600
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES_NL80211_TESTMODE_MSG_H
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Chip-side power state machine for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/list.h>
#include <linux/pm.h>
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Chip-side power state machine interface
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __BES_PWR_H__
#define __BES_PWR_H__
+26 -564
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Bottom-half thread for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <net/mac80211.h>
#include <linux/kthread.h>
@@ -316,83 +316,6 @@ int wsm_release_buffer_to_fw(struct bes2600_vif *priv, int count)
}
#endif
#if 0
static struct sk_buff *bes2600_get_skb(struct bes2600_common *hw_priv, size_t len)
{
struct sk_buff *skb;
size_t alloc_len = (len > SDIO_BLOCK_SIZE) ? len : SDIO_BLOCK_SIZE;
if (len > SDIO_BLOCK_SIZE || !hw_priv->skb_cache) {
skb = dev_alloc_skb(alloc_len
+ WSM_TX_EXTRA_HEADROOM
+ 8 /* TKIP IV */
+ 12 /* TKIP ICV + MIC */
- 2 /* Piggyback */);
/* In AP mode RXed SKB can be looped back as a broadcast.
* Here we reserve enough space for headers. */
skb_reserve(skb, WSM_TX_EXTRA_HEADROOM
+ 8 /* TKIP IV */
- WSM_RX_EXTRA_HEADROOM);
} else {
skb = hw_priv->skb_cache;
hw_priv->skb_cache = NULL;
}
return skb;
}
static void bes2600_put_skb(struct bes2600_common *hw_priv, struct sk_buff *skb)
{
if (hw_priv->skb_cache)
dev_kfree_skb(skb);
else
hw_priv->skb_cache = skb;
}
static int bes2600_bh_read_ctrl_reg(struct bes2600_common *hw_priv,
u16 *ctrl_reg)
{
int ret;
ret = bes2600_reg_read_16(hw_priv,
ST90TDS_CONTROL_REG_ID, ctrl_reg);
if (ret) {
ret = bes2600_reg_read_16(hw_priv,
ST90TDS_CONTROL_REG_ID, ctrl_reg);
if (ret)
bes_err("[BH] Failed to read control register.\n");
}
return ret;
}
static int bes2600_device_wakeup(struct bes2600_common *hw_priv)
{
u16 ctrl_reg;
int ret;
bes_devel("[BH] Device wakeup.\n");
/* To force the device to be always-on, the host sets WLAN_UP to 1 */
ret = bes2600_reg_write_16(hw_priv, ST90TDS_CONTROL_REG_ID,
ST90TDS_CONT_WUP_BIT);
if (WARN_ON(ret))
return ret;
ret = bes2600_bh_read_ctrl_reg(hw_priv, &ctrl_reg);
if (WARN_ON(ret))
return ret;
/* If the device returns WLAN_RDY as 1, the device is active and will
* remain active. */
if (ctrl_reg & ST90TDS_CONT_RDY_BIT) {
bes_devel("[BH] Device awake.\n");
return 1;
}
return 0;
}
#endif
/* Must be called from BH thraed. */
void bes2600_enable_powersave(struct bes2600_vif *priv,
@@ -402,475 +325,6 @@ void bes2600_enable_powersave(struct bes2600_vif *priv,
priv->powersave_enabled = enable;
}
#if 0
#define INTERRUPT_WORKAROUND
static int bes2600_bh(void *arg)
{
struct bes2600_common *hw_priv = arg;
struct bes2600_vif *priv = NULL;
struct sk_buff *skb_rx = NULL;
size_t read_len = 0;
int rx, tx, term, suspend;
struct wsm_hdr *wsm;
size_t wsm_len;
int wsm_id;
u8 wsm_seq;
int rx_resync = 1;
u16 ctrl_reg = 0;
int tx_allowed;
int pending_tx = 0;
int tx_burst;
int rx_burst = 0;
long status;
#if defined(CONFIG_BES2600_WSM_DUMPS)
size_t wsm_dump_max = -1;
#endif
u32 dummy;
bool powersave_enabled;
int i;
int vif_selected;
for (;;) {
powersave_enabled = 1;
spin_lock(&hw_priv->vif_list_lock);
bes2600_for_each_vif(hw_priv, priv, i) {
#ifdef P2P_MULTIVIF
if ((i = (CW12XX_MAX_VIFS - 1)) || !priv)
#else
if (!priv)
#endif
continue;
powersave_enabled &= !!priv->powersave_enabled;
}
spin_unlock(&hw_priv->vif_list_lock);
if (!hw_priv->hw_bufs_used
&& powersave_enabled
&& !hw_priv->device_can_sleep
&& !atomic_read(&hw_priv->recent_scan)) {
status = HZ/8;
bes_devel("[BH] No Device wakedown.\n");
#ifndef FPGA_SETUP
WARN_ON(bes2600_reg_write_16(hw_priv,
ST90TDS_CONTROL_REG_ID, 0));
hw_priv->device_can_sleep = true;
#endif
} else if (hw_priv->hw_bufs_used)
/* Interrupt loss detection */
status = HZ/8;
else
status = HZ/8;
/* Dummy Read for SDIO retry mechanism*/
if (((atomic_read(&hw_priv->bh_rx) == 0) &&
(atomic_read(&hw_priv->bh_tx) == 0)))
bes2600_reg_read(hw_priv, ST90TDS_CONFIG_REG_ID,
&dummy, sizeof(dummy));
#if defined(CONFIG_BES2600_WSM_DUMPS_SHORT)
wsm_dump_max = hw_priv->wsm_dump_max_size;
#endif /* CONFIG_BES2600_WSM_DUMPS_SHORT */
#ifdef INTERRUPT_WORKAROUND
/* If a packet has already been txed to the device then read the
control register for a probable interrupt miss before going
further to wait for interrupt; if the read length is non-zero
then it means there is some data to be received */
if (hw_priv->hw_bufs_used) {
bes2600_bh_read_ctrl_reg(hw_priv, &ctrl_reg);
if(ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
{
rx = 1;
goto test;
}
}
#endif
status = wait_event_interruptible_timeout(hw_priv->bh_wq, ({
rx = atomic_xchg(&hw_priv->bh_rx, 0);
tx = atomic_xchg(&hw_priv->bh_tx, 0);
term = atomic_xchg(&hw_priv->bh_term, 0);
suspend = pending_tx ?
0 : atomic_read(&hw_priv->bh_suspend);
(rx || tx || term || suspend || hw_priv->bh_error);
}), status);
if (status < 0 || term || hw_priv->bh_error)
break;
#ifdef INTERRUPT_WORKAROUND
if (!status) {
bes2600_bh_read_ctrl_reg(hw_priv, &ctrl_reg);
if(ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
{
bes_err("MISS 1\n");
rx = 1;
goto test;
}
}
#endif
if (!status && hw_priv->hw_bufs_used) {
unsigned long timestamp = jiffies;
long timeout;
bool pending = false;
int i;
wiphy_warn(hw_priv->hw->wiphy, "Missed interrupt?\n");
rx = 1;
/* Get a timestamp of "oldest" frame */
for (i = 0; i < 4; ++i)
pending |= bes2600_queue_get_xmit_timestamp(
&hw_priv->tx_queue[i],
&timestamp, -1,
hw_priv->pending_frame_id);
/* Check if frame transmission is timed out.
* Add an extra second with respect to possible
* interrupt loss. */
timeout = timestamp +
WSM_CMD_LAST_CHANCE_TIMEOUT +
1 * HZ -
jiffies;
/* And terminate BH tread if the frame is "stuck" */
if (pending && timeout < 0) {
//wiphy_warn(priv->hw->wiphy,
// "Timeout waiting for TX confirm.\n");
bes_devel("bes2600_bh: Timeout waiting for TX confirm.\n");
break;
}
#if defined(CONFIG_BES2600_DUMP_ON_ERROR)
BUG_ON(1);
#endif /* CONFIG_BES2600_DUMP_ON_ERROR */
} else if (!status) {
if (!hw_priv->device_can_sleep
&& !atomic_read(&hw_priv->recent_scan)) {
bes_devel("[BH] Device wakedown. Timeout.\n");
#ifndef FPGA_SETUP
WARN_ON(bes2600_reg_write_16(hw_priv,
ST90TDS_CONTROL_REG_ID, 0));
hw_priv->device_can_sleep = true;
#endif
}
continue;
} else if (suspend) {
bes_devel("[BH] Device suspend.\n");
powersave_enabled = 1;
spin_lock(&hw_priv->vif_list_lock);
bes2600_for_each_vif(hw_priv, priv, i) {
#ifdef P2P_MULTIVIF
if ((i = (CW12XX_MAX_VIFS - 1)) || !priv)
#else
if (!priv)
#endif
continue;
powersave_enabled &= !!priv->powersave_enabled;
}
spin_unlock(&hw_priv->vif_list_lock);
if (powersave_enabled) {
bes_devel("[BH] No Device wakedown. Suspend.\n");
#ifndef FPGA_SETUP
WARN_ON(bes2600_reg_write_16(hw_priv,
ST90TDS_CONTROL_REG_ID, 0));
hw_priv->device_can_sleep = true;
#endif
}
atomic_set(&hw_priv->bh_suspend, BES2600_BH_SUSPENDED);
wake_up(&hw_priv->bh_evt_wq);
status = wait_event_interruptible(hw_priv->bh_wq,
BES2600_BH_RESUME == atomic_read(
&hw_priv->bh_suspend));
if (status < 0) {
wiphy_err(hw_priv->hw->wiphy,
"%s: Failed to wait for resume: %ld.\n",
__func__, status);
break;
}
bes_devel("[BH] Device resume.\n");
atomic_set(&hw_priv->bh_suspend, BES2600_BH_RESUMED);
wake_up(&hw_priv->bh_evt_wq);
atomic_inc(&hw_priv->bh_rx);
continue;
}
test:
tx += pending_tx;
pending_tx = 0;
if (rx) {
size_t alloc_len;
u8 *data;
#ifdef INTERRUPT_WORKAROUND
if(!(ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK))
#endif
if (WARN_ON(bes2600_bh_read_ctrl_reg(
hw_priv, &ctrl_reg)))
break;
rx:
read_len = (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) * 2;
if (!read_len) {
rx_burst = 0;
goto tx;
}
if (WARN_ON((read_len < sizeof(struct wsm_hdr)) ||
(read_len > EFFECTIVE_BUF_SIZE))) {
bes_devel("Invalid read len: %d", read_len);
break;
}
/* Add SIZE of PIGGYBACK reg (CONTROL Reg)
* to the NEXT Message length + 2 Bytes for SKB */
read_len = read_len + 2;
#if defined(CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES)
alloc_len = hw_priv->sbus_ops->align_size(
hw_priv->sbus_priv, read_len);
#else /* CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES */
/* Platform's SDIO workaround */
alloc_len = read_len & ~(SDIO_BLOCK_SIZE - 1);
if (read_len & (SDIO_BLOCK_SIZE - 1))
alloc_len += SDIO_BLOCK_SIZE;
#endif /* CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES */
/* Check if not exceeding BES2600 capabilities */
if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE))
bes_devel("Read aligned len: %d\n", alloc_len);
skb_rx = bes2600_get_skb(hw_priv, alloc_len);
if (WARN_ON(!skb_rx))
break;
skb_trim(skb_rx, 0);
skb_put(skb_rx, read_len);
data = skb_rx->data;
if (WARN_ON(!data))
break;
if (WARN_ON(bes2600_data_read(hw_priv, data, alloc_len)))
break;
/* Piggyback */
ctrl_reg = __le16_to_cpu(
((__le16 *)data)[alloc_len / 2 - 1]);
wsm = (struct wsm_hdr *)data;
wsm_len = __le32_to_cpu(wsm->len);
if (WARN_ON(wsm_len > read_len))
break;
#if defined(CONFIG_BES2600_WSM_DUMPS)
if (unlikely(hw_priv->wsm_enable_wsm_dumps)) {
u16 msgid, ifid;
u16 *p = (u16 *)data;
msgid = (*(p + 1)) & 0xC3F;
ifid = (*(p + 1)) >> 6;
ifid &= 0xF;
bes_devel("[DUMP] <<< msgid 0x%.4X ifid %d len %d\n", msgid, ifid, *p);
print_hex_dump(KERN_DEBUG, "<-- ", DUMP_PREFIX_NONE, data, min(wsm_len, wsm_dump_max));
}
#endif /* CONFIG_BES2600_WSM_DUMPS */
wsm_id = __le32_to_cpu(wsm->id) & 0xFFF;
wsm_seq = (__le32_to_cpu(wsm->id) >> 13) & 7;
skb_trim(skb_rx, wsm_len);
if (unlikely(wsm_id == 0x0800)) {
wsm_handle_exception(hw_priv,
&data[sizeof(*wsm)],
wsm_len - sizeof(*wsm));
break;
} else if (unlikely(!rx_resync)) {
if (WARN_ON(wsm_seq != hw_priv->wsm_rx_seq)) {
#if defined(CONFIG_BES2600_DUMP_ON_ERROR)
BUG_ON(1);
#endif /* CONFIG_BES2600_DUMP_ON_ERROR */
break;
}
}
hw_priv->wsm_rx_seq = (wsm_seq + 1) & 7;
rx_resync = 0;
if (wsm_id & 0x0400) {
int rc = wsm_release_tx_buffer(hw_priv, 1);
if (WARN_ON(rc < 0))
break;
else if (rc > 0)
tx = 1;
}
/* bes2600_wsm_rx takes care on SKB livetime */
if (WARN_ON(wsm_handle_rx(hw_priv, wsm_id, wsm,
&skb_rx)))
break;
if (skb_rx) {
bes2600_put_skb(hw_priv, skb_rx);
skb_rx = NULL;
}
read_len = 0;
if (rx_burst) {
bes2600_debug_rx_burst(hw_priv);
--rx_burst;
goto rx;
}
}
tx:
BUG_ON(hw_priv->hw_bufs_used > hw_priv->wsm_caps.numInpChBufs);
tx_burst = hw_priv->wsm_caps.numInpChBufs -
hw_priv->hw_bufs_used;
tx_allowed = tx_burst > 0;
if (tx && tx_allowed) {
size_t tx_len;
u8 *data;
int ret;
if (hw_priv->device_can_sleep) {
ret = bes2600_device_wakeup(hw_priv);
if (WARN_ON(ret < 0))
break;
else if (ret)
hw_priv->device_can_sleep = false;
else {
/* Wait for "awake" interrupt */
pending_tx = tx;
continue;
}
}
wsm_alloc_tx_buffer(hw_priv);
ret = wsm_get_tx(hw_priv, &data, &tx_len, &tx_burst,
&vif_selected);
if (ret <= 0) {
wsm_release_tx_buffer(hw_priv, 1);
if (WARN_ON(ret < 0))
break;
} else {
wsm = (struct wsm_hdr *)data;
BUG_ON(tx_len < sizeof(*wsm));
BUG_ON(__le32_to_cpu(wsm->len) != tx_len);
#if 0 /* count is not implemented */
if (ret > 1)
atomic_inc(&hw_priv->bh_tx);
#else
atomic_inc(&hw_priv->bh_tx);
#endif
#if defined(CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES)
if (tx_len <= 8)
tx_len = 16;
tx_len = hw_priv->sbus_ops->align_size(
hw_priv->sbus_priv, tx_len);
#else /* CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES */
/* HACK!!! Platform limitation.
* It is also supported by upper layer:
* there is always enough space at the
* end of the buffer. */
if (tx_len & (SDIO_BLOCK_SIZE - 1)) {
tx_len &= ~(SDIO_BLOCK_SIZE - 1);
tx_len += SDIO_BLOCK_SIZE;
}
#endif /* CONFIG_BES2600_NON_POWER_OF_TWO_BLOCKSIZES */
/* Check if not exceeding BES2600
capabilities */
if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
bes_devel("Write aligned len: %d\n", tx_len);
wsm->id &= __cpu_to_le32(
~WSM_TX_SEQ(WSM_TX_SEQ_MAX));
wsm->id |= cpu_to_le32(WSM_TX_SEQ(
hw_priv->wsm_tx_seq));
if (WARN_ON(bes2600_data_write(hw_priv,
data, tx_len))) {
wsm_release_tx_buffer(hw_priv, 1);
break;
}
if (vif_selected != -1) {
hw_priv->hw_bufs_used_vif[
vif_selected]++;
}
#if defined(CONFIG_BES2600_WSM_DUMPS)
if (unlikely(hw_priv->wsm_enable_wsm_dumps)) {
u16 msgid, ifid;
u16 *p = (u16 *)data;
msgid = (*(p + 1)) & 0x3F;
ifid = (*(p + 1)) >> 6;
ifid &= 0xF;
if (msgid == 0x0006)
bes_devel("[DUMP] >>> msgid 0x%.4X ifid %d len %d MIB 0x%.4X\n", msgid, ifid, *p, *(p + 2));
else
bes_devel("[DUMP] >>> msgid 0x%.4X ifid %d len %d\n", msgid, ifid, *p);
print_hex_dump(KERN_DEBUG, "--> ", DUMP_PREFIX_NONE, data, min(__le32_to_cpu(wsm->len), wsm_dump_max));
}
#endif /* CONFIG_BES2600_WSM_DUMPS */
wsm_txed(hw_priv, data);
hw_priv->wsm_tx_seq = (hw_priv->wsm_tx_seq + 1)
& WSM_TX_SEQ_MAX;
if (tx_burst > 1) {
bes2600_debug_tx_burst(hw_priv);
++rx_burst;
goto tx;
}
}
}
if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
goto rx;
}
if (skb_rx) {
bes2600_put_skb(hw_priv, skb_rx);
skb_rx = NULL;
}
if (!term) {
bes_devel("[BH] Fatal error, exitting.\n");
#if defined(CONFIG_BES2600_DUMP_ON_ERROR)
BUG_ON(1);
#endif /* CONFIG_BES2600_DUMP_ON_ERROR */
hw_priv->bh_error = 1;
#if defined(CONFIG_BES2600_USE_STE_EXTENSIONS)
spin_lock(&hw_priv->vif_list_lock);
bes2600_for_each_vif(hw_priv, priv, i) {
if (!priv)
continue;
ieee80211_driver_hang_notify(priv->vif, GFP_KERNEL);
}
spin_unlock(&hw_priv->vif_list_lock);
bes2600_pm_stay_awake(&hw_priv->pm_state, 3*HZ);
#endif
/* TODO: schedule_work(recovery) */
#ifndef HAS_PUT_TASK_STRUCT
/* The only reason of having this stupid code here is
* that __put_task_struct is not exported by kernel. */
for (;;) {
int status = wait_event_interruptible(hw_priv->bh_wq, ({
term = atomic_xchg(&hw_priv->bh_term, 0);
(term);
}));
if (status || term)
break;
}
#endif
}
return 0;
}
#else
extern int bes2600_bh_read_ctrl_reg(struct bes2600_common *priv, u32 *ctrl_reg);
@@ -1592,7 +1046,15 @@ static int bes2600_bh(void *arg)
tx = 0;
BUG_ON(hw_priv->hw_bufs_used > hw_priv->wsm_caps.numInpChBufs);
/*
* Patch H: BUG_ON -> WARN_ON_ONCE in the steady-state
* hot path. The original BUG_ON ran every bh-loop
* iteration; tripping it on a bookkeeping bug locks
* the kernel up during normal operation, which is
* the wrong response. WARN_ON_ONCE surfaces the
* issue without taking the system down.
*/
WARN_ON_ONCE(hw_priv->hw_bufs_used > hw_priv->wsm_caps.numInpChBufs);
tx_burst = hw_priv->wsm_caps.numInpChBufs - hw_priv->hw_bufs_used;
tx_allowed = tx_burst > 0;
@@ -1636,18 +1098,19 @@ static int bes2600_bh(void *arg)
goto tx;
done:
/* Re-enable device interrupts */
//hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
//__bes2600_irq_enable(1);
//hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
asm volatile ("nop");
/*
* Patch H: dropped the dead `__bes2600_irq_enable(1)` /
* `asm volatile("nop")` placeholder that used to sit here.
* `__bes2600_irq_enable()` is a stub that returns 0 on
* bes2600 silicon the IRQ is managed by sdio_claim_irq
* and chip-side firmware, not by a driver-side enable bit.
* (cw1200 inherited the function from a different chip
* shape; bes2600 kept the stub but the call sites are
* meaningless.)
*/
;
}
/* Explicitly disable device interrupts */
hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
__bes2600_irq_enable(0);
hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
if (!term) {
bes_err("[BH] Fatal error, exiting.\n");
sdio_work_debug(hw_priv->sbus_priv);
@@ -1656,4 +1119,3 @@ static int bes2600_bh(void *arg)
}
return 0;
}
#endif
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Device handling thread interface for mac80211 BES2600 drivers
* Bottom-half thread interface for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_BH_H
+6 -6
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Debugging interface for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* DebugFS code for BES2600 mac80211 driver
* Debugging interface for BES2600 mac80211 driver
*
* Copyright (c) 2011, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_DEBUG_H_INCLUDED
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* BT/WiFi coexistence (ePTA) for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/version.h>
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* BT/WiFi coexistence interface for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __EPTA_COEX_H__
#define __EPTA_COEX_H__
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* BT/WiFi coexistence request handling
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/kernel.h>
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* BT/WiFi coexistence request interface
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef EPTA_REQUEST_H
#define EPTA_REQUEST_H
+6 -6
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Firmware I/O for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Firmware I/O interface for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef FWIO_H_INCLUDED
#define FWIO_H_INCLUDED
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* HT-related code for BES2600 driver
* HT capability config for BES2600
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_HT_H_INCLUDED
+13 -10
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Low-level device IO routines for BES2600 drivers
* Low-level device I/O for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
@@ -324,7 +324,10 @@ out:
}
#endif
int __bes2600_irq_enable(int enable)
{
return 0;
}
/*
* Patch H: __bes2600_irq_enable stub removed. It was a no-op
* (always returned 0) inherited from cw1200 where the analogous
* function manipulates the chip's IRQ-enable register. bes2600
* silicon manages SDIO IRQ via sdio_claim_irq and chip-side
* firmware there is no driver-side enable register to write.
*/
+5 -10
View File
@@ -1,17 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Low-level API for mac80211 BES2600 drivers
* Low-level device I/O interface for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Based on:
* UMAC BES2600 driver which is
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_HWIO_H_INCLUDED
+3 -7
View File
@@ -1,13 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* mac80211 glue code for mac80211 BES2600 drivers
* ITP code
* ITP (in-band test mode) for BES2600
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ITP code for BES2600 mac80211 driver
* ITP interface for BES2600
*
* Copyright (c) 2011, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_ITP_H_INCLUDED
+12 -6
View File
@@ -1,12 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Main entry/init for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* Based on the mac80211 Prism54 code, which is
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
*
* Based on the islsm (softmac prism54) driver, which is
* Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
+6 -6
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 power management API for BES2600 drivers
* Power management for BES2600 mac80211 driver
*
* Copyright (c) 2011, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/platform_device.h>
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 power management interface for BES2600 mac80211 drivers
* Power management interface for BES2600 mac80211 driver
*
* Copyright (c) 2011, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef PM_H_INCLUDED
+9 -9
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* O(1) TX queue with built-in allocator for BES2600 drivers
* O(1) TX queue for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <net/mac80211.h>
@@ -829,19 +829,19 @@ int bes2600_queue_get_skb(struct bes2600_queue *queue, u32 packetID,
bes2600_queue_parse_id(packetID, &queue_generation, &queue_id,
&item_generation, &item_id, &if_id, &link_id);
spin_lock(&queue->stats->hw_priv->tx_loop.pending_record_lock);
spin_lock_bh(&queue->stats->hw_priv->tx_loop.pending_record_lock);
if (!list_empty(&queue->stats->hw_priv->tx_loop.pending_record_list)) {
list_for_each_entry_safe(record_item, temp_record_item, &queue->stats->hw_priv->tx_loop.pending_record_list, head) {
if (record_item->packetID == packetID) {
list_del(&record_item->head);
dev_kfree_skb(record_item->skb);
kfree(record_item);
spin_unlock(&queue->stats->hw_priv->tx_loop.pending_record_lock);
spin_unlock_bh(&queue->stats->hw_priv->tx_loop.pending_record_lock);
return -EINVAL;
}
}
}
spin_unlock(&queue->stats->hw_priv->tx_loop.pending_record_lock);
spin_unlock_bh(&queue->stats->hw_priv->tx_loop.pending_record_lock);
item = &queue->pool[item_id];
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* O(1) TX queue with built-in allocator for BES2600 drivers
* O(1) TX queue interface for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_QUEUE_H_INCLUDED
+7 -8
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Common sbus abstraction layer interface for bes2600 wireless driver
* Bus abstraction interface for BES2600
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
* Replaces hwbus.h from drivers/net/wireless/st/cw1200/
* Copyright (c) 2010, ST-Ericsson
*
* Copyright (c) 2010, Bestechnic
* Author:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_SBUS_H
@@ -95,7 +95,6 @@ struct sbus_ops {
void bes2600_irq_handler(struct bes2600_common *priv);
/* This MUST be wrapped with hwbus_ops->lock/unlock! */
int __bes2600_irq_enable(int enable);
/* Patch H: __bes2600_irq_enable removed (was a stub). */
#endif /* BES2600_SBUS_H */
+36 -6
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Scan implementation for BES2600 mac80211 drivers
* Scan implementation for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/sched.h>
@@ -238,6 +238,36 @@ int bes2600_hw_scan(struct ieee80211_hw *hw,
/* Scan when P2P_GO corrupt firmware MiniAP mode */
if (priv->join_status == BES2600_JOIN_STATUS_AP)
return -EOPNOTSUPP;
/*
* Firmware refuses WSM start-scan for 5 GHz with status 2 ("rejected
* by policy"); see besser issue #1. mac80211 splits multi-band
* hw_scan requests per-band when the driver does not set
* IEEE80211_HW_SINGLE_SCAN_ON_ALL_BANDS (we don't -- see
* ieee80211_hw_set() calls in bes2600_main.c), so each per-band call
* has req->channels[] from one band only (see ieee80211_prep_hw_scan
* in net/mac80211/scan.c). Refuse the 5 GHz iteration at the driver
* boundary so userspace gets a clean aborted-scan for that portion
* rather than waiting for the firmware reject to cascade up.
*
* Only the multi-channel case is refused (n_channels > 1): that's
* the per-band-sweep pattern mac80211 issues internally and the
* one that triggers the firmware storm at the per-band loop
* boundary. Single-channel 5 GHz scans (BSS verification, NM's
* per-freq iteration when 802-11-wireless.band=a is set) pass
* through to firmware, which generally accepts them since the
* storm is the back-to-back per-band issue, not a blanket 5 GHz
* reject. This preserves 5 GHz association via the
* "wpa_supplicant iterates freq_list per channel" path.
*
* Contract: per include/net/mac80211.h struct ieee80211_ops.hw_scan
* documentation, a negative return aborts the scan without requiring
* ieee80211_scan_completed().
*/
if (req->n_channels > 1 &&
req->channels[0]->band == NL80211_BAND_5GHZ)
return -EOPNOTSUPP;
#if 0
if (work_pending(&priv->offchannel_work) ||
(hw_priv->roc_if_id != -1)) {
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Scan interface for BES2600 mac80211 drivers
* Scan interface for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef SCAN_H_INCLUDED
+7 -7
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 STA API for BES2600 drivers
* Mac80211 STA API for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/vmalloc.h>
@@ -1484,7 +1484,7 @@ void bes2600_event_handler(struct work_struct *work)
IEEE80211_STYPE_DEAUTH | IEEE80211_FCTL_TODS);
deauth->u.deauth.reason_code = WLAN_REASON_DEAUTH_LEAVING;
deauth->seq_ctrl = 0;
ieee80211_rx_irqsafe(priv->hw, skb);
ieee80211_rx_ni(priv->hw, skb);
bes_devel(" Inactivity Deauth Frame sent for MAC SA %pM \t and DA %pM\n", deauth->sa, deauth->da);
queue_work(priv->hw_priv->workqueue, &priv->set_tim_work);
break;
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 STA interface for BES2600 mac80211 drivers
* Mac80211 STA API interface for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/version.h>
#ifndef STA_H_INCLUDED
+5 -8
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* Test-mode TX loopback for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "bes2600.h"
#include "wsm.h"
@@ -112,9 +109,9 @@ void bes2600_tx_loop_set_enable(struct bes2600_common *hw_priv, bool need_warn)
bes2600_queue_iterate_pending_packet(&hw_priv->tx_queue[i],
bes2600_tx_loop_item_pending_item);
}
spin_lock(&hw_priv->tx_loop.pending_record_lock);
spin_lock_bh(&hw_priv->tx_loop.pending_record_lock);
bes2600_queue_iterate_record_pending_packet(hw_priv, bes2600_tx_loop_item_pending_item);
spin_unlock(&hw_priv->tx_loop.pending_record_lock);
spin_unlock_bh(&hw_priv->tx_loop.pending_record_lock);
if (atomic_read(&hw_priv->bh_rx) > 0)
wake_up(&hw_priv->bh_wq);
+3 -6
View File
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Mac80211 driver for BES2600 device
* Test-mode TX loopback interface for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __TX_LOOP_H__
#define __TX_LOOP_H__
+32 -14
View File
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Datapath implementation for BES2600 mac80211 drivers
* Datapath implementation for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <net/mac80211.h>
@@ -1942,15 +1942,33 @@ void bes2600_rx_cb(struct bes2600_vif *priv,
if (unlikely(bes2600_itp_rxed(hw_priv, skb)))
consume_skb(skb);
else if (unlikely(early_data)) {
spin_lock_bh(&priv->ps_state_lock);
/* Double-check status with lock held */
if (entry->status == BES2600_LINK_SOFT)
skb_queue_tail(&entry->rx_queue, skb);
else
ieee80211_rx_irqsafe(priv->hw, skb);
spin_unlock_bh(&priv->ps_state_lock);
/*
* Patch E: when c7 has latched pm_unsupported (firmware
* doesn't honour PSM, see feedback_bes2600_firmware_no_psm),
* AP-side power-save state machine is dead and link entries
* never transition to BES2600_LINK_SOFT. The double-check
* branch under ps_state_lock is unreachable in that case,
* so skip the per-frame lock acquisition entirely and
* deliver to mac80211 directly.
*
* On firmware that does honour PSM (the latch self-clears
* if a real PM_INDICATION ever arrives see c7), this
* predicate flips back to false and the original locked
* path is taken.
*/
if (hw_priv->bes_power.pm_unsupported) {
ieee80211_rx_ni(priv->hw, skb);
} else {
spin_lock_bh(&priv->ps_state_lock);
/* Double-check status with lock held */
if (entry->status == BES2600_LINK_SOFT)
skb_queue_tail(&entry->rx_queue, skb);
else
ieee80211_rx_ni(priv->hw, skb);
spin_unlock_bh(&priv->ps_state_lock);
}
} else {
ieee80211_rx_irqsafe(priv->hw, skb);
ieee80211_rx_ni(priv->hw, skb);
}
*skb_p = NULL;
+6 -6
View File
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Datapath interface for BES2600 mac80211 drivers
* Datapath interface for BES2600 mac80211 driver
*
* Copyright (c) 2010, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_TXRX_H
+3 -6
View File
@@ -1,12 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Mac80211 driver for BES2600 device
* WiFi testmode commands for BES2600
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifdef CONFIG_BES2600_TESTMODE
#include <net/netlink.h>
+7 -8
View File
@@ -1,13 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* WSM host interface (HI) implementation for
* BES2600 mac80211 drivers.
* WSM host interface for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/skbuff.h>
@@ -2413,7 +2412,7 @@ int wsm_handle_rx(struct bes2600_common *hw_priv, int id,
if (!hw_priv->beacon_bkp)
hw_priv->beacon_bkp = \
skb_copy(hw_priv->beacon, GFP_ATOMIC);
ieee80211_rx_irqsafe(hw_priv->hw, hw_priv->beacon);
ieee80211_rx_ni(hw_priv->hw, hw_priv->beacon);
hw_priv->beacon = hw_priv->beacon_bkp;
hw_priv->beacon_bkp = NULL;
+5 -9
View File
@@ -1,16 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* WSM host interface (HI) interface for BES2600 mac80211 drivers
* WSM host interface for BES2600 mac80211 driver
*
* Copyright (c) 2022, Bestechnic
* Author:
* Copyright (c) 2010, ST-Ericsson
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
*
* Based on BES2600 UMAC WSM API, which is
* Copyright (C) SA 2010
* Author: Stewart Mathers <stewart.mathers@stericsson.com>
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_WSM_H_INCLUDED