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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
/* $OpenBSD: bcwvar.h,v 1.9 2006/12/28 22:23:07 mglocker Exp $ */
/*
* Copyright (c) 2006 Jon Simola <jsimola@gmail.com>
*
* Permission to use, copy, modify, and 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.
*/
/*
* Broadcom BCM43xx Wireless network chipsets (broadcom.com)
* SiliconBackplane is technology from Sonics, Inc.(sonicsinc.com)
*
* Cliff Wright cliff@snipe444.org
*/
#define BCW_MAX_RADIOS 2
struct bcw_radio {
u_int16_t id;
u_int16_t info;
u_char enabled;
};
#define BCW_MAX_CORES 10
struct bcw_core {
u_int16_t id;
u_int8_t num;
u_int8_t rev;
u_int8_t backplane_flag;
};
/* number of descriptors used in a ring */
#define BCW_RX_RING_COUNT 128
#define BCW_TX_RING_COUNT 128
#define BCW_MAX_SCATTER 8 /* XXX unknown, wild guess */
struct bcw_rx_data {
bus_dmamap_t map;
struct mbuf *m;
};
struct bcw_tx_data {
bus_dmamap_t map;
struct mbuf *m;
uint32_t softstat;
struct ieee80211_node *ni;
};
struct bcw_rx_ring {
bus_dmamap_t map;
bus_dma_segment_t seg;
bus_addr_t physaddr;
struct bcw_desc *desc;
struct bcw_rx_data *data;
int count;
int cur;
int next;
};
struct bcw_tx_ring {
bus_dmamap_t map;
bus_dma_segment_t seg;
bus_addr_t physaddr;
struct bcw_desc *desc;
struct bcw_tx_data *data;
int count;
int queued;
int cur;
int next;
int stat;
};
struct bcw_desc {
u_int32_t ctrl;
u_int32_t addr;
};
/* ring descriptor */
struct bcw_dma_slot {
u_int32_t ctrl;
u_int32_t addr;
};
#define CTRL_BC_MASK 0x1fff /* buffer byte count */
#define CTRL_EOT 0x10000000 /* end of descriptor table */
#define CTRL_IOC 0x20000000 /* interrupt on completion */
#define CTRL_EOF 0x40000000 /* end of frame */
#define CTRL_SOF 0x80000000 /* start of frame */
#if 0
/*
* Mbuf pointers. We need these to keep track of the virtual addresses
* of our mbuf chains since we can only convert from physical to virtual,
* not the other way around.
*
* The chip has 6 DMA engines, looks like we only need to use one each
* for TX and RX, the others stay disabled.
*/
struct bcw_chain_data {
struct mbuf *bcw_tx_chain[BCW_NTXDESC];
struct mbuf *bcw_rx_chain[BCW_NRXDESC];
bus_dmamap_t bcw_tx_map[BCW_NTXDESC];
bus_dmamap_t bcw_rx_map[BCW_NRXDESC];
};
#endif
struct bcw_rx_ring;
struct bcw_tx_ring;
/* Needs to have garbage removed */
struct bcw_softc {
struct device sc_dev;
struct ieee80211com sc_ic;
struct bcw_rx_ring sc_rxring;
struct bcw_tx_ring sc_txring;
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
int (*sc_enable)(struct bcw_softc *);
void (*sc_disable)(struct bcw_softc *);
void (*sc_power)(struct bcw_softc *, int);
void (*sc_conf_write)(struct bcw_softc *,
u_int32_t, u_int32_t);
u_int32_t (*sc_conf_read)(struct bcw_softc *, u_int32_t);
struct timeout sc_scan_to;
bus_dma_tag_t sc_dmat;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
void *bcw_intrhand;
const char *bcw_intrstr; /* interrupt description */
struct pci_attach_args sc_pa;
struct cardbus_attach_args sc_ca;
u_int32_t sc_phy; /* eeprom indicated phy */
struct bcw_dma_slot *bcw_rx_ring; /* receive ring */
struct bcw_dma_slot *bcw_tx_ring; /* transmit ring */
// struct bcw_chain_data sc_cdata; /* mbufs */
bus_dmamap_t sc_ring_map;
u_int32_t sc_intmask; /* current intr mask */
u_int32_t sc_rxin; /* last rx descriptor seen */
u_int32_t sc_txin; /* last tx descriptor seen */
int sc_txsfree; /* no. tx slots available */
int sc_txsnext; /* next available tx slot */
struct timeout sc_timeout;
/* Break these out into seperate structs */
u_int16_t sc_chipid; /* Chip ID */
u_int16_t sc_chiprev; /* Chip Revision */
u_int16_t sc_prodid; /* Product ID */
struct bcw_core sc_core[BCW_MAX_CORES];
// struct bcw_radio radio[BCW_MAX_RADIOS];
u_int16_t sc_phy_version;
u_int16_t sc_phy_type;
u_int16_t sc_phy_rev;
// u_int16_t sc_corerev;
u_int32_t sc_radioid;
u_int16_t sc_radiorev;
u_int16_t sc_radiotype;
u_int32_t sc_phyinfo;
u_int16_t sc_numcores;
u_int16_t sc_havecommon;
int sc_currentcore;
int sc_lastcore;
u_int8_t sc_radio_gain;
u_int16_t sc_radio_pa0b0;
u_int16_t sc_radio_pa0b1;
u_int16_t sc_radio_pa0b2;
u_int16_t sc_radio_pa1b0;
u_int16_t sc_radio_pa1b1;
u_int16_t sc_radio_pa1b2;
u_int8_t sc_idletssi;
u_int8_t sc_spromrev;
u_int16_t sc_boardflags;
u_int8_t sc_sbrev; /* Sonics Backplane Revision */
/* Core locations */
struct bcw_core *sc_core_common;
struct bcw_core *sc_core_80211;
struct bcw_core *sc_core_bus; /* PCI or cardbus */
};
void bcw_attach(struct bcw_softc *);
int bcw_detach(void *);
int bcw_intr(void *);
void bcw_powercontrol_crystal_on(struct bcw_softc *);
#define BCW_DEBUG
#ifdef BCW_DEBUG
//#define DPRINTF(x) do { if (bcw_debug) printf x; } while (0)
//#define DPRINTFN(n,x) do { if (bcwdebug >= (n)) printf x; } while (0)
#define DPRINTF(x) do { if (1) printf x; } while (0)
#define DPRINTFN(n,x) do { if (1 >= (n)) printf x; } while (0)
//int bcw_debug = 99;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
#endif
/*
* Some legacy stuff from bce and iwi to make this compile
*/
/* transmit buffer max frags allowed */
#define BCW_NTXFRAGS 16
/* Packet status is returned in a pre-packet header */
struct rx_pph {
u_int16_t len;
u_int16_t flags;
u_int16_t pad[12];
};
#define BCW_PREPKT_HEADER_SIZE 30
/* packet status flags bits */
#define RXF_NO 0x8 /* odd number of nibbles */
#define RXF_RXER 0x4 /* receive symbol error */
#define RXF_CRC 0x2 /* crc error */
#define RXF_OV 0x1 /* fifo overflow */
#define BCW_TIMEOUT 100 /* # 10us for mii read/write */
/* for ring descriptors */
#define BCW_RXBUF_LEN (MCLBYTES - 4)
#define BCW_INIT_RXDESC(sc, x) \
do { \
struct bcw_dma_slot *__bcwd = &sc->bcw_rx_ring[x]; \
\
*mtod(sc->bcw_cdata.bcw_rx_chain[x], u_int32_t *) = 0; \
__bcwd->addr = \
htole32(sc->bcw_cdata.bcw_rx_map[x]->dm_segs[0].ds_addr \
+ 0x40000000); \
if (x != (BCW_NRXDESC - 1)) \
__bcwd->ctrl = htole32(BCW_RXBUF_LEN); \
else \
__bcwd->ctrl = htole32(BCW_RXBUF_LEN | CTRL_EOT); \
bus_dmamap_sync(sc->bcw_dmatag, sc->bcw_ring_map, \
sizeof(struct bcw_dma_slot) * x, \
sizeof(struct bcw_dma_slot), \
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
} while (/* CONSTCOND */ 0)
#define BCW_NTXFRAGS 16
|