Bluetooth: Add support for setting LE advertising data
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / include / net / bluetooth / hci_core.h
index e7d454609881a30d929ec8aa613390df157c8b43..ef5b85dac3f77720c13ba69a6482b58a3043c018 100644 (file)
@@ -73,6 +73,7 @@ struct discovery_state {
 struct hci_conn_hash {
        struct list_head list;
        unsigned int     acl_num;
+       unsigned int     amp_num;
        unsigned int     sco_num;
        unsigned int     le_num;
 };
@@ -124,6 +125,14 @@ struct le_scan_params {
 
 #define HCI_MAX_SHORT_NAME_LENGTH      10
 
+struct amp_assoc {
+       __u16   len;
+       __u16   offset;
+       __u16   rem_len;
+       __u16   len_so_far;
+       __u8    data[HCI_MAX_AMP_ASSOC_SIZE];
+};
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
        struct list_head list;
@@ -177,6 +186,8 @@ struct hci_dev {
        __u32           amp_max_flush_to;
        __u32           amp_be_flush_to;
 
+       struct amp_assoc        loc_assoc;
+
        __u8            flow_ctl_mode;
 
        unsigned int    auto_accept_delay;
@@ -252,8 +263,6 @@ struct hci_dev {
 
        struct sk_buff_head     driver_init;
 
-       void                    *core_data;
-
        atomic_t                promisc;
 
        struct dentry           *debugfs;
@@ -269,6 +278,10 @@ struct hci_dev {
        struct work_struct      le_scan;
        struct le_scan_params   le_scan_params;
 
+       __s8                    adv_tx_power;
+       __u8                    adv_data[HCI_MAX_AD_LENGTH];
+       __u8                    adv_data_len;
+
        int (*open)(struct hci_dev *hdev);
        int (*close)(struct hci_dev *hdev);
        int (*flush)(struct hci_dev *hdev);
@@ -277,6 +290,8 @@ struct hci_dev {
        int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
 };
 
+#define HCI_PHY_HANDLE(handle) (handle & 0xff)
+
 struct hci_conn {
        struct list_head list;
 
@@ -310,6 +325,7 @@ struct hci_conn {
 
        __u8            remote_cap;
        __u8            remote_auth;
+       __u8            remote_id;
        bool            flush_key;
 
        unsigned int    sent;
@@ -339,10 +355,11 @@ struct hci_conn {
 
 struct hci_chan {
        struct list_head list;
-
+       __u16 handle;
        struct hci_conn *conn;
        struct sk_buff_head data_q;
        unsigned int    sent;
+       __u8            state;
 };
 
 extern struct list_head hci_dev_list;
@@ -438,6 +455,9 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
        case ACL_LINK:
                h->acl_num++;
                break;
+       case AMP_LINK:
+               h->amp_num++;
+               break;
        case LE_LINK:
                h->le_num++;
                break;
@@ -459,6 +479,9 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
        case ACL_LINK:
                h->acl_num--;
                break;
+       case AMP_LINK:
+               h->amp_num--;
+               break;
        case LE_LINK:
                h->le_num--;
                break;
@@ -475,6 +498,8 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
        switch (type) {
        case ACL_LINK:
                return h->acl_num;
+       case AMP_LINK:
+               return h->amp_num;
        case LE_LINK:
                return h->le_num;
        case SCO_LINK:
@@ -556,6 +581,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);
 struct hci_chan *hci_chan_create(struct hci_conn *conn);
 void hci_chan_del(struct hci_chan *chan);
 void hci_chan_list_flush(struct hci_conn *conn);
+struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
                             __u8 dst_type, __u8 sec_level, __u8 auth_type);
@@ -584,7 +610,10 @@ static inline void hci_conn_put(struct hci_conn *conn)
 
        if (atomic_dec_and_test(&conn->refcnt)) {
                unsigned long timeo;
-               if (conn->type == ACL_LINK || conn->type == LE_LINK) {
+
+               switch (conn->type) {
+               case ACL_LINK:
+               case LE_LINK:
                        del_timer(&conn->idle_timer);
                        if (conn->state == BT_CONNECTED) {
                                timeo = conn->disc_timeout;
@@ -593,12 +622,20 @@ static inline void hci_conn_put(struct hci_conn *conn)
                        } else {
                                timeo = msecs_to_jiffies(10);
                        }
-               } else {
+                       break;
+
+               case AMP_LINK:
+                       timeo = conn->disc_timeout;
+                       break;
+
+               default:
                        timeo = msecs_to_jiffies(10);
+                       break;
                }
+
                cancel_delayed_work(&conn->disc_work);
                queue_delayed_work(conn->hdev->workqueue,
-                                       &conn->disc_work, timeo);
+                                  &conn->disc_work, timeo);
        }
 }
 
@@ -650,7 +687,7 @@ static inline uint8_t __hci_num_ctrl(void)
 }
 
 struct hci_dev *hci_dev_get(int index);
-struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src);
 
 struct hci_dev *hci_alloc_dev(void);
 void hci_free_dev(struct hci_dev *hdev);
@@ -699,6 +736,8 @@ 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);
 
+int hci_update_ad(struct hci_dev *hdev);
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
 int hci_recv_frame(struct sk_buff *skb);
@@ -715,18 +754,29 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
 
 /* ----- LMP capabilities ----- */
-#define lmp_rswitch_capable(dev)   ((dev)->features[0] & LMP_RSWITCH)
 #define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
+#define lmp_rswitch_capable(dev)   ((dev)->features[0] & LMP_RSWITCH)
+#define lmp_hold_capable(dev)      ((dev)->features[0] & LMP_HOLD)
 #define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
-#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
+#define lmp_park_capable(dev)      ((dev)->features[1] & LMP_PARK)
+#define lmp_inq_rssi_capable(dev)  ((dev)->features[3] & LMP_RSSI_INQ)
 #define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
+#define lmp_bredr_capable(dev)     (!((dev)->features[4] & LMP_NO_BREDR))
+#define lmp_le_capable(dev)        ((dev)->features[4] & LMP_LE)
+#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
+#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC)
+#define lmp_ext_inq_capable(dev)   ((dev)->features[6] & LMP_EXT_INQ)
+#define lmp_le_br_capable(dev)     ((dev)->features[6] & LMP_SIMUL_LE_BR)
 #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))
+#define lmp_lsto_capable(dev)      ((dev)->features[7] & LMP_LSTO)
+#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[7] & LMP_INQ_TX_PWR)
+#define lmp_ext_feat_capable(dev)  ((dev)->features[7] & LMP_EXTFEATURES)
 
 /* ----- Extended LMP capabilities ----- */
+#define lmp_host_ssp_capable(dev)  ((dev)->host_features[0] & LMP_HOST_SSP)
 #define lmp_host_le_capable(dev)   ((dev)->host_features[0] & LMP_HOST_LE)
+#define lmp_host_le_br_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE_BREDR)
 
 /* ----- HCI protocols ----- */
 static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
@@ -789,6 +839,10 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
                sco_disconn_cfm(conn, reason);
                break;
 
+       /* L2CAP would be handled for BREDR chan */
+       case AMP_LINK:
+               break;
+
        default:
                BT_ERR("unknown link type %d", conn->type);
                break;
@@ -841,7 +895,7 @@ struct hci_cb {
 
 static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
 {
-       struct list_head *p;
+       struct hci_cb *cb;
        __u8 encrypt;
 
        hci_proto_auth_cfm(conn, status);
@@ -852,8 +906,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
        encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
 
        read_lock(&hci_cb_list_lock);
-       list_for_each(p, &hci_cb_list) {
-               struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+       list_for_each_entry(cb, &hci_cb_list, list) {
                if (cb->security_cfm)
                        cb->security_cfm(conn, status, encrypt);
        }
@@ -863,7 +916,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
 static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
                                                                __u8 encrypt)
 {
-       struct list_head *p;
+       struct hci_cb *cb;
 
        if (conn->sec_level == BT_SECURITY_SDP)
                conn->sec_level = BT_SECURITY_LOW;
@@ -874,8 +927,7 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
        hci_proto_encrypt_cfm(conn, status, encrypt);
 
        read_lock(&hci_cb_list_lock);
-       list_for_each(p, &hci_cb_list) {
-               struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+       list_for_each_entry(cb, &hci_cb_list, list) {
                if (cb->security_cfm)
                        cb->security_cfm(conn, status, encrypt);
        }
@@ -884,11 +936,10 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
 
 static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
 {
-       struct list_head *p;
+       struct hci_cb *cb;
 
        read_lock(&hci_cb_list_lock);
-       list_for_each(p, &hci_cb_list) {
-               struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+       list_for_each_entry(cb, &hci_cb_list, list) {
                if (cb->key_change_cfm)
                        cb->key_change_cfm(conn, status);
        }
@@ -898,11 +949,10 @@ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
 static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
                                                                __u8 role)
 {
-       struct list_head *p;
+       struct hci_cb *cb;
 
        read_lock(&hci_cb_list_lock);
-       list_for_each(p, &hci_cb_list) {
-               struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+       list_for_each_entry(cb, &hci_cb_list, list) {
                if (cb->role_switch_cfm)
                        cb->role_switch_cfm(conn, status, role);
        }