brintos

brintos / linux-shallow public Read only

0
0
Text · 31.9 KiB · d352623 Raw
1258 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (c) 2010 Broadcom Corporation4 */5/* ****************** SDIO CARD Interface Functions **************************/6 7#include <linux/types.h>8#include <linux/netdevice.h>9#include <linux/pci.h>10#include <linux/pci_ids.h>11#include <linux/sched.h>12#include <linux/completion.h>13#include <linux/interrupt.h>14#include <linux/scatterlist.h>15#include <linux/mmc/sdio.h>16#include <linux/mmc/core.h>17#include <linux/mmc/sdio_func.h>18#include <linux/mmc/card.h>19#include <linux/mmc/host.h>20#include <linux/pm_runtime.h>21#include <linux/suspend.h>22#include <linux/errno.h>23#include <linux/module.h>24#include <linux/acpi.h>25#include <net/cfg80211.h>26 27#include <defs.h>28#include <brcm_hw_ids.h>29#include <brcmu_utils.h>30#include <brcmu_wifi.h>31#include <chipcommon.h>32#include <soc.h>33#include "chip.h"34#include "bus.h"35#include "debug.h"36#include "sdio.h"37#include "core.h"38#include "common.h"39 40#define SDIOH_API_ACCESS_RETRY_LIMIT	241 42#define DMA_ALIGN_MASK	0x0343 44#define SDIO_FUNC1_BLOCKSIZE		6445#define SDIO_FUNC2_BLOCKSIZE		51246#define SDIO_4373_FUNC2_BLOCKSIZE	25647#define SDIO_435X_FUNC2_BLOCKSIZE	25648#define SDIO_4329_FUNC2_BLOCKSIZE	12849/* Maximum milliseconds to wait for F2 to come up */50#define SDIO_WAIT_F2RDY	300051 52#define BRCMF_DEFAULT_RXGLOM_SIZE	32  /* max rx frames in glom chain */53 54struct brcmf_sdiod_freezer {55	atomic_t freezing;56	atomic_t thread_count;57	u32 frozen_count;58	wait_queue_head_t thread_freeze;59	struct completion resumed;60};61 62static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)63{64	struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);65	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;66 67	brcmf_dbg(INTR, "OOB intr triggered\n");68 69	/* out-of-band interrupt is level-triggered which won't70	 * be cleared until dpc71	 */72	if (sdiodev->irq_en) {73		disable_irq_nosync(irq);74		sdiodev->irq_en = false;75	}76 77	brcmf_sdio_isr(sdiodev->bus, true);78 79	return IRQ_HANDLED;80}81 82static void brcmf_sdiod_ib_irqhandler(struct sdio_func *func)83{84	struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);85	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;86 87	brcmf_dbg(INTR, "IB intr triggered\n");88 89	brcmf_sdio_isr(sdiodev->bus, false);90}91 92/* dummy handler for SDIO function 2 interrupt */93static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func)94{95}96 97int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)98{99	struct brcmfmac_sdio_pd *pdata;100	int ret = 0;101	u8 data;102	u32 addr, gpiocontrol;103 104	pdata = &sdiodev->settings->bus.sdio;105	if (pdata->oob_irq_supported) {106		brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",107			  pdata->oob_irq_nr);108		spin_lock_init(&sdiodev->irq_en_lock);109		sdiodev->irq_en = true;110 111		ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,112				  pdata->oob_irq_flags, "brcmf_oob_intr",113				  &sdiodev->func1->dev);114		if (ret != 0) {115			brcmf_err("request_irq failed %d\n", ret);116			return ret;117		}118		sdiodev->oob_irq_requested = true;119 120		ret = enable_irq_wake(pdata->oob_irq_nr);121		if (ret != 0) {122			brcmf_err("enable_irq_wake failed %d\n", ret);123			return ret;124		}125		disable_irq_wake(pdata->oob_irq_nr);126 127		sdio_claim_host(sdiodev->func1);128 129		if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {130			/* assign GPIO to SDIO core */131			addr = brcmf_chip_enum_base(sdiodev->func1->device);132			addr = CORE_CC_REG(addr, gpiocontrol);133			gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret);134			gpiocontrol |= 0x2;135			brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret);136 137			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT,138					   0xf, &ret);139			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);140			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);141		}142 143		/* must configure SDIO_CCCR_IENx to enable irq */144		data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret);145		data |= SDIO_CCCR_IEN_FUNC1 | SDIO_CCCR_IEN_FUNC2 |146			SDIO_CCCR_IEN_FUNC0;147		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);148 149		/* redirect, configure and enable io for interrupt signal */150		data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE;151		if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)152			data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI;153		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT,154				     data, &ret);155		sdio_release_host(sdiodev->func1);156	} else {157		brcmf_dbg(SDIO, "Entering\n");158		sdio_claim_host(sdiodev->func1);159		sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler);160		sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler);161		sdio_release_host(sdiodev->func1);162		sdiodev->sd_irq_requested = true;163	}164 165	return 0;166}167 168void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)169{170 171	brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",172		  sdiodev->oob_irq_requested,173		  sdiodev->sd_irq_requested);174 175	if (sdiodev->oob_irq_requested) {176		struct brcmfmac_sdio_pd *pdata;177 178		pdata = &sdiodev->settings->bus.sdio;179		sdio_claim_host(sdiodev->func1);180		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);181		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL);182		sdio_release_host(sdiodev->func1);183 184		sdiodev->oob_irq_requested = false;185		free_irq(pdata->oob_irq_nr, &sdiodev->func1->dev);186		sdiodev->irq_en = false;187		sdiodev->oob_irq_requested = false;188	}189 190	if (sdiodev->sd_irq_requested) {191		sdio_claim_host(sdiodev->func1);192		sdio_release_irq(sdiodev->func2);193		sdio_release_irq(sdiodev->func1);194		sdio_release_host(sdiodev->func1);195		sdiodev->sd_irq_requested = false;196	}197}198 199void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,200			      enum brcmf_sdiod_state state)201{202	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||203	    state == sdiodev->state)204		return;205 206	brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);207	switch (sdiodev->state) {208	case BRCMF_SDIOD_DATA:209		/* any other state means bus interface is down */210		brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);211		break;212	case BRCMF_SDIOD_DOWN:213		/* transition from DOWN to DATA means bus interface is up */214		if (state == BRCMF_SDIOD_DATA)215			brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP);216		break;217	default:218		break;219	}220	sdiodev->state = state;221}222 223static int brcmf_sdiod_set_backplane_window(struct brcmf_sdio_dev *sdiodev,224					    u32 addr)225{226	u32 v, bar0 = addr & SBSDIO_SBWINDOW_MASK;227	int err = 0, i;228 229	if (bar0 == sdiodev->sbwad)230		return 0;231 232	v = bar0 >> 8;233 234	for (i = 0 ; i < 3 && !err ; i++, v >>= 8)235		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,236				   v & 0xff, &err);237 238	if (!err)239		sdiodev->sbwad = bar0;240 241	return err;242}243 244u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)245{246	u32 data = 0;247	int retval;248 249	retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);250	if (retval)251		goto out;252 253	addr &= SBSDIO_SB_OFT_ADDR_MASK;254	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;255 256	data = sdio_readl(sdiodev->func1, addr, &retval);257 258out:259	if (ret)260		*ret = retval;261 262	return data;263}264 265void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr,266			u32 data, int *ret)267{268	int retval;269 270	retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);271	if (retval)272		goto out;273 274	addr &= SBSDIO_SB_OFT_ADDR_MASK;275	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;276 277	sdio_writel(sdiodev->func1, data, addr, &retval);278 279out:280	if (ret)281		*ret = retval;282}283 284static int brcmf_sdiod_skbuff_read(struct brcmf_sdio_dev *sdiodev,285				   struct sdio_func *func, u32 addr,286				   struct sk_buff *skb)287{288	unsigned int req_sz;289	int err;290 291	/* Single skb use the standard mmc interface */292	req_sz = skb->len + 3;293	req_sz &= (uint)~3;294 295	switch (func->num) {296	case 1:297		err = sdio_memcpy_fromio(func, ((u8 *)(skb->data)), addr,298					 req_sz);299		break;300	case 2:301		err = sdio_readsb(func, ((u8 *)(skb->data)), addr, req_sz);302		break;303	default:304		/* bail out as things are really fishy here */305		WARN(1, "invalid sdio function number: %d\n", func->num);306		err = -ENOMEDIUM;307	}308 309	if (err == -ENOMEDIUM)310		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);311 312	return err;313}314 315static int brcmf_sdiod_skbuff_write(struct brcmf_sdio_dev *sdiodev,316				    struct sdio_func *func, u32 addr,317				    struct sk_buff *skb)318{319	unsigned int req_sz;320	int err;321 322	/* Single skb use the standard mmc interface */323	req_sz = skb->len + 3;324	req_sz &= (uint)~3;325 326	err = sdio_memcpy_toio(func, addr, ((u8 *)(skb->data)), req_sz);327 328	if (err == -ENOMEDIUM)329		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);330 331	return err;332}333 334static int mmc_submit_one(struct mmc_data *md, struct mmc_request *mr,335			  struct mmc_command *mc, int sg_cnt, int req_sz,336			  int func_blk_sz, u32 *addr,337			  struct brcmf_sdio_dev *sdiodev,338			  struct sdio_func *func, int write)339{340	int ret;341 342	md->sg_len = sg_cnt;343	md->blocks = req_sz / func_blk_sz;344	mc->arg |= (*addr & 0x1FFFF) << 9;	/* address */345	mc->arg |= md->blocks & 0x1FF;	/* block count */346	/* incrementing addr for function 1 */347	if (func->num == 1)348		*addr += req_sz;349 350	mmc_set_data_timeout(md, func->card);351	mmc_wait_for_req(func->card->host, mr);352 353	ret = mc->error ? mc->error : md->error;354	if (ret == -ENOMEDIUM) {355		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);356	} else if (ret != 0) {357		brcmf_err("CMD53 sg block %s failed %d\n",358			  write ? "write" : "read", ret);359		ret = -EIO;360	}361 362	return ret;363}364 365/**366 * brcmf_sdiod_sglist_rw - SDIO interface function for block data access367 * @sdiodev: brcmfmac sdio device368 * @func: SDIO function369 * @write: direction flag370 * @addr: dongle memory address as source/destination371 * @pktlist: skb buffer head pointer372 *373 * This function takes the respbonsibility as the interface function to MMC374 * stack for block data access. It assumes that the skb passed down by the375 * caller has already been padded and aligned.376 */377static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev,378				 struct sdio_func *func,379				 bool write, u32 addr,380				 struct sk_buff_head *pktlist)381{382	unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;383	unsigned int max_req_sz, src_offset, dst_offset;384	unsigned char *pkt_data, *orig_data, *dst_data;385	struct sk_buff_head local_list, *target_list;386	struct sk_buff *pkt_next = NULL, *src;387	unsigned short max_seg_cnt;388	struct mmc_request mmc_req;389	struct mmc_command mmc_cmd;390	struct mmc_data mmc_dat;391	struct scatterlist *sgl;392	int ret = 0;393 394	if (!pktlist->qlen)395		return -EINVAL;396 397	target_list = pktlist;398	/* for host with broken sg support, prepare a page aligned list */399	__skb_queue_head_init(&local_list);400	if (!write && sdiodev->settings->bus.sdio.broken_sg_support) {401		req_sz = 0;402		skb_queue_walk(pktlist, pkt_next)403			req_sz += pkt_next->len;404		req_sz = ALIGN(req_sz, func->cur_blksize);405		while (req_sz > PAGE_SIZE) {406			pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);407			if (pkt_next == NULL) {408				ret = -ENOMEM;409				goto exit;410			}411			__skb_queue_tail(&local_list, pkt_next);412			req_sz -= PAGE_SIZE;413		}414		pkt_next = brcmu_pkt_buf_get_skb(req_sz);415		if (pkt_next == NULL) {416			ret = -ENOMEM;417			goto exit;418		}419		__skb_queue_tail(&local_list, pkt_next);420		target_list = &local_list;421	}422 423	func_blk_sz = func->cur_blksize;424	max_req_sz = sdiodev->max_request_size;425	max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count,426			    target_list->qlen);427 428	memset(&mmc_req, 0, sizeof(struct mmc_request));429	memset(&mmc_cmd, 0, sizeof(struct mmc_command));430	memset(&mmc_dat, 0, sizeof(struct mmc_data));431 432	mmc_dat.sg = sdiodev->sgtable.sgl;433	mmc_dat.blksz = func_blk_sz;434	mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;435	mmc_cmd.opcode = SD_IO_RW_EXTENDED;436	mmc_cmd.arg = write ? 1<<31 : 0;	/* write flag  */437	mmc_cmd.arg |= (func->num & 0x7) << 28;	/* SDIO func num */438	mmc_cmd.arg |= 1 << 27;			/* block mode */439	/* for function 1 the addr will be incremented */440	mmc_cmd.arg |= (func->num == 1) ? 1 << 26 : 0;441	mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;442	mmc_req.cmd = &mmc_cmd;443	mmc_req.data = &mmc_dat;444 445	req_sz = 0;446	sg_cnt = 0;447	sgl = sdiodev->sgtable.sgl;448	skb_queue_walk(target_list, pkt_next) {449		pkt_offset = 0;450		while (pkt_offset < pkt_next->len) {451			pkt_data = pkt_next->data + pkt_offset;452			sg_data_sz = pkt_next->len - pkt_offset;453			if (sg_data_sz > sdiodev->max_segment_size)454				sg_data_sz = sdiodev->max_segment_size;455			if (sg_data_sz > max_req_sz - req_sz)456				sg_data_sz = max_req_sz - req_sz;457 458			sg_set_buf(sgl, pkt_data, sg_data_sz);459			sg_cnt++;460 461			sgl = sg_next(sgl);462			req_sz += sg_data_sz;463			pkt_offset += sg_data_sz;464			if (req_sz >= max_req_sz || sg_cnt >= max_seg_cnt) {465				ret = mmc_submit_one(&mmc_dat, &mmc_req, &mmc_cmd,466						     sg_cnt, req_sz, func_blk_sz,467						     &addr, sdiodev, func, write);468				if (ret)469					goto exit_queue_walk;470				req_sz = 0;471				sg_cnt = 0;472				sgl = sdiodev->sgtable.sgl;473			}474		}475	}476	if (sg_cnt)477		ret = mmc_submit_one(&mmc_dat, &mmc_req, &mmc_cmd,478				     sg_cnt, req_sz, func_blk_sz,479				     &addr, sdiodev, func, write);480exit_queue_walk:481	if (!write && sdiodev->settings->bus.sdio.broken_sg_support) {482		src = __skb_peek(&local_list);483		src_offset = 0;484		skb_queue_walk(pktlist, pkt_next) {485			dst_offset = 0;486 487			/* This is safe because we must have enough SKB data488			 * in the local list to cover everything in pktlist.489			 */490			while (1) {491				req_sz = pkt_next->len - dst_offset;492				if (req_sz > src->len - src_offset)493					req_sz = src->len - src_offset;494 495				orig_data = src->data + src_offset;496				dst_data = pkt_next->data + dst_offset;497				memcpy(dst_data, orig_data, req_sz);498 499				src_offset += req_sz;500				if (src_offset == src->len) {501					src_offset = 0;502					src = skb_peek_next(src, &local_list);503				}504				dst_offset += req_sz;505				if (dst_offset == pkt_next->len)506					break;507			}508		}509	}510 511exit:512	sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);513	while ((pkt_next = __skb_dequeue(&local_list)) != NULL)514		brcmu_pkt_buf_free_skb(pkt_next);515 516	return ret;517}518 519int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)520{521	struct sk_buff *mypkt;522	int err;523 524	mypkt = brcmu_pkt_buf_get_skb(nbytes);525	if (!mypkt) {526		brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",527			  nbytes);528		return -EIO;529	}530 531	err = brcmf_sdiod_recv_pkt(sdiodev, mypkt);532	if (!err)533		memcpy(buf, mypkt->data, nbytes);534 535	brcmu_pkt_buf_free_skb(mypkt);536	return err;537}538 539int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)540{541	u32 addr = sdiodev->cc_core->base;542	int err = 0;543 544	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);545 546	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);547	if (err)548		goto done;549 550	addr &= SBSDIO_SB_OFT_ADDR_MASK;551	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;552 553	err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, pkt);554 555done:556	return err;557}558 559int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,560			   struct sk_buff_head *pktq, uint totlen)561{562	struct sk_buff *glom_skb = NULL;563	struct sk_buff *skb;564	u32 addr = sdiodev->cc_core->base;565	int err = 0;566 567	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",568		  addr, pktq->qlen);569 570	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);571	if (err)572		goto done;573 574	addr &= SBSDIO_SB_OFT_ADDR_MASK;575	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;576 577	if (pktq->qlen == 1)578		err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr,579					      __skb_peek(pktq));580	else if (!sdiodev->sg_support) {581		glom_skb = brcmu_pkt_buf_get_skb(totlen);582		if (!glom_skb)583			return -ENOMEM;584		err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr,585					      glom_skb);586		if (err)587			goto done;588 589		skb_queue_walk(pktq, skb) {590			memcpy(skb->data, glom_skb->data, skb->len);591			skb_pull(glom_skb, skb->len);592		}593	} else594		err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func2, false,595					    addr, pktq);596 597done:598	brcmu_pkt_buf_free_skb(glom_skb);599	return err;600}601 602int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)603{604	struct sk_buff *mypkt;605	u32 addr = sdiodev->cc_core->base;606	int err;607 608	mypkt = brcmu_pkt_buf_get_skb(nbytes);609 610	if (!mypkt) {611		brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",612			  nbytes);613		return -EIO;614	}615 616	memcpy(mypkt->data, buf, nbytes);617 618	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);619	if (err)620		goto out;621 622	addr &= SBSDIO_SB_OFT_ADDR_MASK;623	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;624 625	err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, mypkt);626out:627	brcmu_pkt_buf_free_skb(mypkt);628 629	return err;630}631 632int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,633			 struct sk_buff_head *pktq)634{635	struct sk_buff *skb;636	u32 addr = sdiodev->cc_core->base;637	int err;638 639	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);640 641	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);642	if (err)643		return err;644 645	addr &= SBSDIO_SB_OFT_ADDR_MASK;646	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;647 648	if (pktq->qlen == 1 || !sdiodev->sg_support) {649		skb_queue_walk(pktq, skb) {650			err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2,651						       addr, skb);652			if (err)653				break;654		}655	} else {656		err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func2, true,657					    addr, pktq);658	}659 660	return err;661}662 663int664brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,665		  u8 *data, uint size)666{667	int err = 0;668	struct sk_buff *pkt;669	u32 sdaddr;670	uint dsize;671 672	dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);673	pkt = dev_alloc_skb(dsize);674	if (!pkt) {675		brcmf_err("dev_alloc_skb failed: len %d\n", dsize);676		return -EIO;677	}678	pkt->priority = 0;679 680	/* Determine initial transfer parameters */681	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;682	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)683		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);684	else685		dsize = size;686 687	sdio_claim_host(sdiodev->func1);688 689	/* Do the transfer(s) */690	while (size) {691		/* Set the backplane window to include the start address */692		err = brcmf_sdiod_set_backplane_window(sdiodev, address);693		if (err)694			break;695 696		brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",697			  write ? "write" : "read", dsize,698			  sdaddr, address & SBSDIO_SBWINDOW_MASK);699 700		sdaddr &= SBSDIO_SB_OFT_ADDR_MASK;701		sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG;702 703		skb_put(pkt, dsize);704 705		if (write) {706			memcpy(pkt->data, data, dsize);707			err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func1,708						       sdaddr, pkt);709		} else {710			err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func1,711						      sdaddr, pkt);712		}713 714		if (err) {715			brcmf_err("membytes transfer failed\n");716			break;717		}718		if (!write)719			memcpy(data, pkt->data, dsize);720		skb_trim(pkt, 0);721 722		/* Adjust for next transfer (if any) */723		size -= dsize;724		if (size) {725			data += dsize;726			address += dsize;727			sdaddr = 0;728			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);729		}730	}731 732	dev_kfree_skb(pkt);733 734	sdio_release_host(sdiodev->func1);735 736	return err;737}738 739int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func)740{741	brcmf_dbg(SDIO, "Enter\n");742 743	/* Issue abort cmd52 command through F0 */744	brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, func->num, NULL);745 746	brcmf_dbg(SDIO, "Exit\n");747	return 0;748}749 750void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)751{752	struct sdio_func *func;753	struct mmc_host *host;754	uint max_blocks;755	uint nents;756	int err;757 758	func = sdiodev->func2;759	host = func->card->host;760	sdiodev->sg_support = host->max_segs > 1;761	max_blocks = min_t(uint, host->max_blk_count, 511u);762	sdiodev->max_request_size = min_t(uint, host->max_req_size,763					  max_blocks * func->cur_blksize);764	sdiodev->max_segment_count = min_t(uint, host->max_segs,765					   SG_MAX_SINGLE_ALLOC);766	sdiodev->max_segment_size = host->max_seg_size;767 768	if (!sdiodev->sg_support)769		return;770 771	nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE,772		      sdiodev->settings->bus.sdio.txglomsz);773	nents += (nents >> 4) + 1;774 775	WARN_ON(nents > sdiodev->max_segment_count);776 777	brcmf_dbg(TRACE, "nents=%d\n", nents);778	err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);779	if (err < 0) {780		brcmf_err("allocation failed: disable scatter-gather");781		sdiodev->sg_support = false;782	}783 784	sdiodev->txglomsz = sdiodev->settings->bus.sdio.txglomsz;785}786 787static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)788{789	if (!IS_ENABLED(CONFIG_PM_SLEEP))790		return 0;791 792	sdiodev->freezer = kzalloc(sizeof(*sdiodev->freezer), GFP_KERNEL);793	if (!sdiodev->freezer)794		return -ENOMEM;795	atomic_set(&sdiodev->freezer->thread_count, 0);796	atomic_set(&sdiodev->freezer->freezing, 0);797	init_waitqueue_head(&sdiodev->freezer->thread_freeze);798	init_completion(&sdiodev->freezer->resumed);799	return 0;800}801 802static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)803{804	if (sdiodev->freezer) {805		WARN_ON(atomic_read(&sdiodev->freezer->freezing));806		kfree(sdiodev->freezer);807		sdiodev->freezer = NULL;808	}809}810 811static int brcmf_sdiod_freezer_on(struct brcmf_sdio_dev *sdiodev)812{813	atomic_t *expect = &sdiodev->freezer->thread_count;814	int res = 0;815 816	sdiodev->freezer->frozen_count = 0;817	reinit_completion(&sdiodev->freezer->resumed);818	atomic_set(&sdiodev->freezer->freezing, 1);819	brcmf_sdio_trigger_dpc(sdiodev->bus);820	wait_event(sdiodev->freezer->thread_freeze,821		   atomic_read(expect) == sdiodev->freezer->frozen_count);822	sdio_claim_host(sdiodev->func1);823	res = brcmf_sdio_sleep(sdiodev->bus, true);824	sdio_release_host(sdiodev->func1);825	return res;826}827 828static void brcmf_sdiod_freezer_off(struct brcmf_sdio_dev *sdiodev)829{830	sdio_claim_host(sdiodev->func1);831	brcmf_sdio_sleep(sdiodev->bus, false);832	sdio_release_host(sdiodev->func1);833	atomic_set(&sdiodev->freezer->freezing, 0);834	complete_all(&sdiodev->freezer->resumed);835}836 837bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)838{839	return IS_ENABLED(CONFIG_PM_SLEEP) &&840		atomic_read(&sdiodev->freezer->freezing);841}842 843void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)844{845	if (!brcmf_sdiod_freezing(sdiodev))846		return;847	sdiodev->freezer->frozen_count++;848	wake_up(&sdiodev->freezer->thread_freeze);849	wait_for_completion(&sdiodev->freezer->resumed);850}851 852void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)853{854	if (IS_ENABLED(CONFIG_PM_SLEEP))855		atomic_inc(&sdiodev->freezer->thread_count);856}857 858void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)859{860	if (IS_ENABLED(CONFIG_PM_SLEEP))861		atomic_dec(&sdiodev->freezer->thread_count);862}863 864int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)865{866	sdiodev->state = BRCMF_SDIOD_DOWN;867	if (sdiodev->bus) {868		brcmf_sdio_remove(sdiodev->bus);869		sdiodev->bus = NULL;870	}871 872	brcmf_sdiod_freezer_detach(sdiodev);873 874	/* Disable functions 2 then 1. */875	sdio_claim_host(sdiodev->func1);876	sdio_disable_func(sdiodev->func2);877	sdio_disable_func(sdiodev->func1);878	sdio_release_host(sdiodev->func1);879 880	sg_free_table(&sdiodev->sgtable);881	sdiodev->sbwad = 0;882 883	pm_runtime_allow(sdiodev->func1->card->host->parent);884	return 0;885}886 887static void brcmf_sdiod_host_fixup(struct mmc_host *host)888{889	/* runtime-pm powers off the device */890	pm_runtime_forbid(host->parent);891	/* avoid removal detection upon resume */892	host->caps |= MMC_CAP_NONREMOVABLE;893}894 895int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)896{897	int ret = 0;898	unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE;899 900	sdio_claim_host(sdiodev->func1);901 902	ret = sdio_set_block_size(sdiodev->func1, SDIO_FUNC1_BLOCKSIZE);903	if (ret) {904		brcmf_err("Failed to set F1 blocksize\n");905		sdio_release_host(sdiodev->func1);906		return ret;907	}908	switch (sdiodev->func2->device) {909	case SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373:910		f2_blksz = SDIO_4373_FUNC2_BLOCKSIZE;911		break;912	case SDIO_DEVICE_ID_BROADCOM_4359:913	case SDIO_DEVICE_ID_BROADCOM_4354:914	case SDIO_DEVICE_ID_BROADCOM_4356:915		f2_blksz = SDIO_435X_FUNC2_BLOCKSIZE;916		break;917	case SDIO_DEVICE_ID_BROADCOM_4329:918		f2_blksz = SDIO_4329_FUNC2_BLOCKSIZE;919		break;920	default:921		break;922	}923 924	ret = sdio_set_block_size(sdiodev->func2, f2_blksz);925	if (ret) {926		brcmf_err("Failed to set F2 blocksize\n");927		sdio_release_host(sdiodev->func1);928		return ret;929	} else {930		brcmf_dbg(SDIO, "set F2 blocksize to %d\n", f2_blksz);931	}932 933	/* increase F2 timeout */934	sdiodev->func2->enable_timeout = SDIO_WAIT_F2RDY;935 936	/* Enable Function 1 */937	ret = sdio_enable_func(sdiodev->func1);938	sdio_release_host(sdiodev->func1);939	if (ret) {940		brcmf_err("Failed to enable F1: err=%d\n", ret);941		goto out;942	}943 944	ret = brcmf_sdiod_freezer_attach(sdiodev);945	if (ret)946		goto out;947 948	/* try to attach to the target device */949	sdiodev->bus = brcmf_sdio_probe(sdiodev);950	if (!sdiodev->bus) {951		ret = -ENODEV;952		goto out;953	}954	brcmf_sdiod_host_fixup(sdiodev->func2->card->host);955out:956	if (ret)957		brcmf_sdiod_remove(sdiodev);958 959	return ret;960}961 962#define BRCMF_SDIO_DEVICE(dev_id, fw_vend) \963	{ \964		SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, dev_id), \965		.driver_data = BRCMF_FWVENDOR_ ## fw_vend \966	}967 968#define CYW_SDIO_DEVICE(dev_id, fw_vend) \969	{ \970		SDIO_DEVICE(SDIO_VENDOR_ID_CYPRESS, dev_id), \971		.driver_data = BRCMF_FWVENDOR_ ## fw_vend \972	}973 974/* devices we support, null terminated */975static const struct sdio_device_id brcmf_sdmmc_ids[] = {976	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43143, WCC),977	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43241, WCC),978	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4329, WCC),979	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4330, WCC),980	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4334, WCC),981	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340, WCC),982	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341, WCC),983	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362, WCC),984	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43364, WCC),985	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339, WCC),986	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339, WCC),987	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430, WCC),988	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43439, WCC),989	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345, WCC),990	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455, WCC),991	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354, WCC),992	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356, WCC),993	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4359, WCC),994	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373, CYW),995	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012, CYW),996	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43752, CYW),997	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_89359, CYW),998	CYW_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43439, CYW),999	{ /* end: all zeroes */ }1000};1001MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);1002 1003 1004static void brcmf_sdiod_acpi_save_power_manageable(struct brcmf_sdio_dev *sdiodev)1005{1006#if IS_ENABLED(CONFIG_ACPI)1007	struct acpi_device *adev;1008 1009	adev = ACPI_COMPANION(&sdiodev->func1->dev);1010	if (adev)1011		sdiodev->func1_power_manageable = adev->flags.power_manageable;1012 1013	adev = ACPI_COMPANION(&sdiodev->func2->dev);1014	if (adev)1015		sdiodev->func2_power_manageable = adev->flags.power_manageable;1016#endif1017}1018 1019static void brcmf_sdiod_acpi_set_power_manageable(struct brcmf_sdio_dev *sdiodev,1020						  int enable)1021{1022#if IS_ENABLED(CONFIG_ACPI)1023	struct acpi_device *adev;1024 1025	adev = ACPI_COMPANION(&sdiodev->func1->dev);1026	if (adev)1027		adev->flags.power_manageable = enable ? sdiodev->func1_power_manageable : 0;1028 1029	adev = ACPI_COMPANION(&sdiodev->func2->dev);1030	if (adev)1031		adev->flags.power_manageable = enable ? sdiodev->func2_power_manageable : 0;1032#endif1033}1034 1035static int brcmf_ops_sdio_probe(struct sdio_func *func,1036				const struct sdio_device_id *id)1037{1038	int err;1039	struct brcmf_sdio_dev *sdiodev;1040	struct brcmf_bus *bus_if;1041 1042	if (!id) {1043		dev_err(&func->dev, "Error no sdio_device_id passed for %x:%x\n", func->vendor, func->device);1044		return -ENODEV;1045	}1046 1047	brcmf_dbg(SDIO, "Enter\n");1048	brcmf_dbg(SDIO, "Class=%x\n", func->class);1049	brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);1050	brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);1051	brcmf_dbg(SDIO, "Function#: %d\n", func->num);1052 1053	/* Set MMC_QUIRK_LENIENT_FN0 for this card */1054	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;1055 1056	/* Consume func num 1 but dont do anything with it. */1057	if (func->num == 1)1058		return 0;1059 1060	/* Ignore anything but func 2 */1061	if (func->num != 2)1062		return -ENODEV;1063 1064	bus_if = kzalloc(sizeof(*bus_if), GFP_KERNEL);1065	if (!bus_if)1066		return -ENOMEM;1067	sdiodev = kzalloc(sizeof(*sdiodev), GFP_KERNEL);1068	if (!sdiodev) {1069		kfree(bus_if);1070		return -ENOMEM;1071	}1072 1073	/* store refs to functions used. mmc_card does1074	 * not hold the F0 function pointer.1075	 */1076	sdiodev->func1 = func->card->sdio_func[0];1077	sdiodev->func2 = func;1078 1079	sdiodev->bus_if = bus_if;1080	bus_if->bus_priv.sdio = sdiodev;1081	bus_if->proto_type = BRCMF_PROTO_BCDC;1082	bus_if->fwvid = id->driver_data;1083	dev_set_drvdata(&func->dev, bus_if);1084	dev_set_drvdata(&sdiodev->func1->dev, bus_if);1085	sdiodev->dev = &sdiodev->func1->dev;1086 1087	brcmf_sdiod_acpi_save_power_manageable(sdiodev);1088	brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);1089 1090	brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");1091	err = brcmf_sdiod_probe(sdiodev);1092	if (err) {1093		brcmf_err("F2 error, probe failed %d...\n", err);1094		goto fail;1095	}1096 1097	brcmf_dbg(SDIO, "F2 init completed...\n");1098	return 0;1099 1100fail:1101	dev_set_drvdata(&func->dev, NULL);1102	dev_set_drvdata(&sdiodev->func1->dev, NULL);1103	kfree(sdiodev);1104	kfree(bus_if);1105	return err;1106}1107 1108static void brcmf_ops_sdio_remove(struct sdio_func *func)1109{1110	struct brcmf_bus *bus_if;1111	struct brcmf_sdio_dev *sdiodev;1112 1113	brcmf_dbg(SDIO, "Enter\n");1114	brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);1115	brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);1116	brcmf_dbg(SDIO, "Function: %d\n", func->num);1117 1118	bus_if = dev_get_drvdata(&func->dev);1119	if (bus_if) {1120		sdiodev = bus_if->bus_priv.sdio;1121 1122		/* start by unregistering irqs */1123		brcmf_sdiod_intr_unregister(sdiodev);1124 1125		if (func->num != 1)1126			return;1127 1128		/* only proceed with rest of cleanup if func 1 */1129		brcmf_sdiod_remove(sdiodev);1130 1131		dev_set_drvdata(&sdiodev->func1->dev, NULL);1132		dev_set_drvdata(&sdiodev->func2->dev, NULL);1133 1134		kfree(bus_if);1135		kfree(sdiodev);1136	}1137 1138	brcmf_dbg(SDIO, "Exit\n");1139}1140 1141void brcmf_sdio_wowl_config(struct device *dev, bool enabled)1142{1143	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1144	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;1145	mmc_pm_flag_t pm_caps = sdio_get_host_pm_caps(sdiodev->func1);1146 1147	/* Power must be preserved to be able to support WOWL. */1148	if (!(pm_caps & MMC_PM_KEEP_POWER))1149		goto notsup;1150 1151	if (sdiodev->settings->bus.sdio.oob_irq_supported ||1152	    pm_caps & MMC_PM_WAKE_SDIO_IRQ) {1153		/* Stop ACPI from turning off the device when wowl is enabled */1154		brcmf_sdiod_acpi_set_power_manageable(sdiodev, !enabled);1155		sdiodev->wowl_enabled = enabled;1156		brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled);1157		return;1158	}1159 1160notsup:1161	brcmf_dbg(SDIO, "WOWL not supported\n");1162}1163 1164static int brcmf_ops_sdio_suspend(struct device *dev)1165{1166	struct sdio_func *func;1167	struct brcmf_bus *bus_if;1168	struct brcmf_sdio_dev *sdiodev;1169	mmc_pm_flag_t sdio_flags;1170	int ret = 0;1171 1172	func = container_of(dev, struct sdio_func, dev);1173	brcmf_dbg(SDIO, "Enter: F%d\n", func->num);1174	if (func->num != 1)1175		return 0;1176 1177 1178	bus_if = dev_get_drvdata(dev);1179	sdiodev = bus_if->bus_priv.sdio;1180 1181	if (sdiodev->wowl_enabled) {1182		brcmf_sdiod_freezer_on(sdiodev);1183		brcmf_sdio_wd_timer(sdiodev->bus, 0);1184 1185		sdio_flags = MMC_PM_KEEP_POWER;1186		if (sdiodev->settings->bus.sdio.oob_irq_supported)1187			enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);1188		else1189			sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;1190 1191		if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags))1192			brcmf_err("Failed to set pm_flags %x\n", sdio_flags);1193 1194	} else {1195		/* power will be cut so remove device, probe again in resume */1196		brcmf_sdiod_intr_unregister(sdiodev);1197		ret = brcmf_sdiod_remove(sdiodev);1198		if (ret)1199			brcmf_err("Failed to remove device on suspend\n");1200	}1201 1202	return ret;1203}1204 1205static int brcmf_ops_sdio_resume(struct device *dev)1206{1207	struct brcmf_bus *bus_if = dev_get_drvdata(dev);1208	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;1209	struct sdio_func *func = container_of(dev, struct sdio_func, dev);1210	int ret = 0;1211 1212	brcmf_dbg(SDIO, "Enter: F%d\n", func->num);1213	if (func->num != 2)1214		return 0;1215 1216	if (!sdiodev->wowl_enabled) {1217		/* bus was powered off and device removed, probe again */1218		ret = brcmf_sdiod_probe(sdiodev);1219		if (ret)1220			brcmf_err("Failed to probe device on resume\n");1221	} else {1222		if (sdiodev->settings->bus.sdio.oob_irq_supported)1223			disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);1224 1225		brcmf_sdiod_freezer_off(sdiodev);1226	}1227 1228	return ret;1229}1230 1231static DEFINE_SIMPLE_DEV_PM_OPS(brcmf_sdio_pm_ops,1232				brcmf_ops_sdio_suspend,1233				brcmf_ops_sdio_resume);1234 1235static struct sdio_driver brcmf_sdmmc_driver = {1236	.probe = brcmf_ops_sdio_probe,1237	.remove = brcmf_ops_sdio_remove,1238	.name = KBUILD_MODNAME,1239	.id_table = brcmf_sdmmc_ids,1240	.drv = {1241		.pm = pm_sleep_ptr(&brcmf_sdio_pm_ops),1242		.coredump = brcmf_dev_coredump,1243	},1244};1245 1246int brcmf_sdio_register(void)1247{1248	return sdio_register_driver(&brcmf_sdmmc_driver);1249}1250 1251void brcmf_sdio_exit(void)1252{1253	brcmf_dbg(SDIO, "Enter\n");1254 1255	sdio_unregister_driver(&brcmf_sdmmc_driver);1256}1257 1258