diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/usb.c')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/usb.c | 431 |
1 files changed, 0 insertions, 431 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c deleted file mode 100644 index e3cf397fcaf..00000000000 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ /dev/null | |||
@@ -1,431 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2007-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/usb.h> | ||
19 | |||
20 | #include "debug.h" | ||
21 | #include "core.h" | ||
22 | |||
23 | /* usb device object */ | ||
24 | struct ath6kl_usb { | ||
25 | struct usb_device *udev; | ||
26 | struct usb_interface *interface; | ||
27 | u8 *diag_cmd_buffer; | ||
28 | u8 *diag_resp_buffer; | ||
29 | struct ath6kl *ar; | ||
30 | }; | ||
31 | |||
32 | /* diagnostic command defnitions */ | ||
33 | #define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1 | ||
34 | #define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2 | ||
35 | #define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3 | ||
36 | #define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4 | ||
37 | |||
38 | #define ATH6KL_USB_CTRL_DIAG_CC_READ 0 | ||
39 | #define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1 | ||
40 | |||
41 | struct ath6kl_usb_ctrl_diag_cmd_write { | ||
42 | __le32 cmd; | ||
43 | __le32 address; | ||
44 | __le32 value; | ||
45 | __le32 _pad[1]; | ||
46 | } __packed; | ||
47 | |||
48 | struct ath6kl_usb_ctrl_diag_cmd_read { | ||
49 | __le32 cmd; | ||
50 | __le32 address; | ||
51 | } __packed; | ||
52 | |||
53 | struct ath6kl_usb_ctrl_diag_resp_read { | ||
54 | __le32 value; | ||
55 | } __packed; | ||
56 | |||
57 | #define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)) | ||
58 | #define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read)) | ||
59 | |||
60 | static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb) | ||
61 | { | ||
62 | usb_set_intfdata(ar_usb->interface, NULL); | ||
63 | |||
64 | kfree(ar_usb->diag_cmd_buffer); | ||
65 | kfree(ar_usb->diag_resp_buffer); | ||
66 | |||
67 | kfree(ar_usb); | ||
68 | } | ||
69 | |||
70 | static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface) | ||
71 | { | ||
72 | struct ath6kl_usb *ar_usb = NULL; | ||
73 | struct usb_device *dev = interface_to_usbdev(interface); | ||
74 | int status = 0; | ||
75 | |||
76 | ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL); | ||
77 | if (ar_usb == NULL) | ||
78 | goto fail_ath6kl_usb_create; | ||
79 | |||
80 | memset(ar_usb, 0, sizeof(struct ath6kl_usb)); | ||
81 | usb_set_intfdata(interface, ar_usb); | ||
82 | ar_usb->udev = dev; | ||
83 | ar_usb->interface = interface; | ||
84 | |||
85 | ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL); | ||
86 | if (ar_usb->diag_cmd_buffer == NULL) { | ||
87 | status = -ENOMEM; | ||
88 | goto fail_ath6kl_usb_create; | ||
89 | } | ||
90 | |||
91 | ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP, | ||
92 | GFP_KERNEL); | ||
93 | if (ar_usb->diag_resp_buffer == NULL) { | ||
94 | status = -ENOMEM; | ||
95 | goto fail_ath6kl_usb_create; | ||
96 | } | ||
97 | |||
98 | fail_ath6kl_usb_create: | ||
99 | if (status != 0) { | ||
100 | ath6kl_usb_destroy(ar_usb); | ||
101 | ar_usb = NULL; | ||
102 | } | ||
103 | return ar_usb; | ||
104 | } | ||
105 | |||
106 | static void ath6kl_usb_device_detached(struct usb_interface *interface) | ||
107 | { | ||
108 | struct ath6kl_usb *ar_usb; | ||
109 | |||
110 | ar_usb = usb_get_intfdata(interface); | ||
111 | if (ar_usb == NULL) | ||
112 | return; | ||
113 | |||
114 | ath6kl_stop_txrx(ar_usb->ar); | ||
115 | |||
116 | ath6kl_core_cleanup(ar_usb->ar); | ||
117 | |||
118 | ath6kl_usb_destroy(ar_usb); | ||
119 | } | ||
120 | |||
121 | static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, | ||
122 | u8 req, u16 value, u16 index, void *data, | ||
123 | u32 size) | ||
124 | { | ||
125 | u8 *buf = NULL; | ||
126 | int ret; | ||
127 | |||
128 | if (size > 0) { | ||
129 | buf = kmalloc(size, GFP_KERNEL); | ||
130 | if (buf == NULL) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | memcpy(buf, data, size); | ||
134 | } | ||
135 | |||
136 | /* note: if successful returns number of bytes transfered */ | ||
137 | ret = usb_control_msg(ar_usb->udev, | ||
138 | usb_sndctrlpipe(ar_usb->udev, 0), | ||
139 | req, | ||
140 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
141 | USB_RECIP_DEVICE, value, index, buf, | ||
142 | size, 1000); | ||
143 | |||
144 | if (ret < 0) { | ||
145 | ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", | ||
146 | __func__, ret); | ||
147 | } | ||
148 | |||
149 | kfree(buf); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb, | ||
155 | u8 req, u16 value, u16 index, void *data, | ||
156 | u32 size) | ||
157 | { | ||
158 | u8 *buf = NULL; | ||
159 | int ret; | ||
160 | |||
161 | if (size > 0) { | ||
162 | buf = kmalloc(size, GFP_KERNEL); | ||
163 | if (buf == NULL) | ||
164 | return -ENOMEM; | ||
165 | } | ||
166 | |||
167 | /* note: if successful returns number of bytes transfered */ | ||
168 | ret = usb_control_msg(ar_usb->udev, | ||
169 | usb_rcvctrlpipe(ar_usb->udev, 0), | ||
170 | req, | ||
171 | USB_DIR_IN | USB_TYPE_VENDOR | | ||
172 | USB_RECIP_DEVICE, value, index, buf, | ||
173 | size, 2 * HZ); | ||
174 | |||
175 | if (ret < 0) { | ||
176 | ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", | ||
177 | __func__, ret); | ||
178 | } | ||
179 | |||
180 | memcpy((u8 *) data, buf, size); | ||
181 | |||
182 | kfree(buf); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb, | ||
188 | u8 req_val, u8 *req_buf, u32 req_len, | ||
189 | u8 resp_val, u8 *resp_buf, u32 *resp_len) | ||
190 | { | ||
191 | int ret; | ||
192 | |||
193 | /* send command */ | ||
194 | ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0, | ||
195 | req_buf, req_len); | ||
196 | |||
197 | if (ret != 0) | ||
198 | return ret; | ||
199 | |||
200 | if (resp_buf == NULL) { | ||
201 | /* no expected response */ | ||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | /* get response */ | ||
206 | ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0, | ||
207 | resp_buf, *resp_len); | ||
208 | |||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data) | ||
213 | { | ||
214 | struct ath6kl_usb *ar_usb = ar->hif_priv; | ||
215 | struct ath6kl_usb_ctrl_diag_resp_read *resp; | ||
216 | struct ath6kl_usb_ctrl_diag_cmd_read *cmd; | ||
217 | u32 resp_len; | ||
218 | int ret; | ||
219 | |||
220 | cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer; | ||
221 | |||
222 | memset(cmd, 0, sizeof(*cmd)); | ||
223 | cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ; | ||
224 | cmd->address = cpu_to_le32(address); | ||
225 | resp_len = sizeof(*resp); | ||
226 | |||
227 | ret = ath6kl_usb_ctrl_msg_exchange(ar_usb, | ||
228 | ATH6KL_USB_CONTROL_REQ_DIAG_CMD, | ||
229 | (u8 *) cmd, | ||
230 | sizeof(struct ath6kl_usb_ctrl_diag_cmd_write), | ||
231 | ATH6KL_USB_CONTROL_REQ_DIAG_RESP, | ||
232 | ar_usb->diag_resp_buffer, &resp_len); | ||
233 | |||
234 | if (ret) | ||
235 | return ret; | ||
236 | |||
237 | resp = (struct ath6kl_usb_ctrl_diag_resp_read *) | ||
238 | ar_usb->diag_resp_buffer; | ||
239 | |||
240 | *data = le32_to_cpu(resp->value); | ||
241 | |||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data) | ||
246 | { | ||
247 | struct ath6kl_usb *ar_usb = ar->hif_priv; | ||
248 | struct ath6kl_usb_ctrl_diag_cmd_write *cmd; | ||
249 | |||
250 | cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer; | ||
251 | |||
252 | memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)); | ||
253 | cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE); | ||
254 | cmd->address = cpu_to_le32(address); | ||
255 | cmd->value = data; | ||
256 | |||
257 | return ath6kl_usb_ctrl_msg_exchange(ar_usb, | ||
258 | ATH6KL_USB_CONTROL_REQ_DIAG_CMD, | ||
259 | (u8 *) cmd, | ||
260 | sizeof(*cmd), | ||
261 | 0, NULL, NULL); | ||
262 | |||
263 | } | ||
264 | |||
265 | static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) | ||
266 | { | ||
267 | struct ath6kl_usb *ar_usb = ar->hif_priv; | ||
268 | int ret; | ||
269 | |||
270 | /* get response */ | ||
271 | ret = ath6kl_usb_submit_ctrl_in(ar_usb, | ||
272 | ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP, | ||
273 | 0, 0, buf, len); | ||
274 | if (ret != 0) { | ||
275 | ath6kl_err("Unable to read the bmi data from the device: %d\n", | ||
276 | ret); | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) | ||
284 | { | ||
285 | struct ath6kl_usb *ar_usb = ar->hif_priv; | ||
286 | int ret; | ||
287 | |||
288 | /* send command */ | ||
289 | ret = ath6kl_usb_submit_ctrl_out(ar_usb, | ||
290 | ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD, | ||
291 | 0, 0, buf, len); | ||
292 | if (ret != 0) { | ||
293 | ath6kl_err("unable to send the bmi data to the device: %d\n", | ||
294 | ret); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int ath6kl_usb_power_on(struct ath6kl *ar) | ||
302 | { | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static int ath6kl_usb_power_off(struct ath6kl *ar) | ||
307 | { | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static const struct ath6kl_hif_ops ath6kl_usb_ops = { | ||
312 | .diag_read32 = ath6kl_usb_diag_read32, | ||
313 | .diag_write32 = ath6kl_usb_diag_write32, | ||
314 | .bmi_read = ath6kl_usb_bmi_read, | ||
315 | .bmi_write = ath6kl_usb_bmi_write, | ||
316 | .power_on = ath6kl_usb_power_on, | ||
317 | .power_off = ath6kl_usb_power_off, | ||
318 | }; | ||
319 | |||
320 | /* ath6kl usb driver registered functions */ | ||
321 | static int ath6kl_usb_probe(struct usb_interface *interface, | ||
322 | const struct usb_device_id *id) | ||
323 | { | ||
324 | struct usb_device *dev = interface_to_usbdev(interface); | ||
325 | struct ath6kl *ar; | ||
326 | struct ath6kl_usb *ar_usb = NULL; | ||
327 | int vendor_id, product_id; | ||
328 | int ret = 0; | ||
329 | |||
330 | usb_get_dev(dev); | ||
331 | |||
332 | vendor_id = le16_to_cpu(dev->descriptor.idVendor); | ||
333 | product_id = le16_to_cpu(dev->descriptor.idProduct); | ||
334 | |||
335 | ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id); | ||
336 | ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id); | ||
337 | |||
338 | if (interface->cur_altsetting) | ||
339 | ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n", | ||
340 | interface->cur_altsetting->desc.bInterfaceNumber); | ||
341 | |||
342 | |||
343 | if (dev->speed == USB_SPEED_HIGH) | ||
344 | ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n"); | ||
345 | else | ||
346 | ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n"); | ||
347 | |||
348 | ar_usb = ath6kl_usb_create(interface); | ||
349 | |||
350 | if (ar_usb == NULL) { | ||
351 | ret = -ENOMEM; | ||
352 | goto err_usb_put; | ||
353 | } | ||
354 | |||
355 | ar = ath6kl_core_alloc(&ar_usb->udev->dev); | ||
356 | if (ar == NULL) { | ||
357 | ath6kl_err("Failed to alloc ath6kl core\n"); | ||
358 | ret = -ENOMEM; | ||
359 | goto err_usb_destroy; | ||
360 | } | ||
361 | |||
362 | ar->hif_priv = ar_usb; | ||
363 | ar->hif_type = ATH6KL_HIF_TYPE_USB; | ||
364 | ar->hif_ops = &ath6kl_usb_ops; | ||
365 | ar->mbox_info.block_size = 16; | ||
366 | ar->bmi.max_data_size = 252; | ||
367 | |||
368 | ar_usb->ar = ar; | ||
369 | |||
370 | ret = ath6kl_core_init(ar); | ||
371 | if (ret) { | ||
372 | ath6kl_err("Failed to init ath6kl core: %d\n", ret); | ||
373 | goto err_core_free; | ||
374 | } | ||
375 | |||
376 | return ret; | ||
377 | |||
378 | err_core_free: | ||
379 | ath6kl_core_free(ar); | ||
380 | err_usb_destroy: | ||
381 | ath6kl_usb_destroy(ar_usb); | ||
382 | err_usb_put: | ||
383 | usb_put_dev(dev); | ||
384 | |||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | static void ath6kl_usb_remove(struct usb_interface *interface) | ||
389 | { | ||
390 | usb_put_dev(interface_to_usbdev(interface)); | ||
391 | ath6kl_usb_device_detached(interface); | ||
392 | } | ||
393 | |||
394 | /* table of devices that work with this driver */ | ||
395 | static struct usb_device_id ath6kl_usb_ids[] = { | ||
396 | {USB_DEVICE(0x0cf3, 0x9374)}, | ||
397 | { /* Terminating entry */ }, | ||
398 | }; | ||
399 | |||
400 | MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids); | ||
401 | |||
402 | static struct usb_driver ath6kl_usb_driver = { | ||
403 | .name = "ath6kl_usb", | ||
404 | .probe = ath6kl_usb_probe, | ||
405 | .disconnect = ath6kl_usb_remove, | ||
406 | .id_table = ath6kl_usb_ids, | ||
407 | }; | ||
408 | |||
409 | static int ath6kl_usb_init(void) | ||
410 | { | ||
411 | usb_register(&ath6kl_usb_driver); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static void ath6kl_usb_exit(void) | ||
416 | { | ||
417 | usb_deregister(&ath6kl_usb_driver); | ||
418 | } | ||
419 | |||
420 | module_init(ath6kl_usb_init); | ||
421 | module_exit(ath6kl_usb_exit); | ||
422 | |||
423 | MODULE_AUTHOR("Atheros Communications, Inc."); | ||
424 | MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); | ||
425 | MODULE_LICENSE("Dual BSD/GPL"); | ||
426 | MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); | ||
427 | MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); | ||
428 | MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); | ||
429 | MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); | ||
430 | MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); | ||
431 | MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); | ||