Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 349e7104 authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville
Browse files

brcmfmac: add support for TLV based firmware signalling



The firmware and host can exchange signals which are carried within
the data packets. These are TLV based signals that are inserted
before the actual data, ie. ethernet frame.

This commit adds the new source module for this feature and enables
RSSI signals from firmware.

Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent edee1668
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ brcmfmac-objs += \
		wl_cfg80211.o \
		fwil.o \
		fweh.o \
		fwsignal.o \
		p2p.o \
		dhd_cdc.o \
		dhd_common.o \
+6 −1
Original line number Diff line number Diff line
@@ -501,6 +501,7 @@ struct brcmf_dcmd {
/* Forward decls for struct brcmf_pub (see below) */
struct brcmf_proto;	/* device communication protocol info */
struct brcmf_cfg80211_dev; /* cfg80211 device info */
struct brcmf_fws_info; /* firmware signalling info */

/* Common structure for module and instance linkage */
struct brcmf_pub {
@@ -527,6 +528,10 @@ struct brcmf_pub {
	unsigned char proto_buf[BRCMF_DCMD_MAXLEN];

	struct brcmf_fweh_info fweh;

	bool fw_signals;
	struct brcmf_fws_info *fws;
	spinlock_t fws_spinlock;
#ifdef DEBUG
	struct dentry *dbgfs_dir;
#endif
@@ -582,7 +587,7 @@ extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
				    void *buf, uint len);

/* Remove any protocol-specific data header. */
extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
			       struct sk_buff *rxp);

extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
+6 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include "dhd.h"
#include "dhd_proto.h"
#include "dhd_bus.h"
#include "fwsignal.h"
#include "dhd_dbg.h"

struct brcmf_proto_cdc_dcmd {
@@ -294,7 +295,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
	BDC_SET_IF_IDX(h, ifidx);
}

int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
			struct sk_buff *pktbuf)
{
	struct brcmf_proto_bdc_header *h;
@@ -341,6 +342,9 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
	pktbuf->priority = h->priority & BDC_PRIORITY_MASK;

	skb_pull(pktbuf, BDC_HEADER_LEN);
	if (do_fws)
		brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
	else
		skb_pull(pktbuf, h->data_offset << 2);

	if (pktbuf->len == 0)
+41 −0
Original line number Diff line number Diff line
@@ -124,3 +124,44 @@ void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
		debugfs_create_file("counters", S_IRUGO, dentry,
				    sdcnt, &brcmf_debugfs_sdio_counter_ops);
}

static
ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
				     size_t count, loff_t *ppos)
{
	struct brcmf_fws_stats *fwstats = f->private_data;
	char buf[100];
	int res;

	/* only allow read from start */
	if (*ppos > 0)
		return 0;

	res = scnprintf(buf, sizeof(buf),
			"header_pulls:     %u\n"
			"header_only_pkt:  %u\n"
			"tlv_parse_failed: %u\n"
			"tlv_invalid_type: %u\n",
			fwstats->header_pulls,
			fwstats->header_only_pkt,
			fwstats->tlv_parse_failed,
			fwstats->tlv_invalid_type);

	return simple_read_from_buffer(data, count, ppos, buf, res);
}

static const struct file_operations brcmf_debugfs_fws_stats_ops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = brcmf_debugfs_fws_stats_read
};

void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
				    struct brcmf_fws_stats *stats)
{
	struct dentry *dentry =  drvr->dbgfs_dir;

	if (!IS_ERR_OR_NULL(dentry))
		debugfs_create_file("fws_stats", S_IRUGO, dentry,
				    stats, &brcmf_debugfs_fws_stats_ops);
}
+13 −0
Original line number Diff line number Diff line
@@ -132,6 +132,13 @@ struct brcmf_sdio_count {
	ulong rx_readahead_cnt;	/* packets where header read-ahead was used */
};

struct brcmf_fws_stats {
	u32 tlv_parse_failed;
	u32 tlv_invalid_type;
	u32 header_only_pkt;
	u32 header_pulls;
};

struct brcmf_pub;
#ifdef DEBUG
void brcmf_debugfs_init(void);
@@ -141,6 +148,8 @@ void brcmf_debugfs_detach(struct brcmf_pub *drvr);
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
				     struct brcmf_sdio_count *sdcnt);
void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
				    struct brcmf_fws_stats *stats);
#else
static inline void brcmf_debugfs_init(void)
{
@@ -155,6 +164,10 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
{
}
static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
						  struct brcmf_fws_stats *stats)
{
}
#endif

#endif				/* _BRCMF_DBG_H_ */
Loading