Skip to content

Commit dcb485d

Browse files
WenChieh-FengKalle Valo
authored andcommitted
brcmfmac: add a timer to read console periodically in PCIE bus
Currently, host only reads console buffer when receiving mailbox data or hit crash with PCIE bus. Therefore, we add timer in PCIE code to read console buffer periodically to help developer and user check firmware message when there is no data transmission between host and dongle. Signed-off-by: Wright Feng <wright.feng@cypress.com> Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com> Signed-off-by: Ian Lin <ian.lin@infineon.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220929031001.9962-2-ian.lin@infineon.com
1 parent 62ccb2e commit dcb485d

File tree

3 files changed

+131
-2
lines changed

3 files changed

+131
-2
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
#define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \
2525
BRCMF_NROF_D2H_COMMON_MSGRINGS)
2626

27+
/* The interval to poll console */
28+
#define BRCMF_CONSOLE 10
29+
30+
/* The maximum console interval value (5 mins) */
31+
#define MAX_CONSOLE_INTERVAL (5 * 60)
32+
2733
/* The level of bus communication with the dongle */
2834
enum brcmf_bus_state {
2935
BRCMF_BUS_DOWN, /* Not ready for frame transfers */

drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <linux/interrupt.h>
1313
#include <linux/bcma/bcma.h>
1414
#include <linux/sched.h>
15+
#include <linux/sched/signal.h>
16+
#include <linux/kthread.h>
1517
#include <linux/io.h>
1618
#include <asm/unaligned.h>
1719

@@ -340,6 +342,11 @@ struct brcmf_pciedev_info {
340342
u16 value);
341343
struct brcmf_mp_device *settings;
342344
struct brcmf_otp_params otp;
345+
#ifdef DEBUG
346+
u32 console_interval;
347+
bool console_active;
348+
struct timer_list timer;
349+
#endif
343350
};
344351

345352
struct brcmf_pcie_ringbuf {
@@ -440,6 +447,9 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
440447
struct brcmf_fw_request *fwreq);
441448
static struct brcmf_fw_request *
442449
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo);
450+
static void
451+
brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active);
452+
static void brcmf_pcie_debugfs_create(struct device *dev);
443453

444454
static u16
445455
brcmf_pcie_read_reg16(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
@@ -1413,6 +1423,11 @@ static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
14131423

14141424
static void brcmf_pcie_down(struct device *dev)
14151425
{
1426+
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1427+
struct brcmf_pciedev *pcie_bus_dev = bus_if->bus_priv.pcie;
1428+
struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
1429+
1430+
brcmf_pcie_fwcon_timer(devinfo, false);
14161431
}
14171432

14181433
static int brcmf_pcie_preinit(struct device *dev)
@@ -1547,6 +1562,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
15471562
.get_memdump = brcmf_pcie_get_memdump,
15481563
.get_blob = brcmf_pcie_get_blob,
15491564
.reset = brcmf_pcie_reset,
1565+
.debugfs_create = brcmf_pcie_debugfs_create,
15501566
};
15511567

15521568

@@ -2123,6 +2139,8 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
21232139

21242140
brcmf_pcie_bus_console_read(devinfo, false);
21252141

2142+
brcmf_pcie_fwcon_timer(devinfo, true);
2143+
21262144
return;
21272145

21282146
fail:
@@ -2197,6 +2215,105 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
21972215
return fwreq;
21982216
}
21992217

