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

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

brcmfmac: replace dongle command list with .preinit() callback



The bus-specific interface allowed a list of dongle commands to be
provided to the common driver part. However, upcoming functionality
requires a more dynamic behaviour. Hence the list is replaced
by a new callback function so the bus-specific driver part can
implement this behaviour.

Reviewed-by: default avatarFranky Lin <frankyl@broadcom.com>
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 8dee77ba
Loading
Loading
Loading
Loading
+11 −1
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@ struct brcmf_bus_dcmd {
/**
/**
 * struct brcmf_bus_ops - bus callback operations.
 * struct brcmf_bus_ops - bus callback operations.
 *
 *
 * @preinit: execute bus/device specific dongle init commands (optional).
 * @init: prepare for communication with dongle.
 * @init: prepare for communication with dongle.
 * @stop: clear pending frames, disable data flow.
 * @stop: clear pending frames, disable data flow.
 * @txdata: send a data frame to the dongle. When the data
 * @txdata: send a data frame to the dongle. When the data
@@ -51,6 +52,7 @@ struct brcmf_bus_dcmd {
 * indicated otherwise these callbacks are mandatory.
 * indicated otherwise these callbacks are mandatory.
 */
 */
struct brcmf_bus_ops {
struct brcmf_bus_ops {
	int (*preinit)(struct device *dev);
	int (*init)(struct device *dev);
	int (*init)(struct device *dev);
	void (*stop)(struct device *dev);
	void (*stop)(struct device *dev);
	int (*txdata)(struct device *dev, struct sk_buff *skb);
	int (*txdata)(struct device *dev, struct sk_buff *skb);
@@ -85,7 +87,6 @@ struct brcmf_bus {
	unsigned long tx_realloc;
	unsigned long tx_realloc;
	u32 chip;
	u32 chip;
	u32 chiprev;
	u32 chiprev;
	struct list_head dcmd_list;


	struct brcmf_bus_ops *ops;
	struct brcmf_bus_ops *ops;
};
};
@@ -93,6 +94,13 @@ struct brcmf_bus {
/*
/*
 * callback wrappers
 * callback wrappers
 */
 */
static inline int brcmf_bus_preinit(struct brcmf_bus *bus)
{
	if (!bus->ops->preinit)
		return 0;
	return bus->ops->preinit(bus->dev);
}

static inline int brcmf_bus_init(struct brcmf_bus *bus)
static inline int brcmf_bus_init(struct brcmf_bus *bus)
{
{
	return bus->ops->init(bus->dev);
	return bus->ops->init(bus->dev);
@@ -151,6 +159,8 @@ void brcmf_txflowblock(struct device *dev, bool state);
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);


int brcmf_bus_start(struct device *dev);
int brcmf_bus_start(struct device *dev);
s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data,
				u32 len);
void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
void brcmf_bus_add_txhdrlen(struct device *dev, uint len);


#ifdef CONFIG_BRCMFMAC_SDIO
#ifdef CONFIG_BRCMFMAC_SDIO
+2 −13
Original line number Original line Diff line number Diff line
@@ -257,8 +257,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
	u8 buf[BRCMF_DCMD_SMLEN];
	u8 buf[BRCMF_DCMD_SMLEN];
	char *ptr;
	char *ptr;
	s32 err;
	s32 err;
	struct brcmf_bus_dcmd *cmdlst;
	struct list_head *cur, *q;


	/* retreive mac address */
	/* retreive mac address */
	err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
	err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
@@ -342,17 +340,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
	brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
	brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
					 0, true);
					 0, true);


	/* set bus specific command if there is any */
	/* do bus specific preinit here */
	list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) {
	err = brcmf_bus_preinit(ifp->drvr->bus_if);
		cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
		if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
			brcmf_fil_iovar_data_set(ifp, cmdlst->name,
						 cmdlst->param,
						 cmdlst->param_len);
		}
		list_del(cur);
		kfree(cmdlst);
	}
