Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

This commit is contained in:
John W. Linville 2014-08-25 15:58:02 -04:00
commit 07bc788424
22 changed files with 890 additions and 630 deletions

View File

@ -152,8 +152,8 @@ F: drivers/scsi/53c700*
6LOWPAN GENERIC (BTLE/IEEE 802.15.4)
M: Alexander Aring <alex.aring@gmail.com>
L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers)
L: linux-bluetooth@vger.kernel.org
L: linux-wpan@vger.kernel.org
S: Maintained
F: net/6lowpan/
F: include/net/6lowpan.h
@ -4580,13 +4580,14 @@ F: drivers/idle/i7300_idle.c
IEEE 802.15.4 SUBSYSTEM
M: Alexander Aring <alex.aring@gmail.com>
L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers)
W: http://apps.sourceforge.net/trac/linux-zigbee
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git
L: linux-wpan@vger.kernel.org
W: https://github.com/linux-wpan
T: git git://github.com/linux-wpan/linux-wpan-next.git
S: Maintained
F: net/ieee802154/
F: net/mac802154/
F: drivers/net/ieee802154/
F: Documentation/networking/ieee802154.txt
IGUANAWORKS USB IR TRANSCEIVER
M: Sean Young <sean@mess.org>

View File

@ -88,6 +88,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x04CA, 0x300b) },
{ USB_DEVICE(0x0930, 0x0219) },
{ USB_DEVICE(0x0930, 0x0220) },
{ USB_DEVICE(0x0930, 0x0227) },
{ USB_DEVICE(0x0b05, 0x17d0) },
{ USB_DEVICE(0x0CF3, 0x0036) },
{ USB_DEVICE(0x0CF3, 0x3004) },
@ -138,6 +139,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },

View File

