750 lines · c
1/*2 *3 * Driver for the 3Com Bluetooth PCMCIA card4 *5 * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>6 * Jose Orlando Pereira <jop@di.uminho.pt>7 *8 *9 * This program is free software; you can redistribute it and/or modify10 * it under the terms of the GNU General Public License version 2 as11 * published by the Free Software Foundation;12 *13 * Software distributed under the License is distributed on an "AS14 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or15 * implied. See the License for the specific language governing16 * rights and limitations under the License.17 *18 * The initial developer of the original code is David A. Hinds19 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds20 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.21 *22 */23 24#include <linux/module.h>25 26#include <linux/kernel.h>27#include <linux/init.h>28#include <linux/slab.h>29#include <linux/types.h>30#include <linux/delay.h>31#include <linux/errno.h>32#include <linux/ptrace.h>33#include <linux/ioport.h>34#include <linux/spinlock.h>35#include <linux/moduleparam.h>36 37#include <linux/skbuff.h>38#include <linux/string.h>39#include <linux/serial.h>40#include <linux/serial_reg.h>41#include <linux/bitops.h>42#include <asm/io.h>43 44#include <linux/device.h>45#include <linux/firmware.h>46 47#include <pcmcia/cistpl.h>48#include <pcmcia/ciscode.h>49#include <pcmcia/ds.h>50#include <pcmcia/cisreg.h>51 52#include <net/bluetooth/bluetooth.h>53#include <net/bluetooth/hci_core.h>54 55 56 57/* ======================== Module parameters ======================== */58 59 60MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");61MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");62MODULE_LICENSE("GPL");63MODULE_FIRMWARE("BT3CPCC.bin");64 65 66 67/* ======================== Local structures ======================== */68 69 70struct bt3c_info {71 struct pcmcia_device *p_dev;72 73 struct hci_dev *hdev;74 75 spinlock_t lock; /* For serializing operations */76 77 struct sk_buff_head txq;78 unsigned long tx_state;79 80 unsigned long rx_state;81 unsigned long rx_count;82 struct sk_buff *rx_skb;83};84 85 86static int bt3c_config(struct pcmcia_device *link);87static void bt3c_release(struct pcmcia_device *link);88 89static void bt3c_detach(struct pcmcia_device *p_dev);90 91 92/* Transmit states */93#define XMIT_SENDING 194#define XMIT_WAKEUP 295#define XMIT_WAITING 896 97/* Receiver states */98#define RECV_WAIT_PACKET_TYPE 099#define RECV_WAIT_EVENT_HEADER 1100#define RECV_WAIT_ACL_HEADER 2101#define RECV_WAIT_SCO_HEADER 3102#define RECV_WAIT_DATA 4103 104 105 106/* ======================== Special I/O functions ======================== */107 108 109#define DATA_L 0110#define DATA_H 1111#define ADDR_L 2112#define ADDR_H 3113#define CONTROL 4114 115 116static inline void bt3c_address(unsigned int iobase, unsigned short addr)117{118 outb(addr & 0xff, iobase + ADDR_L);119 outb((addr >> 8) & 0xff, iobase + ADDR_H);120}121 122 123static inline void bt3c_put(unsigned int iobase, unsigned short value)124{125 outb(value & 0xff, iobase + DATA_L);126 outb((value >> 8) & 0xff, iobase + DATA_H);127}128 129 130static inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)131{132 bt3c_address(iobase, addr);133 bt3c_put(iobase, value);134}135 136 137static inline unsigned short bt3c_get(unsigned int iobase)138{139 unsigned short value = inb(iobase + DATA_L);140 141 value |= inb(iobase + DATA_H) << 8;142 143 return value;144}145 146 147static inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)148{149 bt3c_address(iobase, addr);150 151 return bt3c_get(iobase);152}153 154 155 156/* ======================== Interrupt handling ======================== */157 158 159static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)160{161 int actual = 0;162 163 bt3c_address(iobase, 0x7080);164 165 /* Fill FIFO with current frame */166 while (actual < len) {167 /* Transmit next byte */168 bt3c_put(iobase, buf[actual]);169 actual++;170 }171 172 bt3c_io_write(iobase, 0x7005, actual);173 174 return actual;175}176 177 178static void bt3c_write_wakeup(struct bt3c_info *info)179{180 if (!info) {181 BT_ERR("Unknown device");182 return;183 }184 185 if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))186 return;187 188 do {189 unsigned int iobase = info->p_dev->resource[0]->start;190 register struct sk_buff *skb;191 int len;192 193 if (!pcmcia_dev_present(info->p_dev))194 break;195 196 skb = skb_dequeue(&(info->txq));197 if (!skb) {198 clear_bit(XMIT_SENDING, &(info->tx_state));199 break;200 }201 202 /* Send frame */203 len = bt3c_write(iobase, 256, skb->data, skb->len);204 205 if (len != skb->len)206 BT_ERR("Very strange");207 208 kfree_skb(skb);209 210 info->hdev->stat.byte_tx += len;211 212 } while (0);213}214 215 216static void bt3c_receive(struct bt3c_info *info)217{218 unsigned int iobase;219 int size = 0, avail;220 221 if (!info) {222 BT_ERR("Unknown device");223 return;224 }225 226 iobase = info->p_dev->resource[0]->start;227 228 avail = bt3c_read(iobase, 0x7006);229 230 bt3c_address(iobase, 0x7480);231 while (size < avail) {232 size++;233 info->hdev->stat.byte_rx++;234 235 /* Allocate packet */236 if (!info->rx_skb) {237 info->rx_state = RECV_WAIT_PACKET_TYPE;238 info->rx_count = 0;239 info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);240 if (!info->rx_skb) {241 BT_ERR("Can't allocate mem for new packet");242 return;243 }244 }245 246 247 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {248 249 hci_skb_pkt_type(info->rx_skb) = inb(iobase + DATA_L);250 inb(iobase + DATA_H);251 252 switch (hci_skb_pkt_type(info->rx_skb)) {253 254 case HCI_EVENT_PKT:255 info->rx_state = RECV_WAIT_EVENT_HEADER;256 info->rx_count = HCI_EVENT_HDR_SIZE;257 break;258 259 case HCI_ACLDATA_PKT:260 info->rx_state = RECV_WAIT_ACL_HEADER;261 info->rx_count = HCI_ACL_HDR_SIZE;262 break;263 264 case HCI_SCODATA_PKT:265 info->rx_state = RECV_WAIT_SCO_HEADER;266 info->rx_count = HCI_SCO_HDR_SIZE;267 break;268 269 default:270 /* Unknown packet */271 BT_ERR("Unknown HCI packet with type 0x%02x received",272 hci_skb_pkt_type(info->rx_skb));273 info->hdev->stat.err_rx++;274 275 kfree_skb(info->rx_skb);276 info->rx_skb = NULL;277 break;278 279 }280 281 } else {282 283 __u8 x = inb(iobase + DATA_L);284 285 skb_put_u8(info->rx_skb, x);286 inb(iobase + DATA_H);287 info->rx_count--;288 289 if (info->rx_count == 0) {290 291 int dlen;292 struct hci_event_hdr *eh;293 struct hci_acl_hdr *ah;294 struct hci_sco_hdr *sh;295 296 switch (info->rx_state) {297 298 case RECV_WAIT_EVENT_HEADER:299 eh = hci_event_hdr(info->rx_skb);300 info->rx_state = RECV_WAIT_DATA;301 info->rx_count = eh->plen;302 break;303 304 case RECV_WAIT_ACL_HEADER:305 ah = hci_acl_hdr(info->rx_skb);306 dlen = __le16_to_cpu(ah->dlen);307 info->rx_state = RECV_WAIT_DATA;308 info->rx_count = dlen;309 break;310 311 case RECV_WAIT_SCO_HEADER:312 sh = hci_sco_hdr(info->rx_skb);313 info->rx_state = RECV_WAIT_DATA;314 info->rx_count = sh->dlen;315 break;316 317 case RECV_WAIT_DATA:318 hci_recv_frame(info->hdev, info->rx_skb);319 info->rx_skb = NULL;320 break;321 322 }323 324 }325 326 }327 328 }329 330 bt3c_io_write(iobase, 0x7006, 0x0000);331}332 333 334static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)335{336 struct bt3c_info *info = dev_inst;337 unsigned int iobase;338 int iir;339 irqreturn_t r = IRQ_NONE;340 341 if (!info || !info->hdev)342 /* our irq handler is shared */343 return IRQ_NONE;344 345 iobase = info->p_dev->resource[0]->start;346 347 spin_lock(&(info->lock));348 349 iir = inb(iobase + CONTROL);350 if (iir & 0x80) {351 int stat = bt3c_read(iobase, 0x7001);352 353 if ((stat & 0xff) == 0x7f) {354 BT_ERR("Very strange (stat=0x%04x)", stat);355 } else if ((stat & 0xff) != 0xff) {356 if (stat & 0x0020) {357 int status = bt3c_read(iobase, 0x7002) & 0x10;358 bt_dev_info(info->hdev, "Antenna %s",359 status ? "out" : "in");360 }361 if (stat & 0x0001)362 bt3c_receive(info);363 if (stat & 0x0002) {364 clear_bit(XMIT_SENDING, &(info->tx_state));365 bt3c_write_wakeup(info);366 }367 368 bt3c_io_write(iobase, 0x7001, 0x0000);369 370 outb(iir, iobase + CONTROL);371 }372 r = IRQ_HANDLED;373 }374 375 spin_unlock(&(info->lock));376 377 return r;378}379 380 381 382/* ======================== HCI interface ======================== */383 384 385static int bt3c_hci_flush(struct hci_dev *hdev)386{387 struct bt3c_info *info = hci_get_drvdata(hdev);388 389 /* Drop TX queue */390 skb_queue_purge(&(info->txq));391 392 return 0;393}394 395 396static int bt3c_hci_open(struct hci_dev *hdev)397{398 return 0;399}400 401 402static int bt3c_hci_close(struct hci_dev *hdev)403{404 bt3c_hci_flush(hdev);405 406 return 0;407}408 409 410static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)411{412 struct bt3c_info *info = hci_get_drvdata(hdev);413 unsigned long flags;414 415 switch (hci_skb_pkt_type(skb)) {416 case HCI_COMMAND_PKT:417 hdev->stat.cmd_tx++;418 break;419 case HCI_ACLDATA_PKT:420 hdev->stat.acl_tx++;421 break;422 case HCI_SCODATA_PKT:423 hdev->stat.sco_tx++;424 break;425 }426 427 /* Prepend skb with frame type */428 memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);429 skb_queue_tail(&(info->txq), skb);430 431 spin_lock_irqsave(&(info->lock), flags);432 433 bt3c_write_wakeup(info);434 435 spin_unlock_irqrestore(&(info->lock), flags);436 437 return 0;438}439 440 441 442/* ======================== Card services HCI interaction ======================== */443 444 445static int bt3c_load_firmware(struct bt3c_info *info,446 const unsigned char *firmware,447 int count)448{449 char *ptr = (char *) firmware;450 char b[9];451 unsigned int iobase, tmp, tn;452 unsigned long size, addr, fcs;453 int i, err = 0;454 455 iobase = info->p_dev->resource[0]->start;456 457 /* Reset */458 bt3c_io_write(iobase, 0x8040, 0x0404);459 bt3c_io_write(iobase, 0x8040, 0x0400);460 461 udelay(1);462 463 bt3c_io_write(iobase, 0x8040, 0x0404);464 465 udelay(17);466 467 /* Load */468 while (count) {469 if (ptr[0] != 'S') {470 BT_ERR("Bad address in firmware");471 err = -EFAULT;472 goto error;473 }474 475 memset(b, 0, sizeof(b));476 memcpy(b, ptr + 2, 2);477 if (kstrtoul(b, 16, &size) < 0)478 return -EINVAL;479 480 memset(b, 0, sizeof(b));481 memcpy(b, ptr + 4, 8);482 if (kstrtoul(b, 16, &addr) < 0)483 return -EINVAL;484 485 memset(b, 0, sizeof(b));486 memcpy(b, ptr + (size * 2) + 2, 2);487 if (kstrtoul(b, 16, &fcs) < 0)488 return -EINVAL;489 490 memset(b, 0, sizeof(b));491 for (tmp = 0, i = 0; i < size; i++) {492 memcpy(b, ptr + (i * 2) + 2, 2);493 if (kstrtouint(b, 16, &tn))494 return -EINVAL;495 tmp += tn;496 }497 498 if (((tmp + fcs) & 0xff) != 0xff) {499 BT_ERR("Checksum error in firmware");500 err = -EILSEQ;501 goto error;502 }503 504 if (ptr[1] == '3') {505 bt3c_address(iobase, addr);506 507 memset(b, 0, sizeof(b));508 for (i = 0; i < (size - 4) / 2; i++) {509 memcpy(b, ptr + (i * 4) + 12, 4);510 if (kstrtouint(b, 16, &tmp))511 return -EINVAL;512 bt3c_put(iobase, tmp);513 }514 }515 516 ptr += (size * 2) + 6;517 count -= (size * 2) + 6;518 }519 520 udelay(17);521 522 /* Boot */523 bt3c_address(iobase, 0x3000);524 outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);525 526error:527 udelay(17);528 529 /* Clear */530 bt3c_io_write(iobase, 0x7006, 0x0000);531 bt3c_io_write(iobase, 0x7005, 0x0000);532 bt3c_io_write(iobase, 0x7001, 0x0000);533 534 return err;535}536 537 538static int bt3c_open(struct bt3c_info *info)539{540 const struct firmware *firmware;541 struct hci_dev *hdev;542 int err;543 544 spin_lock_init(&(info->lock));545 546 skb_queue_head_init(&(info->txq));547 548 info->rx_state = RECV_WAIT_PACKET_TYPE;549 info->rx_count = 0;550 info->rx_skb = NULL;551 552 /* Initialize HCI device */553 hdev = hci_alloc_dev();554 if (!hdev) {555 BT_ERR("Can't allocate HCI device");556 return -ENOMEM;557 }558 559 info->hdev = hdev;560 561 hdev->bus = HCI_PCCARD;562 hci_set_drvdata(hdev, info);563 SET_HCIDEV_DEV(hdev, &info->p_dev->dev);564 565 hdev->open = bt3c_hci_open;566 hdev->close = bt3c_hci_close;567 hdev->flush = bt3c_hci_flush;568 hdev->send = bt3c_hci_send_frame;569 570 /* Load firmware */571 err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);572 if (err < 0) {573 BT_ERR("Firmware request failed");574 goto error;575 }576 577 err = bt3c_load_firmware(info, firmware->data, firmware->size);578 579 release_firmware(firmware);580 581 if (err < 0) {582 BT_ERR("Firmware loading failed");583 goto error;584 }585 586 /* Timeout before it is safe to send the first HCI packet */587 msleep(1000);588 589 /* Register HCI device */590 err = hci_register_dev(hdev);591 if (err < 0) {592 BT_ERR("Can't register HCI device");593 goto error;594 }595 596 return 0;597 598error:599 info->hdev = NULL;600 hci_free_dev(hdev);601 return err;602}603 604 605static int bt3c_close(struct bt3c_info *info)606{607 struct hci_dev *hdev = info->hdev;608 609 if (!hdev)610 return -ENODEV;611 612 bt3c_hci_close(hdev);613 614 hci_unregister_dev(hdev);615 hci_free_dev(hdev);616 617 return 0;618}619 620static int bt3c_probe(struct pcmcia_device *link)621{622 struct bt3c_info *info;623 624 /* Create new info device */625 info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);626 if (!info)627 return -ENOMEM;628 629 info->p_dev = link;630 link->priv = info;631 632 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |633 CONF_AUTO_SET_IO;634 635 return bt3c_config(link);636}637 638 639static void bt3c_detach(struct pcmcia_device *link)640{641 bt3c_release(link);642}643 644static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data)645{646 int *try = priv_data;647 648 if (!try)649 p_dev->io_lines = 16;650 651 if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))652 return -EINVAL;653 654 p_dev->resource[0]->end = 8;655 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;656 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;657 658 return pcmcia_request_io(p_dev);659}660 661static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,662 void *priv_data)663{664 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };665 int j;666 667 if (p_dev->io_lines > 3)668 return -ENODEV;669 670 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;671 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;672 p_dev->resource[0]->end = 8;673 674 for (j = 0; j < 5; j++) {675 p_dev->resource[0]->start = base[j];676 p_dev->io_lines = base[j] ? 16 : 3;677 if (!pcmcia_request_io(p_dev))678 return 0;679 }680 return -ENODEV;681}682 683static int bt3c_config(struct pcmcia_device *link)684{685 struct bt3c_info *info = link->priv;686 int i;687 unsigned long try;688 689 /* First pass: look for a config entry that looks normal.690 * Two tries: without IO aliases, then with aliases691 */692 for (try = 0; try < 2; try++)693 if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))694 goto found_port;695 696 /* Second pass: try to find an entry that isn't picky about697 * its base address, then try to grab any standard serial port698 * address, and finally try to get any free port.699 */700 if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))701 goto found_port;702 703 BT_ERR("No usable port range found");704 goto failed;705 706found_port:707 i = pcmcia_request_irq(link, &bt3c_interrupt);708 if (i != 0)709 goto failed;710 711 i = pcmcia_enable_device(link);712 if (i != 0)713 goto failed;714 715 if (bt3c_open(info) != 0)716 goto failed;717 718 return 0;719 720failed:721 bt3c_release(link);722 return -ENODEV;723}724 725 726static void bt3c_release(struct pcmcia_device *link)727{728 struct bt3c_info *info = link->priv;729 730 bt3c_close(info);731 732 pcmcia_disable_device(link);733}734 735 736static const struct pcmcia_device_id bt3c_ids[] = {737 PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),738 PCMCIA_DEVICE_NULL739};740MODULE_DEVICE_TABLE(pcmcia, bt3c_ids);741 742static struct pcmcia_driver bt3c_driver = {743 .owner = THIS_MODULE,744 .name = "bt3c_cs",745 .probe = bt3c_probe,746 .remove = bt3c_detach,747 .id_table = bt3c_ids,748};749module_pcmcia_driver(bt3c_driver);750