2218+
#ifdef DEBUG
2219+
static void
2220+
brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active)
2221+
{
2222+
if (!active) {
2223+
if (devinfo->console_active) {
2224+
del_timer_sync(&devinfo->timer);
2225+
devinfo->console_active = false;
2226+
}
2227+
return;
2228+
}
2229+
2230+
/* don't start the timer */
2231+
if (devinfo->state != BRCMFMAC_PCIE_STATE_UP ||
2232+
!devinfo->console_interval || !BRCMF_FWCON_ON())
2233+
return;
2234+
2235+
if (!devinfo->console_active) {
2236+
devinfo->timer.expires = jiffies + devinfo->console_interval;
2237+
add_timer(&devinfo->timer);
2238+
devinfo->console_active = true;
2239+
} else {
2240+
/* Reschedule the timer */
2241+
mod_timer(&devinfo->timer, jiffies + devinfo->console_interval);
2242+
}
2243+
}
2244+
2245+
static void
2246+
brcmf_pcie_fwcon(struct timer_list *t)
2247+
{
2248+
struct brcmf_pciedev_info *devinfo = from_timer(devinfo, t, timer);
2249+
2250+
if (!devinfo->console_active)
2251+
return;
2252+
2253+
brcmf_pcie_bus_console_read(devinfo, false);
2254+
2255+
/* Reschedule the timer if console interval is not zero */
2256+
mod_timer(&devinfo->timer, jiffies + devinfo->console_interval);
2257+
}
2258+
2259+
static int brcmf_pcie_console_interval_get(void *data, u64 *val)
2260+
{
2261+
struct brcmf_pciedev_info *devinfo = data;
2262+
2263+
*val = devinfo->console_interval;
2264+
2265+
return 0;
2266+
}
2267+
2268+
static int brcmf_pcie_console_interval_set(void *data, u64 val)
2269+
{
2270+
struct brcmf_pciedev_info *devinfo = data;
2271+
2272+
if (val > MAX_CONSOLE_INTERVAL)
2273+
return -EINVAL;
2274+
2275+
devinfo->console_interval = val;
2276+
2277+
if (!val && devinfo->console_active)
2278+
brcmf_pcie_fwcon_timer(devinfo, false);
2279+
else if (val)
2280+
brcmf_pcie_fwcon_timer(devinfo, true);
2281+
2282+
return 0;
2283+
}
2284+
2285+
DEFINE_SIMPLE_ATTRIBUTE(brcmf_pcie_console_interval_fops,
2286+
brcmf_pcie_console_interval_get,
2287+
brcmf_pcie_console_interval_set,
2288+
"%llu\n");
2289+
2290+
static void brcmf_pcie_debugfs_create(struct device *dev)
2291+
{
2292+
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2293+
struct brcmf_pub *drvr = bus_if->drvr;
2294+
struct brcmf_pciedev *pcie_bus_dev = bus_if->bus_priv.pcie;
2295+
struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
2296+
struct dentry *dentry = brcmf_debugfs_get_devdir(drvr);
2297+
2298+
if (IS_ERR_OR_NULL(dentry))
2299+
return;
2300+
2301+
devinfo->console_interval = BRCMF_CONSOLE;
2302+
2303+
debugfs_create_file("console_interval", 0644, dentry, devinfo,
2304+
&brcmf_pcie_console_interval_fops);
2305+
}
2306+
2307+
#else
2308+
void brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active)
2309+
{
2310+
}
2311+
2312+
static void brcmf_pcie_debugfs_create(struct device *dev)
2313+
{
2314+
}
2315+
#endif
2316+
22002317
static int
22012318
brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
22022319
{
@@ -2278,6 +2395,11 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
22782395
goto fail_brcmf;
22792396
}
22802397

2398+
#ifdef DEBUG
2399+
/* Set up the fwcon timer */
2400+
timer_setup(&devinfo->timer, brcmf_pcie_fwcon, 0);
2401+
#endif
2402+
22812403
fwreq = brcmf_pcie_prepare_fw_request(devinfo);
22822404
if (!fwreq) {
22832405
ret = -ENOMEM;
@@ -2323,6 +2445,7 @@ brcmf_pcie_remove(struct pci_dev *pdev)
23232445

23242446
devinfo = bus->bus_priv.pcie->devinfo;
23252447
brcmf_pcie_bus_console_read(devinfo, false);
2448+
brcmf_pcie_fwcon_timer(devinfo, false);
23262449

23272450
devinfo->state = BRCMFMAC_PCIE_STATE_DOWN;
23282451
if (devinfo->ci)
@@ -2366,6 +2489,7 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
23662489
bus = dev_get_drvdata(dev);
23672490
devinfo = bus->bus_priv.pcie->devinfo;
23682491

2492+
brcmf_pcie_fwcon_timer(devinfo, false);
23692493
brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
23702494

23712495
devinfo->mbdata_completed = false;
@@ -2409,6 +2533,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
24092533
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
24102534
brcmf_pcie_intr_enable(devinfo);
24112535
brcmf_pcie_hostready(devinfo);
2536+
brcmf_pcie_fwcon_timer(devinfo, true);
24122537
return 0;
24132538
}
24142539

drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,6 @@ struct rte_console {
135135

136136
#define BRCMF_FIRSTREAD (1 << 6)
137137

138-
#define BRCMF_CONSOLE 10 /* watchdog interval to poll console */
139-
140138
/* SBSDIO_DEVICE_CTL */
141139

142140
/* 1: device will assert busy signal when receiving CMD53 */

0 commit comments

Comments
 (0)