Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: L2CAP: Add support for setting BT_PHY

This enables client to use setsockopt(BT_PHY) to set the connection
packet type/PHY:

Example setting BT_PHY_BR_1M_1SLOT:

< HCI Command: Change Conne.. (0x01|0x000f) plen 4
Handle: 1 Address: 00:AA:01:01:00:00 (Intel Corporation)
Packet type: 0x331e
2-DH1 may not be used
3-DH1 may not be used
DM1 may be used
DH1 may be used
2-DH3 may not be used
3-DH3 may not be used
2-DH5 may not be used
3-DH5 may not be used
> HCI Event: Command Status (0x0f) plen 4
Change Connection Packet Type (0x01|0x000f) ncmd 1
Status: Success (0x00)
> HCI Event: Connection Packet Typ.. (0x1d) plen 5
Status: Success (0x00)
Handle: 1 Address: 00:AA:01:01:00:00 (Intel Corporation)
Packet type: 0x331e
2-DH1 may not be used
3-DH1 may not be used
DM1 may be used
DH1 may be used
2-DH3 may not be used
3-DH3 may not be used
2-DH5 may not be used

Example setting BT_PHY_LE_1M_TX and BT_PHY_LE_1M_RX:

< HCI Command: LE Set PHY (0x08|0x0032) plen 7
Handle: 1 Address: 00:AA:01:01:00:00 (Intel Corporation)
All PHYs preference: 0x00
TX PHYs preference: 0x01
LE 1M
RX PHYs preference: 0x01
LE 1M
PHY options preference: Reserved (0x0000)
> HCI Event: Command Status (0x0f) plen 4
LE Set PHY (0x08|0x0032) ncmd 1
Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 6
LE PHY Update Complete (0x0c)
Status: Success (0x00)
Handle: 1 Address: 00:AA:01:01:00:00 (Intel Corporation)
TX PHY: LE 1M (0x01)
RX PHY: LE 1M (0x01)

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

