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#include "i2400m-usb.h"
67#include <linux/wimax/i2400m.h>
68#include <linux/debugfs.h>
69
70
71#define D_SUBMODULE usb
72#include "usb-debug-levels.h"
73
74
75
76static const char *i2400mu_bus_fw_names[] = {
77#define I2400MU_FW_FILE_NAME_v1_4 "i2400m-fw-usb-1.4.sbcf"
78 I2400MU_FW_FILE_NAME_v1_4,
79#define I2400MU_FW_FILE_NAME_v1_3 "i2400m-fw-usb-1.3.sbcf"
80 I2400MU_FW_FILE_NAME_v1_3,
81 NULL,
82};
83
84
85static
86int i2400mu_bus_dev_start(struct i2400m *i2400m)
87{
88 int result;
89 struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m);
90 struct device *dev = &i2400mu->usb_iface->dev;
91
92 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
93 result = i2400mu_tx_setup(i2400mu);
94 if (result < 0)
95 goto error_usb_tx_setup;
96 result = i2400mu_rx_setup(i2400mu);
97 if (result < 0)
98 goto error_usb_rx_setup;
99 result = i2400mu_notification_setup(i2400mu);
100 if (result < 0)
101 goto error_notif_setup;
102 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
103 return result;
104
105error_notif_setup:
106 i2400mu_rx_release(i2400mu);
107error_usb_rx_setup:
108 i2400mu_tx_release(i2400mu);
109error_usb_tx_setup:
110 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
111 return result;
112}
113
114
115static
116void i2400mu_bus_dev_stop(struct i2400m *i2400m)
117{
118 struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m);
119 struct device *dev = &i2400mu->usb_iface->dev;
120
121 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
122 i2400mu_notification_release(i2400mu);
123 i2400mu_rx_release(i2400mu);
124 i2400mu_tx_release(i2400mu);
125 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
126}
127
128
129
130
131
132
133
134
135
136
137
138
139static
140int __i2400mu_send_barker(struct i2400mu *i2400mu,
141 const __le32 *barker,
142 size_t barker_size,
143 unsigned endpoint)
144{
145 struct usb_endpoint_descriptor *epd = NULL;
146 int pipe, actual_len, ret;
147 struct device *dev = &i2400mu->usb_iface->dev;
148 void *buffer;
149 int do_autopm = 1;
150
151 ret = usb_autopm_get_interface(i2400mu->usb_iface);
152 if (ret < 0) {
153 dev_err(dev, "RESET: can't get autopm: %d\n", ret);
154 do_autopm = 0;
155 }
156 ret = -ENOMEM;
157 buffer = kmalloc(barker_size, GFP_KERNEL);
158 if (buffer == NULL)
159 goto error_kzalloc;
160 epd = usb_get_epd(i2400mu->usb_iface, endpoint);
161 pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
162 memcpy(buffer, barker, barker_size);
163 ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size,
164 &actual_len, HZ);
165 if (ret < 0) {
166 if (ret != -EINVAL)
167 dev_err(dev, "E: barker error: %d\n", ret);
168 } else if (actual_len != barker_size) {
169 dev_err(dev, "E: only %d bytes transmitted\n", actual_len);
170 ret = -EIO;
171 }
172 kfree(buffer);
173error_kzalloc:
174 if (do_autopm)
175 usb_autopm_put_interface(i2400mu->usb_iface);
176 return ret;
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
213static
214int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
215{
216 int result;
217 struct i2400mu *i2400mu =
218 container_of(i2400m, struct i2400mu, i2400m);
219 struct device *dev = i2400m_dev(i2400m);
220 static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
221 cpu_to_le32(I2400M_WARM_RESET_BARKER),
222 cpu_to_le32(I2400M_WARM_RESET_BARKER),
223 cpu_to_le32(I2400M_WARM_RESET_BARKER),
224 cpu_to_le32(I2400M_WARM_RESET_BARKER),
225 };
226 static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
227 cpu_to_le32(I2400M_COLD_RESET_BARKER),
228 cpu_to_le32(I2400M_COLD_RESET_BARKER),
229 cpu_to_le32(I2400M_COLD_RESET_BARKER),
230 cpu_to_le32(I2400M_COLD_RESET_BARKER),
231 };
232
233 d_fnstart(3, dev, "(i2400m %p rt %u)\n", i2400m, rt);
234 if (rt == I2400M_RT_WARM)
235 result = __i2400mu_send_barker(i2400mu, i2400m_WARM_BOOT_BARKER,
236 sizeof(i2400m_WARM_BOOT_BARKER),
237 I2400MU_EP_BULK_OUT);
238 else if (rt == I2400M_RT_COLD)
239 result = __i2400mu_send_barker(i2400mu, i2400m_COLD_BOOT_BARKER,
240 sizeof(i2400m_COLD_BOOT_BARKER),
241 I2400MU_EP_RESET_COLD);
242 else if (rt == I2400M_RT_BUS) {
243do_bus_reset:
244 result = usb_reset_device(i2400mu->usb_dev);
245 switch (result) {
246 case 0:
247 case -EINVAL:
248 case -ENODEV:
249 case -ENOENT:
250 case -ESHUTDOWN:
251 result = rt == I2400M_RT_WARM ? -ENODEV : 0;
252 break;
253 default:
254 dev_err(dev, "USB reset failed (%d), giving up!\n",
255 result);
256 }
257 } else {
258 result = -EINVAL;
259 BUG();
260 }
261 if (result < 0
262 && result != -EINVAL
263 && rt != I2400M_RT_BUS) {
264 dev_err(dev, "%s reset failed (%d); trying USB reset\n",
265 rt == I2400M_RT_WARM ? "warm" : "cold", result);
266 rt = I2400M_RT_BUS;
267 goto do_bus_reset;
268 }
269 d_fnend(3, dev, "(i2400m %p rt %u) = %d\n", i2400m, rt, result);
270 return result;
271}
272
273
274static
275void i2400mu_netdev_setup(struct net_device *net_dev)
276{
277 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
278 struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m);
279 i2400mu_init(i2400mu);
280 i2400m_netdev_setup(net_dev);
281}
282
283
284
285
286
287struct d_level D_LEVEL[] = {
288 D_SUBMODULE_DEFINE(usb),
289 D_SUBMODULE_DEFINE(fw),
290 D_SUBMODULE_DEFINE(notif),
291 D_SUBMODULE_DEFINE(rx),
292 D_SUBMODULE_DEFINE(tx),
293};
294size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
295
296
297#define __debugfs_register(prefix, name, parent) \
298do { \
299 result = d_level_register_debugfs(prefix, name, parent); \
300 if (result < 0) \
301 goto error; \
302} while (0)
303
304
305static
306int i2400mu_debugfs_add(struct i2400mu *i2400mu)
307{
308 int result;
309 struct device *dev = &i2400mu->usb_iface->dev;
310 struct dentry *dentry = i2400mu->i2400m.wimax_dev.debugfs_dentry;
311 struct dentry *fd;
312
313 dentry = debugfs_create_dir("i2400m-usb", dentry);
314 result = PTR_ERR(dentry);
315 if (IS_ERR(dentry)) {
316 if (result == -ENODEV)
317 result = 0;
318 goto error;
319 }
320 i2400mu->debugfs_dentry = dentry;
321 __debugfs_register("dl_", usb, dentry);
322 __debugfs_register("dl_", fw, dentry);
323 __debugfs_register("dl_", notif, dentry);
324 __debugfs_register("dl_", rx, dentry);
325 __debugfs_register("dl_", tx, dentry);
326
327
328 fd = debugfs_create_u8("rx_size_auto_shrink", 0600, dentry,
329 &i2400mu->rx_size_auto_shrink);
330 result = PTR_ERR(fd);
331 if (IS_ERR(fd) && result != -ENODEV) {
332 dev_err(dev, "Can't create debugfs entry "
333 "rx_size_auto_shrink: %d\n", result);
334 goto error;
335 }
336
337 fd = debugfs_create_size_t("rx_size", 0600, dentry,
338 &i2400mu->rx_size);
339 result = PTR_ERR(fd);
340 if (IS_ERR(fd) && result != -ENODEV) {
341 dev_err(dev, "Can't create debugfs entry "
342 "rx_size: %d\n", result);
343 goto error;
344 }
345
346 return 0;
347
348error:
349 debugfs_remove_recursive(i2400mu->debugfs_dentry);
350 return result;
351}
352
353
354static struct device_type i2400mu_type = {
355 .name = "wimax",
356};
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372static
373int i2400mu_probe(struct usb_interface *iface,
374 const struct usb_device_id *id)
375{
376 int result;
377 struct net_device *net_dev;
378 struct device *dev = &iface->dev;
379 struct i2400m *i2400m;
380 struct i2400mu *i2400mu;
381 struct usb_device *usb_dev = interface_to_usbdev(iface);
382
383 if (usb_dev->speed != USB_SPEED_HIGH)
384 dev_err(dev, "device not connected as high speed\n");
385
386
387 result = -ENOMEM;
388 net_dev = alloc_netdev(sizeof(*i2400mu), "wmx%d",
389 i2400mu_netdev_setup);
390 if (net_dev == NULL) {
391 dev_err(dev, "no memory for network device instance\n");
392 goto error_alloc_netdev;
393 }
394 SET_NETDEV_DEV(net_dev, dev);
395 SET_NETDEV_DEVTYPE(net_dev, &i2400mu_type);
396 i2400m = net_dev_to_i2400m(net_dev);
397 i2400mu = container_of(i2400m, struct i2400mu, i2400m);
398 i2400m->wimax_dev.net_dev = net_dev;
399 i2400mu->usb_dev = usb_get_dev(usb_dev);
400 i2400mu->usb_iface = iface;
401 usb_set_intfdata(iface, i2400mu);
402
403 i2400m->bus_tx_block_size = I2400MU_BLK_SIZE;
404 i2400m->bus_pl_size_max = I2400MU_PL_SIZE_MAX;
405 i2400m->bus_dev_start = i2400mu_bus_dev_start;
406 i2400m->bus_dev_stop = i2400mu_bus_dev_stop;
407 i2400m->bus_tx_kick = i2400mu_bus_tx_kick;
408 i2400m->bus_reset = i2400mu_bus_reset;
409 i2400m->bus_bm_retries = I2400M_BOOT_RETRIES;
410 i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send;
411 i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack;
412 i2400m->bus_fw_names = i2400mu_bus_fw_names;
413 i2400m->bus_bm_mac_addr_impaired = 0;
414
415#ifdef CONFIG_PM
416 iface->needs_remote_wakeup = 1;
417 device_init_wakeup(dev, 1);
418 usb_autopm_enable(i2400mu->usb_iface);
419 usb_dev->autosuspend_delay = 15 * HZ;
420 usb_dev->autosuspend_disabled = 0;
421#endif
422
423 result = i2400m_setup(i2400m, I2400M_BRI_MAC_REINIT);
424 if (result < 0) {
425 dev_err(dev, "cannot setup device: %d\n", result);
426 goto error_setup;
427 }
428 result = i2400mu_debugfs_add(i2400mu);
429 if (result < 0) {
430 dev_err(dev, "Can't register i2400mu's debugfs: %d\n", result);
431 goto error_debugfs_add;
432 }
433 return 0;
434
435error_debugfs_add:
436 i2400m_release(i2400m);
437error_setup:
438 usb_set_intfdata(iface, NULL);
439 usb_put_dev(i2400mu->usb_dev);
440 free_netdev(net_dev);
441error_alloc_netdev:
442 return result;
443}
444
445
446
447
448
449
450
451
452
453static
454void i2400mu_disconnect(struct usb_interface *iface)
455{
456 struct i2400mu *i2400mu = usb_get_intfdata(iface);
457 struct i2400m *i2400m = &i2400mu->i2400m;
458 struct net_device *net_dev = i2400m->wimax_dev.net_dev;
459 struct device *dev = &iface->dev;
460
461 d_fnstart(3, dev, "(iface %p i2400m %p)\n", iface, i2400m);
462
463 debugfs_remove_recursive(i2400mu->debugfs_dentry);
464 i2400m_release(i2400m);
465 usb_set_intfdata(iface, NULL);
466 usb_put_dev(i2400mu->usb_dev);
467 free_netdev(net_dev);
468 d_fnend(3, dev, "(iface %p i2400m %p) = void\n", iface, i2400m);
469}
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507static
508int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg)
509{
510 int result = 0;
511 struct device *dev = &iface->dev;
512 struct i2400mu *i2400mu = usb_get_intfdata(iface);
513#ifdef CONFIG_PM
514 struct usb_device *usb_dev = i2400mu->usb_dev;
515#endif
516 unsigned is_autosuspend = 0;
517 struct i2400m *i2400m = &i2400mu->i2400m;
518
519#ifdef CONFIG_PM
520 if (usb_dev->auto_pm > 0)
521 is_autosuspend = 1;
522#endif
523
524 d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event);
525 if (i2400m->updown == 0)
526 goto no_firmware;
527 if (i2400m->state == I2400M_SS_DATA_PATH_CONNECTED && is_autosuspend) {
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542 result = -EBADF;
543 d_printf(1, dev, "fw up, link up, not-idle, autosuspend: "
544 "not entering powersave\n");
545 goto error_not_now;
546 }
547 d_printf(1, dev, "fw up: entering powersave\n");
548 atomic_dec(&i2400mu->do_autopm);
549 result = i2400m_cmd_enter_powersave(i2400m);
550 atomic_inc(&i2400mu->do_autopm);
551 if (result < 0 && !is_autosuspend) {
552
553 dev_err(dev, "failed to suspend, will reset on resume\n");
554 result = 0;
555 }
556 if (result < 0)
557 goto error_enter_powersave;
558 i2400mu_notification_release(i2400mu);
559 d_printf(1, dev, "powersave requested\n");
560error_enter_powersave:
561error_not_now:
562no_firmware:
563 d_fnend(3, dev, "(iface %p pm_msg %u) = %d\n",
564 iface, pm_msg.event, result);
565 return result;
566}
567
568
569static
570int i2400mu_resume(struct usb_interface *iface)
571{
572 int ret = 0;
573 struct device *dev = &iface->dev;
574 struct i2400mu *i2400mu = usb_get_intfdata(iface);
575 struct i2400m *i2400m = &i2400mu->i2400m;
576
577 d_fnstart(3, dev, "(iface %p)\n", iface);
578 if (i2400m->updown == 0) {
579 d_printf(1, dev, "fw was down, no resume neeed\n");
580 goto out;
581 }
582 d_printf(1, dev, "fw was up, resuming\n");
583 i2400mu_notification_setup(i2400mu);
584
585
586
587out:
588 d_fnend(3, dev, "(iface %p) = %d\n", iface, ret);
589 return ret;
590}
591
592
593static
594struct usb_device_id i2400mu_id_table[] = {
595 { USB_DEVICE(0x8086, 0x0181) },
596 { USB_DEVICE(0x8086, 0x1403) },
597 { USB_DEVICE(0x8086, 0x1405) },
598 { USB_DEVICE(0x8086, 0x0180) },
599 { USB_DEVICE(0x8086, 0x0182) },
600 { USB_DEVICE(0x8086, 0x1406) },
601 { USB_DEVICE(0x8086, 0x1403) },
602 { },
603};
604MODULE_DEVICE_TABLE(usb, i2400mu_id_table);
605
606
607static
608struct usb_driver i2400mu_driver = {
609 .name = KBUILD_MODNAME,
610 .suspend = i2400mu_suspend,
611 .resume = i2400mu_resume,
612 .probe = i2400mu_probe,
613 .disconnect = i2400mu_disconnect,
614 .id_table = i2400mu_id_table,
615 .supports_autosuspend = 1,
616};
617
618static
619int __init i2400mu_driver_init(void)
620{
621 return usb_register(&i2400mu_driver);
622}
623module_init(i2400mu_driver_init);
624
625
626static
627void __exit i2400mu_driver_exit(void)
628{
629 flush_scheduled_work();
630 usb_deregister(&i2400mu_driver);
631}
632module_exit(i2400mu_driver_exit);
633
634MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
635MODULE_DESCRIPTION("Intel 2400M WiMAX networking for USB");
636MODULE_LICENSE("GPL");
637MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_4);
638MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_3);
639