@ -61,7 +61,7 @@ MODULE_LICENSE("GPL");
/* ======================== Local structures ======================== */
typedef struct bluecard_info_t {
struct bluecard_info {
struct pcmcia_device *p_dev;
struct hci_dev *hdev;
@ -78,7 +78,7 @@ typedef struct bluecard_info_t {
unsigned char ctrl_reg;
unsigned long hw_state; /* Status of the hardware and LED control */
} bluecard_info_t;
};
static int bluecard_config(struct pcmcia_device *link);
@ -157,7 +157,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev);
static void bluecard_activity_led_timeout(u_long arg)
{
bluecard_info_t *info = (bluecard_info_t *)arg;
struct bluecard_info *info = (struct bluecard_info *)arg;
unsigned int iobase = info->p_dev->resource[0]->start;
if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
@ -173,7 +173,7 @@ static void bluecard_activity_led_timeout(u_long arg)
}
static void bluecard_enable_activity_led(bluecard_info_t *info)
static void bluecard_enable_activity_led(struct bluecard_info *info)
{
unsigned int iobase = info->p_dev->resource[0]->start;
@ -215,7 +215,7 @@ static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, i
}
static void bluecard_write_wakeup(bluecard_info_t *info)
static void bluecard_write_wakeup(struct bluecard_info *info)
{
if (!info) {
BT_ERR("Unknown device");
@ -368,7 +368,8 @@ static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, in
}
static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
static void bluecard_receive(struct bluecard_info *info,
unsigned int offset)
{
unsigned int iobase;
unsigned char buf[31];
@ -497,7 +498,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
{
bluecard_info_t *info = dev_inst;
struct bluecard_info *info = dev_inst;
unsigned int iobase;
unsigned char reg;
@ -562,7 +563,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
struct bluecard_info *info = hci_get_drvdata(hdev);
struct sk_buff *skb;
/* Ericsson baud rate command */
@ -611,7 +612,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
static int bluecard_hci_flush(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
struct bluecard_info *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -622,7 +623,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
struct bluecard_info *info = hci_get_drvdata(hdev);
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
@ -643,7 +644,7 @@ static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
struct bluecard_info *info = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
return 0;
@ -663,7 +664,7 @@ static int bluecard_hci_close(struct hci_dev *hdev)
static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
struct bluecard_info *info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -691,7 +692,7 @@ static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
/* ======================== Card services HCI interaction ======================== */
static int bluecard_open(bluecard_info_t *info)
static int bluecard_open(struct bluecard_info *info)
{
unsigned int iobase = info->p_dev->resource[0]->start;
struct hci_dev *hdev;
@ -806,7 +807,7 @@ static int bluecard_open(bluecard_info_t *info)
}
static int bluecard_close(bluecard_info_t *info)
static int bluecard_close(struct bluecard_info *info)
{
unsigned int iobase = info->p_dev->resource[0]->start;
struct hci_dev *hdev = info->hdev;
@ -833,7 +834,7 @@ static int bluecard_close(bluecard_info_t *info)
static int bluecard_probe(struct pcmcia_device *link)
{
bluecard_info_t *info;
struct bluecard_info *info;
/* Create new info device */
info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
@ -857,7 +858,7 @@ static void bluecard_detach(struct pcmcia_device *link)
static int bluecard_config(struct pcmcia_device *link)
{
bluecard_info_t *info = link->priv;
struct bluecard_info *info = link->priv;
int i, n;
link->config_index = 0x20;
@ -897,7 +898,7 @@ failed:
static void bluecard_release(struct pcmcia_device *link)
{
bluecard_info_t *info = link->priv;
struct bluecard_info *info = link->priv;
bluecard_close(info);

View File

@ -67,7 +67,7 @@ MODULE_FIRMWARE("BT3CPCC.bin");
/* ======================== Local structures ======================== */
typedef struct bt3c_info_t {
struct bt3c_info {
struct pcmcia_device *p_dev;
struct hci_dev *hdev;
@ -80,7 +80,7 @@ typedef struct bt3c_info_t {
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
} bt3c_info_t;
};
static int bt3c_config(struct pcmcia_device *link);
@ -175,7 +175,7 @@ static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
}
static void bt3c_write_wakeup(bt3c_info_t *info)
static void bt3c_write_wakeup(struct bt3c_info *info)
{
if (!info) {
BT_ERR("Unknown device");
@ -214,7 +214,7 @@ static void bt3c_write_wakeup(bt3c_info_t *info)
}
static void bt3c_receive(bt3c_info_t *info)
static void bt3c_receive(struct bt3c_info *info)
{
unsigned int iobase;
int size = 0, avail;
@ -336,7 +336,7 @@ static void bt3c_receive(bt3c_info_t *info)
static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
{
bt3c_info_t *info = dev_inst;
struct bt3c_info *info = dev_inst;
unsigned int iobase;
int iir;
irqreturn_t r = IRQ_NONE;
@ -388,7 +388,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
static int bt3c_hci_flush(struct hci_dev *hdev)
{
bt3c_info_t *info = hci_get_drvdata(hdev);
struct bt3c_info *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -418,7 +418,7 @@ static int bt3c_hci_close(struct hci_dev *hdev)
static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
bt3c_info_t *info = hci_get_drvdata(hdev);
struct bt3c_info *info = hci_get_drvdata(hdev);
unsigned long flags;
switch (bt_cb(skb)->pkt_type) {
@ -451,7 +451,8 @@ static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
/* ======================== Card services HCI interaction ======================== */
static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware,
static int bt3c_load_firmware(struct bt3c_info *info,
const unsigned char *firmware,
int count)
{
char *ptr = (char *) firmware;
@ -536,7 +537,7 @@ error:
}
static int bt3c_open(bt3c_info_t *info)
static int bt3c_open(struct bt3c_info *info)
{
const struct firmware *firmware;
struct hci_dev *hdev;
@ -603,7 +604,7 @@ error:
}
static int bt3c_close(bt3c_info_t *info)
static int bt3c_close(struct bt3c_info *info)
{
struct hci_dev *hdev = info->hdev;
@ -620,7 +621,7 @@ static int bt3c_close(bt3c_info_t *info)
static int bt3c_probe(struct pcmcia_device *link)
{
bt3c_info_t *info;
struct bt3c_info *info;
/* Create new info device */
info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
@ -683,7 +684,7 @@ static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
static int bt3c_config(struct pcmcia_device *link)
{
bt3c_info_t *info = link->priv;
struct bt3c_info *info = link->priv;
int i;
unsigned long try;
@ -724,7 +725,7 @@ failed:
static void bt3c_release(struct pcmcia_device *link)
{
bt3c_info_t *info = link->priv;
struct bt3c_info *info = link->priv;
bt3c_close(info);

View File

@ -62,7 +62,7 @@ MODULE_LICENSE("GPL");
/* ======================== Local structures ======================== */
typedef struct btuart_info_t {
struct btuart_info {
struct pcmcia_device *p_dev;
struct hci_dev *hdev;
@ -75,7 +75,7 @@ typedef struct btuart_info_t {
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
} btuart_info_t;
};
static int btuart_config(struct pcmcia_device *link);
@ -127,7 +127,7 @@ static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
}
static void btuart_write_wakeup(btuart_info_t *info)
static void btuart_write_wakeup(struct btuart_info *info)
{
if (!info) {
BT_ERR("Unknown device");
@ -172,7 +172,7 @@ static void btuart_write_wakeup(btuart_info_t *info)
}
static void btuart_receive(btuart_info_t *info)
static void btuart_receive(struct btuart_info *info)
{
unsigned int iobase;
int boguscount = 0;
@ -286,7 +286,7 @@ static void btuart_receive(btuart_info_t *info)
static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
{
btuart_info_t *info = dev_inst;
struct btuart_info *info = dev_inst;
unsigned int iobase;
int boguscount = 0;
int iir, lsr;
@ -340,7 +340,8 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
}
static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
static void btuart_change_speed(struct btuart_info *info,
unsigned int speed)
{
unsigned long flags;
unsigned int iobase;
@ -397,7 +398,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
static int btuart_hci_flush(struct hci_dev *hdev)
{
btuart_info_t *info = hci_get_drvdata(hdev);
struct btuart_info *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -427,7 +428,7 @@ static int btuart_hci_close(struct hci_dev *hdev)
static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
btuart_info_t *info = hci_get_drvdata(hdev);
struct btuart_info *info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -455,7 +456,7 @@ static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
/* ======================== Card services HCI interaction ======================== */
static int btuart_open(btuart_info_t *info)
static int btuart_open(struct btuart_info *info)
{
unsigned long flags;
unsigned int iobase = info->p_dev->resource[0]->start;
@ -521,7 +522,7 @@ static int btuart_open(btuart_info_t *info)
}
static int btuart_close(btuart_info_t *info)
static int btuart_close(struct btuart_info *info)
{
unsigned long flags;
unsigned int iobase = info->p_dev->resource[0]->start;
@ -550,7 +551,7 @@ static int btuart_close(btuart_info_t *info)
static int btuart_probe(struct pcmcia_device *link)
{
btuart_info_t *info;
struct btuart_info *info;
/* Create new info device */
info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
@ -613,7 +614,7 @@ static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
static int btuart_config(struct pcmcia_device *link)
{
btuart_info_t *info = link->priv;
struct btuart_info *info = link->priv;
int i;
int try;
@ -654,7 +655,7 @@ failed:
static void btuart_release(struct pcmcia_device *link)
{
btuart_info_t *info = link->priv;
struct btuart_info *info = link->priv;
btuart_close(info);

View File

@ -165,6 +165,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },

View File

@ -62,7 +62,7 @@ MODULE_LICENSE("GPL");
/* ======================== Local structures ======================== */
typedef struct dtl1_info_t {
struct dtl1_info {
struct pcmcia_device *p_dev;
struct hci_dev *hdev;
@ -78,7 +78,7 @@ typedef struct dtl1_info_t {
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
} dtl1_info_t;
};
static int dtl1_config(struct pcmcia_device *link);
@ -94,11 +94,11 @@ static int dtl1_config(struct pcmcia_device *link);
#define RECV_WAIT_DATA 1
typedef struct {
struct nsh {
u8 type;
u8 zero;
u16 len;
} __packed nsh_t; /* Nokia Specific Header */
} __packed; /* Nokia Specific Header */
#define NSHL 4 /* Nokia Specific Header Length */
@ -126,7 +126,7 @@ static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
}
static void dtl1_write_wakeup(dtl1_info_t *info)
static void dtl1_write_wakeup(struct dtl1_info *info)
{
if (!info) {
BT_ERR("Unknown device");
@ -176,7 +176,7 @@ static void dtl1_write_wakeup(dtl1_info_t *info)
}
static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
static void dtl1_control(struct dtl1_info *info, struct sk_buff *skb)
{
u8 flowmask = *(u8 *)skb->data;
int i;
@ -199,10 +199,10 @@ static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
}
static void dtl1_receive(dtl1_info_t *info)
static void dtl1_receive(struct dtl1_info *info)
{
unsigned int iobase;
nsh_t *nsh;
struct nsh *nsh;
int boguscount = 0;
if (!info) {
@ -227,7 +227,7 @@ static void dtl1_receive(dtl1_info_t *info)
}
*skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
nsh = (nsh_t *)info->rx_skb->data;
nsh = (struct nsh *)info->rx_skb->data;
info->rx_count--;
@ -287,7 +287,7 @@ static void dtl1_receive(dtl1_info_t *info)
static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
{
dtl1_info_t *info = dev_inst;
struct dtl1_info *info = dev_inst;
unsigned int iobase;
unsigned char msr;
int boguscount = 0;
@ -365,7 +365,7 @@ static int dtl1_hci_open(struct hci_dev *hdev)
static int dtl1_hci_flush(struct hci_dev *hdev)
{
dtl1_info_t *info = hci_get_drvdata(hdev);
struct dtl1_info *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -387,9 +387,9 @@ static int dtl1_hci_close(struct hci_dev *hdev)
static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
dtl1_info_t *info = hci_get_drvdata(hdev);
struct dtl1_info *info = hci_get_drvdata(hdev);
struct sk_buff *s;
nsh_t nsh;
struct nsh nsh;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -436,7 +436,7 @@ static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
/* ======================== Card services HCI interaction ======================== */
static int dtl1_open(dtl1_info_t *info)
static int dtl1_open(struct dtl1_info *info)
{
unsigned long flags;
unsigned int iobase = info->p_dev->resource[0]->start;
@ -505,7 +505,7 @@ static int dtl1_open(dtl1_info_t *info)
}
static int dtl1_close(dtl1_info_t *info)
static int dtl1_close(struct dtl1_info *info)
{
unsigned long flags;
unsigned int iobase = info->p_dev->resource[0]->start;
@ -534,7 +534,7 @@ static int dtl1_close(dtl1_info_t *info)
static int dtl1_probe(struct pcmcia_device *link)
{
dtl1_info_t *info;
struct dtl1_info *info;
/* Create new info device */
info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
@ -552,7 +552,7 @@ static int dtl1_probe(struct pcmcia_device *link)
static void dtl1_detach(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
struct dtl1_info *info = link->priv;
dtl1_close(info);
pcmcia_disable_device(link);
@ -571,7 +571,7 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
static int dtl1_config(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
struct dtl1_info *info = link->priv;
int ret;
/* Look for a generic full-sized window */

View File

@ -237,7 +237,7 @@ static void h5_pkt_cull(struct h5 *h5)
break;
to_remove--;
seq = (seq - 1) % 8;
seq = (seq - 1) & 0x07;
}
if (seq != h5->rx_ack)

View File

@ -302,7 +302,7 @@ struct hci_dev {
__u32 req_status;
__u32 req_result;
struct crypto_blkcipher *tfm_aes;
void *smp_data;
struct discovery_state discovery;
struct hci_conn_hash conn_hash;
@ -968,6 +968,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE))
#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \
!test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
/* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01
@ -1256,6 +1259,8 @@ bool hci_req_pending(struct hci_dev *hdev);
void hci_req_add_le_scan_disable(struct hci_request *req);
void hci_req_add_le_passive_scan(struct hci_request *req);
void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req);
struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
const void *param, u32 timeout);
struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
@ -1351,6 +1356,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, s8 rssi, u8 *name, u8 name_len);
void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
bool mgmt_powering_down(struct hci_dev *hdev);
void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,

View File

@ -625,6 +625,9 @@ struct l2cap_conn {
struct delayed_work info_timer;
int disconn_err;
struct work_struct disconn_work;
struct sk_buff *rx_skb;
__u32 rx_len;
__u8 tx_ident;
@ -635,8 +638,7 @@ struct l2cap_conn {
__u8 disc_reason;
struct delayed_work security_timer;
struct smp_chan *smp_chan;
struct l2cap_chan *smp;
struct list_head chan_l;
struct mutex chan_lock;
@ -708,6 +710,7 @@ enum {
FLAG_EFS_ENABLE,
FLAG_DEFER_SETUP,
FLAG_LE_CONN_REQ_SENT,
FLAG_PENDING_SECURITY,
};
enum {
@ -837,18 +840,43 @@ static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan
return NULL;
}
static inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb)
{
return -ENOSYS;
}
static inline struct sk_buff *l2cap_chan_no_alloc_skb(struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb)
{
return ERR_PTR(-ENOSYS);
}
static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err)
{
}
static inline void l2cap_chan_no_close(struct l2cap_chan *chan)
{
}
static inline void l2cap_chan_no_ready(struct l2cap_chan *chan)
{
}
static inline void l2cap_chan_no_state_change(struct l2cap_chan *chan,
int state, int err)
{
}
static inline void l2cap_chan_no_defer(struct l2cap_chan *chan)
{
}
static inline void l2cap_chan_no_suspend(struct l2cap_chan *chan)
{
}
static inline void l2cap_chan_no_resume(struct l2cap_chan *chan)
{
}
@ -918,6 +946,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
u8 status);
void __l2cap_physical_cfm(struct l2cap_chan *chan, int result);
void l2cap_conn_shutdown(struct l2cap_conn *conn, int err);
void l2cap_conn_get(struct l2cap_conn *conn);
void l2cap_conn_put(struct l2cap_conn *conn);

View File

@ -772,16 +772,16 @@ static inline void chan_ready_cb(struct l2cap_chan *chan)
ifup(dev->netdev);
}
static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *chan)
static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan)
{
struct l2cap_chan *pchan;
struct l2cap_chan *chan;
pchan = chan_open(chan);
pchan->ops = chan->ops;
chan = chan_open(pchan);
chan->ops = pchan->ops;
BT_DBG("chan %p pchan %p", chan, pchan);
return pchan;
return chan;
}
static void delete_netdev(struct work_struct *work)

View File

@ -1898,6 +1898,8 @@ static int __hci_init(struct hci_dev *hdev)
debugfs_create_u16("discov_interleaved_timeout", 0644,
hdev->debugfs,
&hdev->discov_interleaved_timeout);
smp_register(hdev);
}
return 0;
@ -3233,7 +3235,7 @@ struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
}
list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
if (smp_irk_matches(hdev, irk->val, rpa)) {
bacpy(&irk->rpa, rpa);
return irk;
}
@ -3882,7 +3884,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
!bacmp(&hdev->random_addr, &hdev->rpa))
return 0;
err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa);
err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
if (err < 0) {
BT_ERR("%s failed to generate new RPA", hdev->name);
return err;
@ -4090,18 +4092,9 @@ int hci_register_dev(struct hci_dev *hdev)
dev_set_name(&hdev->dev, "%s", hdev->name);
hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(hdev->tfm_aes)) {
BT_ERR("Unable to create crypto context");
error = PTR_ERR(hdev->tfm_aes);
hdev->tfm_aes = NULL;
goto err_wqueue;
}
error = device_add(&hdev->dev);
if (error < 0)
goto err_tfm;
goto err_wqueue;
hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
@ -4143,8 +4136,6 @@ int hci_register_dev(struct hci_dev *hdev)
return id;
err_tfm:
crypto_free_blkcipher(hdev->tfm_aes);
err_wqueue:
destroy_workqueue(hdev->workqueue);
destroy_workqueue(hdev->req_workqueue);
@ -4196,8 +4187,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
rfkill_destroy(hdev->rfkill);
}
if (hdev->tfm_aes)
crypto_free_blkcipher(hdev->tfm_aes);
smp_unregister(hdev);
device_del(&hdev->dev);
@ -5680,3 +5670,52 @@ void hci_update_background_scan(struct hci_dev *hdev)
if (err)
BT_ERR("Failed to run HCI request: err %d", err);
}
static bool disconnected_whitelist_entries(struct hci_dev *hdev)
{
struct bdaddr_list *b;
list_for_each_entry(b, &hdev->whitelist, list) {
struct hci_conn *conn;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr);
if (!conn)
return true;
if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
return true;
}
return false;
}
void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req)
{
u8 scan;
if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
return;
if (!hdev_is_powered(hdev))
return;
if (mgmt_powering_down(hdev))
return;
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
disconnected_whitelist_entries(hdev))
scan = SCAN_PAGE;
else
scan = SCAN_DISABLED;
if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE))
return;
if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
scan |= SCAN_INQUIRY;
if (req)
hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
else
hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
}

View File

@ -2071,6 +2071,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
cp.handle = ev->handle;
hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
sizeof(cp), &cp);
hci_update_page_scan(hdev, NULL);
}
/* Set packet type for incoming connection */
@ -2247,10 +2249,13 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
reason, mgmt_connected);
if (conn->type == ACL_LINK &&
test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
if (conn->type == ACL_LINK) {
if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
hci_remove_link_key(hdev, &conn->dst);
hci_update_page_scan(hdev, NULL);
}
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
if (params) {
switch (params->auto_connect) {

View File

@ -210,6 +210,10 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
{
write_lock(&chan_list_lock);
/* Override the defaults (which are for conn-oriented) */
chan->omtu = L2CAP_DEFAULT_MTU;
chan->chan_type = L2CAP_CHAN_FIXED;
chan->scid = scid;
write_unlock(&chan_list_lock);
@ -562,6 +566,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
chan->ops->teardown(chan, err);
if (conn) {
struct amp_mgr *mgr = conn->hcon->amp_mgr;
/* Delete from channel list */
@ -585,8 +591,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
amp_disconnect_logical_link(hs_hchan);
}
chan->ops->teardown(chan, err);
if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
return;
@ -1082,6 +1086,9 @@ static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
{
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
return true;
return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
}
@ -1417,71 +1424,18 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
mutex_unlock(&conn->chan_lock);
}
/* Find socket with cid and source/destination bdaddr.
* Returns closest match, locked.
*/
static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
bdaddr_t *src,
bdaddr_t *dst)
{
struct l2cap_chan *c, *c1 = NULL;
read_lock(&chan_list_lock);
list_for_each_entry(c, &chan_list, global_l) {
if (state && c->state != state)
continue;
if (c->scid == cid) {
int src_match, dst_match;
int src_any, dst_any;
/* Exact match. */
src_match = !bacmp(&c->src, src);
dst_match = !bacmp(&c->dst, dst);
if (src_match && dst_match) {
read_unlock(&chan_list_lock);
return c;
}
/* Closest match */
src_any = !bacmp(&c->src, BDADDR_ANY);
dst_any = !bacmp(&c->dst, BDADDR_ANY);
if ((src_match && dst_any) || (src_any && dst_match) ||
(src_any && dst_any))
c1 = c;
}
}
read_unlock(&chan_list_lock);
return c1;
}
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
struct hci_conn *hcon = conn->hcon;
struct hci_dev *hdev = hcon->hdev;
struct l2cap_chan *chan, *pchan;
u8 dst_type;
BT_DBG("");
BT_DBG("%s conn %p", hdev->name, conn);
/* Check if we have socket listening on cid */
pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
&hcon->src, &hcon->dst);
if (!pchan)
return;
/* Client ATT sockets should override the server one */
if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
return;
dst_type = bdaddr_type(hcon, hcon->dst_type);
/* If device is blocked, do not create a channel for it */
if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type))
return;
/* For outgoing pairing which doesn't necessarily have an
* associated socket (e.g. mgmt_pair_device).
*/
if (hcon->out)
smp_conn_security(hcon, hcon->pending_sec_level);
/* For LE slave connections, make sure the connection interval
* is in the range of the minium and maximum interval that has
@ -1501,22 +1455,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req);
}
l2cap_chan_lock(pchan);
chan = pchan->ops->new_connection(pchan);
if (!chan)
goto clean;
bacpy(&chan->src, &hcon->src);
bacpy(&chan->dst, &hcon->dst);
chan->src_type = bdaddr_type(hcon, hcon->src_type);
chan->dst_type = dst_type;
__l2cap_chan_add(conn, chan);
clean:
l2cap_chan_unlock(pchan);
}
static void l2cap_conn_ready(struct l2cap_conn *conn)
@ -1526,17 +1464,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
BT_DBG("conn %p", conn);
/* For outgoing pairing which doesn't necessarily have an
* associated socket (e.g. mgmt_pair_device).
*/
if (hcon->out && hcon->type == LE_LINK)
smp_conn_security(hcon, hcon->pending_sec_level);
mutex_lock(&conn->chan_lock);
if (hcon->type == LE_LINK)
l2cap_le_conn_ready(conn);
list_for_each_entry(chan, &conn->chan_l, list) {
l2cap_chan_lock(chan);
@ -1560,6 +1489,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
mutex_unlock(&conn->chan_lock);
if (hcon->type == LE_LINK)
l2cap_le_conn_ready(conn);
queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
}
@ -1695,6 +1627,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
if (work_pending(&conn->pending_rx_work))
cancel_work_sync(&conn->pending_rx_work);
if (work_pending(&conn->disconn_work))
cancel_work_sync(&conn->disconn_work);
l2cap_unregister_all_users(conn);
mutex_lock(&conn->chan_lock);
@ -1719,27 +1654,29 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
cancel_delayed_work_sync(&conn->info_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}
hcon->l2cap_data = NULL;
conn->hchan = NULL;
l2cap_conn_put(conn);
}
static void security_timeout(struct work_struct *work)
static void disconn_work(struct work_struct *work)
{
struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
security_timer.work);
disconn_work);
BT_DBG("conn %p", conn);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
smp_chan_destroy(conn);
l2cap_conn_del(conn->hcon, ETIMEDOUT);
}
l2cap_conn_del(conn->hcon, conn->disconn_err);
}
void l2cap_conn_shutdown(struct l2cap_conn *conn, int err)
{
struct hci_dev *hdev = conn->hcon->hdev;
BT_DBG("conn %p err %d", conn, err);
conn->disconn_err = err;
queue_work(hdev->workqueue, &conn->disconn_work);
}
static void l2cap_conn_free(struct kref *ref)
@ -1794,6 +1731,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
src_match = !bacmp(&c->src, src);
dst_match = !bacmp(&c->dst, dst);
if (src_match && dst_match) {
l2cap_chan_hold(c);
read_unlock(&chan_list_lock);
return c;
}
@ -1807,6 +1745,9 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
}
}
if (c1)
l2cap_chan_hold(c1);
read_unlock(&chan_list_lock);
return c1;
@ -2027,10 +1968,12 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan)
tx_skb->data + L2CAP_HDR_SIZE);
}
/* Update FCS */
if (chan->fcs == L2CAP_FCS_CRC16) {
u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
put_unaligned_le16(fcs, skb_put(tx_skb,
L2CAP_FCS_SIZE));
u16 fcs = crc16(0, (u8 *) tx_skb->data,
tx_skb->len - L2CAP_FCS_SIZE);
put_unaligned_le16(fcs, skb_tail_pointer(tx_skb) -
L2CAP_FCS_SIZE);
}
l2cap_do_send(chan, tx_skb);
@ -2334,7 +2277,6 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
} else {
sar = L2CAP_SAR_START;
sdu_len = len;
pdu_len -= L2CAP_SDULEN_SIZE;
}
while (len > 0) {
@ -2349,10 +2291,8 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,
__skb_queue_tail(seg_queue, skb);
len -= pdu_len;
if (sdu_len) {
if (sdu_len)
sdu_len = 0;
pdu_len += L2CAP_SDULEN_SIZE;
}
if (len <= pdu_len) {
sar = L2CAP_SAR_END;
@ -3884,6 +3824,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
response:
l2cap_chan_unlock(pchan);
mutex_unlock(&conn->chan_lock);
l2cap_chan_put(pchan);
sendresp:
rsp.scid = cpu_to_le16(scid);
@ -5497,6 +5438,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
response_unlock:
l2cap_chan_unlock(pchan);
mutex_unlock(&conn->chan_lock);
l2cap_chan_put(pchan);
if (result == L2CAP_CR_PEND)
return 0;
@ -6845,12 +6787,12 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
struct l2cap_chan *chan;
if (hcon->type != ACL_LINK)
goto drop;
goto free_skb;
chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
ACL_LINK);
if (!chan)
goto drop;
goto free_skb;
BT_DBG("chan %p, len %d", chan, skb->len);
@ -6864,36 +6806,14 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
bt_cb(skb)->psm = psm;
if (!chan->ops->recv(chan, skb))
return;
drop:
kfree_skb(skb);
}
static void l2cap_att_channel(struct l2cap_conn *conn,
struct sk_buff *skb)
{
struct hci_conn *hcon = conn->hcon;
struct l2cap_chan *chan;
if (hcon->type != LE_LINK)
goto drop;
chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
&hcon->src, &hcon->dst);
if (!chan)
goto drop;
BT_DBG("chan %p, len %d", chan, skb->len);
if (chan->imtu < skb->len)
goto drop;
if (!chan->ops->recv(chan, skb))
if (!chan->ops->recv(chan, skb)) {
l2cap_chan_put(chan);
return;
}
drop:
l2cap_chan_put(chan);
free_skb:
kfree_skb(skb);
}
@ -6942,19 +6862,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
l2cap_conless_channel(conn, psm, skb);
break;
case L2CAP_CID_ATT:
l2cap_att_channel(conn, skb);
break;
case L2CAP_CID_LE_SIGNALING:
l2cap_le_sig_channel(conn, skb);
break;
case L2CAP_CID_SMP:
if (smp_sig_channel(conn, skb))
l2cap_conn_del(conn->hcon, EACCES);
break;
default:
l2cap_data_channel(conn, cid, skb);
break;
@ -7023,11 +6934,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
INIT_LIST_HEAD(&conn->chan_l);
INIT_LIST_HEAD(&conn->users);
if (hcon->type == LE_LINK)
INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
else
INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
INIT_WORK(&conn->disconn_work, disconn_work);
skb_queue_head_init(&conn->pending_rx);
INIT_WORK(&conn->pending_rx_work, process_pending_rx);
@ -7239,19 +7149,99 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
return exact ? lm1 : lm2;
}
/* Find the next fixed channel in BT_LISTEN state, continue iteration
* from an existing channel in the list or from the beginning of the
* global list (by passing NULL as first parameter).
*/
static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c,
bdaddr_t *src, u8 link_type)
{
read_lock(&chan_list_lock);
if (c)
c = list_next_entry(c, global_l);
else
c = list_entry(chan_list.next, typeof(*c), global_l);
list_for_each_entry_from(c, &chan_list, global_l) {
if (c->chan_type != L2CAP_CHAN_FIXED)
continue;
if (c->state != BT_LISTEN)
continue;
if (bacmp(&c->src, src) && bacmp(&c->src, BDADDR_ANY))
continue;
if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
continue;
if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
continue;
l2cap_chan_hold(c);
read_unlock(&chan_list_lock);
return c;
}
read_unlock(&chan_list_lock);
return NULL;
}
void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
{
struct hci_dev *hdev = hcon->hdev;
struct l2cap_conn *conn;
struct l2cap_chan *pchan;
u8 dst_type;
BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
if (!status) {
conn = l2cap_conn_add(hcon);
if (conn)
l2cap_conn_ready(conn);
} else {
if (status) {
l2cap_conn_del(hcon, bt_to_errno(status));
return;
}
conn = l2cap_conn_add(hcon);
if (!conn)
return;
dst_type = bdaddr_type(hcon, hcon->dst_type);
/* If device is blocked, do not create channels for it */
if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type))
return;
/* Find fixed channels and notify them of the new connection. We
* use multiple individual lookups, continuing each time where
* we left off, because the list lock would prevent calling the
* potentially sleeping l2cap_chan_lock() function.
*/
pchan = l2cap_global_fixed_chan(NULL, &hdev->bdaddr, hcon->type);
while (pchan) {
struct l2cap_chan *chan, *next;
/* Client fixed channels should override server ones */
if (__l2cap_get_chan_by_dcid(conn, pchan->scid))
goto next;
l2cap_chan_lock(pchan);
chan = pchan->ops->new_connection(pchan);
if (chan) {
bacpy(&chan->src, &hcon->src);
bacpy(&chan->dst, &hcon->dst);
chan->src_type = bdaddr_type(hcon, hcon->src_type);
chan->dst_type = dst_type;
__l2cap_chan_add(conn, chan);
}
l2cap_chan_unlock(pchan);
next:
next = l2cap_global_fixed_chan(pchan, &hdev->bdaddr,
hcon->type);
l2cap_chan_put(pchan);
pchan = next;
}
l2cap_conn_ready(conn);
}
int l2cap_disconn_ind(struct hci_conn *hcon)
@ -7299,12 +7289,6 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
if (hcon->type == LE_LINK) {
if (!status && encrypt)
smp_distribute_keys(conn);
cancel_delayed_work(&conn->security_timer);
}
mutex_lock(&conn->chan_lock);
list_for_each_entry(chan, &conn->chan_l, list) {
@ -7318,15 +7302,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
continue;
}
if (chan->scid == L2CAP_CID_ATT) {
if (!status && encrypt) {
if (!status && encrypt)
chan->sec_level = hcon->sec_level;
l2cap_chan_ready(chan);
}
l2cap_chan_unlock(chan);
continue;
}
if (!__l2cap_no_conn_pending(chan)) {
l2cap_chan_unlock(chan);

View File

@ -99,15 +99,6 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
return -EINVAL;
if (la.l2_cid) {
/* When the socket gets created it defaults to
* CHAN_CONN_ORIENTED, so we need to overwrite the
* default here.
*/
chan->chan_type = L2CAP_CHAN_FIXED;
chan->omtu = L2CAP_DEFAULT_MTU;
}
if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
/* We only allow ATT user space socket */
if (la.l2_cid &&
@ -790,6 +781,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
if (chan->scid == L2CAP_CID_ATT) {
if (smp_conn_security(conn->hcon, sec.level))
break;
set_bit(FLAG_PENDING_SECURITY, &chan->flags);
sk->sk_state = BT_CONFIG;
chan->state = BT_CONFIG;
@ -1359,6 +1351,11 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) {
sk->sk_state = BT_CONNECTED;
chan->state = BT_CONNECTED;
}
clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
sk->sk_state_change(sk);
}

View File

@ -129,9 +129,6 @@ static const u16 mgmt_events[] = {
#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \
!test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
struct pending_cmd {
struct list_head list;
u16 opcode;
@ -1536,9 +1533,11 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status)
/* When the discoverable mode gets changed, make sure
* that class of device has the limited discoverable
* bit correctly set.
* bit correctly set. Also update page scan based on whitelist
* entries.
*/
hci_req_init(&req, hdev);
hci_update_page_scan(hdev, &req);
update_class(&req);
hci_req_run(&req, NULL);
@ -1785,6 +1784,7 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status)
if (conn_changed || discov_changed) {
new_settings(hdev, cmd->sk);
hci_update_page_scan(hdev, NULL);
if (discov_changed)
mgmt_update_adv_data(hdev);
hci_update_background_scan(hdev);
@ -1818,6 +1818,7 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
return err;
if (changed) {
hci_update_page_scan(hdev, NULL);
hci_update_background_scan(hdev);
return new_settings(hdev, sk);
}
@ -4381,27 +4382,6 @@ unlock:
return err;
}
static void set_bredr_scan(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;
u8 scan = 0;
/* Ensure that fast connectable is disabled. This function will
* not do anything if the page scan parameters are already what
* they should be.
*/
write_fast_connectable(req, false);
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
!list_empty(&hdev->whitelist))
scan |= SCAN_PAGE;
if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
scan |= SCAN_INQUIRY;
if (scan)
hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
}
static void set_bredr_complete(struct hci_dev *hdev, u8 status)
{
struct pending_cmd *cmd;
@ -4507,9 +4487,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
hci_req_init(&req, hdev);
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
!list_empty(&hdev->whitelist))
set_bredr_scan(&req);
write_fast_connectable(&req, false);
hci_update_page_scan(hdev, &req);
/* Since only the advertising data flags will change, there
* is no need to update the scan response data.
@ -5235,27 +5214,6 @@ unlock:
return err;
}
/* Helper for Add/Remove Device commands */
static void update_page_scan(struct hci_dev *hdev, u8 scan)
{
if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
return;
if (!hdev_is_powered(hdev))
return;
/* If HCI_CONNECTABLE is set then Add/Remove Device should not
* make any changes to page scanning.
*/
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
return;
if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
scan |= SCAN_INQUIRY;
hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
}
static void device_added(struct sock *sk, struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type, u8 action)
{
@ -5291,8 +5249,6 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
hci_dev_lock(hdev);
if (cp->addr.type == BDADDR_BREDR) {
bool update_scan;
/* Only incoming connections action is supported for now */
if (cp->action != 0x01) {
err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
@ -5301,15 +5257,12 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
goto unlock;
}
update_scan = list_empty(&hdev->whitelist);
err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
cp->addr.type);
if (err)
goto unlock;
if (update_scan)
update_page_scan(hdev, SCAN_PAGE);
hci_update_page_scan(hdev, NULL);
goto added;
}
@ -5392,8 +5345,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
goto unlock;
}
if (list_empty(&hdev->whitelist))
update_page_scan(hdev, SCAN_DISABLED);
hci_update_page_scan(hdev, NULL);
device_removed(sk, hdev, &cp->addr.bdaddr,
cp->addr.type);
@ -5444,7 +5396,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
kfree(b);
}
update_page_scan(hdev, SCAN_DISABLED);
hci_update_page_scan(hdev, NULL);
list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) {
if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
@ -5969,8 +5921,8 @@ static int powered_update_hci(struct hci_dev *hdev)
sizeof(link_sec), &link_sec);
if (lmp_bredr_capable(hdev)) {
if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
set_bredr_scan(&req);
write_fast_connectable(&req, false);
hci_update_page_scan(hdev, &req);
update_class(&req);
update_name(&req);
update_eir(&req);
@ -6281,26 +6233,36 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
mgmt_pending_remove(cmd);
}
bool mgmt_powering_down(struct hci_dev *hdev)
{
struct pending_cmd *cmd;
struct mgmt_mode *cp;
cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
if (!cmd)
return false;
cp = cmd->param;
if (!cp->val)
return true;
return false;
}
void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 reason,
bool mgmt_connected)
{
struct mgmt_ev_device_disconnected ev;
struct pending_cmd *power_off;
struct sock *sk = NULL;
power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
if (power_off) {
struct mgmt_mode *cp = power_off->param;
/* The connection is still in hci_conn_hash so test for 1
* instead of 0 to know if this is the last one.
*/
if (!cp->val && hci_conn_count(hdev) == 1) {
if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
cancel_delayed_work(&hdev->power_off);
queue_work(hdev->req_workqueue, &hdev->power_off.work);
}
}
if (!mgmt_connected)
return;
@ -6359,20 +6321,14 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status)
{
struct mgmt_ev_connect_failed ev;
struct pending_cmd *power_off;
power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
if (power_off) {
struct mgmt_mode *cp = power_off->param;
/* The connection is still in hci_conn_hash so test for 1
* instead of 0 to know if this is the last one.
*/
if (!cp->val && hci_conn_count(hdev) == 1) {
if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
cancel_delayed_work(&hdev->power_off);
queue_work(hdev->req_workqueue, &hdev->power_off.work);
}
}
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = link_to_bdaddr(link_type, addr_type);

File diff suppressed because it is too large Load Diff

View File

@ -126,14 +126,12 @@ enum {
/* SMP Commands */
bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level);
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
int smp_distribute_keys(struct l2cap_conn *conn);
int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
void smp_chan_destroy(struct l2cap_conn *conn);
bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr);
int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa);
bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
bdaddr_t *bdaddr);
int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa);
int smp_register(struct hci_dev *hdev);
void smp_unregister(struct hci_dev *hdev);
#endif /* __SMP_H */

View File

@ -77,14 +77,6 @@ lowpan_dev_info *lowpan_dev_info(const struct net_device *dev)
return netdev_priv(dev);
}
static inline void lowpan_address_flip(u8 *src, u8 *dest)
{
int i;
for (i = 0; i < IEEE802154_ADDR_LEN; i++)
(dest)[IEEE802154_ADDR_LEN - i - 1] = (src)[i];
}
static int lowpan_header_create(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *_daddr,
const void *_saddr, unsigned int len)

View File

@ -86,9 +86,8 @@ fail:
static void mac802154_rx_worker(struct work_struct *work)
{
struct rx_work *rw = container_of(work, struct rx_work, work);
struct sk_buff *skb = rw->skb;
mac802154_subif_rx(rw->dev, skb, rw->lqi);
mac802154_subif_rx(rw->dev, rw->skb, rw->lqi);
kfree(rw);
}
@ -101,7 +100,7 @@ ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi)
if (!skb)
return;
work = kzalloc(sizeof(struct rx_work), GFP_ATOMIC);
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work)
return;

View File

@ -89,8 +89,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
if (!(priv->phy->channels_supported[page] & (1 << chan))) {
WARN_ON(1);
kfree_skb(skb);
return NETDEV_TX_OK;
goto err_tx;
}
mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb);
@ -103,12 +102,10 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
data[1] = crc >> 8;
}
if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) {
kfree_skb(skb);
return NETDEV_TX_OK;
}
if (skb_cow_head(skb, priv->hw.extra_tx_headroom))
goto err_tx;
work = kzalloc(sizeof(struct xmit_work), GFP_ATOMIC);
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
kfree_skb(skb);
return NETDEV_TX_BUSY;
@ -129,4 +126,8 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
queue_work(priv->dev_workqueue, &work->work);
return NETDEV_TX_OK;
err_tx:
kfree_skb(skb);
return NETDEV_TX_OK;
}

View File

@ -472,8 +472,7 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
rc = mac802154_llsec_decrypt(&sdata->sec, skb);
if (rc) {
pr_debug("decryption failed: %i\n", rc);
kfree_skb(skb);
return NET_RX_DROP;
goto fail;
}
sdata->dev->stats.rx_packets++;
@ -485,9 +484,12 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
default:
pr_warn("ieee802154: bad frame received (type = %d)\n",
mac_cb(skb)->type);
goto fail;
}
fail:
kfree_skb(skb);
return NET_RX_DROP;
}
}
static void mac802154_print_addr(const char *name,