Commit a7bcffc6 authored by Yang Li's avatar Yang Li Committed by Luiz Augusto von Dentz
Browse files

Bluetooth: Add PA_LINK to distinguish BIG sync and PA sync connections



Currently, BIS_LINK is used for both BIG sync and PA sync connections,
which makes it impossible to distinguish them when searching for a PA
sync connection.

Adding PA_LINK will make the distinction clearer and simplify future
extensions for PA-related features.

Signed-off-by: default avatarYang Li <yang.li@amlogic.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 0cadf853
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -562,6 +562,7 @@ enum {
#define LE_LINK		0x80
#define CIS_LINK	0x82
#define BIS_LINK	0x83
#define PA_LINK		0x84
#define INVALID_LINK	0xff

/* LMP features */
+7 −3
Original line number Diff line number Diff line
@@ -1015,6 +1015,7 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
		break;
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		h->iso_num++;
		break;
	}
@@ -1042,6 +1043,7 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
		break;
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		h->iso_num--;
		break;
	}
@@ -1060,6 +1062,7 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
		return h->sco_num;
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		return h->iso_num;
	default:
		return 0;
@@ -1142,7 +1145,7 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)
	rcu_read_lock();

	list_for_each_entry_rcu(c, &h->list, list) {
		if (c->type != BIS_LINK)
		if (c->type != PA_LINK)
			continue;

		if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags))
@@ -1337,7 +1340,7 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev,
	rcu_read_lock();

	list_for_each_entry_rcu(c, &h->list, list) {
		if (c->type != BIS_LINK)
		if (c->type != PA_LINK)
			continue;

		if (handle == c->iso_qos.bcast.big && num_bis == c->num_bis) {
@@ -1407,7 +1410,7 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle)
	rcu_read_lock();

	list_for_each_entry_rcu(c, &h->list, list) {
		if (c->type != BIS_LINK)
		if (c->type != PA_LINK)
			continue;

		/* Ignore the listen hcon, we are looking
@@ -2006,6 +2009,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,

	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		return iso_connect_ind(hdev, bdaddr, flags);

	default:
+9 −5
Original line number Diff line number Diff line
@@ -785,7 +785,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c
	d->sync_handle = conn->sync_handle;

	if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) {
		hci_conn_hash_list_flag(hdev, find_bis, BIS_LINK,
		hci_conn_hash_list_flag(hdev, find_bis, PA_LINK,
					HCI_CONN_PA_SYNC, d);

		if (!d->count)
@@ -914,6 +914,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
		break;
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		if (hdev->iso_mtu)
			/* Dedicated ISO Buffer exists */
			break;
@@ -979,6 +980,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
		break;
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		/* conn->src should reflect the local identity address */
		hci_copy_identity_address(hdev, &conn->src, &conn->src_type);

@@ -1033,7 +1035,6 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
	}

	hci_conn_init_sysfs(conn);

	return conn;
}

@@ -1077,6 +1078,7 @@ static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
		break;
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		if ((conn->state != BT_CONNECTED &&
		    !test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) ||
		    test_bit(HCI_CONN_BIG_CREATED, &conn->flags))
