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  */
obfuscate_tx_buffer(const __u8 * buf_cleartext,unsigned int len_cleartext,__u8 * buf_xoredtext,unsigned int len_maxbuf)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 */
ks959_speed_irq(struct urb * urb)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 */
ks959_change_speed(struct ks959_cb * kingsun,unsigned speed)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);
ks959_submit_tx_fragment(struct ks959_cb * kingsun)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 */
ks959_send_irq(struct urb * urb)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  */
ks959_hard_xmit(struct sk_buff * skb,struct net_device * netdev)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 */
ks959_rcv_irq(struct urb * urb)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  */
ks959_net_open(struct net_device * netdev)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  */
ks959_net_close(struct net_device * netdev)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  */
ks959_net_ioctl(struct net_device * netdev,struct ifreq * rq,int cmd)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  */
ks959_probe(struct usb_interface * intf,const struct usb_device_id * id)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  */
ks959_disconnect(struct usb_interface * intf)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 */
ks959_suspend(struct usb_interface * intf,pm_message_t message)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 */
ks959_resume(struct usb_interface * intf)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");
913