Home | History | Annotate | Download | only in sys
      1 /*
      2  * Broadcom BCMSDH to gSPI Protocol Conversion Layer
      3  *
      4  * Copyright (C) 2010, Broadcom Corporation
      5  * All Rights Reserved.
      6  *
      7  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
      8  * the contents of this file may not be disclosed to third parties, copied
      9  * or duplicated in any form, in whole or in part, without the prior
     10  * written permission of Broadcom Corporation.
     11  *
     12  * $Id: bcmspibrcm.c,v 1.11.2.10.2.9.6.11 2009/05/21 13:21:57 Exp $
     13  */
     14 
     15 #define HSMODE
     16 
     17 #include <typedefs.h>
     18 
     19 #include <bcmdevs.h>
     20 #include <bcmendian.h>
     21 #include <bcmutils.h>
     22 #include <osl.h>
     23 #include <hndsoc.h>
     24 #include <siutils.h>
     25 #include <sbchipc.h>
     26 #include <sbsdio.h>
     27 #include <spid.h>
     28 
     29 #include <bcmsdbus.h>	/* bcmsdh to/from specific controller APIs */
     30 #include <sdiovar.h>	/* ioctl/iovars */
     31 #include <sdio.h>
     32 
     33 #include <pcicfg.h>
     34 
     35 
     36 #include <bcmspibrcm.h>
     37 #include <bcmspi.h>
     38 
     39 #define F0_RESPONSE_DELAY	16
     40 #define F1_RESPONSE_DELAY	16
     41 #define F2_RESPONSE_DELAY	F0_RESPONSE_DELAY
     42 
     43 #define CMDLEN		4
     44 
     45 #define DWORDMODE_ON (sd->chip == BCM4329_CHIP_ID) && (sd->chiprev == 2) && (sd->dwordmode == TRUE)
     46 
     47 /* Globals */
     48 uint sd_msglevel = 0;
     49 
     50 uint sd_hiok = FALSE;		/* Use hi-speed mode if available? */
     51 uint sd_sdmode = SDIOH_MODE_SPI;		/* Use SD4 mode by default */
     52 uint sd_f2_blocksize = 64;		/* Default blocksize */
     53 
     54 
     55 uint sd_divisor = 2;
     56 uint sd_power = 1;		/* Default to SD Slot powered ON */
     57 uint sd_clock = 1;		/* Default to SD Clock turned ON */
     58 uint sd_crc = 0;		/* Default to SPI CRC Check turned OFF */
     59 
     60 uint8	spi_outbuf[SPI_MAX_PKT_LEN];
     61 uint8	spi_inbuf[SPI_MAX_PKT_LEN];
     62 
     63 /* 128bytes buffer is enough to clear data-not-available and program response-delay F0 bits
     64  * assuming we will not exceed F0 response delay > 100 bytes at 48MHz.
     65  */
     66 #define BUF2_PKT_LEN	128
     67 uint8	spi_outbuf2[BUF2_PKT_LEN];
     68 uint8	spi_inbuf2[BUF2_PKT_LEN];
     69 
     70 /* Prototypes */
     71 static bool bcmspi_test_card(sdioh_info_t *sd);
     72 static bool bcmspi_host_device_init_adapt(sdioh_info_t *sd);
     73 static int bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode);
     74 static int bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg,
     75                            uint32 *data, uint32 datalen);
     76 static int bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr,
     77                               int regsize, uint32 *data);
     78 static int bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr,
     79                                int regsize, uint32 data);
     80 static int bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr,
     81                                uint8 *data);
     82 static int bcmspi_driver_init(sdioh_info_t *sd);
     83 static int bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo,
     84                           uint32 addr, int nbytes, uint32 *data);
     85 static int bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize,
     86                                  uint32 *data);
     87 static void bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer);
     88 static int bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg);
     89 
     90 /*
     91  *  Public entry points & extern's
     92  */
     93 extern sdioh_info_t *
     94 sdioh_attach(osl_t *osh, void *bar0, uint irq)
     95 {
     96 	sdioh_info_t *sd;
     97 
     98 	sd_trace(("%s\n", __FUNCTION__));
     99 	if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) {
    100 		sd_err(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh)));
    101 		return NULL;
    102 	}
    103 	bzero((char *)sd, sizeof(sdioh_info_t));
    104 	sd->osh = osh;
    105 	if (spi_osinit(sd) != 0) {
    106 		sd_err(("%s: spi_osinit() failed\n", __FUNCTION__));
    107 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
    108 		return NULL;
    109 	}
    110 
    111 	sd->bar0 = bar0;
    112 	sd->irq = irq;
    113 	sd->intr_handler = NULL;
    114 	sd->intr_handler_arg = NULL;
    115 	sd->intr_handler_valid = FALSE;
    116 
    117 	/* Set defaults */
    118 	sd->use_client_ints = TRUE;
    119 	sd->sd_use_dma = FALSE;	/* DMA Not supported */
    120 
    121 	/* Spi device default is 16bit mode, change to 4 when device is changed to 32bit
    122 	 * mode
    123 	 */
    124 	sd->wordlen = 2;
    125 
    126 	if (!spi_hw_attach(sd)) {
    127 		sd_err(("%s: spi_hw_attach() failed\n", __FUNCTION__));
    128 		spi_osfree(sd);
    129 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
    130 		return (NULL);
    131 	}
    132 
    133 	if (bcmspi_driver_init(sd) != SUCCESS) {
    134 		sd_err(("%s: bcmspi_driver_init() failed()\n", __FUNCTION__));
    135 		spi_hw_detach(sd);
    136 		spi_osfree(sd);
    137 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
    138 		return (NULL);
    139 	}
    140 
    141 	if (spi_register_irq(sd, irq) != SUCCESS) {
    142 		sd_err(("%s: spi_register_irq() failed for irq = %d\n", __FUNCTION__, irq));
    143 		spi_hw_detach(sd);
    144 		spi_osfree(sd);
    145 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
    146 		return (NULL);
    147 	}
    148 
    149 	sd_trace(("%s: Done\n", __FUNCTION__));
    150 
    151 	return sd;
    152 }
    153 
    154 extern SDIOH_API_RC
    155 sdioh_detach(osl_t *osh, sdioh_info_t *sd)
    156 {
    157 	sd_trace(("%s\n", __FUNCTION__));
    158 	if (sd) {
    159 		sd_err(("%s: detaching from hardware\n", __FUNCTION__));
    160 		spi_free_irq(sd->irq, sd);
    161 		spi_hw_detach(sd);
    162 		spi_osfree(sd);
    163 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
    164 	}
    165 	return SDIOH_API_RC_SUCCESS;
    166 }
    167 
    168 /* Configure callback to client when we recieve client interrupt */
    169 extern SDIOH_API_RC
    170 sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
    171 {
    172 	sd_trace(("%s: Entering\n", __FUNCTION__));
    173 	sd->intr_handler = fn;
    174 	sd->intr_handler_arg = argh;
    175 	sd->intr_handler_valid = TRUE;
    176 	return SDIOH_API_RC_SUCCESS;
    177 }
    178 
    179 extern SDIOH_API_RC
    180 sdioh_interrupt_deregister(sdioh_info_t *sd)
    181 {
    182 	sd_trace(("%s: Entering\n", __FUNCTION__));
    183 	sd->intr_handler_valid = FALSE;
    184 	sd->intr_handler = NULL;
    185 	sd->intr_handler_arg = NULL;
    186 	return SDIOH_API_RC_SUCCESS;
    187 }
    188 
    189 extern SDIOH_API_RC
    190 sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
    191 {
    192 	sd_trace(("%s: Entering\n", __FUNCTION__));
    193 	*onoff = sd->client_intr_enabled;
    194 	return SDIOH_API_RC_SUCCESS;
    195 }
    196 
    197 #if defined(DHD_DEBUG)
    198 extern bool
    199 sdioh_interrupt_pending(sdioh_info_t *sd)
    200 {
    201 	return 0;
    202 }
    203 #endif
    204 
    205 extern SDIOH_API_RC
    206 sdioh_query_device(sdioh_info_t *sd)
    207 {
    208 	/* Return a BRCM ID appropriate to the dongle class */
    209 	return (sd->num_funcs > 1) ? BCM4329_D11NDUAL_ID : BCM4318_D11G_ID;
    210 }
    211 
    212 /* Provide dstatus bits of spi-transaction for dhd layers. */
    213 extern uint32
    214 sdioh_get_dstatus(sdioh_info_t *sd)
    215 {
    216 	return sd->card_dstatus;
    217 }
    218 
    219 extern void
    220 sdioh_chipinfo(sdioh_info_t *sd, uint32 chip, uint32 chiprev)
    221 {
    222 	sd->chip = chip;
    223 	sd->chiprev = chiprev;
    224 }
    225 
    226 extern void
    227 sdioh_dwordmode(sdioh_info_t *sd, bool set)
    228 {
    229 	uint8 reg = 0;
    230 	int status;
    231 
    232 	if ((status = sdioh_request_byte(sd, SDIOH_READ, SPI_FUNC_0, SPID_STATUS_ENABLE, &reg)) !=
    233 	     SUCCESS) {
    234 		sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__));
    235 		return;
    236 	}
    237 
    238 	if (set) {
    239 		reg |= DWORD_PKT_LEN_EN;
    240 		sd->dwordmode = TRUE;
    241 		sd->client_block_size[SPI_FUNC_2] = 4096; /* h2spi's limit is 4KB, we support 8KB */
    242 	} else {
    243 		reg &= ~DWORD_PKT_LEN_EN;
    244 		sd->dwordmode = FALSE;
    245 		sd->client_block_size[SPI_FUNC_2] = 2048;
    246 	}
    247 
    248 	if ((status = sdioh_request_byte(sd, SDIOH_WRITE, SPI_FUNC_0, SPID_STATUS_ENABLE, &reg)) !=
    249 	     SUCCESS) {
    250 		sd_err(("%s: Failed to set dwordmode in gSPI\n", __FUNCTION__));
    251 		return;
    252 	}
    253 }
    254 
    255 
    256 uint
    257 sdioh_query_iofnum(sdioh_info_t *sd)
    258 {
    259 	return sd->num_funcs;
    260 }
    261 
    262 /* IOVar table */
    263 enum {
    264 	IOV_MSGLEVEL = 1,
    265 	IOV_BLOCKMODE,
    266 	IOV_BLOCKSIZE,
    267 	IOV_DMA,
    268 	IOV_USEINTS,
    269 	IOV_NUMINTS,
    270 	IOV_NUMLOCALINTS,
    271 	IOV_HOSTREG,
    272 	IOV_DEVREG,
    273 	IOV_DIVISOR,
    274 	IOV_SDMODE,
    275 	IOV_HISPEED,
    276 	IOV_HCIREGS,
    277 	IOV_POWER,
    278 	IOV_CLOCK,
    279 	IOV_SPIERRSTATS,
    280 	IOV_RESP_DELAY_ALL
    281 };
    282 
    283 const bcm_iovar_t sdioh_iovars[] = {
    284 	{"sd_msglevel",	IOV_MSGLEVEL, 	0,	IOVT_UINT32,	0 },
    285 	{"sd_blocksize", IOV_BLOCKSIZE, 0,	IOVT_UINT32,	0 }, /* ((fn << 16) | size) */
    286 	{"sd_dma",	IOV_DMA,	0,	IOVT_BOOL,	0 },
    287 	{"sd_ints",	IOV_USEINTS,	0,	IOVT_BOOL,	0 },
    288 	{"sd_numints",	IOV_NUMINTS,	0,	IOVT_UINT32,	0 },
    289 	{"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32,	0 },
    290 	{"sd_hostreg",	IOV_HOSTREG,	0,	IOVT_BUFFER,	sizeof(sdreg_t) },
    291 	{"sd_devreg",	IOV_DEVREG,	0,	IOVT_BUFFER,	sizeof(sdreg_t)	},
    292 	{"sd_divisor",	IOV_DIVISOR,	0,	IOVT_UINT32,	0 },
    293 	{"sd_power",	IOV_POWER,	0,	IOVT_UINT32,	0 },
    294 	{"sd_clock",	IOV_CLOCK,	0,	IOVT_UINT32,	0 },
    295 	{"sd_mode",	IOV_SDMODE,	0,	IOVT_UINT32,	100},
    296 	{"sd_highspeed",	IOV_HISPEED,	0,	IOVT_UINT32,	0},
    297 	{"spi_errstats", IOV_SPIERRSTATS, 0, IOVT_BUFFER, sizeof(struct spierrstats_t) },
    298 	{"spi_respdelay",	IOV_RESP_DELAY_ALL,	0,	IOVT_BOOL,	0 },
    299 	{NULL, 0, 0, 0, 0 }
    300 };
    301 
    302 int
    303 sdioh_iovar_op(sdioh_info_t *si, const char *name,
    304                void *params, int plen, void *arg, int len, bool set)
    305 {
    306 	const bcm_iovar_t *vi = NULL;
    307 	int bcmerror = 0;
    308 	int val_size;
    309 	int32 int_val = 0;
    310 	bool bool_val;
    311 	uint32 actionid;
    312 /*
    313 	sdioh_regs_t *regs;
    314 */
    315 
    316 	ASSERT(name);
    317 	ASSERT(len >= 0);
    318 
    319 	/* Get must have return space; Set does not take qualifiers */
    320 	ASSERT(set || (arg && len));
    321 	ASSERT(!set || (!params && !plen));
    322 
    323 	sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name));
    324 
    325 	if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) {
    326 		bcmerror = BCME_UNSUPPORTED;
    327 		goto exit;
    328 	}
    329 
    330 	if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0)
    331 		goto exit;
    332 
    333 	/* Set up params so get and set can share the convenience variables */
    334 	if (params == NULL) {
    335 		params = arg;
    336 		plen = len;
    337 	}
    338 
    339 	if (vi->type == IOVT_VOID)
    340 		val_size = 0;
    341 	else if (vi->type == IOVT_BUFFER)
    342 		val_size = len;
    343 	else
    344 		val_size = sizeof(int);
    345 
    346 	if (plen >= (int)sizeof(int_val))
    347 		bcopy(params, &int_val, sizeof(int_val));
    348 
    349 	bool_val = (int_val != 0) ? TRUE : FALSE;
    350 
    351 	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
    352 	switch (actionid) {
    353 	case IOV_GVAL(IOV_MSGLEVEL):
    354 		int_val = (int32)sd_msglevel;
    355 		bcopy(&int_val, arg, val_size);
    356 		break;
    357 
    358 	case IOV_SVAL(IOV_MSGLEVEL):
    359 		sd_msglevel = int_val;
    360 		break;
    361 
    362 	case IOV_GVAL(IOV_BLOCKSIZE):
    363 		if ((uint32)int_val > si->num_funcs) {
    364 			bcmerror = BCME_BADARG;
    365 			break;
    366 		}
    367 		int_val = (int32)si->client_block_size[int_val];
    368 		bcopy(&int_val, arg, val_size);
    369 		break;
    370 
    371 	case IOV_GVAL(IOV_DMA):
    372 		int_val = (int32)si->sd_use_dma;
    373 		bcopy(&int_val, arg, val_size);
    374 		break;
    375 
    376 	case IOV_SVAL(IOV_DMA):
    377 		si->sd_use_dma = (bool)int_val;
    378 		break;
    379 
    380 	case IOV_GVAL(IOV_USEINTS):
    381 		int_val = (int32)si->use_client_ints;
    382 		bcopy(&int_val, arg, val_size);
    383 		break;
    384 
    385 	case IOV_SVAL(IOV_USEINTS):
    386 		break;
    387 
    388 	case IOV_GVAL(IOV_DIVISOR):
    389 		int_val = (uint32)sd_divisor;
    390 		bcopy(&int_val, arg, val_size);
    391 		break;
    392 
    393 	case IOV_SVAL(IOV_DIVISOR):
    394 		sd_divisor = int_val;
    395 		if (!spi_start_clock(si, (uint16)sd_divisor)) {
    396 			sd_err(("%s: set clock failed\n", __FUNCTION__));
    397 			bcmerror = BCME_ERROR;
    398 		}
    399 		break;
    400 
    401 	case IOV_GVAL(IOV_POWER):
    402 		int_val = (uint32)sd_power;
    403 		bcopy(&int_val, arg, val_size);
    404 		break;
    405 
    406 	case IOV_SVAL(IOV_POWER):
    407 		sd_power = int_val;
    408 		break;
    409 
    410 	case IOV_GVAL(IOV_CLOCK):
    411 		int_val = (uint32)sd_clock;
    412 		bcopy(&int_val, arg, val_size);
    413 		break;
    414 
    415 	case IOV_SVAL(IOV_CLOCK):
    416 		sd_clock = int_val;
    417 		break;
    418 
    419 	case IOV_GVAL(IOV_SDMODE):
    420 		int_val = (uint32)sd_sdmode;
    421 		bcopy(&int_val, arg, val_size);
    422 		break;
    423 
    424 	case IOV_SVAL(IOV_SDMODE):
    425 		sd_sdmode = int_val;
    426 		break;
    427 
    428 	case IOV_GVAL(IOV_HISPEED):
    429 		int_val = (uint32)sd_hiok;
    430 		bcopy(&int_val, arg, val_size);
    431 		break;
    432 
    433 	case IOV_SVAL(IOV_HISPEED):
    434 		sd_hiok = int_val;
    435 
    436 		if (!bcmspi_set_highspeed_mode(si, (bool)sd_hiok)) {
    437 			sd_err(("%s: Failed changing highspeed mode to %d.\n",
    438 			        __FUNCTION__, sd_hiok));
    439 			bcmerror = BCME_ERROR;
    440 			return ERROR;
    441 		}
    442 		break;
    443 
    444 	case IOV_GVAL(IOV_NUMINTS):
    445 		int_val = (int32)si->intrcount;
    446 		bcopy(&int_val, arg, val_size);
    447 		break;
    448 
    449 	case IOV_GVAL(IOV_NUMLOCALINTS):
    450 		int_val = (int32)si->local_intrcount;
    451 		bcopy(&int_val, arg, val_size);
    452 		break;
    453 	case IOV_GVAL(IOV_DEVREG):
    454 	{
    455 		sdreg_t *sd_ptr = (sdreg_t *)params;
    456 		uint8 data;
    457 
    458 		if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
    459 			bcmerror = BCME_SDIO_ERROR;
    460 			break;
    461 		}
    462 
    463 		int_val = (int)data;
    464 		bcopy(&int_val, arg, sizeof(int_val));
    465 		break;
    466 	}
    467 
    468 	case IOV_SVAL(IOV_DEVREG):
    469 	{
    470 		sdreg_t *sd_ptr = (sdreg_t *)params;
    471 		uint8 data = (uint8)sd_ptr->value;
    472 
    473 		if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
    474 			bcmerror = BCME_SDIO_ERROR;
    475 			break;
    476 		}
    477 		break;
    478 	}
    479 
    480 
    481 	case IOV_GVAL(IOV_SPIERRSTATS):
    482 	{
    483 		bcopy(&si->spierrstats, arg, sizeof(struct spierrstats_t));
    484 		break;
    485 	}
    486 
    487 	case IOV_SVAL(IOV_SPIERRSTATS):
    488 	{
    489 		bzero(&si->spierrstats, sizeof(struct spierrstats_t));
    490 		break;
    491 	}
    492 
    493 	case IOV_GVAL(IOV_RESP_DELAY_ALL):
    494 		int_val = (int32)si->resp_delay_all;
    495 		bcopy(&int_val, arg, val_size);
    496 		break;
    497 
    498 	case IOV_SVAL(IOV_RESP_DELAY_ALL):
    499 		si->resp_delay_all = (bool)int_val;
    500 		int_val = STATUS_ENABLE|INTR_WITH_STATUS;
    501 		if (si->resp_delay_all)
    502 			int_val |= RESP_DELAY_ALL;
    503 		else {
    504 			if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_RESPONSE_DELAY, 1,
    505 			     F1_RESPONSE_DELAY) != SUCCESS) {
    506 				sd_err(("%s: Unable to set response delay.\n", __FUNCTION__));
    507 				bcmerror = BCME_SDIO_ERROR;
    508 				break;
    509 			}
    510 		}
    511 
    512 		if (bcmspi_card_regwrite(si, SPI_FUNC_0, SPID_STATUS_ENABLE, 1, int_val)
    513 		     != SUCCESS) {
    514 			sd_err(("%s: Unable to set response delay.\n", __FUNCTION__));
    515 			bcmerror = BCME_SDIO_ERROR;
    516 			break;
    517 		}
    518 		break;
    519 
    520 	default:
    521 		bcmerror = BCME_UNSUPPORTED;
    522 		break;
    523 	}
    524 exit:
    525 
    526 	return bcmerror;
    527 }
    528 
    529 extern SDIOH_API_RC
    530 sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
    531 {
    532 	SDIOH_API_RC status;
    533 	/* No lock needed since sdioh_request_byte does locking */
    534 	status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
    535 	return status;
    536 }
    537 
    538 extern SDIOH_API_RC
    539 sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
    540 {
    541 	/* No lock needed since sdioh_request_byte does locking */
    542 	SDIOH_API_RC status;
    543 
    544 	if ((fnc_num == SPI_FUNC_1) && (addr == SBSDIO_FUNC1_FRAMECTRL)) {
    545 		uint8 dummy_data;
    546 		status = sdioh_cfg_read(sd, fnc_num, addr, &dummy_data);
    547 		if (status) {
    548 			sd_err(("sdioh_cfg_read() failed.\n"));
    549 			return status;
    550 		}
    551 	}
    552 
    553 	status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
    554 	return status;
    555 }
    556 
    557 extern SDIOH_API_RC
    558 sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
    559 {
    560 	uint32 count;
    561 	int offset;
    562 	uint32 cis_byte;
    563 	uint16 *cis = (uint16 *)cisd;
    564 	uint bar0 = SI_ENUM_BASE;
    565 	int status;
    566 	uint8 data;
    567 
    568 	sd_trace(("%s: Func %d\n", __FUNCTION__, func));
    569 
    570 	spi_lock(sd);
    571 
    572 	/* Set sb window address to 0x18000000 */
    573 	data = (bar0 >> 8) & SBSDIO_SBADDRLOW_MASK;
    574 	status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, &data);
    575 	if (status == SUCCESS) {
    576 		data = (bar0 >> 16) & SBSDIO_SBADDRMID_MASK;
    577 		status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, &data);
    578 	} else {
    579 		sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__));
    580 		spi_unlock(sd);
    581 		return (BCME_ERROR);
    582 	}
    583 	if (status == SUCCESS) {
    584 		data = (bar0 >> 24) & SBSDIO_SBADDRHIGH_MASK;
    585 		status = bcmspi_card_bytewrite(sd, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, &data);
    586 	} else {
    587 		sd_err(("%s: Unable to set sb-addr-windows\n", __FUNCTION__));
    588 		spi_unlock(sd);
    589 		return (BCME_ERROR);
    590 	}
    591 
    592 	offset =  CC_OTP; /* OTP offset in chipcommon. */
    593 	for (count = 0; count < length/2; count++) {
    594 		if (bcmspi_card_regread (sd, SDIO_FUNC_1, offset, 2, &cis_byte) < 0) {
    595 			sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__));
    596 			spi_unlock(sd);
    597 			return (BCME_ERROR);
    598 		}
    599 
    600 		*cis = (uint16)cis_byte;
    601 		cis++;
    602 		offset += 2;
    603 	}
    604 
    605 	spi_unlock(sd);
    606 
    607 	return (BCME_OK);
    608 }
    609 
    610 extern SDIOH_API_RC
    611 sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
    612 {
    613 	int status;
    614 	uint32 cmd_arg;
    615 	uint32 dstatus;
    616 	uint32 data = (uint32)(*byte);
    617 
    618 	spi_lock(sd);
    619 
    620 	cmd_arg = 0;
    621 	cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
    622 	cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1);	/* Incremental access */
    623 	cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
    624 	cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, rw == SDIOH_READ ? 0 : 1);
    625 	cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1);
    626 
    627 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
    628 	sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, rw, func,
    629 	         regaddr, data));
    630 
    631 	if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma,
    632 	                              cmd_arg, &data, 1)) != SUCCESS) {
    633 		spi_unlock(sd);
    634 		return status;
    635 	}
    636 
    637 	if (rw == SDIOH_READ)
    638 		*byte = (uint8)data;
    639 
    640 	bcmspi_cmd_getdstatus(sd, &dstatus);
    641 	if (dstatus)
    642 		sd_trace(("dstatus =0x%x\n", dstatus));
    643 
    644 	spi_unlock(sd);
    645 	return SDIOH_API_RC_SUCCESS;
    646 }
    647 
    648 extern SDIOH_API_RC
    649 sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr,
    650                    uint32 *word, uint nbytes)
    651 {
    652 	int status;
    653 
    654 	spi_lock(sd);
    655 
    656 	if (rw == SDIOH_READ)
    657 		status = bcmspi_card_regread(sd, func, addr, nbytes, word);
    658 	else
    659 		status = bcmspi_card_regwrite(sd, func, addr, nbytes, *word);
    660 
    661 	spi_unlock(sd);
    662 	return (status == SUCCESS ?  SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
    663 }
    664 
    665 extern SDIOH_API_RC
    666 sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func,
    667                      uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
    668 {
    669 	int len;
    670 	int buflen = (int)buflen_u;
    671 	bool fifo = (fix_inc == SDIOH_DATA_FIX);
    672 
    673 	spi_lock(sd);
    674 
    675 	ASSERT(reg_width == 4);
    676 	ASSERT(buflen_u < (1 << 30));
    677 	ASSERT(sd->client_block_size[func]);
    678 
    679 	sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n",
    680 	         __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W',
    681 	         buflen_u, sd->r_cnt, sd->t_cnt, pkt));
    682 
    683 	/* Break buffer down into blocksize chunks. */
    684 	while (buflen > 0) {
    685 		len = MIN(sd->client_block_size[func], buflen);
    686 		if (bcmspi_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) {
    687 			sd_err(("%s: bcmspi_card_buf %s failed\n",
    688 				__FUNCTION__, rw == SDIOH_READ ? "Read" : "Write"));
    689 			spi_unlock(sd);
    690 			return SDIOH_API_RC_FAIL;
    691 		}
    692 		buffer += len;
    693 		buflen -= len;
    694 		if (!fifo)
    695 			addr += len;
    696 	}
    697 	spi_unlock(sd);
    698 	return SDIOH_API_RC_SUCCESS;
    699 }
    700 
    701 /* This function allows write to gspi bus when another rd/wr function is deep down the call stack.
    702  * Its main aim is to have simpler spi writes rather than recursive writes.
    703  * e.g. When there is a need to program response delay on the fly after detecting the SPI-func
    704  * this call will allow to program the response delay.
    705  */
    706 static int
    707 bcmspi_card_byterewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 byte)
    708 {
    709 	uint32 cmd_arg;
    710 	uint32 datalen = 1;
    711 	uint32 hostlen;
    712 
    713 	cmd_arg = 0;
    714 
    715 	cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1);
    716 	cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1);	/* Incremental access */
    717 	cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
    718 	cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
    719 	cmd_arg = SFIELD(cmd_arg, SPI_LEN, datalen);
    720 
    721 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
    722 
    723 
    724 	/* Set up and issue the SPI command.  MSByte goes out on bus first.  Increase datalen
    725 	 * according to the wordlen mode(16/32bit) the device is in.
    726 	 */
    727 	ASSERT(sd->wordlen == 4 || sd->wordlen == 2);
    728 	datalen = ROUNDUP(datalen, sd->wordlen);
    729 
    730 	/* Start by copying command in the spi-outbuffer */
    731 	if (sd->wordlen == 4) { /* 32bit spid */
    732 		*(uint32 *)spi_outbuf2 = bcmswap32(cmd_arg);
    733 		if (datalen & 0x3)
    734 			datalen += (4 - (datalen & 0x3));
    735 	} else if (sd->wordlen == 2) { /* 16bit spid */
    736 		*(uint16 *)spi_outbuf2 = bcmswap16(cmd_arg & 0xffff);
    737 		*(uint16 *)&spi_outbuf2[2] = bcmswap16((cmd_arg & 0xffff0000) >> 16);
    738 		if (datalen & 0x1)
    739 			datalen++;
    740 	} else {
    741 		sd_err(("%s: Host is %d bit spid, could not create SPI command.\n",
    742 		        __FUNCTION__, 8 * sd->wordlen));
    743 		return ERROR;
    744 	}
    745 
    746 	/* for Write, put the data into the output buffer  */
    747 	if (datalen != 0) {
    748 			if (sd->wordlen == 4) { /* 32bit spid */
    749 				*(uint32 *)&spi_outbuf2[CMDLEN] = bcmswap32(byte);
    750 			} else if (sd->wordlen == 2) { /* 16bit spid */
    751 				*(uint16 *)&spi_outbuf2[CMDLEN] = bcmswap16(byte & 0xffff);
    752 				*(uint16 *)&spi_outbuf2[CMDLEN + 2] =
    753 					bcmswap16((byte & 0xffff0000) >> 16);
    754 			}
    755 	}
    756 
    757 	/* +4 for cmd, +4 for dstatus */
    758 	hostlen = datalen + 8;
    759 	hostlen += (4 - (hostlen & 0x3));
    760 	spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, hostlen);
    761 
    762 	/* Last 4bytes are dstatus.  Device is configured to return status bits. */
    763 	if (sd->wordlen == 4) { /* 32bit spid */
    764 		sd->card_dstatus = bcmswap32(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]);
    765 	} else if (sd->wordlen == 2) { /* 16bit spid */
    766 		sd->card_dstatus = (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN ]) |
    767 		                   (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN + 2]) << 16));
    768 	} else {
    769 		sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n",
    770 		        __FUNCTION__, 8 * sd->wordlen));
    771 		return ERROR;
    772 	}
    773 
    774 	if (sd->card_dstatus)
    775 		sd_trace(("dstatus after byte rewrite = 0x%x\n", sd->card_dstatus));
    776 
    777 	return (BCME_OK);
    778 }
    779 
    780 /* Program the response delay corresponding to the spi function */
    781 static int
    782 bcmspi_prog_resp_delay(sdioh_info_t *sd, int func, uint8 resp_delay)
    783 {
    784 	if (sd->resp_delay_all == FALSE)
    785 		return (BCME_OK);
    786 
    787 	if (sd->prev_fun == func)
    788 		return (BCME_OK);
    789 
    790 	if (F0_RESPONSE_DELAY == F1_RESPONSE_DELAY)
    791 		return (BCME_OK);
    792 
    793 	bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_RESPONSE_DELAY, resp_delay);
    794 
    795 	/* Remember function for which to avoid reprogramming resp-delay in next iteration */
    796 	sd->prev_fun = func;
    797 
    798 	return (BCME_OK);
    799 
    800 }
    801 
    802 #define GSPI_RESYNC_PATTERN	0x0
    803 
    804 /* A resync pattern is a 32bit MOSI line with all zeros. Its a special command in gSPI.
    805  * It resets the spi-bkplane logic so that all F1 related ping-pong buffer logic is
    806  * synchronised and all queued resuests are cancelled.
    807  */
    808 static int
    809 bcmspi_resync_f1(sdioh_info_t *sd)
    810 {
    811 	uint32 cmd_arg = GSPI_RESYNC_PATTERN, data = 0, datalen = 0;
    812 
    813 
    814 	/* Set up and issue the SPI command.  MSByte goes out on bus first.  Increase datalen
    815 	 * according to the wordlen mode(16/32bit) the device is in.
    816 	 */
    817 	ASSERT(sd->wordlen == 4 || sd->wordlen == 2);
    818 	datalen = ROUNDUP(datalen, sd->wordlen);
    819 
    820 	/* Start by copying command in the spi-outbuffer */
    821 	*(uint32 *)spi_outbuf2 = cmd_arg;
    822 
    823 	/* for Write, put the data into the output buffer  */
    824 	*(uint32 *)&spi_outbuf2[CMDLEN] = data;
    825 
    826 	/* +4 for cmd, +4 for dstatus */
    827 	spi_sendrecv(sd, spi_outbuf2, spi_inbuf2, datalen + 8);
    828 
    829 	/* Last 4bytes are dstatus.  Device is configured to return status bits. */
    830 	if (sd->wordlen == 4) { /* 32bit spid */
    831 		sd->card_dstatus = bcmswap32(*(uint32 *)&spi_inbuf2[datalen + CMDLEN ]);
    832 	} else if (sd->wordlen == 2) { /* 16bit spid */
    833 		sd->card_dstatus = (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN ]) |
    834 		                   (bcmswap16(*(uint16 *)&spi_inbuf2[datalen + CMDLEN + 2]) << 16));
    835 	} else {
    836 		sd_err(("%s: Host is %d bit machine, could not read SPI dstatus.\n",
    837 		        __FUNCTION__, 8 * sd->wordlen));
    838 		return ERROR;
    839 	}
    840 
    841 	if (sd->card_dstatus)
    842 		sd_trace(("dstatus after resync pattern write = 0x%x\n", sd->card_dstatus));
    843 
    844 	return (BCME_OK);
    845 }
    846 
    847 uint32 dstatus_count = 0;
    848 
    849 static int
    850 bcmspi_update_stats(sdioh_info_t *sd, uint32 cmd_arg)
    851 {
    852 	uint32 dstatus = sd->card_dstatus;
    853 	struct spierrstats_t *spierrstats = &sd->spierrstats;
    854 	int err = SUCCESS;
    855 
    856 	sd_trace(("cmd = 0x%x, dstatus = 0x%x\n", cmd_arg, dstatus));
    857 
    858 	/* Store dstatus of last few gSPI transactions */
    859 	spierrstats->dstatus[dstatus_count % NUM_PREV_TRANSACTIONS] = dstatus;
    860 	spierrstats->spicmd[dstatus_count % NUM_PREV_TRANSACTIONS] = cmd_arg;
    861 	dstatus_count++;
    862 
    863 	if (sd->card_init_done == FALSE)
    864 		return err;
    865 
    866 	if (dstatus & STATUS_DATA_NOT_AVAILABLE) {
    867 		spierrstats->dna++;
    868 		sd_trace(("Read data not available on F1 addr = 0x%x\n",
    869 		        GFIELD(cmd_arg, SPI_REG_ADDR)));
    870 		/* Clear dna bit */
    871 		bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, DATA_UNAVAILABLE);
    872 	}
    873 
    874 	if (dstatus & STATUS_UNDERFLOW) {
    875 		spierrstats->rdunderflow++;
    876 		sd_err(("FIFO underflow happened due to current F2 read command.\n"));
    877 	}
    878 
    879 	if (dstatus & STATUS_OVERFLOW) {
    880 		spierrstats->wroverflow++;
    881 		sd_err(("FIFO overflow happened due to current (F1/F2) write command.\n"));
    882 		if ((sd->chip == BCM4329_CHIP_ID) && (sd->chiprev == 0)) {
    883 			bcmspi_card_byterewrite(sd, SPI_FUNC_0, SPID_INTR_REG, F1_OVERFLOW);
    884 			bcmspi_resync_f1(sd);
    885 			sd_err(("Recovering from F1 FIFO overflow.\n"));
    886 		} else {
    887 			err = ERROR_OF;
    888 		}
    889 	}
    890 
    891 	if (dstatus & STATUS_F2_INTR) {
    892 		spierrstats->f2interrupt++;
    893 		sd_trace(("Interrupt from F2.  SW should clear corresponding IntStatus bits\n"));
    894 	}
    895 
    896 	if (dstatus & STATUS_F3_INTR) {
    897 		spierrstats->f3interrupt++;
    898 		sd_err(("Interrupt from F3.  SW should clear corresponding IntStatus bits\n"));
    899 	}
    900 
    901 	if (dstatus & STATUS_HOST_CMD_DATA_ERR) {
    902 		spierrstats->hostcmddataerr++;
    903 		sd_err(("Error in CMD or Host data, detected by CRC/Checksum (optional)\n"));
    904 	}
    905 
    906 	if (dstatus & STATUS_F2_PKT_AVAILABLE) {
    907 		spierrstats->f2pktavailable++;
    908 		sd_trace(("Packet is available/ready in F2 TX FIFO\n"));
    909 		sd_trace(("Packet length = %d\n", sd->dwordmode ?
    910 		         ((dstatus & STATUS_F2_PKT_LEN_MASK) >> (STATUS_F2_PKT_LEN_SHIFT - 2)) :
    911 		         ((dstatus & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT)));
    912 	}
    913 
    914 	if (dstatus & STATUS_F3_PKT_AVAILABLE) {
    915 		spierrstats->f3pktavailable++;
    916 		sd_err(("Packet is available/ready in F3 TX FIFO\n"));
    917 		sd_err(("Packet length = %d\n",
    918 		        (dstatus & STATUS_F3_PKT_LEN_MASK) >> STATUS_F3_PKT_LEN_SHIFT));
    919 	}
    920 
    921 	return err;
    922 }
    923 
    924 extern int
    925 sdioh_abort(sdioh_info_t *sd, uint func)
    926 {
    927 	return 0;
    928 }
    929 
    930 int
    931 sdioh_start(sdioh_info_t *sd, int stage)
    932 {
    933 	return SUCCESS;
    934 }
    935 
    936 int
    937 sdioh_stop(sdioh_info_t *sd)
    938 {
    939 	return SUCCESS;
    940 }
    941 
    942 
    943 
    944 /*
    945  * Private/Static work routines
    946  */
    947 static int
    948 bcmspi_host_init(sdioh_info_t *sd)
    949 {
    950 
    951 	/* Default power on mode */
    952 	sd->sd_mode = SDIOH_MODE_SPI;
    953 	sd->polled_mode = TRUE;
    954 	sd->host_init_done = TRUE;
    955 	sd->card_init_done = FALSE;
    956 	sd->adapter_slot = 1;
    957 
    958 	return (SUCCESS);
    959 }
    960 
    961 static int
    962 get_client_blocksize(sdioh_info_t *sd)
    963 {
    964 	uint32 regdata[2];
    965 	int status;
    966 
    967 	/* Find F1/F2/F3 max packet size */
    968 	if ((status = bcmspi_card_regread(sd, 0, SPID_F1_INFO_REG,
    969 	                                 8, regdata)) != SUCCESS) {
    970 		return status;
    971 	}
    972 
    973 	sd_trace(("pkt_size regdata[0] = 0x%x, regdata[1] = 0x%x\n",
    974 	        regdata[0], regdata[1]));
    975 
    976 	sd->client_block_size[1] = (regdata[0] & F1_MAX_PKT_SIZE) >> 2;
    977 	sd_trace(("Func1 blocksize = %d\n", sd->client_block_size[1]));
    978 	ASSERT(sd->client_block_size[1] == BLOCK_SIZE_F1);
    979 
    980 	sd->client_block_size[2] = ((regdata[0] >> 16) & F2_MAX_PKT_SIZE) >> 2;
    981 	sd_trace(("Func2 blocksize = %d\n", sd->client_block_size[2]));
    982 	ASSERT(sd->client_block_size[2] == BLOCK_SIZE_F2);
    983 
    984 	sd->client_block_size[3] = (regdata[1] & F3_MAX_PKT_SIZE) >> 2;
    985 	sd_trace(("Func3 blocksize = %d\n", sd->client_block_size[3]));
    986 	ASSERT(sd->client_block_size[3] == BLOCK_SIZE_F3);
    987 
    988 	return 0;
    989 }
    990 
    991 static int
    992 bcmspi_client_init(sdioh_info_t *sd)
    993 {
    994 	uint32	status_en_reg = 0;
    995 	sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot));
    996 
    997 #ifdef HSMODE
    998 	if (!spi_start_clock(sd, (uint16)sd_divisor)) {
    999 		sd_err(("spi_start_clock failed\n"));
   1000 		return ERROR;
   1001 	}
   1002 #else
   1003 	/* Start at ~400KHz clock rate for initialization */
   1004 	if (!spi_start_clock(sd, 128)) {
   1005 		sd_err(("spi_start_clock failed\n"));
   1006 		return ERROR;
   1007 	}
   1008 #endif /* HSMODE */
   1009 
   1010 	if (!bcmspi_host_device_init_adapt(sd)) {
   1011 		sd_err(("bcmspi_host_device_init_adapt failed\n"));
   1012 		return ERROR;
   1013 	}
   1014 
   1015 	if (!bcmspi_test_card(sd)) {
   1016 		sd_err(("bcmspi_test_card failed\n"));
   1017 		return ERROR;
   1018 	}
   1019 
   1020 	sd->num_funcs = SPI_MAX_IOFUNCS;
   1021 
   1022 	get_client_blocksize(sd);
   1023 
   1024 	/* Apply resync pattern cmd with all zeros to reset spi-bkplane F1 logic */
   1025 	bcmspi_resync_f1(sd);
   1026 
   1027 	sd->dwordmode = FALSE;
   1028 
   1029 	bcmspi_card_regread(sd, 0, SPID_STATUS_ENABLE, 1, &status_en_reg);
   1030 
   1031 	sd_trace(("%s: Enabling interrupt with dstatus \n", __FUNCTION__));
   1032 	status_en_reg |= INTR_WITH_STATUS;
   1033 
   1034 
   1035 	if (bcmspi_card_regwrite(sd, SPI_FUNC_0, SPID_STATUS_ENABLE, 1,
   1036 	    status_en_reg & 0xff) != SUCCESS) {
   1037 		sd_err(("%s: Unable to set response delay for all fun's.\n", __FUNCTION__));
   1038 		return ERROR;
   1039 	}
   1040 
   1041 
   1042 #ifndef HSMODE
   1043 	/* After configuring for High-Speed mode, set the desired clock rate. */
   1044 	if (!spi_start_clock(sd, 4)) {
   1045 		sd_err(("spi_start_clock failed\n"));
   1046 		return ERROR;
   1047 	}
   1048 #endif /* HSMODE */
   1049 
   1050 	sd->card_init_done = TRUE;
   1051 
   1052 
   1053 	return SUCCESS;
   1054 }
   1055 
   1056 static int
   1057 bcmspi_set_highspeed_mode(sdioh_info_t *sd, bool hsmode)
   1058 {
   1059 	uint32 regdata;
   1060 	int status;
   1061 
   1062 	if ((status = bcmspi_card_regread(sd, 0, SPID_CONFIG,
   1063 	                                 4, &regdata)) != SUCCESS)
   1064 		return status;
   1065 
   1066 	sd_trace(("In %s spih-ctrl = 0x%x \n", __FUNCTION__, regdata));
   1067 
   1068 
   1069 	if (hsmode == TRUE) {
   1070 		sd_trace(("Attempting to enable High-Speed mode.\n"));
   1071 
   1072 		if (regdata & HIGH_SPEED_MODE) {
   1073 			sd_trace(("Device is already in High-Speed mode.\n"));
   1074 			return status;
   1075 		} else {
   1076 			regdata |= HIGH_SPEED_MODE;
   1077 			sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG));
   1078 			if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG,
   1079 			                                  4, regdata)) != SUCCESS) {
   1080 				return status;
   1081 			}
   1082 		}
   1083 	} else {
   1084 		sd_trace(("Attempting to disable High-Speed mode.\n"));
   1085 
   1086 		if (regdata & HIGH_SPEED_MODE) {
   1087 			regdata &= ~HIGH_SPEED_MODE;
   1088 			sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG));
   1089 			if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG,
   1090 			                                  4, regdata)) != SUCCESS)
   1091 				return status;
   1092 		}
   1093 		 else {
   1094 			sd_trace(("Device is already in Low-Speed mode.\n"));
   1095 			return status;
   1096 		}
   1097 	}
   1098 
   1099 	spi_controller_highspeed_mode(sd, hsmode);
   1100 
   1101 	return TRUE;
   1102 }
   1103 
   1104 #define bcmspi_find_curr_mode(sd) { \
   1105 	sd->wordlen = 2; \
   1106 	status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, &regdata); \
   1107 	regdata &= 0xff; \
   1108 	if ((regdata == 0xad) || (regdata == 0x5b) || \
   1109 	    (regdata == 0x5d) || (regdata == 0x5a)) \
   1110 		break; \
   1111 	sd->wordlen = 4; \
   1112 	status = bcmspi_card_regread_fixedaddr(sd, 0, SPID_TEST_READ, 4, &regdata); \
   1113 	regdata &= 0xff; \
   1114 	if ((regdata == 0xad) || (regdata == 0x5b) || \
   1115 	    (regdata == 0x5d) || (regdata == 0x5a)) \
   1116 		break; \
   1117 	sd_trace(("Silicon testability issue: regdata = 0x%x." \
   1118 	          " Expected 0xad, 0x5a, 0x5b or 0x5d.\n", regdata));	\
   1119 	OSL_DELAY(100000); \
   1120 }
   1121 
   1122 #define INIT_ADAPT_LOOP		100
   1123 
   1124 /* Adapt clock-phase-speed-bitwidth between host and device */
   1125 static bool
   1126 bcmspi_host_device_init_adapt(sdioh_info_t *sd)
   1127 {
   1128 	uint32 wrregdata, regdata = 0;
   1129 	int status;
   1130 	int i;
   1131 
   1132 	/* Due to a silicon testability issue, the first command from the Host
   1133 	 * to the device will get corrupted (first bit will be lost). So the
   1134 	 * Host should poll the device with a safe read request. ie: The Host
   1135 	 * should try to read F0 addr 0x14 using the Fixed address mode
   1136 	 * (This will prevent a unintended write command to be detected by device)
   1137 	 */
   1138 	for (i = 0; i < INIT_ADAPT_LOOP; i++) {
   1139 		/* If device was not power-cycled it will stay in 32bit mode with
   1140 		 * response-delay-all bit set.  Alternate the iteration so that
   1141 		 * read either with or without response-delay for F0 to succeed.
   1142 		 */
   1143 		bcmspi_find_curr_mode(sd);
   1144 		sd->resp_delay_all = (i & 0x1) ? TRUE : FALSE;
   1145 
   1146 		bcmspi_find_curr_mode(sd);
   1147 		sd->dwordmode = TRUE;
   1148 
   1149 		bcmspi_find_curr_mode(sd);
   1150 		sd->dwordmode = FALSE;
   1151 	}
   1152 
   1153 	/* Bail out, device not detected */
   1154 	if (i == INIT_ADAPT_LOOP)
   1155 		return FALSE;
   1156 
   1157 	/* Softreset the spid logic */
   1158 	if ((sd->dwordmode) || (sd->wordlen == 4)) {
   1159 		bcmspi_card_regwrite(sd, 0, SPID_RESET_BP, 1, RESET_ON_WLAN_BP_RESET|RESET_SPI);
   1160 		bcmspi_card_regread(sd, 0, SPID_RESET_BP, 1, &regdata);
   1161 		sd_trace(("reset reg read = 0x%x\n", regdata));
   1162 		sd_trace(("dwordmode = %d, wordlen = %d, resp_delay_all = %d\n", sd->dwordmode,
   1163 		       sd->wordlen, sd->resp_delay_all));
   1164 		/* Restore default state after softreset */
   1165 		sd->wordlen = 2;
   1166 		sd->dwordmode = FALSE;
   1167 	}
   1168 
   1169 	if (sd->wordlen == 4) {
   1170 		if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) !=
   1171 		     SUCCESS)
   1172 				return FALSE;
   1173 		if (regdata == TEST_RO_DATA_32BIT_LE) {
   1174 			sd_trace(("Spid is already in 32bit LE mode. Value read = 0x%x\n",
   1175 			          regdata));
   1176 			sd_trace(("Spid power was left on.\n"));
   1177 		} else {
   1178 			sd_err(("Spid power was left on but signature read failed."
   1179 			        " Value read = 0x%x\n", regdata));
   1180 			return FALSE;
   1181 		}
   1182 	} else {
   1183 		sd->wordlen = 2;
   1184 
   1185 #define CTRL_REG_DEFAULT	0x00010430 /* according to the host m/c */
   1186 
   1187 		wrregdata = (CTRL_REG_DEFAULT);
   1188 		sd->resp_delay_all = TRUE;
   1189 		if (sd->resp_delay_all == TRUE) {
   1190 			/* Enable response delay for all */
   1191 			wrregdata |= (RESP_DELAY_ALL << 16);
   1192 			/* Program response delay value */
   1193 			wrregdata &= 0xffff00ff;
   1194 			wrregdata |= (F1_RESPONSE_DELAY << 8);
   1195 			sd->prev_fun = SPI_FUNC_1;
   1196 			bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata);
   1197 		}
   1198 
   1199 		if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) != SUCCESS)
   1200 			return FALSE;
   1201 		sd_trace(("(we are still in 16bit mode) 32bit READ LE regdata = 0x%x\n", regdata));
   1202 
   1203 #ifndef HSMODE
   1204 		wrregdata |= (CLOCK_PHASE | CLOCK_POLARITY);
   1205 		wrregdata &= ~HIGH_SPEED_MODE;
   1206 		bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata);
   1207 #endif /* HSMODE */
   1208 
   1209 		for (i = 0; i < INIT_ADAPT_LOOP; i++) {
   1210 			if ((regdata == 0xfdda7d5b) || (regdata == 0xfdda7d5a)) {
   1211 				sd_trace(("0xfeedbead was leftshifted by 1-bit.\n"));
   1212 				if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4,
   1213 				     &regdata)) != SUCCESS)
   1214 					return FALSE;
   1215 			}
   1216 			OSL_DELAY(1000);
   1217 		}
   1218 
   1219 
   1220 		/* Change to host controller intr-polarity of active-low */
   1221 		wrregdata &= ~INTR_POLARITY;
   1222 		sd_trace(("(we are still in 16bit mode) 32bit Write LE reg-ctrl-data = 0x%x\n",
   1223 		        wrregdata));
   1224 		/* Change to 32bit mode */
   1225 		wrregdata |= WORD_LENGTH_32;
   1226 		bcmspi_card_regwrite(sd, 0, SPID_CONFIG, 4, wrregdata);
   1227 
   1228 		/* Change command/data packaging in 32bit LE mode */
   1229 		sd->wordlen = 4;
   1230 
   1231 		if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) != SUCCESS)
   1232 			return FALSE;
   1233 
   1234 		if (regdata == TEST_RO_DATA_32BIT_LE) {
   1235 			sd_trace(("Read spid passed. Value read = 0x%x\n", regdata));
   1236 			sd_trace(("Spid had power-on cycle OR spi was soft-resetted \n"));
   1237 		} else {
   1238 			sd_err(("Stale spid reg values read as it was kept powered. Value read ="
   1239 			  "0x%x\n", regdata));
   1240 			return FALSE;
   1241 		}
   1242 	}
   1243 
   1244 
   1245 	return TRUE;
   1246 }
   1247 
   1248 static bool
   1249 bcmspi_test_card(sdioh_info_t *sd)
   1250 {
   1251 	uint32 regdata;
   1252 	int status;
   1253 
   1254 	if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_READ, 4, &regdata)) != SUCCESS)
   1255 		return FALSE;
   1256 
   1257 	if (regdata == (TEST_RO_DATA_32BIT_LE))
   1258 		sd_trace(("32bit LE regdata = 0x%x\n", regdata));
   1259 	else {
   1260 		sd_trace(("Incorrect 32bit LE regdata = 0x%x\n", regdata));
   1261 		return FALSE;
   1262 	}
   1263 
   1264 
   1265 #define RW_PATTERN1	0xA0A1A2A3
   1266 #define RW_PATTERN2	0x4B5B6B7B
   1267 
   1268 	regdata = RW_PATTERN1;
   1269 	if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS)
   1270 		return FALSE;
   1271 	regdata = 0;
   1272 	if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, &regdata)) != SUCCESS)
   1273 		return FALSE;
   1274 	if (regdata != RW_PATTERN1) {
   1275 		sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n",
   1276 			RW_PATTERN1, regdata));
   1277 		return FALSE;
   1278 	} else
   1279 		sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata));
   1280 
   1281 	regdata = RW_PATTERN2;
   1282 	if ((status = bcmspi_card_regwrite(sd, 0, SPID_TEST_RW, 4, regdata)) != SUCCESS)
   1283 		return FALSE;
   1284 	regdata = 0;
   1285 	if ((status = bcmspi_card_regread(sd, 0, SPID_TEST_RW, 4, &regdata)) != SUCCESS)
   1286 		return FALSE;
   1287 	if (regdata != RW_PATTERN2) {
   1288 		sd_err(("Write-Read spid failed. Value wrote = 0x%x, Value read = 0x%x\n",
   1289 			RW_PATTERN2, regdata));
   1290 		return FALSE;
   1291 	} else
   1292 		sd_trace(("R/W spid passed. Value read = 0x%x\n", regdata));
   1293 
   1294 	return TRUE;
   1295 }
   1296 
   1297 static int
   1298 bcmspi_driver_init(sdioh_info_t *sd)
   1299 {
   1300 	sd_trace(("%s\n", __FUNCTION__));
   1301 	if ((bcmspi_host_init(sd)) != SUCCESS) {
   1302 		return ERROR;
   1303 	}
   1304 
   1305 	if (bcmspi_client_init(sd) != SUCCESS) {
   1306 		return ERROR;
   1307 	}
   1308 
   1309 	return SUCCESS;
   1310 }
   1311 
   1312 /* Read device reg */
   1313 static int
   1314 bcmspi_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data)
   1315 {
   1316 	int status;
   1317 	uint32 cmd_arg, dstatus;
   1318 
   1319 	ASSERT(regsize);
   1320 
   1321 	if (func == 2)
   1322 		sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n"));
   1323 
   1324 	cmd_arg = 0;
   1325 	cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0);
   1326 	cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1);	/* Incremental access */
   1327 	cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
   1328 	cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
   1329 	cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize);
   1330 
   1331 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
   1332 	sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, 0, func,
   1333 	         regaddr, *data));
   1334 
   1335 	if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize))
   1336 	    != SUCCESS)
   1337 		return status;
   1338 
   1339 	bcmspi_cmd_getdstatus(sd, &dstatus);
   1340 	if (dstatus)
   1341 		sd_trace(("dstatus =0x%x\n", dstatus));
   1342 
   1343 	return SUCCESS;
   1344 }
   1345 
   1346 static int
   1347 bcmspi_card_regread_fixedaddr(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data)
   1348 {
   1349 
   1350 	int status;
   1351 	uint32 cmd_arg;
   1352 	uint32 dstatus;
   1353 
   1354 	ASSERT(regsize);
   1355 
   1356 	if (func == 2)
   1357 		sd_trace(("Reg access on F2 will generate error indication in dstatus bits.\n"));
   1358 
   1359 	cmd_arg = 0;
   1360 	cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 0);
   1361 	cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0);	/* Fixed access */
   1362 	cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
   1363 	cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
   1364 	cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize);
   1365 
   1366 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
   1367 
   1368 	if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, regsize))
   1369 	    != SUCCESS)
   1370 		return status;
   1371 
   1372 	sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, 0, func,
   1373 	         regaddr, *data));
   1374 
   1375 	bcmspi_cmd_getdstatus(sd, &dstatus);
   1376 	sd_trace(("dstatus =0x%x\n", dstatus));
   1377 	return SUCCESS;
   1378 }
   1379 
   1380 /* write a device register */
   1381 static int
   1382 bcmspi_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data)
   1383 {
   1384 	int status;
   1385 	uint32 cmd_arg, dstatus;
   1386 
   1387 	ASSERT(regsize);
   1388 
   1389 	cmd_arg = 0;
   1390 
   1391 	cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1);
   1392 	cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1);	/* Incremental access */
   1393 	cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
   1394 	cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
   1395 	cmd_arg = SFIELD(cmd_arg, SPI_LEN, regsize == BLOCK_SIZE_F2 ? 0 : regsize);
   1396 
   1397 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
   1398 	sd_trace(("%s: rw=%d, func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, 1, func,
   1399 	         regaddr, data));
   1400 
   1401 
   1402 	if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, &data, regsize))
   1403 	    != SUCCESS)
   1404 		return status;
   1405 
   1406 	bcmspi_cmd_getdstatus(sd, &dstatus);
   1407 	if (dstatus)
   1408 		sd_trace(("dstatus =0x%x\n", dstatus));
   1409 
   1410 	return SUCCESS;
   1411 }
   1412 
   1413 /* write a device register - 1 byte */
   1414 static int
   1415 bcmspi_card_bytewrite(sdioh_info_t *sd, int func, uint32 regaddr, uint8 *byte)
   1416 {
   1417 	int status;
   1418 	uint32 cmd_arg;
   1419 	uint32 dstatus;
   1420 	uint32 data = (uint32)(*byte);
   1421 
   1422 	cmd_arg = 0;
   1423 	cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
   1424 	cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1);	/* Incremental access */
   1425 	cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, regaddr);
   1426 	cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, 1);
   1427 	cmd_arg = SFIELD(cmd_arg, SPI_LEN, 1);
   1428 
   1429 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
   1430 	sd_trace(("%s: func=%d, regaddr=0x%08x, data=0x%x\n", __FUNCTION__, func,
   1431 	         regaddr, data));
   1432 
   1433 	if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma,
   1434 	                              cmd_arg, &data, 1)) != SUCCESS) {
   1435 		return status;
   1436 	}
   1437 
   1438 	bcmspi_cmd_getdstatus(sd, &dstatus);
   1439 	if (dstatus)
   1440 		sd_trace(("dstatus =0x%x\n", dstatus));
   1441 
   1442 	return SUCCESS;
   1443 }
   1444 
   1445 void
   1446 bcmspi_cmd_getdstatus(sdioh_info_t *sd, uint32 *dstatus_buffer)
   1447 {
   1448 	*dstatus_buffer = sd->card_dstatus;
   1449 }
   1450 
   1451 /* 'data' is of type uint32 whereas other buffers are of type uint8 */
   1452 static int
   1453 bcmspi_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd_arg,
   1454                 uint32 *data, uint32 datalen)
   1455 {
   1456 	uint32	i, j;
   1457 	uint8	resp_delay = 0;
   1458 	int	err = SUCCESS;
   1459 	uint32	hostlen;
   1460 	uint32 spilen = 0;
   1461 	uint32 dstatus_idx = 0;
   1462 	uint16 templen, buslen, len, *ptr = NULL;
   1463 
   1464 	sd_trace(("spi cmd = 0x%x\n", cmd_arg));
   1465 
   1466 	if (DWORDMODE_ON) {
   1467 		spilen = GFIELD(cmd_arg, SPI_LEN);
   1468 		if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_0) ||
   1469 		    (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_1))
   1470 			dstatus_idx = spilen * 3;
   1471 
   1472 		if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) &&
   1473 		    (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) {
   1474 			spilen = spilen << 2;
   1475 			dstatus_idx = (spilen % 16) ? (16 - (spilen % 16)) : 0;
   1476 			/* convert len to mod16 size */
   1477 			spilen = ROUNDUP(spilen, 16);
   1478 			cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2));
   1479 		}
   1480 	}
   1481 
   1482 	/* Set up and issue the SPI command.  MSByte goes out on bus first.  Increase datalen
   1483 	 * according to the wordlen mode(16/32bit) the device is in.
   1484 	 */
   1485 	if (sd->wordlen == 4) { /* 32bit spid */
   1486 		*(uint32 *)spi_outbuf = bcmswap32(cmd_arg);
   1487 		if (datalen & 0x3)
   1488 			datalen += (4 - (datalen & 0x3));
   1489 	} else if (sd->wordlen == 2) { /* 16bit spid */
   1490 		*(uint16 *)spi_outbuf = bcmswap16(cmd_arg & 0xffff);
   1491 		*(uint16 *)&spi_outbuf[2] = bcmswap16((cmd_arg & 0xffff0000) >> 16);
   1492 		if (datalen & 0x1)
   1493 			datalen++;
   1494 		if (datalen < 4)
   1495 			datalen = ROUNDUP(datalen, 4);
   1496 	} else {
   1497 		sd_err(("Host is %d bit spid, could not create SPI command.\n",
   1498 			8 * sd->wordlen));
   1499 		return ERROR;
   1500 	}
   1501 
   1502 	/* for Write, put the data into the output buffer */
   1503 	if (GFIELD(cmd_arg, SPI_RW_FLAG) == 1) {
   1504 		/* We send len field of hw-header always a mod16 size, both from host and dongle */
   1505 		if (DWORDMODE_ON) {
   1506 			if (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) {
   1507 				ptr = (uint16 *)&data[0];
   1508 				templen = *ptr;
   1509 				/* ASSERT(*ptr == ~*(ptr + 1)); */
   1510 				templen = ROUNDUP(templen, 16);
   1511 				*ptr = templen;
   1512 				sd_trace(("actual tx len = %d\n", (uint16)(~*(ptr+1))));
   1513 			}
   1514 		}
   1515 
   1516 		if (datalen != 0) {
   1517 			for (i = 0; i < datalen/4; i++) {
   1518 				if (sd->wordlen == 4) { /* 32bit spid */
   1519 					*(uint32 *)&spi_outbuf[i * 4 + CMDLEN] =
   1520 						bcmswap32(data[i]);
   1521 				} else if (sd->wordlen == 2) { /* 16bit spid */
   1522 					*(uint16 *)&spi_outbuf[i * 4 + CMDLEN] =
   1523 						bcmswap16(data[i] & 0xffff);
   1524 					*(uint16 *)&spi_outbuf[i * 4 + CMDLEN + 2] =
   1525 						bcmswap16((data[i] & 0xffff0000) >> 16);
   1526 				}
   1527 			}
   1528 		}
   1529 	}
   1530 
   1531 	/* Append resp-delay number of bytes and clock them out for F0/1/2 reads. */
   1532 	if (GFIELD(cmd_arg, SPI_RW_FLAG) == 0) {
   1533 		int func = GFIELD(cmd_arg, SPI_FUNCTION);
   1534 		switch (func) {
   1535 			case 0:
   1536 				resp_delay = sd->resp_delay_all ? F0_RESPONSE_DELAY : 0;
   1537 				break;
   1538 			case 1:
   1539 				resp_delay = F1_RESPONSE_DELAY;
   1540 				break;
   1541 			case 2:
   1542 				resp_delay = sd->resp_delay_all ? F2_RESPONSE_DELAY : 0;
   1543 				break;
   1544 			default:
   1545 				ASSERT(0);
   1546 				break;
   1547 		}
   1548 		/* Program response delay */
   1549 	        bcmspi_prog_resp_delay(sd, func, resp_delay);
   1550 	}
   1551 
   1552 	/* +4 for cmd and +4 for dstatus */
   1553 	hostlen = datalen + 8 + resp_delay;
   1554 	hostlen += dstatus_idx;
   1555 	hostlen += (4 - (hostlen & 0x3));
   1556 	spi_sendrecv(sd, spi_outbuf, spi_inbuf, hostlen);
   1557 
   1558 	/* for Read, get the data into the input buffer */
   1559 	if (datalen != 0) {
   1560 		if (GFIELD(cmd_arg, SPI_RW_FLAG) == 0) { /* if read cmd */
   1561 			for (j = 0; j < datalen/4; j++) {
   1562 				if (sd->wordlen == 4) { /* 32bit spid */
   1563 					data[j] = bcmswap32(*(uint32 *)&spi_inbuf[j * 4 +
   1564 					            CMDLEN + resp_delay]);
   1565 				} else if (sd->wordlen == 2) { /* 16bit spid */
   1566 					data[j] = (bcmswap16(*(uint16 *)&spi_inbuf[j * 4 +
   1567 					            CMDLEN + resp_delay])) |
   1568 					         ((bcmswap16(*(uint16 *)&spi_inbuf[j * 4 +
   1569 					            CMDLEN + resp_delay + 2])) << 16);
   1570 				}
   1571 			}
   1572 
   1573 			if ((DWORDMODE_ON) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) {
   1574 				ptr = (uint16 *)&data[0];
   1575 				templen = *ptr;
   1576 				buslen = len = ~(*(ptr + 1));
   1577 				buslen = ROUNDUP(buslen, 16);
   1578 				/* populate actual len in hw-header */
   1579 				if (templen == buslen)
   1580 					*ptr = len;
   1581 			}
   1582 		}
   1583 	}
   1584 
   1585 	/* Restore back the len field of the hw header */
   1586 	if (DWORDMODE_ON) {
   1587 		if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) &&
   1588 		    (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) {
   1589 			ptr = (uint16 *)&data[0];
   1590 			*ptr = (uint16)(~*(ptr+1));
   1591 		}
   1592 	}
   1593 
   1594 	dstatus_idx += (datalen + CMDLEN + resp_delay);
   1595 	/* Last 4bytes are dstatus.  Device is configured to return status bits. */
   1596 	if (sd->wordlen == 4) { /* 32bit spid */
   1597 		sd->card_dstatus = bcmswap32(*(uint32 *)&spi_inbuf[dstatus_idx]);
   1598 	} else if (sd->wordlen == 2) { /* 16bit spid */
   1599 		sd->card_dstatus = (bcmswap16(*(uint16 *)&spi_inbuf[dstatus_idx]) |
   1600 		                   (bcmswap16(*(uint16 *)&spi_inbuf[dstatus_idx + 2]) << 16));
   1601 	} else {
   1602 		sd_err(("Host is %d bit machine, could not read SPI dstatus.\n",
   1603 			8 * sd->wordlen));
   1604 		return ERROR;
   1605 	}
   1606 	if (sd->card_dstatus == 0xffffffff) {
   1607 		sd_err(("looks like not a GSPI device or device is not powered.\n"));
   1608 	}
   1609 
   1610 	err = bcmspi_update_stats(sd, cmd_arg);
   1611 
   1612 	return err;
   1613 
   1614 }
   1615 
   1616 static int
   1617 bcmspi_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo,
   1618                 uint32 addr, int nbytes, uint32 *data)
   1619 {
   1620 	int status;
   1621 	uint32 cmd_arg;
   1622 	bool write = rw == SDIOH_READ ? 0 : 1;
   1623 	uint retries = 0;
   1624 
   1625 	bool enable;
   1626 	uint32	spilen;
   1627 
   1628 	cmd_arg = 0;
   1629 
   1630 	ASSERT(nbytes);
   1631 	ASSERT(nbytes <= sd->client_block_size[func]);
   1632 
   1633 	if (write) sd->t_cnt++; else sd->r_cnt++;
   1634 
   1635 	if (func == 2) {
   1636 		/* Frame len check limited by gSPI. */
   1637 		if ((nbytes > 2000) && write) {
   1638 			sd_trace((">2KB write: F2 wr of %d bytes\n", nbytes));
   1639 		}
   1640 		/* ASSERT(nbytes <= 2048); Fix bigger len gspi issue and uncomment. */
   1641 		/* If F2 fifo on device is not ready to receive data, don't do F2 transfer */
   1642 		if (write) {
   1643 			uint32 dstatus;
   1644 			/* check F2 ready with cached one */
   1645 			bcmspi_cmd_getdstatus(sd, &dstatus);
   1646 			if ((dstatus & STATUS_F2_RX_READY) == 0) {
   1647 				retries = WAIT_F2RXFIFORDY;
   1648 				enable = 0;
   1649 				while (retries-- && !enable) {
   1650 					OSL_DELAY(WAIT_F2RXFIFORDY_DELAY * 1000);
   1651 					bcmspi_card_regread(sd, SPI_FUNC_0, SPID_STATUS_REG, 4,
   1652 					                   &dstatus);
   1653 					if (dstatus & STATUS_F2_RX_READY)
   1654 						enable = TRUE;
   1655 				}
   1656 				if (!enable) {
   1657 					struct spierrstats_t *spierrstats = &sd->spierrstats;
   1658 					spierrstats->f2rxnotready++;
   1659 					sd_err(("F2 FIFO is not ready to receive data.\n"));
   1660 					return ERROR;
   1661 				}
   1662 				sd_trace(("No of retries on F2 ready %d\n",
   1663 					(WAIT_F2RXFIFORDY - retries)));
   1664 			}
   1665 		}
   1666 	}
   1667 
   1668 	/* F2 transfers happen on 0 addr */
   1669 	addr = (func == 2) ? 0 : addr;
   1670 
   1671 	/* In pio mode buffer is read using fixed address fifo in func 1 */
   1672 	if ((func == 1) && (fifo))
   1673 		cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 0);
   1674 	else
   1675 		cmd_arg = SFIELD(cmd_arg, SPI_ACCESS, 1);
   1676 
   1677 	cmd_arg = SFIELD(cmd_arg, SPI_FUNCTION, func);
   1678 	cmd_arg = SFIELD(cmd_arg, SPI_REG_ADDR, addr);
   1679 	cmd_arg = SFIELD(cmd_arg, SPI_RW_FLAG, write);
   1680 	spilen = sd->data_xfer_count = MIN(sd->client_block_size[func], nbytes);
   1681 	if ((sd->dwordmode == TRUE) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) {
   1682 		/* convert len to mod4 size */
   1683 		spilen = spilen + ((spilen & 0x3) ? (4 - (spilen & 0x3)): 0);
   1684 		cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2));
   1685 	} else
   1686 		cmd_arg = SFIELD(cmd_arg, SPI_LEN, spilen);
   1687 
   1688 	if ((func == 2) && (fifo == 1)) {
   1689 		sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n",
   1690 		          __FUNCTION__, write ? "Wr" : "Rd", func, "INCR",
   1691 		          addr, nbytes, sd->r_cnt, sd->t_cnt));
   1692 	}
   1693 
   1694 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
   1695 	sd_data(("%s: %s func %d, %s, addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n",
   1696 	         __FUNCTION__, write ? "Wd" : "Rd", func, "INCR",
   1697 	         addr, nbytes, sd->r_cnt, sd->t_cnt));
   1698 
   1699 
   1700 	if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg,
   1701 	     data, nbytes)) != SUCCESS) {
   1702 		sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__,
   1703 			(write ? "write" : "read")));
   1704 		return status;
   1705 	}
   1706 
   1707 	/* gSPI expects that hw-header-len is equal to spi-command-len */
   1708 	if ((func == 2) && (rw == SDIOH_WRITE) && (sd->dwordmode == FALSE)) {
   1709 		ASSERT((uint16)sd->data_xfer_count == (uint16)(*data & 0xffff));
   1710 		ASSERT((uint16)sd->data_xfer_count == (uint16)(~((*data & 0xffff0000) >> 16)));
   1711 	}
   1712 
   1713 	if ((nbytes > 2000) && !write) {
   1714 		sd_trace((">2KB read: F2 rd of %d bytes\n", nbytes));
   1715 	}
   1716 
   1717 	return SUCCESS;
   1718 }
   1719 
   1720 /* Reset and re-initialize the device */
   1721 int
   1722 sdioh_sdio_reset(sdioh_info_t *si)
   1723 {
   1724 	si->card_init_done = FALSE;
   1725 	return bcmspi_client_init(si);
   1726 }
   1727