File Index
Files and directories
Sign in
FILE

sdio_ops.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/rtl8723bs/hal/sdio_ops.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5 *
   6 *******************************************************************************/
   7#include <drv_types.h>
   8#include <rtl8723b_hal.h>
   9
  10/*  */
  11/*  Description: */
  12/*	The following mapping is for SDIO host local register space. */
  13/*  */
  14/*  Creadted by Roger, 2011.01.31. */
  15/*  */
  16static void hal_sdio_get_cmd_addr_8723b(
  17	struct adapter *adapter,
  18	u8 device_id,
  19	u32 addr,
  20	u32 *cmdaddr
  21)
  22{
  23	switch (device_id) {
  24	case SDIO_LOCAL_DEVICE_ID:
  25		*cmdaddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (addr & SDIO_LOCAL_MSK));
  26		break;
  27
  28	case WLAN_IOREG_DEVICE_ID:
  29		*cmdaddr = ((WLAN_IOREG_DEVICE_ID << 13) | (addr & WLAN_IOREG_MSK));
  30		break;
  31
  32	case WLAN_TX_HIQ_DEVICE_ID:
  33		*cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
  34		break;
  35
  36	case WLAN_TX_MIQ_DEVICE_ID:
  37		*cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
  38		break;
  39
  40	case WLAN_TX_LOQ_DEVICE_ID:
  41		*cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
  42		break;
  43
  44	case WLAN_RX0FF_DEVICE_ID:
  45		*cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK));
  46		break;
  47
  48	default:
  49		break;
  50	}
  51}
  52
  53static u8 get_deviceid(u32 addr)
  54{
  55	u8 devide_id;
  56	u16 pseudo_id;
  57
  58	pseudo_id = (u16)(addr >> 16);
  59	switch (pseudo_id) {
  60	case 0x1025:
  61		devide_id = SDIO_LOCAL_DEVICE_ID;
  62		break;
  63
  64	case 0x1026:
  65		devide_id = WLAN_IOREG_DEVICE_ID;
  66		break;
  67
  68	case 0x1031:
  69		devide_id = WLAN_TX_HIQ_DEVICE_ID;
  70		break;
  71
  72	case 0x1032:
  73		devide_id = WLAN_TX_MIQ_DEVICE_ID;
  74		break;
  75
  76	case 0x1033:
  77		devide_id = WLAN_TX_LOQ_DEVICE_ID;
  78		break;
  79
  80	case 0x1034:
  81		devide_id = WLAN_RX0FF_DEVICE_ID;
  82		break;
  83
  84	default:
  85		devide_id = WLAN_IOREG_DEVICE_ID;
  86		break;
  87	}
  88
  89	return devide_id;
  90}
  91
  92static u32 _cvrt2ftaddr(const u32 addr, u8 *pdevice_id, u16 *poffset)
  93{
  94	u8 device_id;
  95	u16 offset;
  96	u32 ftaddr;
  97
  98	device_id = get_deviceid(addr);
  99	offset = 0;
 100
 101	switch (device_id) {
 102	case SDIO_LOCAL_DEVICE_ID:
 103		offset = addr & SDIO_LOCAL_MSK;
 104		break;
 105
 106	case WLAN_TX_HIQ_DEVICE_ID:
 107	case WLAN_TX_MIQ_DEVICE_ID:
 108	case WLAN_TX_LOQ_DEVICE_ID:
 109		offset = addr & WLAN_FIFO_MSK;
 110		break;
 111
 112	case WLAN_RX0FF_DEVICE_ID:
 113		offset = addr & WLAN_RX0FF_MSK;
 114		break;
 115
 116	case WLAN_IOREG_DEVICE_ID:
 117	default:
 118		device_id = WLAN_IOREG_DEVICE_ID;
 119		offset = addr & WLAN_IOREG_MSK;
 120		break;
 121	}
 122	ftaddr = (device_id << 13) | offset;
 123
 124	if (pdevice_id)
 125		*pdevice_id = device_id;
 126	if (poffset)
 127		*poffset = offset;
 128
 129	return ftaddr;
 130}
 131
 132static u8 sdio_read8(struct intf_hdl *intfhdl, u32 addr)
 133{
 134	u32 ftaddr;
 135	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 136
 137	return sd_read8(intfhdl, ftaddr, NULL);
 138}
 139
 140static u16 sdio_read16(struct intf_hdl *intfhdl, u32 addr)
 141{
 142	u32 ftaddr;
 143	__le16 le_tmp;
 144
 145	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 146	sd_cmd52_read(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
 147
 148	return le16_to_cpu(le_tmp);
 149}
 150
 151static u32 sdio_read32(struct intf_hdl *intfhdl, u32 addr)
 152{
 153	struct adapter *adapter;
 154	u8 mac_pwr_ctrl_on;
 155	u8 device_id;
 156	u16 offset;
 157	u32 ftaddr;
 158	u8 shift;
 159	u32 val;
 160	s32 __maybe_unused err;
 161	__le32 le_tmp;
 162
 163	adapter = intfhdl->padapter;
 164	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 165
 166	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 167	if (
 168		((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 169		(!mac_pwr_ctrl_on) ||
 170		(adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
 171	) {
 172		err = sd_cmd52_read(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
 173		return le32_to_cpu(le_tmp);
 174	}
 175
 176	/*  4 bytes alignment */
 177	shift = ftaddr & 0x3;
 178	if (shift == 0) {
 179		val = sd_read32(intfhdl, ftaddr, NULL);
 180	} else {
 181		u8 *tmpbuf;
 182
 183		tmpbuf = rtw_malloc(8);
 184		if (!tmpbuf)
 185			return SDIO_ERR_VAL32;
 186
 187		ftaddr &= ~(u16)0x3;
 188		sd_read(intfhdl, ftaddr, 8, tmpbuf);
 189		memcpy(&le_tmp, tmpbuf + shift, 4);
 190		val = le32_to_cpu(le_tmp);
 191
 192		kfree(tmpbuf);
 193	}
 194	return val;
 195}
 196
 197static s32 sdio_readN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
 198{
 199	struct adapter *adapter;
 200	u8 mac_pwr_ctrl_on;
 201	u8 device_id;
 202	u16 offset;
 203	u32 ftaddr;
 204	u8 shift;
 205	s32 err;
 206
 207	adapter = intfhdl->padapter;
 208	err = 0;
 209
 210	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 211
 212	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 213	if (
 214		((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 215		(!mac_pwr_ctrl_on) ||
 216		(adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
 217	)
 218		return sd_cmd52_read(intfhdl, ftaddr, cnt, buf);
 219
 220	/*  4 bytes alignment */
 221	shift = ftaddr & 0x3;
 222	if (shift == 0) {
 223		err = sd_read(intfhdl, ftaddr, cnt, buf);
 224	} else {
 225		u8 *tmpbuf;
 226		u32 n;
 227
 228		ftaddr &= ~(u16)0x3;
 229		n = cnt + shift;
 230		tmpbuf = rtw_malloc(n);
 231		if (!tmpbuf)
 232			return -1;
 233
 234		err = sd_read(intfhdl, ftaddr, n, tmpbuf);
 235		if (!err)
 236			memcpy(buf, tmpbuf + shift, cnt);
 237		kfree(tmpbuf);
 238	}
 239	return err;
 240}
 241
 242static s32 sdio_write8(struct intf_hdl *intfhdl, u32 addr, u8 val)
 243{
 244	u32 ftaddr;
 245	s32 err;
 246
 247	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 248	sd_write8(intfhdl, ftaddr, val, &err);
 249
 250	return err;
 251}
 252
 253static s32 sdio_write16(struct intf_hdl *intfhdl, u32 addr, u16 val)
 254{
 255	u32 ftaddr;
 256	__le16 le_tmp;
 257
 258	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
 259	le_tmp = cpu_to_le16(val);
 260	return sd_cmd52_write(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
 261}
 262
 263static s32 sdio_write32(struct intf_hdl *intfhdl, u32 addr, u32 val)
 264{
 265	struct adapter *adapter;
 266	u8 mac_pwr_ctrl_on;
 267	u8 device_id;
 268	u16 offset;
 269	u32 ftaddr;
 270	u8 shift;
 271	s32 err;
 272	__le32 le_tmp;
 273
 274	adapter = intfhdl->padapter;
 275	err = 0;
 276
 277	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 278
 279	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 280	if (
 281		((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 282		(!mac_pwr_ctrl_on) ||
 283		(adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
 284	) {
 285		le_tmp = cpu_to_le32(val);
 286
 287		return sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
 288	}
 289
 290	/*  4 bytes alignment */
 291	shift = ftaddr & 0x3;
 292	if (shift == 0) {
 293		sd_write32(intfhdl, ftaddr, val, &err);
 294	} else {
 295		le_tmp = cpu_to_le32(val);
 296		err = sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
 297	}
 298	return err;
 299}
 300
 301static s32 sdio_writeN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
 302{
 303	struct adapter *adapter;
 304	u8 mac_pwr_ctrl_on;
 305	u8 device_id;
 306	u16 offset;
 307	u32 ftaddr;
 308	u8 shift;
 309	s32 err;
 310
 311	adapter = intfhdl->padapter;
 312	err = 0;
 313
 314	ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
 315
 316	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 317	if (
 318		((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
 319		(!mac_pwr_ctrl_on) ||
 320		(adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
 321	)
 322		return sd_cmd52_write(intfhdl, ftaddr, cnt, buf);
 323
 324	shift = ftaddr & 0x3;
 325	if (shift == 0) {
 326		err = sd_write(intfhdl, ftaddr, cnt, buf);
 327	} else {
 328		u8 *tmpbuf;
 329		u32 n;
 330
 331		ftaddr &= ~(u16)0x3;
 332		n = cnt + shift;
 333		tmpbuf = rtw_malloc(n);
 334		if (!tmpbuf)
 335			return -1;
 336		err = sd_read(intfhdl, ftaddr, 4, tmpbuf);
 337		if (err) {
 338			kfree(tmpbuf);
 339			return err;
 340		}
 341		memcpy(tmpbuf + shift, buf, cnt);
 342		err = sd_write(intfhdl, ftaddr, n, tmpbuf);
 343		kfree(tmpbuf);
 344	}
 345	return err;
 346}
 347
 348static void sdio_read_mem(
 349	struct intf_hdl *intfhdl,
 350	u32 addr,
 351	u32 cnt,
 352	u8 *rmem
 353)
 354{
 355	sdio_readN(intfhdl, addr, cnt, rmem);
 356}
 357
 358static void sdio_write_mem(
 359	struct intf_hdl *intfhdl,
 360	u32 addr,
 361	u32 cnt,
 362	u8 *wmem
 363)
 364{
 365	sdio_writeN(intfhdl, addr, cnt, wmem);
 366}
 367
 368/*
 369 * Description:
 370 *Read from RX FIFO
 371 *Round read size to block size,
 372 *and make sure data transfer will be done in one command.
 373 *
 374 * Parameters:
 375 *intfhdl	a pointer of intf_hdl
 376 *addr		port ID
 377 *cnt			size to read
 378 *rmem		address to put data
 379 *
 380 * Return:
 381 *_SUCCESS(1)		Success
 382 *_FAIL(0)		Fail
 383 */
 384static u32 sdio_read_port(
 385	struct intf_hdl *intfhdl,
 386	u32 addr,
 387	u32 cnt,
 388	u8 *mem
 389)
 390{
 391	struct adapter *adapter;
 392	struct sdio_data *psdio;
 393	struct hal_com_data *hal;
 394	s32 err;
 395
 396	adapter = intfhdl->padapter;
 397	psdio = &adapter_to_dvobj(adapter)->intf_data;
 398	hal = GET_HAL_DATA(adapter);
 399
 400	hal_sdio_get_cmd_addr_8723b(adapter, addr, hal->SdioRxFIFOCnt++, &addr);
 401
 402	if (cnt > psdio->block_transfer_len)
 403		cnt = _RND(cnt, psdio->block_transfer_len);
 404
 405	err = _sd_read(intfhdl, addr, cnt, mem);
 406
 407	if (err)
 408		return _FAIL;
 409	return _SUCCESS;
 410}
 411
 412/*
 413 * Description:
 414 *Write to TX FIFO
 415 *Align write size block size,
 416 *and make sure data could be written in one command.
 417 *
 418 * Parameters:
 419 *intfhdl	a pointer of intf_hdl
 420 *addr		port ID
 421 *cnt			size to write
 422 *wmem		data pointer to write
 423 *
 424 * Return:
 425 *_SUCCESS(1)		Success
 426 *_FAIL(0)		Fail
 427 */
 428static u32 sdio_write_port(
 429	struct intf_hdl *intfhdl,
 430	u32 addr,
 431	u32 cnt,
 432	u8 *mem
 433)
 434{
 435	struct adapter *adapter;
 436	struct sdio_data *psdio;
 437	s32 err;
 438	struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
 439
 440	adapter = intfhdl->padapter;
 441	psdio = &adapter_to_dvobj(adapter)->intf_data;
 442
 443	if (!adapter->hw_init_completed)
 444		return _FAIL;
 445
 446	cnt = round_up(cnt, 4);
 447	hal_sdio_get_cmd_addr_8723b(adapter, addr, cnt >> 2, &addr);
 448
 449	if (cnt > psdio->block_transfer_len)
 450		cnt = _RND(cnt, psdio->block_transfer_len);
 451
 452	err = sd_write(intfhdl, addr, cnt, xmitbuf->pdata);
 453
 454	rtw_sctx_done_err(
 455		&xmitbuf->sctx,
 456		err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS
 457	);
 458
 459	if (err)
 460		return _FAIL;
 461	return _SUCCESS;
 462}
 463
 464void sdio_set_intf_ops(struct adapter *adapter, struct _io_ops *ops)
 465{
 466	ops->_read8 = &sdio_read8;
 467	ops->_read16 = &sdio_read16;
 468	ops->_read32 = &sdio_read32;
 469	ops->_read_mem = &sdio_read_mem;
 470	ops->_read_port = &sdio_read_port;
 471
 472	ops->_write8 = &sdio_write8;
 473	ops->_write16 = &sdio_write16;
 474	ops->_write32 = &sdio_write32;
 475	ops->_writeN = &sdio_writeN;
 476	ops->_write_mem = &sdio_write_mem;
 477	ops->_write_port = &sdio_write_port;
 478}
 479
 480/*
 481 * Todo: align address to 4 bytes.
 482 */
 483static s32 _sdio_local_read(
 484	struct adapter *adapter,
 485	u32 addr,
 486	u32 cnt,
 487	u8 *buf
 488)
 489{
 490	struct intf_hdl *intfhdl;
 491	u8 mac_pwr_ctrl_on;
 492	s32 err;
 493	u8 *tmpbuf;
 494	u32 n;
 495
 496	intfhdl = &adapter->iopriv.intf;
 497
 498	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 499
 500	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 501	if (!mac_pwr_ctrl_on)
 502		return _sd_cmd52_read(intfhdl, addr, cnt, buf);
 503
 504	n = round_up(cnt, 4);
 505	tmpbuf = rtw_malloc(n);
 506	if (!tmpbuf)
 507		return -1;
 508
 509	err = _sd_read(intfhdl, addr, n, tmpbuf);
 510	if (!err)
 511		memcpy(buf, tmpbuf, cnt);
 512
 513	kfree(tmpbuf);
 514
 515	return err;
 516}
 517
 518/*
 519 * Todo: align address to 4 bytes.
 520 */
 521s32 sdio_local_read(
 522	struct adapter *adapter,
 523	u32 addr,
 524	u32 cnt,
 525	u8 *buf
 526)
 527{
 528	struct intf_hdl *intfhdl;
 529	u8 mac_pwr_ctrl_on;
 530	s32 err;
 531	u8 *tmpbuf;
 532	u32 n;
 533
 534	intfhdl = &adapter->iopriv.intf;
 535
 536	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 537
 538	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 539	if (
 540		(!mac_pwr_ctrl_on) ||
 541		(adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
 542	)
 543		return sd_cmd52_read(intfhdl, addr, cnt, buf);
 544
 545	n = round_up(cnt, 4);
 546	tmpbuf = rtw_malloc(n);
 547	if (!tmpbuf)
 548		return -1;
 549
 550	err = sd_read(intfhdl, addr, n, tmpbuf);
 551	if (!err)
 552		memcpy(buf, tmpbuf, cnt);
 553
 554	kfree(tmpbuf);
 555
 556	return err;
 557}
 558
 559/*
 560 * Todo: align address to 4 bytes.
 561 */
 562s32 sdio_local_write(
 563	struct adapter *adapter,
 564	u32 addr,
 565	u32 cnt,
 566	u8 *buf
 567)
 568{
 569	struct intf_hdl *intfhdl;
 570	u8 mac_pwr_ctrl_on;
 571	s32 err;
 572	u8 *tmpbuf;
 573
 574	intfhdl = &adapter->iopriv.intf;
 575
 576	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 577
 578	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 579	if (
 580		(!mac_pwr_ctrl_on) ||
 581		(adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
 582	)
 583		return sd_cmd52_write(intfhdl, addr, cnt, buf);
 584
 585	tmpbuf = rtw_malloc(cnt);
 586	if (!tmpbuf)
 587		return -1;
 588
 589	memcpy(tmpbuf, buf, cnt);
 590
 591	err = sd_write(intfhdl, addr, cnt, tmpbuf);
 592
 593	kfree(tmpbuf);
 594
 595	return err;
 596}
 597
 598u8 SdioLocalCmd52Read1Byte(struct adapter *adapter, u32 addr)
 599{
 600	u8 val = 0;
 601	struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 602
 603	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 604	sd_cmd52_read(intfhdl, addr, 1, &val);
 605
 606	return val;
 607}
 608
 609static u16 sdio_local_cmd52_read2byte(struct adapter *adapter, u32 addr)
 610{
 611	__le16 val = 0;
 612	struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 613
 614	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 615	sd_cmd52_read(intfhdl, addr, 2, (u8 *)&val);
 616
 617	return le16_to_cpu(val);
 618}
 619
 620static u32 sdio_local_cmd53_read4byte(struct adapter *adapter, u32 addr)
 621{
 622
 623	u8 mac_pwr_ctrl_on;
 624	u32 val = 0;
 625	struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 626	__le32 le_tmp;
 627
 628	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 629	rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
 630	if (!mac_pwr_ctrl_on || adapter_to_pwrctl(adapter)->fw_current_in_ps_mode) {
 631		sd_cmd52_read(intfhdl, addr, 4, (u8 *)&le_tmp);
 632		val = le32_to_cpu(le_tmp);
 633	} else {
 634		val = sd_read32(intfhdl, addr, NULL);
 635	}
 636	return val;
 637}
 638
 639void SdioLocalCmd52Write1Byte(struct adapter *adapter, u32 addr, u8 v)
 640{
 641	struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 642
 643	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 644	sd_cmd52_write(intfhdl, addr, 1, &v);
 645}
 646
 647static void sdio_local_cmd52_write4byte(struct adapter *adapter, u32 addr, u32 v)
 648{
 649	struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 650	__le32 le_tmp;
 651
 652	hal_sdio_get_cmd_addr_8723b(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
 653	le_tmp = cpu_to_le32(v);
 654	sd_cmd52_write(intfhdl, addr, 4, (u8 *)&le_tmp);
 655}
 656
 657static s32 read_interrupt_8723b_sdio(struct adapter *adapter, u32 *phisr)
 658{
 659	u32 hisr, himr;
 660	u8 val8, hisr_len;
 661
 662	if (!phisr)
 663		return false;
 664
 665	himr = GET_HAL_DATA(adapter)->sdio_himr;
 666
 667	/*  decide how many bytes need to be read */
 668	hisr_len = 0;
 669	while (himr) {
 670		hisr_len++;
 671		himr >>= 8;
 672	}
 673
 674	hisr = 0;
 675	while (hisr_len != 0) {
 676		hisr_len--;
 677		val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR + hisr_len);
 678		hisr |= (val8 << (8 * hisr_len));
 679	}
 680
 681	*phisr = hisr;
 682
 683	return true;
 684}
 685
 686/*  */
 687/*	Description: */
 688/*		Initialize SDIO Host Interrupt Mask configuration variables for future use. */
 689/*  */
 690/*	Assumption: */
 691/*		Using SDIO Local register ONLY for configuration. */
 692/*  */
 693/*	Created by Roger, 2011.02.11. */
 694/*  */
 695void InitInterrupt8723BSdio(struct adapter *adapter)
 696{
 697	struct hal_com_data *haldata;
 698
 699	haldata = GET_HAL_DATA(adapter);
 700	haldata->sdio_himr = (u32)(SDIO_HIMR_RX_REQUEST_MSK	|
 701				   SDIO_HIMR_AVAL_MSK		|
 702				   0);
 703}
 704
 705/*  */
 706/*	Description: */
 707/*		Initialize System Host Interrupt Mask configuration variables for future use. */
 708/*  */
 709/*	Created by Roger, 2011.08.03. */
 710/*  */
 711void InitSysInterrupt8723BSdio(struct adapter *adapter)
 712{
 713	struct hal_com_data *haldata;
 714
 715	haldata = GET_HAL_DATA(adapter);
 716
 717	haldata->SysIntrMask = (0);
 718}
 719
 720/*  */
 721/*	Description: */
 722/*		Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain. */
 723/*  */
 724/*	Assumption: */
 725/*		1. Using SDIO Local register ONLY for configuration. */
 726/*		2. PASSIVE LEVEL */
 727/*  */
 728/*	Created by Roger, 2011.02.11. */
 729/*  */
 730void EnableInterrupt8723BSdio(struct adapter *adapter)
 731{
 732	struct hal_com_data *haldata;
 733	__le32 himr;
 734	u32 tmp;
 735
 736	haldata = GET_HAL_DATA(adapter);
 737
 738	himr = cpu_to_le32(haldata->sdio_himr);
 739	sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
 740
 741	/*  Update current system IMR settings */
 742	tmp = rtw_read32(adapter, REG_HSIMR);
 743	rtw_write32(adapter, REG_HSIMR, tmp | haldata->SysIntrMask);
 744
 745	/*  */
 746	/*  <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. */
 747	/*  So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */
 748	/*  2011.10.19. */
 749	/*  */
 750	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
 751}
 752
 753/*  */
 754/*	Description: */
 755/*		Disable SDIO Host IMR configuration to mask unnecessary interrupt service. */
 756/*  */
 757/*	Assumption: */
 758/*		Using SDIO Local register ONLY for configuration. */
 759/*  */
 760/*	Created by Roger, 2011.02.11. */
 761/*  */
 762void DisableInterrupt8723BSdio(struct adapter *adapter)
 763{
 764	__le32 himr;
 765
 766	himr = cpu_to_le32(SDIO_HIMR_DISABLED);
 767	sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
 768}
 769
 770/*  */
 771/*	Description: */
 772/*		Using 0x100 to check the power status of FW. */
 773/*  */
 774/*	Assumption: */
 775/*		Using SDIO Local register ONLY for configuration. */
 776/*  */
 777/*	Created by Isaac, 2013.09.10. */
 778/*  */
 779u8 CheckIPSStatus(struct adapter *adapter)
 780{
 781	if (rtw_read8(adapter, 0x100) == 0xEA)
 782		return true;
 783	else
 784		return false;
 785}
 786
 787static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size)
 788{
 789	u32 readsize, ret;
 790	u8 *readbuf;
 791	struct recv_priv *recv_priv;
 792	struct recv_buf	*recvbuf;
 793
 794	/*  Patch for some SDIO Host 4 bytes issue */
 795	/*  ex. RK3188 */
 796	readsize = round_up(size, 4);
 797
 798	/* 3 1. alloc recvbuf */
 799	recv_priv = &adapter->recvpriv;
 800	recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue);
 801	if (!recvbuf) {
 802		netdev_err(adapter->pnetdev, "%s: alloc recvbuf FAIL!\n",
 803			   __func__);
 804		return NULL;
 805	}
 806
 807	/* 3 2. alloc skb */
 808	if (!recvbuf->pskb) {
 809		SIZE_PTR tmpaddr = 0;
 810		SIZE_PTR alignment = 0;
 811
 812		recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
 813		if (!recvbuf->pskb)
 814			return NULL;
 815
 816		recvbuf->pskb->dev = adapter->pnetdev;
 817
 818		tmpaddr = (SIZE_PTR)recvbuf->pskb->data;
 819		alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
 820		skb_reserve(recvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
 821	}
 822
 823	/* 3 3. read data from rxfifo */
 824	readbuf = recvbuf->pskb->data;
 825	ret = sdio_read_port(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, readbuf);
 826	if (ret == _FAIL)
 827		return NULL;
 828
 829	/* 3 4. init recvbuf */
 830	recvbuf->len = size;
 831	recvbuf->phead = recvbuf->pskb->head;
 832	recvbuf->pdata = recvbuf->pskb->data;
 833	skb_set_tail_pointer(recvbuf->pskb, size);
 834	recvbuf->ptail = skb_tail_pointer(recvbuf->pskb);
 835	recvbuf->pend = skb_end_pointer(recvbuf->pskb);
 836
 837	return recvbuf;
 838}
 839
 840static void sd_rxhandler(struct adapter *adapter, struct recv_buf *recvbuf)
 841{
 842	struct recv_priv *recv_priv;
 843	struct __queue *pending_queue;
 844
 845	recv_priv = &adapter->recvpriv;
 846	pending_queue = &recv_priv->recv_buf_pending_queue;
 847
 848	/* 3 1. enqueue recvbuf */
 849	rtw_enqueue_recvbuf(recvbuf, pending_queue);
 850
 851	/* 3 2. schedule tasklet */
 852	tasklet_schedule(&recv_priv->recv_tasklet);
 853}
 854
 855void sd_int_dpc(struct adapter *adapter)
 856{
 857	struct hal_com_data *hal;
 858	struct dvobj_priv *dvobj;
 859	struct intf_hdl *intfhdl = &adapter->iopriv.intf;
 860	struct pwrctrl_priv *pwrctl;
 861
 862	hal = GET_HAL_DATA(adapter);
 863	dvobj = adapter_to_dvobj(adapter);
 864	pwrctl = dvobj_to_pwrctl(dvobj);
 865
 866	if (hal->sdio_hisr & SDIO_HISR_AVAL) {
 867		u8 freepage[4];
 868
 869		_sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage);
 870		complete(&(adapter->xmitpriv.xmit_comp));
 871	}
 872
 873	if (hal->sdio_hisr & SDIO_HISR_CPWM1) {
 874		timer_delete_sync(&(pwrctl->pwr_rpwm_timer));
 875
 876		SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B);
 877
 878		_set_workitem(&(pwrctl->cpwm_event));
 879	}
 880
 881	if (hal->sdio_hisr & SDIO_HISR_TXERR) {
 882		u8 *status;
 883		u32 addr;
 884
 885		status = rtw_malloc(4);
 886		if (status) {
 887			addr = REG_TXDMA_STATUS;
 888			hal_sdio_get_cmd_addr_8723b(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
 889			_sd_read(intfhdl, addr, 4, status);
 890			_sd_write(intfhdl, addr, 4, status);
 891			kfree(status);
 892		}
 893	}
 894
 895	if (hal->sdio_hisr & SDIO_HISR_C2HCMD) {
 896		struct c2h_evt_hdr_88xx *c2h_evt;
 897
 898		c2h_evt = rtw_zmalloc(16);
 899		if (c2h_evt) {
 900			if (c2h_evt_read_88xx(adapter, (u8 *)c2h_evt) == _SUCCESS) {
 901				if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
 902					/* Handle CCX report here */
 903					rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt);
 904					kfree(c2h_evt);
 905				} else {
 906					rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
 907				}
 908			} else {
 909				kfree(c2h_evt);
 910			}
 911		} else {
 912			/* Error handling for malloc fail */
 913			rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL);
 914			_set_workitem(&adapter->evtpriv.c2h_wk);
 915		}
 916	}
 917
 918	if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
 919		struct recv_buf *recvbuf;
 920		int alloc_fail_time = 0;
 921		u32 hisr;
 922
 923		hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
 924		do {
 925			hal->SdioRxFIFOSize = sdio_local_cmd52_read2byte(adapter, SDIO_REG_RX0_REQ_LEN);
 926			if (hal->SdioRxFIFOSize != 0) {
 927				recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize);
 928				if (recvbuf)
 929					sd_rxhandler(adapter, recvbuf);
 930				else {
 931					alloc_fail_time++;
 932					if (alloc_fail_time >= 10)
 933						break;
 934				}
 935				hal->SdioRxFIFOSize = 0;
 936			} else
 937				break;
 938
 939			hisr = 0;
 940			read_interrupt_8723b_sdio(adapter, &hisr);
 941			hisr &= SDIO_HISR_RX_REQUEST;
 942			if (!hisr)
 943				break;
 944		} while (1);
 945	}
 946}
 947
 948void sd_int_hdl(struct adapter *adapter)
 949{
 950	struct hal_com_data *hal;
 951
 952	if (
 953		(adapter->bDriverStopped) || (adapter->bSurpriseRemoved)
 954	)
 955		return;
 956
 957	hal = GET_HAL_DATA(adapter);
 958
 959	hal->sdio_hisr = 0;
 960	read_interrupt_8723b_sdio(adapter, &hal->sdio_hisr);
 961
 962	if (hal->sdio_hisr & hal->sdio_himr) {
 963		u32 v32;
 964
 965		hal->sdio_hisr &= hal->sdio_himr;
 966
 967		/*  clear HISR */
 968		v32 = hal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
 969		if (v32)
 970			sdio_local_cmd52_write4byte(adapter, SDIO_REG_HISR, v32);
 971
 972		sd_int_dpc(adapter);
 973	}
 974}
 975
 976/*  */
 977/*	Description: */
 978/*		Query SDIO Local register to query current the number of Free TxPacketBuffer page. */
 979/*  */
 980/*	Assumption: */
 981/*		1. Running at PASSIVE_LEVEL */
 982/*		2. RT_TX_SPINLOCK is NOT acquired. */
 983/*  */
 984/*	Created by Roger, 2011.01.28. */
 985/*  */
 986u8 HalQueryTxBufferStatus8723BSdio(struct adapter *adapter)
 987{
 988	struct hal_com_data *hal;
 989	u32 numof_free_page;
 990
 991	hal = GET_HAL_DATA(adapter);
 992
 993	numof_free_page = sdio_local_cmd53_read4byte(adapter, SDIO_REG_FREE_TXPG);
 994
 995	memcpy(hal->SdioTxFIFOFreePage, &numof_free_page, 4);
 996
 997	return true;
 998}
 999
1000/* Read the TX OQT free page count from the SDIO local register. */
1001void HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter)
1002{
1003	struct hal_com_data *haldata = GET_HAL_DATA(adapter);
1004
1005	haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG);
1006}
1007
1008
~/ Read-only file preview.