aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/prism54/isl_38xx.h
blob: e83e4912ab66033273a54b6c0c288f400f50062c (plain) (blame)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
 *  
 *  Copyright (C) 2002 Intersil Americas Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef _ISL_38XX_H
#define _ISL_38XX_H

#include <linux/version.h>
#include <asm/io.h>
#include <asm/byteorder.h>

#define ISL38XX_CB_RX_QSIZE                     8
#define ISL38XX_CB_TX_QSIZE                     32

/* ISL38XX Access Point Specific definitions */
#define ISL38XX_MAX_WDS_LINKS                   8

/* ISL38xx Client Specific definitions */
#define ISL38XX_PSM_ACTIVE_STATE                0
#define ISL38XX_PSM_POWERSAVE_STATE             1

/* ISL38XX Host Interface Definitions */
#define ISL38XX_PCI_MEM_SIZE                    0x02000
#define ISL38XX_MEMORY_WINDOW_SIZE              0x01000
#define ISL38XX_DEV_FIRMWARE_ADDRES             0x20000
#define ISL38XX_WRITEIO_DELAY                   10	/* in us */
#define ISL38XX_RESET_DELAY                     50	/* in ms */
#define ISL38XX_WAIT_CYCLE                      10	/* in 10ms */
#define ISL38XX_MAX_WAIT_CYCLES                 10

/* PCI Memory Area */
#define ISL38XX_HARDWARE_REG                    0x0000
#define ISL38XX_CARDBUS_CIS                     0x0800
#define ISL38XX_DIRECT_MEM_WIN                  0x1000

/* Hardware registers */
#define ISL38XX_DEV_INT_REG                     0x0000
#define ISL38XX_INT_IDENT_REG                   0x0010
#define ISL38XX_INT_ACK_REG                     0x0014
#define ISL38XX_INT_EN_REG                      0x0018
#define ISL38XX_GEN_PURP_COM_REG_1              0x0020
#define ISL38XX_GEN_PURP_COM_REG_2              0x0024
#define ISL38XX_CTRL_BLK_BASE_REG               ISL38XX_GEN_PURP_COM_REG_1
#define ISL38XX_DIR_MEM_BASE_REG                0x0030
#define ISL38XX_CTRL_STAT_REG                   0x0078

/* High end mobos queue up pci writes, the following
 * is used to "read" from after a write to force flush */
#define ISL38XX_PCI_POSTING_FLUSH		ISL38XX_INT_EN_REG

/**
 * isl38xx_w32_flush - PCI iomem write helper
 * @base: (host) memory base address of the device
 * @val: 32bit value (host order) to write
 * @offset: byte offset into @base to write value to
 * 
 *  This helper takes care of writing a 32bit datum to the
 *  specified offset into the device's pci memory space, and making sure 
 *  the pci memory buffers get flushed by performing one harmless read 
 *  from the %ISL38XX_PCI_POSTING_FLUSH offset.
 */
static inline void
isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
{
	writel(val, base + offset);
	(void) readl(base + ISL38XX_PCI_POSTING_FLUSH);
}

/* Device Interrupt register bits */
#define ISL38XX_DEV_INT_RESET                   0x0001
#define ISL38XX_DEV_INT_UPDATE                  0x0002
#define ISL38XX_DEV_INT_WAKEUP                  0x0008
#define ISL38XX_DEV_INT_SLEEP                   0x0010

/* Interrupt Identification/Acknowledge/Enable register bits */
#define ISL38XX_INT_IDENT_UPDATE                0x0002
#define ISL38XX_INT_IDENT_INIT                  0x0004
#define ISL38XX_INT_IDENT_WAKEUP                0x0008
#define ISL38XX_INT_IDENT_SLEEP                 0x0010
#define ISL38XX_INT_SOURCES                     0x001E

