diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 11:20:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 11:20:34 -0400 |
commit | 9779a8325a9bbf4ccd3853e0e4064984cf9da9c9 (patch) | |
tree | 7814d54c7554210ee03d0dbecc546cc2e8a876ec /include/linux/uwb | |
parent | 309e1e4240636f3a9704d77a164a08e1f5a81fea (diff) | |
parent | 61e0e79ee3c609eb34edf2fe023708cba6a79b1f (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/dvrabel/uwb
* 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/dvrabel/uwb: (47 commits)
uwb: wrong sizeof argument in mac address compare
uwb: don't use printk_ratelimit() so often
uwb: use kcalloc where appropriate
uwb: use time_after() when purging stale beacons
uwb: add credits for the original developers of the UWB/WUSB/WLP subsystems
uwb: add entries in the MAINTAINERS file
uwb: depend on EXPERIMENTAL
wusb: wusb-cbaf (CBA driver) sysfs ABI simplification
uwb: document UWB and WUSB sysfs files
uwb: add symlinks in sysfs between radio controllers and PALs
uwb: dont tranmit identification IEs
uwb: i1480/GUWA100U: fix firmware download issues
uwb: i1480: remove MAC/PHY information checking function
uwb: add Intel i1480 HWA to the UWB RC quirk table
uwb: disable command/event filtering for D-Link DUB-1210
uwb: initialize the debug sub-system
uwb: Fix handling IEs with empty IE data in uwb_est_get_size()
wusb: fix bmRequestType for Abort RPipe request
wusb: fix error path for wusb_set_dev_addr()
wusb: add HWA host controller driver
...
Diffstat (limited to 'include/linux/uwb')
-rw-r--r-- | include/linux/uwb/debug-cmd.h | 57 | ||||
-rw-r--r-- | include/linux/uwb/debug.h | 82 | ||||
-rw-r--r-- | include/linux/uwb/spec.h | 727 | ||||
-rw-r--r-- | include/linux/uwb/umc.h | 194 | ||||
-rw-r--r-- | include/linux/uwb/whci.h | 117 |
5 files changed, 1177 insertions, 0 deletions
diff --git a/include/linux/uwb/debug-cmd.h b/include/linux/uwb/debug-cmd.h new file mode 100644 index 000000000000..1141f41bab5c --- /dev/null +++ b/include/linux/uwb/debug-cmd.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Ultra Wide Band | ||
3 | * Debug interface commands | ||
4 | * | ||
5 | * Copyright (C) 2008 Cambridge Silicon Radio Ltd. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | #ifndef __LINUX__UWB__DEBUG_CMD_H__ | ||
20 | #define __LINUX__UWB__DEBUG_CMD_H__ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | |||
24 | /* | ||
25 | * Debug interface commands | ||
26 | * | ||
27 | * UWB_DBG_CMD_RSV_ESTABLISH: Establish a new unicast reservation. | ||
28 | * | ||
29 | * UWB_DBG_CMD_RSV_TERMINATE: Terminate the Nth reservation. | ||
30 | */ | ||
31 | |||
32 | enum uwb_dbg_cmd_type { | ||
33 | UWB_DBG_CMD_RSV_ESTABLISH = 1, | ||
34 | UWB_DBG_CMD_RSV_TERMINATE = 2, | ||
35 | }; | ||
36 | |||
37 | struct uwb_dbg_cmd_rsv_establish { | ||
38 | __u8 target[6]; | ||
39 | __u8 type; | ||
40 | __u16 max_mas; | ||
41 | __u16 min_mas; | ||
42 | __u8 sparsity; | ||
43 | }; | ||
44 | |||
45 | struct uwb_dbg_cmd_rsv_terminate { | ||
46 | int index; | ||
47 | }; | ||
48 | |||
49 | struct uwb_dbg_cmd { | ||
50 | __u32 type; | ||
51 | union { | ||
52 | struct uwb_dbg_cmd_rsv_establish rsv_establish; | ||
53 | struct uwb_dbg_cmd_rsv_terminate rsv_terminate; | ||
54 | }; | ||
55 | }; | ||
56 | |||
57 | #endif /* #ifndef __LINUX__UWB__DEBUG_CMD_H__ */ | ||
diff --git a/include/linux/uwb/debug.h b/include/linux/uwb/debug.h new file mode 100644 index 000000000000..a86a73fe303f --- /dev/null +++ b/include/linux/uwb/debug.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Ultra Wide Band | ||
3 | * Debug Support | ||
4 | * | ||
5 | * Copyright (C) 2005-2006 Intel Corporation | ||
6 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA. | ||
21 | * | ||
22 | * | ||
23 | * FIXME: doc | ||
24 | * Invoke like: | ||
25 | * | ||
26 | * #define D_LOCAL 4 | ||
27 | * #include <linux/uwb/debug.h> | ||
28 | * | ||
29 | * At the end of your include files. | ||
30 | */ | ||
31 | #include <linux/types.h> | ||
32 | |||
33 | struct device; | ||
34 | extern void dump_bytes(struct device *dev, const void *_buf, size_t rsize); | ||
35 | |||
36 | /* Master debug switch; !0 enables, 0 disables */ | ||
37 | #define D_MASTER (!0) | ||
38 | |||
39 | /* Local (per-file) debug switch; #define before #including */ | ||
40 | #ifndef D_LOCAL | ||
41 | #define D_LOCAL 0 | ||
42 | #endif | ||
43 | |||
44 | #undef __d_printf | ||
45 | #undef d_fnstart | ||
46 | #undef d_fnend | ||
47 | #undef d_printf | ||
48 | #undef d_dump | ||
49 | |||
50 | #define __d_printf(l, _tag, _dev, f, a...) \ | ||
51 | do { \ | ||
52 | struct device *__dev = (_dev); \ | ||
53 | if (D_MASTER && D_LOCAL >= (l)) { \ | ||
54 | char __head[64] = ""; \ | ||
55 | if (_dev != NULL) { \ | ||
56 | if ((unsigned long)__dev < 4096) \ | ||
57 | printk(KERN_ERR "E: Corrupt dev %p\n", \ | ||
58 | __dev); \ | ||
59 | else \ | ||
60 | snprintf(__head, sizeof(__head), \ | ||
61 | "%s %s: ", \ | ||
62 | dev_driver_string(__dev), \ | ||
63 | __dev->bus_id); \ | ||
64 | } \ | ||
65 | printk(KERN_ERR "%s%s" _tag ": " f, __head, \ | ||
66 | __func__, ## a); \ | ||
67 | } \ | ||
68 | } while (0 && _dev) | ||
69 | |||
70 | #define d_fnstart(l, _dev, f, a...) \ | ||
71 | __d_printf(l, " FNSTART", _dev, f, ## a) | ||
72 | #define d_fnend(l, _dev, f, a...) \ | ||
73 | __d_printf(l, " FNEND", _dev, f, ## a) | ||
74 | #define d_printf(l, _dev, f, a...) \ | ||
75 | __d_printf(l, "", _dev, f, ## a) | ||
76 | #define d_dump(l, _dev, ptr, size) \ | ||
77 | do { \ | ||
78 | struct device *__dev = _dev; \ | ||
79 | if (D_MASTER && D_LOCAL >= (l)) \ | ||
80 | dump_bytes(__dev, ptr, size); \ | ||
81 | } while (0 && _dev) | ||
82 | #define d_test(l) (D_MASTER && D_LOCAL >= (l)) | ||
diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h new file mode 100644 index 000000000000..198c15f8e251 --- /dev/null +++ b/include/linux/uwb/spec.h | |||
@@ -0,0 +1,727 @@ | |||
1 | /* | ||
2 | * Ultra Wide Band | ||
3 | * UWB Standard definitions | ||
4 | * | ||
5 | * Copyright (C) 2005-2006 Intel Corporation | ||
6 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA. | ||
21 | * | ||
22 | * | ||
23 | * All these definitions are based on the ECMA-368 standard. | ||
24 | * | ||
25 | * Note all definitions are Little Endian in the wire, and we will | ||
26 | * convert them to host order before operating on the bitfields (that | ||
27 | * yes, we use extensively). | ||
28 | */ | ||
29 | |||
30 | #ifndef __LINUX__UWB_SPEC_H__ | ||
31 | #define __LINUX__UWB_SPEC_H__ | ||
32 | |||
33 | #include <linux/types.h> | ||
34 | #include <linux/bitmap.h> | ||
35 | |||
36 | #define i1480_FW 0x00000303 | ||
37 | /* #define i1480_FW 0x00000302 */ | ||
38 | |||
39 | /** | ||
40 | * Number of Medium Access Slots in a superframe. | ||
41 | * | ||
42 | * UWB divides time in SuperFrames, each one divided in 256 pieces, or | ||
43 | * Medium Access Slots. See MBOA MAC[5.4.5] for details. The MAS is the | ||
44 | * basic bandwidth allocation unit in UWB. | ||
45 | */ | ||
46 | enum { UWB_NUM_MAS = 256 }; | ||
47 | |||
48 | /** | ||
49 | * Number of Zones in superframe. | ||
50 | * | ||
51 | * UWB divides the superframe into zones with numbering starting from BPST. | ||
52 | * See MBOA MAC[16.8.6] | ||
53 | */ | ||
54 | enum { UWB_NUM_ZONES = 16 }; | ||
55 | |||
56 | /* | ||
57 | * Number of MAS in a zone. | ||
58 | */ | ||
59 | #define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES) | ||
60 | |||
61 | /* | ||
62 | * Number of streams per DRP reservation between a pair of devices. | ||
63 | * | ||
64 | * [ECMA-368] section 16.8.6. | ||
65 | */ | ||
66 | enum { UWB_NUM_STREAMS = 8 }; | ||
67 | |||
68 | /* | ||
69 | * mMasLength | ||
70 | * | ||
71 | * The length of a MAS in microseconds. | ||
72 | * | ||
73 | * [ECMA-368] section 17.16. | ||
74 | */ | ||
75 | enum { UWB_MAS_LENGTH_US = 256 }; | ||
76 | |||
77 | /* | ||
78 | * mBeaconSlotLength | ||
79 | * | ||
80 | * The length of the beacon slot in microseconds. | ||
81 | * | ||
82 | * [ECMA-368] section 17.16 | ||
83 | */ | ||
84 | enum { UWB_BEACON_SLOT_LENGTH_US = 85 }; | ||
85 | |||
86 | /* | ||
87 | * mMaxLostBeacons | ||
88 | * | ||
89 | * The number beacons missing in consecutive superframes before a | ||
90 | * device can be considered as unreachable. | ||
91 | * | ||
92 | * [ECMA-368] section 17.16 | ||
93 | */ | ||
94 | enum { UWB_MAX_LOST_BEACONS = 3 }; | ||
95 | |||
96 | /* | ||
97 | * Length of a superframe in microseconds. | ||
98 | */ | ||
99 | #define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS) | ||
100 | |||
101 | /** | ||
102 | * UWB MAC address | ||
103 | * | ||
104 | * It is *imperative* that this struct is exactly 6 packed bytes (as | ||
105 | * it is also used to define headers sent down and up the wire/radio). | ||
106 | */ | ||
107 | struct uwb_mac_addr { | ||
108 | u8 data[6]; | ||
109 | } __attribute__((packed)); | ||
110 | |||
111 | |||
112 | /** | ||
113 | * UWB device address | ||
114 | * | ||
115 | * It is *imperative* that this struct is exactly 6 packed bytes (as | ||
116 | * it is also used to define headers sent down and up the wire/radio). | ||
117 | */ | ||
118 | struct uwb_dev_addr { | ||
119 | u8 data[2]; | ||
120 | } __attribute__((packed)); | ||
121 | |||
122 | |||
123 | /** | ||
124 | * Types of UWB addresses | ||
125 | * | ||
126 | * Order matters (by size). | ||
127 | */ | ||
128 | enum uwb_addr_type { | ||
129 | UWB_ADDR_DEV = 0, | ||
130 | UWB_ADDR_MAC = 1, | ||
131 | }; | ||
132 | |||
133 | |||
134 | /** Size of a char buffer for printing a MAC/device address */ | ||
135 | enum { UWB_ADDR_STRSIZE = 32 }; | ||
136 | |||
137 | |||
138 | /** UWB WiMedia protocol IDs. */ | ||
139 | enum uwb_prid { | ||
140 | UWB_PRID_WLP_RESERVED = 0x0000, | ||
141 | UWB_PRID_WLP = 0x0001, | ||
142 | UWB_PRID_WUSB_BOT = 0x0010, | ||
143 | UWB_PRID_WUSB = 0x0010, | ||
144 | UWB_PRID_WUSB_TOP = 0x001F, | ||
145 | }; | ||
146 | |||
147 | |||
148 | /** PHY Rate (MBOA MAC[7.8.12, Table 61]) */ | ||
149 | enum uwb_phy_rate { | ||
150 | UWB_PHY_RATE_53 = 0, | ||
151 | UWB_PHY_RATE_80, | ||
152 | UWB_PHY_RATE_106, | ||
153 | UWB_PHY_RATE_160, | ||
154 | UWB_PHY_RATE_200, | ||
155 | UWB_PHY_RATE_320, | ||
156 | UWB_PHY_RATE_400, | ||
157 | UWB_PHY_RATE_480, | ||
158 | UWB_PHY_RATE_INVALID | ||
159 | }; | ||
160 | |||
161 | |||
162 | /** | ||
163 | * Different ways to scan (MBOA MAC[6.2.2, Table 8], WUSB[Table 8-78]) | ||
164 | */ | ||
165 | enum uwb_scan_type { | ||
166 | UWB_SCAN_ONLY = 0, | ||
167 | UWB_SCAN_OUTSIDE_BP, | ||
168 | UWB_SCAN_WHILE_INACTIVE, | ||
169 | UWB_SCAN_DISABLED, | ||
170 | UWB_SCAN_ONLY_STARTTIME, | ||
171 | UWB_SCAN_TOP | ||
172 | }; | ||
173 | |||
174 | |||
175 | /** ACK Policy types (MBOA MAC[7.2.1.3]) */ | ||
176 | enum uwb_ack_pol { | ||
177 | UWB_ACK_NO = 0, | ||
178 | UWB_ACK_INM = 1, | ||
179 | UWB_ACK_B = 2, | ||
180 | UWB_ACK_B_REQ = 3, | ||
181 | }; | ||
182 | |||
183 | |||
184 | /** DRP reservation types ([ECMA-368 table 106) */ | ||
185 | enum uwb_drp_type { | ||
186 | UWB_DRP_TYPE_ALIEN_BP = 0, | ||
187 | UWB_DRP_TYPE_HARD, | ||
188 | UWB_DRP_TYPE_SOFT, | ||
189 | UWB_DRP_TYPE_PRIVATE, | ||
190 | UWB_DRP_TYPE_PCA, | ||
191 | }; | ||
192 | |||
193 | |||
194 | /** DRP Reason Codes ([ECMA-368] table 107) */ | ||
195 | enum uwb_drp_reason { | ||
196 | UWB_DRP_REASON_ACCEPTED = 0, | ||
197 | UWB_DRP_REASON_CONFLICT, | ||
198 | UWB_DRP_REASON_PENDING, | ||
199 | UWB_DRP_REASON_DENIED, | ||
200 | UWB_DRP_REASON_MODIFIED, | ||
201 | }; | ||
202 | |||
203 | /** | ||
204 | * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) | ||
205 | */ | ||
206 | enum uwb_drp_notif_reason { | ||
207 | UWB_DRP_NOTIF_DRP_IE_RCVD = 0, | ||
208 | UWB_DRP_NOTIF_CONFLICT, | ||
209 | UWB_DRP_NOTIF_TERMINATE, | ||
210 | }; | ||
211 | |||
212 | |||
213 | /** Allocation of MAS slots in a DRP request MBOA MAC[7.8.7] */ | ||
214 | struct uwb_drp_alloc { | ||
215 | __le16 zone_bm; | ||
216 | __le16 mas_bm; | ||
217 | } __attribute__((packed)); | ||
218 | |||
219 | |||
220 | /** General MAC Header format (ECMA-368[16.2]) */ | ||
221 | struct uwb_mac_frame_hdr { | ||
222 | __le16 Frame_Control; | ||
223 | struct uwb_dev_addr DestAddr; | ||
224 | struct uwb_dev_addr SrcAddr; | ||
225 | __le16 Sequence_Control; | ||
226 | __le16 Access_Information; | ||
227 | } __attribute__((packed)); | ||
228 | |||
229 | |||
230 | /** | ||
231 | * uwb_beacon_frame - a beacon frame including MAC headers | ||
232 | * | ||
233 | * [ECMA] section 16.3. | ||
234 | */ | ||
235 | struct uwb_beacon_frame { | ||
236 | struct uwb_mac_frame_hdr hdr; | ||
237 | struct uwb_mac_addr Device_Identifier; /* may be a NULL EUI-48 */ | ||
238 | u8 Beacon_Slot_Number; | ||
239 | u8 Device_Control; | ||
240 | u8 IEData[]; | ||
241 | } __attribute__((packed)); | ||
242 | |||
243 | |||
244 | /** Information Element codes (MBOA MAC[T54]) */ | ||
245 | enum uwb_ie { | ||
246 | UWB_PCA_AVAILABILITY = 2, | ||
247 | UWB_IE_DRP_AVAILABILITY = 8, | ||
248 | UWB_IE_DRP = 9, | ||
249 | UWB_BP_SWITCH_IE = 11, | ||
250 | UWB_MAC_CAPABILITIES_IE = 12, | ||
251 | UWB_PHY_CAPABILITIES_IE = 13, | ||
252 | UWB_APP_SPEC_PROBE_IE = 15, | ||
253 | UWB_IDENTIFICATION_IE = 19, | ||
254 | UWB_MASTER_KEY_ID_IE = 20, | ||
255 | UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ | ||
256 | UWB_APP_SPEC_IE = 255, | ||
257 | }; | ||
258 | |||
259 | |||
260 | /** | ||
261 | * Header common to all Information Elements (IEs) | ||
262 | */ | ||
263 | struct uwb_ie_hdr { | ||
264 | u8 element_id; /* enum uwb_ie */ | ||
265 | u8 length; | ||
266 | } __attribute__((packed)); | ||
267 | |||
268 | |||
269 | /** Dynamic Reservation Protocol IE (MBOA MAC[7.8.6]) */ | ||
270 | struct uwb_ie_drp { | ||
271 | struct uwb_ie_hdr hdr; | ||
272 | __le16 drp_control; | ||
273 | struct uwb_dev_addr dev_addr; | ||
274 | struct uwb_drp_alloc allocs[]; | ||
275 | } __attribute__((packed)); | ||
276 | |||
277 | static inline int uwb_ie_drp_type(struct uwb_ie_drp *ie) | ||
278 | { | ||
279 | return (le16_to_cpu(ie->drp_control) >> 0) & 0x7; | ||
280 | } | ||
281 | |||
282 | static inline int uwb_ie_drp_stream_index(struct uwb_ie_drp *ie) | ||
283 | { | ||
284 | return (le16_to_cpu(ie->drp_control) >> 3) & 0x7; | ||
285 | } | ||
286 | |||
287 | static inline int uwb_ie_drp_reason_code(struct uwb_ie_drp *ie) | ||
288 | { | ||
289 | return (le16_to_cpu(ie->drp_control) >> 6) & 0x7; | ||
290 | } | ||
291 | |||
292 | static inline int uwb_ie_drp_status(struct uwb_ie_drp *ie) | ||
293 | { | ||
294 | return (le16_to_cpu(ie->drp_control) >> 9) & 0x1; | ||
295 | } | ||
296 | |||
297 | static inline int uwb_ie_drp_owner(struct uwb_ie_drp *ie) | ||
298 | { | ||
299 | return (le16_to_cpu(ie->drp_control) >> 10) & 0x1; | ||
300 | } | ||
301 | |||
302 | static inline int uwb_ie_drp_tiebreaker(struct uwb_ie_drp *ie) | ||
303 | { | ||
304 | return (le16_to_cpu(ie->drp_control) >> 11) & 0x1; | ||
305 | } | ||
306 | |||
307 | static inline int uwb_ie_drp_unsafe(struct uwb_ie_drp *ie) | ||
308 | { | ||
309 | return (le16_to_cpu(ie->drp_control) >> 12) & 0x1; | ||
310 | } | ||
311 | |||
312 | static inline void uwb_ie_drp_set_type(struct uwb_ie_drp *ie, enum uwb_drp_type type) | ||
313 | { | ||
314 | u16 drp_control = le16_to_cpu(ie->drp_control); | ||
315 | drp_control = (drp_control & ~(0x7 << 0)) | (type << 0); | ||
316 | ie->drp_control = cpu_to_le16(drp_control); | ||
317 | } | ||
318 | |||
319 | static inline void uwb_ie_drp_set_stream_index(struct uwb_ie_drp *ie, int stream_index) | ||
320 | { | ||
321 | u16 drp_control = le16_to_cpu(ie->drp_control); | ||
322 | drp_control = (drp_control & ~(0x7 << 3)) | (stream_index << 3); | ||
323 | ie->drp_control = cpu_to_le16(drp_control); | ||
324 | } | ||
325 | |||
326 | static inline void uwb_ie_drp_set_reason_code(struct uwb_ie_drp *ie, | ||
327 | enum uwb_drp_reason reason_code) | ||
328 | { | ||
329 | u16 drp_control = le16_to_cpu(ie->drp_control); | ||
330 | drp_control = (ie->drp_control & ~(0x7 << 6)) | (reason_code << 6); | ||
331 | ie->drp_control = cpu_to_le16(drp_control); | ||
332 | } | ||
333 | |||
334 | static inline void uwb_ie_drp_set_status(struct uwb_ie_drp *ie, int status) | ||
335 | { | ||
336 | u16 drp_control = le16_to_cpu(ie->drp_control); | ||
337 | drp_control = (drp_control & ~(0x1 << 9)) | (status << 9); | ||
338 | ie->drp_control = cpu_to_le16(drp_control); | ||
339 | } | ||
340 | |||
341 | static inline void uwb_ie_drp_set_owner(struct uwb_ie_drp *ie, int owner) | ||
342 | { | ||
343 | u16 drp_control = le16_to_cpu(ie->drp_control); | ||
344 | drp_control = (drp_control & ~(0x1 << 10)) | (owner << 10); | ||
345 | ie->drp_control = cpu_to_le16(drp_control); | ||
346 | } | ||
347 | |||
348 | static inline void uwb_ie_drp_set_tiebreaker(struct uwb_ie_drp *ie, int tiebreaker) | ||
349 | { | ||
350 | u16 drp_control = le16_to_cpu(ie->drp_control); | ||
351 | drp_control = (drp_control & ~(0x1 << 11)) | (tiebreaker << 11); | ||
352 | ie->drp_control = cpu_to_le16(drp_control); | ||
353 | } | ||
354 | |||
355 | static inline void uwb_ie_drp_set_unsafe(struct uwb_ie_drp *ie, int unsafe) | ||
356 | { | ||
357 | u16 drp_control = le16_to_cpu(ie->drp_control); | ||
358 | drp_control = (drp_control & ~(0x1 << 12)) | (unsafe << 12); | ||
359 | ie->drp_control = cpu_to_le16(drp_control); | ||
360 | } | ||
361 | |||
362 | /** Dynamic Reservation Protocol IE (MBOA MAC[7.8.7]) */ | ||
363 | struct uwb_ie_drp_avail { | ||
364 | struct uwb_ie_hdr hdr; | ||
365 | DECLARE_BITMAP(bmp, UWB_NUM_MAS); | ||
366 | } __attribute__((packed)); | ||
367 | |||
368 | /** | ||
369 | * The Vendor ID is set to an OUI that indicates the vendor of the device. | ||
370 | * ECMA-368 [16.8.10] | ||
371 | */ | ||
372 | struct uwb_vendor_id { | ||
373 | u8 data[3]; | ||
374 | } __attribute__((packed)); | ||
375 | |||
376 | /** | ||
377 | * The device type ID | ||
378 | * FIXME: clarify what this means | ||
379 | * ECMA-368 [16.8.10] | ||
380 | */ | ||
381 | struct uwb_device_type_id { | ||
382 | u8 data[3]; | ||
383 | } __attribute__((packed)); | ||
384 | |||
385 | |||
386 | /** | ||
387 | * UWB device information types | ||
388 | * ECMA-368 [16.8.10] | ||
389 | */ | ||
390 | enum uwb_dev_info_type { | ||
391 | UWB_DEV_INFO_VENDOR_ID = 0, | ||
392 | UWB_DEV_INFO_VENDOR_TYPE, | ||
393 | UWB_DEV_INFO_NAME, | ||
394 | }; | ||
395 | |||
396 | /** | ||
397 | * UWB device information found in Identification IE | ||
398 | * ECMA-368 [16.8.10] | ||
399 | */ | ||
400 | struct uwb_dev_info { | ||
401 | u8 type; /* enum uwb_dev_info_type */ | ||
402 | u8 length; | ||
403 | u8 data[]; | ||
404 | } __attribute__((packed)); | ||
405 | |||
406 | /** | ||
407 | * UWB Identification IE | ||
408 | * ECMA-368 [16.8.10] | ||
409 | */ | ||
410 | struct uwb_identification_ie { | ||
411 | struct uwb_ie_hdr hdr; | ||
412 | struct uwb_dev_info info[]; | ||
413 | } __attribute__((packed)); | ||
414 | |||
415 | /* | ||
416 | * UWB Radio Controller | ||
417 | * | ||
418 | * These definitions are common to the Radio Control layers as | ||
419 | * exported by the WUSB1.0 HWA and WHCI interfaces. | ||
420 | */ | ||
421 | |||
422 | /** Radio Control Command Block (WUSB1.0[Table 8-65] and WHCI 0.95) */ | ||
423 | struct uwb_rccb { | ||
424 | u8 bCommandType; /* enum hwa_cet */ | ||
425 | __le16 wCommand; /* Command code */ | ||
426 | u8 bCommandContext; /* Context ID */ | ||
427 | } __attribute__((packed)); | ||
428 | |||
429 | |||
430 | /** Radio Control Event Block (WUSB[table 8-66], WHCI 0.95) */ | ||
431 | struct uwb_rceb { | ||
432 | u8 bEventType; /* enum hwa_cet */ | ||
433 | __le16 wEvent; /* Event code */ | ||
434 | u8 bEventContext; /* Context ID */ | ||
435 | } __attribute__((packed)); | ||
436 | |||
437 | |||
438 | enum { | ||
439 | UWB_RC_CET_GENERAL = 0, /* General Command/Event type */ | ||
440 | UWB_RC_CET_EX_TYPE_1 = 1, /* Extended Type 1 Command/Event type */ | ||
441 | }; | ||
442 | |||
443 | /* Commands to the radio controller */ | ||
444 | enum uwb_rc_cmd { | ||
445 | UWB_RC_CMD_CHANNEL_CHANGE = 16, | ||
446 | UWB_RC_CMD_DEV_ADDR_MGMT = 17, /* Device Address Management */ | ||
447 | UWB_RC_CMD_GET_IE = 18, /* GET Information Elements */ | ||
448 | UWB_RC_CMD_RESET = 19, | ||
449 | UWB_RC_CMD_SCAN = 20, /* Scan management */ | ||
450 | UWB_RC_CMD_SET_BEACON_FILTER = 21, | ||
451 | UWB_RC_CMD_SET_DRP_IE = 22, /* Dynamic Reservation Protocol IEs */ | ||
452 | UWB_RC_CMD_SET_IE = 23, /* Information Element management */ | ||
453 | UWB_RC_CMD_SET_NOTIFICATION_FILTER = 24, | ||
454 | UWB_RC_CMD_SET_TX_POWER = 25, | ||
455 | UWB_RC_CMD_SLEEP = 26, | ||
456 | UWB_RC_CMD_START_BEACON = 27, | ||
457 | UWB_RC_CMD_STOP_BEACON = 28, | ||
458 | UWB_RC_CMD_BP_MERGE = 29, | ||
459 | UWB_RC_CMD_SEND_COMMAND_FRAME = 30, | ||
460 | UWB_RC_CMD_SET_ASIE_NOTIF = 31, | ||
461 | }; | ||
462 | |||
463 | /* Notifications from the radio controller */ | ||
464 | enum uwb_rc_evt { | ||
465 | UWB_RC_EVT_IE_RCV = 0, | ||
466 | UWB_RC_EVT_BEACON = 1, | ||
467 | UWB_RC_EVT_BEACON_SIZE = 2, | ||
468 | UWB_RC_EVT_BPOIE_CHANGE = 3, | ||
469 | UWB_RC_EVT_BP_SLOT_CHANGE = 4, | ||
470 | UWB_RC_EVT_BP_SWITCH_IE_RCV = 5, | ||
471 | UWB_RC_EVT_DEV_ADDR_CONFLICT = 6, | ||
472 | UWB_RC_EVT_DRP_AVAIL = 7, | ||
473 | UWB_RC_EVT_DRP = 8, | ||
474 | UWB_RC_EVT_BP_SWITCH_STATUS = 9, | ||
475 | UWB_RC_EVT_CMD_FRAME_RCV = 10, | ||
476 | UWB_RC_EVT_CHANNEL_CHANGE_IE_RCV = 11, | ||
477 | /* Events (command responses) use the same code as the command */ | ||
478 | UWB_RC_EVT_UNKNOWN_CMD_RCV = 65535, | ||
479 | }; | ||
480 | |||
481 | enum uwb_rc_extended_type_1_cmd { | ||
482 | UWB_RC_SET_DAA_ENERGY_MASK = 32, | ||
483 | UWB_RC_SET_NOTIFICATION_FILTER_EX = 33, | ||
484 | }; | ||
485 | |||
486 | enum uwb_rc_extended_type_1_evt { | ||
487 | UWB_RC_DAA_ENERGY_DETECTED = 0, | ||
488 | }; | ||
489 | |||
490 | /* Radio Control Result Code. [WHCI] table 3-3. */ | ||
491 | enum { | ||
492 | UWB_RC_RES_SUCCESS = 0, | ||
493 | UWB_RC_RES_FAIL, | ||
494 | UWB_RC_RES_FAIL_HARDWARE, | ||
495 | UWB_RC_RES_FAIL_NO_SLOTS, | ||
496 | UWB_RC_RES_FAIL_BEACON_TOO_LARGE, | ||
497 | UWB_RC_RES_FAIL_INVALID_PARAMETER, | ||
498 | UWB_RC_RES_FAIL_UNSUPPORTED_PWR_LEVEL, | ||
499 | UWB_RC_RES_FAIL_INVALID_IE_DATA, | ||
500 | UWB_RC_RES_FAIL_BEACON_SIZE_EXCEEDED, | ||
501 | UWB_RC_RES_FAIL_CANCELLED, | ||
502 | UWB_RC_RES_FAIL_INVALID_STATE, | ||
503 | UWB_RC_RES_FAIL_INVALID_SIZE, | ||
504 | UWB_RC_RES_FAIL_ACK_NOT_RECEIVED, | ||
505 | UWB_RC_RES_FAIL_NO_MORE_ASIE_NOTIF, | ||
506 | UWB_RC_RES_FAIL_TIME_OUT = 255, | ||
507 | }; | ||
508 | |||
509 | /* Confirm event. [WHCI] section 3.1.3.1 etc. */ | ||
510 | struct uwb_rc_evt_confirm { | ||
511 | struct uwb_rceb rceb; | ||
512 | u8 bResultCode; | ||
513 | } __attribute__((packed)); | ||
514 | |||
515 | /* Device Address Management event. [WHCI] section 3.1.3.2. */ | ||
516 | struct uwb_rc_evt_dev_addr_mgmt { | ||
517 | struct uwb_rceb rceb; | ||
518 | u8 baAddr[6]; | ||
519 | u8 bResultCode; | ||
520 | } __attribute__((packed)); | ||
521 | |||
522 | |||
523 | /* Get IE Event. [WHCI] section 3.1.3.3. */ | ||
524 | struct uwb_rc_evt_get_ie { | ||
525 | struct uwb_rceb rceb; | ||
526 | __le16 wIELength; | ||
527 | u8 IEData[]; | ||
528 | } __attribute__((packed)); | ||
529 | |||
530 | /* Set DRP IE Event. [WHCI] section 3.1.3.7. */ | ||
531 | struct uwb_rc_evt_set_drp_ie { | ||
532 | struct uwb_rceb rceb; | ||
533 | __le16 wRemainingSpace; | ||
534 | u8 bResultCode; | ||
535 | } __attribute__((packed)); | ||
536 | |||
537 | /* Set IE Event. [WHCI] section 3.1.3.8. */ | ||
538 | struct uwb_rc_evt_set_ie { | ||
539 | struct uwb_rceb rceb; | ||
540 | __le16 RemainingSpace; | ||
541 | u8 bResultCode; | ||
542 | } __attribute__((packed)); | ||
543 | |||
544 | /* Scan command. [WHCI] 3.1.3.5. */ | ||
545 | struct uwb_rc_cmd_scan { | ||
546 | struct uwb_rccb rccb; | ||
547 | u8 bChannelNumber; | ||
548 | u8 bScanState; | ||
549 | __le16 wStartTime; | ||
550 | } __attribute__((packed)); | ||
551 | |||
552 | /* Set DRP IE command. [WHCI] section 3.1.3.7. */ | ||
553 | struct uwb_rc_cmd_set_drp_ie { | ||
554 | struct uwb_rccb rccb; | ||
555 | __le16 wIELength; | ||
556 | struct uwb_ie_drp IEData[]; | ||
557 | } __attribute__((packed)); | ||
558 | |||
559 | /* Set IE command. [WHCI] section 3.1.3.8. */ | ||
560 | struct uwb_rc_cmd_set_ie { | ||
561 | struct uwb_rccb rccb; | ||
562 | __le16 wIELength; | ||
563 | u8 IEData[]; | ||
564 | } __attribute__((packed)); | ||
565 | |||
566 | /* Set DAA Energy Mask event. [WHCI 0.96] section 3.1.3.17. */ | ||
567 | struct uwb_rc_evt_set_daa_energy_mask { | ||
568 | struct uwb_rceb rceb; | ||
569 | __le16 wLength; | ||
570 | u8 result; | ||
571 | } __attribute__((packed)); | ||
572 | |||
573 | /* Set Notification Filter Extended event. [WHCI 0.96] section 3.1.3.18. */ | ||
574 | struct uwb_rc_evt_set_notification_filter_ex { | ||
575 | struct uwb_rceb rceb; | ||
576 | __le16 wLength; | ||
577 | u8 result; | ||
578 | } __attribute__((packed)); | ||
579 | |||
580 | /* IE Received notification. [WHCI] section 3.1.4.1. */ | ||
581 | struct uwb_rc_evt_ie_rcv { | ||
582 | struct uwb_rceb rceb; | ||
583 | struct uwb_dev_addr SrcAddr; | ||
584 | __le16 wIELength; | ||
585 | u8 IEData[]; | ||
586 | } __attribute__((packed)); | ||
587 | |||
588 | /* Type of the received beacon. [WHCI] section 3.1.4.2. */ | ||
589 | enum uwb_rc_beacon_type { | ||
590 | UWB_RC_BEACON_TYPE_SCAN = 0, | ||
591 | UWB_RC_BEACON_TYPE_NEIGHBOR, | ||
592 | UWB_RC_BEACON_TYPE_OL_ALIEN, | ||
593 | UWB_RC_BEACON_TYPE_NOL_ALIEN, | ||
594 | }; | ||
595 | |||
596 | /* Beacon received notification. [WHCI] 3.1.4.2. */ | ||
597 | struct uwb_rc_evt_beacon { | ||
598 | struct uwb_rceb rceb; | ||
599 | u8 bChannelNumber; | ||
600 | u8 bBeaconType; | ||
601 | __le16 wBPSTOffset; | ||
602 | u8 bLQI; | ||
603 | u8 bRSSI; | ||
604 | __le16 wBeaconInfoLength; | ||
605 | u8 BeaconInfo[]; | ||
606 | } __attribute__((packed)); | ||
607 | |||
608 | |||
609 | /* Beacon Size Change notification. [WHCI] section 3.1.4.3 */ | ||
610 | struct uwb_rc_evt_beacon_size { | ||
611 | struct uwb_rceb rceb; | ||
612 | __le16 wNewBeaconSize; | ||
613 | } __attribute__((packed)); | ||
614 | |||
615 | |||
616 | /* BPOIE Change notification. [WHCI] section 3.1.4.4. */ | ||
617 | struct uwb_rc_evt_bpoie_change { | ||
618 | struct uwb_rceb rceb; | ||
619 | __le16 wBPOIELength; | ||
620 | u8 BPOIE[]; | ||
621 | } __attribute__((packed)); | ||
622 | |||
623 | |||
624 | /* Beacon Slot Change notification. [WHCI] section 3.1.4.5. */ | ||
625 | struct uwb_rc_evt_bp_slot_change { | ||
626 | struct uwb_rceb rceb; | ||
627 | u8 slot_info; | ||
628 | } __attribute__((packed)); | ||
629 | |||
630 | static inline int uwb_rc_evt_bp_slot_change_slot_num( | ||
631 | const struct uwb_rc_evt_bp_slot_change *evt) | ||
632 | { | ||
633 | return evt->slot_info & 0x7f; | ||
634 | } | ||
635 | |||
636 | static inline int uwb_rc_evt_bp_slot_change_no_slot( | ||
637 | const struct uwb_rc_evt_bp_slot_change *evt) | ||
638 | { | ||
639 | return (evt->slot_info & 0x80) >> 7; | ||
640 | } | ||
641 | |||
642 | /* BP Switch IE Received notification. [WHCI] section 3.1.4.6. */ | ||
643 | struct uwb_rc_evt_bp_switch_ie_rcv { | ||
644 | struct uwb_rceb rceb; | ||
645 | struct uwb_dev_addr wSrcAddr; | ||
646 | __le16 wIELength; | ||
647 | u8 IEData[]; | ||
648 | } __attribute__((packed)); | ||
649 | |||
650 | /* DevAddr Conflict notification. [WHCI] section 3.1.4.7. */ | ||
651 | struct uwb_rc_evt_dev_addr_conflict { | ||
652 | struct uwb_rceb rceb; | ||
653 | } __attribute__((packed)); | ||
654 | |||
655 | /* DRP notification. [WHCI] section 3.1.4.9. */ | ||
656 | struct uwb_rc_evt_drp { | ||
657 | struct uwb_rceb rceb; | ||
658 | struct uwb_dev_addr src_addr; | ||
659 | u8 reason; | ||
660 | u8 beacon_slot_number; | ||
661 | __le16 ie_length; | ||
662 | u8 ie_data[]; | ||
663 | } __attribute__((packed)); | ||
664 | |||
665 | static inline enum uwb_drp_notif_reason uwb_rc_evt_drp_reason(struct uwb_rc_evt_drp *evt) | ||
666 | { | ||
667 | return evt->reason & 0x0f; | ||
668 | } | ||
669 | |||
670 | |||
671 | /* DRP Availability Change notification. [WHCI] section 3.1.4.8. */ | ||
672 | struct uwb_rc_evt_drp_avail { | ||
673 | struct uwb_rceb rceb; | ||
674 | DECLARE_BITMAP(bmp, UWB_NUM_MAS); | ||
675 | } __attribute__((packed)); | ||
676 | |||
677 | /* BP switch status notification. [WHCI] section 3.1.4.10. */ | ||
678 | struct uwb_rc_evt_bp_switch_status { | ||
679 | struct uwb_rceb rceb; | ||
680 | u8 status; | ||
681 | u8 slot_offset; | ||
682 | __le16 bpst_offset; | ||
683 | u8 move_countdown; | ||
684 | } __attribute__((packed)); | ||
685 | |||
686 | /* Command Frame Received notification. [WHCI] section 3.1.4.11. */ | ||
687 | struct uwb_rc_evt_cmd_frame_rcv { | ||
688 | struct uwb_rceb rceb; | ||
689 | __le16 receive_time; | ||
690 | struct uwb_dev_addr wSrcAddr; | ||
691 | struct uwb_dev_addr wDstAddr; | ||
692 | __le16 control; | ||
693 | __le16 reserved; | ||
694 | __le16 dataLength; | ||
695 | u8 data[]; | ||
696 | } __attribute__((packed)); | ||
697 | |||
698 | /* Channel Change IE Received notification. [WHCI] section 3.1.4.12. */ | ||
699 | struct uwb_rc_evt_channel_change_ie_rcv { | ||
700 | struct uwb_rceb rceb; | ||
701 | struct uwb_dev_addr wSrcAddr; | ||
702 | __le16 wIELength; | ||
703 | u8 IEData[]; | ||
704 | } __attribute__((packed)); | ||
705 | |||
706 | /* DAA Energy Detected notification. [WHCI 0.96] section 3.1.4.14. */ | ||
707 | struct uwb_rc_evt_daa_energy_detected { | ||
708 | struct uwb_rceb rceb; | ||
709 | __le16 wLength; | ||
710 | u8 bandID; | ||
711 | u8 reserved; | ||
712 | u8 toneBmp[16]; | ||
713 | } __attribute__((packed)); | ||
714 | |||
715 | |||
716 | /** | ||
717 | * Radio Control Interface Class Descriptor | ||
718 | * | ||
719 | * WUSB 1.0 [8.6.1.2] | ||
720 | */ | ||
721 | struct uwb_rc_control_intf_class_desc { | ||
722 | u8 bLength; | ||
723 | u8 bDescriptorType; | ||
724 | __le16 bcdRCIVersion; | ||
725 | } __attribute__((packed)); | ||
726 | |||
727 | #endif /* #ifndef __LINUX__UWB_SPEC_H__ */ | ||
diff --git a/include/linux/uwb/umc.h b/include/linux/uwb/umc.h new file mode 100644 index 000000000000..36a39e34f8d7 --- /dev/null +++ b/include/linux/uwb/umc.h | |||
@@ -0,0 +1,194 @@ | |||
1 | /* | ||
2 | * UWB Multi-interface Controller support. | ||
3 | * | ||
4 | * Copyright (C) 2007 Cambridge Silicon Radio Ltd. | ||
5 | * | ||
6 | * This file is released under the GPLv2 | ||
7 | * | ||
8 | * UMC (UWB Multi-interface Controller) capabilities (e.g., radio | ||
9 | * controller, host controller) are presented as devices on the "umc" | ||
10 | * bus. | ||
11 | * | ||
12 | * The radio controller is not strictly a UMC capability but it's | ||
13 | * useful to present it as such. | ||
14 | * | ||
15 | * References: | ||
16 | * | ||
17 | * [WHCI] Wireless Host Controller Interface Specification for | ||
18 | * Certified Wireless Universal Serial Bus, revision 0.95. | ||
19 | * | ||
20 | * How this works is kind of convoluted but simple. The whci.ko driver | ||
21 | * loads when WHCI devices are detected. These WHCI devices expose | ||
22 | * many devices in the same PCI function (they couldn't have reused | ||
23 | * functions, no), so for each PCI function that exposes these many | ||
24 | * devices, whci ceates a umc_dev [whci_probe() -> whci_add_cap()] | ||
25 | * with umc_device_create() and adds it to the bus with | ||
26 | * umc_device_register(). | ||
27 | * | ||
28 | * umc_device_register() calls device_register() which will push the | ||
29 | * bus management code to load your UMC driver's somehting_probe() | ||
30 | * that you have registered for that capability code. | ||
31 | * | ||
32 | * Now when the WHCI device is removed, whci_remove() will go over | ||
33 | * each umc_dev assigned to each of the PCI function's capabilities | ||
34 | * and through whci_del_cap() call umc_device_unregister() each | ||
35 | * created umc_dev. Of course, if you are bound to the device, your | ||
36 | * driver's something_remove() will be called. | ||
37 | */ | ||
38 | |||
39 | #ifndef _LINUX_UWB_UMC_H_ | ||
40 | #define _LINUX_UWB_UMC_H_ | ||
41 | |||
42 | #include <linux/device.h> | ||
43 | #include <linux/pci.h> | ||
44 | |||
45 | /* | ||
46 | * UMC capability IDs. | ||
47 | * | ||
48 | * 0x00 is reserved so use it for the radio controller device. | ||
49 | * | ||
50 | * [WHCI] table 2-8 | ||
51 | */ | ||
52 | #define UMC_CAP_ID_WHCI_RC 0x00 /* radio controller */ | ||
53 | #define UMC_CAP_ID_WHCI_WUSB_HC 0x01 /* WUSB host controller */ | ||
54 | |||
55 | /** | ||
56 | * struct umc_dev - UMC capability device | ||
57 | * | ||
58 | * @version: version of the specification this capability conforms to. | ||
59 | * @cap_id: capability ID. | ||
60 | * @bar: PCI Bar (64 bit) where the resource lies | ||
61 | * @resource: register space resource. | ||
62 | * @irq: interrupt line. | ||
63 | */ | ||
64 | struct umc_dev { | ||
65 | u16 version; | ||
66 | u8 cap_id; | ||
67 | u8 bar; | ||
68 | struct resource resource; | ||
69 | unsigned irq; | ||
70 | struct device dev; | ||
71 | }; | ||
72 | |||
73 | #define to_umc_dev(d) container_of(d, struct umc_dev, dev) | ||
74 | |||
75 | /** | ||
76 | * struct umc_driver - UMC capability driver | ||
77 | * @cap_id: supported capability ID. | ||
78 | * @match: driver specific capability matching function. | ||
79 | * @match_data: driver specific data for match() (e.g., a | ||
80 | * table of pci_device_id's if umc_match_pci_id() is used). | ||
81 | */ | ||
82 | struct umc_driver { | ||
83 | char *name; | ||
84 | u8 cap_id; | ||
85 | int (*match)(struct umc_driver *, struct umc_dev *); | ||
86 | const void *match_data; | ||
87 | |||
88 | int (*probe)(struct umc_dev *); | ||
89 | void (*remove)(struct umc_dev *); | ||
90 | int (*suspend)(struct umc_dev *, pm_message_t state); | ||
91 | int (*resume)(struct umc_dev *); | ||
92 | |||
93 | struct device_driver driver; | ||
94 | }; | ||
95 | |||
96 | #define to_umc_driver(d) container_of(d, struct umc_driver, driver) | ||
97 | |||
98 | extern struct bus_type umc_bus_type; | ||
99 | |||
100 | struct umc_dev *umc_device_create(struct device *parent, int n); | ||
101 | int __must_check umc_device_register(struct umc_dev *umc); | ||
102 | void umc_device_unregister(struct umc_dev *umc); | ||
103 | |||
104 | int __must_check __umc_driver_register(struct umc_driver *umc_drv, | ||
105 | struct module *mod, | ||
106 | const char *mod_name); | ||
107 | |||
108 | /** | ||
109 | * umc_driver_register - register a UMC capabiltity driver. | ||
110 | * @umc_drv: pointer to the driver. | ||
111 | */ | ||
112 | static inline int __must_check umc_driver_register(struct umc_driver *umc_drv) | ||
113 | { | ||
114 | return __umc_driver_register(umc_drv, THIS_MODULE, KBUILD_MODNAME); | ||
115 | } | ||
116 | void umc_driver_unregister(struct umc_driver *umc_drv); | ||
117 | |||
118 | /* | ||
119 | * Utility function you can use to match (umc_driver->match) against a | ||
120 | * null-terminated array of 'struct pci_device_id' in | ||
121 | * umc_driver->match_data. | ||
122 | */ | ||
123 | int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc); | ||
124 | |||
125 | /** | ||
126 | * umc_parent_pci_dev - return the UMC's parent PCI device or NULL if none | ||
127 | * @umc_dev: UMC device whose parent PCI device we are looking for | ||
128 | * | ||
129 | * DIRTY!!! DON'T RELY ON THIS | ||
130 | * | ||
131 | * FIXME: This is as dirty as it gets, but we need some way to check | ||
132 | * the correct type of umc_dev->parent (so that for example, we can | ||
133 | * cast to pci_dev). Casting to pci_dev is necesary because at some | ||
134 | * point we need to request resources from the device. Mapping is | ||
135 | * easily over come (ioremap and stuff are bus agnostic), but hooking | ||
136 | * up to some error handlers (such as pci error handlers) might need | ||
137 | * this. | ||
138 | * | ||
139 | * THIS might (probably will) be removed in the future, so don't count | ||
140 | * on it. | ||
141 | */ | ||
142 | static inline struct pci_dev *umc_parent_pci_dev(struct umc_dev *umc_dev) | ||
143 | { | ||
144 | struct pci_dev *pci_dev = NULL; | ||
145 | if (umc_dev->dev.parent->bus == &pci_bus_type) | ||
146 | pci_dev = to_pci_dev(umc_dev->dev.parent); | ||
147 | return pci_dev; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * umc_dev_get() - reference a UMC device. | ||
152 | * @umc_dev: Pointer to UMC device. | ||
153 | * | ||
154 | * NOTE: we are assuming in this whole scheme that the parent device | ||
155 | * is referenced at _probe() time and unreferenced at _remove() | ||
156 | * time by the parent's subsystem. | ||
157 | */ | ||
158 | static inline struct umc_dev *umc_dev_get(struct umc_dev *umc_dev) | ||
159 | { | ||
160 | get_device(&umc_dev->dev); | ||
161 | return umc_dev; | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * umc_dev_put() - unreference a UMC device. | ||
166 | * @umc_dev: Pointer to UMC device. | ||
167 | */ | ||
168 | static inline void umc_dev_put(struct umc_dev *umc_dev) | ||
169 | { | ||
170 | put_device(&umc_dev->dev); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * umc_set_drvdata - set UMC device's driver data. | ||
175 | * @umc_dev: Pointer to UMC device. | ||
176 | * @data: Data to set. | ||
177 | */ | ||
178 | static inline void umc_set_drvdata(struct umc_dev *umc_dev, void *data) | ||
179 | { | ||
180 | dev_set_drvdata(&umc_dev->dev, data); | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * umc_get_drvdata - recover UMC device's driver data. | ||
185 | * @umc_dev: Pointer to UMC device. | ||
186 | */ | ||
187 | static inline void *umc_get_drvdata(struct umc_dev *umc_dev) | ||
188 | { | ||
189 | return dev_get_drvdata(&umc_dev->dev); | ||
190 | } | ||
191 | |||
192 | int umc_controller_reset(struct umc_dev *umc); | ||
193 | |||
194 | #endif /* #ifndef _LINUX_UWB_UMC_H_ */ | ||
diff --git a/include/linux/uwb/whci.h b/include/linux/uwb/whci.h new file mode 100644 index 000000000000..915ec23042d4 --- /dev/null +++ b/include/linux/uwb/whci.h | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * Wireless Host Controller Interface for Ultra-Wide-Band and Wireless USB | ||
3 | * | ||
4 | * Copyright (C) 2005-2006 Intel Corporation | ||
5 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
19 | * 02110-1301, USA. | ||
20 | * | ||
21 | * | ||
22 | * | ||
23 | * References: | ||
24 | * [WHCI] Wireless Host Controller Interface Specification for | ||
25 | * Certified Wireless Universal Serial Bus, revision 0.95. | ||
26 | */ | ||
27 | #ifndef _LINUX_UWB_WHCI_H_ | ||
28 | #define _LINUX_UWB_WHCI_H_ | ||
29 | |||
30 | #include <linux/pci.h> | ||
31 | |||
32 | /* | ||
33 | * UWB interface capability registers (offsets from UWBBASE) | ||
34 | * | ||
35 | * [WHCI] section 2.2 | ||
36 | */ | ||
37 | #define UWBCAPINFO 0x00 /* == UWBCAPDATA(0) */ | ||
38 | # define UWBCAPINFO_TO_N_CAPS(c) (((c) >> 0) & 0xFull) | ||
39 | #define UWBCAPDATA(n) (8*(n)) | ||
40 | # define UWBCAPDATA_TO_VERSION(c) (((c) >> 32) & 0xFFFFull) | ||
41 | # define UWBCAPDATA_TO_OFFSET(c) (((c) >> 18) & 0x3FFFull) | ||
42 | # define UWBCAPDATA_TO_BAR(c) (((c) >> 16) & 0x3ull) | ||
43 | # define UWBCAPDATA_TO_SIZE(c) ((((c) >> 8) & 0xFFull) * sizeof(u32)) | ||
44 | # define UWBCAPDATA_TO_CAP_ID(c) (((c) >> 0) & 0xFFull) | ||
45 | |||
46 | /* Size of the WHCI capability data (including the RC capability) for | ||
47 | a device with n capabilities. */ | ||
48 | #define UWBCAPDATA_SIZE(n) (8 + 8*(n)) | ||
49 | |||
50 | |||
51 | /* | ||
52 | * URC registers (offsets from URCBASE) | ||
53 | * | ||
54 | * [WHCI] section 2.3 | ||
55 | */ | ||
56 | #define URCCMD 0x00 | ||
57 | # define URCCMD_RESET (1 << 31) /* UMC Hardware reset */ | ||
58 | # define URCCMD_RS (1 << 30) /* Run/Stop */ | ||
59 | # define URCCMD_EARV (1 << 29) /* Event Address Register Valid */ | ||
60 | # define URCCMD_ACTIVE (1 << 15) /* Command is active */ | ||
61 | # define URCCMD_IWR (1 << 14) /* Interrupt When Ready */ | ||
62 | # define URCCMD_SIZE_MASK 0x00000fff /* Command size mask */ | ||
63 | #define URCSTS 0x04 | ||
64 | # define URCSTS_EPS (1 << 17) /* Event Processing Status */ | ||
65 | # define URCSTS_HALTED (1 << 16) /* RC halted */ | ||
66 | # define URCSTS_HSE (1 << 10) /* Host System Error...fried */ | ||
67 | # define URCSTS_ER (1 << 9) /* Event Ready */ | ||
68 | # define URCSTS_RCI (1 << 8) /* Ready for Command Interrupt */ | ||
69 | # define URCSTS_INT_MASK 0x00000700 /* URC interrupt sources */ | ||
70 | # define URCSTS_ISI 0x000000ff /* Interrupt Source Identification */ | ||
71 | #define URCINTR 0x08 | ||
72 | # define URCINTR_EN_ALL 0x000007ff /* Enable all interrupt sources */ | ||
73 | #define URCCMDADDR 0x10 | ||
74 | #define URCEVTADDR 0x18 | ||
75 | # define URCEVTADDR_OFFSET_MASK 0xfff /* Event pointer offset mask */ | ||
76 | |||
77 | |||
78 | /** Write 32 bit @value to little endian register at @addr */ | ||
79 | static inline | ||
80 | void le_writel(u32 value, void __iomem *addr) | ||
81 | { | ||
82 | iowrite32(value, addr); | ||
83 | } | ||
84 | |||
85 | |||
86 | /** Read from 32 bit little endian register at @addr */ | ||
87 | static inline | ||
88 | u32 le_readl(void __iomem *addr) | ||
89 | { | ||
90 | return ioread32(addr); | ||
91 | } | ||
92 | |||
93 | |||
94 | /** Write 64 bit @value to little endian register at @addr */ | ||
95 | static inline | ||
96 | void le_writeq(u64 value, void __iomem *addr) | ||
97 | { | ||
98 | iowrite32(value, addr); | ||
99 | iowrite32(value >> 32, addr + 4); | ||
100 | } | ||
101 | |||
102 | |||
103 | /** Read from 64 bit little endian register at @addr */ | ||
104 | static inline | ||
105 | u64 le_readq(void __iomem *addr) | ||
106 | { | ||
107 | u64 value; | ||
108 | value = ioread32(addr); | ||
109 | value |= (u64)ioread32(addr + 4) << 32; | ||
110 | return value; | ||
111 | } | ||
112 | |||
113 | extern int whci_wait_for(struct device *dev, u32 __iomem *reg, | ||
114 | u32 mask, u32 result, | ||
115 | unsigned long max_ms, const char *tag); | ||
116 | |||
117 | #endif /* #ifndef _LINUX_UWB_WHCI_H_ */ | ||