Commit 767f19ae authored by Ilan Elias's avatar Ilan Elias Committed by Samuel Ortiz
Browse files

NFC: Implement NCI dep_link_up and dep_link_down



During NFC-DEP target activation, store the remote
general bytes to be used later in dep_link_up.
When dep_link_up is called, activate the NFC-DEP target,
and forward the remote general bytes.
When dep_link_down is called, deactivate the target.

Signed-off-by: default avatarIlan Elias <ilane@ti.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent ac206838
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -138,6 +138,10 @@ struct nci_dev {
	data_exchange_cb_t	data_exchange_cb;
	void			*data_exchange_cb_context;
	struct sk_buff		*rx_data_reassembly;

	/* stored during intf_activated_ntf */
	__u8 remote_gb[NFC_MAX_GT_LEN];
	__u8 remote_gb_len;
};

/* ----- NCI Devices ----- */
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ struct nfc_ops {

#define NFC_TARGET_IDX_ANY -1
#define NFC_MAX_GT_LEN 48
#define NFC_ATR_RES_GT_OFFSET 15

struct nfc_target {
	u32 idx;
+35 −1
Original line number Diff line number Diff line
@@ -564,7 +564,7 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev,
{
	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);

	pr_debug("target_idx %d\n", target->idx);
	pr_debug("entry\n");

	if (!ndev->target_active_prot) {
		pr_err("unable to deactivate target, no active target\n");
@@ -579,6 +579,38 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev,
	}
}


static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
			   __u8 comm_mode, __u8 *gb, size_t gb_len)
{
	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
	int rc;

	pr_debug("target_idx %d, comm_mode %d\n", target->idx, comm_mode);

	rc = nci_activate_target(nfc_dev, target, NFC_PROTO_NFC_DEP);
	if (rc)
		return rc;

	rc = nfc_set_remote_general_bytes(nfc_dev, ndev->remote_gb,
					  ndev->remote_gb_len);
	if (!rc)
		rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_PASSIVE,
					NFC_RF_INITIATOR);

	return rc;
}

static int nci_dep_link_down(struct nfc_dev *nfc_dev)
{
	pr_debug("entry\n");

	nci_deactivate_target(nfc_dev, NULL);

	return 0;
}


static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
			  struct sk_buff *skb,
			  data_exchange_cb_t cb, void *cb_context)
@@ -612,6 +644,8 @@ static struct nfc_ops nci_nfc_ops = {
	.dev_down = nci_dev_down,
	.start_poll = nci_start_poll,
	.stop_poll = nci_stop_poll,
	.dep_link_up = nci_dep_link_up,
	.dep_link_down = nci_dep_link_down,
	.activate_target = nci_activate_target,
	.deactivate_target = nci_deactivate_target,
	.im_transceive = nci_transceive,
+20 −0
Original line number Diff line number Diff line
@@ -176,6 +176,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
			protocol = NFC_PROTO_ISO14443_B_MASK;
	else if (rf_protocol == NCI_RF_PROTOCOL_T3T)
		protocol = NFC_PROTO_FELICA_MASK;
	else if (rf_protocol == NCI_RF_PROTOCOL_NFC_DEP)
		protocol = NFC_PROTO_NFC_DEP_MASK;
	else
		protocol = 0;

@@ -505,6 +507,24 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,

		/* set the available credits to initial value */
		atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);

		/* store general bytes to be reported later in dep_link_up */
		if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) {
			ndev->remote_gb_len = 0;

			if (ntf.activation_params_len > 0) {
				/* ATR_RES general bytes at offset 15 */
				ndev->remote_gb_len = min_t(__u8,
					(ntf.activation_params
					.poll_nfc_dep.atr_res_len
					- NFC_ATR_RES_GT_OFFSET),
					NFC_MAX_GT_LEN);
				memcpy(ndev->remote_gb,
				       (ntf.activation_params.poll_nfc_dep
				       .atr_res + NFC_ATR_RES_GT_OFFSET),
				       ndev->remote_gb_len);
			}
		}
	}

	if (atomic_read(&ndev->state) == NCI_DISCOVERY) {