aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig25
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile37
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c10
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c5
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.c10
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c431
8 files changed, 20 insertions, 501 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index d755a5e7ed20..3d5f8be20eac 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -1,29 +1,12 @@
1config ATH6KL 1config ATH6KL
2 tristate "Atheros mobile chipsets support" 2 tristate "Atheros ath6kl support"
3
4config ATH6KL_SDIO
5 tristate "Atheros ath6kl SDIO support"
6 depends on ATH6KL
7 depends on MMC 3 depends on MMC
8 depends on CFG80211 4 depends on CFG80211
9 ---help--- 5 ---help---
10 This module adds support for wireless adapters based on 6 This module adds support for wireless adapters based on
11 Atheros AR6003 and AR6004 chipsets running over SDIO. If you 7 Atheros AR6003 chipset running over SDIO. If you choose to
12 choose to build it as a module, it will be called ath6kl_sdio. 8 build it as a module, it will be called ath6kl. Pls note
13 Please note that AR6002 and AR6001 are not supported by this 9 that AR6002 and AR6001 are not supported by this driver.
14 driver.
15
16config ATH6KL_USB
17 tristate "Atheros ath6kl USB support"
18 depends on ATH6KL
19 depends on USB
20 depends on CFG80211
21 depends on EXPERIMENTAL
22 ---help---
23 This module adds support for wireless adapters based on
24 Atheros AR6004 chipset running over USB. This is still under
25 implementation and it isn't functional. If you choose to
26 build it as a module, it will be called ath6kl_usb.
27 10
28config ATH6KL_DEBUG 11config ATH6KL_DEBUG
29 bool "Atheros ath6kl debugging" 12 bool "Atheros ath6kl debugging"
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index e14cef9c3c0e..707069303550 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -21,30 +21,17 @@
21# Author(s): ="Atheros" 21# Author(s): ="Atheros"
22#------------------------------------------------------------------------------ 22#------------------------------------------------------------------------------
23 23
24obj-$(CONFIG_ATH6KL_SDIO) := ath6kl_sdio.o 24obj-$(CONFIG_ATH6KL) := ath6kl.o
25ath6kl_sdio-y += debug.o 25ath6kl-y += debug.o
26ath6kl_sdio-y += hif.o 26ath6kl-y += hif.o
27ath6kl_sdio-y += htc.o 27ath6kl-y += htc.o
28ath6kl_sdio-y += bmi.o 28ath6kl-y += bmi.o
29ath6kl_sdio-y += cfg80211.o 29ath6kl-y += cfg80211.o
30ath6kl_sdio-y += init.o 30ath6kl-y += init.o
31ath6kl_sdio-y += main.o 31ath6kl-y += main.o
32ath6kl_sdio-y += txrx.o 32ath6kl-y += txrx.o
33ath6kl_sdio-y += wmi.o 33ath6kl-y += wmi.o
34ath6kl_sdio-y += sdio.o 34ath6kl-y += sdio.o
35ath6kl_sdio-$(CONFIG_NL80211_TESTMODE) += testmode.o 35ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
36
37obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
38ath6kl_usb-y += debug.o
39ath6kl_usb-y += hif.o
40ath6kl_usb-y += htc.o
41ath6kl_usb-y += bmi.o
42ath6kl_usb-y += cfg80211.o
43ath6kl_usb-y += init.o
44ath6kl_usb-y += main.o
45ath6kl_usb-y += txrx.o
46ath6kl_usb-y += wmi.o
47ath6kl_usb-y += usb.o
48ath6kl_usb-$(CONFIG_NL80211_TESTMODE) += testmode.o
49 36
50ccflags-y += -D__CHECK_ENDIAN__ 37ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index aef00d5a1438..bce3575c310a 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -57,14 +57,8 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
57 return ret; 57 return ret;
58 } 58 }
59 59
60 if (ar->hif_type == ATH6KL_HIF_TYPE_USB) { 60 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
61 ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info, 61 sizeof(targ_info->version));
62 sizeof(*targ_info));
63 } else {
64 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
65 sizeof(targ_info->version));
66 }
67
68 if (ret) { 62 if (ret) {
69 ath6kl_err("Unable to recv target info: %d\n", ret); 63 ath6kl_err("Unable to recv target info: %d\n", ret);
70 return ret; 64 return ret;
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index e569c652e35c..9853c9c125c1 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -41,7 +41,6 @@ enum ATH6K_DEBUG_MASK {
41 ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ 41 ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */
42 ATH6KL_DBG_WMI_DUMP = BIT(19), 42 ATH6KL_DBG_WMI_DUMP = BIT(19),
43 ATH6KL_DBG_SUSPEND = BIT(20), 43 ATH6KL_DBG_SUSPEND = BIT(20),
44 ATH6KL_DBG_USB = BIT(21),
45 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ 44 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
46}; 45};
47 46
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index 0772ef650174..e57da35e59fa 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -689,11 +689,6 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
689 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", 689 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
690 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); 690 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
691 691
692 /* usb doesn't support enabling interrupts */
693 /* FIXME: remove check once USB support is implemented */
694 if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
695 return 0;
696
697 status = ath6kl_hif_disable_intrs(dev); 692 status = ath6kl_hif_disable_intrs(dev);
698 693
699fail_setup: 694fail_setup:
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index b01702258faf..f3b63ca25c7e 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -2543,12 +2543,6 @@ int ath6kl_htc_wait_target(struct htc_target *target)
2543 struct htc_service_connect_resp resp; 2543 struct htc_service_connect_resp resp;
2544 int status; 2544 int status;
2545 2545
2546 /* FIXME: remove once USB support is implemented */
2547 if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
2548 ath6kl_err("HTC doesn't support USB yet. Patience!\n");
2549 return -EOPNOTSUPP;
2550 }
2551
2552 /* we should be getting 1 control message that the target is ready */ 2546 /* we should be getting 1 control message that the target is ready */
2553 packet = htc_wait_for_ctrl_msg(target); 2547 packet = htc_wait_for_ctrl_msg(target);
2554 2548
@@ -2778,9 +2772,7 @@ void ath6kl_htc_cleanup(struct htc_target *target)
2778{ 2772{
2779 struct htc_packet *packet, *tmp_packet; 2773 struct htc_packet *packet, *tmp_packet;
2780 2774
2781 /* FIXME: remove check once USB support is implemented */ 2775 ath6kl_hif_cleanup_scatter(target->dev->ar);
2782 if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
2783 ath6kl_hif_cleanup_scatter(target->dev->ar);
2784 2776
2785 list_for_each_entry_safe(packet, tmp_packet, 2777 list_for_each_entry_safe(packet, tmp_packet,
2786 &target->free_ctrl_txbuf, list) { 2778 &target->free_ctrl_txbuf, list) {
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 15c3f56caf4f..9475e2d0d0b7 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -1332,7 +1332,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = {
1332MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); 1332MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
1333 1333
1334static struct sdio_driver ath6kl_sdio_driver = { 1334static struct sdio_driver ath6kl_sdio_driver = {
1335 .name = "ath6kl_sdio", 1335 .name = "ath6kl",
1336 .id_table = ath6kl_sdio_devices, 1336 .id_table = ath6kl_sdio_devices,
1337 .probe = ath6kl_sdio_probe, 1337 .probe = ath6kl_sdio_probe,
1338 .remove = ath6kl_sdio_remove, 1338 .remove = ath6kl_sdio_remove,
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
deleted file mode 100644
index e3cf397fcafe..000000000000
--- 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 */
24struct 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
41struct ath6kl_usb_ctrl_diag_cmd_write {
42 __le32 cmd;
43 __le32 address;
44 __le32 value;
45 __le32 _pad[1];
46} __packed;
47
48struct ath6kl_usb_ctrl_diag_cmd_read {
49 __le32 cmd;
50 __le32 address;
51} __packed;
52
53struct 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
60static 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
70static 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
98fail_ath6kl_usb_create:
99 if (status != 0) {
100 ath6kl_usb_destroy(ar_usb);
101 ar_usb = NULL;
102 }
103 return ar_usb;
104}
105
106static 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
121static 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
154static 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
187static 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
212static 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
245static 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
265static 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
283static 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
301static int ath6kl_usb_power_on(struct ath6kl *ar)
302{
303 return 0;
304}
305
306static int ath6kl_usb_power_off(struct ath6kl *ar)
307{
308 return 0;
309}
310
311static 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 */
321static 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
378err_core_free:
379 ath6kl_core_free(ar);
380err_usb_destroy:
381 ath6kl_usb_destroy(ar_usb);
382err_usb_put:
383 usb_put_dev(dev);
384
385 return ret;
386}
387
388static 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 */
395static struct usb_device_id ath6kl_usb_ids[] = {
396 {USB_DEVICE(0x0cf3, 0x9374)},
397 { /* Terminating entry */ },
398};
399
400MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids);
401
402static 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
409static int ath6kl_usb_init(void)
410{
411 usb_register(&ath6kl_usb_driver);
412 return 0;
413}
414
415static void ath6kl_usb_exit(void)
416{
417 usb_deregister(&ath6kl_usb_driver);
418}
419
420module_init(ath6kl_usb_init);
421module_exit(ath6kl_usb_exit);
422
423MODULE_AUTHOR("Atheros Communications, Inc.");
424MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices");
425MODULE_LICENSE("Dual BSD/GPL");
426MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE);
427MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
428MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
429MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
430MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
431MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);