summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rsi/rsi_sdio.h
blob: ead8e7c4df3a47a12ab9ebca1176337e40466197 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
 * @section LICENSE
 * Copyright (c) 2014 Redpine Signals Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#ifndef __RSI_SDIO_INTF__
#define __RSI_SDIO_INTF__

#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sd.h>
#include <linux/mmc/sdio_ids.h>
#include "rsi_main.h"

enum sdio_interrupt_type {
	BUFFER_FULL         = 0x0,
	BUFFER_AVAILABLE    = 0x2,
	FIRMWARE_ASSERT_IND = 0x3,
	MSDU_PACKET_PENDING = 0x4,
	UNKNOWN_INT         = 0XE
};

/* Buffer status register related info */
#define PKT_BUFF_SEMI_FULL                      0
#define PKT_BUFF_FULL                           1
#define PKT_MGMT_BUFF_FULL                      2
#define MSDU_PKT_PENDING                        3
#define RECV_NUM_BLOCKS                         4
/* Interrupt Bit Related Macros */
#define PKT_BUFF_AVAILABLE                      1
#define FW_ASSERT_IND                           2

#define RSI_MASTER_REG_BUF_SIZE			12

#define RSI_DEVICE_BUFFER_STATUS_REGISTER       0xf3
#define RSI_FN1_INT_REGISTER                    0xf9
#define RSI_INT_ENABLE_REGISTER			0x04
#define RSI_INT_ENABLE_MASK			0xfc
#define RSI_SD_REQUEST_MASTER                   0x10000

/* FOR SD CARD ONLY */
#define SDIO_RX_NUM_BLOCKS_REG                  0x000F1
#define SDIO_FW_STATUS_REG                      0x000F2
#define SDIO_NXT_RD_DELAY2                      0x000F5
#define SDIO_MASTER_ACCESS_MSBYTE               0x000FA
#define SDIO_MASTER_ACCESS_LSBYTE               0x000FB
#define SDIO_READ_START_LVL                     0x000FC
#define SDIO_READ_FIFO_CTL                      0x000FD
#define SDIO_WRITE_FIFO_CTL                     0x000FE
#define SDIO_WAKEUP_REG				0x000FF
#define SDIO_FUN1_INTR_CLR_REG                  0x0008
#define SDIO_REG_HIGH_SPEED                     0x0013

#define RSI_GET_SDIO_INTERRUPT_TYPE(_I, TYPE)      \
	{					   \
		TYPE =                             \
		(_I & (1 << PKT_BUFF_AVAILABLE)) ? \
		BUFFER_AVAILABLE :		   \
		(_I & (1 << MSDU_PKT_PENDING)) ?   \
		MSDU_PACKET_PENDING :              \
		(_I & (1 << FW_ASSERT_IND)) ?      \
		FIRMWARE_ASSERT_IND : UNKNOWN_INT; \
	}

/* common registers in SDIO function1 */
#define TA_SOFT_RESET_REG            0x0004
#define TA_TH0_PC_REG                0x0400
#define TA_HOLD_THREAD_REG           0x0844
#define TA_RELEASE_THREAD_REG        0x0848

#define TA_SOFT_RST_CLR              0
#define TA_SOFT_RST_SET              BIT(0)
#define TA_PC_ZERO                   0
#define TA_HOLD_THREAD_VALUE         cpu_to_le32(0xF)
#define TA_RELEASE_THREAD_VALUE      cpu_to_le32(0xF)
#define TA_BASE_ADDR                 0x2200
#define MISC_CFG_BASE_ADDR           0x4105

struct receive_info {
	bool buffer_full;
	bool semi_buffer_full;
	bool mgmt_buffer_full;
	u32 mgmt_buf_full_counter;
	u32 buf_semi_full_counter;
	u8 watch_bufferfull_count;
	u32 sdio_intr_status_zero;
	u32 sdio_int_counter;
	u32 total_sdio_msdu_pending_intr;
	u32 total_sdio_unknown_intr;
	u32 buf_full_counter;
	u32 buf_available_counter;
};

struct rsi_sdio_rx_q {
	u8 num_rx_pkts;
	struct sk_buff_head head;
};

struct rsi_91x_sdiodev {
	struct sdio_func *pfunction;
	struct task_struct *sdio_irq_task;
	struct receive_info rx_info;
	u32 next_read_delay;
	u32 sdio_high_speed_enable;
	u8 sdio_clock_speed;
	u32 cardcapability;
	u8 prev_desc[16];
	u16 tx_blk_size;
	u8 write_fail;
	bool buff_status_updated;
	struct rsi_sdio_rx_q rx_q;
	struct rsi_thread rx_thread;
};

void rsi_interrupt_handler(struct rsi_hw *adapter);
int rsi_init_sdio_slave_regs(struct rsi_hw *adapter);
int rsi_sdio_read_register(struct rsi_hw *adapter, u32 addr, u8 *data);
int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, u8 *pkt, u32 length);
int rsi_sdio_write_register(struct rsi_hw *adapter, u8 function,
			    u32 addr, u8 *data);
int rsi_sdio_write_register_multiple(struct rsi_hw *adapter, u32 addr,
				     u8 *data, u16 count);
int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word);
void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit);
int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter);
int rsi_sdio_check_buffer_status(struct rsi_hw *adapter, u8 q_num);
void rsi_sdio_rx_thread(struct rsi_common *common);
#endif