726 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *4 * AVM BlueFRITZ! USB driver5 *6 * Copyright (C) 2003-2006 Marcel Holtmann <marcel@holtmann.org>7 */8 9#include <linux/module.h>10 11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/slab.h>14#include <linux/types.h>15#include <linux/errno.h>16#include <linux/skbuff.h>17 18#include <linux/device.h>19#include <linux/firmware.h>20 21#include <linux/usb.h>22 23#include <net/bluetooth/bluetooth.h>24#include <net/bluetooth/hci_core.h>25 26#define VERSION "1.2"27 28static struct usb_driver bfusb_driver;29 30static const struct usb_device_id bfusb_table[] = {31 /* AVM BlueFRITZ! USB */32 { USB_DEVICE(0x057c, 0x2200) },33 34 { } /* Terminating entry */35};36 37MODULE_DEVICE_TABLE(usb, bfusb_table);38 39#define BFUSB_MAX_BLOCK_SIZE 25640 41#define BFUSB_BLOCK_TIMEOUT 300042 43#define BFUSB_TX_PROCESS 144#define BFUSB_TX_WAKEUP 245 46#define BFUSB_MAX_BULK_TX 247#define BFUSB_MAX_BULK_RX 248 49struct bfusb_data {50 struct hci_dev *hdev;51 52 unsigned long state;53 54 struct usb_device *udev;55 56 unsigned int bulk_in_ep;57 unsigned int bulk_out_ep;58 unsigned int bulk_pkt_size;59 60 rwlock_t lock;61 62 struct sk_buff_head transmit_q;63 64 struct sk_buff *reassembly;65 66 atomic_t pending_tx;67 struct sk_buff_head pending_q;68 struct sk_buff_head completed_q;69};70 71struct bfusb_data_scb {72 struct urb *urb;73};74 75static void bfusb_tx_complete(struct urb *urb);76static void bfusb_rx_complete(struct urb *urb);77 78static struct urb *bfusb_get_completed(struct bfusb_data *data)79{80 struct sk_buff *skb;81 struct urb *urb = NULL;82 83 BT_DBG("bfusb %p", data);84 85 skb = skb_dequeue(&data->completed_q);86 if (skb) {87 urb = ((struct bfusb_data_scb *) skb->cb)->urb;88 kfree_skb(skb);89 }90 91 return urb;92}93 94static void bfusb_unlink_urbs(struct bfusb_data *data)95{96 struct sk_buff *skb;97 struct urb *urb;98 99 BT_DBG("bfusb %p", data);100 101 while ((skb = skb_dequeue(&data->pending_q))) {102 urb = ((struct bfusb_data_scb *) skb->cb)->urb;103 usb_kill_urb(urb);104 skb_queue_tail(&data->completed_q, skb);105 }106 107 while ((urb = bfusb_get_completed(data)))108 usb_free_urb(urb);109}110 111static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb)112{113 struct bfusb_data_scb *scb = (void *) skb->cb;114 struct urb *urb = bfusb_get_completed(data);115 int err, pipe;116 117 BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len);118 119 if (!urb) {120 urb = usb_alloc_urb(0, GFP_ATOMIC);121 if (!urb)122 return -ENOMEM;123 }124 125 pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);126 127 usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len,128 bfusb_tx_complete, skb);129 130 scb->urb = urb;131 132 skb_queue_tail(&data->pending_q, skb);133 134 err = usb_submit_urb(urb, GFP_ATOMIC);135 if (err) {136 bt_dev_err(data->hdev, "bulk tx submit failed urb %p err %d",137 urb, err);138 skb_unlink(skb, &data->pending_q);139 usb_free_urb(urb);140 } else141 atomic_inc(&data->pending_tx);142 143 return err;144}145 146static void bfusb_tx_wakeup(struct bfusb_data *data)147{148 struct sk_buff *skb;149 150 BT_DBG("bfusb %p", data);151 152 if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) {153 set_bit(BFUSB_TX_WAKEUP, &data->state);154 return;155 }156 157 do {158 clear_bit(BFUSB_TX_WAKEUP, &data->state);159 160 while ((atomic_read(&data->pending_tx) < BFUSB_MAX_BULK_TX) &&161 (skb = skb_dequeue(&data->transmit_q))) {162 if (bfusb_send_bulk(data, skb) < 0) {163 skb_queue_head(&data->transmit_q, skb);164 break;165 }166 }167 168 } while (test_bit(BFUSB_TX_WAKEUP, &data->state));169 170 clear_bit(BFUSB_TX_PROCESS, &data->state);171}172 173static void bfusb_tx_complete(struct urb *urb)174{175 struct sk_buff *skb = (struct sk_buff *) urb->context;176 struct bfusb_data *data = (struct bfusb_data *) skb->dev;177 178 BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len);179 180 atomic_dec(&data->pending_tx);181 182 if (!test_bit(HCI_RUNNING, &data->hdev->flags))183 return;184 185 if (!urb->status)186 data->hdev->stat.byte_tx += skb->len;187 else188 data->hdev->stat.err_tx++;189 190 read_lock(&data->lock);191 192 skb_unlink(skb, &data->pending_q);193 skb_queue_tail(&data->completed_q, skb);194 195 bfusb_tx_wakeup(data);196 197 read_unlock(&data->lock);198}199 200 201static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb)202{203 struct bfusb_data_scb *scb;204 struct sk_buff *skb;205 int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;206 207 BT_DBG("bfusb %p urb %p", data, urb);208 209 if (!urb) {210 urb = usb_alloc_urb(0, GFP_ATOMIC);211 if (!urb)212 return -ENOMEM;213 }214 215 skb = bt_skb_alloc(size, GFP_ATOMIC);216 if (!skb) {217 usb_free_urb(urb);218 return -ENOMEM;219 }220 221 skb->dev = (void *) data;222 223 scb = (struct bfusb_data_scb *) skb->cb;224 scb->urb = urb;225 226 pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep);227 228 usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size,229 bfusb_rx_complete, skb);230 231 skb_queue_tail(&data->pending_q, skb);232 233 err = usb_submit_urb(urb, GFP_ATOMIC);234 if (err) {235 bt_dev_err(data->hdev, "bulk rx submit failed urb %p err %d",236 urb, err);237 skb_unlink(skb, &data->pending_q);238 kfree_skb(skb);239 usb_free_urb(urb);240 }241 242 return err;243}244 245static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len)246{247 BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len);248 249 if (hdr & 0x10) {250 bt_dev_err(data->hdev, "error in block");251 kfree_skb(data->reassembly);252 data->reassembly = NULL;253 return -EIO;254 }255 256 if (hdr & 0x04) {257 struct sk_buff *skb;258 unsigned char pkt_type;259 int pkt_len = 0;260 261 if (data->reassembly) {262 bt_dev_err(data->hdev, "unexpected start block");263 kfree_skb(data->reassembly);264 data->reassembly = NULL;265 }266 267 if (len < 1) {268 bt_dev_err(data->hdev, "no packet type found");269 return -EPROTO;270 }271 272 pkt_type = *buf++; len--;273 274 switch (pkt_type) {275 case HCI_EVENT_PKT:276 if (len >= HCI_EVENT_HDR_SIZE) {277 struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf;278 pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;279 } else {280 bt_dev_err(data->hdev, "event block is too short");281 return -EILSEQ;282 }283 break;284 285 case HCI_ACLDATA_PKT:286 if (len >= HCI_ACL_HDR_SIZE) {287 struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf;288 pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);289 } else {290 bt_dev_err(data->hdev, "data block is too short");291 return -EILSEQ;292 }293 break;294 295 case HCI_SCODATA_PKT:296 if (len >= HCI_SCO_HDR_SIZE) {297 struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf;298 pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;299 } else {300 bt_dev_err(data->hdev, "audio block is too short");301 return -EILSEQ;302 }303 break;304 }305 306 skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);307 if (!skb) {308 bt_dev_err(data->hdev, "no memory for the packet");309 return -ENOMEM;310 }311 312 hci_skb_pkt_type(skb) = pkt_type;313 314 data->reassembly = skb;315 } else {316 if (!data->reassembly) {317 bt_dev_err(data->hdev, "unexpected continuation block");318 return -EIO;319 }320 }321 322 if (len > 0)323 skb_put_data(data->reassembly, buf, len);324 325 if (hdr & 0x08) {326 hci_recv_frame(data->hdev, data->reassembly);327 data->reassembly = NULL;328 }329 330 return 0;331}332 333static void bfusb_rx_complete(struct urb *urb)334{335 struct sk_buff *skb = (struct sk_buff *) urb->context;336 struct bfusb_data *data = (struct bfusb_data *) skb->dev;337 unsigned char *buf = urb->transfer_buffer;338 int count = urb->actual_length;339 int err, hdr, len;340 341 BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len);342 343 read_lock(&data->lock);344 345 if (!test_bit(HCI_RUNNING, &data->hdev->flags))346 goto unlock;347 348 if (urb->status || !count)349 goto resubmit;350 351 data->hdev->stat.byte_rx += count;352 353 skb_put(skb, count);354 355 while (count) {356 hdr = buf[0] | (buf[1] << 8);357 358 if (hdr & 0x4000) {359 len = 0;360 count -= 2;361 buf += 2;362 } else {363 len = (buf[2] == 0) ? 256 : buf[2];364 count -= 3;365 buf += 3;366 }367 368 if (count < len) {369 bt_dev_err(data->hdev, "block extends over URB buffer ranges");370 }371 372 if ((hdr & 0xe1) == 0xc1)373 bfusb_recv_block(data, hdr, buf, len);374 375 count -= len;376 buf += len;377 }378 379 skb_unlink(skb, &data->pending_q);380 kfree_skb(skb);381 382 bfusb_rx_submit(data, urb);383 384 read_unlock(&data->lock);385 386 return;387 388resubmit:389 urb->dev = data->udev;390 391 err = usb_submit_urb(urb, GFP_ATOMIC);392 if (err) {393 bt_dev_err(data->hdev, "bulk resubmit failed urb %p err %d",394 urb, err);395 }396 397unlock:398 read_unlock(&data->lock);399}400 401static int bfusb_open(struct hci_dev *hdev)402{403 struct bfusb_data *data = hci_get_drvdata(hdev);404 unsigned long flags;405 int i, err;406 407 BT_DBG("hdev %p bfusb %p", hdev, data);408 409 write_lock_irqsave(&data->lock, flags);410 411 err = bfusb_rx_submit(data, NULL);412 if (!err) {413 for (i = 1; i < BFUSB_MAX_BULK_RX; i++)414 bfusb_rx_submit(data, NULL);415 }416 417 write_unlock_irqrestore(&data->lock, flags);418 419 return err;420}421 422static int bfusb_flush(struct hci_dev *hdev)423{424 struct bfusb_data *data = hci_get_drvdata(hdev);425 426 BT_DBG("hdev %p bfusb %p", hdev, data);427 428 skb_queue_purge(&data->transmit_q);429 430 return 0;431}432 433static int bfusb_close(struct hci_dev *hdev)434{435 struct bfusb_data *data = hci_get_drvdata(hdev);436 unsigned long flags;437 438 BT_DBG("hdev %p bfusb %p", hdev, data);439 440 write_lock_irqsave(&data->lock, flags);441 write_unlock_irqrestore(&data->lock, flags);442 443 bfusb_unlink_urbs(data);444 bfusb_flush(hdev);445 446 return 0;447}448 449static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)450{451 struct bfusb_data *data = hci_get_drvdata(hdev);452 struct sk_buff *nskb;453 unsigned char buf[3];454 int sent = 0, size, count;455 456 BT_DBG("hdev %p skb %p type %d len %d", hdev, skb,457 hci_skb_pkt_type(skb), skb->len);458 459 switch (hci_skb_pkt_type(skb)) {460 case HCI_COMMAND_PKT:461 hdev->stat.cmd_tx++;462 break;463 case HCI_ACLDATA_PKT:464 hdev->stat.acl_tx++;465 break;466 case HCI_SCODATA_PKT:467 hdev->stat.sco_tx++;468 break;469 }470 471 /* Prepend skb with frame type */472 memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);473 474 count = skb->len;475 476 /* Max HCI frame size seems to be 1511 + 1 */477 nskb = bt_skb_alloc(count + 32, GFP_KERNEL);478 if (!nskb) {479 bt_dev_err(hdev, "Can't allocate memory for new packet");480 return -ENOMEM;481 }482 483 nskb->dev = (void *) data;484 485 while (count) {486 size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);487 488 buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);489 buf[1] = 0x00;490 buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;491 492 skb_put_data(nskb, buf, 3);493 skb_copy_from_linear_data_offset(skb, sent, skb_put(nskb, size), size);494 495 sent += size;496 count -= size;497 }498 499 /* Don't send frame with multiple size of bulk max packet */500 if ((nskb->len % data->bulk_pkt_size) == 0) {501 buf[0] = 0xdd;502 buf[1] = 0x00;503 skb_put_data(nskb, buf, 2);504 }505 506 read_lock(&data->lock);507 508 skb_queue_tail(&data->transmit_q, nskb);509 bfusb_tx_wakeup(data);510 511 read_unlock(&data->lock);512 513 kfree_skb(skb);514 515 return 0;516}517 518static int bfusb_load_firmware(struct bfusb_data *data,519 const unsigned char *firmware, int count)520{521 unsigned char *buf;522 int err, pipe, len, size, sent = 0;523 524 BT_DBG("bfusb %p udev %p", data, data->udev);525 526 BT_INFO("BlueFRITZ! USB loading firmware");527 528 buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);529 if (!buf) {530 BT_ERR("Can't allocate memory chunk for firmware");531 return -ENOMEM;532 }533 534 pipe = usb_sndctrlpipe(data->udev, 0);535 536 if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,537 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {538 BT_ERR("Can't change to loading configuration");539 kfree(buf);540 return -EBUSY;541 }542 543 data->udev->toggle[0] = data->udev->toggle[1] = 0;544 545 pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);546 547 while (count) {548 size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);549 550 memcpy(buf, firmware + sent, size);551 552 err = usb_bulk_msg(data->udev, pipe, buf, size,553 &len, BFUSB_BLOCK_TIMEOUT);554 555 if (err || (len != size)) {556 BT_ERR("Error in firmware loading");557 goto error;558 }559 560 sent += size;561 count -= size;562 }563 564 err = usb_bulk_msg(data->udev, pipe, NULL, 0,565 &len, BFUSB_BLOCK_TIMEOUT);566 if (err < 0) {567 BT_ERR("Error in null packet request");568 goto error;569 }570 571 pipe = usb_sndctrlpipe(data->udev, 0);572 573 err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,574 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);575 if (err < 0) {576 BT_ERR("Can't change to running configuration");577 goto error;578 }579 580 data->udev->toggle[0] = data->udev->toggle[1] = 0;581 582 BT_INFO("BlueFRITZ! USB device ready");583 584 kfree(buf);585 return 0;586 587error:588 kfree(buf);589 590 pipe = usb_sndctrlpipe(data->udev, 0);591 592 usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,593 0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);594 595 return err;596}597 598static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *id)599{600 const struct firmware *firmware;601 struct usb_device *udev = interface_to_usbdev(intf);602 struct usb_host_endpoint *bulk_out_ep;603 struct usb_host_endpoint *bulk_in_ep;604 struct hci_dev *hdev;605 struct bfusb_data *data;606 607 BT_DBG("intf %p id %p", intf, id);608 609 /* Check number of endpoints */610 if (intf->cur_altsetting->desc.bNumEndpoints < 2)611 return -EIO;612 613 bulk_out_ep = &intf->cur_altsetting->endpoint[0];614 bulk_in_ep = &intf->cur_altsetting->endpoint[1];615 616 if (!bulk_out_ep || !bulk_in_ep) {617 BT_ERR("Bulk endpoints not found");618 goto done;619 }620 621 /* Initialize control structure and load firmware */622 data = devm_kzalloc(&intf->dev, sizeof(struct bfusb_data), GFP_KERNEL);623 if (!data)624 return -ENOMEM;625 626 data->udev = udev;627 data->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress;628 data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;629 data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);630 631 if (!data->bulk_pkt_size)632 goto done;633 634 rwlock_init(&data->lock);635 636 data->reassembly = NULL;637 638 skb_queue_head_init(&data->transmit_q);639 skb_queue_head_init(&data->pending_q);640 skb_queue_head_init(&data->completed_q);641 642 if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {643 BT_ERR("Firmware request failed");644 goto done;645 }646 647 BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);648 649 if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {650 BT_ERR("Firmware loading failed");651 goto release;652 }653 654 release_firmware(firmware);655 656 /* Initialize and register HCI device */657 hdev = hci_alloc_dev();658 if (!hdev) {659 BT_ERR("Can't allocate HCI device");660 goto done;661 }662 663 data->hdev = hdev;664 665 hdev->bus = HCI_USB;666 hci_set_drvdata(hdev, data);667 SET_HCIDEV_DEV(hdev, &intf->dev);668 669 hdev->open = bfusb_open;670 hdev->close = bfusb_close;671 hdev->flush = bfusb_flush;672 hdev->send = bfusb_send_frame;673 674 set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);675 676 if (hci_register_dev(hdev) < 0) {677 BT_ERR("Can't register HCI device");678 hci_free_dev(hdev);679 goto done;680 }681 682 usb_set_intfdata(intf, data);683 684 return 0;685 686release:687 release_firmware(firmware);688 689done:690 return -EIO;691}692 693static void bfusb_disconnect(struct usb_interface *intf)694{695 struct bfusb_data *data = usb_get_intfdata(intf);696 struct hci_dev *hdev = data->hdev;697 698 BT_DBG("intf %p", intf);699 700 if (!hdev)701 return;702 703 usb_set_intfdata(intf, NULL);704 705 bfusb_close(hdev);706 707 hci_unregister_dev(hdev);708 hci_free_dev(hdev);709}710 711static struct usb_driver bfusb_driver = {712 .name = "bfusb",713 .probe = bfusb_probe,714 .disconnect = bfusb_disconnect,715 .id_table = bfusb_table,716 .disable_hub_initiated_lpm = 1,717};718 719module_usb_driver(bfusb_driver);720 721MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");722MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);723MODULE_VERSION(VERSION);724MODULE_LICENSE("GPL");725MODULE_FIRMWARE("bfubase.frm");726