done:
done:
	return err;
	return err;
}
}
+8 −2
Original line number Original line Diff line number Diff line
@@ -1048,8 +1048,6 @@ int brcmf_attach(struct device *dev)
	/* attach firmware event handler */
	/* attach firmware event handler */
	brcmf_fweh_attach(drvr);
	brcmf_fweh_attach(drvr);


	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

	return ret;
	return ret;


fail:
fail:
@@ -1206,6 +1204,14 @@ void brcmf_detach(struct device *dev)
	kfree(drvr);
	kfree(drvr);
}
}


s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
{
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_if *ifp = bus_if->drvr->iflist[0];

	return brcmf_fil_iovar_data_set(ifp, name, data, len);
}

static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
{
{
	return atomic_read(&ifp->pend_8021x_cnt);
	return atomic_read(&ifp->pend_8021x_cnt);
+30 −28
Original line number Original line Diff line number Diff line
@@ -3425,6 +3425,35 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
	return ret;
	return ret;
}
}


static int brcmf_sdbrcm_bus_preinit(struct device *dev)
{
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
	struct brcmf_sdio *bus = sdiodev->bus;
	u32 value;
	u8 idx;
	int err;

	/* sdio bus core specific dcmd */
	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
	if (bus->ci->c_inf[idx].rev < 12) {
		/* for sdio core rev < 12, disable txgloming */
		value = 0;
		err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
					   sizeof(u32));
	} else {
		/* otherwise, set txglomalign */
		value = 4;
		if (sdiodev->pdata)
			value = sdiodev->pdata->sd_sgentry_align;
		/* SDIO ADMA requires at least 32 bit alignment */
		value = max_t(u32, value, 4);
		err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
					   sizeof(u32));
	}
	return err;
}

static int brcmf_sdbrcm_bus_init(struct device *dev)
static int brcmf_sdbrcm_bus_init(struct device *dev)
{
{
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -3905,6 +3934,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)


static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
	.stop = brcmf_sdbrcm_bus_stop,
	.stop = brcmf_sdbrcm_bus_stop,
	.preinit = brcmf_sdbrcm_bus_preinit,
	.init = brcmf_sdbrcm_bus_init,
	.init = brcmf_sdbrcm_bus_init,
	.txdata = brcmf_sdbrcm_bus_txdata,
	.txdata = brcmf_sdbrcm_bus_txdata,
	.txctl = brcmf_sdbrcm_bus_txctl,
	.txctl = brcmf_sdbrcm_bus_txctl,
@@ -3916,10 +3946,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
{
{
	int ret;
	int ret;
	struct brcmf_sdio *bus;
	struct brcmf_sdio *bus;
	struct brcmf_bus_dcmd *dlst;
	u32 dngl_txglom;
	u32 txglomalign = 0;
	u8 idx;


	brcmf_dbg(TRACE, "Enter\n");
	brcmf_dbg(TRACE, "Enter\n");


@@ -4003,30 +4029,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
	brcmf_sdio_debugfs_create(bus);
	brcmf_sdio_debugfs_create(bus);
	brcmf_dbg(INFO, "completed!!\n");
	brcmf_dbg(INFO, "completed!!\n");


	/* sdio bus core specific dcmd */
	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
	dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
	if (dlst) {
		if (bus->ci->c_inf[idx].rev < 12) {
			/* for sdio core rev < 12, disable txgloming */
			dngl_txglom = 0;
			dlst->name = "bus:txglom";
			dlst->param = (char *)&dngl_txglom;
			dlst->param_len = sizeof(u32);
		} else {
			/* otherwise, set txglomalign */
			if (sdiodev->pdata)
				txglomalign = sdiodev->pdata->sd_sgentry_align;
			/* SDIO ADMA requires at least 32 bit alignment */
			if (txglomalign < 4)
				txglomalign = 4;
			dlst->name = "bus:txglomalign";
			dlst->param = (char *)&txglomalign;
			dlst->param_len = sizeof(u32);
		}
		list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
	}

	brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
	brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);


	/* if firmware path present try to download and bring up bus */
	/* if firmware path present try to download and bring up bus */