+259 -16
+24 -15
include/net/bluetooth/bluetooth.h
··· 130 130 #define BT_RCVMTU 13 131 131 #define BT_PHY 14 132 132 133 - #define BT_PHY_BR_1M_1SLOT 0x00000001 134 - #define BT_PHY_BR_1M_3SLOT 0x00000002 135 - #define BT_PHY_BR_1M_5SLOT 0x00000004 136 - #define BT_PHY_EDR_2M_1SLOT 0x00000008 137 - #define BT_PHY_EDR_2M_3SLOT 0x00000010 138 - #define BT_PHY_EDR_2M_5SLOT 0x00000020 139 - #define BT_PHY_EDR_3M_1SLOT 0x00000040 140 - #define BT_PHY_EDR_3M_3SLOT 0x00000080 141 - #define BT_PHY_EDR_3M_5SLOT 0x00000100 142 - #define BT_PHY_LE_1M_TX 0x00000200 143 - #define BT_PHY_LE_1M_RX 0x00000400 144 - #define BT_PHY_LE_2M_TX 0x00000800 145 - #define BT_PHY_LE_2M_RX 0x00001000 146 - #define BT_PHY_LE_CODED_TX 0x00002000 147 - #define BT_PHY_LE_CODED_RX 0x00004000 133 + #define BT_PHY_BR_1M_1SLOT BIT(0) 134 + #define BT_PHY_BR_1M_3SLOT BIT(1) 135 + #define BT_PHY_BR_1M_5SLOT BIT(2) 136 + #define BT_PHY_EDR_2M_1SLOT BIT(3) 137 + #define BT_PHY_EDR_2M_3SLOT BIT(4) 138 + #define BT_PHY_EDR_2M_5SLOT BIT(5) 139 + #define BT_PHY_EDR_3M_1SLOT BIT(6) 140 + #define BT_PHY_EDR_3M_3SLOT BIT(7) 141 + #define BT_PHY_EDR_3M_5SLOT BIT(8) 142 + #define BT_PHY_LE_1M_TX BIT(9) 143 + #define BT_PHY_LE_1M_RX BIT(10) 144 + #define BT_PHY_LE_2M_TX BIT(11) 145 + #define BT_PHY_LE_2M_RX BIT(12) 146 + #define BT_PHY_LE_CODED_TX BIT(13) 147 + #define BT_PHY_LE_CODED_RX BIT(14) 148 + 149 + #define BT_PHY_BREDR_MASK (BT_PHY_BR_1M_1SLOT | BT_PHY_BR_1M_3SLOT | \ 150 + BT_PHY_BR_1M_5SLOT | BT_PHY_EDR_2M_1SLOT | \ 151 + BT_PHY_EDR_2M_3SLOT | BT_PHY_EDR_2M_5SLOT | \ 152 + BT_PHY_EDR_3M_1SLOT | BT_PHY_EDR_3M_3SLOT | \ 153 + BT_PHY_EDR_3M_5SLOT) 154 + #define BT_PHY_LE_MASK (BT_PHY_LE_1M_TX | BT_PHY_LE_1M_RX | \ 155 + BT_PHY_LE_2M_TX | BT_PHY_LE_2M_RX | \ 156 + BT_PHY_LE_CODED_TX | BT_PHY_LE_CODED_RX) 148 157 149 158 #define BT_MODE 15 150 159
+9
include/net/bluetooth/hci.h
··· 1885 1885 #define HCI_LE_SET_PHY_2M 0x02 1886 1886 #define HCI_LE_SET_PHY_CODED 0x04 1887 1887 1888 + #define HCI_OP_LE_SET_PHY 0x2032 1889 + struct hci_cp_le_set_phy { 1890 + __le16 handle; 1891 + __u8 all_phys; 1892 + __u8 tx_phys; 1893 + __u8 rx_phys; 1894 + __le16 phy_opts; 1895 + } __packed; 1896 + 1888 1897 #define HCI_OP_LE_SET_EXT_SCAN_PARAMS 0x2041 1889 1898 struct hci_cp_le_set_ext_scan_params { 1890 1899 __u8 own_addr_type;
+1
include/net/bluetooth/hci_core.h
··· 2342 2342 void *hci_recv_event_data(struct hci_dev *hdev, __u8 event); 2343 2343 2344 2344 u32 hci_conn_get_phy(struct hci_conn *conn); 2345 + int hci_conn_set_phy(struct hci_conn *conn, u32 phys); 2345 2346 2346 2347 /* ----- HCI Sockets ----- */ 2347 2348 void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
+3
include/net/bluetooth/hci_sync.h
··· 191 191 int hci_past_sync(struct hci_conn *conn, struct hci_conn *le); 192 192 193 193 int hci_le_read_remote_features(struct hci_conn *conn); 194 + 195 + int hci_acl_change_pkt_type(struct hci_conn *conn, u16 pkt_type); 196 + int hci_le_set_phy(struct hci_conn *conn, u8 tx_phys, u8 rx_phys);
+105
net/bluetooth/hci_conn.c
··· 2958 2958 return phys; 2959 2959 } 2960 2960 2961 + static u16 bt_phy_pkt_type(struct hci_conn *conn, u32 phys) 2962 + { 2963 + u16 pkt_type = conn->pkt_type; 2964 + 2965 + if (phys & BT_PHY_BR_1M_3SLOT) 2966 + pkt_type |= HCI_DM3 | HCI_DH3; 2967 + else 2968 + pkt_type &= ~(HCI_DM3 | HCI_DH3); 2969 + 2970 + if (phys & BT_PHY_BR_1M_5SLOT) 2971 + pkt_type |= HCI_DM5 | HCI_DH5; 2972 + else 2973 + pkt_type &= ~(HCI_DM5 | HCI_DH5); 2974 + 2975 + if (phys & BT_PHY_EDR_2M_1SLOT) 2976 + pkt_type &= ~HCI_2DH1; 2977 + else 2978 + pkt_type |= HCI_2DH1; 2979 + 2980 + if (phys & BT_PHY_EDR_2M_3SLOT) 2981 + pkt_type &= ~HCI_2DH3; 2982 + else 2983 + pkt_type |= HCI_2DH3; 2984 + 2985 + if (phys & BT_PHY_EDR_2M_5SLOT) 2986 + pkt_type &= ~HCI_2DH5; 2987 + else 2988 + pkt_type |= HCI_2DH5; 2989 + 2990 + if (phys & BT_PHY_EDR_3M_1SLOT) 2991 + pkt_type &= ~HCI_3DH1; 2992 + else 2993 + pkt_type |= HCI_3DH1; 2994 + 2995 + if (phys & BT_PHY_EDR_3M_3SLOT) 2996 + pkt_type &= ~HCI_3DH3; 2997 + else 2998 + pkt_type |= HCI_3DH3; 2999 + 3000 + if (phys & BT_PHY_EDR_3M_5SLOT) 3001 + pkt_type &= ~HCI_3DH5; 3002 + else 3003 + pkt_type |= HCI_3DH5; 3004 + 3005 + return pkt_type; 3006 + } 3007 + 3008 + static int bt_phy_le_phy(u32 phys, u8 *tx_phys, u8 *rx_phys) 3009 + { 3010 + if (!tx_phys || !rx_phys) 3011 + return -EINVAL; 3012 + 3013 + *tx_phys = 0; 3014 + *rx_phys = 0; 3015 + 3016 + if (phys & BT_PHY_LE_1M_TX) 3017 + *tx_phys |= HCI_LE_SET_PHY_1M; 3018 + 3019 + if (phys & BT_PHY_LE_1M_RX) 3020 + *rx_phys |= HCI_LE_SET_PHY_1M; 3021 + 3022 + if (phys & BT_PHY_LE_2M_TX) 3023 + *tx_phys |= HCI_LE_SET_PHY_2M; 3024 + 3025 + if (phys & BT_PHY_LE_2M_RX) 3026 + *rx_phys |= HCI_LE_SET_PHY_2M; 3027 + 3028 + if (phys & BT_PHY_LE_CODED_TX) 3029 + *tx_phys |= HCI_LE_SET_PHY_CODED; 3030 + 3031 + if (phys & BT_PHY_LE_CODED_RX) 3032 + *rx_phys |= HCI_LE_SET_PHY_CODED; 3033 + 3034 + return 0; 3035 + } 3036 + 3037 + int hci_conn_set_phy(struct hci_conn *conn, u32 phys) 3038 + { 3039 + u8 tx_phys, rx_phys; 3040 + 3041 + switch (conn->type) { 3042 + case SCO_LINK: 3043 + case ESCO_LINK: 3044 + return -EINVAL; 3045 + case ACL_LINK: 3046 + /* Only allow setting BR/EDR PHYs if link type is ACL */ 3047 + if (phys & ~BT_PHY_BREDR_MASK) 3048 + return -EINVAL; 3049 + 3050 + return hci_acl_change_pkt_type(conn, 3051 + bt_phy_pkt_type(conn, phys)); 3052 + case LE_LINK: 3053 + /* Only allow setting LE PHYs if link type is LE */ 3054 + if (phys & ~BT_PHY_LE_MASK) 3055 + return -EINVAL; 3056 + 3057 + if (bt_phy_le_phy(phys, &tx_phys, &rx_phys)) 3058 + return -EINVAL; 3059 + 3060 + return hci_le_set_phy(conn, tx_phys, rx_phys); 3061 + default: 3062 + return -EINVAL; 3063 + } 3064 + } 3065 + 2961 3066 static int abort_conn_sync(struct hci_dev *hdev, void *data) 2962 3067 { 2963 3068 struct hci_conn *conn = data;
+26
net/bluetooth/hci_event.c
··· 2869 2869 hci_dev_unlock(hdev); 2870 2870 } 2871 2871 2872 + static void hci_cs_le_set_phy(struct hci_dev *hdev, u8 status) 2873 + { 2874 + struct hci_cp_le_set_phy *cp; 2875 + struct hci_conn *conn; 2876 + 2877 + bt_dev_dbg(hdev, "status 0x%2.2x", status); 2878 + 2879 + if (status) 2880 + return; 2881 + 2882 + cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PHY); 2883 + if (!cp) 2884 + return; 2885 + 2886 + hci_dev_lock(hdev); 2887 + 2888 + conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2889 + if (conn) { 2890 + conn->le_tx_def_phys = cp->tx_phys; 2891 + conn->le_rx_def_phys = cp->rx_phys; 2892 + } 2893 + 2894 + hci_dev_unlock(hdev); 2895 + } 2896 + 2872 2897 static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status) 2873 2898 { 2874 2899 struct hci_cp_le_read_remote_features *cp; ··· 4384 4359 HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn), 4385 4360 HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features), 4386 4361 HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc), 4362 + HCI_CS(HCI_OP_LE_SET_PHY, hci_cs_le_set_phy), 4387 4363 HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn), 4388 4364 HCI_CS(HCI_OP_LE_CREATE_CIS, hci_cs_le_create_cis), 4389 4365 HCI_CS(HCI_OP_LE_CREATE_BIG, hci_cs_le_create_big),
+72
net/bluetooth/hci_sync.c
··· 7448 7448 7449 7449 return err; 7450 7450 } 7451 + 7452 + static void pkt_type_changed(struct hci_dev *hdev, void *data, int err) 7453 + { 7454 + struct hci_cp_change_conn_ptype *cp = data; 7455 + 7456 + bt_dev_dbg(hdev, "err %d", err); 7457 + 7458 + kfree(cp); 7459 + } 7460 + 7461 + static int hci_change_conn_ptype_sync(struct hci_dev *hdev, void *data) 7462 + { 7463 + struct hci_cp_change_conn_ptype *cp = data; 7464 + 7465 + return __hci_cmd_sync_status_sk(hdev, HCI_OP_CHANGE_CONN_PTYPE, 7466 + sizeof(*cp), cp, 7467 + HCI_EV_PKT_TYPE_CHANGE, 7468 + HCI_CMD_TIMEOUT, NULL); 7469 + } 7470 + 7471 + int hci_acl_change_pkt_type(struct hci_conn *conn, u16 pkt_type) 7472 + { 7473 + struct hci_dev *hdev = conn->hdev; 7474 + struct hci_cp_change_conn_ptype *cp; 7475 + 7476 + cp = kmalloc(sizeof(*cp), GFP_KERNEL); 7477 + if (!cp) 7478 + return -ENOMEM; 7479 + 7480 + cp->handle = cpu_to_le16(conn->handle); 7481 + cp->pkt_type = cpu_to_le16(pkt_type); 7482 + 7483 + return hci_cmd_sync_queue_once(hdev, hci_change_conn_ptype_sync, cp, 7484 + pkt_type_changed); 7485 + } 7486 + 7487 + static void le_phy_update_complete(struct hci_dev *hdev, void *data, int err) 7488 + { 7489 + struct hci_cp_le_set_phy *cp = data; 7490 + 7491 + bt_dev_dbg(hdev, "err %d", err); 7492 + 7493 + kfree(cp); 7494 + } 7495 + 7496 + static int hci_le_set_phy_sync(struct hci_dev *hdev, void *data) 7497 + { 7498 + struct hci_cp_le_set_phy *cp = data; 7499 + 7500 + return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_SET_PHY, 7501 + sizeof(*cp), cp, 7502 + HCI_EV_LE_PHY_UPDATE_COMPLETE, 7503 + HCI_CMD_TIMEOUT, NULL); 7504 + } 7505 + 7506 + int hci_le_set_phy(struct hci_conn *conn, u8 tx_phys, u8 rx_phys) 7507 + { 7508 + struct hci_dev *hdev = conn->hdev; 7509 + struct hci_cp_le_set_phy *cp; 7510 + 7511 + cp = kmalloc(sizeof(*cp), GFP_KERNEL); 7512 + if (!cp) 7513 + return -ENOMEM; 7514 + 7515 + memset(cp, 0, sizeof(*cp)); 7516 + cp->handle = cpu_to_le16(conn->handle); 7517 + cp->tx_phys = tx_phys; 7518 + cp->rx_phys = rx_phys; 7519 + 7520 + return hci_cmd_sync_queue_once(hdev, hci_le_set_phy_sync, cp, 7521 + le_phy_update_complete); 7522 + }
+19 -1
net/bluetooth/l2cap_sock.c
··· 885 885 struct bt_power pwr; 886 886 struct l2cap_conn *conn; 887 887 int err = 0; 888 - u32 opt; 888 + u32 opt, phys; 889 889 u16 mtu; 890 890 u8 mode; 891 891 ··· 1057 1057 else 1058 1058 chan->imtu = mtu; 1059 1059 1060 + break; 1061 + 1062 + case BT_PHY: 1063 + if (sk->sk_state != BT_CONNECTED) { 1064 + err = -ENOTCONN; 1065 + break; 1066 + } 1067 + 1068 + err = copy_safe_from_sockptr(&phys, sizeof(phys), optval, 1069 + optlen); 1070 + if (err) 1071 + break; 1072 + 1073 + if (!chan->conn) 1074 + break; 1075 + 1076 + conn = chan->conn; 1077 + err = hci_conn_set_phy(conn->hcon, phys); 1060 1078 break; 1061 1079 1062 1080 case BT_MODE: