Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / drivers / net / irda / ks959-sir.c
1 /*****************************************************************************
2 *
3 * Filename:      ks959-sir.c
4 * Version:       0.1.2
5 * Description:   Irda KingSun KS-959 USB Dongle
6 * Status:        Experimental
7 * Author:        Alex Villacís Lasso <a_villacis@palosanto.com>
8 *         with help from Domen Puncer <domen@coderock.org>
9 *
10 *    Based on stir4200, mcs7780, kingsun-sir drivers.
11 *
12 *    This program is free software; you can redistribute it and/or modify
13 *    it under the terms of the GNU General Public License as published by
14 *    the Free Software Foundation; either version 2 of the License.
15 *
16 *    This program is distributed in the hope that it will be useful,
17 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *    GNU General Public License for more details.
20 *
21 *    You should have received a copy of the GNU General Public License
22 *    along with this program; if not, write to the Free Software
23 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *****************************************************************************/
26
27 /*
28  * Following is my most current (2007-07-17) understanding of how the Kingsun
29  * KS-959 dongle is supposed to work. This information was deduced by
30  * reverse-engineering and examining the USB traffic captured with USBSnoopy
31  * from the WinXP driver. Feel free to update here as more of the dongle is
32  * known.
33  *
34  * My most sincere thanks must go to Domen Puncer <domen@coderock.org> for
35  * invaluable help in cracking the obfuscation and padding required for this
36  * dongle.
37  *
38  * General: This dongle exposes one interface with one interrupt IN endpoint.
39  * However, the interrupt endpoint is NOT used at all for this dongle. Instead,
40  * this dongle uses control transfers for everything, including sending and
41  * receiving the IrDA frame data. Apparently the interrupt endpoint is just a
42  * dummy to ensure the dongle has a valid interface to present to the PC.And I
43  * thought the DonShine dongle was weird... In addition, this dongle uses
44  * obfuscation (?!?!), applied at the USB level, to hide the traffic, both sent
45  * and received, from the dongle. I call it obfuscation because the XOR keying
46  * and padding required to produce an USB traffic acceptable for the dongle can
47  * not be explained by any other technical requirement.
48  *
49  * Transmission: To transmit an IrDA frame, the driver must prepare a control
50  * URB with the following as a setup packet:
51  *    bRequestType    USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
52  *    bRequest        0x09
53  *    wValue          <length of valid data before padding, little endian>
54  *    wIndex          0x0000
55  *    wLength         <length of padded data>
56  * The payload packet must be manually wrapped and escaped (as in stir4200.c),
57  * then padded and obfuscated before being sent. Both padding and obfuscation
58  * are implemented in the procedure obfuscate_tx_buffer(). Suffice to say, the
59  * designer/programmer of the dongle used his name as a source for the
60  * obfuscation. WTF?!
61  * Apparently the dongle cannot handle payloads larger than 256 bytes. The
62  * driver has to perform fragmentation in order to send anything larger than
63  * this limit.
64  *
65  * Reception: To receive data, the driver must poll the dongle regularly (like
66  * kingsun-sir.c) with control URBs and the following as a setup packet:
67  *    bRequestType    USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE
68  *    bRequest        0x01
69  *    wValue          0x0200
70  *    wIndex          0x0000
71  *    wLength         0x0800 (size of available buffer)
72  * If there is data to be read, it will be returned as the response payload.
73  * This data is (apparently) not padded, but it is obfuscated. To de-obfuscate
74  * it, the driver must XOR every byte, in sequence, with a value that starts at
75  * 1 and is incremented with each byte processed, and then with 0x55. The value
76  * incremented with each byte processed overflows as an unsigned char. The
77  * resulting bytes form a wrapped SIR frame that is unwrapped and unescaped
78  * as in stir4200.c The incremented value is NOT reset with each frame, but is
79  * kept across the entire session with the dongle. Also, the dongle inserts an
80  * extra garbage byte with value 0x95 (after decoding) every 0xff bytes, which
81  * must be skipped.
82  *
83  * Speed change: To change the speed of the dongle, the driver prepares a
84  * control URB with the following as a setup packet:
85  *    bRequestType    USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
86  *    bRequest        0x09
87  *    wValue          0x0200
88  *    wIndex          0x0001
89  *    wLength         0x0008 (length of the payload)
90  * The payload is a 8-byte record, apparently identical to the one used in
91  * drivers/usb/serial/cypress_m8.c to change speed:
92  *     __u32 baudSpeed;
93  *    unsigned int dataBits : 2;    // 0 - 5 bits 3 - 8 bits
94  *    unsigned int : 1;
95  *    unsigned int stopBits : 1;
96  *    unsigned int parityEnable : 1;
97  *    unsigned int parityType : 1;
98  *    unsigned int : 1;
99  *    unsigned int reset : 1;
100  *    unsigned char reserved[3];    // set to 0
101  *
102  * For now only SIR speeds have been observed with this dongle. Therefore,
103  * nothing is known on what changes (if any) must be done to frame wrapping /
104  * unwrapping for higher than SIR speeds. This driver assumes no change is
105  * necessary and announces support for all the way to 57600 bps. Although the
106  * package announces support for up to 4MBps, tests with a Sony Ericcson K300
107  * phone show corruption when receiving large frames at 115200 bps, the highest
108  * speed announced by the phone. However, transmission at 115200 bps is OK. Go
109  * figure. Since I don't know whether the phone or the dongle is at fault, max
110  * announced speed is 57600 bps until someone produces a device that can run
111  * at higher speeds with this dongle.
112  */
113
114 #include <linux/module.h>
115 #include <linux/moduleparam.h>
116 #include <linux/kernel.h>
117 #include <linux/types.h>
118 #include <linux/errno.h>
119 #include <linux/init.h>
120 #include <linux/slab.h>
121 #include <linux/module.h>
122 #include <linux/kref.h>
123 #include <linux/usb.h>
124 #include <linux/device.h>
125 #include <linux/crc32.h>
126
127 #include <asm/unaligned.h>
128 #include <asm/byteorder.h>
129 #include <asm/uaccess.h>
130
131 #include <net/irda/irda.h>
132 #include <net/irda/wrapper.h>
133 #include <net/irda/crc.h>
134
135 #define KS959_VENDOR_ID 0x07d0
136 #define KS959_PRODUCT_ID 0x4959
137
138 /* These are the currently known USB ids */
139 static struct usb_device_id dongles[] = {
140         /* KingSun Co,Ltd  IrDA/USB Bridge */
141         {USB_DEVICE(KS959_VENDOR_ID, KS959_PRODUCT_ID)},
142         {}
143 };
144
145 MODULE_DEVICE_TABLE(usb, dongles);
146
147 #define KINGSUN_MTT 0x07
148 #define KINGSUN_REQ_RECV 0x01
149 #define KINGSUN_REQ_SEND 0x09
150
151 #define KINGSUN_RCV_FIFO_SIZE    2048   /* Max length we can receive */
152 #define KINGSUN_SND_FIFO_SIZE    2048   /* Max packet we can send */
153 #define KINGSUN_SND_PACKET_SIZE    256  /* Max packet dongle can handle */
154
155 struct ks959_speedparams {
156         __le32 baudrate;        /* baud rate, little endian */
157         __u8 flags;
158         __u8 reserved[3];
159 } __attribute__ ((packed));
160
161 #define KS_DATA_5_BITS 0x00
162 #define KS_DATA_6_BITS 0x01
163 #define KS_DATA_7_BITS 0x02
164 #define KS_DATA_8_BITS 0x03
165
166 #define KS_STOP_BITS_1 0x00
167 #define KS_STOP_BITS_2 0x08
168
169 #define KS_PAR_DISABLE    0x00
170 #define KS_PAR_EVEN    0x10
171 #define KS_PAR_ODD    0x30
172 #define KS_RESET    0x80
173
174 struct ks959_cb {
175         struct usb_device *usbdev;      /* init: probe_irda */
176         struct net_device *netdev;      /* network layer */
177         struct irlap_cb *irlap; /* The link layer we are binded to */
178         struct net_device_stats stats;  /* network statistics */
179         struct qos_info qos;
180
181         struct usb_ctrlrequest *tx_setuprequest;
182         struct urb *tx_urb;
183         __u8 *tx_buf_clear;
184         unsigned int tx_buf_clear_used;
185         unsigned int tx_buf_clear_sent;
186         __u8 *tx_buf_xored;
187
188         struct usb_ctrlrequest *rx_setuprequest;
189         struct urb *rx_urb;
190         __u8 *rx_buf;
191         __u8 rx_variable_xormask;
192         iobuff_t rx_unwrap_buff;
193         struct timeval rx_time;
194
195         struct usb_ctrlrequest *speed_setuprequest;
196         struct urb *speed_urb;
197         struct ks959_speedparams speedparams;
198         unsigned int new_speed;
199
200         spinlock_t lock;
201         int receiving;
202 };
203
204 /* Procedure to perform the obfuscation/padding expected by the dongle
205  *
206  * buf_cleartext    (IN) Cleartext version of the IrDA frame to transmit
207  * len_cleartext    (IN) Length of the cleartext version of IrDA frame
208  * buf_xoredtext    (OUT) Obfuscated version of frame built by proc
209  * len_maxbuf        (OUT) Maximum space available at buf_xoredtext
210  *
211  * (return)         length of obfuscated frame with padding
212  *
213  * If not enough space (as indicated by len_maxbuf vs. required padding),
214  * zero is returned
215  *
216  * The value of lookup_string is actually a required portion of the algorithm.
217  * Seems the designer of the dongle wanted to state who exactly is responsible
218  * for implementing obfuscation. Send your best (or other) wishes to him ]:-)
219  */
220 static unsigned int obfuscate_tx_buffer(const __u8 * buf_cleartext,
221                                         unsigned int len_cleartext,
222                                         __u8 * buf_xoredtext,
223                                         unsigned int len_maxbuf)
224 {
225         unsigned int len_xoredtext;
226
227         /* Calculate required length with padding, check for necessary space */
228         len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10;
229         if (len_xoredtext <= len_maxbuf) {
230                 static const __u8 lookup_string[] = "wangshuofei19710";
231                 __u8 xor_mask;
232
233                 /* Unlike the WinXP driver, we *do* clear out the padding */
234                 memset(buf_xoredtext, 0, len_xoredtext);
235
236                 xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55;
237
238                 while (len_cleartext-- > 0) {
239                         *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask;
240                 }
241         } else {
242                 len_xoredtext = 0;
243         }
244         return len_xoredtext;
245 }
246
247 /* Callback transmission routine */
248 static void ks959_speed_irq(struct urb *urb)
249 {
250         /* unlink, shutdown, unplug, other nasties */
251         if (urb->status != 0) {
252                 err("ks959_speed_irq: urb asynchronously failed - %d",
253                     urb->status);
254         }
255 }
256
257 /* Send a control request to change speed of the dongle */
258 static int ks959_change_speed(struct ks959_cb *kingsun, unsigned speed)
259 {
260         static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400,
261                 57600, 115200, 576000, 1152000, 4000000, 0
262         };
263         int err;
264         unsigned int i;
265
266         if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL)
267                 return -ENOMEM;
268
269         /* Check that requested speed is among the supported ones */
270         for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ;
271         if (supported_speeds[i] == 0)
272                 return -EOPNOTSUPP;
273
274         memset(&(kingsun->speedparams), 0, sizeof(struct ks959_speedparams));
275         kingsun->speedparams.baudrate = cpu_to_le32(speed);
276         kingsun->speedparams.flags = KS_DATA_8_BITS;
277
278         /* speed_setuprequest pre-filled in ks959_probe */
279         usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev,
280                              usb_sndctrlpipe(kingsun->usbdev, 0),
281                              (unsigned char *)kingsun->speed_setuprequest,
282                              &(kingsun->speedparams),
283                              sizeof(struct ks959_speedparams), ks959_speed_irq,
284                              kingsun);
285         kingsun->speed_urb->status = 0;
286         err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC);
287
288         return err;
289 }
290
291 /* Submit one fragment of an IrDA frame to the dongle */
292 static void ks959_send_irq(struct urb *urb);
293 static int ks959_submit_tx_fragment(struct ks959_cb *kingsun)
294 {
295         unsigned int padlen;
296         unsigned int wraplen;
297         int ret;
298
299         /* Check whether current plaintext can produce a padded buffer that fits
300            within the range handled by the dongle */
301         wraplen = (KINGSUN_SND_PACKET_SIZE & ~0x7) - 0x10;
302         if (wraplen > kingsun->tx_buf_clear_used)
303                 wraplen = kingsun->tx_buf_clear_used;
304
305         /* Perform dongle obfuscation. Also remove the portion of the frame that
306            was just obfuscated and will now be sent to the dongle. */
307         padlen = obfuscate_tx_buffer(kingsun->tx_buf_clear, wraplen,
308                                      kingsun->tx_buf_xored,
309                                      KINGSUN_SND_PACKET_SIZE);
310
311         /* Calculate how much data can be transmitted in this urb */
312         kingsun->tx_setuprequest->wValue = cpu_to_le16(wraplen);
313         kingsun->tx_setuprequest->wLength = cpu_to_le16(padlen);
314         /* Rest of the fields were filled in ks959_probe */
315         usb_fill_control_urb(kingsun->tx_urb, kingsun->usbdev,
316                              usb_sndctrlpipe(kingsun->usbdev, 0),
317                              (unsigned char *)kingsun->tx_setuprequest,
318                              kingsun->tx_buf_xored, padlen,
319                              ks959_send_irq, kingsun);
320         kingsun->tx_urb->status = 0;
321         ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC);
322
323         /* Remember how much data was sent, in order to update at callback */
324         kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0;
325         return ret;
326 }
327
328 /* Callback transmission routine */
329 static void ks959_send_irq(struct urb *urb)
330 {
331         struct ks959_cb *kingsun = urb->context;
332         struct net_device *netdev = kingsun->netdev;
333         int ret = 0;
334
335         /* in process of stopping, just drop data */
336         if (!netif_running(kingsun->netdev)) {
337                 err("ks959_send_irq: Network not running!");
338                 return;
339         }
340
341         /* unlink, shutdown, unplug, other nasties */
342         if (urb->status != 0) {
343                 err("ks959_send_irq: urb asynchronously failed - %d",
344                     urb->status);
345                 return;
346         }
347
348         if (kingsun->tx_buf_clear_used > 0) {
349                 /* Update data remaining to be sent */
350                 if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) {
351                         memmove(kingsun->tx_buf_clear,
352                                 kingsun->tx_buf_clear +
353                                 kingsun->tx_buf_clear_sent,
354                                 kingsun->tx_buf_clear_used -
355                                 kingsun->tx_buf_clear_sent);
356                 }
357                 kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent;
358                 kingsun->tx_buf_clear_sent = 0;
359
360                 if (kingsun->tx_buf_clear_used > 0) {
361                         /* There is more data to be sent */
362                         if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
363                                 err("ks959_send_irq: failed tx_urb submit: %d",
364                                     ret);
365                                 switch (ret) {
366                                 case -ENODEV:
367                                 case -EPIPE:
368                                         break;
369                                 default:
370                                         kingsun->stats.tx_errors++;
371                                         netif_start_queue(netdev);
372                                 }
373                         }
374                 } else {
375                         /* All data sent, send next speed && wake network queue */
376                         if (kingsun->new_speed != -1 &&
377                             cpu_to_le32(kingsun->new_speed) !=
378                             kingsun->speedparams.baudrate)
379                                 ks959_change_speed(kingsun, kingsun->new_speed);
380
381                         netif_wake_queue(netdev);
382                 }
383         }
384 }
385
386 /*
387  * Called from net/core when new frame is available.
388  */
389 static int ks959_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
390 {
391         struct ks959_cb *kingsun;
392         unsigned int wraplen;
393         int ret = 0;
394
395         if (skb == NULL || netdev == NULL)
396                 return -EINVAL;
397
398         netif_stop_queue(netdev);
399
400         /* the IRDA wrapping routines don't deal with non linear skb */
401         SKB_LINEAR_ASSERT(skb);
402
403         kingsun = netdev_priv(netdev);
404
405         spin_lock(&kingsun->lock);
406         kingsun->new_speed = irda_get_next_speed(skb);
407
408         /* Append data to the end of whatever data remains to be transmitted */
409         wraplen =
410             async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE);
411         kingsun->tx_buf_clear_used = wraplen;
412
413         if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
414                 err("ks959_hard_xmit: failed tx_urb submit: %d", ret);
415                 switch (ret) {
416                 case -ENODEV:
417                 case -EPIPE:
418                         break;
419                 default:
420                         kingsun->stats.tx_errors++;
421                         netif_start_queue(netdev);
422                 }
423         } else {
424                 kingsun->stats.tx_packets++;
425                 kingsun->stats.tx_bytes += skb->len;
426
427         }
428
429         dev_kfree_skb(skb);
430         spin_unlock(&kingsun->lock);
431
432         return ret;
433 }
434
435 /* Receive callback function */
436 static void ks959_rcv_irq(struct urb *urb)
437 {
438         struct ks959_cb *kingsun = urb->context;
439         int ret;
440
441         /* in process of stopping, just drop data */
442         if (!netif_running(kingsun->netdev)) {
443                 kingsun->receiving = 0;
444                 return;
445         }
446
447         /* unlink, shutdown, unplug, other nasties */
448         if (urb->status != 0) {
449                 err("kingsun_rcv_irq: urb asynchronously failed - %d",
450                     urb->status);
451                 kingsun->receiving = 0;
452                 return;
453         }
454
455         if (urb->actual_length > 0) {
456                 __u8 *bytes = urb->transfer_buffer;
457                 unsigned int i;
458
459                 for (i = 0; i < urb->actual_length; i++) {
460                         /* De-obfuscation implemented here: variable portion of
461                            xormask is incremented, and then used with the encoded
462                            byte for the XOR. The result of the operation is used
463                            to unwrap the SIR frame. */
464                         kingsun->rx_variable_xormask++;
465                         bytes[i] =
466                             bytes[i] ^ kingsun->rx_variable_xormask ^ 0x55u;
467
468                         /* rx_variable_xormask doubles as an index counter so we
469                            can skip the byte at 0xff (wrapped around to 0).
470                          */
471                         if (kingsun->rx_variable_xormask != 0) {
472                                 async_unwrap_char(kingsun->netdev,
473                                                   &kingsun->stats,
474                                                   &kingsun->rx_unwrap_buff,
475                                                   bytes[i]);
476                         }
477                 }
478                 kingsun->netdev->last_rx = jiffies;
479                 do_gettimeofday(&kingsun->rx_time);
480                 kingsun->receiving =
481                     (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
482         }
483
484         /* This urb has already been filled in kingsun_net_open. Setup
485            packet must be re-filled, but it is assumed that urb keeps the
486            pointer to the initial setup packet, as well as the payload buffer.
487            Setup packet is already pre-filled at ks959_probe.
488          */
489         urb->status = 0;
490         ret = usb_submit_urb(urb, GFP_ATOMIC);
491 }
492
493 /*
494  * Function kingsun_net_open (dev)
495  *
496  *    Network device is taken up. Usually this is done by "ifconfig irda0 up"
497  */
498 static int ks959_net_open(struct net_device *netdev)
499 {
500         struct ks959_cb *kingsun = netdev_priv(netdev);
501         int err = -ENOMEM;
502         char hwname[16];
503
504         /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */
505         kingsun->receiving = 0;
506
507         /* Initialize for SIR to copy data directly into skb.  */
508         kingsun->rx_unwrap_buff.in_frame = FALSE;
509         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
510         kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU;
511         kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
512         if (!kingsun->rx_unwrap_buff.skb)
513                 goto free_mem;
514
515         skb_reserve(kingsun->rx_unwrap_buff.skb, 1);
516         kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data;
517         do_gettimeofday(&kingsun->rx_time);
518
519         kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
520         if (!kingsun->rx_urb)
521                 goto free_mem;
522
523         kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
524         if (!kingsun->tx_urb)
525                 goto free_mem;
526
527         kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
528         if (!kingsun->speed_urb)
529                 goto free_mem;
530
531         /* Initialize speed for dongle */
532         kingsun->new_speed = 9600;
533         err = ks959_change_speed(kingsun, 9600);
534         if (err < 0)
535                 goto free_mem;
536
537         /*
538          * Now that everything should be initialized properly,
539          * Open new IrLAP layer instance to take care of us...
540          */
541         sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
542         kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
543         if (!kingsun->irlap) {
544                 err("ks959-sir: irlap_open failed");
545                 goto free_mem;
546         }
547
548         /* Start reception. Setup request already pre-filled in ks959_probe */
549         usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev,
550                              usb_rcvctrlpipe(kingsun->usbdev, 0),
551                              (unsigned char *)kingsun->rx_setuprequest,
552                              kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE,
553                              ks959_rcv_irq, kingsun);
554         kingsun->rx_urb->status = 0;
555         err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
556         if (err) {
557                 err("ks959-sir: first urb-submit failed: %d", err);
558                 goto close_irlap;
559         }
560
561         netif_start_queue(netdev);
562
563         /* Situation at this point:
564            - all work buffers allocated
565            - urbs allocated and ready to fill
566            - max rx packet known (in max_rx)
567            - unwrap state machine initialized, in state outside of any frame
568            - receive request in progress
569            - IrLAP layer started, about to hand over packets to send
570          */
571
572         return 0;
573
574       close_irlap:
575         irlap_close(kingsun->irlap);
576       free_mem:
577         usb_free_urb(kingsun->speed_urb);
578         kingsun->speed_urb = NULL;
579         usb_free_urb(kingsun->tx_urb);
580         kingsun->tx_urb = NULL;
581         usb_free_urb(kingsun->rx_urb);
582         kingsun->rx_urb = NULL;
583         if (kingsun->rx_unwrap_buff.skb) {
584                 kfree_skb(kingsun->rx_unwrap_buff.skb);
585                 kingsun->rx_unwrap_buff.skb = NULL;
586                 kingsun->rx_unwrap_buff.head = NULL;
587         }
588         return err;
589 }
590
591 /*
592  * Function kingsun_net_close (kingsun)
593  *
594  *    Network device is taken down. Usually this is done by
595  *    "ifconfig irda0 down"
596  */
597 static int ks959_net_close(struct net_device *netdev)
598 {
599         struct ks959_cb *kingsun = netdev_priv(netdev);
600
601         /* Stop transmit processing */
602         netif_stop_queue(netdev);
603
604         /* Mop up receive && transmit urb's */
605         usb_kill_urb(kingsun->tx_urb);
606         usb_free_urb(kingsun->tx_urb);
607         kingsun->tx_urb = NULL;
608
609         usb_kill_urb(kingsun->speed_urb);
610         usb_free_urb(kingsun->speed_urb);
611         kingsun->speed_urb = NULL;
612
613         usb_kill_urb(kingsun->rx_urb);
614         usb_free_urb(kingsun->rx_urb);
615         kingsun->rx_urb = NULL;
616
617         kfree_skb(kingsun->rx_unwrap_buff.skb);
618         kingsun->rx_unwrap_buff.skb = NULL;
619         kingsun->rx_unwrap_buff.head = NULL;
620         kingsun->rx_unwrap_buff.in_frame = FALSE;
621         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
622         kingsun->receiving = 0;
623
624         /* Stop and remove instance of IrLAP */
625         if (kingsun->irlap)
626                 irlap_close(kingsun->irlap);
627
628         kingsun->irlap = NULL;
629
630         return 0;
631 }
632
633 /*
634  * IOCTLs : Extra out-of-band network commands...
635  */
636 static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
637 {
638         struct if_irda_req *irq = (struct if_irda_req *)rq;
639         struct ks959_cb *kingsun = netdev_priv(netdev);
640         int ret = 0;
641
642         switch (cmd) {
643         case SIOCSBANDWIDTH:    /* Set bandwidth */
644                 if (!capable(CAP_NET_ADMIN))
645                         return -EPERM;
646
647                 /* Check if the device is still there */
648                 if (netif_device_present(kingsun->netdev))
649                         return ks959_change_speed(kingsun, irq->ifr_baudrate);
650                 break;
651
652         case SIOCSMEDIABUSY:    /* Set media busy */
653                 if (!capable(CAP_NET_ADMIN))
654                         return -EPERM;
655
656                 /* Check if the IrDA stack is still there */
657                 if (netif_running(kingsun->netdev))
658                         irda_device_set_media_busy(kingsun->netdev, TRUE);
659                 break;
660
661         case SIOCGRECEIVING:
662                 /* Only approximately true */
663                 irq->ifr_receiving = kingsun->receiving;
664                 break;
665
666         default:
667                 ret = -EOPNOTSUPP;
668         }
669
670         return ret;
671 }
672
673 /*
674  * Get device stats (for /proc/net/dev and ifconfig)
675  */
676 static struct net_device_stats *ks959_net_get_stats(struct net_device *netdev)
677 {
678         struct ks959_cb *kingsun = netdev_priv(netdev);
679         return &kingsun->stats;
680 }
681
682 /*
683  * This routine is called by the USB subsystem for each new device
684  * in the system. We need to check if the device is ours, and in
685  * this case start handling it.
686  */
687 static int ks959_probe(struct usb_interface *intf,
688                        const struct usb_device_id *id)
689 {
690         struct usb_device *dev = interface_to_usbdev(intf);
691         struct ks959_cb *kingsun = NULL;
692         struct net_device *net = NULL;
693         int ret = -ENOMEM;
694
695         /* Allocate network device container. */
696         net = alloc_irdadev(sizeof(*kingsun));
697         if (!net)
698                 goto err_out1;
699
700         SET_NETDEV_DEV(net, &intf->dev);
701         kingsun = netdev_priv(net);
702         kingsun->netdev = net;
703         kingsun->usbdev = dev;
704         kingsun->irlap = NULL;
705         kingsun->tx_setuprequest = NULL;
706         kingsun->tx_urb = NULL;
707         kingsun->tx_buf_clear = NULL;
708         kingsun->tx_buf_xored = NULL;
709         kingsun->tx_buf_clear_used = 0;
710         kingsun->tx_buf_clear_sent = 0;
711
712         kingsun->rx_setuprequest = NULL;
713         kingsun->rx_urb = NULL;
714         kingsun->rx_buf = NULL;
715         kingsun->rx_variable_xormask = 0;
716         kingsun->rx_unwrap_buff.in_frame = FALSE;
717         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
718         kingsun->rx_unwrap_buff.skb = NULL;
719         kingsun->receiving = 0;
720         spin_lock_init(&kingsun->lock);
721
722         kingsun->speed_setuprequest = NULL;
723         kingsun->speed_urb = NULL;
724         kingsun->speedparams.baudrate = 0;
725
726         /* Allocate input buffer */
727         kingsun->rx_buf = kmalloc(KINGSUN_RCV_FIFO_SIZE, GFP_KERNEL);
728         if (!kingsun->rx_buf)
729                 goto free_mem;
730
731         /* Allocate input setup packet */
732         kingsun->rx_setuprequest =
733             kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
734         if (!kingsun->rx_setuprequest)
735                 goto free_mem;
736         kingsun->rx_setuprequest->bRequestType =
737             USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
738         kingsun->rx_setuprequest->bRequest = KINGSUN_REQ_RECV;
739         kingsun->rx_setuprequest->wValue = cpu_to_le16(0x0200);
740         kingsun->rx_setuprequest->wIndex = 0;
741         kingsun->rx_setuprequest->wLength = cpu_to_le16(KINGSUN_RCV_FIFO_SIZE);
742
743         /* Allocate output buffer */
744         kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL);
745         if (!kingsun->tx_buf_clear)
746                 goto free_mem;
747         kingsun->tx_buf_xored = kmalloc(KINGSUN_SND_PACKET_SIZE, GFP_KERNEL);
748         if (!kingsun->tx_buf_xored)
749                 goto free_mem;
750
751         /* Allocate and initialize output setup packet */
752         kingsun->tx_setuprequest =
753             kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
754         if (!kingsun->tx_setuprequest)
755                 goto free_mem;
756         kingsun->tx_setuprequest->bRequestType =
757             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
758         kingsun->tx_setuprequest->bRequest = KINGSUN_REQ_SEND;
759         kingsun->tx_setuprequest->wValue = 0;
760         kingsun->tx_setuprequest->wIndex = 0;
761         kingsun->tx_setuprequest->wLength = 0;
762
763         /* Allocate and initialize speed setup packet */
764         kingsun->speed_setuprequest =
765             kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
766         if (!kingsun->speed_setuprequest)
767                 goto free_mem;
768         kingsun->speed_setuprequest->bRequestType =
769             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
770         kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND;
771         kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200);
772         kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001);
773         kingsun->speed_setuprequest->wLength =
774             cpu_to_le16(sizeof(struct ks959_speedparams));
775
776         printk(KERN_INFO "KingSun KS-959 IRDA/USB found at address %d, "
777                "Vendor: %x, Product: %x\n",
778                dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
779                le16_to_cpu(dev->descriptor.idProduct));
780
781         /* Initialize QoS for this device */
782         irda_init_max_qos_capabilies(&kingsun->qos);
783
784         /* Baud rates known to be supported. Please uncomment if devices (other
785            than a SonyEriccson K300 phone) can be shown to support higher speed
786            with this dongle.
787          */
788         kingsun->qos.baud_rate.bits =
789             IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600;
790         kingsun->qos.min_turn_time.bits &= KINGSUN_MTT;
791         irda_qos_bits_to_value(&kingsun->qos);
792
793         /* Override the network functions we need to use */
794         net->hard_start_xmit = ks959_hard_xmit;
795         net->open = ks959_net_open;
796         net->stop = ks959_net_close;
797         net->get_stats = ks959_net_get_stats;
798         net->do_ioctl = ks959_net_ioctl;
799
800         ret = register_netdev(net);
801         if (ret != 0)
802                 goto free_mem;
803
804         info("IrDA: Registered KingSun KS-959 device %s", net->name);
805
806         usb_set_intfdata(intf, kingsun);
807
808         /* Situation at this point:
809            - all work buffers allocated
810            - setup requests pre-filled
811            - urbs not allocated, set to NULL
812            - max rx packet known (is KINGSUN_FIFO_SIZE)
813            - unwrap state machine (partially) initialized, but skb == NULL
814          */
815
816         return 0;
817
818       free_mem:
819         kfree(kingsun->speed_setuprequest);
820         kfree(kingsun->tx_setuprequest);
821         kfree(kingsun->tx_buf_xored);
822         kfree(kingsun->tx_buf_clear);
823         kfree(kingsun->rx_setuprequest);
824         kfree(kingsun->rx_buf);
825         free_netdev(net);
826       err_out1:
827         return ret;
828 }
829
830 /*
831  * The current device is removed, the USB layer tell us to shut it down...
832  */
833 static void ks959_disconnect(struct usb_interface *intf)
834 {
835         struct ks959_cb *kingsun = usb_get_intfdata(intf);
836
837         if (!kingsun)
838                 return;
839
840         unregister_netdev(kingsun->netdev);
841
842         /* Mop up receive && transmit urb's */
843         if (kingsun->speed_urb != NULL) {
844                 usb_kill_urb(kingsun->speed_urb);
845                 usb_free_urb(kingsun->speed_urb);
846                 kingsun->speed_urb = NULL;
847         }
848         if (kingsun->tx_urb != NULL) {
849                 usb_kill_urb(kingsun->tx_urb);
850                 usb_free_urb(kingsun->tx_urb);
851                 kingsun->tx_urb = NULL;
852         }
853         if (kingsun->rx_urb != NULL) {
854                 usb_kill_urb(kingsun->rx_urb);
855                 usb_free_urb(kingsun->rx_urb);
856                 kingsun->rx_urb = NULL;
857         }
858
859         kfree(kingsun->speed_setuprequest);
860         kfree(kingsun->tx_setuprequest);
861         kfree(kingsun->tx_buf_xored);
862         kfree(kingsun->tx_buf_clear);
863         kfree(kingsun->rx_setuprequest);
864         kfree(kingsun->rx_buf);
865         free_netdev(kingsun->netdev);
866
867         usb_set_intfdata(intf, NULL);
868 }
869
870 #ifdef CONFIG_PM
871 /* USB suspend, so power off the transmitter/receiver */
872 static int ks959_suspend(struct usb_interface *intf, pm_message_t message)
873 {
874         struct ks959_cb *kingsun = usb_get_intfdata(intf);
875
876         netif_device_detach(kingsun->netdev);
877         if (kingsun->speed_urb != NULL)
878                 usb_kill_urb(kingsun->speed_urb);
879         if (kingsun->tx_urb != NULL)
880                 usb_kill_urb(kingsun->tx_urb);
881         if (kingsun->rx_urb != NULL)
882                 usb_kill_urb(kingsun->rx_urb);
883         return 0;
884 }
885
886 /* Coming out of suspend, so reset hardware */
887 static int ks959_resume(struct usb_interface *intf)
888 {
889         struct ks959_cb *kingsun = usb_get_intfdata(intf);
890
891         if (kingsun->rx_urb != NULL) {
892                 /* Setup request already filled in ks959_probe */
893                 usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
894         }
895         netif_device_attach(kingsun->netdev);
896
897         return 0;
898 }
899 #endif
900
901 /*
902  * USB device callbacks
903  */
904 static struct usb_driver irda_driver = {
905         .name = "ks959-sir",
906         .probe = ks959_probe,
907         .disconnect = ks959_disconnect,
908         .id_table = dongles,
909 #ifdef CONFIG_PM
910         .suspend = ks959_suspend,
911         .resume = ks959_resume,
912 #endif
913 };
914
915 /*
916  * Module insertion
917  */
918 static int __init ks959_init(void)
919 {
920         return usb_register(&irda_driver);
921 }
922
923 module_init(ks959_init);
924
925 /*
926  * Module removal
927  */
928 static void __exit ks959_cleanup(void)
929 {
930         /* Deregister the driver and remove all pending instances */
931         usb_deregister(&irda_driver);
932 }
933
934 module_exit(ks959_cleanup);
935
936 MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>");
937 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun KS-959");
938 MODULE_LICENSE("GPL");