NFC: pn533: Remove frame logic from poll cmds

Remove frame logic from start_pool cb using the new iface
for async send.

Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Waldemar Rymarkiewicz 2012-12-10 14:42:48 +01:00 committed by Samuel Ortiz
parent 99e591be3d
commit b5193e5da2

View File

@ -320,20 +320,6 @@ struct pn533_cmd_jump_dep_response {
#define PN533_INIT_TARGET_RESP_ACTIVE 0x1 #define PN533_INIT_TARGET_RESP_ACTIVE 0x1
#define PN533_INIT_TARGET_RESP_DEP 0x4 #define PN533_INIT_TARGET_RESP_DEP 0x4
struct pn533_cmd_init_target {
u8 mode;
u8 mifare[6];
u8 felica[18];
u8 nfcid3[10];
u8 gb_len;
u8 gb[];
} __packed;
struct pn533_cmd_init_target_response {
u8 mode;
u8 cmd[];
} __packed;
struct pn533 { struct pn533 {
struct usb_device *udev; struct usb_device *udev;
struct usb_interface *interface; struct usb_interface *interface;
@ -1315,50 +1301,37 @@ static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data,
return 0; return 0;
} }
struct pn533_poll_response { static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata,
u8 nbtg; int tgdata_len)
u8 tg;
u8 target_data[];
} __packed;
static int pn533_target_found(struct pn533 *dev,
struct pn533_poll_response *resp, int resp_len)
{ {
int target_data_len;
struct nfc_target nfc_tgt; struct nfc_target nfc_tgt;
int rc; int rc;
nfc_dev_dbg(&dev->interface->dev, "%s - modulation=%d", __func__, nfc_dev_dbg(&dev->interface->dev, "%s - modulation=%d", __func__,
dev->poll_mod_curr); dev->poll_mod_curr);
if (resp->tg != 1) if (tg != 1)
return -EPROTO; return -EPROTO;
memset(&nfc_tgt, 0, sizeof(struct nfc_target)); memset(&nfc_tgt, 0, sizeof(struct nfc_target));
target_data_len = resp_len - sizeof(struct pn533_poll_response);
switch (dev->poll_mod_curr) { switch (dev->poll_mod_curr) {
case PN533_POLL_MOD_106KBPS_A: case PN533_POLL_MOD_106KBPS_A:
rc = pn533_target_found_type_a(&nfc_tgt, resp->target_data, rc = pn533_target_found_type_a(&nfc_tgt, tgdata, tgdata_len);
target_data_len);
break; break;
case PN533_POLL_MOD_212KBPS_FELICA: case PN533_POLL_MOD_212KBPS_FELICA:
case PN533_POLL_MOD_424KBPS_FELICA: case PN533_POLL_MOD_424KBPS_FELICA:
rc = pn533_target_found_felica(&nfc_tgt, resp->target_data, rc = pn533_target_found_felica(&nfc_tgt, tgdata, tgdata_len);
target_data_len);
break; break;
case PN533_POLL_MOD_106KBPS_JEWEL: case PN533_POLL_MOD_106KBPS_JEWEL:
rc = pn533_target_found_jewel(&nfc_tgt, resp->target_data, rc = pn533_target_found_jewel(&nfc_tgt, tgdata, tgdata_len);
target_data_len);
break; break;
case PN533_POLL_MOD_847KBPS_B: case PN533_POLL_MOD_847KBPS_B:
rc = pn533_target_found_type_b(&nfc_tgt, resp->target_data, rc = pn533_target_found_type_b(&nfc_tgt, tgdata, tgdata_len);
target_data_len);
break; break;
default: default:
nfc_dev_err(&dev->interface->dev, "Unknown current poll" nfc_dev_err(&dev->interface->dev,
" modulation"); "Unknown current poll modulation");
return -EPROTO; return -EPROTO;
} }
@ -1366,13 +1339,14 @@ static int pn533_target_found(struct pn533 *dev,
return rc; return rc;
if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) { if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) {
nfc_dev_dbg(&dev->interface->dev, "The target found does not" nfc_dev_dbg(&dev->interface->dev,
" have the desired protocol"); "The Tg found doesn't have the desired protocol");
return -EAGAIN; return -EAGAIN;
} }
nfc_dev_dbg(&dev->interface->dev, "Target found - supported protocols: " nfc_dev_dbg(&dev->interface->dev,
"0x%x", nfc_tgt.supported_protocols); "Target found - supported protocols: 0x%x",
nfc_tgt.supported_protocols);
dev->tgt_available_prots = nfc_tgt.supported_protocols; dev->tgt_available_prots = nfc_tgt.supported_protocols;
@ -1424,16 +1398,20 @@ static void pn533_poll_create_mod_list(struct pn533 *dev,
pn533_poll_add_mod(dev, PN533_LISTEN_MOD); pn533_poll_add_mod(dev, PN533_LISTEN_MOD);
} }
static int pn533_start_poll_complete(struct pn533 *dev, u8 *params, int params_len) static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp)
{ {
struct pn533_poll_response *resp; u8 nbtg, tg, *tgdata;
int rc; int rc, tgdata_len;
nfc_dev_dbg(&dev->interface->dev, "%s", __func__); nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
resp = (struct pn533_poll_response *) params; nbtg = resp->data[0];
if (resp->nbtg) { tg = resp->data[1];
rc = pn533_target_found(dev, resp, params_len); tgdata = &resp->data[2];
tgdata_len = resp->len - 2; /* nbtg + tg */
if (nbtg) {
rc = pn533_target_found(dev, tg, tgdata, tgdata_len);
/* We must stop the poll after a valid target found */ /* We must stop the poll after a valid target found */
if (rc == 0) { if (rc == 0) {
@ -1445,56 +1423,55 @@ static int pn533_start_poll_complete(struct pn533 *dev, u8 *params, int params_l
return -EAGAIN; return -EAGAIN;
} }
static int pn533_init_target_frame(struct pn533_frame *frame, static struct sk_buff *pn533_alloc_poll_tg_frame(u8 *gbytes, size_t gbytes_len)
u8 *gb, size_t gb_len)
{ {
struct pn533_cmd_init_target *cmd; struct sk_buff *skb;
size_t cmd_len; u8 *felica, *nfcid3, *gb;
u8 felica_params[18] = {0x1, 0xfe, /* DEP */ u8 felica_params[18] = {0x1, 0xfe, /* DEP */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* random */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* random */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xff, 0xff}; /* System code */ 0xff, 0xff}; /* System code */
u8 mifare_params[6] = {0x1, 0x1, /* SENS_RES */ u8 mifare_params[6] = {0x1, 0x1, /* SENS_RES */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x40}; /* SEL_RES for DEP */ 0x40}; /* SEL_RES for DEP */
cmd_len = sizeof(struct pn533_cmd_init_target) + gb_len + 1; unsigned int skb_len = 36 + /* mode (1), mifare (6),
cmd = kzalloc(cmd_len, GFP_KERNEL); felica (18), nfcid3 (10), gb_len (1) */
if (cmd == NULL) gbytes_len +
return -ENOMEM; 1; /* len Tk*/
pn533_tx_frame_init(frame, PN533_CMD_TG_INIT_AS_TARGET); skb = pn533_alloc_skb(skb_len);
if (!skb)
return NULL;
/* DEP support only */ /* DEP support only */
cmd->mode |= PN533_INIT_TARGET_DEP; *skb_put(skb, 1) |= PN533_INIT_TARGET_DEP;
/* Felica params */
memcpy(cmd->felica, felica_params, 18);
get_random_bytes(cmd->felica + 2, 6);
/* NFCID3 */
memset(cmd->nfcid3, 0, 10);
memcpy(cmd->nfcid3, cmd->felica, 8);
/* MIFARE params */ /* MIFARE params */
memcpy(cmd->mifare, mifare_params, 6); memcpy(skb_put(skb, 6), mifare_params, 6);
/* Felica params */
felica = skb_put(skb, 18);
memcpy(felica, felica_params, 18);
get_random_bytes(felica + 2, 6);
/* NFCID3 */
nfcid3 = skb_put(skb, 10);
memset(nfcid3, 0, 10);
memcpy(nfcid3, felica, 8);
/* General bytes */ /* General bytes */
cmd->gb_len = gb_len; *skb_put(skb, 1) = gbytes_len;
memcpy(cmd->gb, gb, gb_len);
gb = skb_put(skb, gbytes_len);
memcpy(gb, gbytes, gbytes_len);
/* Len Tk */ /* Len Tk */
cmd->gb[gb_len] = 0; *skb_put(skb, 1) = 0;
memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), cmd, cmd_len); return skb;
frame->datalen += cmd_len;
pn533_tx_frame_finish(frame);
kfree(cmd);
return 0;
} }
#define PN533_CMD_DATAEXCH_HEAD_LEN 1 #define PN533_CMD_DATAEXCH_HEAD_LEN 1
@ -1545,41 +1522,32 @@ static void pn533_wq_tg_get_data(struct work_struct *work)
} }
#define ATR_REQ_GB_OFFSET 17 #define ATR_REQ_GB_OFFSET 17
static int pn533_init_target_complete(struct pn533 *dev, u8 *params, int params_len) static int pn533_init_target_complete(struct pn533 *dev, struct sk_buff *resp)
{ {
struct pn533_cmd_init_target_response *resp; u8 mode, *cmd, comm_mode = NFC_COMM_PASSIVE, *gb;
u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb;
size_t gb_len; size_t gb_len;
int rc; int rc;
nfc_dev_dbg(&dev->interface->dev, "%s", __func__); nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
if (params_len < 0) { if (resp->len < ATR_REQ_GB_OFFSET + 1)
nfc_dev_err(&dev->interface->dev,
"Error %d when starting as a target",
params_len);
return params_len;
}
if (params_len < ATR_REQ_GB_OFFSET + 1)
return -EINVAL; return -EINVAL;
resp = (struct pn533_cmd_init_target_response *) params; mode = resp->data[0];
cmd = &resp->data[1];
nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x param len %d\n", nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x len %d\n",
resp->mode, params_len); mode, resp->len);
frame = resp->mode & PN533_INIT_TARGET_RESP_FRAME_MASK; if ((mode & PN533_INIT_TARGET_RESP_FRAME_MASK) ==
if (frame == PN533_INIT_TARGET_RESP_ACTIVE) PN533_INIT_TARGET_RESP_ACTIVE)
comm_mode = NFC_COMM_ACTIVE; comm_mode = NFC_COMM_ACTIVE;
/* Again, only DEP */ if ((mode & PN533_INIT_TARGET_RESP_DEP) == 0) /* Only DEP supported */
if ((resp->mode & PN533_INIT_TARGET_RESP_DEP) == 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
gb = resp->cmd + ATR_REQ_GB_OFFSET; gb = cmd + ATR_REQ_GB_OFFSET;
gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); gb_len = resp->len - (ATR_REQ_GB_OFFSET + 1);
rc = nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, rc = nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
comm_mode, gb, gb_len); comm_mode, gb, gb_len);
@ -1590,7 +1558,6 @@ static int pn533_init_target_complete(struct pn533 *dev, u8 *params, int params_
} }
dev->tgt_mode = 1; dev->tgt_mode = 1;
queue_work(dev->wq, &dev->tg_work); queue_work(dev->wq, &dev->tg_work);
return 0; return 0;
@ -1613,89 +1580,104 @@ static void pn533_listen_mode_timer(unsigned long data)
} }
static int pn533_poll_complete(struct pn533 *dev, void *arg, static int pn533_poll_complete(struct pn533 *dev, void *arg,
u8 *params, int params_len) struct sk_buff *resp)
{ {
struct pn533_poll_modulations *cur_mod; struct pn533_poll_modulations *cur_mod;
int rc; int rc;
nfc_dev_dbg(&dev->interface->dev, "%s", __func__); nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
if (params_len == -ENOENT) { if (IS_ERR(resp)) {
if (dev->poll_mod_count != 0) rc = PTR_ERR(resp);
return 0;
nfc_dev_err(&dev->interface->dev, nfc_dev_err(&dev->interface->dev, "%s Poll complete error %d",
"Polling operation has been stopped"); __func__, rc);
goto stop_poll; if (rc == -ENOENT) {
} if (dev->poll_mod_count != 0)
return rc;
if (params_len < 0) { else
nfc_dev_err(&dev->interface->dev, goto stop_poll;
"Error %d when running poll", params_len); } else if (rc < 0) {
nfc_dev_err(&dev->interface->dev,
goto stop_poll; "Error %d when running poll", rc);
goto stop_poll;
}
} }
cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
if (cur_mod->len == 0) { if (cur_mod->len == 0) { /* Target mode */
del_timer(&dev->listen_timer); del_timer(&dev->listen_timer);
rc = pn533_init_target_complete(dev, resp);
return pn533_init_target_complete(dev, params, params_len); goto done;
} else {
rc = pn533_start_poll_complete(dev, params, params_len);
if (!rc)
return rc;
} }
/* Initiator mode */
rc = pn533_start_poll_complete(dev, resp);
if (!rc)
goto done;
pn533_poll_next_mod(dev); pn533_poll_next_mod(dev);
queue_work(dev->wq, &dev->poll_work); queue_work(dev->wq, &dev->poll_work);
return 0; done:
dev_kfree_skb(resp);
return rc;
stop_poll: stop_poll:
nfc_dev_err(&dev->interface->dev, "Polling operation has been stopped");
pn533_poll_reset_mod_list(dev); pn533_poll_reset_mod_list(dev);
dev->poll_protocols = 0; dev->poll_protocols = 0;
return 0; return rc;
} }
static void pn533_build_poll_frame(struct pn533 *dev, static struct sk_buff *pn533_alloc_poll_in_frame(struct pn533_poll_modulations
struct pn533_frame *frame, *mod)
struct pn533_poll_modulations *mod)
{ {
nfc_dev_dbg(&dev->interface->dev, "mod len %d\n", mod->len); struct sk_buff *skb;
if (mod->len == 0) { skb = pn533_alloc_skb(mod->len);
/* Listen mode */ if (!skb)
pn533_init_target_frame(frame, dev->gb, dev->gb_len); return NULL;
} else {
/* Polling mode */
pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET);
memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len); memcpy(skb_put(skb, mod->len), &mod->data, mod->len);
frame->datalen += mod->len;
pn533_tx_frame_finish(frame); return skb;
}
} }
static int pn533_send_poll_frame(struct pn533 *dev) static int pn533_send_poll_frame(struct pn533 *dev)
{ {
struct pn533_poll_modulations *cur_mod; struct pn533_poll_modulations *mod;
struct sk_buff *skb;
int rc; int rc;
u8 cmd_code;
cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; mod = dev->poll_mod_active[dev->poll_mod_curr];
pn533_build_poll_frame(dev, dev->out_frame, cur_mod); nfc_dev_dbg(&dev->interface->dev, "%s mod len %d\n",
__func__, mod->len);
rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, if (mod->len == 0) { /* Listen mode */
PN533_NORMAL_FRAME_MAX_LEN, cmd_code = PN533_CMD_TG_INIT_AS_TARGET;
pn533_poll_complete, skb = pn533_alloc_poll_tg_frame(dev->gb, dev->gb_len);
NULL); } else { /* Polling mode */
if (rc) cmd_code = PN533_CMD_IN_LIST_PASSIVE_TARGET;
skb = pn533_alloc_poll_in_frame(mod);
}
if (!skb) {
nfc_dev_err(&dev->interface->dev, "Failed to allocate skb.");
return -ENOMEM;
}
rc = pn533_send_cmd_async(dev, cmd_code, skb, pn533_poll_complete,
NULL);
if (rc < 0) {
dev_kfree_skb(skb);
nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc); nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc);
}
return rc; return rc;
} }