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

Commit e8107623 authored by Arron Wang's avatar Arron Wang Committed by Samuel Ortiz
Browse files

NFC: Implement HCI DEP send and receive data



And implement the corresponding hooks for pn544.

Signed-off-by: default avatarArron Wang <arron.wang@intel.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent c40d1740
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -900,7 +900,7 @@ static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb,
 * <= 0: driver handled the data exchange
 *    1: driver doesn't especially handle, please do standard processing
 */
static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev,
static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev,
				   struct nfc_target *target,
				   struct sk_buff *skb, data_exchange_cb_t cb,
				   void *cb_context)
@@ -953,11 +953,26 @@ static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev,
		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
					      PN544_JEWEL_RAW_CMD, skb->data,
					      skb->len, cb, cb_context);
	case PN544_RF_READER_NFCIP1_INITIATOR_GATE:
		*skb_push(skb, 1) = 0;

		return nfc_hci_send_event(hdev, target->hci_reader_gate,
					PN544_HCI_EVT_SND_DATA, skb->data,
					skb->len);
	default:
		return 1;
	}
}

static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
{
	/* Set default false for multiple information chaining */
	*skb_push(skb, 1) = 0;

	return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
				PN544_HCI_EVT_SND_DATA, skb->data, skb->len);
}

static int pn544_hci_check_presence(struct nfc_hci_dev *hdev,
				   struct nfc_target *target)
{
@@ -996,6 +1011,22 @@ void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event,
		nfc_hci_send_event(hdev, gate,
			NFC_HCI_EVT_END_OPERATION, NULL, 0);
		break;
	case PN544_HCI_EVT_RCV_DATA:
		if (skb->len < 2) {
			r = -EPROTO;
			goto exit;
		}

		if (skb->data[0] != 0) {
			pr_debug("data0 %d", skb->data[0]);
			r = -EPROTO;
			goto exit;
		}

		skb_pull(skb, 2);
		nfc_tm_data_received(hdev->ndev, skb);

		return;
	default:
		break;
	}
@@ -1014,7 +1045,8 @@ static struct nfc_hci_ops pn544_hci_ops = {
	.dep_link_down = pn544_hci_dep_link_down,
	.target_from_gate = pn544_hci_target_from_gate,
	.complete_target_discovered = pn544_hci_complete_target_discovered,
	.data_exchange = pn544_hci_data_exchange,
	.im_transceive = pn544_hci_im_transceive,
	.tm_send = pn544_hci_tm_send,
	.check_presence = pn544_hci_check_presence,
	.event_received = pn544_hci_event_received,
};
+2 −1
Original line number Diff line number Diff line
@@ -45,9 +45,10 @@ struct nfc_hci_ops {
				 struct nfc_target *target);
	int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate,
					   struct nfc_target *target);
	int (*data_exchange) (struct nfc_hci_dev *hdev,
	int (*im_transceive) (struct nfc_hci_dev *hdev,
			      struct nfc_target *target, struct sk_buff *skb,
			      data_exchange_cb_t cb, void *cb_context);
	int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
	int (*check_presence)(struct nfc_hci_dev *hdev,
			      struct nfc_target *target);
	void (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
+15 −4
Original line number Diff line number Diff line
@@ -616,8 +616,8 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
	switch (target->hci_reader_gate) {
	case NFC_HCI_RF_READER_A_GATE:
	case NFC_HCI_RF_READER_B_GATE:
		if (hdev->ops->data_exchange) {
			r = hdev->ops->data_exchange(hdev, target, skb, cb,
		if (hdev->ops->im_transceive) {
			r = hdev->ops->im_transceive(hdev, target, skb, cb,
						     cb_context);
			if (r <= 0)	/* handled */
				break;
@@ -634,8 +634,8 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
					   skb->len, hci_transceive_cb, hdev);
		break;
	default:
		if (hdev->ops->data_exchange) {
			r = hdev->ops->data_exchange(hdev, target, skb, cb,
		if (hdev->ops->im_transceive) {
			r = hdev->ops->im_transceive(hdev, target, skb, cb,
						     cb_context);
			if (r == 1)
				r = -ENOTSUPP;
@@ -650,6 +650,16 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
	return r;
}

int hci_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
{
	struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);

	if (hdev->ops->tm_send)
		return hdev->ops->tm_send(hdev, skb);
	else
		return -ENOTSUPP;
}

static int hci_check_presence(struct nfc_dev *nfc_dev,
			      struct nfc_target *target)
{
@@ -758,6 +768,7 @@ static struct nfc_ops hci_nfc_ops = {
	.activate_target = hci_activate_target,
	.deactivate_target = hci_deactivate_target,
	.im_transceive = hci_transceive,
	.tm_send = hci_tm_send,
	.check_presence = hci_check_presence,
};