Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7c23df8 authored by Jaganath Kanakkassery's avatar Jaganath Kanakkassery Committed by Marcel Holtmann
Browse files

Bluetooth: Implement PHY changed event



This defines and implement phy changed event and send it to user
whenever selected PHYs changes using SET_PHY_CONFIGURATION.

This will be also trigerred when BREDR pkt_type is changed using
the legacy ioctl HCISETPTYPE.

@ MGMT Command: Set PHY Configuration (0x0045) plen 4
		Selected PHYs: 0x7fff
		  BR 1M 1SLOT
		  BR 1M 3SLOT
		  BR 1M 5SLOT
		  EDR 2M 1SLOT
		  EDR 2M 3SLOT
		  EDR 2M 5SLOT
		  EDR 3M 1SLOT
		  EDR 3M 3SLOT
		  EDR 3M 5SLOT
		  LE 1M TX
		  LE 1M RX
		  LE 2M TX
		  LE 2M RX
		  LE CODED TX
		  LE CODED RX
< HCI Command: LE Set Default PHY (0x08|0x0031) plen 3
		All PHYs preference: 0x00
		TX PHYs preference: 0x07
		  LE 1M
		  LE 2M
		  LE Coded
		RX PHYs preference: 0x07
		  LE 1M
		  LE 2M
		  LE Coded
> HCI Event: Command Complete (0x0e) plen 4
	  LE Set Default PHY (0x08|0x0031) ncmd 1
		Status: Success (0x00)
@ MGMT Event: Command Complete (0x0001) plen 3
	  Set PHY Configuration (0x0045) plen 0
		Status: Success (0x00)
@ MGMT Event: PHY Configuration Changed (0x0026) plen 4
		Selected PHYs: 0x7fff
		  BR 1M 1SLOT
		  BR 1M 3SLOT
		  BR 1M 5SLOT
		  EDR 2M 1SLOT
		  EDR 2M 3SLOT
		  EDR 2M 5SLOT
		  EDR 3M 1SLOT
		  EDR 3M 3SLOT
		  EDR 3M 5SLOT
		  LE 1M TX
		  LE 1M RX
		  LE 2M TX
		  LE 2M RX
		  LE CODED TX
		  LE CODED RX

Signed-off-by: default avatarJaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 0314f286
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1544,6 +1544,7 @@ void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
			    u8 instance);
void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
			      u8 instance);
int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);

u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
		      u16 to_multiplier);
+5 −0
Original line number Diff line number Diff line
@@ -868,3 +868,8 @@ struct mgmt_ev_ext_info_changed {
	__le16	eir_len;
	__u8	eir[0];
} __packed;

#define MGMT_EV_PHY_CONFIGURATION_CHANGED	0x0026
struct mgmt_ev_phy_configuration_changed {
	__le32	selected_phys;
} __packed;
+4 −0
Original line number Diff line number Diff line
@@ -1924,7 +1924,11 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
		break;

	case HCISETPTYPE:
		if (hdev->pkt_type == (__u16) dr.dev_opt)
			break;

		hdev->pkt_type = (__u16) dr.dev_opt;
		mgmt_phy_configuration_changed(hdev, NULL);
		break;

	case HCISETACLMTU:
+21 −1
Original line number Diff line number Diff line
@@ -3328,6 +3328,18 @@ static int get_phy_configuration(struct sock *sk, struct hci_dev *hdev,
				 &rp, sizeof(rp));
}

int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip)
{
	struct mgmt_ev_phy_configuration_changed ev;

	memset(&ev, 0, sizeof(ev));

	ev.selected_phys = cpu_to_le32(get_selected_phys(hdev));

	return mgmt_event(MGMT_EV_PHY_CONFIGURATION_CHANGED, hdev, &ev,
			  sizeof(ev), skip);
}

static void set_default_phy_complete(struct hci_dev *hdev, u8 status,
				     u16 opcode, struct sk_buff *skb)
{
@@ -3352,6 +3364,8 @@ static void set_default_phy_complete(struct hci_dev *hdev, u8 status,
		mgmt_cmd_complete(cmd->sk, hdev->id,
				  MGMT_OP_SET_PHY_CONFIGURATION, 0,
				  NULL, 0);

		mgmt_phy_configuration_changed(hdev, cmd->sk);
	}

	mgmt_pending_remove(cmd);
@@ -3369,6 +3383,7 @@ static int set_phy_configuration(struct sock *sk, struct hci_dev *hdev,
	struct hci_request req;
	u32 selected_phys, configurable_phys, supported_phys, unconfigure_phys;
	u16 pkt_type = (HCI_DH1 | HCI_DM1);
	bool changed = false;
	int err;

	BT_DBG("sock %p %s", sk, hdev->name);
@@ -3450,11 +3465,16 @@ static int set_phy_configuration(struct sock *sk, struct hci_dev *hdev,
	else
		pkt_type |= HCI_3DH5;

	if (pkt_type != hdev->pkt_type)
	if (pkt_type != hdev->pkt_type) {
		hdev->pkt_type = pkt_type;
		changed = true;
	}

	if ((selected_phys & MGMT_PHY_LE_MASK) ==
	    (get_selected_phys(hdev) & MGMT_PHY_LE_MASK)) {
		if (changed)
			mgmt_phy_configuration_changed(hdev, sk);

		err = mgmt_cmd_complete(sk, hdev->id,
					MGMT_OP_SET_PHY_CONFIGURATION,
					0, NULL, 0);