Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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/slab.h>
120 #include <linux/usb.h>
121 #include <linux/device.h>
122 #include <linux/crc32.h>
123
124 #include <asm/unaligned.h>
125 #include <asm/byteorder.h>
126 #include <asm/uaccess.h>
127
128 #include <net/irda/irda.h>
129 #include <net/irda/wrapper.h>
130 #include <net/irda/crc.h>
131
132 #define KS959_VENDOR_ID 0x07d0
133 #define KS959_PRODUCT_ID 0x4959
134
135 /* These are the currently known USB ids */
136 static struct usb_device_id dongles[] = {
137         /* KingSun Co,Ltd  IrDA/USB Bridge */
138         {USB_DEVICE(KS959_VENDOR_ID, KS959_PRODUCT_ID)},
139         {}
140 };
141
142 MODULE_DEVICE_TABLE(usb, dongles);
143
144 #define KINGSUN_MTT 0x07
145 #define KINGSUN_REQ_RECV 0x01
146 #define KINGSUN_REQ_SEND 0x09
147
148 #define KINGSUN_RCV_FIFO_SIZE    2048   /* Max length we can receive */
149 #define KINGSUN_SND_FIFO_SIZE    2048   /* Max packet we can send */
150 #define KINGSUN_SND_PACKET_SIZE    256  /* Max packet dongle can handle */
151
152 struct ks959_speedparams {
153         __le32 baudrate;        /* baud rate, little endian */
154         __u8 flags;
155         __u8 reserved[3];
156 } __packed;
157
158 #define KS_DATA_5_BITS 0x00
159 #define KS_DATA_6_BITS 0x01
160 #define KS_DATA_7_BITS 0x02
161 #define KS_DATA_8_BITS 0x03
162
163 #define KS_STOP_BITS_1 0x00
164 #define KS_STOP_BITS_2 0x08
165
166 #define KS_PAR_DISABLE    0x00
167 #define KS_PAR_EVEN    0x10
168 #define KS_PAR_ODD    0x30
169 #define KS_RESET    0x80
170
171 struct ks959_cb {
172         struct usb_device *usbdev;      /* init: probe_irda */
173         struct net_device *netdev;      /* network layer */
174         struct irlap_cb *irlap; /* The link layer we are binded to */
175
176         struct qos_info qos;
177
178         struct usb_ctrlrequest *tx_setuprequest;
179         struct urb *tx_urb;
180         __u8 *tx_buf_clear;
181         unsigned int tx_buf_clear_used;
182         unsigned int tx_buf_clear_sent;
183         __u8 *tx_buf_xored;
184
185         struct usb_ctrlrequest *rx_setuprequest;
186         struct urb *rx_urb;
187         __u8 *rx_buf;
188         __u8 rx_variable_xormask;
189         iobuff_t rx_unwrap_buff;
190
191         struct usb_ctrlrequest *speed_setuprequest;
192         struct urb *speed_urb;
193         struct ks959_speedparams speedparams;
194         unsigned int new_speed;
195
196         spinlock_t lock;
197         int receiving;
198 };
199
200 /* Procedure to perform the obfuscation/padding expected by the dongle
201  *
202  * buf_cleartext    (IN) Cleartext version of the IrDA frame to transmit
203  * len_cleartext    (IN) Length of the cleartext version of IrDA frame
204  * buf_xoredtext    (OUT) Obfuscated version of frame built by proc
205  * len_maxbuf        (OUT) Maximum space available at buf_xoredtext
206  *
207  * (return)         length of obfuscated frame with padding
208  *
209  * If not enough space (as indicated by len_maxbuf vs. required padding),
210  * zero is returned
211  *
212  * The value of lookup_string is actually a required portion of the algorithm.
213  * Seems the designer of the dongle wanted to state who exactly is responsible
214  * for implementing obfuscation. Send your best (or other) wishes to him ]:-)
215  */
216 static unsigned int obfuscate_tx_buffer(const __u8 * buf_cleartext,
217                                         unsigned int len_cleartext,
218                                         __u8 * buf_xoredtext,
219                                         unsigned int len_maxbuf)
220 {
221         unsigned int len_xoredtext;
222
223         /* Calculate required length with padding, check for necessary space */
224         len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10;
225         if (len_xoredtext <= len_maxbuf) {
226                 static const __u8 lookup_string[] = "wangshuofei19710";
227                 __u8 xor_mask;
228
229                 /* Unlike the WinXP driver, we *do* clear out the padding */
230                 memset(buf_xoredtext, 0, len_xoredtext);
231
232                 xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55;
233
234                 while (len_cleartext-- > 0) {
235                         *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask;
236                 }
237         } else {
238                 len_xoredtext = 0;
239         }
240         return len_xoredtext;
241 }
242
243 /* Callback transmission routine */
244 static void ks959_speed_irq(struct urb *urb)
245 {
246         /* unlink, shutdown, unplug, other nasties */
247         if (urb->status != 0) {
248                 dev_err(&urb->dev->dev,
249                         "ks959_speed_irq: urb asynchronously failed - %d\n",
250                         urb->status);
251         }
252 }
253
254 /* Send a control request to change speed of the dongle */
255 static int ks959_change_speed(struct ks959_cb *kingsun, unsigned speed)
256 {
257         static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400,
258                 57600, 115200, 576000, 1152000, 4000000, 0
259         };
260         int err;
261         unsigned int i;
262
263         if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL)
264                 return -ENOMEM;
265
266         /* Check that requested speed is among the supported ones */
267         for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ;
268         if (supported_speeds[i] == 0)
269                 return -EOPNOTSUPP;
270
271         memset(&(kingsun->speedparams), 0, sizeof(struct ks959_speedparams));
272         kingsun->speedparams.baudrate = cpu_to_le32(speed);
273         kingsun->speedparams.flags = KS_DATA_8_BITS;
274
275         /* speed_setuprequest pre-filled in ks959_probe */
276         usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev,
277                              usb_sndctrlpipe(kingsun->usbdev, 0),
278                              (unsigned char *)kingsun->speed_setuprequest,
279                              &(kingsun->speedparams),
280                              sizeof(struct ks959_speedparams), ks959_speed_irq,
281                              kingsun);
282         kingsun->speed_urb->status = 0;
283         err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC);
284
285         return err;
286 }
287
288 /* Submit one fragment of an IrDA frame to the dongle */
289 static void ks959_send_irq(struct urb *urb);
290 static int ks959_submit_tx_fragment(struct ks959_cb *kingsun)
291 {
292         unsigned int padlen;
293         unsigned int wraplen;
294         int ret;
295
296         /* Check whether current plaintext can produce a padded buffer that fits
297            within the range handled by the dongle */
298         wraplen = (KINGSUN_SND_PACKET_SIZE & ~0x7) - 0x10;
299         if (wraplen > kingsun->tx_buf_clear_used)
300                 wraplen = kingsun->tx_buf_clear_used;
301
302         /* Perform dongle obfuscation. Also remove the portion of the frame that
303            was just obfuscated and will now be sent to the dongle. */
304         padlen = obfuscate_tx_buffer(kingsun->tx_buf_clear, wraplen,
305                                      kingsun->tx_buf_xored,
306                                      KINGSUN_SND_PACKET_SIZE);
307
308         /* Calculate how much data can be transmitted in this urb */
309         kingsun->tx_setuprequest->wValue = cpu_to_le16(wraplen);
310         kingsun->tx_setuprequest->wLength = cpu_to_le16(padlen);
311         /* Rest of the fields were filled in ks959_probe */
312         usb_fill_control_urb(kingsun->tx_urb, kingsun->usbdev,
313                              usb_sndctrlpipe(kingsun->usbdev, 0),
314                              (unsigned char *)kingsun->tx_setuprequest,
315                              kingsun->tx_buf_xored, padlen,
316                              ks959_send_irq, kingsun);
317         kingsun->tx_urb->status = 0;
318         ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC);
319
320         /* Remember how much data was sent, in order to update at callback */
321         kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0;
322         return ret;
323 }
324
325 /* Callback transmission routine */
326 static void ks959_send_irq(struct urb *urb)
327 {
328         struct ks959_cb *kingsun = urb->context;
329         struct net_device *netdev = kingsun->netdev;
330         int ret = 0;
331
332         /* in process of stopping, just drop data */
333         if (!netif_running(kingsun->netdev)) {
334                 dev_err(&kingsun->usbdev->dev,
335                         "ks959_send_irq: Network not running!\n");
336                 return;
337         }
338
339         /* unlink, shutdown, unplug, other nasties */
340         if (urb->status != 0) {
341                 dev_err(&kingsun->usbdev->dev,
342                         "ks959_send_irq: urb asynchronously failed - %d\n",
343                         urb->status);
344                 return;
345         }
346
347         if (kingsun->tx_buf_clear_used > 0) {
348                 /* Update data remaining to be sent */
349                 if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) {
350                         memmove(kingsun->tx_buf_clear,
351                                 kingsun->tx_buf_clear +
352                                 kingsun->tx_buf_clear_sent,
353                                 kingsun->tx_buf_clear_used -
354                                 kingsun->tx_buf_clear_sent);
355                 }
356                 kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent;
357                 kingsun->tx_buf_clear_sent = 0;
358
359                 if (kingsun->tx_buf_clear_used > 0) {
360                         /* There is more data to be sent */
361                         if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
362                                 dev_err(&kingsun->usbdev->dev,
363                                         "ks959_send_irq: failed tx_urb submit: %d\n",
364                                         ret);
365                                 switch (ret) {
366                                 case -ENODEV:
367                                 case -EPIPE:
368                                         break;
369                                 default:
370                                         netdev->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 netdev_tx_t ks959_hard_xmit(struct sk_buff *skb,
390                                          struct net_device *netdev)
391 {
392         struct ks959_cb *kingsun;
393         unsigned int wraplen;
394         int ret = 0;
395
396         netif_stop_queue(netdev);
397
398         /* the IRDA wrapping routines don't deal with non linear skb */
399         SKB_LINEAR_ASSERT(skb);
400
401         kingsun = netdev_priv(netdev);
402
403         spin_lock(&kingsun->lock);
404         kingsun->new_speed = irda_get_next_speed(skb);
405
406         /* Append data to the end of whatever data remains to be transmitted */
407         wraplen =
408             async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE);
409         kingsun->tx_buf_clear_used = wraplen;
410
411         if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
412                 dev_err(&kingsun->usbdev->dev,
413                         "ks959_hard_xmit: failed tx_urb submit: %d\n", ret);
414                 switch (ret) {
415                 case -ENODEV:
416                 case -EPIPE:
417                         break;
418                 default:
419                         netdev->stats.tx_errors++;
420                         netif_start_queue(netdev);
421                 }
422         } else {
423                 netdev->stats.tx_packets++;
424                 netdev->stats.tx_bytes += skb->len;
425
426         }
427
428         dev_kfree_skb(skb);
429         spin_unlock(&kingsun->lock);
430
431         return NETDEV_TX_OK;
432 }
433
434 /* Receive callback function */
435 static void ks959_rcv_irq(struct urb *urb)
436 {
437         struct ks959_cb *kingsun = urb->context;
438         int ret;
439
440         /* in process of stopping, just drop data */
441         if (!netif_running(kingsun->netdev)) {
442                 kingsun->receiving = 0;
443                 return;
444         }
445
446         /* unlink, shutdown, unplug, other nasties */
447         if (urb->status != 0) {
448                 dev_err(&kingsun->usbdev->dev,
449                         "kingsun_rcv_irq: urb asynchronously failed - %d\n",
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->netdev->stats,
474                                                   &kingsun->rx_unwrap_buff,
475                                                   bytes[i]);
476                         }
477                 }
478                 kingsun->receiving =
479                     (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
480         }
481
482         /* This urb has already been filled in kingsun_net_open. Setup
483            packet must be re-filled, but it is assumed that urb keeps the
484            pointer to the initial setup packet, as well as the payload buffer.
485            Setup packet is already pre-filled at ks959_probe.
486          */
487         urb->status = 0;
488         ret = usb_submit_urb(urb, GFP_ATOMIC);
489 }
490
491 /*
492  * Function kingsun_net_open (dev)
493  *
494  *    Network device is taken up. Usually this is done by "ifconfig irda0 up"
495  */
496 static int ks959_net_open(struct net_device *netdev)
497 {
498         struct ks959_cb *kingsun = netdev_priv(netdev);
499         int err = -ENOMEM;
500         char hwname[16];
501
502         /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */
503         kingsun->receiving = 0;
504
505         /* Initialize for SIR to copy data directly into skb.  */
506         kingsun->rx_unwrap_buff.in_frame = FALSE;
507         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
508         kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU;
509         kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
510         if (!kingsun->rx_unwrap_buff.skb)
511                 goto free_mem;
512
513         skb_reserve(kingsun->rx_unwrap_buff.skb, 1);
514         kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data;
515
516         kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
517         if (!kingsun->rx_urb)
518                 goto free_mem;
519
520         kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
521         if (!kingsun->tx_urb)
522                 goto free_mem;
523
524         kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
525         if (!kingsun->speed_urb)
526                 goto free_mem;
527
528         /* Initialize speed for dongle */
529         kingsun->new_speed = 9600;
530         err = ks959_change_speed(kingsun, 9600);
531         if (err < 0)
532                 goto free_mem;
533
534         /*
535          * Now that everything should be initialized properly,
536          * Open new IrLAP layer instance to take care of us...
537          */
538         sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
539         kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
540         if (!kingsun->irlap) {
541                 err = -ENOMEM;
542                 dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
543                 goto free_mem;
544         }
545
546         /* Start reception. Setup request already pre-filled in ks959_probe */
547         usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev,
548                              usb_rcvctrlpipe(kingsun->usbdev, 0),
549                              (unsigned char *)kingsun->rx_setuprequest,
550                              kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE,
551                              ks959_rcv_irq, kingsun);
552         kingsun->rx_urb->status = 0;
553         err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
554         if (err) {
555                 dev_err(&kingsun->usbdev->dev,
556                         "first urb-submit failed: %d\n", err);
557                 goto close_irlap;
558         }
559
560         netif_start_queue(netdev);
561
562         /* Situation at this point:
563            - all work buffers allocated
564            - urbs allocated and ready to fill
565            - max rx packet known (in max_rx)
566            - unwrap state machine initialized, in state outside of any frame
567            - receive request in progress
568            - IrLAP layer started, about to hand over packets to send
569          */
570
571         return 0;
572
573       close_irlap:
574         irlap_close(kingsun->irlap);
575       free_mem:
576         usb_free_urb(kingsun->speed_urb);
577         kingsun->speed_urb = NULL;
578         usb_free_urb(kingsun->tx_urb);
579         kingsun->tx_urb = NULL;
580         usb_free_urb(kingsun->rx_urb);
581         kingsun->rx_urb = NULL;
582         if (kingsun->rx_unwrap_buff.skb) {
583                 kfree_skb(kingsun->rx_unwrap_buff.skb);
584                 kingsun->rx_unwrap_buff.skb = NULL;
585                 kingsun->rx_unwrap_buff.head = NULL;
586         }
587         return err;
588 }
589
590 /*
591  * Function kingsun_net_close (kingsun)
592  *
593  *    Network device is taken down. Usually this is done by
594  *    "ifconfig irda0 down"
595  */
596 static int ks959_net_close(struct net_device *netdev)
597 {
598         struct ks959_cb *kingsun = netdev_priv(netdev);
599
600         /* Stop transmit processing */
601         netif_stop_queue(netdev);
602
603         /* Mop up receive && transmit urb's */
604         usb_kill_urb(kingsun->tx_urb);
605         usb_free_urb(kingsun->tx_urb);
606         kingsun->tx_urb = NULL;
607
608         usb_kill_urb(kingsun->speed_urb);
609         usb_free_urb(kingsun->speed_urb);
610         kingsun->speed_urb = NULL;
611
612         usb_kill_urb(kingsun->rx_urb);
613         usb_free_urb(kingsun->rx_urb);
614         kingsun->rx_urb = NULL;
615
616         kfree_skb(kingsun->rx_unwrap_buff.skb);
617         kingsun->rx_unwrap_buff.skb = NULL;
618         kingsun->rx_unwrap_buff.head = NULL;
619         kingsun->rx_unwrap_buff.in_frame = FALSE;
620         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
621         kingsun->receiving = 0;
622
623         /* Stop and remove instance of IrLAP */
624         if (kingsun->irlap)
625                 irlap_close(kingsun->irlap);
626
627         kingsun->irlap = NULL;
628
629         return 0;
630 }
631
632 /*
633  * IOCTLs : Extra out-of-band network commands...
634  */
635 static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
636 {
637         struct if_irda_req *irq = (struct if_irda_req *)rq;
638         struct ks959_cb *kingsun = netdev_priv(netdev);
639         int ret = 0;
640
641         switch (cmd) {
642         case SIOCSBANDWIDTH:    /* Set bandwidth */
643                 if (!capable(CAP_NET_ADMIN))
644                         return -EPERM;
645
646                 /* Check if the device is still there */
647                 if (netif_device_present(kingsun->netdev))
648                         return ks959_change_speed(kingsun, irq->ifr_baudrate);
649                 break;
650
651         case SIOCSMEDIABUSY:    /* Set media busy */
652                 if (!capable(CAP_NET_ADMIN))
653                         return -EPERM;
654
655                 /* Check if the IrDA stack is still there */
656                 if (netif_running(kingsun->netdev))
657                         irda_device_set_media_busy(kingsun->netdev, TRUE);
658                 break;
659
660         case SIOCGRECEIVING:
661                 /* Only approximately true */
662                 irq->ifr_receiving = kingsun->receiving;
663                 break;
664
665         default:
666                 ret = -EOPNOTSUPP;
667         }
668
669         return ret;
670 }
671
672 static const struct net_device_ops ks959_ops = {
673         .ndo_start_xmit = ks959_hard_xmit,
674         .ndo_open       = ks959_net_open,
675         .ndo_stop       = ks959_net_close,
676         .ndo_do_ioctl   = ks959_net_ioctl,
677 };
678 /*
679  * This routine is called by the USB subsystem for each new device
680  * in the system. We need to check if the device is ours, and in
681  * this case start handling it.
682  */
683 static int ks959_probe(struct usb_interface *intf,
684                        const struct usb_device_id *id)
685 {
686         struct usb_device *dev = interface_to_usbdev(intf);
687         struct ks959_cb *kingsun = NULL;
688         struct net_device *net = NULL;
689         int ret = -ENOMEM;
690
691         /* Allocate network device container. */
692         net = alloc_irdadev(sizeof(*kingsun));
693         if (!net)
694                 goto err_out1;
695
696         SET_NETDEV_DEV(net, &intf->dev);
697         kingsun = netdev_priv(net);
698         kingsun->netdev = net;
699         kingsun->usbdev = dev;
700         kingsun->irlap = NULL;
701         kingsun->tx_setuprequest = NULL;
702         kingsun->tx_urb = NULL;
703         kingsun->tx_buf_clear = NULL;
704         kingsun->tx_buf_xored = NULL;
705         kingsun->tx_buf_clear_used = 0;
706         kingsun->tx_buf_clear_sent = 0;
707
708         kingsun->rx_setuprequest = NULL;
709         kingsun->rx_urb = NULL;
710         kingsun->rx_buf = NULL;
711         kingsun->rx_variable_xormask = 0;
712         kingsun->rx_unwrap_buff.in_frame = FALSE;
713         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
714         kingsun->rx_unwrap_buff.skb = NULL;
715         kingsun->receiving = 0;
716         spin_lock_init(&kingsun->lock);
717
718         kingsun->speed_setuprequest = NULL;
719         kingsun->speed_urb = NULL;
720         kingsun->speedparams.baudrate = 0;
721
722         /* Allocate input buffer */
723         kingsun->rx_buf = kmalloc(KINGSUN_RCV_FIFO_SIZE, GFP_KERNEL);
724         if (!kingsun->rx_buf)
725                 goto free_mem;
726
727         /* Allocate input setup packet */
728         kingsun->rx_setuprequest =
729             kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
730         if (!kingsun->rx_setuprequest)
731                 goto free_mem;
732         kingsun->rx_setuprequest->bRequestType =
733             USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
734         kingsun->rx_setuprequest->bRequest = KINGSUN_REQ_RECV;
735         kingsun->rx_setuprequest->wValue = cpu_to_le16(0x0200);
736         kingsun->rx_setuprequest->wIndex = 0;
737         kingsun->rx_setuprequest->wLength = cpu_to_le16(KINGSUN_RCV_FIFO_SIZE);
738
739         /* Allocate output buffer */
740         kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL);
741         if (!kingsun->tx_buf_clear)
742                 goto free_mem;
743         kingsun->tx_buf_xored = kmalloc(KINGSUN_SND_PACKET_SIZE, GFP_KERNEL);
744         if (!kingsun->tx_buf_xored)
745                 goto free_mem;
746
747         /* Allocate and initialize output setup packet */
748         kingsun->tx_setuprequest =
749             kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
750         if (!kingsun->tx_setuprequest)
751                 goto free_mem;
752         kingsun->tx_setuprequest->bRequestType =
753             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
754         kingsun->tx_setuprequest->bRequest = KINGSUN_REQ_SEND;
755         kingsun->tx_setuprequest->wValue = 0;
756         kingsun->tx_setuprequest->wIndex = 0;
757         kingsun->tx_setuprequest->wLength = 0;
758
759         /* Allocate and initialize speed setup packet */
760         kingsun->speed_setuprequest =
761             kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
762         if (!kingsun->speed_setuprequest)
763                 goto free_mem;
764         kingsun->speed_setuprequest->bRequestType =
765             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
766         kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND;
767         kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200);
768         kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001);
769         kingsun->speed_setuprequest->wLength =
770             cpu_to_le16(sizeof(struct ks959_speedparams));
771
772         printk(KERN_INFO "KingSun KS-959 IRDA/USB found at address %d, "
773                "Vendor: %x, Product: %x\n",
774                dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
775                le16_to_cpu(dev->descriptor.idProduct));
776
777         /* Initialize QoS for this device */
778         irda_init_max_qos_capabilies(&kingsun->qos);
779
780         /* Baud rates known to be supported. Please uncomment if devices (other
781            than a SonyEriccson K300 phone) can be shown to support higher speed
782            with this dongle.
783          */
784         kingsun->qos.baud_rate.bits =
785             IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600;
786         kingsun->qos.min_turn_time.bits &= KINGSUN_MTT;
787         irda_qos_bits_to_value(&kingsun->qos);
788
789         /* Override the network functions we need to use */
790         net->netdev_ops = &ks959_ops;
791
792         ret = register_netdev(net);
793         if (ret != 0)
794                 goto free_mem;
795
796         dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n",
797                  net->name);
798
799         usb_set_intfdata(intf, kingsun);
800
801         /* Situation at this point:
802            - all work buffers allocated
803            - setup requests pre-filled
804            - urbs not allocated, set to NULL
805            - max rx packet known (is KINGSUN_FIFO_SIZE)
806            - unwrap state machine (partially) initialized, but skb == NULL
807          */
808
809         return 0;
810
811       free_mem:
812         kfree(kingsun->speed_setuprequest);
813         kfree(kingsun->tx_setuprequest);
814         kfree(kingsun->tx_buf_xored);
815         kfree(kingsun->tx_buf_clear);
816         kfree(kingsun->rx_setuprequest);
817         kfree(kingsun->rx_buf);
818         free_netdev(net);
819       err_out1:
820         return ret;
821 }
822
823 /*
824  * The current device is removed, the USB layer tell us to shut it down...
825  */
826 static void ks959_disconnect(struct usb_interface *intf)
827 {
828         struct ks959_cb *kingsun = usb_get_intfdata(intf);
829
830         if (!kingsun)
831                 return;
832
833         unregister_netdev(kingsun->netdev);
834
835         /* Mop up receive && transmit urb's */
836         if (kingsun->speed_urb != NULL) {
837                 usb_kill_urb(kingsun->speed_urb);
838                 usb_free_urb(kingsun->speed_urb);
839                 kingsun->speed_urb = NULL;
840         }
841         if (kingsun->tx_urb != NULL) {
842                 usb_kill_urb(kingsun->tx_urb);
843                 usb_free_urb(kingsun->tx_urb);
844                 kingsun->tx_urb = NULL;
845         }
846         if (kingsun->rx_urb != NULL) {
847                 usb_kill_urb(kingsun->rx_urb);
848                 usb_free_urb(kingsun->rx_urb);
849                 kingsun->rx_urb = NULL;
850         }
851
852         kfree(kingsun->speed_setuprequest);
853         kfree(kingsun->tx_setuprequest);
854         kfree(kingsun->tx_buf_xored);
855         kfree(kingsun->tx_buf_clear);
856         kfree(kingsun->rx_setuprequest);
857         kfree(kingsun->rx_buf);
858         free_netdev(kingsun->netdev);
859
860         usb_set_intfdata(intf, NULL);
861 }
862
863 #ifdef CONFIG_PM
864 /* USB suspend, so power off the transmitter/receiver */
865 static int ks959_suspend(struct usb_interface *intf, pm_message_t message)
866 {
867         struct ks959_cb *kingsun = usb_get_intfdata(intf);
868
869         netif_device_detach(kingsun->netdev);
870         if (kingsun->speed_urb != NULL)
871                 usb_kill_urb(kingsun->speed_urb);
872         if (kingsun->tx_urb != NULL)
873                 usb_kill_urb(kingsun->tx_urb);
874         if (kingsun->rx_urb != NULL)
875                 usb_kill_urb(kingsun->rx_urb);
876         return 0;
877 }
878
879 /* Coming out of suspend, so reset hardware */
880 static int ks959_resume(struct usb_interface *intf)
881 {
882         struct ks959_cb *kingsun = usb_get_intfdata(intf);
883
884         if (kingsun->rx_urb != NULL) {
885                 /* Setup request already filled in ks959_probe */
886                 usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
887         }
888         netif_device_attach(kingsun->netdev);
889
890         return 0;
891 }
892 #endif
893
894 /*
895  * USB device callbacks
896  */
897 static struct usb_driver irda_driver = {
898         .name = "ks959-sir",
899         .probe = ks959_probe,
900         .disconnect = ks959_disconnect,
901         .id_table = dongles,
902 #ifdef CONFIG_PM
903         .suspend = ks959_suspend,
904         .resume = ks959_resume,
905 #endif
906 };
907
908 module_usb_driver(irda_driver);
909
910 MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>");
911 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun KS-959");
912 MODULE_LICENSE("GPL");