brcmfmac: rework bus interface
Rework the bus interface between common driver part and bus-specific driver part. It prepares for adding tracing in bus-specific callback functions. Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
9e2ff36bea
commit
d9cb259650
9 changed files with 111 additions and 47 deletions
|
@ -470,7 +470,6 @@ struct brcmf_pub {
|
||||||
struct brcmf_bus *bus_if;
|
struct brcmf_bus *bus_if;
|
||||||
struct brcmf_proto *prot;
|
struct brcmf_proto *prot;
|
||||||
struct brcmf_cfg80211_info *config;
|
struct brcmf_cfg80211_info *config;
|
||||||
struct device *dev; /* fullmac dongle device pointer */
|
|
||||||
|
|
||||||
/* Internal brcmf items */
|
/* Internal brcmf items */
|
||||||
uint hdrlen; /* Total BRCMF header length (proto + bus) */
|
uint hdrlen; /* Total BRCMF header length (proto + bus) */
|
||||||
|
|
|
@ -43,35 +43,89 @@ struct brcmf_bus_dcmd {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* interface structure between common and bus layer */
|
/**
|
||||||
|
* struct brcmf_bus_ops - bus callback operations.
|
||||||
|
*
|
||||||
|
* @init: prepare for communication with dongle.
|
||||||
|
* @stop: clear pending frames, disable data flow.
|
||||||
|
* @txdata: send a data frame to the dongle (callee disposes skb).
|
||||||
|
* @txctl: transmit a control request message to dongle.
|
||||||
|
* @rxctl: receive a control response message from dongle.
|
||||||
|
*
|
||||||
|
* This structure provides an abstract interface towards the
|
||||||
|
* bus specific driver. For control messages to common driver
|
||||||
|
* will assure there is only one active transaction.
|
||||||
|
*/
|
||||||
|
struct brcmf_bus_ops {
|
||||||
|
int (*init)(struct device *dev);
|
||||||
|
void (*stop)(struct device *dev);
|
||||||
|
int (*txdata)(struct device *dev, struct sk_buff *skb);
|
||||||
|
int (*txctl)(struct device *dev, unsigned char *msg, uint len);
|
||||||
|
int (*rxctl)(struct device *dev, unsigned char *msg, uint len);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct brcmf_bus - interface structure between common and bus layer
|
||||||
|
*
|
||||||
|
* @bus_priv: pointer to private bus device.
|
||||||
|
* @dev: device pointer of bus device.
|
||||||
|
* @drvr: public driver information.
|
||||||
|
* @state: operational state of the bus interface.
|
||||||
|
* @maxctl: maximum size for rxctl request message.
|
||||||
|
* @drvr_up: indicates driver up/down status.
|
||||||
|
* @tx_realloc: number of tx packets realloced for headroom.
|
||||||
|
* @dstats: dongle-based statistical data.
|
||||||
|
* @align: alignment requirement for the bus.
|
||||||
|
* @dcmd_list: bus/device specific dongle initialization commands.
|
||||||
|
*/
|
||||||
struct brcmf_bus {
|
struct brcmf_bus {
|
||||||
union {
|
union {
|
||||||
struct brcmf_sdio_dev *sdio;
|
struct brcmf_sdio_dev *sdio;
|
||||||
struct brcmf_usbdev *usb;
|
struct brcmf_usbdev *usb;
|
||||||
} bus_priv;
|
} bus_priv;
|
||||||
struct brcmf_pub *drvr; /* pointer to driver pub structure brcmf_pub */
|
struct device *dev;
|
||||||
|
struct brcmf_pub *drvr;
|
||||||
enum brcmf_bus_state state;
|
enum brcmf_bus_state state;
|
||||||
uint maxctl; /* Max size rxctl request from proto to bus */
|
uint maxctl;
|
||||||
bool drvr_up; /* Status flag of driver up/down */
|
bool drvr_up;
|
||||||
unsigned long tx_realloc; /* Tx packets realloced for headroom */
|
unsigned long tx_realloc;
|
||||||
struct dngl_stats dstats; /* Stats for dongle-based data */
|
struct dngl_stats dstats;
|
||||||
u8 align; /* bus alignment requirement */
|
u8 align;
|
||||||
struct list_head dcmd_list;
|
struct list_head dcmd_list;
|
||||||
|
|
||||||
/* interface functions pointers */
|
struct brcmf_bus_ops *ops;
|
||||||
/* Stop bus module: clear pending frames, disable data flow */
|
|
||||||
void (*brcmf_bus_stop)(struct device *);
|
|
||||||
/* Initialize bus module: prepare for communication w/dongle */
|
|
||||||
int (*brcmf_bus_init)(struct device *);
|
|
||||||
/* Send a data frame to the dongle. Callee disposes of txp. */
|
|
||||||
int (*brcmf_bus_txdata)(struct device *, struct sk_buff *);
|
|
||||||
/* Send/receive a control message to/from the dongle.
|
|
||||||
* Expects caller to enforce a single outstanding transaction.
|
|
||||||
*/
|
|
||||||
int (*brcmf_bus_txctl)(struct device *, unsigned char *, uint);
|
|
||||||
int (*brcmf_bus_rxctl)(struct device *, unsigned char *, uint);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* callback wrappers
|
||||||
|
*/
|
||||||
|
static inline int brcmf_bus_init(struct brcmf_bus *bus)
|
||||||
|
{
|
||||||
|
return bus->ops->init(bus->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void brcmf_bus_stop(struct brcmf_bus *bus)
|
||||||
|
{
|
||||||
|
bus->ops->stop(bus->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int brcmf_bus_txdata(struct brcmf_bus *bus, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return bus->ops->txdata(bus->dev, skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int brcmf_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint len)
|
||||||
|
{
|
||||||
|
return bus->ops->txctl(bus->dev, msg, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int brcmf_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint len)
|
||||||
|
{
|
||||||
|
return bus->ops->rxctl(bus->dev, msg, len);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* interface functions from common layer
|
* interface functions from common layer
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -117,9 +117,7 @@ static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
|
||||||
len = CDC_MAX_MSG_SIZE;
|
len = CDC_MAX_MSG_SIZE;
|
||||||
|
|
||||||
/* Send request */
|
/* Send request */
|
||||||
return drvr->bus_if->brcmf_bus_txctl(drvr->dev,
|
return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len);
|
||||||
(unsigned char *)&prot->msg,
|
|
||||||
len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
|
static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
|
||||||
|
@ -128,11 +126,10 @@ static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
|
||||||
struct brcmf_proto *prot = drvr->prot;
|
struct brcmf_proto *prot = drvr->prot;
|
||||||
|
|
||||||
brcmf_dbg(TRACE, "Enter\n");
|
brcmf_dbg(TRACE, "Enter\n");
|
||||||
|
len += sizeof(struct brcmf_proto_cdc_dcmd);
|
||||||
do {
|
do {
|
||||||
ret = drvr->bus_if->brcmf_bus_rxctl(drvr->dev,
|
ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg,
|
||||||
(unsigned char *)&prot->msg,
|
len);
|
||||||
len + sizeof(struct brcmf_proto_cdc_dcmd));
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
} while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
|
} while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <brcmu_wifi.h>
|
#include <brcmu_wifi.h>
|
||||||
#include <brcmu_utils.h>
|
#include <brcmu_utils.h>
|
||||||
#include "dhd.h"
|
#include "dhd.h"
|
||||||
|
#include "dhd_bus.h"
|
||||||
#include "dhd_dbg.h"
|
#include "dhd_dbg.h"
|
||||||
|
|
||||||
static struct dentry *root_folder;
|
static struct dentry *root_folder;
|
||||||
|
@ -42,10 +43,12 @@ void brcmf_debugfs_exit(void)
|
||||||
|
|
||||||
int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
||||||
{
|
{
|
||||||
|
struct device *dev = drvr->bus_if->dev;
|
||||||
|
|
||||||
if (!root_folder)
|
if (!root_folder)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
drvr->dbgfs_dir = debugfs_create_dir(dev_name(drvr->dev), root_folder);
|
drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
|
||||||
return PTR_RET(drvr->dbgfs_dir);
|
return PTR_RET(drvr->dbgfs_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||||
brcmf_proto_hdrpush(drvr, ifp->idx, skb);
|
brcmf_proto_hdrpush(drvr, ifp->idx, skb);
|
||||||
|
|
||||||
/* Use bus module to send data frame */
|
/* Use bus module to send data frame */
|
||||||
ret = drvr->bus_if->brcmf_bus_txdata(drvr->dev, skb);
|
ret = brcmf_bus_txdata(drvr->bus_if, skb);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -397,7 +397,7 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
|
||||||
|
|
||||||
sprintf(info->driver, KBUILD_MODNAME);
|
sprintf(info->driver, KBUILD_MODNAME);
|
||||||
sprintf(info->version, "%lu", drvr->drv_version);
|
sprintf(info->version, "%lu", drvr->drv_version);
|
||||||
sprintf(info->bus_info, "%s", dev_name(drvr->dev));
|
sprintf(info->bus_info, "%s", dev_name(drvr->bus_if->dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ethtool_ops brcmf_ethtool_ops = {
|
static const struct ethtool_ops brcmf_ethtool_ops = {
|
||||||
|
@ -753,7 +753,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
|
||||||
drvr->hdrlen = bus_hdrlen;
|
drvr->hdrlen = bus_hdrlen;
|
||||||
drvr->bus_if = dev_get_drvdata(dev);
|
drvr->bus_if = dev_get_drvdata(dev);
|
||||||
drvr->bus_if->drvr = drvr;
|
drvr->bus_if->drvr = drvr;
|
||||||
drvr->dev = dev;
|
|
||||||
|
|
||||||
/* create device debugfs folder */
|
/* create device debugfs folder */
|
||||||
brcmf_debugfs_attach(drvr);
|
brcmf_debugfs_attach(drvr);
|
||||||
|
@ -790,7 +789,7 @@ int brcmf_bus_start(struct device *dev)
|
||||||
brcmf_dbg(TRACE, "\n");
|
brcmf_dbg(TRACE, "\n");
|
||||||
|
|
||||||
/* Bring up the bus */
|
/* Bring up the bus */
|
||||||
ret = bus_if->brcmf_bus_init(dev);
|
ret = brcmf_bus_init(bus_if);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
|
brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -809,7 +808,7 @@ int brcmf_bus_start(struct device *dev)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
drvr->config = brcmf_cfg80211_attach(drvr);
|
drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
|
||||||
if (drvr->config == NULL) {
|
if (drvr->config == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -842,7 +841,7 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr)
|
||||||
brcmf_proto_stop(drvr);
|
brcmf_proto_stop(drvr);
|
||||||
|
|
||||||
/* Stop the bus module */
|
/* Stop the bus module */
|
||||||
drvr->bus_if->brcmf_bus_stop(drvr->dev);
|
brcmf_bus_stop(drvr->bus_if);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3883,6 +3883,14 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
|
||||||
brcmf_dbg(TRACE, "Disconnected\n");
|
brcmf_dbg(TRACE, "Disconnected\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
|
||||||
|
.stop = brcmf_sdbrcm_bus_stop,
|
||||||
|
.init = brcmf_sdbrcm_bus_init,
|
||||||
|
.txdata = brcmf_sdbrcm_bus_txdata,
|
||||||
|
.txctl = brcmf_sdbrcm_bus_txctl,
|
||||||
|
.rxctl = brcmf_sdbrcm_bus_rxctl,
|
||||||
|
};
|
||||||
|
|
||||||
void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -3946,11 +3954,9 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||||
spin_lock_init(&bus->dpc_tl_lock);
|
spin_lock_init(&bus->dpc_tl_lock);
|
||||||
|
|
||||||
/* Assign bus interface call back */
|
/* Assign bus interface call back */
|
||||||
bus->sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop;
|
bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
|
||||||
bus->sdiodev->bus_if->brcmf_bus_init = brcmf_sdbrcm_bus_init;
|
bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops;
|
||||||
bus->sdiodev->bus_if->brcmf_bus_txdata = brcmf_sdbrcm_bus_txdata;
|
|
||||||
bus->sdiodev->bus_if->brcmf_bus_txctl = brcmf_sdbrcm_bus_txctl;
|
|
||||||
bus->sdiodev->bus_if->brcmf_bus_rxctl = brcmf_sdbrcm_bus_rxctl;
|
|
||||||
/* Attach to the brcmf/OS/network interface */
|
/* Attach to the brcmf/OS/network interface */
|
||||||
ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
|
ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
|
|
@ -1228,6 +1228,14 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct brcmf_bus_ops brcmf_usb_bus_ops = {
|
||||||
|
.txdata = brcmf_usb_tx,
|
||||||
|
.init = brcmf_usb_up,
|
||||||
|
.stop = brcmf_usb_down,
|
||||||
|
.txctl = brcmf_usb_tx_ctlpkt,
|
||||||
|
.rxctl = brcmf_usb_rx_ctlpkt,
|
||||||
|
};
|
||||||
|
|
||||||
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
|
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
|
||||||
{
|
{
|
||||||
struct brcmf_bus *bus = NULL;
|
struct brcmf_bus *bus = NULL;
|
||||||
|
@ -1246,14 +1254,11 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bus->dev = dev;
|
||||||
bus_pub->bus = bus;
|
bus_pub->bus = bus;
|
||||||
bus->brcmf_bus_txdata = brcmf_usb_tx;
|
|
||||||
bus->brcmf_bus_init = brcmf_usb_up;
|
|
||||||
bus->brcmf_bus_stop = brcmf_usb_down;
|
|
||||||
bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt;
|
|
||||||
bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt;
|
|
||||||
bus->bus_priv.usb = bus_pub;
|
bus->bus_priv.usb = bus_pub;
|
||||||
dev_set_drvdata(dev, bus);
|
dev_set_drvdata(dev, bus);
|
||||||
|
bus->ops = &brcmf_usb_bus_ops;
|
||||||
|
|
||||||
/* Attach to the common driver interface */
|
/* Attach to the common driver interface */
|
||||||
ret = brcmf_attach(0, dev);
|
ret = brcmf_attach(0, dev);
|
||||||
|
|
|
@ -4271,10 +4271,10 @@ static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
|
||||||
brcmf_deinit_priv_mem(cfg);
|
brcmf_deinit_priv_mem(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr)
|
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
||||||
|
struct device *busdev)
|
||||||
{
|
{
|
||||||
struct net_device *ndev = drvr->iflist[0]->ndev;
|
struct net_device *ndev = drvr->iflist[0]->ndev;
|
||||||
struct device *busdev = drvr->dev;
|
|
||||||
struct brcmf_cfg80211_info *cfg;
|
struct brcmf_cfg80211_info *cfg;
|
||||||
struct wiphy *wiphy;
|
struct wiphy *wiphy;
|
||||||
struct brcmf_cfg80211_vif *vif;
|
struct brcmf_cfg80211_vif *vif;
|
||||||
|
|
|
@ -450,7 +450,8 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
|
||||||
return &cfg->conn_info;
|
return &cfg->conn_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr);
|
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
||||||
|
struct device *busdev);
|
||||||
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
|
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
|
||||||
s32 brcmf_cfg80211_up(struct net_device *ndev);
|
s32 brcmf_cfg80211_up(struct net_device *ndev);
|
||||||
s32 brcmf_cfg80211_down(struct net_device *ndev);
|
s32 brcmf_cfg80211_down(struct net_device *ndev);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue