Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[sfrench/cifs-2.6.git] / drivers / uwb / i1480 / i1480u-wlp / lc.c
1 /*
2  * WUSB Wire Adapter: WLP interface
3  * Driver for the Linux Network stack.
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: docs
24  *
25  * This implements a very simple network driver for the WLP USB
26  * device that is associated to a UWB (Ultra Wide Band) host.
27  *
28  * This is seen as an interface of a composite device. Once the UWB
29  * host has an association to another WLP capable device, the
30  * networking interface (aka WLP) can start to send packets back and
31  * forth.
32  *
33  * Limitations:
34  *
35  *  - Hand cranked; can't ifup the interface until there is an association
36  *
37  *  - BW allocation very simplistic [see i1480u_mas_set() and callees].
38  *
39  *
40  * ROADMAP:
41  *
42  *   ENTRY POINTS (driver model):
43  *
44  *     i1480u_driver_{exit,init}(): initialization of the driver.
45  *
46  *     i1480u_probe(): called by the driver code when a device
47  *                     matching 'i1480u_id_table' is connected.
48  *
49  *                     This allocs a netdev instance, inits with
50  *                     i1480u_add(), then registers_netdev().
51  *         i1480u_init()
52  *         i1480u_add()
53  *
54  *     i1480u_disconnect(): device has been disconnected/module
55  *                          is being removed.
56  *         i1480u_rm()
57  */
58 #include <linux/gfp.h>
59 #include <linux/if_arp.h>
60 #include <linux/etherdevice.h>
61
62 #include "i1480u-wlp.h"
63
64
65
66 static inline
67 void i1480u_init(struct i1480u *i1480u)
68 {
69         /* nothing so far... doesn't it suck? */
70         spin_lock_init(&i1480u->lock);
71         INIT_LIST_HEAD(&i1480u->tx_list);
72         spin_lock_init(&i1480u->tx_list_lock);
73         wlp_options_init(&i1480u->options);
74         edc_init(&i1480u->tx_errors);
75         edc_init(&i1480u->rx_errors);
76 #ifdef i1480u_FLOW_CONTROL
77         edc_init(&i1480u->notif_edc);
78 #endif
79         stats_init(&i1480u->lqe_stats);
80         stats_init(&i1480u->rssi_stats);
81         wlp_init(&i1480u->wlp);
82 }
83
84 /**
85  * Fill WLP device information structure
86  *
87  * The structure will contain a few character arrays, each ending with a
88  * null terminated string. Each string has to fit (excluding terminating
89  * character) into a specified range obtained from the WLP substack.
90  *
91  * It is still not clear exactly how this device information should be
92  * obtained. Until we find out we use the USB device descriptor as backup, some
93  * information elements have intuitive mappings, other not.
94  */
95 static
96 void i1480u_fill_device_info(struct wlp *wlp, struct wlp_device_info *dev_info)
97 {
98         struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
99         struct usb_device *usb_dev = i1480u->usb_dev;
100         /* Treat device name and model name the same */
101         if (usb_dev->descriptor.iProduct) {
102                 usb_string(usb_dev, usb_dev->descriptor.iProduct,
103                            dev_info->name, sizeof(dev_info->name));
104                 usb_string(usb_dev, usb_dev->descriptor.iProduct,
105                            dev_info->model_name, sizeof(dev_info->model_name));
106         }
107         if (usb_dev->descriptor.iManufacturer)
108                 usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
109                            dev_info->manufacturer,
110                            sizeof(dev_info->manufacturer));
111         scnprintf(dev_info->model_nr, sizeof(dev_info->model_nr), "%04x",
112                   __le16_to_cpu(usb_dev->descriptor.bcdDevice));
113         if (usb_dev->descriptor.iSerialNumber)
114                 usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
115                            dev_info->serial, sizeof(dev_info->serial));
116         /* FIXME: where should we obtain category? */
117         dev_info->prim_dev_type.category = cpu_to_le16(WLP_DEV_CAT_OTHER);
118         /* FIXME: Complete OUI and OUIsubdiv attributes */
119 }
120
121 #ifdef i1480u_FLOW_CONTROL
122 /**
123  * Callback for the notification endpoint
124  *
125  * This mostly controls the xon/xoff protocol. In case of hard error,
126  * we stop the queue. If not, we always retry.
127  */
128 static
129 void i1480u_notif_cb(struct urb *urb, struct pt_regs *regs)
130 {
131         struct i1480u *i1480u = urb->context;
132         struct usb_interface *usb_iface = i1480u->usb_iface;
133         struct device *dev = &usb_iface->dev;
134         int result;
135
136         switch (urb->status) {
137         case 0:                         /* Got valid data, do xon/xoff */
138                 switch (i1480u->notif_buffer[0]) {
139                 case 'N':
140                         dev_err(dev, "XOFF STOPPING queue at %lu\n", jiffies);
141                         netif_stop_queue(i1480u->net_dev);
142                         break;
143                 case 'A':
144                         dev_err(dev, "XON STARTING queue at %lu\n", jiffies);
145                         netif_start_queue(i1480u->net_dev);
146                         break;
147                 default:
148                         dev_err(dev, "NEP: unknown data 0x%02hhx\n",
149                                 i1480u->notif_buffer[0]);
150                 }
151                 break;
152         case -ECONNRESET:               /* Controlled situation ... */
153         case -ENOENT:                   /* we killed the URB... */
154                 dev_err(dev, "NEP: URB reset/noent %d\n", urb->status);
155                 goto error;
156         case -ESHUTDOWN:                /* going away! */
157                 dev_err(dev, "NEP: URB down %d\n", urb->status);
158                 goto error;
159         default:                        /* Retry unless it gets ugly */
160                 if (edc_inc(&i1480u->notif_edc, EDC_MAX_ERRORS,
161                             EDC_ERROR_TIMEFRAME)) {
162                         dev_err(dev, "NEP: URB max acceptable errors "
163                                 "exceeded; resetting device\n");
164                         goto error_reset;
165                 }
166                 dev_err(dev, "NEP: URB error %d\n", urb->status);
167                 break;
168         }
169         result = usb_submit_urb(urb, GFP_ATOMIC);
170         if (result < 0) {
171                 dev_err(dev, "NEP: Can't resubmit URB: %d; resetting device\n",
172                         result);
173                 goto error_reset;
174         }
175         return;
176
177 error_reset:
178         wlp_reset_all(&i1480-wlp);
179 error:
180         netif_stop_queue(i1480u->net_dev);
181         return;
182 }
183 #endif
184
185 static const struct net_device_ops i1480u_netdev_ops = {
186         .ndo_open       = i1480u_open,
187         .ndo_stop       = i1480u_stop,
188         .ndo_start_xmit = i1480u_hard_start_xmit,
189         .ndo_tx_timeout = i1480u_tx_timeout,
190         .ndo_set_config = i1480u_set_config,
191         .ndo_change_mtu = i1480u_change_mtu,
192 };
193
194 static
195 int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface)
196 {
197         int result = -ENODEV;
198         struct wlp *wlp = &i1480u->wlp;
199         struct usb_device *usb_dev = interface_to_usbdev(iface);
200         struct net_device *net_dev = i1480u->net_dev;
201         struct uwb_rc *rc;
202         struct uwb_dev *uwb_dev;
203 #ifdef i1480u_FLOW_CONTROL
204         struct usb_endpoint_descriptor *epd;
205 #endif
206
207         i1480u->usb_dev = usb_get_dev(usb_dev);
208         i1480u->usb_iface = iface;
209         rc = uwb_rc_get_by_grandpa(&i1480u->usb_dev->dev);
210         if (rc == NULL) {
211                 dev_err(&iface->dev, "Cannot get associated UWB Radio "
212                         "Controller\n");
213                 goto out;
214         }
215         wlp->xmit_frame = i1480u_xmit_frame;
216         wlp->fill_device_info = i1480u_fill_device_info;
217         wlp->stop_queue = i1480u_stop_queue;
218         wlp->start_queue = i1480u_start_queue;
219         result = wlp_setup(wlp, rc, net_dev);
220         if (result < 0) {
221                 dev_err(&iface->dev, "Cannot setup WLP\n");
222                 goto error_wlp_setup;
223         }
224         result = 0;
225         ether_setup(net_dev);                   /* make it an etherdevice */
226         uwb_dev = &rc->uwb_dev;
227         /* FIXME: hookup address change notifications? */
228
229         memcpy(net_dev->dev_addr, uwb_dev->mac_addr.data,
230                sizeof(net_dev->dev_addr));
231
232         net_dev->hard_header_len = sizeof(struct untd_hdr_cmp)
233                 + sizeof(struct wlp_tx_hdr)
234                 + WLP_DATA_HLEN
235                 + ETH_HLEN;
236         net_dev->mtu = 3500;
237         net_dev->tx_queue_len = 20;             /* FIXME: maybe use 1000? */
238
239 /*      net_dev->flags &= ~IFF_BROADCAST;       FIXME: BUG in firmware */
240         /* FIXME: multicast disabled */
241         net_dev->flags &= ~IFF_MULTICAST;
242         net_dev->features &= ~NETIF_F_SG;
243         net_dev->features &= ~NETIF_F_FRAGLIST;
244         /* All NETIF_F_*_CSUM disabled */
245         net_dev->features |= NETIF_F_HIGHDMA;
246         net_dev->watchdog_timeo = 5*HZ;         /* FIXME: a better default? */
247
248         net_dev->netdev_ops = &i1480u_netdev_ops;
249
250 #ifdef i1480u_FLOW_CONTROL
251         /* Notification endpoint setup (submitted when we open the device) */
252         i1480u->notif_urb = usb_alloc_urb(0, GFP_KERNEL);
253         if (i1480u->notif_urb == NULL) {
254                 dev_err(&iface->dev, "Unable to allocate notification URB\n");
255                 result = -ENOMEM;
256                 goto error_urb_alloc;
257         }
258         epd = &iface->cur_altsetting->endpoint[0].desc;
259         usb_fill_int_urb(i1480u->notif_urb, usb_dev,
260                          usb_rcvintpipe(usb_dev, epd->bEndpointAddress),
261                          i1480u->notif_buffer, sizeof(i1480u->notif_buffer),
262                          i1480u_notif_cb, i1480u, epd->bInterval);
263
264 #endif
265
266         i1480u->tx_inflight.max = i1480u_TX_INFLIGHT_MAX;
267         i1480u->tx_inflight.threshold = i1480u_TX_INFLIGHT_THRESHOLD;
268         i1480u->tx_inflight.restart_ts = jiffies;
269         usb_set_intfdata(iface, i1480u);
270         return result;
271
272 #ifdef i1480u_FLOW_CONTROL
273 error_urb_alloc:
274 #endif
275         wlp_remove(wlp);
276 error_wlp_setup:
277         uwb_rc_put(rc);
278 out:
279         usb_put_dev(i1480u->usb_dev);
280         return result;
281 }
282
283 static void i1480u_rm(struct i1480u *i1480u)
284 {
285         struct uwb_rc *rc = i1480u->wlp.rc;
286         usb_set_intfdata(i1480u->usb_iface, NULL);
287 #ifdef i1480u_FLOW_CONTROL
288         usb_kill_urb(i1480u->notif_urb);
289         usb_free_urb(i1480u->notif_urb);
290 #endif
291         wlp_remove(&i1480u->wlp);
292         uwb_rc_put(rc);
293         usb_put_dev(i1480u->usb_dev);
294 }
295
296 /** Just setup @net_dev's i1480u private data */
297 static void i1480u_netdev_setup(struct net_device *net_dev)
298 {
299         struct i1480u *i1480u = netdev_priv(net_dev);
300         /* Initialize @i1480u */
301         memset(i1480u, 0, sizeof(*i1480u));
302         i1480u_init(i1480u);
303 }
304
305 /**
306  * Probe a i1480u interface and register it
307  *
308  * @iface:   USB interface to link to
309  * @id:      USB class/subclass/protocol id
310  * @returns: 0 if ok, < 0 errno code on error.
311  *
312  * Does basic housekeeping stuff and then allocs a netdev with space
313  * for the i1480u  data. Initializes, registers in i1480u, registers in
314  * netdev, ready to go.
315  */
316 static int i1480u_probe(struct usb_interface *iface,
317                         const struct usb_device_id *id)
318 {
319         int result;
320         struct net_device *net_dev;
321         struct device *dev = &iface->dev;
322         struct i1480u *i1480u;
323
324         /* Allocate instance [calls i1480u_netdev_setup() on it] */
325         result = -ENOMEM;
326         net_dev = alloc_netdev(sizeof(*i1480u), "wlp%d", i1480u_netdev_setup);
327         if (net_dev == NULL) {
328                 dev_err(dev, "no memory for network device instance\n");
329                 goto error_alloc_netdev;
330         }
331         SET_NETDEV_DEV(net_dev, dev);
332         i1480u = netdev_priv(net_dev);
333         i1480u->net_dev = net_dev;
334         result = i1480u_add(i1480u, iface);     /* Now setup all the wlp stuff */
335         if (result < 0) {
336                 dev_err(dev, "cannot add i1480u device: %d\n", result);
337                 goto error_i1480u_add;
338         }
339         result = register_netdev(net_dev);      /* Okey dokey, bring it up */
340         if (result < 0) {
341                 dev_err(dev, "cannot register network device: %d\n", result);
342                 goto error_register_netdev;
343         }
344         i1480u_sysfs_setup(i1480u);
345         if (result < 0)
346                 goto error_sysfs_init;
347         return 0;
348
349 error_sysfs_init:
350         unregister_netdev(net_dev);
351 error_register_netdev:
352         i1480u_rm(i1480u);
353 error_i1480u_add:
354         free_netdev(net_dev);
355 error_alloc_netdev:
356         return result;
357 }
358
359
360 /**
361  * Disconect a i1480u from the system.
362  *
363  * i1480u_stop() has been called before, so al the rx and tx contexts
364  * have been taken down already. Make sure the queue is stopped,
365  * unregister netdev and i1480u, free and kill.
366  */
367 static void i1480u_disconnect(struct usb_interface *iface)
368 {
369         struct i1480u *i1480u;
370         struct net_device *net_dev;
371
372         i1480u = usb_get_intfdata(iface);
373         net_dev = i1480u->net_dev;
374         netif_stop_queue(net_dev);
375 #ifdef i1480u_FLOW_CONTROL
376         usb_kill_urb(i1480u->notif_urb);
377 #endif
378         i1480u_sysfs_release(i1480u);
379         unregister_netdev(net_dev);
380         i1480u_rm(i1480u);
381         free_netdev(net_dev);
382 }
383
384 static struct usb_device_id i1480u_id_table[] = {
385         {
386                 .match_flags = USB_DEVICE_ID_MATCH_DEVICE \
387                                 |  USB_DEVICE_ID_MATCH_DEV_INFO \
388                                 |  USB_DEVICE_ID_MATCH_INT_INFO,
389                 .idVendor = 0x8086,
390                 .idProduct = 0x0c3b,
391                 .bDeviceClass = 0xef,
392                 .bDeviceSubClass = 0x02,
393                 .bDeviceProtocol = 0x02,
394                 .bInterfaceClass = 0xff,
395                 .bInterfaceSubClass = 0xff,
396                 .bInterfaceProtocol = 0xff,
397         },
398         {},
399 };
400 MODULE_DEVICE_TABLE(usb, i1480u_id_table);
401
402 static struct usb_driver i1480u_driver = {
403         .name =         KBUILD_MODNAME,
404         .probe =        i1480u_probe,
405         .disconnect =   i1480u_disconnect,
406         .id_table =     i1480u_id_table,
407 };
408
409 static int __init i1480u_driver_init(void)
410 {
411         return usb_register(&i1480u_driver);
412 }
413 module_init(i1480u_driver_init);
414
415
416 static void __exit i1480u_driver_exit(void)
417 {
418         usb_deregister(&i1480u_driver);
419 }
420 module_exit(i1480u_driver_exit);
421
422 MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
423 MODULE_DESCRIPTION("i1480 Wireless UWB Link WLP networking for USB");
424 MODULE_LICENSE("GPL");