Commit 7e035230 authored by Ilan Elias's avatar Ilan Elias Committed by Samuel Ortiz
Browse files

NFC: Set local general bytes in nci_start_poll



If initiator protocol is NFC-DEP, set the local general bytes
in nci_start_poll.

Signed-off-by: default avatarIlan Elias <ilane@ti.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 5d50b364
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#define NCI_MAX_NUM_MAPPING_CONFIGS				10
#define NCI_MAX_NUM_RF_CONFIGS					10
#define NCI_MAX_NUM_CONN					10
#define NCI_MAX_PARAM_LEN					251

/* NCI Status Codes */
#define NCI_STATUS_OK						0x00
@@ -102,6 +103,9 @@
#define NCI_RF_INTERFACE_ISO_DEP				0x02
#define NCI_RF_INTERFACE_NFC_DEP				0x03

/* NCI Configuration Parameter Tags */
#define NCI_PN_ATR_REQ_GEN_BYTES				0x29

/* NCI Reset types */
#define NCI_RESET_TYPE_KEEP_CONFIG				0x00
#define NCI_RESET_TYPE_RESET_CONFIG				0x01
@@ -188,6 +192,18 @@ struct nci_core_reset_cmd {

#define NCI_OP_CORE_INIT_CMD		nci_opcode_pack(NCI_GID_CORE, 0x01)

#define NCI_OP_CORE_SET_CONFIG_CMD	nci_opcode_pack(NCI_GID_CORE, 0x02)
struct set_config_param {
	__u8	id;
	__u8	len;
	__u8	val[NCI_MAX_PARAM_LEN];
} __packed;

struct nci_core_set_config_cmd {
	__u8	num_params;
	struct	set_config_param param; /* support 1 param per cmd is enough */
} __packed;

#define NCI_OP_RF_DISCOVER_MAP_CMD	nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)
struct disc_map_config {
	__u8	rf_protocol;
@@ -252,6 +268,13 @@ struct nci_core_init_rsp_2 {
	__le32	manufact_specific_info;
} __packed;

#define NCI_OP_CORE_SET_CONFIG_RSP	nci_opcode_pack(NCI_GID_CORE, 0x02)
struct nci_core_set_config_rsp {
	__u8	status;
	__u8	num_params;
	__u8	params_id[0];	/* variable size array */
} __packed;

#define NCI_OP_RF_DISCOVER_MAP_RSP	nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)

#define NCI_OP_RF_DISCOVER_RSP		nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ enum nci_state {
/* NCI timeouts */
#define NCI_RESET_TIMEOUT			5000
#define NCI_INIT_TIMEOUT			5000
#define NCI_SET_CONFIG_TIMEOUT			5000
#define NCI_RF_DISC_TIMEOUT			5000
#define NCI_RF_DISC_SELECT_TIMEOUT		5000
#define NCI_RF_DEACTIVATE_TIMEOUT		30000
+55 −0
Original line number Diff line number Diff line
@@ -176,6 +176,27 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
		     (1 + ((*num) * sizeof(struct disc_map_config))), &cmd);
}

struct nci_set_config_param {
	__u8	id;
	size_t	len;
	__u8	*val;
};

static void nci_set_config_req(struct nci_dev *ndev, unsigned long opt)
{
	struct nci_set_config_param *param = (struct nci_set_config_param *)opt;
	struct nci_core_set_config_cmd cmd;

	BUG_ON(param->len > NCI_MAX_PARAM_LEN);

	cmd.num_params = 1;
	cmd.param.id = param->id;
	cmd.param.len = param->len;
	memcpy(cmd.param.val, param->val, param->len);

	nci_send_cmd(ndev, NCI_OP_CORE_SET_CONFIG_CMD, (3 + param->len), &cmd);
}

static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
{
	struct nci_rf_disc_cmd cmd;
@@ -388,6 +409,32 @@ static int nci_dev_down(struct nfc_dev *nfc_dev)
	return nci_close_device(ndev);
}

static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev)
{
	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
	struct nci_set_config_param param;
	__u8 local_gb[NFC_MAX_GT_LEN];
	int i, rc = 0;

	param.val = nfc_get_local_general_bytes(nfc_dev, &param.len);
	if ((param.val == NULL) || (param.len == 0))
		return rc;

	if (param.len > NCI_MAX_PARAM_LEN)
		return -EINVAL;

	for (i = 0; i < param.len; i++)
		local_gb[param.len-1-i] = param.val[i];

	param.id = NCI_PN_ATR_REQ_GEN_BYTES;
	param.val = local_gb;

	rc = nci_request(ndev, nci_set_config_req, (unsigned long)&param,
			 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));

	return rc;
}

static int nci_start_poll(struct nfc_dev *nfc_dev,
			  __u32 im_protocols, __u32 tm_protocols)
{
@@ -415,6 +462,14 @@ static int nci_start_poll(struct nfc_dev *nfc_dev,
			return -EBUSY;
	}

	if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
		rc = nci_set_local_general_bytes(nfc_dev);
		if (rc) {
			pr_err("failed to set local general bytes\n");
			return rc;
		}
	}

	rc = nci_request(ndev, nci_rf_discover_req, im_protocols,
			 msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));

+14 −0
Original line number Diff line number Diff line
@@ -119,6 +119,16 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
	nci_req_complete(ndev, rsp_1->status);
}

static void nci_core_set_config_rsp_packet(struct nci_dev *ndev,
					   struct sk_buff *skb)
{
	struct nci_core_set_config_rsp *rsp = (void *) skb->data;

	pr_debug("status 0x%x\n", rsp->status);

	nci_req_complete(ndev, rsp->status);
}

static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev,
				       struct sk_buff *skb)
{
@@ -194,6 +204,10 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
		nci_core_init_rsp_packet(ndev, skb);
		break;

	case NCI_OP_CORE_SET_CONFIG_RSP:
		nci_core_set_config_rsp_packet(ndev, skb);
		break;

	case NCI_OP_RF_DISCOVER_MAP_RSP:
		nci_rf_disc_map_rsp_packet(ndev, skb);
		break;