Skip to content

Commit 673088f

Browse files
author
Samuel Ortiz
committed
NFC: pn533: Send ATR_REQ directly for active device detection
In order to improve active devices detection, we send an ATR_REQ between each passive detection cycle. Without this algorithm, Android 4.3 based devices running the Broadcom stack are hardly detected. Signed-off-by: Samuel Ortiz <[email protected]>
1 parent e29a9e2 commit 673088f

File tree

1 file changed

+120
-1
lines changed

1 file changed

+120
-1
lines changed

drivers/nfc/pn533.c

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ struct pn533 {
387387
struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1];
388388
u8 poll_mod_count;
389389
u8 poll_mod_curr;
390+
u8 poll_dep;
390391
u32 poll_protocols;
391392
u32 listen_protocols;
392393
struct timer_list listen_timer;
@@ -1546,6 +1547,9 @@ static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp)
15461547
u8 nbtg, tg, *tgdata;
15471548
int rc, tgdata_len;
15481549

1550+
/* Toggle the DEP polling */
1551+
dev->poll_dep = 1;
1552+
15491553
nbtg = resp->data[0];
15501554
tg = resp->data[1];
15511555
tgdata = &resp->data[2];
@@ -1767,6 +1771,117 @@ static void pn533_wq_rf(struct work_struct *work)
17671771
return;
17681772
}
17691773

1774+
static int pn533_poll_dep_complete(struct pn533 *dev, void *arg,
1775+
struct sk_buff *resp)
1776+
{
1777+
struct pn533_cmd_jump_dep_response *rsp;
1778+
struct nfc_target nfc_target;
1779+
u8 target_gt_len;
1780+
int rc;
1781+
1782+
if (IS_ERR(resp))
1783+
return PTR_ERR(resp);
1784+
1785+
rsp = (struct pn533_cmd_jump_dep_response *)resp->data;
1786+
1787+
rc = rsp->status & PN533_CMD_RET_MASK;
1788+
if (rc != PN533_CMD_RET_SUCCESS) {
1789+
/* Not target found, turn radio off */
1790+
queue_work(dev->wq, &dev->rf_work);
1791+
1792+
dev_kfree_skb(resp);
1793+
return 0;
1794+
}
1795+
1796+
dev_dbg(&dev->interface->dev, "Creating new target");
1797+
1798+
nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
1799+
nfc_target.nfcid1_len = 10;
1800+
memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len);
1801+
rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1);
1802+
if (rc)
1803+
goto error;
1804+
1805+
dev->tgt_available_prots = 0;
1806+
dev->tgt_active_prot = NFC_PROTO_NFC_DEP;
1807+
1808+
/* ATR_RES general bytes are located at offset 17 */
1809+
target_gt_len = resp->len - 17;
1810+
rc = nfc_set_remote_general_bytes(dev->nfc_dev,
1811+
rsp->gt, target_gt_len);
1812+
if (!rc) {
1813+
rc = nfc_dep_link_is_up(dev->nfc_dev,
1814+
dev->nfc_dev->targets[0].idx,
1815+
0, NFC_RF_INITIATOR);
1816+
1817+
if (!rc)
1818+
pn533_poll_reset_mod_list(dev);
1819+
}
1820+
error:
1821+
dev_kfree_skb(resp);
1822+
return rc;
1823+
}
1824+
1825+
#define PASSIVE_DATA_LEN 5
1826+
static int pn533_poll_dep(struct nfc_dev *nfc_dev)
1827+
{
1828+
struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1829+
struct sk_buff *skb;
1830+
int rc, skb_len;
1831+
u8 *next, nfcid3[NFC_NFCID3_MAXSIZE];
1832+
u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3};
1833+
1834+
dev_dbg(&dev->interface->dev, "%s", __func__);
1835+
1836+
if (!dev->gb) {
1837+
dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
1838+
1839+
if (!dev->gb || !dev->gb_len) {
1840+
dev->poll_dep = 0;
1841+
queue_work(dev->wq, &dev->rf_work);
1842+
}
1843+
}
1844+
1845+
skb_len = 3 + dev->gb_len; /* ActPass + BR + Next */
1846+
skb_len += PASSIVE_DATA_LEN;
1847+
1848+
/* NFCID3 */
1849+
skb_len += NFC_NFCID3_MAXSIZE;
1850+
nfcid3[0] = 0x1;
1851+
nfcid3[1] = 0xfe;
1852+
get_random_bytes(nfcid3 + 2, 6);
1853+
1854+
skb = pn533_alloc_skb(dev, skb_len);
1855+
if (!skb)
1856+
return -ENOMEM;
1857+
1858+
*skb_put(skb, 1) = 0x01; /* Active */
1859+
*skb_put(skb, 1) = 0x02; /* 424 kbps */
1860+
1861+
next = skb_put(skb, 1); /* Next */
1862+
*next = 0;
1863+
1864+
/* Copy passive data */
1865+
memcpy(skb_put(skb, PASSIVE_DATA_LEN), passive_data, PASSIVE_DATA_LEN);
1866+
*next |= 1;
1867+
1868+
/* Copy NFCID3 (which is NFCID2 from SENSF_RES) */
1869+
memcpy(skb_put(skb, NFC_NFCID3_MAXSIZE), nfcid3,
1870+
NFC_NFCID3_MAXSIZE);
1871+
*next |= 2;
1872+
1873+
memcpy(skb_put(skb, dev->gb_len), dev->gb, dev->gb_len);
1874+
*next |= 4; /* We have some Gi */
1875+
1876+
rc = pn533_send_cmd_async(dev, PN533_CMD_IN_JUMP_FOR_DEP, skb,
1877+
pn533_poll_dep_complete, NULL);
1878+
1879+
if (rc < 0)
1880+
dev_kfree_skb(skb);
1881+
1882+
return rc;
1883+
}
1884+
17701885
static int pn533_poll_complete(struct pn533 *dev, void *arg,
17711886
struct sk_buff *resp)
17721887
{
@@ -1853,6 +1968,11 @@ static int pn533_send_poll_frame(struct pn533 *dev)
18531968
dev_dbg(&dev->interface->dev, "%s mod len %d\n",
18541969
__func__, mod->len);
18551970

1971+
if (dev->poll_dep) {
1972+
dev->poll_dep = 0;
1973+
return pn533_poll_dep(dev->nfc_dev);
1974+
}
1975+
18561976
if (mod->len == 0) { /* Listen mode */
18571977
cmd_code = PN533_CMD_TG_INIT_AS_TARGET;
18581978
skb = pn533_alloc_poll_tg_frame(dev);
@@ -2146,7 +2266,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
21462266
}
21472267

21482268
static int pn533_rf_field(struct nfc_dev *nfc_dev, u8 rf);
2149-
#define PASSIVE_DATA_LEN 5
21502269
static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
21512270
u8 comm_mode, u8 *gb, size_t gb_len)
21522271
{

0 commit comments

Comments
 (0)