diff options
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 15 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 59 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 68 | ||||
-rw-r--r-- | include/net/bluetooth/l2cap.h | 117 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt.h | 10 | ||||
-rw-r--r-- | include/net/bluetooth/rfcomm.h | 9 | ||||
-rw-r--r-- | include/net/bluetooth/smp.h | 46 | ||||
-rw-r--r-- | include/net/cfg80211.h | 11 | ||||
-rw-r--r-- | include/net/genetlink.h | 32 | ||||
-rw-r--r-- | include/net/mac80211.h | 41 | ||||
-rw-r--r-- | include/net/netlink.h | 24 |
11 files changed, 367 insertions, 65 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 43750439c521..7bccaf921cab 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -69,6 +69,13 @@ struct bt_security { #define BT_FLUSHABLE_OFF 0 #define BT_FLUSHABLE_ON 1 +#define BT_POWER 9 +struct bt_power { + __u8 force_active; +}; +#define BT_POWER_FORCE_ACTIVE_OFF 0 +#define BT_POWER_FORCE_ACTIVE_ON 1 + #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) @@ -130,7 +137,8 @@ int bt_sock_register(int proto, const struct net_proto_family *ops); int bt_sock_unregister(int proto); void bt_sock_link(struct bt_sock_list *l, struct sock *s); void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); -int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); +int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t len, int flags); int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); @@ -150,6 +158,7 @@ struct bt_skb_cb { __u8 retries; __u8 sar; unsigned short channel; + __u8 force_active; }; #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) @@ -164,8 +173,8 @@ static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) return skb; } -static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long len, - int nb, int *err) +static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, + unsigned long len, int nb, int *err) { struct sk_buff *skb; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 0c20227e57f6..65345cd215be 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -710,6 +710,12 @@ struct hci_rp_le_read_buffer_size { __u8 le_max_pkt; } __packed; +#define HCI_OP_LE_SET_SCAN_ENABLE 0x200c +struct hci_cp_le_set_scan_enable { + __u8 enable; + __u8 filter_dup; +} __packed; + #define HCI_OP_LE_CREATE_CONN 0x200d struct hci_cp_le_create_conn { __le16 scan_interval; @@ -739,6 +745,33 @@ struct hci_cp_le_conn_update { __le16 max_ce_len; } __packed; +#define HCI_OP_LE_START_ENC 0x2019 +struct hci_cp_le_start_enc { + __le16 handle; + __u8 rand[8]; + __le16 ediv; + __u8 ltk[16]; +} __packed; + +#define HCI_OP_LE_LTK_REPLY 0x201a +struct hci_cp_le_ltk_reply { + __le16 handle; + __u8 ltk[16]; +} __packed; +struct hci_rp_le_ltk_reply { + __u8 status; + __le16 handle; +} __packed; + +#define HCI_OP_LE_LTK_NEG_REPLY 0x201b +struct hci_cp_le_ltk_neg_reply { + __le16 handle; +} __packed; +struct hci_rp_le_ltk_neg_reply { + __u8 status; + __le16 handle; +} __packed; + /* ---- HCI Events ---- */ #define HCI_EV_INQUIRY_COMPLETE 0x01 @@ -1029,6 +1062,32 @@ struct hci_ev_le_conn_complete { __u8 clk_accurancy; } __packed; +#define HCI_EV_LE_LTK_REQ 0x05 +struct hci_ev_le_ltk_req { + __le16 handle; + __u8 random[8]; + __le16 ediv; +} __packed; + +/* Advertising report event types */ +#define ADV_IND 0x00 +#define ADV_DIRECT_IND 0x01 +#define ADV_SCAN_IND 0x02 +#define ADV_NONCONN_IND 0x03 +#define ADV_SCAN_RSP 0x04 + +#define ADDR_LE_DEV_PUBLIC 0x00 +#define ADDR_LE_DEV_RANDOM 0x01 + +#define HCI_EV_LE_ADVERTISING_REPORT 0x02 +struct hci_ev_le_advertising_info { + __u8 evt_type; + __u8 bdaddr_type; + bdaddr_t bdaddr; + __u8 length; + __u8 data[0]; +} __packed; + /* Internal events generated by Bluetooth stack */ #define HCI_EV_STACK_INTERNAL 0xfd struct hci_ev_stack_internal { diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6c994c004d15..26233d4d371c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -89,6 +89,12 @@ struct oob_data { u8 randomizer[16]; }; +struct adv_entry { + struct list_head list; + bdaddr_t bdaddr; + u8 bdaddr_type; +}; + #define NUM_REASSEMBLY 4 struct hci_dev { struct list_head list; @@ -171,6 +177,8 @@ struct hci_dev { __u16 init_last_cmd; + struct crypto_blkcipher *tfm; + struct inquiry_cache inq_cache; struct hci_conn_hash conn_hash; struct list_head blacklist; @@ -181,6 +189,9 @@ struct hci_dev { struct list_head remote_oob_data; + struct list_head adv_entries; + struct timer_list adv_timer; + struct hci_dev_stats stat; struct sk_buff_head driver_init; @@ -215,6 +226,7 @@ struct hci_conn { spinlock_t lock; bdaddr_t dst; + __u8 dst_type; __u16 handle; __u16 state; __u8 mode; @@ -237,6 +249,7 @@ struct hci_conn { __u8 power_save; __u16 disc_timeout; unsigned long pend; + __u8 ltk[16]; __u8 remote_cap; __u8 remote_oob; @@ -307,12 +320,14 @@ static inline long inquiry_entry_age(struct inquiry_entry *e) return jiffies - e->timestamp; } -struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); +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); /* ----- HCI Connections ----- */ enum { HCI_CONN_AUTH_PEND, + HCI_CONN_REAUTH_PEND, HCI_CONN_ENCRYPT_PEND, HCI_CONN_RSWITCH_PEND, HCI_CONN_MODE_CHANGE_PEND, @@ -420,14 +435,15 @@ int hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); -struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, + __u8 sec_level, __u8 auth_type); int hci_conn_check_link_mode(struct hci_conn *conn); int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); int hci_conn_change_link_key(struct hci_conn *conn); int hci_conn_switch_role(struct hci_conn *conn, __u8 role); -void hci_conn_enter_active_mode(struct hci_conn *conn); +void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); void hci_conn_enter_sniff_mode(struct hci_conn *conn); void hci_conn_hold_device(struct hci_conn *conn); @@ -449,10 +465,12 @@ static inline void hci_conn_put(struct hci_conn *conn) timeo = msecs_to_jiffies(conn->disc_timeout); if (!conn->out) timeo *= 2; - } else + } else { timeo = msecs_to_jiffies(10); - } else + } + } else { timeo = msecs_to_jiffies(10); + } mod_timer(&conn->disc_timer, jiffies + timeo); } } @@ -511,6 +529,8 @@ 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_uuids_clear(struct hci_dev *hdev); @@ -527,6 +547,12 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, u8 *randomizer); int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); +#define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */ +int hci_adv_entries_clear(struct hci_dev *hdev); +struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr); +int hci_add_adv_entry(struct hci_dev *hdev, + struct hci_ev_le_advertising_info *ev); + void hci_del_off_timer(struct hci_dev *hdev); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); @@ -561,16 +587,20 @@ struct hci_proto { void *priv; - int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); + int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, + __u8 type); int (*connect_cfm) (struct hci_conn *conn, __u8 status); int (*disconn_ind) (struct hci_conn *conn); int (*disconn_cfm) (struct hci_conn *conn, __u8 reason); - int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); + int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, + __u16 flags); int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); - int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); + int (*security_cfm) (struct hci_conn *conn, __u8 status, + __u8 encrypt); }; -static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) +static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, + __u8 type) { register struct hci_proto *hp; int mask = 0; @@ -656,7 +686,8 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) conn->security_cfm_cb(conn, status); } -static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) +static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, + __u8 encrypt) { register struct hci_proto *hp; @@ -681,7 +712,8 @@ struct hci_cb { char *name; - void (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); + void (*security_cfm) (struct hci_conn *conn, __u8 status, + __u8 encrypt); void (*key_change_cfm) (struct hci_conn *conn, __u8 status); void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); }; @@ -707,13 +739,17 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) read_unlock_bh(&hci_cb_list_lock); } -static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) +static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, + __u8 encrypt) { struct list_head *p; if (conn->sec_level == BT_SECURITY_SDP) conn->sec_level = BT_SECURITY_LOW; + if (conn->pending_sec_level > conn->sec_level) + conn->sec_level = conn->pending_sec_level; + hci_proto_encrypt_cfm(conn, status, encrypt); read_lock_bh(&hci_cb_list_lock); @@ -738,7 +774,8 @@ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) read_unlock_bh(&hci_cb_list_lock); } -static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role) +static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, + __u8 role) { struct list_head *p; @@ -830,4 +867,9 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result); void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, u16 to_multiplier); +void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], + __u8 ltk[16]); +void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]); +void hci_le_ltk_neg_reply(struct hci_conn *conn); + #endif /* __HCI_CORE_H */ diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index d09c9b1118e3..9c18e555b6ed 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -287,6 +287,10 @@ struct l2cap_chan { struct l2cap_conn *conn; + __u8 state; + + atomic_t refcnt; + __le16 psm; __u16 dcid; __u16 scid; @@ -295,6 +299,7 @@ struct l2cap_chan { __u16 omtu; __u16 flush_to; __u8 mode; + __u8 chan_type; __le16 sport; @@ -302,6 +307,7 @@ struct l2cap_chan { __u8 role_switch; __u8 force_reliable; __u8 flushable; + __u8 force_active; __u8 ident; @@ -318,8 +324,8 @@ struct l2cap_chan { __u16 monitor_timeout; __u16 mps; - __u8 conf_state; - __u16 conn_state; + unsigned long conf_state; + unsigned long conn_state; __u8 next_tx_seq; __u8 expected_ack_seq; @@ -339,6 +345,7 @@ struct l2cap_chan { __u8 remote_max_tx; __u16 remote_mps; + struct timer_list chan_timer; struct timer_list retrans_timer; struct timer_list monitor_timer; struct timer_list ack_timer; @@ -351,6 +358,18 @@ struct l2cap_chan { struct list_head list; struct list_head global_l; + + void *data; + struct l2cap_ops *ops; +}; + +struct l2cap_ops { + char *name; + + struct l2cap_chan *(*new_connection) (void *data); + int (*recv) (void *data, struct sk_buff *skb); + void (*close) (void *data); + void (*state_change) (void *data, int state); }; struct l2cap_conn { @@ -376,6 +395,15 @@ struct l2cap_conn { __u8 disc_reason; + __u8 preq[7]; /* SMP Pairing Request */ + __u8 prsp[7]; /* SMP Pairing Response */ + __u8 prnd[16]; /* SMP Pairing Random */ + __u8 pcnf[16]; /* SMP Pairing Confirm */ + __u8 tk[16]; /* SMP Temporary Key */ + __u8 smp_key_size; + + struct timer_list security_timer; + struct list_head chan_l; rwlock_t chan_lock; }; @@ -384,6 +412,10 @@ struct l2cap_conn { #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 +#define L2CAP_CHAN_RAW 1 +#define L2CAP_CHAN_CONN_LESS 2 +#define L2CAP_CHAN_CONN_ORIENTED 3 + /* ----- L2CAP socket info ----- */ #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) @@ -392,36 +424,45 @@ struct l2cap_pinfo { struct l2cap_chan *chan; }; -#define L2CAP_CONF_REQ_SENT 0x01 -#define L2CAP_CONF_INPUT_DONE 0x02 -#define L2CAP_CONF_OUTPUT_DONE 0x04 -#define L2CAP_CONF_MTU_DONE 0x08 -#define L2CAP_CONF_MODE_DONE 0x10 -#define L2CAP_CONF_CONNECT_PEND 0x20 -#define L2CAP_CONF_NO_FCS_RECV 0x40 -#define L2CAP_CONF_STATE2_DEVICE 0x80 +enum { + CONF_REQ_SENT, + CONF_INPUT_DONE, + CONF_OUTPUT_DONE, + CONF_MTU_DONE, + CONF_MODE_DONE, + CONF_CONNECT_PEND, + CONF_NO_FCS_RECV, + CONF_STATE2_DEVICE, +}; #define L2CAP_CONF_MAX_CONF_REQ 2 #define L2CAP_CONF_MAX_CONF_RSP 2 -#define L2CAP_CONN_SAR_SDU 0x0001 -#define L2CAP_CONN_SREJ_SENT 0x0002 -#define L2CAP_CONN_WAIT_F 0x0004 -#define L2CAP_CONN_SREJ_ACT 0x0008 -#define L2CAP_CONN_SEND_PBIT 0x0010 -#define L2CAP_CONN_REMOTE_BUSY 0x0020 -#define L2CAP_CONN_LOCAL_BUSY 0x0040 -#define L2CAP_CONN_REJ_ACT 0x0080 -#define L2CAP_CONN_SEND_FBIT 0x0100 -#define L2CAP_CONN_RNR_SENT 0x0200 -#define L2CAP_CONN_SAR_RETRY 0x0400 - -#define __mod_retrans_timer() mod_timer(&chan->retrans_timer, \ - jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); -#define __mod_monitor_timer() mod_timer(&chan->monitor_timer, \ - jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); -#define __mod_ack_timer() mod_timer(&chan->ack_timer, \ - jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); +enum { + CONN_SAR_SDU, + CONN_SREJ_SENT, + CONN_WAIT_F, + CONN_SREJ_ACT, + CONN_SEND_PBIT, + CONN_REMOTE_BUSY, + CONN_LOCAL_BUSY, + CONN_REJ_ACT, + CONN_SEND_FBIT, + CONN_RNR_SENT, + CONN_SAR_RETRY, +}; + +#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) +#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) +#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ + L2CAP_DEFAULT_RETRANS_TO); +#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) +#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ + L2CAP_DEFAULT_MONITOR_TO); +#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) +#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ + L2CAP_DEFAULT_ACK_TO); +#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) static inline int l2cap_tx_window_full(struct l2cap_chan *ch) { @@ -446,32 +487,16 @@ extern int disable_ertm; int l2cap_init_sockets(void); void l2cap_cleanup_sockets(void); -void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); int __l2cap_wait_ack(struct sock *sk); -struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); -struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); -struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen); -int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); -void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb); -void l2cap_streaming_send(struct l2cap_chan *chan); -int l2cap_ertm_send(struct l2cap_chan *chan); - int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); -void l2cap_sock_set_timer(struct sock *sk, long timeout); -void l2cap_sock_clear_timer(struct sock *sk); -void __l2cap_sock_close(struct sock *sk, int reason); -void l2cap_sock_kill(struct sock *sk); -void l2cap_sock_init(struct sock *sk, struct sock *parent); -struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, - int proto, gfp_t prio); -void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); struct l2cap_chan *l2cap_chan_create(struct sock *sk); -void l2cap_chan_del(struct l2cap_chan *chan, int err); +void l2cap_chan_close(struct l2cap_chan *chan, int reason); void l2cap_chan_destroy(struct l2cap_chan *chan); int l2cap_chan_connect(struct l2cap_chan *chan); +int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len); #endif /* __L2CAP_H */ diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 4899286ed4e4..45bea25d737f 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -199,6 +199,16 @@ struct mgmt_cp_remove_remote_oob_data { #define MGMT_OP_STOP_DISCOVERY 0x001C +#define MGMT_OP_BLOCK_DEVICE 0x001D +struct mgmt_cp_block_device { + bdaddr_t bdaddr; +} __packed; + +#define MGMT_OP_UNBLOCK_DEVICE 0x001E +struct mgmt_cp_unblock_device { + bdaddr_t bdaddr; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 6eac4a760c3b..d5eee2093b1e 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -234,7 +234,8 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, /* ---- RFCOMM DLCs (channels) ---- */ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio); void rfcomm_dlc_free(struct rfcomm_dlc *d); -int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel); +int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, + u8 channel); int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason); int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb); int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig); @@ -271,7 +272,8 @@ static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) } /* ---- RFCOMM sessions ---- */ -void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst); +void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, + bdaddr_t *dst); static inline void rfcomm_session_hold(struct rfcomm_session *s) { @@ -312,7 +314,8 @@ struct rfcomm_pinfo { int rfcomm_init_sockets(void); void rfcomm_cleanup_sockets(void); -int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d); +int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, + struct rfcomm_dlc **d); /* ---- RFCOMM TTY ---- */ #define RFCOMM_MAX_DEV 256 diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h index 8f2edbf979dc..4fb7d198a876 100644 --- a/include/net/bluetooth/smp.h +++ b/include/net/bluetooth/smp.h @@ -1,3 +1,25 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + #ifndef __SMP_H #define __SMP_H @@ -16,6 +38,23 @@ struct smp_cmd_pairing { __u8 resp_key_dist; } __packed; +#define SMP_IO_DISPLAY_ONLY 0x00 +#define SMP_IO_DISPLAY_YESNO 0x01 +#define SMP_IO_KEYBOARD_ONLY 0x02 +#define SMP_IO_NO_INPUT_OUTPUT 0x03 +#define SMP_IO_KEYBOARD_DISPLAY 0x04 + +#define SMP_OOB_NOT_PRESENT 0x00 +#define SMP_OOB_PRESENT 0x01 + +#define SMP_DIST_ENC_KEY 0x01 +#define SMP_DIST_ID_KEY 0x02 +#define SMP_DIST_SIGN 0x04 + +#define SMP_AUTH_NONE 0x00 +#define SMP_AUTH_BONDING 0x01 +#define SMP_AUTH_MITM 0x04 + #define SMP_CMD_PAIRING_CONFIRM 0x03 struct smp_cmd_pairing_confirm { __u8 confirm_val[16]; @@ -73,4 +112,11 @@ struct smp_cmd_security_req { #define SMP_UNSPECIFIED 0x08 #define SMP_REPEATED_ATTEMPTS 0x09 +#define SMP_MIN_ENC_KEY_SIZE 7 +#define SMP_MAX_ENC_KEY_SIZE 16 + +/* SMP Commands */ +int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level); +int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); + #endif /* __SMP_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 396e8fc8910e..7202bce7bfeb 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1284,6 +1284,12 @@ struct cfg80211_wowlan { * frame on another channel * * @testmode_cmd: run a test mode command + * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be + * used by the function, but 0 and 1 must not be touched. Additionally, + * return error codes other than -ENOBUFS and -ENOENT will terminate the + * dump and return to userspace with an error, so be careful. If any data + * was passed in from userspace then the data/len arguments will be present + * and point to the data contained in %NL80211_ATTR_TESTDATA. * * @set_bitrate_mask: set the bitrate mask configuration * @@ -1433,6 +1439,9 @@ struct cfg80211_ops { #ifdef CONFIG_NL80211_TESTMODE int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len); + int (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb, + struct netlink_callback *cb, + void *data, int len); #endif int (*set_bitrate_mask)(struct wiphy *wiphy, @@ -2849,8 +2858,10 @@ struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp); #define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), +#define CFG80211_TESTMODE_DUMP(cmd) .testmode_dump = (cmd), #else #define CFG80211_TESTMODE_CMD(cmd) +#define CFG80211_TESTMODE_DUMP(cmd) #endif /** diff --git a/include/net/genetlink.h b/include/net/genetlink.h index d420f28b6d60..82d8d09faa44 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -160,6 +160,38 @@ static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, } /** + * genlmsg_nlhdr - Obtain netlink header from user specified header + * @user_hdr: user header as returned from genlmsg_put() + * @family: generic netlink family + * + * Returns pointer to netlink header. + */ +static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr, + struct genl_family *family) +{ + return (struct nlmsghdr *)((char *)user_hdr - + family->hdrsize - + GENL_HDRLEN - + NLMSG_HDRLEN); +} + +/** + * genl_dump_check_consistent - check if sequence is consistent and advertise if not + * @cb: netlink callback structure that stores the sequence number + * @user_hdr: user header as returned from genlmsg_put() + * @family: generic netlink family + * + * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it + * simpler to use with generic netlink. + */ +static inline void genl_dump_check_consistent(struct netlink_callback *cb, + void *user_hdr, + struct genl_family *family) +{ + nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr, family)); +} + +/** * genlmsg_put_reply - Add generic netlink header to a reply message * @skb: socket buffer holding the message * @info: receiver info diff --git a/include/net/mac80211.h b/include/net/mac80211.h index e6d6a66a8f71..120f102814b6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1708,6 +1708,14 @@ enum ieee80211_ampdu_mlme_action { * any error unless this callback returned a negative error code. * The callback can sleep. * + * @cancel_hw_scan: Ask the low-level tp cancel the active hw scan. + * The driver should ask the hardware to cancel the scan (if possible), + * but the scan will be completed only after the driver will call + * ieee80211_scan_completed(). + * This callback is needed for wowlan, to prevent enqueueing a new + * scan_work after the low-level driver was already suspended. + * The callback can sleep. + * * @sched_scan_start: Ask the hardware to start scanning repeatedly at * specific intervals. The driver must call the * ieee80211_sched_scan_results() function whenever it finds results. @@ -1816,6 +1824,7 @@ enum ieee80211_ampdu_mlme_action { * * @testmode_cmd: Implement a cfg80211 test mode command. * The callback can sleep. + * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. * * @flush: Flush all pending frames from the hardware queue, making sure * that the hardware queues are empty. If the parameter @drop is set @@ -1899,6 +1908,8 @@ struct ieee80211_ops { u32 iv32, u16 *phase1key); int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); + void (*cancel_hw_scan)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); int (*sched_scan_start)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, @@ -1936,6 +1947,9 @@ struct ieee80211_ops { void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class); #ifdef CONFIG_NL80211_TESTMODE int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len); + int (*testmode_dump)(struct ieee80211_hw *hw, struct sk_buff *skb, + struct netlink_callback *cb, + void *data, int len); #endif void (*flush)(struct ieee80211_hw *hw, bool drop); void (*channel_switch)(struct ieee80211_hw *hw, @@ -2916,6 +2930,16 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, gfp_t gfp); /** + * ieee80211_get_operstate - get the operstate of the vif + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * The driver might need to know the operstate of the net_device + * (specifically, whether the link is IF_OPER_UP after resume) + */ +unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif); + +/** * ieee80211_chswitch_done - Complete channel switch process * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @success: make the channel switch successful or not @@ -2965,6 +2989,23 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw); */ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw); +/** + * ieee80211_stop_rx_ba_session - callback to stop existing BA sessions + * + * in order not to harm the system performance and user experience, the device + * may request not to allow any rx ba session and tear down existing rx ba + * sessions based on system constraints such as periodic BT activity that needs + * to limit wlan activity (eg.sco or a2dp)." + * in such cases, the intention is to limit the duration of the rx ppdu and + * therefore prevent the peer device to use a-mpdu aggregation. + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @ba_rx_bitmap: Bit map of open rx ba per tid + * @addr: & to bssid mac address + */ +void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap, + const u8 *addr); + /* Rate control API */ /** diff --git a/include/net/netlink.h b/include/net/netlink.h index 02740a94f108..98c185441bee 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -638,6 +638,30 @@ static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid) nlmsg_ok(pos, rem); \ pos = nlmsg_next(pos, &(rem))) +/** + * nl_dump_check_consistent - check if sequence is consistent and advertise if not + * @cb: netlink callback structure that stores the sequence number + * @nlh: netlink message header to write the flag to + * + * This function checks if the sequence (generation) number changed during dump + * and if it did, advertises it in the netlink message header. + * + * The correct way to use it is to set cb->seq to the generation counter when + * all locks for dumping have been acquired, and then call this function for + * each message that is generated. + * + * Note that due to initialisation concerns, 0 is an invalid sequence number + * and must not be used by code that uses this functionality. + */ +static inline void +nl_dump_check_consistent(struct netlink_callback *cb, + struct nlmsghdr *nlh) +{ + if (cb->prev_seq && cb->seq != cb->prev_seq) + nlh->nlmsg_flags |= NLM_F_DUMP_INTR; + cb->prev_seq = cb->seq; +} + /************************************************************************** * Netlink Attributes **************************************************************************/ |