Loading drivers/bluetooth/Kconfig +2 −2 Original line number Diff line number Diff line Loading @@ -201,7 +201,7 @@ config BT_MRVL The core driver to support Marvell Bluetooth devices. This driver is required if you want to support Marvell Bluetooth devices, such as 8688/8787/8797/8897. Marvell Bluetooth devices, such as 8688/8787/8797/8887/8897. Say Y here to compile Marvell Bluetooth driver into the kernel or say M to compile it as module. Loading @@ -214,7 +214,7 @@ config BT_MRVL_SDIO The driver for Marvell Bluetooth chipsets with SDIO interface. This driver is required if you want to use Marvell Bluetooth devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897 devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8887/SD8897 chipsets are supported. Say Y here to compile support for Marvell BT-over-SDIO driver Loading drivers/bluetooth/btmrvl_sdio.c +34 −2 Original line number Diff line number Diff line Loading @@ -84,7 +84,27 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { .int_read_to_clear = false, }; static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { static const struct btmrvl_sdio_card_reg btmrvl_reg_8887 = { .cfg = 0x00, .host_int_mask = 0x08, .host_intstatus = 0x0C, .card_status = 0x5C, .sq_read_base_addr_a0 = 0x6C, .sq_read_base_addr_a1 = 0x6D, .card_revision = 0xC8, .card_fw_status0 = 0x88, .card_fw_status1 = 0x89, .card_rx_len = 0x8A, .card_rx_unit = 0x8B, .io_port_0 = 0xE4, .io_port_1 = 0xE5, .io_port_2 = 0xE6, .int_read_to_clear = true, .host_int_rsr = 0x04, .card_misc_cfg = 0xD8, }; static const struct btmrvl_sdio_card_reg btmrvl_reg_8897 = { .cfg = 0x00, .host_int_mask = 0x02, .host_intstatus = 0x03, Loading Loading @@ -128,10 +148,18 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { .sd_blksz_fw_dl = 256, }; static const struct btmrvl_sdio_device btmrvl_sdio_sd8887 = { .helper = NULL, .firmware = "mrvl/sd8887_uapsta.bin", .reg = &btmrvl_reg_8887, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, }; static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { .helper = NULL, .firmware = "mrvl/sd8897_uapsta.bin", .reg = &btmrvl_reg_88xx, .reg = &btmrvl_reg_8897, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, }; Loading @@ -149,6 +177,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8797 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, /* Marvell SD8887 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9136), .driver_data = (unsigned long)&btmrvl_sdio_sd8887 }, /* Marvell SD8897 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E), .driver_data = (unsigned long) &btmrvl_sdio_sd8897 }, Loading Loading @@ -1280,4 +1311,5 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin"); MODULE_FIRMWARE("mrvl/sd8688.bin"); MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin"); drivers/bluetooth/btusb.c +0 −4 Original line number Diff line number Diff line Loading @@ -268,8 +268,6 @@ struct btusb_data { struct usb_interface *intf; struct usb_interface *isoc; spinlock_t lock; unsigned long flags; struct work_struct work; Loading Loading @@ -2002,8 +2000,6 @@ static int btusb_probe(struct usb_interface *intf, data->udev = interface_to_usbdev(intf); data->intf = intf; spin_lock_init(&data->lock); INIT_WORK(&data->work, btusb_work); INIT_WORK(&data->waker, btusb_waker); init_usb_anchor(&data->deferred); Loading net/bluetooth/6lowpan.c +95 −50 Original line number Diff line number Diff line Loading @@ -426,38 +426,33 @@ static void convert_dest_bdaddr(struct in6_addr *ip6_daddr, *addr_type = get_addr_type_from_eui64(addr->b[5]); } static int header_create(struct sk_buff *skb, struct net_device *netdev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len) static int setup_header(struct sk_buff *skb, struct net_device *netdev, bdaddr_t *peer_addr, u8 *peer_addr_type) { struct ipv6hdr *hdr; struct in6_addr ipv6_daddr; struct lowpan_dev *dev; struct lowpan_peer *peer; bdaddr_t addr, *any = BDADDR_ANY; u8 *saddr, *daddr = any->b; u8 addr_type; if (type != ETH_P_IPV6) return -EINVAL; hdr = ipv6_hdr(skb); u8 *daddr = any->b; int err, status = 0; dev = lowpan_dev(netdev); if (ipv6_addr_is_multicast(&hdr->daddr)) { memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); memcpy(&ipv6_daddr, &lowpan_cb(skb)->addr, sizeof(ipv6_daddr)); if (ipv6_addr_is_multicast(&ipv6_daddr)) { lowpan_cb(skb)->chan = NULL; } else { unsigned long flags; u8 addr_type; /* Get destination BT device from skb. * If there is no such peer then discard the packet. */ convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type); convert_dest_bdaddr(&ipv6_daddr, &addr, &addr_type); BT_DBG("dest addr %pMR type %d IP %pI6c", &addr, addr_type, &hdr->daddr); addr_type, &ipv6_daddr); read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_ba(dev, &addr, addr_type); Loading @@ -470,7 +465,7 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, * the destination address. */ read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_dst(dev, &hdr->daddr, skb); peer = peer_lookup_dst(dev, &ipv6_daddr, skb); read_unlock_irqrestore(&devices_lock, flags); if (!peer) { BT_DBG("no such peer %pMR found", &addr); Loading @@ -479,15 +474,37 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, } daddr = peer->eui64_addr; memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); *peer_addr = addr; *peer_addr_type = addr_type; lowpan_cb(skb)->chan = peer->chan; status = 1; } saddr = dev->netdev->dev_addr; lowpan_header_compress(skb, netdev, ETH_P_IPV6, daddr, dev->netdev->dev_addr, skb->len); err = dev_hard_header(skb, netdev, ETH_P_IPV6, NULL, NULL, 0); if (err < 0) return err; return lowpan_header_compress(skb, netdev, type, daddr, saddr, len); return status; } static int header_create(struct sk_buff *skb, struct net_device *netdev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len) { struct ipv6hdr *hdr; if (type != ETH_P_IPV6) return -EINVAL; hdr = ipv6_hdr(skb); memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); return 0; } /* Packet to BT LE device */ Loading Loading @@ -529,11 +546,12 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, return err; } static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) { struct sk_buff *local_skb; struct lowpan_dev *entry, *tmp; unsigned long flags; int err = 0; read_lock_irqsave(&devices_lock, flags); Loading @@ -547,57 +565,77 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) dev = lowpan_dev(entry->netdev); list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) { int ret; local_skb = skb_clone(skb, GFP_ATOMIC); send_pkt(pentry->chan, local_skb, netdev); BT_DBG("xmit %s to %pMR type %d IP %pI6c chan %p", netdev->name, &pentry->chan->dst, pentry->chan->dst_type, &pentry->peer_addr, pentry->chan); ret = send_pkt(pentry->chan, local_skb, netdev); if (ret < 0) err = ret; kfree_skb(local_skb); } } read_unlock_irqrestore(&devices_lock, flags); return err; } static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) { int err = 0; struct lowpan_dev *dev; struct lowpan_peer *peer; bdaddr_t addr; u8 addr_type; struct sk_buff *tmpskb; if (ipv6_addr_is_multicast(&lowpan_cb(skb)->addr)) { /* We need to send the packet to every device * behind this interface. /* We must take a copy of the skb before we modify/replace the ipv6 * header as the header could be used elsewhere */ send_mcast_pkt(skb, netdev); } else { unsigned long flags; convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type); dev = lowpan_dev(netdev); tmpskb = skb_unshare(skb, GFP_ATOMIC); if (!tmpskb) { kfree_skb(skb); return NET_XMIT_DROP; } skb = tmpskb; read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_ba(dev, &addr, addr_type); if (!peer) peer = peer_lookup_dst(dev, &lowpan_cb(skb)->addr, skb); read_unlock_irqrestore(&devices_lock, flags); /* Return values from setup_header() * <0 - error, packet is dropped * 0 - this is a multicast packet * 1 - this is unicast packet */ err = setup_header(skb, netdev, &addr, &addr_type); if (err < 0) { kfree_skb(skb); return NET_XMIT_DROP; } BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p", if (err) { if (lowpan_cb(skb)->chan) { BT_DBG("xmit %s to %pMR type %d IP %pI6c chan %p", netdev->name, &addr, addr_type, &lowpan_cb(skb)->addr, peer); if (peer && peer->chan) err = send_pkt(peer->chan, skb, netdev); else &lowpan_cb(skb)->addr, lowpan_cb(skb)->chan); err = send_pkt(lowpan_cb(skb)->chan, skb, netdev); } else { err = -ENOENT; } } else { /* We need to send the packet to every device behind this * interface. */ err = send_mcast_pkt(skb, netdev); } dev_kfree_skb(skb); if (err) BT_DBG("ERROR: xmit failed (%d)", err); return (err < 0) ? NET_XMIT_DROP : err; return err < 0 ? NET_XMIT_DROP : err; } static const struct net_device_ops netdev_ops = { Loading @@ -617,7 +655,8 @@ static void netdev_setup(struct net_device *dev) dev->needed_tailroom = 0; dev->mtu = IPV6_MIN_MTU; dev->tx_queue_len = 0; dev->flags = IFF_RUNNING | IFF_POINTOPOINT; dev->flags = IFF_RUNNING | IFF_POINTOPOINT | IFF_MULTICAST; dev->watchdog_timeo = 0; dev->netdev_ops = &netdev_ops; Loading Loading @@ -950,6 +989,9 @@ static void chan_suspend_cb(struct l2cap_chan *chan) BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb); if (!skb) return; lowpan_cb(skb)->status = -EAGAIN; } Loading @@ -959,6 +1001,9 @@ static void chan_resume_cb(struct l2cap_chan *chan) BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb); if (!skb) return; lowpan_cb(skb)->status = 0; } Loading net/bluetooth/l2cap_core.c +8 −5 Original line number Diff line number Diff line Loading @@ -6980,8 +6980,6 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, hci_dev_lock(hdev); l2cap_chan_lock(chan); if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid && chan->chan_type != L2CAP_CHAN_RAW) { err = -EINVAL; Loading Loading @@ -7078,17 +7076,20 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, goto done; } mutex_lock(&conn->chan_lock); l2cap_chan_lock(chan); if (cid && __l2cap_get_chan_by_dcid(conn, cid)) { hci_conn_drop(hcon); err = -EBUSY; goto done; goto chan_unlock; } /* Update source addr of the socket */ bacpy(&chan->src, &hcon->src); chan->src_type = bdaddr_type(hcon, hcon->src_type); l2cap_chan_add(conn, chan); __l2cap_chan_add(conn, chan); /* l2cap_chan_add takes its own ref so we can drop this one */ hci_conn_drop(hcon); Loading @@ -7114,8 +7115,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, err = 0; done: chan_unlock: l2cap_chan_unlock(chan); mutex_unlock(&conn->chan_lock); done: hci_dev_unlock(hdev); hci_dev_put(hdev); return err; Loading Loading
drivers/bluetooth/Kconfig +2 −2 Original line number Diff line number Diff line Loading @@ -201,7 +201,7 @@ config BT_MRVL The core driver to support Marvell Bluetooth devices. This driver is required if you want to support Marvell Bluetooth devices, such as 8688/8787/8797/8897. Marvell Bluetooth devices, such as 8688/8787/8797/8887/8897. Say Y here to compile Marvell Bluetooth driver into the kernel or say M to compile it as module. Loading @@ -214,7 +214,7 @@ config BT_MRVL_SDIO The driver for Marvell Bluetooth chipsets with SDIO interface. This driver is required if you want to use Marvell Bluetooth devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897 devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8887/SD8897 chipsets are supported. Say Y here to compile support for Marvell BT-over-SDIO driver Loading
drivers/bluetooth/btmrvl_sdio.c +34 −2 Original line number Diff line number Diff line Loading @@ -84,7 +84,27 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { .int_read_to_clear = false, }; static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { static const struct btmrvl_sdio_card_reg btmrvl_reg_8887 = { .cfg = 0x00, .host_int_mask = 0x08, .host_intstatus = 0x0C, .card_status = 0x5C, .sq_read_base_addr_a0 = 0x6C, .sq_read_base_addr_a1 = 0x6D, .card_revision = 0xC8, .card_fw_status0 = 0x88, .card_fw_status1 = 0x89, .card_rx_len = 0x8A, .card_rx_unit = 0x8B, .io_port_0 = 0xE4, .io_port_1 = 0xE5, .io_port_2 = 0xE6, .int_read_to_clear = true, .host_int_rsr = 0x04, .card_misc_cfg = 0xD8, }; static const struct btmrvl_sdio_card_reg btmrvl_reg_8897 = { .cfg = 0x00, .host_int_mask = 0x02, .host_intstatus = 0x03, Loading Loading @@ -128,10 +148,18 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { .sd_blksz_fw_dl = 256, }; static const struct btmrvl_sdio_device btmrvl_sdio_sd8887 = { .helper = NULL, .firmware = "mrvl/sd8887_uapsta.bin", .reg = &btmrvl_reg_8887, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, }; static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { .helper = NULL, .firmware = "mrvl/sd8897_uapsta.bin", .reg = &btmrvl_reg_88xx, .reg = &btmrvl_reg_8897, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, }; Loading @@ -149,6 +177,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8797 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, /* Marvell SD8887 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9136), .driver_data = (unsigned long)&btmrvl_sdio_sd8887 }, /* Marvell SD8897 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E), .driver_data = (unsigned long) &btmrvl_sdio_sd8897 }, Loading Loading @@ -1280,4 +1311,5 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin"); MODULE_FIRMWARE("mrvl/sd8688.bin"); MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
drivers/bluetooth/btusb.c +0 −4 Original line number Diff line number Diff line Loading @@ -268,8 +268,6 @@ struct btusb_data { struct usb_interface *intf; struct usb_interface *isoc; spinlock_t lock; unsigned long flags; struct work_struct work; Loading Loading @@ -2002,8 +2000,6 @@ static int btusb_probe(struct usb_interface *intf, data->udev = interface_to_usbdev(intf); data->intf = intf; spin_lock_init(&data->lock); INIT_WORK(&data->work, btusb_work); INIT_WORK(&data->waker, btusb_waker); init_usb_anchor(&data->deferred); Loading
net/bluetooth/6lowpan.c +95 −50 Original line number Diff line number Diff line Loading @@ -426,38 +426,33 @@ static void convert_dest_bdaddr(struct in6_addr *ip6_daddr, *addr_type = get_addr_type_from_eui64(addr->b[5]); } static int header_create(struct sk_buff *skb, struct net_device *netdev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len) static int setup_header(struct sk_buff *skb, struct net_device *netdev, bdaddr_t *peer_addr, u8 *peer_addr_type) { struct ipv6hdr *hdr; struct in6_addr ipv6_daddr; struct lowpan_dev *dev; struct lowpan_peer *peer; bdaddr_t addr, *any = BDADDR_ANY; u8 *saddr, *daddr = any->b; u8 addr_type; if (type != ETH_P_IPV6) return -EINVAL; hdr = ipv6_hdr(skb); u8 *daddr = any->b; int err, status = 0; dev = lowpan_dev(netdev); if (ipv6_addr_is_multicast(&hdr->daddr)) { memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); memcpy(&ipv6_daddr, &lowpan_cb(skb)->addr, sizeof(ipv6_daddr)); if (ipv6_addr_is_multicast(&ipv6_daddr)) { lowpan_cb(skb)->chan = NULL; } else { unsigned long flags; u8 addr_type; /* Get destination BT device from skb. * If there is no such peer then discard the packet. */ convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type); convert_dest_bdaddr(&ipv6_daddr, &addr, &addr_type); BT_DBG("dest addr %pMR type %d IP %pI6c", &addr, addr_type, &hdr->daddr); addr_type, &ipv6_daddr); read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_ba(dev, &addr, addr_type); Loading @@ -470,7 +465,7 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, * the destination address. */ read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_dst(dev, &hdr->daddr, skb); peer = peer_lookup_dst(dev, &ipv6_daddr, skb); read_unlock_irqrestore(&devices_lock, flags); if (!peer) { BT_DBG("no such peer %pMR found", &addr); Loading @@ -479,15 +474,37 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, } daddr = peer->eui64_addr; memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); *peer_addr = addr; *peer_addr_type = addr_type; lowpan_cb(skb)->chan = peer->chan; status = 1; } saddr = dev->netdev->dev_addr; lowpan_header_compress(skb, netdev, ETH_P_IPV6, daddr, dev->netdev->dev_addr, skb->len); err = dev_hard_header(skb, netdev, ETH_P_IPV6, NULL, NULL, 0); if (err < 0) return err; return lowpan_header_compress(skb, netdev, type, daddr, saddr, len); return status; } static int header_create(struct sk_buff *skb, struct net_device *netdev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len) { struct ipv6hdr *hdr; if (type != ETH_P_IPV6) return -EINVAL; hdr = ipv6_hdr(skb); memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); return 0; } /* Packet to BT LE device */ Loading Loading @@ -529,11 +546,12 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, return err; } static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) { struct sk_buff *local_skb; struct lowpan_dev *entry, *tmp; unsigned long flags; int err = 0; read_lock_irqsave(&devices_lock, flags); Loading @@ -547,57 +565,77 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) dev = lowpan_dev(entry->netdev); list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) { int ret; local_skb = skb_clone(skb, GFP_ATOMIC); send_pkt(pentry->chan, local_skb, netdev); BT_DBG("xmit %s to %pMR type %d IP %pI6c chan %p", netdev->name, &pentry->chan->dst, pentry->chan->dst_type, &pentry->peer_addr, pentry->chan); ret = send_pkt(pentry->chan, local_skb, netdev); if (ret < 0) err = ret; kfree_skb(local_skb); } } read_unlock_irqrestore(&devices_lock, flags); return err; } static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) { int err = 0; struct lowpan_dev *dev; struct lowpan_peer *peer; bdaddr_t addr; u8 addr_type; struct sk_buff *tmpskb; if (ipv6_addr_is_multicast(&lowpan_cb(skb)->addr)) { /* We need to send the packet to every device * behind this interface. /* We must take a copy of the skb before we modify/replace the ipv6 * header as the header could be used elsewhere */ send_mcast_pkt(skb, netdev); } else { unsigned long flags; convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type); dev = lowpan_dev(netdev); tmpskb = skb_unshare(skb, GFP_ATOMIC); if (!tmpskb) { kfree_skb(skb); return NET_XMIT_DROP; } skb = tmpskb; read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_ba(dev, &addr, addr_type); if (!peer) peer = peer_lookup_dst(dev, &lowpan_cb(skb)->addr, skb); read_unlock_irqrestore(&devices_lock, flags); /* Return values from setup_header() * <0 - error, packet is dropped * 0 - this is a multicast packet * 1 - this is unicast packet */ err = setup_header(skb, netdev, &addr, &addr_type); if (err < 0) { kfree_skb(skb); return NET_XMIT_DROP; } BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p", if (err) { if (lowpan_cb(skb)->chan) { BT_DBG("xmit %s to %pMR type %d IP %pI6c chan %p", netdev->name, &addr, addr_type, &lowpan_cb(skb)->addr, peer); if (peer && peer->chan) err = send_pkt(peer->chan, skb, netdev); else &lowpan_cb(skb)->addr, lowpan_cb(skb)->chan); err = send_pkt(lowpan_cb(skb)->chan, skb, netdev); } else { err = -ENOENT; } } else { /* We need to send the packet to every device behind this * interface. */ err = send_mcast_pkt(skb, netdev); } dev_kfree_skb(skb); if (err) BT_DBG("ERROR: xmit failed (%d)", err); return (err < 0) ? NET_XMIT_DROP : err; return err < 0 ? NET_XMIT_DROP : err; } static const struct net_device_ops netdev_ops = { Loading @@ -617,7 +655,8 @@ static void netdev_setup(struct net_device *dev) dev->needed_tailroom = 0; dev->mtu = IPV6_MIN_MTU; dev->tx_queue_len = 0; dev->flags = IFF_RUNNING | IFF_POINTOPOINT; dev->flags = IFF_RUNNING | IFF_POINTOPOINT | IFF_MULTICAST; dev->watchdog_timeo = 0; dev->netdev_ops = &netdev_ops; Loading Loading @@ -950,6 +989,9 @@ static void chan_suspend_cb(struct l2cap_chan *chan) BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb); if (!skb) return; lowpan_cb(skb)->status = -EAGAIN; } Loading @@ -959,6 +1001,9 @@ static void chan_resume_cb(struct l2cap_chan *chan) BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb); if (!skb) return; lowpan_cb(skb)->status = 0; } Loading
net/bluetooth/l2cap_core.c +8 −5 Original line number Diff line number Diff line Loading @@ -6980,8 +6980,6 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, hci_dev_lock(hdev); l2cap_chan_lock(chan); if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid && chan->chan_type != L2CAP_CHAN_RAW) { err = -EINVAL; Loading Loading @@ -7078,17 +7076,20 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, goto done; } mutex_lock(&conn->chan_lock); l2cap_chan_lock(chan); if (cid && __l2cap_get_chan_by_dcid(conn, cid)) { hci_conn_drop(hcon); err = -EBUSY; goto done; goto chan_unlock; } /* Update source addr of the socket */ bacpy(&chan->src, &hcon->src); chan->src_type = bdaddr_type(hcon, hcon->src_type); l2cap_chan_add(conn, chan); __l2cap_chan_add(conn, chan); /* l2cap_chan_add takes its own ref so we can drop this one */ hci_conn_drop(hcon); Loading @@ -7114,8 +7115,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, err = 0; done: chan_unlock: l2cap_chan_unlock(chan); mutex_unlock(&conn->chan_lock); done: hci_dev_unlock(hdev); hci_dev_put(hdev); return err; Loading