1 | /* |
2 | * |
3 | * A driver for Nokia Connectivity Card DTL-1 devices |
4 | * |
5 | * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org> |
6 | * |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation; |
11 | * |
12 | * Software distributed under the License is distributed on an "AS |
13 | * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
14 | * implied. See the License for the specific language governing |
15 | * rights and limitations under the License. |
16 | * |
17 | * The initial developer of the original code is David A. Hinds |
18 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds |
19 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. |
20 | * |
21 | */ |
22 | |
23 | #include <linux/module.h> |
24 | |
25 | #include <linux/kernel.h> |
26 | #include <linux/init.h> |
27 | #include <linux/slab.h> |
28 | #include <linux/types.h> |
29 | #include <linux/delay.h> |
30 | #include <linux/errno.h> |
31 | #include <linux/ptrace.h> |
32 | #include <linux/ioport.h> |
33 | #include <linux/spinlock.h> |
34 | #include <linux/moduleparam.h> |
35 | |
36 | #include <linux/skbuff.h> |
37 | #include <linux/string.h> |
38 | #include <linux/serial.h> |
39 | #include <linux/serial_reg.h> |
40 | #include <linux/bitops.h> |
41 | #include <asm/io.h> |
42 | |
43 | #include <pcmcia/cistpl.h> |
44 | #include <pcmcia/ciscode.h> |
45 | #include <pcmcia/ds.h> |
46 | #include <pcmcia/cisreg.h> |
47 | |
48 | #include <net/bluetooth/bluetooth.h> |
49 | #include <net/bluetooth/hci_core.h> |
50 | |
51 | |
52 | |
53 | /* ======================== Module parameters ======================== */ |
54 | |
55 | |
56 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>" ); |
57 | MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1" ); |
58 | MODULE_LICENSE("GPL" ); |
59 | |
60 | |
61 | |
62 | /* ======================== Local structures ======================== */ |
63 | |
64 | |
65 | struct dtl1_info { |
66 | struct pcmcia_device *p_dev; |
67 | |
68 | struct hci_dev *hdev; |
69 | |
70 | spinlock_t lock; /* For serializing operations */ |
71 | |
72 | unsigned long flowmask; /* HCI flow mask */ |
73 | int ri_latch; |
74 | |
75 | struct sk_buff_head txq; |
76 | unsigned long tx_state; |
77 | |
78 | unsigned long rx_state; |
79 | unsigned long rx_count; |
80 | struct sk_buff *rx_skb; |
81 | }; |
82 | |
83 | |
84 | static int dtl1_config(struct pcmcia_device *link); |
85 | |
86 | |
87 | /* Transmit states */ |
88 | #define XMIT_SENDING 1 |
89 | #define XMIT_WAKEUP 2 |
90 | #define XMIT_WAITING 8 |
91 | |
92 | /* Receiver States */ |
93 | #define RECV_WAIT_NSH 0 |
94 | #define RECV_WAIT_DATA 1 |
95 | |
96 | |
97 | struct nsh { |
98 | u8 type; |
99 | u8 zero; |
100 | u16 len; |
101 | } __packed; /* Nokia Specific Header */ |
102 | |
103 | #define NSHL 4 /* Nokia Specific Header Length */ |
104 | |
105 | |
106 | |
107 | /* ======================== Interrupt handling ======================== */ |
108 | |
109 | |
110 | static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) |
111 | { |
112 | int actual = 0; |
113 | |
114 | /* Tx FIFO should be empty */ |
115 | if (!(inb(port: iobase + UART_LSR) & UART_LSR_THRE)) |
116 | return 0; |
117 | |
118 | /* Fill FIFO with current frame */ |
119 | while ((fifo_size-- > 0) && (actual < len)) { |
120 | /* Transmit next byte */ |
121 | outb(value: buf[actual], port: iobase + UART_TX); |
122 | actual++; |
123 | } |
124 | |
125 | return actual; |
126 | } |
127 | |
128 | |
129 | static void dtl1_write_wakeup(struct dtl1_info *info) |
130 | { |
131 | if (!info) { |
132 | BT_ERR("Unknown device" ); |
133 | return; |
134 | } |
135 | |
136 | if (test_bit(XMIT_WAITING, &(info->tx_state))) { |
137 | set_bit(XMIT_WAKEUP, addr: &(info->tx_state)); |
138 | return; |
139 | } |
140 | |
141 | if (test_and_set_bit(XMIT_SENDING, addr: &(info->tx_state))) { |
142 | set_bit(XMIT_WAKEUP, addr: &(info->tx_state)); |
143 | return; |
144 | } |
145 | |
146 | do { |
147 | unsigned int iobase = info->p_dev->resource[0]->start; |
148 | register struct sk_buff *skb; |
149 | int len; |
150 | |
151 | clear_bit(XMIT_WAKEUP, addr: &(info->tx_state)); |
152 | |
153 | if (!pcmcia_dev_present(p_dev: info->p_dev)) |
154 | return; |
155 | |
156 | skb = skb_dequeue(list: &(info->txq)); |
157 | if (!skb) |
158 | break; |
159 | |
160 | /* Send frame */ |
161 | len = dtl1_write(iobase, fifo_size: 32, buf: skb->data, len: skb->len); |
162 | |
163 | if (len == skb->len) { |
164 | set_bit(XMIT_WAITING, addr: &(info->tx_state)); |
165 | kfree_skb(skb); |
166 | } else { |
167 | skb_pull(skb, len); |
168 | skb_queue_head(list: &(info->txq), newsk: skb); |
169 | } |
170 | |
171 | info->hdev->stat.byte_tx += len; |
172 | |
173 | } while (test_bit(XMIT_WAKEUP, &(info->tx_state))); |
174 | |
175 | clear_bit(XMIT_SENDING, addr: &(info->tx_state)); |
176 | } |
177 | |
178 | |
179 | static void dtl1_control(struct dtl1_info *info, struct sk_buff *skb) |
180 | { |
181 | u8 flowmask = *(u8 *)skb->data; |
182 | int i; |
183 | |
184 | printk(KERN_INFO "Bluetooth: Nokia control data =" ); |
185 | for (i = 0; i < skb->len; i++) |
186 | printk(" %02x" , skb->data[i]); |
187 | |
188 | printk("\n" ); |
189 | |
190 | /* transition to active state */ |
191 | if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) { |
192 | clear_bit(XMIT_WAITING, addr: &(info->tx_state)); |
193 | dtl1_write_wakeup(info); |
194 | } |
195 | |
196 | info->flowmask = flowmask; |
197 | |
198 | kfree_skb(skb); |
199 | } |
200 | |
201 | |
202 | static void dtl1_receive(struct dtl1_info *info) |
203 | { |
204 | unsigned int iobase; |
205 | struct nsh *nsh; |
206 | int boguscount = 0; |
207 | |
208 | if (!info) { |
209 | BT_ERR("Unknown device" ); |
210 | return; |
211 | } |
212 | |
213 | iobase = info->p_dev->resource[0]->start; |
214 | |
215 | do { |
216 | info->hdev->stat.byte_rx++; |
217 | |
218 | /* Allocate packet */ |
219 | if (info->rx_skb == NULL) { |
220 | info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); |
221 | if (!info->rx_skb) { |
222 | BT_ERR("Can't allocate mem for new packet" ); |
223 | info->rx_state = RECV_WAIT_NSH; |
224 | info->rx_count = NSHL; |
225 | return; |
226 | } |
227 | } |
228 | |
229 | skb_put_u8(skb: info->rx_skb, inb(port: iobase + UART_RX)); |
230 | nsh = (struct nsh *)info->rx_skb->data; |
231 | |
232 | info->rx_count--; |
233 | |
234 | if (info->rx_count == 0) { |
235 | |
236 | switch (info->rx_state) { |
237 | case RECV_WAIT_NSH: |
238 | info->rx_state = RECV_WAIT_DATA; |
239 | info->rx_count = nsh->len + (nsh->len & 0x0001); |
240 | break; |
241 | case RECV_WAIT_DATA: |
242 | hci_skb_pkt_type(info->rx_skb) = nsh->type; |
243 | |
244 | /* remove PAD byte if it exists */ |
245 | if (nsh->len & 0x0001) { |
246 | info->rx_skb->tail--; |
247 | info->rx_skb->len--; |
248 | } |
249 | |
250 | /* remove NSH */ |
251 | skb_pull(skb: info->rx_skb, NSHL); |
252 | |
253 | switch (hci_skb_pkt_type(info->rx_skb)) { |
254 | case 0x80: |
255 | /* control data for the Nokia Card */ |
256 | dtl1_control(info, skb: info->rx_skb); |
257 | break; |
258 | case 0x82: |
259 | case 0x83: |
260 | case 0x84: |
261 | /* send frame to the HCI layer */ |
262 | hci_skb_pkt_type(info->rx_skb) &= 0x0f; |
263 | hci_recv_frame(hdev: info->hdev, skb: info->rx_skb); |
264 | break; |
265 | default: |
266 | /* unknown packet */ |
267 | BT_ERR("Unknown HCI packet with type 0x%02x received" , |
268 | hci_skb_pkt_type(info->rx_skb)); |
269 | kfree_skb(skb: info->rx_skb); |
270 | break; |
271 | } |
272 | |
273 | info->rx_state = RECV_WAIT_NSH; |
274 | info->rx_count = NSHL; |
275 | info->rx_skb = NULL; |
276 | break; |
277 | } |
278 | |
279 | } |
280 | |
281 | /* Make sure we don't stay here too long */ |
282 | if (boguscount++ > 32) |
283 | break; |
284 | |
285 | } while (inb(port: iobase + UART_LSR) & UART_LSR_DR); |
286 | } |
287 | |
288 | |
289 | static irqreturn_t dtl1_interrupt(int irq, void *dev_inst) |
290 | { |
291 | struct dtl1_info *info = dev_inst; |
292 | unsigned int iobase; |
293 | unsigned char msr; |
294 | int boguscount = 0; |
295 | int iir, lsr; |
296 | irqreturn_t r = IRQ_NONE; |
297 | |
298 | if (!info || !info->hdev) |
299 | /* our irq handler is shared */ |
300 | return IRQ_NONE; |
301 | |
302 | iobase = info->p_dev->resource[0]->start; |
303 | |
304 | spin_lock(lock: &(info->lock)); |
305 | |
306 | iir = inb(port: iobase + UART_IIR) & UART_IIR_ID; |
307 | while (iir) { |
308 | |
309 | r = IRQ_HANDLED; |
310 | /* Clear interrupt */ |
311 | lsr = inb(port: iobase + UART_LSR); |
312 | |
313 | switch (iir) { |
314 | case UART_IIR_RLSI: |
315 | BT_ERR("RLSI" ); |
316 | break; |
317 | case UART_IIR_RDI: |
318 | /* Receive interrupt */ |
319 | dtl1_receive(info); |
320 | break; |
321 | case UART_IIR_THRI: |
322 | if (lsr & UART_LSR_THRE) { |
323 | /* Transmitter ready for data */ |
324 | dtl1_write_wakeup(info); |
325 | } |
326 | break; |
327 | default: |
328 | BT_ERR("Unhandled IIR=%#x" , iir); |
329 | break; |
330 | } |
331 | |
332 | /* Make sure we don't stay here too long */ |
333 | if (boguscount++ > 100) |
334 | break; |
335 | |
336 | iir = inb(port: iobase + UART_IIR) & UART_IIR_ID; |
337 | |
338 | } |
339 | |
340 | msr = inb(port: iobase + UART_MSR); |
341 | |
342 | if (info->ri_latch ^ (msr & UART_MSR_RI)) { |
343 | info->ri_latch = msr & UART_MSR_RI; |
344 | clear_bit(XMIT_WAITING, addr: &(info->tx_state)); |
345 | dtl1_write_wakeup(info); |
346 | r = IRQ_HANDLED; |
347 | } |
348 | |
349 | spin_unlock(lock: &(info->lock)); |
350 | |
351 | return r; |
352 | } |
353 | |
354 | |
355 | |
356 | /* ======================== HCI interface ======================== */ |
357 | |
358 | |
359 | static int dtl1_hci_open(struct hci_dev *hdev) |
360 | { |
361 | return 0; |
362 | } |
363 | |
364 | |
365 | static int dtl1_hci_flush(struct hci_dev *hdev) |
366 | { |
367 | struct dtl1_info *info = hci_get_drvdata(hdev); |
368 | |
369 | /* Drop TX queue */ |
370 | skb_queue_purge(list: &(info->txq)); |
371 | |
372 | return 0; |
373 | } |
374 | |
375 | |
376 | static int dtl1_hci_close(struct hci_dev *hdev) |
377 | { |
378 | dtl1_hci_flush(hdev); |
379 | |
380 | return 0; |
381 | } |
382 | |
383 | |
384 | static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) |
385 | { |
386 | struct dtl1_info *info = hci_get_drvdata(hdev); |
387 | struct sk_buff *s; |
388 | struct nsh nsh; |
389 | |
390 | switch (hci_skb_pkt_type(skb)) { |
391 | case HCI_COMMAND_PKT: |
392 | hdev->stat.cmd_tx++; |
393 | nsh.type = 0x81; |
394 | break; |
395 | case HCI_ACLDATA_PKT: |
396 | hdev->stat.acl_tx++; |
397 | nsh.type = 0x82; |
398 | break; |
399 | case HCI_SCODATA_PKT: |
400 | hdev->stat.sco_tx++; |
401 | nsh.type = 0x83; |
402 | break; |
403 | default: |
404 | return -EILSEQ; |
405 | } |
406 | |
407 | nsh.zero = 0; |
408 | nsh.len = skb->len; |
409 | |
410 | s = bt_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC); |
411 | if (!s) |
412 | return -ENOMEM; |
413 | |
414 | skb_reserve(skb: s, NSHL); |
415 | skb_copy_from_linear_data(skb, to: skb_put(skb: s, len: skb->len), len: skb->len); |
416 | if (skb->len & 0x0001) |
417 | skb_put_u8(skb: s, val: 0); /* PAD */ |
418 | |
419 | /* Prepend skb with Nokia frame header and queue */ |
420 | memcpy(skb_push(s, NSHL), &nsh, NSHL); |
421 | skb_queue_tail(list: &(info->txq), newsk: s); |
422 | |
423 | dtl1_write_wakeup(info); |
424 | |
425 | kfree_skb(skb); |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | |
431 | |
432 | /* ======================== Card services HCI interaction ======================== */ |
433 | |
434 | |
435 | static int dtl1_open(struct dtl1_info *info) |
436 | { |
437 | unsigned long flags; |
438 | unsigned int iobase = info->p_dev->resource[0]->start; |
439 | struct hci_dev *hdev; |
440 | |
441 | spin_lock_init(&(info->lock)); |
442 | |
443 | skb_queue_head_init(list: &(info->txq)); |
444 | |
445 | info->rx_state = RECV_WAIT_NSH; |
446 | info->rx_count = NSHL; |
447 | info->rx_skb = NULL; |
448 | |
449 | set_bit(XMIT_WAITING, addr: &(info->tx_state)); |
450 | |
451 | /* Initialize HCI device */ |
452 | hdev = hci_alloc_dev(); |
453 | if (!hdev) { |
454 | BT_ERR("Can't allocate HCI device" ); |
455 | return -ENOMEM; |
456 | } |
457 | |
458 | info->hdev = hdev; |
459 | |
460 | hdev->bus = HCI_PCCARD; |
461 | hci_set_drvdata(hdev, data: info); |
462 | SET_HCIDEV_DEV(hdev, &info->p_dev->dev); |
463 | |
464 | hdev->open = dtl1_hci_open; |
465 | hdev->close = dtl1_hci_close; |
466 | hdev->flush = dtl1_hci_flush; |
467 | hdev->send = dtl1_hci_send_frame; |
468 | |
469 | spin_lock_irqsave(&(info->lock), flags); |
470 | |
471 | /* Reset UART */ |
472 | outb(value: 0, port: iobase + UART_MCR); |
473 | |
474 | /* Turn off interrupts */ |
475 | outb(value: 0, port: iobase + UART_IER); |
476 | |
477 | /* Initialize UART */ |
478 | outb(UART_LCR_WLEN8, port: iobase + UART_LCR); /* Reset DLAB */ |
479 | outb(value: (UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), port: iobase + UART_MCR); |
480 | |
481 | info->ri_latch = inb(port: info->p_dev->resource[0]->start + UART_MSR) |
482 | & UART_MSR_RI; |
483 | |
484 | /* Turn on interrupts */ |
485 | outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, port: iobase + UART_IER); |
486 | |
487 | spin_unlock_irqrestore(lock: &(info->lock), flags); |
488 | |
489 | /* Timeout before it is safe to send the first HCI packet */ |
490 | msleep(msecs: 2000); |
491 | |
492 | /* Register HCI device */ |
493 | if (hci_register_dev(hdev) < 0) { |
494 | BT_ERR("Can't register HCI device" ); |
495 | info->hdev = NULL; |
496 | hci_free_dev(hdev); |
497 | return -ENODEV; |
498 | } |
499 | |
500 | return 0; |
501 | } |
502 | |
503 | |
504 | static int dtl1_close(struct dtl1_info *info) |
505 | { |
506 | unsigned long flags; |
507 | unsigned int iobase = info->p_dev->resource[0]->start; |
508 | struct hci_dev *hdev = info->hdev; |
509 | |
510 | if (!hdev) |
511 | return -ENODEV; |
512 | |
513 | dtl1_hci_close(hdev); |
514 | |
515 | spin_lock_irqsave(&(info->lock), flags); |
516 | |
517 | /* Reset UART */ |
518 | outb(value: 0, port: iobase + UART_MCR); |
519 | |
520 | /* Turn off interrupts */ |
521 | outb(value: 0, port: iobase + UART_IER); |
522 | |
523 | spin_unlock_irqrestore(lock: &(info->lock), flags); |
524 | |
525 | hci_unregister_dev(hdev); |
526 | hci_free_dev(hdev); |
527 | |
528 | return 0; |
529 | } |
530 | |
531 | static int dtl1_probe(struct pcmcia_device *link) |
532 | { |
533 | struct dtl1_info *info; |
534 | |
535 | /* Create new info device */ |
536 | info = devm_kzalloc(dev: &link->dev, size: sizeof(*info), GFP_KERNEL); |
537 | if (!info) |
538 | return -ENOMEM; |
539 | |
540 | info->p_dev = link; |
541 | link->priv = info; |
542 | |
543 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
544 | |
545 | return dtl1_config(link); |
546 | } |
547 | |
548 | |
549 | static void dtl1_detach(struct pcmcia_device *link) |
550 | { |
551 | struct dtl1_info *info = link->priv; |
552 | |
553 | dtl1_close(info); |
554 | pcmcia_disable_device(p_dev: link); |
555 | } |
556 | |
557 | static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data) |
558 | { |
559 | if ((p_dev->resource[1]->end) || (p_dev->resource[1]->end < 8)) |
560 | return -ENODEV; |
561 | |
562 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
563 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
564 | |
565 | return pcmcia_request_io(p_dev); |
566 | } |
567 | |
568 | static int dtl1_config(struct pcmcia_device *link) |
569 | { |
570 | struct dtl1_info *info = link->priv; |
571 | int ret; |
572 | |
573 | /* Look for a generic full-sized window */ |
574 | link->resource[0]->end = 8; |
575 | ret = pcmcia_loop_config(p_dev: link, conf_check: dtl1_confcheck, NULL); |
576 | if (ret) |
577 | goto failed; |
578 | |
579 | ret = pcmcia_request_irq(p_dev: link, handler: dtl1_interrupt); |
580 | if (ret) |
581 | goto failed; |
582 | |
583 | ret = pcmcia_enable_device(p_dev: link); |
584 | if (ret) |
585 | goto failed; |
586 | |
587 | ret = dtl1_open(info); |
588 | if (ret) |
589 | goto failed; |
590 | |
591 | return 0; |
592 | |
593 | failed: |
594 | dtl1_detach(link); |
595 | return ret; |
596 | } |
597 | |
598 | static const struct pcmcia_device_id dtl1_ids[] = { |
599 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones" , "DTL-1" , 0xe1bfdd64, 0xe168480d), |
600 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones" , "DTL-4" , 0xe1bfdd64, 0x9102bc82), |
601 | PCMCIA_DEVICE_PROD_ID12("Socket" , "CF" , 0xb38bcc2e, 0x44ebf863), |
602 | PCMCIA_DEVICE_PROD_ID12("Socket" , "CF+ Personal Network Card" , 0xb38bcc2e, 0xe732bae3), |
603 | PCMCIA_DEVICE_NULL |
604 | }; |
605 | MODULE_DEVICE_TABLE(pcmcia, dtl1_ids); |
606 | |
607 | static struct pcmcia_driver dtl1_driver = { |
608 | .owner = THIS_MODULE, |
609 | .name = "dtl1_cs" , |
610 | .probe = dtl1_probe, |
611 | .remove = dtl1_detach, |
612 | .id_table = dtl1_ids, |
613 | }; |
614 | module_pcmcia_driver(dtl1_driver); |
615 | |