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#include <linux/debugfs.h>
61#include <linux/mmc/sdio_ids.h>
62#include <linux/mmc/sdio.h>
63#include <linux/mmc/sdio_func.h>
64#include "i2400m-sdio.h"
65#include <linux/wimax/i2400m.h>
66
67#define D_SUBMODULE main
68#include "sdio-debug-levels.h"
69
70
71static int ioe_timeout = 2;
72module_param(ioe_timeout, int, 0);
73
74
75static const char *i2400ms_bus_fw_names[] = {
76#define I2400MS_FW_FILE_NAME "i2400m-fw-sdio-1.3.sbcf"
77 I2400MS_FW_FILE_NAME,
78 NULL
79};
80
81
82static const struct i2400m_poke_table i2400ms_pokes[] = {
83 I2400M_FW_POKE(0x6BE260, 0x00000088),
84 I2400M_FW_POKE(0x080550, 0x00000005),
85 I2400M_FW_POKE(0xAE0000, 0x00000000),
86 I2400M_FW_POKE(0x000000, 0x00000000),
87
88};
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103static
104int i2400ms_enable_function(struct sdio_func *func)
105{
106 u64 timeout;
107 int err;
108 struct device *dev = &func->dev;
109
110 d_fnstart(3, dev, "(func %p)\n", func);
111
112
113
114 timeout = get_jiffies_64() + ioe_timeout * HZ;
115 err = -ENODEV;
116 while (err != 0 && time_before64(get_jiffies_64(), timeout)) {
117 sdio_claim_host(func);
118 err = sdio_enable_func(func);
119 if (0 == err) {
120 sdio_release_host(func);
121 d_printf(2, dev, "SDIO function enabled\n");
122 goto function_enabled;
123 }
124 d_printf(2, dev, "SDIO function failed to enable: %d\n", err);
125 sdio_disable_func(func);
126 sdio_release_host(func);
127 msleep(I2400MS_INIT_SLEEP_INTERVAL);
128 }
129
130
131 if (err == -ETIME) {
132 dev_err(dev, "Can't enable WiMAX function; "
133 " has the function been enabled?\n");
134 err = -ENODEV;
135 }
136function_enabled:
137 d_fnend(3, dev, "(func %p) = %d\n", func, err);
138 return err;
139}
140
141
142
143
144
145
146
147
148
149
150static
151int i2400ms_bus_dev_start(struct i2400m *i2400m)
152{
153 int result;
154 struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
155 struct sdio_func *func = i2400ms->func;
156 struct device *dev = &func->dev;
157
158 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
159 msleep(200);
160 result = i2400ms_tx_setup(i2400ms);
161 if (result < 0)
162 goto error_tx_setup;
163 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
164 return result;
165
166error_tx_setup:
167 i2400ms_tx_release(i2400ms);
168 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
169 return result;
170}
171
172
173static
174void i2400ms_bus_dev_stop(struct i2400m *i2400m)
175{
176 struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
177 struct sdio_func *func = i2400ms->func;
178 struct device *dev = &func->dev;
179
180 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
181 i2400ms_tx_release(i2400ms);
182 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
183}
184
185
186
187
188
189
190
191
192
193
194
195static
196int __i2400ms_send_barker(struct i2400ms *i2400ms,
197 const __le32 *barker, size_t barker_size)
198{
199 int ret;
200 struct sdio_func *func = i2400ms->func;
201 struct device *dev = &func->dev;
202 void *buffer;
203
204 ret = -ENOMEM;
205 buffer = kmalloc(I2400MS_BLK_SIZE, GFP_KERNEL);
206 if (buffer == NULL)
207 goto error_kzalloc;
208
209 memcpy(buffer, barker, barker_size);
210 sdio_claim_host(func);
211 ret = sdio_memcpy_toio(func, 0, buffer, I2400MS_BLK_SIZE);
212 sdio_release_host(func);
213
214 if (ret < 0)
215 d_printf(0, dev, "E: barker error: %d\n", ret);
216
217 kfree(buffer);
218error_kzalloc:
219 return ret;
220}
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258static
259int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
260{
261 int result = 0;
262 struct i2400ms *i2400ms =
263 container_of(i2400m, struct i2400ms, i2400m);
264 struct device *dev = i2400m_dev(i2400m);
265 static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
266 cpu_to_le32(I2400M_WARM_RESET_BARKER),
267 cpu_to_le32(I2400M_WARM_RESET_BARKER),
268 cpu_to_le32(I2400M_WARM_RESET_BARKER),
269 cpu_to_le32(I2400M_WARM_RESET_BARKER),
270 };
271 static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
272 cpu_to_le32(I2400M_COLD_RESET_BARKER),
273 cpu_to_le32(I2400M_COLD_RESET_BARKER),
274 cpu_to_le32(I2400M_COLD_RESET_BARKER),
275 cpu_to_le32(I2400M_COLD_RESET_BARKER),
276 };
277
278 if (rt == I2400M_RT_WARM)
279 result = __i2400ms_send_barker(i2400ms, i2400m_WARM_BOOT_BARKER,
280 sizeof(i2400m_WARM_BOOT_BARKER));
281 else if (rt == I2400M_RT_COLD)
282 result = __i2400ms_send_barker(i2400ms, i2400m_COLD_BOOT_BARKER,
283 sizeof(i2400m_COLD_BOOT_BARKER));
284 else if (rt == I2400M_RT_BUS) {
285do_bus_reset:
286
287
288
289
290
291 if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
292 netif_tx_disable(i2400m->wimax_dev.net_dev);
293
294 i2400ms_rx_release(i2400ms);
295 sdio_claim_host(i2400ms->func);
296 sdio_disable_func(i2400ms->func);
297 sdio_release_host(i2400ms->func);
298
299
300 msleep(40);
301
302 result = i2400ms_enable_function(i2400ms->func);
303 if (result >= 0)
304 i2400ms_rx_setup(i2400ms);
305 } else
306 BUG();
307 if (result < 0 && rt != I2400M_RT_BUS) {
308 dev_err(dev, "%s reset failed (%d); trying SDIO reset\n",
309 rt == I2400M_RT_WARM ? "warm" : "cold", result);
310 rt = I2400M_RT_BUS;
311 goto do_bus_reset;
312 }
313 return result;
314}
315
316
317static
318void i2400ms_netdev_setup(struct net_device *net_dev)
319{
320 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
321 struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
322 i2400ms_init(i2400ms);
323 i2400m_netdev_setup(net_dev);
324}
325
326
327
328
329
330struct d_level D_LEVEL[] = {
331 D_SUBMODULE_DEFINE(main),
332 D_SUBMODULE_DEFINE(tx),
333 D_SUBMODULE_DEFINE(rx),
334 D_SUBMODULE_DEFINE(fw),
335};
336size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
337
338
339#define __debugfs_register(prefix, name, parent) \
340do { \
341 result = d_level_register_debugfs(prefix, name, parent); \
342 if (result < 0) \
343 goto error; \
344} while (0)
345
346
347static
348int i2400ms_debugfs_add(struct i2400ms *i2400ms)
349{
350 int result;
351 struct dentry *dentry = i2400ms->i2400m.wimax_dev.debugfs_dentry;
352
353 dentry = debugfs_create_dir("i2400m-usb", dentry);
354 result = PTR_ERR(dentry);
355 if (IS_ERR(dentry)) {
356 if (result == -ENODEV)
357 result = 0;
358 goto error;
359 }
360 i2400ms->debugfs_dentry = dentry;
361 __debugfs_register("dl_", main, dentry);
362 __debugfs_register("dl_", tx, dentry);
363 __debugfs_register("dl_", rx, dentry);
364 __debugfs_register("dl_", fw, dentry);
365
366 return 0;
367
368error:
369 debugfs_remove_recursive(i2400ms->debugfs_dentry);
370 return result;
371}
372
373
374static struct device_type i2400ms_type = {
375 .name = "wimax",
376};
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400static
401int i2400ms_probe(struct sdio_func *func,
402 const struct sdio_device_id *id)
403{
404 int result;
405 struct net_device *net_dev;
406 struct device *dev = &func->dev;
407 struct i2400m *i2400m;
408 struct i2400ms *i2400ms;
409
410
411 result = -ENOMEM;
412 net_dev = alloc_netdev(sizeof(*i2400ms), "wmx%d",
413 i2400ms_netdev_setup);
414 if (net_dev == NULL) {
415 dev_err(dev, "no memory for network device instance\n");
416 goto error_alloc_netdev;
417 }
418 SET_NETDEV_DEV(net_dev, dev);
419 SET_NETDEV_DEVTYPE(net_dev, &i2400ms_type);
420 i2400m = net_dev_to_i2400m(net_dev);
421 i2400ms = container_of(i2400m, struct i2400ms, i2400m);
422 i2400m->wimax_dev.net_dev = net_dev;
423 i2400ms->func = func;
424 sdio_set_drvdata(func, i2400ms);
425
426 i2400m->bus_tx_block_size = I2400MS_BLK_SIZE;
427 i2400m->bus_pl_size_max = I2400MS_PL_SIZE_MAX;
428 i2400m->bus_dev_start = i2400ms_bus_dev_start;
429 i2400m->bus_dev_stop = i2400ms_bus_dev_stop;
430 i2400m->bus_tx_kick = i2400ms_bus_tx_kick;
431 i2400m->bus_reset = i2400ms_bus_reset;
432
433
434 i2400m->bus_bm_retries = I3200_BOOT_RETRIES;
435 i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
436 i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
437 i2400m->bus_fw_names = i2400ms_bus_fw_names;
438 i2400m->bus_bm_mac_addr_impaired = 1;
439 i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
440
441 sdio_claim_host(func);
442 result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
443 sdio_release_host(func);
444 if (result < 0) {
445 dev_err(dev, "Failed to set block size: %d\n", result);
446 goto error_set_blk_size;
447 }
448
449 result = i2400ms_enable_function(i2400ms->func);
450 if (result < 0) {
451 dev_err(dev, "Cannot enable SDIO function: %d\n", result);
452 goto error_func_enable;
453 }
454
455 result = i2400ms_rx_setup(i2400ms);
456 if (result < 0)
457 goto error_rx_setup;
458
459 result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT);
460 if (result < 0) {
461 dev_err(dev, "cannot setup device: %d\n", result);
462 goto error_setup;
463 }
464
465 result = i2400ms_debugfs_add(i2400ms);
466 if (result < 0) {
467 dev_err(dev, "cannot create SDIO debugfs: %d\n",
468 result);
469 goto error_debugfs_add;
470 }
471 return 0;
472
473error_debugfs_add:
474 i2400m_release(i2400m);
475error_setup:
476 i2400ms_rx_release(i2400ms);
477error_rx_setup:
478 sdio_claim_host(func);
479 sdio_disable_func(func);
480 sdio_release_host(func);
481error_func_enable:
482error_set_blk_size:
483 sdio_set_drvdata(func, NULL);
484 free_netdev(net_dev);
485error_alloc_netdev:
486 return result;
487}
488
489
490static
491void i2400ms_remove(struct sdio_func *func)
492{
493 struct device *dev = &func->dev;
494 struct i2400ms *i2400ms = sdio_get_drvdata(func);
495 struct i2400m *i2400m = &i2400ms->i2400m;
496 struct net_device *net_dev = i2400m->wimax_dev.net_dev;
497
498 d_fnstart(3, dev, "SDIO func %p\n", func);
499 debugfs_remove_recursive(i2400ms->debugfs_dentry);
500 i2400ms_rx_release(i2400ms);
501 i2400m_release(i2400m);
502 sdio_set_drvdata(func, NULL);
503 sdio_claim_host(func);
504 sdio_disable_func(func);
505 sdio_release_host(func);
506 free_netdev(net_dev);
507 d_fnend(3, dev, "SDIO func %p\n", func);
508}
509
510static
511const struct sdio_device_id i2400ms_sdio_ids[] = {
512
513 { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
514 SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX) },
515 { },
516};
517MODULE_DEVICE_TABLE(sdio, i2400ms_sdio_ids);
518
519
520static
521struct sdio_driver i2400m_sdio_driver = {
522 .name = KBUILD_MODNAME,
523 .probe = i2400ms_probe,
524 .remove = i2400ms_remove,
525 .id_table = i2400ms_sdio_ids,
526};
527
528
529static
530int __init i2400ms_driver_init(void)
531{
532 return sdio_register_driver(&i2400m_sdio_driver);
533}
534module_init(i2400ms_driver_init);
535
536
537static
538void __exit i2400ms_driver_exit(void)
539{
540 flush_scheduled_work();
541 sdio_unregister_driver(&i2400m_sdio_driver);
542}
543module_exit(i2400ms_driver_exit);
544
545
546MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
547MODULE_DESCRIPTION("Intel 2400M WiMAX networking for SDIO");
548MODULE_LICENSE("GPL");
549MODULE_FIRMWARE(I2400MS_FW_FILE_NAME);
550