aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/nfc/digital.h12
-rw-r--r--net/nfc/digital.h3
-rw-r--r--net/nfc/digital_core.c16
-rw-r--r--net/nfc/digital_technology.c71
4 files changed, 93 insertions, 9 deletions
diff --git a/include/net/nfc/digital.h b/include/net/nfc/digital.h
index 575d668b7852..d9a5cf7ac1c4 100644
--- a/include/net/nfc/digital.h
+++ b/include/net/nfc/digital.h
@@ -127,6 +127,15 @@ typedef void (*nfc_digital_cmd_complete_t)(struct nfc_digital_dev *ddev,
127 * the NFC-DEP ATR_REQ command through cb. The digital stack deducts the RF 127 * the NFC-DEP ATR_REQ command through cb. The digital stack deducts the RF
128 * tech by analyzing the SoD of the frame containing the ATR_REQ command. 128 * tech by analyzing the SoD of the frame containing the ATR_REQ command.
129 * This is an asynchronous function. 129 * This is an asynchronous function.
130 * @tg_listen_md: If supported, put the device in automatic listen mode with
131 * mode detection but without automatic anti-collision. In this mode, the
132 * device automatically detects the RF technology. What the actual
133 * RF technology is can be retrieved by calling @tg_get_rf_tech.
134 * The digital stack will then perform the appropriate anti-collision
135 * sequence. This is an asynchronous function.
136 * @tg_get_rf_tech: Required when @tg_listen_md is supported, unused otherwise.
137 * Return the RF Technology that was detected by the @tg_listen_md call.
138 * This is a synchronous function.
130 * 139 *
131 * @switch_rf: Turns device radio on or off. The stack does not call explicitly 140 * @switch_rf: Turns device radio on or off. The stack does not call explicitly
132 * switch_rf to turn the radio on. A call to in|tg_configure_hw must turn 141 * switch_rf to turn the radio on. A call to in|tg_configure_hw must turn
@@ -161,6 +170,9 @@ struct nfc_digital_ops {
161 struct digital_tg_mdaa_params *mdaa_params, 170 struct digital_tg_mdaa_params *mdaa_params,
162 u16 timeout, nfc_digital_cmd_complete_t cb, 171 u16 timeout, nfc_digital_cmd_complete_t cb,
163 void *arg); 172 void *arg);
173 int (*tg_listen_md)(struct nfc_digital_dev *ddev, u16 timeout,
174 nfc_digital_cmd_complete_t cb, void *arg);
175 int (*tg_get_rf_tech)(struct nfc_digital_dev *ddev, u8 *rf_tech);
164 176
165 int (*switch_rf)(struct nfc_digital_dev *ddev, bool on); 177 int (*switch_rf)(struct nfc_digital_dev *ddev, bool on);
166 void (*abort_cmd)(struct nfc_digital_dev *ddev); 178 void (*abort_cmd)(struct nfc_digital_dev *ddev);
diff --git a/net/nfc/digital.h b/net/nfc/digital.h
index 71ad7eefddd4..3c39c72eb038 100644
--- a/net/nfc/digital.h
+++ b/net/nfc/digital.h
@@ -29,6 +29,7 @@
29#define DIGITAL_CMD_TG_SEND 1 29#define DIGITAL_CMD_TG_SEND 1
30#define DIGITAL_CMD_TG_LISTEN 2 30#define DIGITAL_CMD_TG_LISTEN 2
31#define DIGITAL_CMD_TG_LISTEN_MDAA 3 31#define DIGITAL_CMD_TG_LISTEN_MDAA 3
32#define DIGITAL_CMD_TG_LISTEN_MD 4
32 33
33#define DIGITAL_MAX_HEADER_LEN 7 34#define DIGITAL_MAX_HEADER_LEN 7
34#define DIGITAL_CRC_LEN 2 35#define DIGITAL_CRC_LEN 2
@@ -121,6 +122,8 @@ int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb);
121 122
122int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech); 123int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech);
123int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech); 124int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech);
125void digital_tg_recv_md_req(struct nfc_digital_dev *ddev, void *arg,
126 struct sk_buff *resp);
124 127
125typedef u16 (*crc_func_t)(u16, const u8 *, size_t); 128typedef u16 (*crc_func_t)(u16, const u8 *, size_t);
126 129
diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c
index 361bc37d2db1..009bcf317101 100644
--- a/net/nfc/digital_core.c
+++ b/net/nfc/digital_core.c
@@ -201,6 +201,11 @@ static void digital_wq_cmd(struct work_struct *work)
201 digital_send_cmd_complete, cmd); 201 digital_send_cmd_complete, cmd);
202 break; 202 break;
203 203
204 case DIGITAL_CMD_TG_LISTEN_MD:
205 rc = ddev->ops->tg_listen_md(ddev, cmd->timeout,
206 digital_send_cmd_complete, cmd);
207 break;
208
204 default: 209 default:
205 pr_err("Unknown cmd type %d\n", cmd->type); 210 pr_err("Unknown cmd type %d\n", cmd->type);
206 return; 211 return;
@@ -293,6 +298,12 @@ static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech)
293 500, digital_tg_recv_atr_req, NULL); 298 500, digital_tg_recv_atr_req, NULL);
294} 299}
295 300
301static int digital_tg_listen_md(struct nfc_digital_dev *ddev, u8 rf_tech)
302{
303 return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN_MD, NULL, NULL, 500,
304 digital_tg_recv_md_req, NULL);
305}
306
296int digital_target_found(struct nfc_digital_dev *ddev, 307int digital_target_found(struct nfc_digital_dev *ddev,
297 struct nfc_target *target, u8 protocol) 308 struct nfc_target *target, u8 protocol)
298{ 309{
@@ -510,6 +521,9 @@ static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols,
510 if (ddev->ops->tg_listen_mdaa) { 521 if (ddev->ops->tg_listen_mdaa) {
511 digital_add_poll_tech(ddev, 0, 522 digital_add_poll_tech(ddev, 0,
512 digital_tg_listen_mdaa); 523 digital_tg_listen_mdaa);
524 } else if (ddev->ops->tg_listen_md) {
525 digital_add_poll_tech(ddev, 0,
526 digital_tg_listen_md);
513 } else { 527 } else {
514 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, 528 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A,
515 digital_tg_listen_nfca); 529 digital_tg_listen_nfca);
@@ -737,7 +751,7 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
737 751
738 if (!ops->in_configure_hw || !ops->in_send_cmd || !ops->tg_listen || 752 if (!ops->in_configure_hw || !ops->in_send_cmd || !ops->tg_listen ||
739 !ops->tg_configure_hw || !ops->tg_send_cmd || !ops->abort_cmd || 753 !ops->tg_configure_hw || !ops->tg_send_cmd || !ops->abort_cmd ||
740 !ops->switch_rf) 754 !ops->switch_rf || (ops->tg_listen_md && !ops->tg_get_rf_tech))
741 return NULL; 755 return NULL;
742 756
743 ddev = kzalloc(sizeof(struct nfc_digital_dev), GFP_KERNEL); 757 ddev = kzalloc(sizeof(struct nfc_digital_dev), GFP_KERNEL);
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c
index d276518cc8bf..fb58ed2dd41d 100644
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -1218,33 +1218,48 @@ exit:
1218 dev_kfree_skb(resp); 1218 dev_kfree_skb(resp);
1219} 1219}
1220 1220
1221int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech) 1221static int digital_tg_config_nfca(struct nfc_digital_dev *ddev)
1222{ 1222{
1223 int rc; 1223 int rc;
1224 1224
1225 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); 1225 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
1226 NFC_DIGITAL_RF_TECH_106A);
1226 if (rc) 1227 if (rc)
1227 return rc; 1228 return rc;
1228 1229
1229 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, 1230 return digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
1230 NFC_DIGITAL_FRAMING_NFCA_NFC_DEP); 1231 NFC_DIGITAL_FRAMING_NFCA_NFC_DEP);
1232}
1233
1234int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech)
1235{
1236 int rc;
1237
1238 rc = digital_tg_config_nfca(ddev);
1231 if (rc) 1239 if (rc)
1232 return rc; 1240 return rc;
1233 1241
1234 return digital_tg_listen(ddev, 300, digital_tg_recv_sens_req, NULL); 1242 return digital_tg_listen(ddev, 300, digital_tg_recv_sens_req, NULL);
1235} 1243}
1236 1244
1237int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech) 1245static int digital_tg_config_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech)
1238{ 1246{
1239 int rc; 1247 int rc;
1240 u8 *nfcid2;
1241 1248
1242 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); 1249 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech);
1243 if (rc) 1250 if (rc)
1244 return rc; 1251 return rc;
1245 1252
1246 rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, 1253 return digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
1247 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP); 1254 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP);
1255}
1256
1257int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech)
1258{
1259 int rc;
1260 u8 *nfcid2;
1261
1262 rc = digital_tg_config_nfcf(ddev, rf_tech);
1248 if (rc) 1263 if (rc)
1249 return rc; 1264 return rc;
1250 1265
@@ -1258,3 +1273,43 @@ int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech)
1258 1273
1259 return digital_tg_listen(ddev, 300, digital_tg_recv_sensf_req, nfcid2); 1274 return digital_tg_listen(ddev, 300, digital_tg_recv_sensf_req, nfcid2);
1260} 1275}
1276
1277void digital_tg_recv_md_req(struct nfc_digital_dev *ddev, void *arg,
1278 struct sk_buff *resp)
1279{
1280 u8 rf_tech;
1281 int rc;
1282
1283 if (IS_ERR(resp)) {
1284 resp = NULL;
1285 goto exit_free_skb;
1286 }
1287
1288 rc = ddev->ops->tg_get_rf_tech(ddev, &rf_tech);
1289 if (rc)
1290 goto exit_free_skb;
1291
1292 switch (rf_tech) {
1293 case NFC_DIGITAL_RF_TECH_106A:
1294 rc = digital_tg_config_nfca(ddev);
1295 if (rc)
1296 goto exit_free_skb;
1297 digital_tg_recv_sens_req(ddev, arg, resp);
1298 break;
1299 case NFC_DIGITAL_RF_TECH_212F:
1300 case NFC_DIGITAL_RF_TECH_424F:
1301 rc = digital_tg_config_nfcf(ddev, rf_tech);
1302 if (rc)
1303 goto exit_free_skb;
1304 digital_tg_recv_sensf_req(ddev, arg, resp);
1305 break;
1306 default:
1307 goto exit_free_skb;
1308 }
1309
1310 return;
1311
1312exit_free_skb:
1313 digital_poll_next_tech(ddev);
1314 dev_kfree_skb(resp);
1315}