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

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
......@@ -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)
......
......@@ -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
......
......@@ -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));
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment