diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 21:04:47 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 21:04:47 -0700 |
| commit | 3b59bf081622b6446db77ad06c93fe23677bc533 (patch) | |
| tree | 3f4bb5a27c90cc86994a1f6d3c53fbf9208003cb /include/net | |
| parent | e45836fafe157df137a837093037f741ad8f4c90 (diff) | |
| parent | bbdb32cb5b73597386913d052165423b9d736145 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking merge from David Miller:
"1) Move ixgbe driver over to purely page based buffering on receive.
From Alexander Duyck.
2) Add receive packet steering support to e1000e, from Bruce Allan.
3) Convert TCP MD5 support over to RCU, from Eric Dumazet.
4) Reduce cpu usage in handling out-of-order TCP packets on modern
systems, also from Eric Dumazet.
5) Support the IP{,V6}_UNICAST_IF socket options, making the wine
folks happy, from Erich Hoover.
6) Support VLAN trunking from guests in hyperv driver, from Haiyang
Zhang.
7) Support byte-queue-limtis in r8169, from Igor Maravic.
8) Outline code intended for IP_RECVTOS in IP_PKTOPTIONS existed but
was never properly implemented, Jiri Benc fixed that.
9) 64-bit statistics support in r8169 and 8139too, from Junchang Wang.
10) Support kernel side dump filtering by ctmark in netfilter
ctnetlink, from Pablo Neira Ayuso.
11) Support byte-queue-limits in gianfar driver, from Paul Gortmaker.
12) Add new peek socket options to assist with socket migration, from
Pavel Emelyanov.
13) Add sch_plug packet scheduler whose queue is controlled by
userland daemons using explicit freeze and release commands. From
Shriram Rajagopalan.
14) Fix FCOE checksum offload handling on transmit, from Yi Zou."
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1846 commits)
Fix pppol2tp getsockname()
Remove printk from rds_sendmsg
ipv6: fix incorrent ipv6 ipsec packet fragment
cpsw: Hook up default ndo_change_mtu.
net: qmi_wwan: fix build error due to cdc-wdm dependecy
netdev: driver: ethernet: Add TI CPSW driver
netdev: driver: ethernet: add cpsw address lookup engine support
phy: add am79c874 PHY support
mlx4_core: fix race on comm channel
bonding: send igmp report for its master
fs_enet: Add MPC5125 FEC support and PHY interface selection
net: bpf_jit: fix BPF_S_LDX_B_MSH compilation
net: update the usage of CHECKSUM_UNNECESSARY
fcoe: use CHECKSUM_UNNECESSARY instead of CHECKSUM_PARTIAL on tx
net: do not do gso for CHECKSUM_UNNECESSARY in netif_needs_gso
ixgbe: Fix issues with SR-IOV loopback when flow control is disabled
net/hyperv: Fix the code handling tx busy
ixgbe: fix namespace issues when FCoE/DCB is not enabled
rtlwifi: Remove unused ETH_ADDR_LEN defines
igbvf: Use ETH_ALEN
...
Fix up fairly trivial conflicts in drivers/isdn/gigaset/interface.c and
drivers/net/usb/{Kconfig,qmi_wwan.c} as per David.
Diffstat (limited to 'include/net')
34 files changed, 1082 insertions, 583 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index f68dce2d8d88..757a17638b1b 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -160,7 +160,6 @@ extern void addrconf_prefix_rcv(struct net_device *dev, extern int ipv6_sock_ac_join(struct sock *sk,int ifindex, const struct in6_addr *addr); extern int ipv6_sock_ac_drop(struct sock *sk,int ifindex, const struct in6_addr *addr); extern void ipv6_sock_ac_close(struct sock *sk); -extern int inet6_ac_check(struct sock *sk, const struct in6_addr *addr, int ifindex); extern int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr); extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr); diff --git a/include/net/arp.h b/include/net/arp.h index 0013dc87940b..4a1f3fb562eb 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -15,14 +15,14 @@ static inline u32 arp_hashfn(u32 key, const struct net_device *dev, u32 hash_rnd return val * hash_rnd; } -static inline struct neighbour *__ipv4_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, u32 key) +static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key) { struct neigh_hash_table *nht; struct neighbour *n; u32 hash_val; rcu_read_lock_bh(); - nht = rcu_dereference_bh(tbl->nht); + nht = rcu_dereference_bh(arp_tbl.nht); hash_val = arp_hashfn(key, dev, nht->hash_rnd[0]) >> (32 - nht->hash_shift); for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); n != NULL; diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 4a82ca0bb0b2..262ebd1747d4 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -109,12 +109,14 @@ struct bt_power { */ #define BT_CHANNEL_POLICY_AMP_PREFERRED 2 -__printf(2, 3) -int bt_printk(const char *level, const char *fmt, ...); +__printf(1, 2) +int bt_info(const char *fmt, ...); +__printf(1, 2) +int bt_err(const char *fmt, ...); -#define BT_INFO(fmt, arg...) bt_printk(KERN_INFO, pr_fmt(fmt), ##arg) -#define BT_ERR(fmt, arg...) bt_printk(KERN_ERR, pr_fmt(fmt), ##arg) -#define BT_DBG(fmt, arg...) pr_debug(fmt "\n", ##arg) +#define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__) +#define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__) +#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__) /* Connection and socket states */ enum { @@ -129,6 +131,33 @@ enum { BT_CLOSED }; +/* If unused will be removed by compiler */ +static inline const char *state_to_string(int state) +{ + switch (state) { + case BT_CONNECTED: + return "BT_CONNECTED"; + case BT_OPEN: + return "BT_OPEN"; + case BT_BOUND: + return "BT_BOUND"; + case BT_LISTEN: + return "BT_LISTEN"; + case BT_CONNECT: + return "BT_CONNECT"; + case BT_CONNECT2: + return "BT_CONNECT2"; + case BT_CONFIG: + return "BT_CONFIG"; + case BT_DISCONN: + return "BT_DISCONN"; + case BT_CLOSED: + return "BT_CLOSED"; + } + + return "invalid state"; +} + /* BD Address */ typedef struct { __u8 b[6]; @@ -193,7 +222,6 @@ struct bt_skb_cb { __u16 tx_seq; __u8 retries; __u8 sar; - unsigned short channel; __u8 force_active; }; #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 00596e816b4d..344b0f972828 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -77,14 +77,6 @@ enum { HCI_RAW, - HCI_SETUP, - HCI_AUTO_OFF, - HCI_MGMT, - HCI_PAIRABLE, - HCI_SERVICE_CACHE, - HCI_LINK_KEYS, - HCI_DEBUG_KEYS, - HCI_RESET, }; @@ -93,7 +85,22 @@ enum { * states from the controller. */ enum { + HCI_SETUP, + HCI_AUTO_OFF, + HCI_MGMT, + HCI_PAIRABLE, + HCI_SERVICE_CACHE, + HCI_LINK_KEYS, + HCI_DEBUG_KEYS, + HCI_LE_SCAN, + HCI_SSP_ENABLED, + HCI_HS_ENABLED, + HCI_LE_ENABLED, + HCI_CONNECTABLE, + HCI_DISCOVERABLE, + HCI_LINK_SECURITY, + HCI_PENDING_CLASS, }; /* HCI ioctl defines */ @@ -130,6 +137,7 @@ enum { #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ #define HCI_CMD_TIMEOUT (1000) /* 1 seconds */ +#define HCI_ACL_TX_TIMEOUT (45000) /* 45 seconds */ /* HCI data types */ #define HCI_COMMAND_PKT 0x01 @@ -229,7 +237,9 @@ enum { #define LMP_EXTFEATURES 0x80 /* Extended LMP features */ -#define LMP_HOST_LE 0x02 +#define LMP_HOST_SSP 0x01 +#define LMP_HOST_LE 0x02 +#define LMP_HOST_LE_BREDR 0x04 /* Connection modes */ #define HCI_CM_ACTIVE 0x0000 @@ -268,10 +278,11 @@ enum { #define HCI_LK_UNAUTH_COMBINATION 0x04 #define HCI_LK_AUTH_COMBINATION 0x05 #define HCI_LK_CHANGED_COMBINATION 0x06 -/* The spec doesn't define types for SMP keys */ -#define HCI_LK_SMP_LTK 0x81 -#define HCI_LK_SMP_IRK 0x82 -#define HCI_LK_SMP_CSRK 0x83 +/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */ +#define HCI_SMP_STK 0x80 +#define HCI_SMP_STK_SLAVE 0x81 +#define HCI_SMP_LTK 0x82 +#define HCI_SMP_LTK_SLAVE 0x83 /* ---- HCI Error Codes ---- */ #define HCI_ERROR_AUTH_FAILURE 0x05 @@ -284,6 +295,22 @@ enum { #define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 #define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01 +/* Extended Inquiry Response field types */ +#define EIR_FLAGS 0x01 /* flags */ +#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ +#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ +#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ +#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ +#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ +#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ +#define EIR_NAME_SHORT 0x08 /* shortened local name */ +#define EIR_NAME_COMPLETE 0x09 /* complete local name */ +#define EIR_TX_POWER 0x0A /* transmit power level */ +#define EIR_CLASS_OF_DEV 0x0D /* Class of Device */ +#define EIR_SSP_HASH_C 0x0E /* Simple Pairing Hash C */ +#define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */ +#define EIR_DEVICE_ID 0x10 /* device ID */ + /* ----- HCI Commands ---- */ #define HCI_OP_NOP 0x0000 @@ -666,8 +693,8 @@ struct hci_cp_host_buffer_size { #define HCI_OP_WRITE_EIR 0x0c52 struct hci_cp_write_eir { - uint8_t fec; - uint8_t data[HCI_MAX_EIR_LENGTH]; + __u8 fec; + __u8 data[HCI_MAX_EIR_LENGTH]; } __packed; #define HCI_OP_READ_SSP_MODE 0x0c55 @@ -698,8 +725,8 @@ struct hci_rp_read_flow_control_mode { #define HCI_OP_WRITE_LE_HOST_SUPPORTED 0x0c6d struct hci_cp_write_le_host_supported { - __u8 le; - __u8 simul; + __u8 le; + __u8 simul; } __packed; #define HCI_OP_READ_LOCAL_VERSION 0x1001 @@ -1155,6 +1182,19 @@ struct hci_ev_le_meta { __u8 subevent; } __packed; +#define HCI_EV_NUM_COMP_BLOCKS 0x48 +struct hci_comp_blocks_info { + __le16 handle; + __le16 pkts; + __le16 blocks; +} __packed; + +struct hci_ev_num_comp_blocks { + __le16 num_blocks; + __u8 num_hndl; + struct hci_comp_blocks_info handles[0]; +} __packed; + /* Low energy meta events */ #define HCI_EV_LE_CONN_COMPLETE 0x01 struct hci_ev_le_conn_complete { @@ -1288,6 +1328,7 @@ struct sockaddr_hci { #define HCI_CHANNEL_RAW 0 #define HCI_CHANNEL_CONTROL 1 +#define HCI_CHANNEL_MONITOR 2 struct hci_filter { unsigned long type_mask; @@ -1389,5 +1430,6 @@ struct hci_inquiry_req { #define IREQ_CACHE_FLUSH 0x0001 extern bool enable_hs; +extern bool enable_le; #endif /* __HCI_H */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 453893b3120e..daefaac51131 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -44,14 +44,31 @@ struct inquiry_data { }; struct inquiry_entry { - struct inquiry_entry *next; + struct list_head all; /* inq_cache.all */ + struct list_head list; /* unknown or resolve */ + enum { + NAME_NOT_KNOWN, + NAME_NEEDED, + NAME_PENDING, + NAME_KNOWN, + } name_state; __u32 timestamp; struct inquiry_data data; }; -struct inquiry_cache { +struct discovery_state { + int type; + enum { + DISCOVERY_STOPPED, + DISCOVERY_STARTING, + DISCOVERY_FINDING, + DISCOVERY_RESOLVING, + DISCOVERY_STOPPING, + } state; + struct list_head all; /* All devices found during inquiry */ + struct list_head unknown; /* Name state not known */ + struct list_head resolve; /* Name needs to be resolved */ __u32 timestamp; - struct inquiry_entry *list; }; struct hci_conn_hash { @@ -72,18 +89,16 @@ struct bt_uuid { u8 svc_hint; }; -struct key_master_id { - __le16 ediv; - u8 rand[8]; -} __packed; - -struct link_key_data { +struct smp_ltk { + struct list_head list; bdaddr_t bdaddr; + u8 bdaddr_type; + u8 authenticated; u8 type; + u8 enc_size; + __le16 ediv; + u8 rand[8]; u8 val[16]; - u8 pin_len; - u8 dlen; - u8 data[0]; } __packed; struct link_key { @@ -92,8 +107,6 @@ struct link_key { u8 type; u8 val[16]; u8 pin_len; - u8 dlen; - u8 data[0]; }; struct oob_data { @@ -109,11 +122,19 @@ struct adv_entry { u8 bdaddr_type; }; +struct le_scan_params { + u8 type; + u16 interval; + u16 window; + int timeout; +}; + +#define HCI_MAX_SHORT_NAME_LENGTH 10 + #define NUM_REASSEMBLY 4 struct hci_dev { struct list_head list; struct mutex lock; - atomic_t refcnt; char name[8]; unsigned long flags; @@ -122,6 +143,7 @@ struct hci_dev { __u8 dev_type; bdaddr_t bdaddr; __u8 dev_name[HCI_MAX_NAME_LENGTH]; + __u8 short_name[HCI_MAX_SHORT_NAME_LENGTH]; __u8 eir[HCI_MAX_EIR_LENGTH]; __u8 dev_class[3]; __u8 major_class; @@ -129,7 +151,6 @@ struct hci_dev { __u8 features[8]; __u8 host_features[8]; __u8 commands[64]; - __u8 ssp_mode; __u8 hci_ver; __u16 hci_rev; __u8 lmp_ver; @@ -217,7 +238,7 @@ struct hci_dev { struct list_head mgmt_pending; - struct inquiry_cache inq_cache; + struct discovery_state discovery; struct hci_conn_hash conn_hash; struct list_head blacklist; @@ -225,6 +246,8 @@ struct hci_dev { struct list_head link_keys; + struct list_head long_term_keys; + struct list_head remote_oob_data; struct list_head adv_entries; @@ -234,7 +257,6 @@ struct hci_dev { struct sk_buff_head driver_init; - void *driver_data; void *core_data; atomic_t promisc; @@ -246,15 +268,17 @@ struct hci_dev { struct rfkill *rfkill; - struct module *owner; - unsigned long dev_flags; + struct delayed_work le_scan_disable; + + struct work_struct le_scan; + struct le_scan_params le_scan_params; + int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); int (*send)(struct sk_buff *skb); - void (*destruct)(struct hci_dev *hdev); void (*notify)(struct hci_dev *hdev, unsigned int evt); int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); }; @@ -270,11 +294,10 @@ struct hci_conn { __u16 state; __u8 mode; __u8 type; - __u8 out; + bool out; __u8 attempt; __u8 dev_class[3]; __u8 features[8]; - __u8 ssp_mode; __u16 interval; __u16 pkt_type; __u16 link_policy; @@ -286,12 +309,10 @@ struct hci_conn { __u8 pin_length; __u8 enc_key_size; __u8 io_capability; - __u8 power_save; __u16 disc_timeout; - unsigned long pend; + unsigned long flags; __u8 remote_cap; - __u8 remote_oob; __u8 remote_auth; unsigned int sent; @@ -348,21 +369,26 @@ extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ -static inline void inquiry_cache_init(struct hci_dev *hdev) +static inline void discovery_init(struct hci_dev *hdev) { - struct inquiry_cache *c = &hdev->inq_cache; - c->list = NULL; + hdev->discovery.state = DISCOVERY_STOPPED; + INIT_LIST_HEAD(&hdev->discovery.all); + INIT_LIST_HEAD(&hdev->discovery.unknown); + INIT_LIST_HEAD(&hdev->discovery.resolve); } +bool hci_discovery_active(struct hci_dev *hdev); + +void hci_discovery_set_state(struct hci_dev *hdev, int state); + static inline int inquiry_cache_empty(struct hci_dev *hdev) { - struct inquiry_cache *c = &hdev->inq_cache; - return c->list == NULL; + return list_empty(&hdev->discovery.all); } static inline long inquiry_cache_age(struct hci_dev *hdev) { - struct inquiry_cache *c = &hdev->inq_cache; + struct discovery_state *c = &hdev->discovery; return jiffies - c->timestamp; } @@ -372,8 +398,16 @@ static inline long inquiry_entry_age(struct inquiry_entry *e) } struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, - bdaddr_t *bdaddr); -void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data); + bdaddr_t *bdaddr); +struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, + bdaddr_t *bdaddr); +struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, + bdaddr_t *bdaddr, + int state); +void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, + struct inquiry_entry *ie); +bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, + bool name_known, bool *ssp); /* ----- HCI Connections ----- */ enum { @@ -384,8 +418,19 @@ enum { HCI_CONN_MODE_CHANGE_PEND, HCI_CONN_SCO_SETUP_PEND, HCI_CONN_LE_SMP_PEND, + HCI_CONN_MGMT_CONNECTED, + HCI_CONN_SSP_ENABLED, + HCI_CONN_POWER_SAVE, + HCI_CONN_REMOTE_OOB, }; +static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) +{ + struct hci_dev *hdev = conn->hdev; + return (test_bit(HCI_SSP_ENABLED, &hdev->flags) && + test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)); +} + static inline void hci_conn_hash_init(struct hci_dev *hdev) { struct hci_conn_hash *h = &hdev->conn_hash; @@ -566,36 +611,33 @@ static inline void hci_conn_put(struct hci_conn *conn) } /* ----- HCI Devices ----- */ -static inline void __hci_dev_put(struct hci_dev *d) +static inline void hci_dev_put(struct hci_dev *d) { - if (atomic_dec_and_test(&d->refcnt)) - d->destruct(d); + put_device(&d->dev); } -/* - * hci_dev_put and hci_dev_hold are macros to avoid dragging all the - * overhead of all the modular infrastructure into this header. - */ -#define hci_dev_put(d) \ -do { \ - __hci_dev_put(d); \ - module_put(d->owner); \ -} while (0) - -static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d) +static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) { - atomic_inc(&d->refcnt); + get_device(&d->dev); return d; } -#define hci_dev_hold(d) \ -({ \ - try_module_get(d->owner) ? __hci_dev_hold(d) : NULL; \ -}) - #define hci_dev_lock(d) mutex_lock(&d->lock) #define hci_dev_unlock(d) mutex_unlock(&d->lock) +#define to_hci_dev(d) container_of(d, struct hci_dev, dev) +#define to_hci_conn(c) container_of(c, struct hci_conn, dev) + +static inline void *hci_get_drvdata(struct hci_dev *hdev) +{ + return dev_get_drvdata(&hdev->dev); +} + +static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) +{ + dev_set_drvdata(&hdev->dev, data); +} + struct hci_dev *hci_dev_get(int index); struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); @@ -619,20 +661,23 @@ int hci_inquiry(void __user *arg); struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); int hci_blacklist_clear(struct hci_dev *hdev); -int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr); +int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); +int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int hci_uuids_clear(struct hci_dev *hdev); int hci_link_keys_clear(struct hci_dev *hdev); struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, - bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len); -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]); -struct link_key *hci_find_link_key_type(struct hci_dev *hdev, - bdaddr_t *bdaddr, u8 type); -int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, - u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]); + bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len); +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]); +int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, + int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16 ediv, + u8 rand[8]); +struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 addr_type); +int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr); +int hci_smp_ltks_clear(struct hci_dev *hdev); int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); int hci_remote_oob_data_clear(struct hci_dev *hdev); @@ -674,6 +719,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) #define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) #define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) +#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) /* ----- Extended LMP capabilities ----- */ #define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE) @@ -755,7 +801,7 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) if (conn->type != ACL_LINK && conn->type != LE_LINK) return; - if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) return; encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; @@ -796,7 +842,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) hci_proto_auth_cfm(conn, status); - if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) return; encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; @@ -859,25 +905,71 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, read_unlock(&hci_cb_list_lock); } +static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) +{ + u8 field_len; + size_t parsed; + + for (parsed = 0; parsed < data_len - 1; parsed += field_len) { + field_len = data[0]; + + if (field_len == 0) + break; + + parsed += field_len + 1; + + if (parsed > data_len) + break; + + if (data[1] == type) + return true; + + data += field_len + 1; + } + + return false; +} + +static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, + u8 data_len) +{ + eir[eir_len++] = sizeof(type) + data_len; + eir[eir_len++] = type; + memcpy(&eir[eir_len], data, data_len); + eir_len += data_len; + + return eir_len; +} + int hci_register_cb(struct hci_cb *hcb); int hci_unregister_cb(struct hci_cb *hcb); -int hci_register_notifier(struct notifier_block *nb); -int hci_unregister_notifier(struct notifier_block *nb); - int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); -void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); - /* ----- HCI Sockets ----- */ -void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, - struct sock *skip_sk); +void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); +void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk); +void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); + +void hci_sock_dev_event(struct hci_dev *hdev, int event); /* Management interface */ +#define MGMT_ADDR_BREDR 0x00 +#define MGMT_ADDR_LE_PUBLIC 0x01 +#define MGMT_ADDR_LE_RANDOM 0x02 +#define MGMT_ADDR_INVALID 0xff + +#define DISCOV_TYPE_BREDR (BIT(MGMT_ADDR_BREDR)) +#define DISCOV_TYPE_LE (BIT(MGMT_ADDR_LE_PUBLIC) | \ + BIT(MGMT_ADDR_LE_RANDOM)) +#define DISCOV_TYPE_INTERLEAVED (BIT(MGMT_ADDR_BREDR) | \ + BIT(MGMT_ADDR_LE_PUBLIC) | \ + BIT(MGMT_ADDR_LE_RANDOM)) + int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_index_added(struct hci_dev *hdev); int mgmt_index_removed(struct hci_dev *hdev); @@ -886,56 +978,67 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); int mgmt_connectable(struct hci_dev *hdev, u8 connectable); int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, - u8 persistent); -int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type); -int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type); -int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status); + u8 persistent); +int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u32 flags, u8 *name, u8 name_len, + u8 *dev_class); +int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type); +int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type, u8 status); int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u8 status); + u8 addr_type, u8 status); int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 status); + u8 status); int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 status); + u8 status); int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, - __le32 value, u8 confirm_hint); + u8 link_type, u8 addr_type, __le32 value, + u8 confirm_hint); int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 status); -int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, - bdaddr_t *bdaddr, u8 status); -int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr); + u8 link_type, u8 addr_type, u8 status); +int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type, u8 status); +int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type); int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 status); -int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, - bdaddr_t *bdaddr, u8 status); -int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status); + u8 link_type, u8 addr_type, u8 status); +int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, + u8 link_type, u8 addr_type, u8 status); +int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, + u8 addr_type, u8 status); +int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); +int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); +int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, + u8 status); int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, - u8 *randomizer, u8 status); |