@@ -1152,7 +1154,8 @@ void hci_conn_del(struct hci_conn *conn)
	} else {
		/* Unacked ISO frames */
		if (conn->type == CIS_LINK ||
		    conn->type == BIS_LINK) {
		    conn->type == BIS_LINK ||
		    conn->type == PA_LINK) {
			if (hdev->iso_pkts)
				hdev->iso_cnt += conn->sent;
			else if (hdev->le_pkts)
@@ -2081,7 +2084,7 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,

	bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid);

	conn = hci_conn_add_unset(hdev, BIS_LINK, dst, HCI_ROLE_SLAVE);
	conn = hci_conn_add_unset(hdev, PA_LINK, dst, HCI_ROLE_SLAVE);
	if (IS_ERR(conn))
		return conn;

@@ -2246,7 +2249,7 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
	 * the start periodic advertising and create BIG commands have
	 * been queued
	 */
	hci_conn_hash_list_state(hdev, bis_mark_per_adv, BIS_LINK,
	hci_conn_hash_list_state(hdev, bis_mark_per_adv, PA_LINK,
				 BT_BOUND, &data);

	/* Queue start periodic advertising and create BIG */
@@ -2980,6 +2983,7 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb)
	switch (conn->type) {
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
	case ACL_LINK:
	case LE_LINK:
		break;
+15 −12
Original line number Diff line number Diff line
@@ -2936,12 +2936,14 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
	case HCI_ACLDATA_PKT:
		/* Detect if ISO packet has been sent as ACL */
		if (hci_conn_num(hdev, CIS_LINK) ||
		    hci_conn_num(hdev, BIS_LINK)) {
		    hci_conn_num(hdev, BIS_LINK) ||
			hci_conn_num(hdev, PA_LINK)) {
			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
			__u8 type;

			type = hci_conn_lookup_type(hdev, hci_handle(handle));
			if (type == CIS_LINK || type == BIS_LINK)
			if (type == CIS_LINK || type == BIS_LINK ||
			    type == PA_LINK)
				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
		}
		break;
@@ -3396,6 +3398,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
		break;
	case CIS_LINK:
	case BIS_LINK:
	case PA_LINK:
		cnt = hdev->iso_mtu ? hdev->iso_cnt :
			hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
		break;
@@ -3409,7 +3412,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
}

static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
				     __u8 type2, int *quote)
				     int *quote)
{
	struct hci_conn_hash *h = &hdev->conn_hash;
	struct hci_conn *conn = NULL, *c;
@@ -3421,7 +3424,7 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
	rcu_read_lock();

	list_for_each_entry_rcu(c, &h->list, list) {
		if ((c->type != type && c->type != type2) ||
		if (c->type != type ||
		    skb_queue_empty(&c->data_q))
			continue;

@@ -3625,7 +3628,7 @@ static void hci_sched_sco(struct hci_dev *hdev, __u8 type)
	else
		cnt = &hdev->sco_cnt;

	while (*cnt && (conn = hci_low_sent(hdev, type, type, &quote))) {
	while (*cnt && (conn = hci_low_sent(hdev, type, &quote))) {
		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
			BT_DBG("skb %p len %d", skb, skb->len);
			hci_send_conn_frame(hdev, conn, skb);
@@ -3744,8 +3747,8 @@ static void hci_sched_le(struct hci_dev *hdev)
		hci_prio_recalculate(hdev, LE_LINK);
}

/* Schedule CIS */
static void hci_sched_iso(struct hci_dev *hdev)
/* Schedule iso */
static void hci_sched_iso(struct hci_dev *hdev, __u8 type)
{
	struct hci_conn *conn;
	struct sk_buff *skb;
@@ -3753,14 +3756,12 @@ static void hci_sched_iso(struct hci_dev *hdev)

	BT_DBG("%s", hdev->name);

	if (!hci_conn_num(hdev, CIS_LINK) &&
	    !hci_conn_num(hdev, BIS_LINK))
	if (!hci_conn_num(hdev, type))
		return;

	cnt = hdev->iso_pkts ? &hdev->iso_cnt :
		hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
	while (*cnt && (conn = hci_low_sent(hdev, CIS_LINK, BIS_LINK,
					    &quote))) {
	while (*cnt && (conn = hci_low_sent(hdev, type, &quote))) {
		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
			BT_DBG("skb %p len %d", skb, skb->len);
			hci_send_conn_frame(hdev, conn, skb);
@@ -3785,7 +3786,9 @@ static void hci_tx_work(struct work_struct *work)
		/* Schedule queues and send stuff to HCI driver */
		hci_sched_sco(hdev, SCO_LINK);
		hci_sched_sco(hdev, ESCO_LINK);
		hci_sched_iso(hdev);
		hci_sched_iso(hdev, CIS_LINK);
		hci_sched_iso(hdev, BIS_LINK);
		hci_sched_iso(hdev, PA_LINK);
		hci_sched_acl(hdev);
		hci_sched_le(hdev);
	}
+4 −3
Original line number Diff line number Diff line
@@ -4432,6 +4432,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,

		case CIS_LINK:
		case BIS_LINK:
		case PA_LINK:
			if (hdev->iso_pkts) {
				hdev->iso_cnt += count;
				if (hdev->iso_cnt > hdev->iso_pkts)
@@ -6381,7 +6382,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data,
	conn->sync_handle = le16_to_cpu(ev->handle);
	conn->sid = HCI_SID_INVALID;

	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, BIS_LINK,
	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, PA_LINK,
				      &flags);
	if (!(mask & HCI_LM_ACCEPT)) {
		hci_le_pa_term_sync(hdev, ev->handle);
@@ -6392,7 +6393,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data,
		goto unlock;

	/* Add connection to indicate PA sync event */
	pa_sync = hci_conn_add_unset(hdev, BIS_LINK, BDADDR_ANY,
	pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
				     HCI_ROLE_SLAVE);

	if (IS_ERR(pa_sync))
@@ -6423,7 +6424,7 @@ static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data,

	hci_dev_lock(hdev);

	mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, BIS_LINK, &flags);
	mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, PA_LINK, &flags);
	if (!(mask & HCI_LM_ACCEPT))
		goto unlock;

Loading