Merge git://1984.lsi.us.es/nf-next
[cascardo/linux.git] / 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/usb.h>
122 #include <linux/device.h>
123 #include <linux/crc32.h>
124
125 #include <asm/unaligned.h>
126 #include <asm/byteorder.h>
127 #include <asm/uaccess.h>
128
129 #include <net/irda/irda.h>
130 #include <net/irda/wrapper.h>
131 #include <net/irda/crc.h>
132
133 #define KS959_VENDOR_ID 0x07d0
134 #define KS959_PRODUCT_ID 0x4959
135
136 /* These are the currently known USB ids */
137 static struct usb_device_id dongles[] = {
138         /* KingSun Co,Ltd  IrDA/USB Bridge */
139         {USB_DEVICE(KS959_VENDOR_ID, KS959_PRODUCT_ID)},
140         {}
141 };
142
143 MODULE_DEVICE_TABLE(usb, dongles);
144
145 #define KINGSUN_MTT 0x07
146 #define KINGSUN_REQ_RECV 0x01
147 #define KINGSUN_REQ_SEND 0x09
148
149 #define KINGSUN_RCV_FIFO_SIZE    2048   /* Max length we can receive */
150 #define KINGSUN_SND_FIFO_SIZE    2048   /* Max packet we can send */
151 #define KINGSUN_SND_PACKET_SIZE    256  /* Max packet dongle can handle */
152
153 struct ks959_speedparams {
154         __le32 baudrate;        /* baud rate, little endian */
155         __u8 flags;
156         __u8 reserved[3];
157 } __packed;
158
159 #define KS_DATA_5_BITS 0x00
160 #define KS_DATA_6_BITS 0x01
161 #define KS_DATA_7_BITS 0x02
162 #define KS_DATA_8_BITS 0x03
163
164 #define KS_STOP_BITS_1 0x00
165 #define KS_STOP_BITS_2 0x08
166
167 #define KS_PAR_DISABLE    0x00
168 #define KS_PAR_EVEN    0x10
169 #define KS_PAR_ODD    0x30
170 #define KS_RESET    0x80
171
172 struct ks959_cb {
173         struct usb_device *usbdev;      /* init: probe_irda */
174         struct net_device *netdev;      /* network layer */
175         struct irlap_cb *irlap; /* The link layer we are binded to */
176
177         struct qos_info qos;
178
179         struct usb_ctrlrequest *tx_setuprequest;
180         struct urb *tx_urb;
181         __u8 *tx_buf_clear;
182         unsigned int tx_buf_clear_used;
183         unsigned int tx_buf_clear_sent;
184         __u8 *tx_buf_xored;
185
186         struct usb_ctrlrequest *rx_setuprequest;
187         struct urb *rx_urb;
188         __u8 *rx_buf;
189         __u8 rx_variable_xormask;
190         iobuff_t rx_unwrap_buff;
191         struct timeval rx_time;
192
193         struct usb_ctrlrequest *speed_setuprequest;
194         struct urb *speed_urb;
195         struct ks959_speedparams speedparams;
196         unsigned int new_speed;
197
198         spinlock_t lock;
199         int receiving;
200 };
201
202 /* Procedure to perform the obfuscation/padding expected by the dongle
203  *
204  * buf_cleartext    (IN) Cleartext version of the IrDA frame to transmit
205  * len_cleartext    (IN) Length of the cleartext version of IrDA frame
206  * buf_xoredtext    (OUT) Obfuscated version of frame built by proc
207  * len_maxbuf        (OUT) Maximum space available at buf_xoredtext
208  *
209  * (return)         length of obfuscated frame with padding
210  *
211  * If not enough space (as indicated by len_maxbuf vs. required padding),
212  * zero is returned
213  *
214  * The value of lookup_string is actually a required portion of the algorithm.
215  * Seems the designer of the dongle wanted to state who exactly is responsible
216  * for implementing obfuscation. Send your best (or other) wishes to him ]:-)
217  */
218 static unsigned int obfuscate_tx_buffer(const __u8 * buf_cleartext,
219                                         unsigned int len_cleartext,
220                                         __u8 * buf_xoredtext,
221                                         unsigned int len_maxbuf)
222 {
223         unsigned int len_xoredtext;
224
225         /* Calculate required length with padding, check for necessary space */
226         len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10;
227         if (len_xoredtext <= len_maxbuf) {
228                 static const __u8 lookup_string[] = "wangshuofei19710";
229                 __u8 xor_mask;
230
231                 /* Unlike the WinXP driver, we *do* clear out the padding */
232                 memset(buf_xoredtext, 0, len_xoredtext);
233
234                 xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55;
235
236                 while (len_cleartext-- > 0) {
237                         *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask;
238                 }
239         } else {
240                 len_xoredtext = 0;
241         }
242         return len_xoredtext;
243 }
244
245 /* Callback transmission routine */
246 static void ks959_speed_irq(struct urb *urb)
247 {
248         /* unlink, shutdown, unplug, other nasties */
249         if (urb->status != 0) {
250                 dev_err(&urb->dev->dev,
251                         "ks959_speed_irq: urb asynchronously failed - %d\n",
252                         urb->status);
253         }
254 }
255
256 /* Send a control request to change speed of the dongle */
257 static int ks959_change_speed(struct ks959_cb *kingsun, unsigned speed)
258 {
259         static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400,
260                 57600, 115200, 576000, 1152000, 4000000, 0
261         };
262         int err;
263         unsigned int i;
264
265         if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL)
266                 return -ENOMEM;
267
268         /* Check that requested speed is among the supported ones */
269         for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ;
270         if (supported_speeds[i] == 0)
271                 return -EOPNOTSUPP;
272
273         memset(&(kingsun->speedparams), 0, sizeof(struct ks959_speedparams));
274         kingsun->speedparams.baudrate = cpu_to_le32(speed);
275         kingsun->speedparams.flags = KS_DATA_8_BITS;
276
277         /* speed_setuprequest pre-filled in ks959_probe */
278         usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev,
279                              usb_sndctrlpipe(kingsun->usbdev, 0),
280                              (unsigned char *)kingsun->speed_setuprequest,
281                              &(kingsun->speedparams),
282                              sizeof(struct ks959_speedparams), ks959_speed_irq,
283                              kingsun);
284         kingsun->speed_urb->status = 0;
285         err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC);
286
287         return err;
288 }
289
290 /* Submit one fragment of an IrDA frame to the dongle */
291 static void ks959_send_irq(struct urb *urb);
292 static int ks959_submit_tx_fragment(struct ks959_cb *kingsun)
293 {
294         unsigned int padlen;
295         unsigned int wraplen;
296         int ret;
297
298         /* Check whether current plaintext can produce a padded buffer that fits
299            within the range handled by the dongle */
300         wraplen = (KINGSUN_SND_PACKET_SIZE & ~0x7) - 0x10;
301         if (wraplen > kingsun->tx_buf_clear_used)
302                 wraplen = kingsun->tx_buf_clear_used;
303
304         /* Perform dongle obfuscation. Also remove the portion of the frame that
305            was just obfuscated and will now be sent to the dongle. */
306         padlen = obfuscate_tx_buffer(kingsun->tx_buf_clear, wraplen,
307                                      kingsun->tx_buf_xored,
308                                      KINGSUN_SND_PACKET_SIZE);
309
310         /* Calculate how much data can be transmitted in this urb */
311         kingsun->tx_setuprequest->wValue = cpu_to_le16(wraplen);
312         kingsun->tx_setuprequest->wLength = cpu_to_le16(padlen);
313         /* Rest of the fields were filled in ks959_probe */
314         usb_fill_control_urb(kingsun->tx_urb, kingsun->usbdev,
315                              usb_sndctrlpipe(kingsun->usbdev, 0),
316                              (unsigned char *)kingsun->tx_setuprequest,
317                              kingsun->tx_buf_xored, padlen,
318                              ks959_send_irq, kingsun);
319         kingsun->tx_urb->status = 0;
320         ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC);
321
322         /* Remember how much data was sent, in order to update at callback */
323         kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0;
324         return ret;
325 }
326
327 /* Callback transmission routine */
328 static void ks959_send_irq(struct urb *urb)
329 {
330         struct ks959_cb *kingsun = urb->context;
331         struct net_device *netdev = kingsun->netdev;
332         int ret = 0;
333
334         /* in process of stopping, just drop data */
335         if (!netif_running(kingsun->netdev)) {
336                 dev_err(&kingsun->usbdev->dev,
337                         "ks959_send_irq: Network not running!\n");
338                 return;
339         }
340
341         /* unlink, shutdown, unplug, other nasties */
342         if (urb->status != 0) {
343                 dev_err(&kingsun->usbdev->dev,
344                         "ks959_send_irq: urb asynchronously failed - %d\n",
345                         urb->status);
346                 return;
347         }
348
349         if (kingsun->tx_buf_clear_used > 0) {
350                 /* Update data remaining to be sent */
351                 if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) {
352                         memmove(kingsun->tx_buf_clear,
353                                 kingsun->tx_buf_clear +
354                                 kingsun->tx_buf_clear_sent,
355                                 kingsun->tx_buf_clear_used -
356                                 kingsun->tx_buf_clear_sent);
357                 }
358                 kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent;
359                 kingsun->tx_buf_clear_sent = 0;
360
361                 if (kingsun->tx_buf_clear_used > 0) {
362                         /* There is more data to be sent */
363                         if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
364                                 dev_err(&kingsun->usbdev->dev,
365                                         "ks959_send_irq: failed tx_urb submit: %d\n",
366                                         ret);
367                                 switch (ret) {
368                                 case -ENODEV:
369                                 case -EPIPE:
370                                         break;
371                                 default:
372                                         netdev->stats.tx_errors++;
373                                         netif_start_queue(netdev);
374                                 }
375                         }
376                 } else {
377                         /* All data sent, send next speed && wake network queue */
378                         if (kingsun->new_speed != -1 &&
379                             cpu_to_le32(kingsun->new_speed) !=
380                             kingsun->speedparams.baudrate)
381                                 ks959_change_speed(kingsun, kingsun->new_speed);
382
383                         netif_wake_queue(netdev);
384                 }
385         }
386 }
387
388 /*
389  * Called from net/core when new frame is available.
390  */
391 static netdev_tx_t ks959_hard_xmit(struct sk_buff *skb,
392                                          struct net_device *netdev)
393 {
394         struct ks959_cb *kingsun;
395         unsigned int wraplen;
396         int ret = 0;
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                 dev_err(&kingsun->usbdev->dev,
415                         "ks959_hard_xmit: failed tx_urb submit: %d\n", ret);
416                 switch (ret) {
417                 case -ENODEV:
418                 case -EPIPE:
419                         break;
420                 default:
421                         netdev->stats.tx_errors++;
422                         netif_start_queue(netdev);
423                 }
424         } else {
425                 netdev->stats.tx_packets++;
426                 netdev->stats.tx_bytes += skb->len;
427
428         }
429
430         dev_kfree_skb(skb);
431         spin_unlock(&kingsun->lock);
432
433         return NETDEV_TX_OK;
434 }
435
436 /* Receive callback function */
437 static void ks959_rcv_irq(struct urb *urb)
438 {
439         struct ks959_cb *kingsun = urb->context;
440         int ret;
441
442         /* in process of stopping, just drop data */
443         if (!netif_running(kingsun->netdev)) {
444                 kingsun->receiving = 0;
445                 return;
446         }
447
448         /* unlink, shutdown, unplug, other nasties */
449         if (urb->status != 0) {
450                 dev_err(&kingsun->usbdev->dev,
451                         "kingsun_rcv_irq: urb asynchronously failed - %d\n",
452                         urb->status);
453                 kingsun->receiving = 0;
454                 return;
455         }
456
457         if (urb->actual_length > 0) {
458                 __u8 *bytes = urb->transfer_buffer;
459                 unsigned int i;
460
461                 for (i = 0; i < urb->actual_length; i++) {
462                         /* De-obfuscation implemented here: variable portion of
463                            xormask is incremented, and then used with the encoded
464                            byte for the XOR. The result of the operation is used
465                            to unwrap the SIR frame. */
466                         kingsun->rx_variable_xormask++;
467                         bytes[i] =
468                             bytes[i] ^ kingsun->rx_variable_xormask ^ 0x55u;
469
470                         /* rx_variable_xormask doubles as an index counter so we
471                            can skip the byte at 0xff (wrapped around to 0).
472                          */
473                         if (kingsun->rx_variable_xormask != 0) {
474                                 async_unwrap_char(kingsun->netdev,
475                                                   &kingsun->netdev->stats,
476                                                   &kingsun->rx_unwrap_buff,
477                                                   bytes[i]);
478                         }
479                 }
480                 do_gettimeofday(&kingsun->rx_time);
481                 kingsun->receiving =
482                     (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
483         }
484
485         /* This urb has already been filled in kingsun_net_open. Setup
486            packet must be re-filled, but it is assumed that urb keeps the
487            pointer to the initial setup packet, as well as the payload buffer.
488            Setup packet is already pre-filled at ks959_probe.
489          */
490         urb->status = 0;
491         ret = usb_submit_urb(urb, GFP_ATOMIC);
492 }
493
494 /*
495  * Function kingsun_net_open (dev)
496  *
497  *    Network device is taken up. Usually this is done by "ifconfig irda0 up"
498  */
499 static int ks959_net_open(struct net_device *netdev)
500 {
501         struct ks959_cb *kingsun = netdev_priv(netdev);
502         int err = -ENOMEM;
503         char hwname[16];
504
505         /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */
506         kingsun->receiving = 0;
507
508         /* Initialize for SIR to copy data directly into skb.  */
509         kingsun->rx_unwrap_buff.in_frame = FALSE;
510         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
511         kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU;
512         kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
513         if (!kingsun->rx_unwrap_buff.skb)
514                 goto free_mem;
515
516         skb_reserve(kingsun->rx_unwrap_buff.skb, 1);
517         kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data;
518         do_gettimeofday(&kingsun->rx_time);
519
520         kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
521         if (!kingsun->rx_urb)
522                 goto free_mem;
523
524         kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
525         if (!kingsun->tx_urb)
526                 goto free_mem;
527
528         kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
529         if (!kingsun->speed_urb)
530                 goto free_mem;
531
532         /* Initialize speed for dongle */
533         kingsun->new_speed = 9600;
534         err = ks959_change_speed(kingsun, 9600);
535         if (err < 0)
536                 goto free_mem;
537
538         /*
539          * Now that everything should be initialized properly,
540          * Open new IrLAP layer instance to take care of us...
541          */
542         sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
543         kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
544         if (!kingsun->irlap) {
545                 err = -ENOMEM;
546                 dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
547                 goto free_mem;
548         }
549
550         /* Start reception. Setup request already pre-filled in ks959_probe */
551         usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev,
552                              usb_rcvctrlpipe(kingsun->usbdev, 0),
553                              (unsigned char *)kingsun->rx_setuprequest,
554                              kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE,
555                              ks959_rcv_irq, kingsun);
556         kingsun->rx_urb->status = 0;
557         err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
558         if (err) {
559                 dev_err(&kingsun->usbdev->dev,
560                         "first urb-submit failed: %d\n", err);
561                 goto close_irlap;
562         }
563
564         netif_start_queue(netdev);
565
566         /* Situation at this point:
567            - all work buffers allocated
568            - urbs allocated and ready to fill
569            - max rx packet known (in max_rx)
570            - unwrap state machine initialized, in state outside of any frame
571            - receive request in progress
572            - IrLAP layer started, about to hand over packets to send
573          */
574
575         return 0;
576
577       close_irlap:
578         irlap_close(kingsun->irlap);
579       free_mem:
580         usb_free_urb(kingsun->speed_urb);
581         kingsun->speed_urb = NULL;
582         usb_free_urb(kingsun->tx_urb);
583         kingsun->tx_urb = NULL;
584         usb_free_urb(kingsun->rx_urb);
585         kingsun->rx_urb = NULL;
586         if (kingsun->rx_unwrap_buff.skb) {
587                 kfree_skb(kingsun->rx_unwrap_buff.skb);
588                 kingsun->rx_unwrap_buff.skb = NULL;
589                 kingsun->rx_unwrap_buff.head = NULL;
590         }
591         return err;
592 }
593
594 /*
595  * Function kingsun_net_close (kingsun)
596  *
597  *    Network device is taken down. Usually this is done by
598  *    "ifconfig irda0 down"
599  */
600 static int ks959_net_close(struct net_device *netdev)
601 {
602         struct ks959_cb *kingsun = netdev_priv(netdev);
603
604         /* Stop transmit processing */
605         netif_stop_queue(netdev);
606
607         /* Mop up receive && transmit urb's */
608         usb_kill_urb(kingsun->tx_urb);
609         usb_free_urb(kingsun->tx_urb);
610         kingsun->tx_urb = NULL;
611
612         usb_kill_urb(kingsun->speed_urb);
613         usb_free_urb(kingsun->speed_urb);
614         kingsun->speed_urb = NULL;
615
616         usb_kill_urb(kingsun->rx_urb);
617         usb_free_urb(kingsun->rx_urb);
618         kingsun->rx_urb = NULL;
619
620         kfree_skb(kingsun->rx_unwrap_buff.skb);
621         kingsun->rx_unwrap_buff.skb = NULL;
622         kingsun->rx_unwrap_buff.head = NULL;
623         kingsun->rx_unwrap_buff.in_frame = FALSE;
624         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
625         kingsun->receiving = 0;
626
627         /* Stop and remove instance of IrLAP */
628         if (kingsun->irlap)
629                 irlap_close(kingsun->irlap);
630
631         kingsun->irlap = NULL;
632
633         return 0;
634 }
635
636 /*
637  * IOCTLs : Extra out-of-band network commands...
638  */
639 static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
640 {
641         struct if_irda_req *irq = (struct if_irda_req *)rq;
642         struct ks959_cb *kingsun = netdev_priv(netdev);
643         int ret = 0;
644
645         switch (cmd) {
646         case SIOCSBANDWIDTH:    /* Set bandwidth */
647                 if (!capable(CAP_NET_ADMIN))
648                         return -EPERM;
649
650                 /* Check if the device is still there */
651                 if (netif_device_present(kingsun->netdev))
652                         return ks959_change_speed(kingsun, irq->ifr_baudrate);
653                 break;
654
655         case SIOCSMEDIABUSY:    /* Set media busy */
656                 if (!capable(CAP_NET_ADMIN))
657                         return -EPERM;
658
659                 /* Check if the IrDA stack is still there */
660                 if (netif_running(kingsun->netdev))
661                         irda_device_set_media_busy(kingsun->netdev, TRUE);
662                 break;
663
664         case SIOCGRECEIVING:
665                 /* Only approximately true */
666                 irq->ifr_receiving = kingsun->receiving;
667                 break;
668
669         default:
670                 ret = -EOPNOTSUPP;
671         }
672
673         return ret;
674 }
675
676 static const struct net_device_ops ks959_ops = {
677         .ndo_start_xmit = ks959_hard_xmit,
678         .ndo_open       = ks959_net_open,
679         .ndo_stop       = ks959_net_close,
680         .ndo_do_ioctl   = ks959_net_ioctl,
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->netdev_ops = &ks959_ops;
795
796         ret = register_netdev(net);
797         if (ret != 0)
798                 goto free_mem;
799
800         dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n",
801                  net->name);
802
803         usb_set_intfdata(intf, kingsun);
804
805         /* Situation at this point:
806            - all work buffers allocated
807            - setup requests pre-filled
808            - urbs not allocated, set to NULL
809            - max rx packet known (is KINGSUN_FIFO_SIZE)
810            - unwrap state machine (partially) initialized, but skb == NULL
811          */
812
813         return 0;
814
815       free_mem:
816         kfree(kingsun->speed_setuprequest);
817         kfree(kingsun->tx_setuprequest);
818         kfree(kingsun->tx_buf_xored);
819         kfree(kingsun->tx_buf_clear);
820         kfree(kingsun->rx_setuprequest);
821         kfree(kingsun->rx_buf);
822         free_netdev(net);
823       err_out1:
824         return ret;
825 }
826
827 /*
828  * The current device is removed, the USB layer tell us to shut it down...
829  */
830 static void ks959_disconnect(struct usb_interface *intf)
831 {
832         struct ks959_cb *kingsun = usb_get_intfdata(intf);
833
834         if (!kingsun)
835                 return;
836
837         unregister_netdev(kingsun->netdev);
838
839         /* Mop up receive && transmit urb's */
840         if (kingsun->speed_urb != NULL) {
841                 usb_kill_urb(kingsun->speed_urb);
842                 usb_free_urb(kingsun->speed_urb);
843                 kingsun->speed_urb = NULL;
844         }
845         if (kingsun->tx_urb != NULL) {
846                 usb_kill_urb(kingsun->tx_urb);
847                 usb_free_urb(kingsun->tx_urb);
848                 kingsun->tx_urb = NULL;
849         }
850         if (kingsun->rx_urb != NULL) {
851                 usb_kill_urb(kingsun->rx_urb);
852                 usb_free_urb(kingsun->rx_urb);
853                 kingsun->rx_urb = NULL;
854         }
855
856         kfree(kingsun->speed_setuprequest);
857         kfree(kingsun->tx_setuprequest);
858         kfree(kingsun->tx_buf_xored);
859         kfree(kingsun->tx_buf_clear);
860         kfree(kingsun->rx_setuprequest);
861         kfree(kingsun->rx_buf);
862         free_netdev(kingsun->netdev);
863
864         usb_set_intfdata(intf, NULL);
865 }
866
867 #ifdef CONFIG_PM
868 /* USB suspend, so power off the transmitter/receiver */
869 static int ks959_suspend(struct usb_interface *intf, pm_message_t message)
870 {
871         struct ks959_cb *kingsun = usb_get_intfdata(intf);
872
873         netif_device_detach(kingsun->netdev);
874         if (kingsun->speed_urb != NULL)
875                 usb_kill_urb(kingsun->speed_urb);
876         if (kingsun->tx_urb != NULL)
877                 usb_kill_urb(kingsun->tx_urb);
878         if (kingsun->rx_urb != NULL)
879                 usb_kill_urb(kingsun->rx_urb);
880         return 0;
881 }
882
883 /* Coming out of suspend, so reset hardware */
884 static int ks959_resume(struct usb_interface *intf)
885 {
886         struct ks959_cb *kingsun = usb_get_intfdata(intf);
887
888         if (kingsun->rx_urb != NULL) {
889                 /* Setup request already filled in ks959_probe */
890                 usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
891         }
892         netif_device_attach(kingsun->netdev);
893
894         return 0;
895 }
896 #endif
897
898 /*
899  * USB device callbacks
900  */
901 static struct usb_driver irda_driver = {
902         .name = "ks959-sir",
903         .probe = ks959_probe,
904         .disconnect = ks959_disconnect,
905         .id_table = dongles,
906 #ifdef CONFIG_PM
907         .suspend = ks959_suspend,
908         .resume = ks959_resume,
909 #endif
910 };
911
912 module_usb_driver(irda_driver);
913
914 MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>");
915 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun KS-959");
916 MODULE_LICENSE("GPL");