/* Control/Status register bits */
/* Looks like there are other meaningful bits
    0x20004400 seen in normal operation,
    0x200044db at 'timeout waiting for mgmt response'
*/
#define ISL38XX_CTRL_STAT_SLEEPMODE             0x00000200
#define	ISL38XX_CTRL_STAT_CLKRUN		0x00800000
#define ISL38XX_CTRL_STAT_RESET                 0x10000000
#define ISL38XX_CTRL_STAT_RAMBOOT               0x20000000
#define ISL38XX_CTRL_STAT_STARTHALTED           0x40000000
#define ISL38XX_CTRL_STAT_HOST_OVERRIDE         0x80000000

/* Control Block definitions */
#define ISL38XX_CB_RX_DATA_LQ                   0
#define ISL38XX_CB_TX_DATA_LQ                   1
#define ISL38XX_CB_RX_DATA_HQ                   2
#define ISL38XX_CB_TX_DATA_HQ                   3
#define ISL38XX_CB_RX_MGMTQ                     4
#define ISL38XX_CB_TX_MGMTQ                     5
#define ISL38XX_CB_QCOUNT                       6
#define ISL38XX_CB_MGMT_QSIZE                   4
#define ISL38XX_MIN_QTHRESHOLD                  4	/* fragments */

/* Memory Manager definitions */
#define MGMT_FRAME_SIZE                         1500	/* >= size struct obj_bsslist */
#define MGMT_TX_FRAME_COUNT                     24	/* max 4 + spare 4 + 8 init */
#define MGMT_RX_FRAME_COUNT                     24	/* 4*4 + spare 8 */
#define MGMT_FRAME_COUNT                        (MGMT_TX_FRAME_COUNT + MGMT_RX_FRAME_COUNT)
#define CONTROL_BLOCK_SIZE                      1024	/* should be enough */
#define PSM_FRAME_SIZE                          1536
#define PSM_MINIMAL_STATION_COUNT               64
#define PSM_FRAME_COUNT                         PSM_MINIMAL_STATION_COUNT
#define PSM_BUFFER_SIZE                         PSM_FRAME_SIZE * PSM_FRAME_COUNT
#define MAX_TRAP_RX_QUEUE                       4
#define HOST_MEM_BLOCK                          CONTROL_BLOCK_SIZE + PSM_BUFFER_SIZE

/* Fragment package definitions */
#define FRAGMENT_FLAG_MF                        0x0001
#define MAX_FRAGMENT_SIZE                       1536

/* In monitor mode frames have a header. I don't know exactly how big those
 * frame can be but I've never seen any frame bigger than 1584... :
 */
#define MAX_FRAGMENT_SIZE_RX	                1600

typedef struct {
	u32 address;		/* physical address on host */
	u16 size;		/* packet size */
	u16 flags;		/* set of bit-wise flags */
} isl38xx_fragment;

struct isl38xx_cb {
	u32 driver_curr_frag[ISL38XX_CB_QCOUNT];
	u32 device_curr_frag[ISL38XX_CB_QCOUNT];
	isl38xx_fragment rx_data_low[ISL38XX_CB_RX_QSIZE];
	isl38xx_fragment tx_data_low[ISL38XX_CB_TX_QSIZE];
	isl38xx_fragment rx_data_high[ISL38XX_CB_RX_QSIZE];
	isl38xx_fragment tx_data_high[ISL38XX_CB_TX_QSIZE];
	isl38xx_fragment rx_data_mgmt[ISL38XX_CB_MGMT_QSIZE];
	isl38xx_fragment tx_data_mgmt[ISL38XX_CB_MGMT_QSIZE];
};

typedef struct isl38xx_cb isl38xx_control_block;

/* determine number of entries currently in queue */
int isl38xx_in_queue(isl38xx_control_block *cb, int queue);

void isl38xx_disable_interrupts(void __iomem *);
void isl38xx_enable_common_interrupts(void __iomem *);

void isl38xx_handle_sleep_request(isl38xx_control_block *, int *,
				  void __iomem *);
void isl38xx_handle_wakeup(isl38xx_control_block *, int *, void __iomem *);
void isl38xx_trigger_device(int, void __iomem *);
void isl38xx_interface_reset(void __iomem *, dma_addr_t);

#endif				/* _ISL_38XX_H */