1e9eb4581f
Patch C v3 — match cw1200 mainline architecture (drivers/net/wireless/st/cw1200/). Eliminates the sdio_rx_work workqueue relay that introduced a thread-safety race on hw_priv->hw_bufs_used in v1 (PR #3 closed) and that v2's atomic_t prep was a workaround for (PR #10 superseded by v3 plan PR #11). Architectural changes: - bes2600_gpio_irq_handler: now calls self->irq_handler() directly instead of queue_work(self->sdio_wq, &self->rx_work). Bumps bh_rx atomic + wakes bh_wq. - bes2600_bh_rx_helper (BES_SDIO_RX_MULTIPLE_ENABLE branch): now calls priv->sbus_ops->bus_rx_batch() to do the SDIO read inline. No pipe_read, no skb_dequeue. - bes2600_sdio_read_rx_batch (new): the SDIO read sequence extracted from sdio_rx_work, registered as sbus_ops->bus_rx_batch. Runs in bh thread context. - bes2600_sdio_extract_packets: calls bes2600_bh_handle_rx_skb() directly per parsed SKB. No skb_queue_tail, no rx_queue. - bes2600_bh_handle_rx_skb (new in bh.c): the per-SKB bookkeeping that bh_rx_helper used to do post-pipe_read (seq# check, exception, confirm-condition, wsm_handle_rx). Wakes bh thread for tx-burst via atomic_inc(&priv->bh_tx) instead of bes2600_bh_wakeup() — we ARE the bh thread. - Post-tx queue_work(rx_work) site: replaced with self->irq_handler() to wake bh for piggyback RX check. Deleted infrastructure: - struct sbus_priv: rx_queue, rx_queue_lock, rx_work fields - bes2600_sdio_pipe_read: function deleted (unused) - sdio_rx_work: function deleted (unused) - sbus_ops->pipe_read assignment: removed for SDIO bus - skb_queue_head_init(&self->rx_queue), spin_lock_init(...), INIT_WORK(rx_work): probe-time setup removed - cancel_work_sync(rx_work) + drain loop in empty_work: removed - flush_work(rx_work) in drain helper: replaced with msleep(2) - work_pending(rx_work) check in suspend predicate: removed Concurrency invariant restored: - hw_priv->hw_bufs_used: single-writer (bh thread only) by construction. No atomic_t needed. - hw_priv->hw_bufs_used_vif[]: ditto. - hw_priv->wsm_tx_pending[]: ditto. - All other shared state: unchanged or already protected. Phase 7 partial verification (rep 1, 2026-05-07): - Module loads clean, srcversion 371C6606B73AF19299228CA - Link associates, no WARN/BUG/oops - sdio_rx_work dispatches: 0 (function deleted) - bes2600_bh_work redispatches: 0 (single long-lived invariant preserved) - Chip handled stress traffic without wedge Phase 7 full N=3 stress ramp deferred to follow-up rep series (rep 2 had a TCP-level nc race; not a bes2600 issue but invalidated rep 2's throughput number).
102 lines
3.3 KiB
C
102 lines
3.3 KiB
C
/*
|
|
* Common sbus abstraction layer interface for bes2600 wireless driver
|
|
*
|
|
* 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
|
|
#define BES2600_SBUS_H
|
|
|
|
/*
|
|
* sbus priv forward definition.
|
|
* Implemented and instantiated in particular modules.
|
|
*/
|
|
struct sbus_priv;
|
|
struct bes2600_common;
|
|
|
|
typedef void (*sbus_irq_handler)(void *priv);
|
|
|
|
enum SUBSYSTEM {
|
|
SUBSYSTEM_MCU = 0,
|
|
SUBSYSTEM_WIFI,
|
|
SUBSYSTEM_BT,
|
|
SUBSYSTEM_BT_LP,
|
|
};
|
|
|
|
enum GPIO_WAKE_FLAG
|
|
{
|
|
GPIO_WAKE_FLAG_MCU = 0,
|
|
GPIO_WAKE_FLAG_WIFI_ON,
|
|
GPIO_WAKE_FLAG_WIFI_OFF,
|
|
GPIO_WAKE_FLAG_BT_ON,
|
|
GPIO_WAKE_FLAG_BT_OFF,
|
|
GPIO_WAKE_FLAG_BT_LP_ON,
|
|
GPIO_WAKE_FLAG_BT_LP_OFF,
|
|
GPIO_WAKE_FLAG_HOST_SUSPEND,
|
|
GPIO_WAKE_FLAG_HOST_RESUME,
|
|
GPIO_WAKE_FLAG_SDIO_RX,
|
|
GPIO_WAKE_FLAG_SDIO_PROBE,
|
|
};
|
|
|
|
struct sbus_ops {
|
|
int (*init)(struct sbus_priv *self, struct bes2600_common *core);
|
|
int (*sbus_memcpy_fromio)(struct sbus_priv *self, unsigned int addr,
|
|
void *dst, int count);
|
|
int (*sbus_memcpy_toio)(struct sbus_priv *self, unsigned int addr,
|
|
const void *src, int count);
|
|
void (*lock)(struct sbus_priv *self);
|
|
void (*unlock)(struct sbus_priv *self);
|
|
int (*irq_subscribe)(struct sbus_priv *self, sbus_irq_handler handler,
|
|
void *priv);
|
|
int (*irq_unsubscribe)(struct sbus_priv *self);
|
|
int (*reset)(struct sbus_priv *self);
|
|
size_t (*align_size)(struct sbus_priv *self, size_t size);
|
|
int (*set_block_size)(struct sbus_priv *self, size_t size);
|
|
int (*pipe_send)(struct sbus_priv *self, u8 pipe, u32 len, u8 *buf);
|
|
void * (*pipe_read)(struct sbus_priv *self);
|
|
int (*sbus_reg_read)(struct sbus_priv *self, u32 reg,
|
|
void *buf, int count);
|
|
int (*sbus_reg_write)(struct sbus_priv *self, u32 reg,
|
|
const void *buf, int count);
|
|
|
|
/* sub_system: 0 for mcu, 1 for wifi, 2 for bt, ... */
|
|
int (*sbus_active)(struct sbus_priv *self, int sub_system);
|
|
int (*sbus_deactive)(struct sbus_priv *self, int sub_system);
|
|
int (*power_switch)(struct sbus_priv *self, int on);
|
|
/* gpio wake, beacuse bes2600 sdio can't wakeup mcu, so add the two of interfaces */
|
|
void (*gpio_wake)(struct sbus_priv *self, int falg);
|
|
void (*gpio_sleep)(struct sbus_priv *self, int falg);
|
|
/* halt device to get debug information */
|
|
void (*halt_device)(struct sbus_priv *self);
|
|
bool (*wakeup_source)(struct sbus_priv *self);
|
|
int (*reboot)(struct sbus_priv *self);
|
|
/*
|
|
* Force the host bus to re-detect and re-probe the chip. Called
|
|
* from the firmware-wedge recovery path when power_switch() has no
|
|
* effective chip-reset signal of its own (e.g. PineTab2, where the
|
|
* wifi-reset GPIO is owned by sdio_pwrseq, not the bes2600 node).
|
|
* Returns 0 on success or a negative errno.
|
|
*/
|
|
int (*bus_reset)(struct sbus_priv *self);
|
|
/*
|
|
* Read a batch of RX frames inline from the bus and deliver each
|
|
* one via bes2600_bh_handle_rx_skb(). Called from the bh thread
|
|
* (process context, sleepable). Replaces the
|
|
* sdio_rx_work + rx_queue + pipe_read relay (Patch C v3, 2026).
|
|
* Returns 0 on success, negative on read error.
|
|
*/
|
|
int (*bus_rx_batch)(struct sbus_priv *self);
|
|
};
|
|
|
|
void bes2600_irq_handler(struct bes2600_common *priv);
|
|
|
|
/* This MUST be wrapped with hwbus_ops->lock/unlock! */
|
|
int __bes2600_irq_enable(int enable);
|
|
|
|
#endif /* BES2600_SBUS_H */
|