2011-07-02 02:31:37 +04:00
/*
2016-03-25 17:46:53 +03:00
* Driver for NXP PN533 NFC Chip - core functions
*
2011-07-02 02:31:37 +04:00
* Copyright ( C ) 2011 Instituto Nokia de Tecnologia
2013-04-03 10:02:01 +04:00
* Copyright ( C ) 2012 - 2013 Tieto Poland
2011-07-02 02:31:37 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2013-12-06 20:56:16 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2011-07-02 02:31:37 +04:00
*/
# include <linux/device.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/slab.h>
# include <linux/nfc.h>
# include <linux/netdevice.h>
2011-09-18 12:19:34 +04:00
# include <net/nfc/nfc.h>
2016-03-25 17:46:53 +03:00
# include "pn533.h"
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
# define VERSION "0.3"
2011-07-02 02:31:37 +04:00
2012-05-30 19:20:25 +04:00
/* How much time we spend listening for initiators */
# define PN533_LISTEN_TIME 2
2013-07-03 16:50:36 +04:00
/* Delay between each poll frame (ms) */
# define PN533_POLL_INTERVAL 10
2012-05-30 19:20:25 +04:00
2011-07-02 02:31:37 +04:00
/* structs for pn533 commands */
/* PN533_CMD_GET_FIRMWARE_VERSION */
struct pn533_fw_version {
u8 ic ;
u8 ver ;
u8 rev ;
u8 support ;
} ;
/* PN533_CMD_RF_CONFIGURATION */
2013-04-11 13:45:41 +04:00
# define PN533_CFGITEM_RF_FIELD 0x01
# define PN533_CFGITEM_TIMING 0x02
2011-07-02 02:31:37 +04:00
# define PN533_CFGITEM_MAX_RETRIES 0x05
2013-04-11 13:45:41 +04:00
# define PN533_CFGITEM_PASORI 0x82
2013-07-01 19:26:58 +04:00
# define PN533_CFGITEM_RF_FIELD_AUTO_RFCA 0x2
# define PN533_CFGITEM_RF_FIELD_ON 0x1
# define PN533_CFGITEM_RF_FIELD_OFF 0x0
2011-07-02 02:31:37 +04:00
2012-05-29 23:34:08 +04:00
# define PN533_CONFIG_TIMING_102 0xb
# define PN533_CONFIG_TIMING_204 0xc
# define PN533_CONFIG_TIMING_409 0xd
# define PN533_CONFIG_TIMING_819 0xe
2011-07-02 02:31:37 +04:00
# define PN533_CONFIG_MAX_RETRIES_NO_RETRY 0x00
# define PN533_CONFIG_MAX_RETRIES_ENDLESS 0xFF
struct pn533_config_max_retries {
u8 mx_rty_atr ;
u8 mx_rty_psl ;
u8 mx_rty_passive_act ;
} __packed ;
2012-05-29 23:34:08 +04:00
struct pn533_config_timing {
u8 rfu ;
u8 atr_res_timeout ;
u8 dep_timeout ;
} __packed ;
2011-07-02 02:31:37 +04:00
/* PN533_CMD_IN_LIST_PASSIVE_TARGET */
/* felica commands opcode */
# define PN533_FELICA_OPC_SENSF_REQ 0
# define PN533_FELICA_OPC_SENSF_RES 1
/* felica SENSF_REQ parameters */
# define PN533_FELICA_SENSF_SC_ALL 0xFFFF
# define PN533_FELICA_SENSF_RC_NO_SYSTEM_CODE 0
# define PN533_FELICA_SENSF_RC_SYSTEM_CODE 1
# define PN533_FELICA_SENSF_RC_ADVANCED_PROTOCOL 2
/* type B initiator_data values */
# define PN533_TYPE_B_AFI_ALL_FAMILIES 0
# define PN533_TYPE_B_POLL_METHOD_TIMESLOT 0
# define PN533_TYPE_B_POLL_METHOD_PROBABILISTIC 1
union pn533_cmd_poll_initdata {
struct {
u8 afi ;
u8 polling_method ;
} __packed type_b ;
struct {
u8 opcode ;
__be16 sc ;
u8 rc ;
u8 tsn ;
} __packed felica ;
} ;
struct pn533_poll_modulations {
struct {
u8 maxtg ;
u8 brty ;
union pn533_cmd_poll_initdata initiator_data ;
} __packed data ;
u8 len ;
} ;
2013-01-16 18:51:51 +04:00
static const struct pn533_poll_modulations poll_mod [ ] = {
2011-07-02 02:31:37 +04:00
[ PN533_POLL_MOD_106KBPS_A ] = {
. data = {
. maxtg = 1 ,
. brty = 0 ,
} ,
. len = 2 ,
} ,
[ PN533_POLL_MOD_212KBPS_FELICA ] = {
. data = {
. maxtg = 1 ,
. brty = 1 ,
. initiator_data . felica = {
. opcode = PN533_FELICA_OPC_SENSF_REQ ,
. sc = PN533_FELICA_SENSF_SC_ALL ,
2013-06-28 17:43:19 +04:00
. rc = PN533_FELICA_SENSF_RC_SYSTEM_CODE ,
2013-05-27 16:59:40 +04:00
. tsn = 0x03 ,
2011-07-02 02:31:37 +04:00
} ,
} ,
. len = 7 ,
} ,
[ PN533_POLL_MOD_424KBPS_FELICA ] = {
. data = {
. maxtg = 1 ,
. brty = 2 ,
. initiator_data . felica = {
. opcode = PN533_FELICA_OPC_SENSF_REQ ,
. sc = PN533_FELICA_SENSF_SC_ALL ,
2013-06-28 17:43:19 +04:00
. rc = PN533_FELICA_SENSF_RC_SYSTEM_CODE ,
2013-05-27 16:59:40 +04:00
. tsn = 0x03 ,
2011-07-02 02:31:37 +04:00
} ,
} ,
. len = 7 ,
} ,
[ PN533_POLL_MOD_106KBPS_JEWEL ] = {
. data = {
. maxtg = 1 ,
. brty = 4 ,
} ,
. len = 2 ,
} ,
[ PN533_POLL_MOD_847KBPS_B ] = {
. data = {
. maxtg = 1 ,
. brty = 8 ,
. initiator_data . type_b = {
. afi = PN533_TYPE_B_AFI_ALL_FAMILIES ,
. polling_method =
PN533_TYPE_B_POLL_METHOD_TIMESLOT ,
} ,
} ,
. len = 3 ,
} ,
2012-05-30 19:20:25 +04:00
[ PN533_LISTEN_MOD ] = {
. len = 0 ,
} ,
2011-07-02 02:31:37 +04:00
} ;
/* PN533_CMD_IN_ATR */
struct pn533_cmd_activate_response {
u8 status ;
u8 nfcid3t [ 10 ] ;
u8 didt ;
u8 bst ;
u8 brt ;
u8 to ;
u8 ppt ;
/* optional */
u8 gt [ ] ;
} __packed ;
2011-12-14 19:43:11 +04:00
struct pn533_cmd_jump_dep_response {
u8 status ;
u8 tg ;
u8 nfcid3t [ 10 ] ;
u8 didt ;
u8 bst ;
u8 brt ;
u8 to ;
u8 ppt ;
/* optional */
u8 gt [ ] ;
} __packed ;
2011-07-02 02:31:37 +04:00
2012-05-31 01:54:55 +04:00
/* PN533_TG_INIT_AS_TARGET */
# define PN533_INIT_TARGET_PASSIVE 0x1
# define PN533_INIT_TARGET_DEP 0x2
2012-06-01 15:21:13 +04:00
# define PN533_INIT_TARGET_RESP_FRAME_MASK 0x3
# define PN533_INIT_TARGET_RESP_ACTIVE 0x1
# define PN533_INIT_TARGET_RESP_DEP 0x4
2013-06-13 17:43:27 +04:00
/* The rule: value(high byte) + value(low byte) + checksum = 0 */
static inline u8 pn533_ext_checksum ( u16 value )
{
return ~ ( u8 ) ( ( ( value & 0xFF00 ) > > 8 ) + ( u8 ) ( value & 0xFF ) ) + 1 ;
}
2011-07-02 02:31:37 +04:00
/* The rule: value + checksum = 0 */
2013-04-03 10:01:58 +04:00
static inline u8 pn533_std_checksum ( u8 value )
2011-07-02 02:31:37 +04:00
{
return ~ value + 1 ;
}
/* The rule: sum(data elements) + checksum = 0 */
2013-04-03 10:01:58 +04:00
static u8 pn533_std_data_checksum ( u8 * data , int datalen )
2011-07-02 02:31:37 +04:00
{
u8 sum = 0 ;
int i ;
for ( i = 0 ; i < datalen ; i + + )
sum + = data [ i ] ;
2013-04-03 10:01:58 +04:00
return pn533_std_checksum ( sum ) ;
2011-07-02 02:31:37 +04:00
}
2013-04-03 10:01:58 +04:00
static void pn533_std_tx_frame_init ( void * _frame , u8 cmd_code )
2011-07-02 02:31:37 +04:00
{
2013-04-03 10:01:58 +04:00
struct pn533_std_frame * frame = _frame ;
2012-12-10 17:43:01 +04:00
2011-07-02 02:31:37 +04:00
frame - > preamble = 0 ;
2013-04-03 10:01:58 +04:00
frame - > start_frame = cpu_to_be16 ( PN533_STD_FRAME_SOF ) ;
PN533_STD_FRAME_IDENTIFIER ( frame ) = PN533_STD_FRAME_DIR_OUT ;
2013-06-13 17:43:27 +04:00
PN533_FRAME_CMD ( frame ) = cmd_code ;
2011-07-02 02:31:37 +04:00
frame - > datalen = 2 ;
}
2013-04-03 10:01:58 +04:00
static void pn533_std_tx_frame_finish ( void * _frame )
2011-07-02 02:31:37 +04:00
{
2013-04-03 10:01:58 +04:00
struct pn533_std_frame * frame = _frame ;
2012-12-10 17:43:01 +04:00
2013-04-03 10:01:58 +04:00
frame - > datalen_checksum = pn533_std_checksum ( frame - > datalen ) ;
2011-07-02 02:31:37 +04:00
2013-04-03 10:01:58 +04:00
PN533_STD_FRAME_CHECKSUM ( frame ) =
pn533_std_data_checksum ( frame - > data , frame - > datalen ) ;
2011-07-02 02:31:37 +04:00
2013-04-03 10:01:58 +04:00
PN533_STD_FRAME_POSTAMBLE ( frame ) = 0 ;
2011-07-02 02:31:37 +04:00
}
2013-04-03 10:01:58 +04:00
static void pn533_std_tx_update_payload_len ( void * _frame , int len )
2012-12-10 17:43:01 +04:00
{
2013-04-03 10:01:58 +04:00
struct pn533_std_frame * frame = _frame ;
2012-12-10 17:43:01 +04:00
frame - > datalen + = len ;
}
2013-06-13 17:43:29 +04:00
static bool pn533_std_rx_frame_is_valid ( void * _frame , struct pn533 * dev )
2011-07-02 02:31:37 +04:00
{
u8 checksum ;
2013-06-13 17:43:27 +04:00
struct pn533_std_frame * stdf = _frame ;
2011-07-02 02:31:37 +04:00
2013-06-13 17:43:27 +04:00
if ( stdf - > start_frame ! = cpu_to_be16 ( PN533_STD_FRAME_SOF ) )
2011-07-02 02:31:37 +04:00
return false ;
2013-06-13 17:43:27 +04:00
if ( likely ( ! PN533_STD_IS_EXTENDED ( stdf ) ) ) {
/* Standard frame code */
2013-06-13 17:43:29 +04:00
dev - > ops - > rx_header_len = PN533_STD_FRAME_HEADER_LEN ;
2013-06-13 17:43:27 +04:00
checksum = pn533_std_checksum ( stdf - > datalen ) ;
if ( checksum ! = stdf - > datalen_checksum )
return false ;
checksum = pn533_std_data_checksum ( stdf - > data , stdf - > datalen ) ;
if ( checksum ! = PN533_STD_FRAME_CHECKSUM ( stdf ) )
return false ;
} else {
/* Extended */
struct pn533_ext_frame * eif = _frame ;
2013-06-13 17:43:29 +04:00
dev - > ops - > rx_header_len = PN533_EXT_FRAME_HEADER_LEN ;
2013-06-13 17:43:27 +04:00
checksum = pn533_ext_checksum ( be16_to_cpu ( eif - > datalen ) ) ;
if ( checksum ! = eif - > datalen_checksum )
return false ;
/* check data checksum */
checksum = pn533_std_data_checksum ( eif - > data ,
be16_to_cpu ( eif - > datalen ) ) ;
if ( checksum ! = PN533_EXT_FRAME_CHECKSUM ( eif ) )
return false ;
}
2011-07-02 02:31:37 +04:00
return true ;
}
2016-03-25 17:46:53 +03:00
bool pn533_rx_frame_is_ack ( void * _frame )
2011-07-02 02:31:37 +04:00
{
2016-03-25 17:46:53 +03:00
struct pn533_std_frame * frame = _frame ;
2013-04-03 10:01:58 +04:00
if ( frame - > start_frame ! = cpu_to_be16 ( PN533_STD_FRAME_SOF ) )
2011-07-02 02:31:37 +04:00
return false ;
if ( frame - > datalen ! = 0 | | frame - > datalen_checksum ! = 0xFF )
return false ;
return true ;
}
2016-03-25 17:46:53 +03:00
EXPORT_SYMBOL_GPL ( pn533_rx_frame_is_ack ) ;
2011-07-02 02:31:37 +04:00
2013-04-03 10:01:58 +04:00
static inline int pn533_std_rx_frame_size ( void * frame )
2012-12-10 17:43:01 +04:00
{
2013-04-03 10:01:58 +04:00
struct pn533_std_frame * f = frame ;
2012-12-10 17:43:01 +04:00
2013-06-13 17:43:27 +04:00
/* check for Extended Information frame */
if ( PN533_STD_IS_EXTENDED ( f ) ) {
struct pn533_ext_frame * eif = frame ;
return sizeof ( struct pn533_ext_frame )
+ be16_to_cpu ( eif - > datalen ) + PN533_STD_FRAME_TAIL_LEN ;
}
2013-04-03 10:01:58 +04:00
return sizeof ( struct pn533_std_frame ) + f - > datalen +
PN533_STD_FRAME_TAIL_LEN ;
2012-12-10 17:43:01 +04:00
}
2013-04-03 10:01:58 +04:00
static u8 pn533_std_get_cmd_code ( void * frame )
2012-12-10 17:43:01 +04:00
{
2013-04-03 10:01:58 +04:00
struct pn533_std_frame * f = frame ;
2013-06-13 17:43:27 +04:00
struct pn533_ext_frame * eif = frame ;
2012-12-10 17:43:01 +04:00
2013-06-13 17:43:27 +04:00
if ( PN533_STD_IS_EXTENDED ( f ) )
return PN533_FRAME_CMD ( eif ) ;
else
return PN533_FRAME_CMD ( f ) ;
2012-12-10 17:43:01 +04:00
}
2016-03-25 17:46:53 +03:00
bool pn533_rx_frame_is_cmd_response ( struct pn533 * dev , void * frame )
{
return ( dev - > ops - > get_cmd_code ( frame ) = =
PN533_CMD_RESPONSE ( dev - > cmd - > code ) ) ;
}
EXPORT_SYMBOL_GPL ( pn533_rx_frame_is_cmd_response ) ;
2013-01-16 18:51:51 +04:00
static struct pn533_frame_ops pn533_std_frame_ops = {
2013-04-03 10:01:58 +04:00
. tx_frame_init = pn533_std_tx_frame_init ,
. tx_frame_finish = pn533_std_tx_frame_finish ,
. tx_update_payload_len = pn533_std_tx_update_payload_len ,
. tx_header_len = PN533_STD_FRAME_HEADER_LEN ,
. tx_tail_len = PN533_STD_FRAME_TAIL_LEN ,
. rx_is_frame_valid = pn533_std_rx_frame_is_valid ,
. rx_frame_size = pn533_std_rx_frame_size ,
. rx_header_len = PN533_STD_FRAME_HEADER_LEN ,
. rx_tail_len = PN533_STD_FRAME_TAIL_LEN ,
. max_payload_len = PN533_STD_FRAME_MAX_PAYLOAD_LEN ,
. get_cmd_code = pn533_std_get_cmd_code ,
2012-12-10 17:43:01 +04:00
} ;
static void pn533_build_cmd_frame ( struct pn533 * dev , u8 cmd_code ,
struct sk_buff * skb )
2012-11-26 17:18:34 +04:00
{
/* payload is already there, just update datalen */
int payload_len = skb - > len ;
2012-12-10 17:43:01 +04:00
struct pn533_frame_ops * ops = dev - > ops ;
2012-11-26 17:18:34 +04:00
2012-12-10 17:43:01 +04:00
skb_push ( skb , ops - > tx_header_len ) ;
skb_put ( skb , ops - > tx_tail_len ) ;
2012-11-26 17:18:34 +04:00
2012-12-10 17:43:01 +04:00
ops - > tx_frame_init ( skb - > data , cmd_code ) ;
ops - > tx_update_payload_len ( skb - > data , payload_len ) ;
ops - > tx_frame_finish ( skb - > data ) ;
2012-11-26 17:18:34 +04:00
}
2013-04-03 10:02:08 +04:00
static int pn533_send_async_complete ( struct pn533 * dev )
2012-11-26 17:18:34 +04:00
{
2013-04-03 10:02:08 +04:00
struct pn533_cmd * cmd = dev - > cmd ;
2013-04-03 10:02:11 +04:00
int status = cmd - > status ;
2012-11-26 17:18:34 +04:00
2013-04-03 10:02:04 +04:00
struct sk_buff * req = cmd - > req ;
struct sk_buff * resp = cmd - > resp ;
2012-11-26 17:18:34 +04:00
int rc ;
dev_kfree_skb ( req ) ;
2012-12-10 17:42:59 +04:00
if ( status < 0 ) {
2013-04-03 10:02:04 +04:00
rc = cmd - > complete_cb ( dev , cmd - > complete_cb_context ,
ERR_PTR ( status ) ) ;
2012-11-26 17:18:34 +04:00
dev_kfree_skb ( resp ) ;
2013-04-03 10:02:05 +04:00
goto done ;
2012-11-26 17:18:34 +04:00
}
2012-12-10 17:43:01 +04:00
skb_pull ( resp , dev - > ops - > rx_header_len ) ;
skb_trim ( resp , resp - > len - dev - > ops - > rx_tail_len ) ;
2012-11-26 17:18:34 +04:00
2013-04-03 10:02:04 +04:00
rc = cmd - > complete_cb ( dev , cmd - > complete_cb_context , resp ) ;
2012-11-26 17:18:34 +04:00
2013-04-03 10:02:05 +04:00
done :
2013-04-03 10:02:04 +04:00
kfree ( cmd ) ;
2013-04-03 10:02:05 +04:00
dev - > cmd = NULL ;
2012-11-26 17:18:34 +04:00
return rc ;
}
static int __pn533_send_async ( struct pn533 * dev , u8 cmd_code ,
2016-03-25 17:46:53 +03:00
struct sk_buff * req ,
2012-11-26 17:18:34 +04:00
pn533_send_async_complete_t complete_cb ,
void * complete_cb_context )
{
struct pn533_cmd * cmd ;
int rc = 0 ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " Sending command 0x%x \n " , cmd_code ) ;
2012-11-26 17:18:34 +04:00
2013-04-03 10:02:04 +04:00
cmd = kzalloc ( sizeof ( * cmd ) , GFP_KERNEL ) ;
if ( ! cmd )
2012-11-26 17:18:34 +04:00
return - ENOMEM ;
2013-04-03 10:02:06 +04:00
cmd - > code = cmd_code ;
2013-04-03 10:02:04 +04:00
cmd - > req = req ;
cmd - > complete_cb = complete_cb ;
cmd - > complete_cb_context = complete_cb_context ;
2012-11-26 17:18:34 +04:00
2012-12-10 17:43:01 +04:00
pn533_build_cmd_frame ( dev , cmd_code , req ) ;
2012-11-26 17:18:34 +04:00
mutex_lock ( & dev - > cmd_lock ) ;
if ( ! dev - > cmd_pending ) {
2016-03-25 17:46:53 +03:00
rc = dev - > phy_ops - > send_frame ( dev , req ) ;
2012-11-26 17:18:34 +04:00
if ( rc )
goto error ;
dev - > cmd_pending = 1 ;
2013-04-03 10:02:05 +04:00
dev - > cmd = cmd ;
2012-11-26 17:18:34 +04:00
goto unlock ;
}
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s Queueing command 0x%x \n " ,
2013-04-05 23:27:37 +04:00
__func__ , cmd_code ) ;
2012-11-26 17:18:34 +04:00
INIT_LIST_HEAD ( & cmd - > queue ) ;
list_add_tail ( & cmd - > queue , & dev - > cmd_queue ) ;
goto unlock ;
error :
2013-04-03 10:02:04 +04:00
kfree ( cmd ) ;
2012-11-26 17:18:34 +04:00
unlock :
mutex_unlock ( & dev - > cmd_lock ) ;
return rc ;
2012-11-26 17:18:35 +04:00
}
static int pn533_send_data_async ( struct pn533 * dev , u8 cmd_code ,
struct sk_buff * req ,
pn533_send_async_complete_t complete_cb ,
void * complete_cb_context )
{
int rc ;
2016-03-25 17:46:53 +03:00
rc = __pn533_send_async ( dev , cmd_code , req , complete_cb ,
2012-11-26 17:18:35 +04:00
complete_cb_context ) ;
return rc ;
2012-11-26 17:18:34 +04:00
}
static int pn533_send_cmd_async ( struct pn533 * dev , u8 cmd_code ,
struct sk_buff * req ,
pn533_send_async_complete_t complete_cb ,
void * complete_cb_context )
{
int rc ;
2016-03-25 17:46:53 +03:00
rc = __pn533_send_async ( dev , cmd_code , req , complete_cb ,
2012-12-10 17:43:01 +04:00
complete_cb_context ) ;
2012-11-26 17:18:34 +04:00
return rc ;
}
2012-12-10 17:42:46 +04:00
/*
* pn533_send_cmd_direct_async
*
* The function sends a piority cmd directly to the chip omiting the cmd
* queue . It ' s intended to be used by chaining mechanism of received responses
* where the host has to request every single chunk of data before scheduling
* next cmd from the queue .
*/
static int pn533_send_cmd_direct_async ( struct pn533 * dev , u8 cmd_code ,
struct sk_buff * req ,
pn533_send_async_complete_t complete_cb ,
void * complete_cb_context )
{
2013-04-03 10:02:04 +04:00
struct pn533_cmd * cmd ;
2012-12-10 17:42:46 +04:00
int rc ;
2013-04-03 10:02:04 +04:00
cmd = kzalloc ( sizeof ( * cmd ) , GFP_KERNEL ) ;
2016-03-25 17:46:53 +03:00
if ( ! cmd )
2012-12-10 17:42:46 +04:00
return - ENOMEM ;
2013-04-03 10:02:06 +04:00
cmd - > code = cmd_code ;
2013-04-03 10:02:04 +04:00
cmd - > req = req ;
cmd - > complete_cb = complete_cb ;
cmd - > complete_cb_context = complete_cb_context ;
2012-12-10 17:42:46 +04:00
2012-12-10 17:43:01 +04:00
pn533_build_cmd_frame ( dev , cmd_code , req ) ;
2012-12-10 17:42:46 +04:00
2016-03-25 17:46:53 +03:00
rc = dev - > phy_ops - > send_frame ( dev , req ) ;
if ( rc < 0 )
2013-04-03 10:02:04 +04:00
kfree ( cmd ) ;
2016-03-25 17:46:53 +03:00
else
2013-04-03 10:02:05 +04:00
dev - > cmd = cmd ;
2012-12-10 17:42:46 +04:00
return rc ;
}
2013-04-03 10:02:09 +04:00
static void pn533_wq_cmd_complete ( struct work_struct * work )
{
struct pn533 * dev = container_of ( work , struct pn533 , cmd_complete_work ) ;
int rc ;
rc = pn533_send_async_complete ( dev ) ;
if ( rc ! = - EINPROGRESS )
queue_work ( dev - > wq , & dev - > cmd_work ) ;
}
2012-08-18 01:47:54 +04:00
static void pn533_wq_cmd ( struct work_struct * work )
{
struct pn533 * dev = container_of ( work , struct pn533 , cmd_work ) ;
struct pn533_cmd * cmd ;
2013-04-03 10:02:03 +04:00
int rc ;
2012-08-18 01:47:54 +04:00
mutex_lock ( & dev - > cmd_lock ) ;
if ( list_empty ( & dev - > cmd_queue ) ) {
dev - > cmd_pending = 0 ;
mutex_unlock ( & dev - > cmd_lock ) ;
return ;
}
cmd = list_first_entry ( & dev - > cmd_queue , struct pn533_cmd , queue ) ;
2012-10-25 19:29:45 +04:00
list_del ( & cmd - > queue ) ;
2012-08-18 01:47:54 +04:00
mutex_unlock ( & dev - > cmd_lock ) ;
2016-03-25 17:46:53 +03:00
rc = dev - > phy_ops - > send_frame ( dev , cmd - > req ) ;
2013-04-03 10:02:03 +04:00
if ( rc < 0 ) {
dev_kfree_skb ( cmd - > req ) ;
2013-04-03 10:02:04 +04:00
kfree ( cmd ) ;
2013-04-03 10:02:05 +04:00
return ;
2013-04-03 10:02:03 +04:00
}
2013-04-03 10:02:05 +04:00
dev - > cmd = cmd ;
2012-08-18 01:47:54 +04:00
}
2011-07-02 02:31:37 +04:00
struct pn533_sync_cmd_response {
2012-11-26 17:18:36 +04:00
struct sk_buff * resp ;
2011-07-02 02:31:37 +04:00
struct completion done ;
} ;
2012-11-26 17:18:36 +04:00
static int pn533_send_sync_complete ( struct pn533 * dev , void * _arg ,
struct sk_buff * resp )
{
struct pn533_sync_cmd_response * arg = _arg ;
arg - > resp = resp ;
complete ( & arg - > done ) ;
return 0 ;
}
/* pn533_send_cmd_sync
*
* Please note the req parameter is freed inside the function to
* limit a number of return value interpretations by the caller .
*
* 1. negative in case of error during TX path - > req should be freed
*
* 2. negative in case of error during RX path - > req should not be freed
2016-03-25 17:46:53 +03:00
* as it ' s been already freed at the beginning of RX path by
2012-11-26 17:18:36 +04:00
* async_complete_cb .
*
* 3. valid pointer in case of succesfult RX path
*
* A caller has to check a return value with IS_ERR macro . If the test pass ,
* the returned pointer is valid .
*
2016-03-25 17:46:53 +03:00
*/
2012-11-26 17:18:36 +04:00
static struct sk_buff * pn533_send_cmd_sync ( struct pn533 * dev , u8 cmd_code ,
struct sk_buff * req )
{
int rc ;
struct pn533_sync_cmd_response arg ;
init_completion ( & arg . done ) ;
rc = pn533_send_cmd_async ( dev , cmd_code , req ,
pn533_send_sync_complete , & arg ) ;
if ( rc ) {
dev_kfree_skb ( req ) ;
return ERR_PTR ( rc ) ;
}
wait_for_completion ( & arg . done ) ;
return arg . resp ;
}
2012-12-10 17:43:01 +04:00
static struct sk_buff * pn533_alloc_skb ( struct pn533 * dev , unsigned int size )
2012-11-26 17:18:37 +04:00
{
struct sk_buff * skb ;
2012-12-10 17:43:01 +04:00
skb = alloc_skb ( dev - > ops - > tx_header_len +
2012-11-26 17:18:37 +04:00
size +
2012-12-10 17:43:01 +04:00
dev - > ops - > tx_tail_len , GFP_KERNEL ) ;
2012-11-26 17:18:37 +04:00
if ( skb )
2012-12-10 17:43:01 +04:00
skb_reserve ( skb , dev - > ops - > tx_header_len ) ;
2012-11-26 17:18:37 +04:00
return skb ;
}
2011-07-02 02:31:37 +04:00
struct pn533_target_type_a {
__be16 sens_res ;
u8 sel_res ;
u8 nfcid_len ;
u8 nfcid_data [ ] ;
} __packed ;
# define PN533_TYPE_A_SENS_RES_NFCID1(x) ((u8)((be16_to_cpu(x) & 0x00C0) >> 6))
# define PN533_TYPE_A_SENS_RES_SSD(x) ((u8)((be16_to_cpu(x) & 0x001F) >> 0))
# define PN533_TYPE_A_SENS_RES_PLATCONF(x) ((u8)((be16_to_cpu(x) & 0x0F00) >> 8))
# define PN533_TYPE_A_SENS_RES_SSD_JEWEL 0x00
# define PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL 0x0C
# define PN533_TYPE_A_SEL_PROT(x) (((x) & 0x60) >> 5)
# define PN533_TYPE_A_SEL_CASCADE(x) (((x) & 0x04) >> 2)
# define PN533_TYPE_A_SEL_PROT_MIFARE 0
# define PN533_TYPE_A_SEL_PROT_ISO14443 1
# define PN533_TYPE_A_SEL_PROT_DEP 2
# define PN533_TYPE_A_SEL_PROT_ISO14443_DEP 3
static bool pn533_target_type_a_is_valid ( struct pn533_target_type_a * type_a ,
int target_data_len )
{
u8 ssd ;
u8 platconf ;
if ( target_data_len < sizeof ( struct pn533_target_type_a ) )
return false ;
2016-03-25 17:46:53 +03:00
/*
* The length check of nfcid [ ] and ats [ ] are not being performed because
* the values are not being used
*/
2011-07-02 02:31:37 +04:00
/* Requirement 4.6.3.3 from NFC Forum Digital Spec */
ssd = PN533_TYPE_A_SENS_RES_SSD ( type_a - > sens_res ) ;
platconf = PN533_TYPE_A_SENS_RES_PLATCONF ( type_a - > sens_res ) ;
if ( ( ssd = = PN533_TYPE_A_SENS_RES_SSD_JEWEL & &
2012-12-10 17:42:51 +04:00
platconf ! = PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL ) | |
( ssd ! = PN533_TYPE_A_SENS_RES_SSD_JEWEL & &
platconf = = PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL ) )
2011-07-02 02:31:37 +04:00
return false ;
/* Requirements 4.8.2.1, 4.8.2.3, 4.8.2.5 and 4.8.2.7 from NFC Forum */
if ( PN533_TYPE_A_SEL_CASCADE ( type_a - > sel_res ) ! = 0 )
return false ;
return true ;
}
static int pn533_target_found_type_a ( struct nfc_target * nfc_tgt , u8 * tgt_data ,
int tgt_data_len )
{
struct pn533_target_type_a * tgt_type_a ;
2012-12-10 17:42:50 +04:00
tgt_type_a = ( struct pn533_target_type_a * ) tgt_data ;
2011-07-02 02:31:37 +04:00
if ( ! pn533_target_type_a_is_valid ( tgt_type_a , tgt_data_len ) )
return - EPROTO ;
switch ( PN533_TYPE_A_SEL_PROT ( tgt_type_a - > sel_res ) ) {
case PN533_TYPE_A_SEL_PROT_MIFARE :
nfc_tgt - > supported_protocols = NFC_PROTO_MIFARE_MASK ;
break ;
case PN533_TYPE_A_SEL_PROT_ISO14443 :
nfc_tgt - > supported_protocols = NFC_PROTO_ISO14443_MASK ;
break ;
case PN533_TYPE_A_SEL_PROT_DEP :
nfc_tgt - > supported_protocols = NFC_PROTO_NFC_DEP_MASK ;
break ;
case PN533_TYPE_A_SEL_PROT_ISO14443_DEP :
nfc_tgt - > supported_protocols = NFC_PROTO_ISO14443_MASK |
NFC_PROTO_NFC_DEP_MASK ;
break ;
}
nfc_tgt - > sens_res = be16_to_cpu ( tgt_type_a - > sens_res ) ;
nfc_tgt - > sel_res = tgt_type_a - > sel_res ;
2012-03-05 04:03:33 +04:00
nfc_tgt - > nfcid1_len = tgt_type_a - > nfcid_len ;
memcpy ( nfc_tgt - > nfcid1 , tgt_type_a - > nfcid_data , nfc_tgt - > nfcid1_len ) ;
2011-07-02 02:31:37 +04:00
return 0 ;
}
struct pn533_target_felica {
u8 pol_res ;
u8 opcode ;
2013-05-27 17:29:11 +04:00
u8 nfcid2 [ NFC_NFCID2_MAXSIZE ] ;
2011-07-02 02:31:37 +04:00
u8 pad [ 8 ] ;
/* optional */
u8 syst_code [ ] ;
} __packed ;
# define PN533_FELICA_SENSF_NFCID2_DEP_B1 0x01
# define PN533_FELICA_SENSF_NFCID2_DEP_B2 0xFE
static bool pn533_target_felica_is_valid ( struct pn533_target_felica * felica ,
int target_data_len )
{
if ( target_data_len < sizeof ( struct pn533_target_felica ) )
return false ;
if ( felica - > opcode ! = PN533_FELICA_OPC_SENSF_RES )
return false ;
return true ;
}
static int pn533_target_found_felica ( struct nfc_target * nfc_tgt , u8 * tgt_data ,
int tgt_data_len )
{
struct pn533_target_felica * tgt_felica ;
2012-12-10 17:42:50 +04:00
tgt_felica = ( struct pn533_target_felica * ) tgt_data ;
2011-07-02 02:31:37 +04:00
if ( ! pn533_target_felica_is_valid ( tgt_felica , tgt_data_len ) )
return - EPROTO ;
2012-12-10 17:42:51 +04:00
if ( ( tgt_felica - > nfcid2 [ 0 ] = = PN533_FELICA_SENSF_NFCID2_DEP_B1 ) & &
( tgt_felica - > nfcid2 [ 1 ] = = PN533_FELICA_SENSF_NFCID2_DEP_B2 ) )
2011-07-02 02:31:37 +04:00
nfc_tgt - > supported_protocols = NFC_PROTO_NFC_DEP_MASK ;
else
nfc_tgt - > supported_protocols = NFC_PROTO_FELICA_MASK ;
2012-03-05 04:03:45 +04:00
memcpy ( nfc_tgt - > sensf_res , & tgt_felica - > opcode , 9 ) ;
nfc_tgt - > sensf_res_len = 9 ;
2013-05-27 17:29:11 +04:00
memcpy ( nfc_tgt - > nfcid2 , tgt_felica - > nfcid2 , NFC_NFCID2_MAXSIZE ) ;
nfc_tgt - > nfcid2_len = NFC_NFCID2_MAXSIZE ;
2011-07-02 02:31:37 +04:00
return 0 ;
}
struct pn533_target_jewel {
__be16 sens_res ;
u8 jewelid [ 4 ] ;
} __packed ;
static bool pn533_target_jewel_is_valid ( struct pn533_target_jewel * jewel ,
int target_data_len )
{
u8 ssd ;
u8 platconf ;
if ( target_data_len < sizeof ( struct pn533_target_jewel ) )
return false ;
/* Requirement 4.6.3.3 from NFC Forum Digital Spec */
ssd = PN533_TYPE_A_SENS_RES_SSD ( jewel - > sens_res ) ;
platconf = PN533_TYPE_A_SENS_RES_PLATCONF ( jewel - > sens_res ) ;
if ( ( ssd = = PN533_TYPE_A_SENS_RES_SSD_JEWEL & &
2012-12-10 17:42:51 +04:00
platconf ! = PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL ) | |
( ssd ! = PN533_TYPE_A_SENS_RES_SSD_JEWEL & &
platconf = = PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL ) )
2011-07-02 02:31:37 +04:00
return false ;
return true ;
}
static int pn533_target_found_jewel ( struct nfc_target * nfc_tgt , u8 * tgt_data ,
int tgt_data_len )
{
struct pn533_target_jewel * tgt_jewel ;
2012-12-10 17:42:50 +04:00
tgt_jewel = ( struct pn533_target_jewel * ) tgt_data ;
2011-07-02 02:31:37 +04:00
if ( ! pn533_target_jewel_is_valid ( tgt_jewel , tgt_data_len ) )
return - EPROTO ;
nfc_tgt - > supported_protocols = NFC_PROTO_JEWEL_MASK ;
nfc_tgt - > sens_res = be16_to_cpu ( tgt_jewel - > sens_res ) ;
2012-03-05 04:03:46 +04:00
nfc_tgt - > nfcid1_len = 4 ;
memcpy ( nfc_tgt - > nfcid1 , tgt_jewel - > jewelid , nfc_tgt - > nfcid1_len ) ;
2011-07-02 02:31:37 +04:00
return 0 ;
}
struct pn533_type_b_prot_info {
u8 bitrate ;
u8 fsci_type ;
u8 fwi_adc_fo ;
} __packed ;
# define PN533_TYPE_B_PROT_FCSI(x) (((x) & 0xF0) >> 4)
# define PN533_TYPE_B_PROT_TYPE(x) (((x) & 0x0F) >> 0)
# define PN533_TYPE_B_PROT_TYPE_RFU_MASK 0x8
struct pn533_type_b_sens_res {
u8 opcode ;
u8 nfcid [ 4 ] ;
u8 appdata [ 4 ] ;
struct pn533_type_b_prot_info prot_info ;
} __packed ;
# define PN533_TYPE_B_OPC_SENSB_RES 0x50
struct pn533_target_type_b {
struct pn533_type_b_sens_res sensb_res ;
u8 attrib_res_len ;
u8 attrib_res [ ] ;
} __packed ;
static bool pn533_target_type_b_is_valid ( struct pn533_target_type_b * type_b ,
int target_data_len )
{
if ( target_data_len < sizeof ( struct pn533_target_type_b ) )
return false ;
if ( type_b - > sensb_res . opcode ! = PN533_TYPE_B_OPC_SENSB_RES )
return false ;
if ( PN533_TYPE_B_PROT_TYPE ( type_b - > sensb_res . prot_info . fsci_type ) &
PN533_TYPE_B_PROT_TYPE_RFU_MASK )
return false ;
return true ;
}
static int pn533_target_found_type_b ( struct nfc_target * nfc_tgt , u8 * tgt_data ,
int tgt_data_len )
{
struct pn533_target_type_b * tgt_type_b ;
2012-12-10 17:42:50 +04:00
tgt_type_b = ( struct pn533_target_type_b * ) tgt_data ;
2011-07-02 02:31:37 +04:00
if ( ! pn533_target_type_b_is_valid ( tgt_type_b , tgt_data_len ) )
return - EPROTO ;
2012-07-04 02:14:04 +04:00
nfc_tgt - > supported_protocols = NFC_PROTO_ISO14443_B_MASK ;
2011-07-02 02:31:37 +04:00
return 0 ;
}
2012-12-10 17:42:48 +04:00
static int pn533_target_found ( struct pn533 * dev , u8 tg , u8 * tgdata ,
int tgdata_len )
2011-07-02 02:31:37 +04:00
{
struct nfc_target nfc_tgt ;
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s: modulation=%d \n " ,
2013-04-05 23:27:37 +04:00
__func__ , dev - > poll_mod_curr ) ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:42:48 +04:00
if ( tg ! = 1 )
2011-07-02 02:31:37 +04:00
return - EPROTO ;
2012-03-05 04:03:39 +04:00
memset ( & nfc_tgt , 0 , sizeof ( struct nfc_target ) ) ;
2011-07-02 02:31:37 +04:00
switch ( dev - > poll_mod_curr ) {
case PN533_POLL_MOD_106KBPS_A :
2012-12-10 17:42:48 +04:00
rc = pn533_target_found_type_a ( & nfc_tgt , tgdata , tgdata_len ) ;
2011-07-02 02:31:37 +04:00
break ;
case PN533_POLL_MOD_212KBPS_FELICA :
case PN533_POLL_MOD_424KBPS_FELICA :
2012-12-10 17:42:48 +04:00
rc = pn533_target_found_felica ( & nfc_tgt , tgdata , tgdata_len ) ;
2011-07-02 02:31:37 +04:00
break ;
case PN533_POLL_MOD_106KBPS_JEWEL :
2012-12-10 17:42:48 +04:00
rc = pn533_target_found_jewel ( & nfc_tgt , tgdata , tgdata_len ) ;
2011-07-02 02:31:37 +04:00
break ;
case PN533_POLL_MOD_847KBPS_B :
2012-12-10 17:42:48 +04:00
rc = pn533_target_found_type_b ( & nfc_tgt , tgdata , tgdata_len ) ;
2011-07-02 02:31:37 +04:00
break ;
default :
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Unknown current poll modulation \n " ) ;
2011-07-02 02:31:37 +04:00
return - EPROTO ;
}
if ( rc )
return rc ;
if ( ! ( nfc_tgt . supported_protocols & dev - > poll_protocols ) ) {
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev ,
2013-04-05 23:27:37 +04:00
" The Tg found doesn't have the desired protocol \n " ) ;
2011-07-02 02:31:37 +04:00
return - EAGAIN ;
}
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev ,
2013-04-05 23:27:37 +04:00
" Target found - supported protocols: 0x%x \n " ,
nfc_tgt . supported_protocols ) ;
2011-07-02 02:31:37 +04:00
dev - > tgt_available_prots = nfc_tgt . supported_protocols ;
nfc_targets_found ( dev - > nfc_dev , & nfc_tgt , 1 ) ;
return 0 ;
}
2012-05-30 19:20:25 +04:00
static inline void pn533_poll_next_mod ( struct pn533 * dev )
{
dev - > poll_mod_curr = ( dev - > poll_mod_curr + 1 ) % dev - > poll_mod_count ;
}
2011-07-02 02:31:37 +04:00
static void pn533_poll_reset_mod_list ( struct pn533 * dev )
{
dev - > poll_mod_count = 0 ;
}
static void pn533_poll_add_mod ( struct pn533 * dev , u8 mod_index )
{
dev - > poll_mod_active [ dev - > poll_mod_count ] =
2012-12-10 17:42:50 +04:00
( struct pn533_poll_modulations * ) & poll_mod [ mod_index ] ;
2011-07-02 02:31:37 +04:00
dev - > poll_mod_count + + ;
}
2012-05-30 19:20:25 +04:00
static void pn533_poll_create_mod_list ( struct pn533 * dev ,
u32 im_protocols , u32 tm_protocols )
2011-07-02 02:31:37 +04:00
{
pn533_poll_reset_mod_list ( dev ) ;
2012-12-10 17:42:52 +04:00
if ( ( im_protocols & NFC_PROTO_MIFARE_MASK ) | |
( im_protocols & NFC_PROTO_ISO14443_MASK ) | |
( im_protocols & NFC_PROTO_NFC_DEP_MASK ) )
2011-07-02 02:31:37 +04:00
pn533_poll_add_mod ( dev , PN533_POLL_MOD_106KBPS_A ) ;
2012-12-10 17:42:52 +04:00
if ( im_protocols & NFC_PROTO_FELICA_MASK | |
im_protocols & NFC_PROTO_NFC_DEP_MASK ) {
2011-07-02 02:31:37 +04:00
pn533_poll_add_mod ( dev , PN533_POLL_MOD_212KBPS_FELICA ) ;
pn533_poll_add_mod ( dev , PN533_POLL_MOD_424KBPS_FELICA ) ;
}
2012-05-30 19:20:25 +04:00
if ( im_protocols & NFC_PROTO_JEWEL_MASK )
2011-07-02 02:31:37 +04:00
pn533_poll_add_mod ( dev , PN533_POLL_MOD_106KBPS_JEWEL ) ;
2012-07-04 02:14:04 +04:00
if ( im_protocols & NFC_PROTO_ISO14443_B_MASK )
2011-07-02 02:31:37 +04:00
pn533_poll_add_mod ( dev , PN533_POLL_MOD_847KBPS_B ) ;
2012-05-30 19:20:25 +04:00
if ( tm_protocols )
pn533_poll_add_mod ( dev , PN533_LISTEN_MOD ) ;
2011-07-02 02:31:37 +04:00
}
2012-12-10 17:42:48 +04:00
static int pn533_start_poll_complete ( struct pn533 * dev , struct sk_buff * resp )
2011-07-02 02:31:37 +04:00
{
2012-12-10 17:42:48 +04:00
u8 nbtg , tg , * tgdata ;
int rc , tgdata_len ;
2011-07-02 02:31:37 +04:00
2013-08-21 17:06:55 +04:00
/* Toggle the DEP polling */
2016-03-25 17:46:51 +03:00
if ( dev - > poll_protocols & NFC_PROTO_NFC_DEP_MASK )
dev - > poll_dep = 1 ;
2013-08-21 17:06:55 +04:00
2012-12-10 17:42:48 +04:00
nbtg = resp - > data [ 0 ] ;
tg = resp - > data [ 1 ] ;
tgdata = & resp - > data [ 2 ] ;
tgdata_len = resp - > len - 2 ; /* nbtg + tg */
if ( nbtg ) {
rc = pn533_target_found ( dev , tg , tgdata , tgdata_len ) ;
2011-07-02 02:31:37 +04:00
/* We must stop the poll after a valid target found */
2012-05-30 19:20:25 +04:00
if ( rc = = 0 ) {
pn533_poll_reset_mod_list ( dev ) ;
return 0 ;
}
2011-07-02 02:31:37 +04:00
}
2012-05-30 19:20:25 +04:00
return - EAGAIN ;
2011-07-02 02:31:37 +04:00
}
2012-12-10 17:43:01 +04:00
static struct sk_buff * pn533_alloc_poll_tg_frame ( struct pn533 * dev )
2012-05-31 01:54:55 +04:00
{
2012-12-10 17:42:48 +04:00
struct sk_buff * skb ;
u8 * felica , * nfcid3 , * gb ;
2012-12-10 17:43:01 +04:00
u8 * gbytes = dev - > gb ;
size_t gbytes_len = dev - > gb_len ;
2012-05-30 03:48:46 +04:00
u8 felica_params [ 18 ] = { 0x1 , 0xfe , /* DEP */
0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , /* random */
0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
0xff , 0xff } ; /* System code */
2012-12-10 17:42:48 +04:00
2012-05-30 03:48:46 +04:00
u8 mifare_params [ 6 ] = { 0x1 , 0x1 , /* SENS_RES */
0x0 , 0x0 , 0x0 ,
0x40 } ; /* SEL_RES for DEP */
2012-05-31 01:54:55 +04:00
2016-03-25 17:46:53 +03:00
unsigned int skb_len = 36 + /*
* mode ( 1 ) , mifare ( 6 ) ,
* felica ( 18 ) , nfcid3 ( 10 ) , gb_len ( 1 )
*/
2012-12-10 17:42:48 +04:00
gbytes_len +
1 ; /* len Tk*/
2012-05-31 01:54:55 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , skb_len ) ;
2012-12-10 17:42:48 +04:00
if ( ! skb )
return NULL ;
2012-05-31 01:54:55 +04:00
/* DEP support only */
2013-02-05 13:08:35 +04:00
* skb_put ( skb , 1 ) = PN533_INIT_TARGET_DEP ;
2012-12-10 17:42:48 +04:00
/* MIFARE params */
memcpy ( skb_put ( skb , 6 ) , mifare_params , 6 ) ;
2012-05-30 03:48:46 +04:00
/* Felica params */
2012-12-10 17:42:48 +04:00
felica = skb_put ( skb , 18 ) ;
memcpy ( felica , felica_params , 18 ) ;
get_random_bytes ( felica + 2 , 6 ) ;
2012-05-30 03:48:46 +04:00
/* NFCID3 */
2012-12-10 17:42:48 +04:00
nfcid3 = skb_put ( skb , 10 ) ;
memset ( nfcid3 , 0 , 10 ) ;
memcpy ( nfcid3 , felica , 8 ) ;
2012-05-30 03:48:46 +04:00
/* General bytes */
2012-12-10 17:42:48 +04:00
* skb_put ( skb , 1 ) = gbytes_len ;
2012-05-30 03:48:46 +04:00
2012-12-10 17:42:48 +04:00
gb = skb_put ( skb , gbytes_len ) ;
memcpy ( gb , gbytes , gbytes_len ) ;
2012-05-31 01:54:55 +04:00
2012-12-10 17:42:48 +04:00
/* Len Tk */
* skb_put ( skb , 1 ) = 0 ;
2012-05-30 03:48:46 +04:00
2012-12-10 17:42:48 +04:00
return skb ;
2012-05-31 01:54:55 +04:00
}
2013-09-23 14:24:38 +04:00
static void pn533_wq_tm_mi_recv ( struct work_struct * work ) ;
static struct sk_buff * pn533_build_response ( struct pn533 * dev ) ;
2012-05-31 02:07:51 +04:00
static int pn533_tm_get_data_complete ( struct pn533 * dev , void * arg ,
2012-12-10 17:42:44 +04:00
struct sk_buff * resp )
2012-05-31 02:07:51 +04:00
{
2013-09-23 14:24:38 +04:00
struct sk_buff * skb ;
u8 status , ret , mi ;
int rc ;
2012-05-31 02:07:51 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-05-31 02:07:51 +04:00
2013-09-23 14:24:38 +04:00
if ( IS_ERR ( resp ) ) {
skb_queue_purge ( & dev - > resp_q ) ;
2012-12-10 17:42:44 +04:00
return PTR_ERR ( resp ) ;
2013-09-23 14:24:38 +04:00
}
2012-05-31 02:07:51 +04:00
2012-12-10 17:42:44 +04:00
status = resp - > data [ 0 ] ;
2013-09-23 14:24:38 +04:00
ret = status & PN533_CMD_RET_MASK ;
mi = status & PN533_CMD_MI_MASK ;
2012-12-10 17:42:44 +04:00
skb_pull ( resp , sizeof ( status ) ) ;
2012-05-31 02:07:51 +04:00
2013-09-23 14:24:38 +04:00
if ( ret ! = PN533_CMD_RET_SUCCESS ) {
rc = - EIO ;
goto error ;
}
skb_queue_tail ( & dev - > resp_q , resp ) ;
if ( mi ) {
queue_work ( dev - > wq , & dev - > mi_tm_rx_work ) ;
return - EINPROGRESS ;
}
skb = pn533_build_response ( dev ) ;
if ( ! skb ) {
rc = - EIO ;
goto error ;
2012-05-31 02:07:51 +04:00
}
2013-09-23 14:24:38 +04:00
return nfc_tm_data_received ( dev - > nfc_dev , skb ) ;
error :
nfc_tm_deactivated ( dev - > nfc_dev ) ;
dev - > tgt_mode = 0 ;
skb_queue_purge ( & dev - > resp_q ) ;
dev_kfree_skb ( resp ) ;
return rc ;
}
static void pn533_wq_tm_mi_recv ( struct work_struct * work )
{
struct pn533 * dev = container_of ( work , struct pn533 , mi_tm_rx_work ) ;
struct sk_buff * skb ;
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2013-09-23 14:24:38 +04:00
skb = pn533_alloc_skb ( dev , 0 ) ;
if ( ! skb )
return ;
rc = pn533_send_cmd_direct_async ( dev ,
PN533_CMD_TG_GET_DATA ,
skb ,
pn533_tm_get_data_complete ,
NULL ) ;
if ( rc < 0 )
dev_kfree_skb ( skb ) ;
2012-05-31 02:07:51 +04:00
}
2013-09-23 14:24:39 +04:00
static int pn533_tm_send_complete ( struct pn533 * dev , void * arg ,
struct sk_buff * resp ) ;
static void pn533_wq_tm_mi_send ( struct work_struct * work )
{
struct pn533 * dev = container_of ( work , struct pn533 , mi_tm_tx_work ) ;
struct sk_buff * skb ;
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2013-09-23 14:24:39 +04:00
/* Grab the first skb in the queue */
skb = skb_dequeue ( & dev - > fragment_skb ) ;
if ( skb = = NULL ) { /* No more data */
/* Reset the queue for future use */
skb_queue_head_init ( & dev - > fragment_skb ) ;
goto error ;
}
/* last entry - remove MI bit */
if ( skb_queue_len ( & dev - > fragment_skb ) = = 0 ) {
rc = pn533_send_cmd_direct_async ( dev , PN533_CMD_TG_SET_DATA ,
skb , pn533_tm_send_complete , NULL ) ;
} else
rc = pn533_send_cmd_direct_async ( dev ,
PN533_CMD_TG_SET_META_DATA ,
skb , pn533_tm_send_complete , NULL ) ;
if ( rc = = 0 ) /* success */
return ;
2016-03-25 17:46:53 +03:00
dev_err ( dev - > dev ,
2013-09-23 14:24:39 +04:00
" Error %d when trying to perform set meta data_exchange " , rc ) ;
dev_kfree_skb ( skb ) ;
error :
2016-03-25 17:46:53 +03:00
dev - > phy_ops - > send_ack ( dev , GFP_KERNEL ) ;
2013-09-23 14:24:39 +04:00
queue_work ( dev - > wq , & dev - > cmd_work ) ;
}
2012-05-31 02:07:51 +04:00
static void pn533_wq_tg_get_data ( struct work_struct * work )
{
struct pn533 * dev = container_of ( work , struct pn533 , tg_work ) ;
2012-12-10 17:42:44 +04:00
struct sk_buff * skb ;
int rc ;
2012-05-31 02:07:51 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-05-31 02:07:51 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , 0 ) ;
2012-12-10 17:42:44 +04:00
if ( ! skb )
2012-05-31 02:07:51 +04:00
return ;
2012-12-10 17:42:44 +04:00
rc = pn533_send_data_async ( dev , PN533_CMD_TG_GET_DATA , skb ,
pn533_tm_get_data_complete , NULL ) ;
2012-05-31 02:07:51 +04:00
2012-12-10 17:42:44 +04:00
if ( rc < 0 )
dev_kfree_skb ( skb ) ;
2012-05-31 02:07:51 +04:00
}
2012-06-01 15:21:13 +04:00
# define ATR_REQ_GB_OFFSET 17
2012-12-10 17:42:48 +04:00
static int pn533_init_target_complete ( struct pn533 * dev , struct sk_buff * resp )
2012-05-15 17:57:06 +04:00
{
2012-12-10 17:42:48 +04:00
u8 mode , * cmd , comm_mode = NFC_COMM_PASSIVE , * gb ;
2012-06-01 15:21:13 +04:00
size_t gb_len ;
2012-05-31 02:07:51 +04:00
int rc ;
2012-05-31 01:54:55 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-05-31 01:54:55 +04:00
2012-12-10 17:42:48 +04:00
if ( resp - > len < ATR_REQ_GB_OFFSET + 1 )
2012-06-01 15:21:13 +04:00
return - EINVAL ;
2012-12-10 17:42:48 +04:00
mode = resp - > data [ 0 ] ;
cmd = & resp - > data [ 1 ] ;
2012-05-31 01:54:55 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " Target mode 0x%x len %d \n " ,
2013-04-05 23:27:37 +04:00
mode , resp - > len ) ;
2012-05-31 01:54:55 +04:00
2012-12-10 17:42:48 +04:00
if ( ( mode & PN533_INIT_TARGET_RESP_FRAME_MASK ) = =
PN533_INIT_TARGET_RESP_ACTIVE )
2012-06-01 15:21:13 +04:00
comm_mode = NFC_COMM_ACTIVE ;
2012-12-10 17:42:48 +04:00
if ( ( mode & PN533_INIT_TARGET_RESP_DEP ) = = 0 ) /* Only DEP supported */
2012-06-01 15:21:13 +04:00
return - EOPNOTSUPP ;
2012-12-10 17:42:48 +04:00
gb = cmd + ATR_REQ_GB_OFFSET ;
gb_len = resp - > len - ( ATR_REQ_GB_OFFSET + 1 ) ;
2012-06-01 15:21:13 +04:00
2012-05-31 02:07:51 +04:00
rc = nfc_tm_activated ( dev - > nfc_dev , NFC_PROTO_NFC_DEP_MASK ,
comm_mode , gb , gb_len ) ;
if ( rc < 0 ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Error when signaling target activation \n " ) ;
2012-05-31 02:07:51 +04:00
return rc ;
}
2012-05-31 22:01:32 +04:00
dev - > tgt_mode = 1 ;
2012-05-31 02:07:51 +04:00
queue_work ( dev - > wq , & dev - > tg_work ) ;
return 0 ;
2012-05-15 17:57:06 +04:00
}
2012-05-30 19:20:25 +04:00
static void pn533_listen_mode_timer ( unsigned long data )
2012-05-31 01:54:55 +04:00
{
2012-12-10 17:42:50 +04:00
struct pn533 * dev = ( struct pn533 * ) data ;
2012-05-30 19:20:25 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " Listen mode timeout \n " ) ;
2012-05-30 19:20:25 +04:00
dev - > cancel_listen = 1 ;
pn533_poll_next_mod ( dev ) ;
2013-07-03 16:50:36 +04:00
queue_delayed_work ( dev - > wq , & dev - > poll_work ,
msecs_to_jiffies ( PN533_POLL_INTERVAL ) ) ;
2012-05-30 19:20:25 +04:00
}
2013-06-26 20:16:21 +04:00
static int pn533_rf_complete ( struct pn533 * dev , void * arg ,
struct sk_buff * resp )
{
int rc = 0 ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2013-06-26 20:16:21 +04:00
if ( IS_ERR ( resp ) ) {
rc = PTR_ERR ( resp ) ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " RF setting error %d \n " , rc ) ;
2013-06-26 20:16:21 +04:00
return rc ;
}
2013-07-03 16:50:36 +04:00
queue_delayed_work ( dev - > wq , & dev - > poll_work ,
msecs_to_jiffies ( PN533_POLL_INTERVAL ) ) ;
2013-06-26 20:16:21 +04:00
dev_kfree_skb ( resp ) ;
return rc ;
}
static void pn533_wq_rf ( struct work_struct * work )
{
struct pn533 * dev = container_of ( work , struct pn533 , rf_work ) ;
struct sk_buff * skb ;
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2013-06-26 20:16:21 +04:00
skb = pn533_alloc_skb ( dev , 2 ) ;
if ( ! skb )
return ;
* skb_put ( skb , 1 ) = PN533_CFGITEM_RF_FIELD ;
2013-07-01 19:26:58 +04:00
* skb_put ( skb , 1 ) = PN533_CFGITEM_RF_FIELD_AUTO_RFCA ;
2013-06-26 20:16:21 +04:00
rc = pn533_send_cmd_async ( dev , PN533_CMD_RF_CONFIGURATION , skb ,
pn533_rf_complete , NULL ) ;
if ( rc < 0 ) {
dev_kfree_skb ( skb ) ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " RF setting error %d \n " , rc ) ;
2013-06-26 20:16:21 +04:00
}
}
2013-08-21 17:06:55 +04:00
static int pn533_poll_dep_complete ( struct pn533 * dev , void * arg ,
struct sk_buff * resp )
{
struct pn533_cmd_jump_dep_response * rsp ;
struct nfc_target nfc_target ;
u8 target_gt_len ;
int rc ;
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
rsp = ( struct pn533_cmd_jump_dep_response * ) resp - > data ;
rc = rsp - > status & PN533_CMD_RET_MASK ;
if ( rc ! = PN533_CMD_RET_SUCCESS ) {
/* Not target found, turn radio off */
queue_work ( dev - > wq , & dev - > rf_work ) ;
dev_kfree_skb ( resp ) ;
return 0 ;
}
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " Creating new target " ) ;
2013-08-21 17:06:55 +04:00
nfc_target . supported_protocols = NFC_PROTO_NFC_DEP_MASK ;
nfc_target . nfcid1_len = 10 ;
memcpy ( nfc_target . nfcid1 , rsp - > nfcid3t , nfc_target . nfcid1_len ) ;
rc = nfc_targets_found ( dev - > nfc_dev , & nfc_target , 1 ) ;
if ( rc )
goto error ;
dev - > tgt_available_prots = 0 ;
dev - > tgt_active_prot = NFC_PROTO_NFC_DEP ;
/* ATR_RES general bytes are located at offset 17 */
target_gt_len = resp - > len - 17 ;
rc = nfc_set_remote_general_bytes ( dev - > nfc_dev ,
rsp - > gt , target_gt_len ) ;
if ( ! rc ) {
rc = nfc_dep_link_is_up ( dev - > nfc_dev ,
dev - > nfc_dev - > targets [ 0 ] . idx ,
0 , NFC_RF_INITIATOR ) ;
if ( ! rc )
pn533_poll_reset_mod_list ( dev ) ;
}
error :
dev_kfree_skb ( resp ) ;
return rc ;
}
# define PASSIVE_DATA_LEN 5
static int pn533_poll_dep ( struct nfc_dev * nfc_dev )
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
struct sk_buff * skb ;
int rc , skb_len ;
u8 * next , nfcid3 [ NFC_NFCID3_MAXSIZE ] ;
u8 passive_data [ PASSIVE_DATA_LEN ] = { 0x00 , 0xff , 0xff , 0x00 , 0x3 } ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s " , __func__ ) ;
2013-08-21 17:06:55 +04:00
if ( ! dev - > gb ) {
dev - > gb = nfc_get_local_general_bytes ( nfc_dev , & dev - > gb_len ) ;
if ( ! dev - > gb | | ! dev - > gb_len ) {
dev - > poll_dep = 0 ;
queue_work ( dev - > wq , & dev - > rf_work ) ;
}
}
skb_len = 3 + dev - > gb_len ; /* ActPass + BR + Next */
skb_len + = PASSIVE_DATA_LEN ;
/* NFCID3 */
skb_len + = NFC_NFCID3_MAXSIZE ;
nfcid3 [ 0 ] = 0x1 ;
nfcid3 [ 1 ] = 0xfe ;
get_random_bytes ( nfcid3 + 2 , 6 ) ;
skb = pn533_alloc_skb ( dev , skb_len ) ;
if ( ! skb )
return - ENOMEM ;
* skb_put ( skb , 1 ) = 0x01 ; /* Active */
* skb_put ( skb , 1 ) = 0x02 ; /* 424 kbps */
next = skb_put ( skb , 1 ) ; /* Next */
* next = 0 ;
/* Copy passive data */
memcpy ( skb_put ( skb , PASSIVE_DATA_LEN ) , passive_data , PASSIVE_DATA_LEN ) ;
* next | = 1 ;
/* Copy NFCID3 (which is NFCID2 from SENSF_RES) */
memcpy ( skb_put ( skb , NFC_NFCID3_MAXSIZE ) , nfcid3 ,
NFC_NFCID3_MAXSIZE ) ;
* next | = 2 ;
memcpy ( skb_put ( skb , dev - > gb_len ) , dev - > gb , dev - > gb_len ) ;
* next | = 4 ; /* We have some Gi */
rc = pn533_send_cmd_async ( dev , PN533_CMD_IN_JUMP_FOR_DEP , skb ,
pn533_poll_dep_complete , NULL ) ;
if ( rc < 0 )
dev_kfree_skb ( skb ) ;
return rc ;
}
2012-05-30 19:20:25 +04:00
static int pn533_poll_complete ( struct pn533 * dev , void * arg ,
2012-12-10 17:42:48 +04:00
struct sk_buff * resp )
2012-05-30 19:20:25 +04:00
{
struct pn533_poll_modulations * cur_mod ;
2012-05-31 01:54:55 +04:00
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-05-31 01:54:55 +04:00
2012-12-10 17:42:48 +04:00
if ( IS_ERR ( resp ) ) {
rc = PTR_ERR ( resp ) ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " %s Poll complete error %d \n " ,
2013-04-05 23:27:38 +04:00
__func__ , rc ) ;
2012-12-10 17:42:48 +04:00
if ( rc = = - ENOENT ) {
if ( dev - > poll_mod_count ! = 0 )
return rc ;
2016-03-25 17:46:53 +03:00
goto stop_poll ;
2012-12-10 17:42:48 +04:00
} else if ( rc < 0 ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Error %d when running poll \n " , rc ) ;
2012-12-10 17:42:48 +04:00
goto stop_poll ;
}
2012-05-30 19:20:25 +04:00
}
2012-05-31 01:54:55 +04:00
2012-05-30 19:20:25 +04:00
cur_mod = dev - > poll_mod_active [ dev - > poll_mod_curr ] ;
2012-12-10 17:42:48 +04:00
if ( cur_mod - > len = = 0 ) { /* Target mode */
2012-05-30 19:20:25 +04:00
del_timer ( & dev - > listen_timer ) ;
2012-12-10 17:42:48 +04:00
rc = pn533_init_target_complete ( dev , resp ) ;
goto done ;
2012-05-30 19:20:25 +04:00
}
2012-12-10 17:42:48 +04:00
/* Initiator mode */
rc = pn533_start_poll_complete ( dev , resp ) ;
if ( ! rc )
goto done ;
2012-05-30 19:20:25 +04:00
2013-04-03 10:02:00 +04:00
if ( ! dev - > poll_mod_count ) {
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " Polling has been stopped \n " ) ;
2013-04-03 10:02:00 +04:00
goto done ;
}
2012-12-10 17:42:48 +04:00
pn533_poll_next_mod ( dev ) ;
2013-06-26 20:16:21 +04:00
/* Not target found, turn radio off */
queue_work ( dev - > wq , & dev - > rf_work ) ;
2012-05-30 19:20:25 +04:00
2012-12-10 17:42:48 +04:00
done :
dev_kfree_skb ( resp ) ;
return rc ;
2012-05-30 19:20:25 +04:00
stop_poll :
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Polling operation has been stopped \n " ) ;
2012-12-10 17:42:48 +04:00
2012-05-30 19:20:25 +04:00
pn533_poll_reset_mod_list ( dev ) ;
dev - > poll_protocols = 0 ;
2012-12-10 17:42:48 +04:00
return rc ;
2012-05-31 01:54:55 +04:00
}
2012-12-10 17:43:01 +04:00
static struct sk_buff * pn533_alloc_poll_in_frame ( struct pn533 * dev ,
struct pn533_poll_modulations * mod )
2011-07-02 02:31:37 +04:00
{
2012-12-10 17:42:48 +04:00
struct sk_buff * skb ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , mod - > len ) ;
2012-12-10 17:42:48 +04:00
if ( ! skb )
return NULL ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:42:48 +04:00
memcpy ( skb_put ( skb , mod - > len ) , & mod - > data , mod - > len ) ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:42:48 +04:00
return skb ;
2012-05-30 19:20:25 +04:00
}
2011-07-02 02:31:37 +04:00
2012-05-30 19:20:25 +04:00
static int pn533_send_poll_frame ( struct pn533 * dev )
{
2012-12-10 17:42:48 +04:00
struct pn533_poll_modulations * mod ;
struct sk_buff * skb ;
2012-05-30 19:20:25 +04:00
int rc ;
2012-12-10 17:42:48 +04:00
u8 cmd_code ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:42:48 +04:00
mod = dev - > poll_mod_active [ dev - > poll_mod_curr ] ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s mod len %d \n " ,
2013-04-05 23:27:37 +04:00
__func__ , mod - > len ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:51 +03:00
if ( ( dev - > poll_protocols & NFC_PROTO_NFC_DEP_MASK ) & & dev - > poll_dep ) {
2013-08-21 17:06:55 +04:00
dev - > poll_dep = 0 ;
return pn533_poll_dep ( dev - > nfc_dev ) ;
}
2012-12-10 17:42:48 +04:00
if ( mod - > len = = 0 ) { /* Listen mode */
cmd_code = PN533_CMD_TG_INIT_AS_TARGET ;
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_poll_tg_frame ( dev ) ;
2012-12-10 17:42:48 +04:00
} else { /* Polling mode */
cmd_code = PN533_CMD_IN_LIST_PASSIVE_TARGET ;
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_poll_in_frame ( dev , mod ) ;
2012-12-10 17:42:48 +04:00
}
if ( ! skb ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Failed to allocate skb \n " ) ;
2012-12-10 17:42:48 +04:00
return - ENOMEM ;
}
rc = pn533_send_cmd_async ( dev , cmd_code , skb , pn533_poll_complete ,
NULL ) ;
if ( rc < 0 ) {
dev_kfree_skb ( skb ) ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Polling loop error %d \n " , rc ) ;
2012-12-10 17:42:48 +04:00
}
2011-07-02 02:31:37 +04:00
2012-05-30 19:20:25 +04:00
return rc ;
}
static void pn533_wq_poll ( struct work_struct * work )
{
2013-07-03 16:50:36 +04:00
struct pn533 * dev = container_of ( work , struct pn533 , poll_work . work ) ;
2012-05-30 19:20:25 +04:00
struct pn533_poll_modulations * cur_mod ;
int rc ;
cur_mod = dev - > poll_mod_active [ dev - > poll_mod_curr ] ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev ,
2013-04-05 23:27:37 +04:00
" %s cancel_listen %d modulation len %d \n " ,
__func__ , dev - > cancel_listen , cur_mod - > len ) ;
2012-05-30 19:20:25 +04:00
if ( dev - > cancel_listen = = 1 ) {
dev - > cancel_listen = 0 ;
2016-03-25 17:46:53 +03:00
dev - > phy_ops - > abort_cmd ( dev , GFP_ATOMIC ) ;
2011-07-02 02:31:37 +04:00
}
2012-05-30 19:20:25 +04:00
rc = pn533_send_poll_frame ( dev ) ;
if ( rc )
return ;
2011-07-02 02:31:37 +04:00
2012-05-30 19:20:25 +04:00
if ( cur_mod - > len = = 0 & & dev - > poll_mod_count > 1 )
mod_timer ( & dev - > listen_timer , jiffies + PN533_LISTEN_TIME * HZ ) ;
2011-07-02 02:31:37 +04:00
}
2012-05-15 17:57:06 +04:00
static int pn533_start_poll ( struct nfc_dev * nfc_dev ,
u32 im_protocols , u32 tm_protocols )
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
2013-08-21 17:12:06 +04:00
struct pn533_poll_modulations * cur_mod ;
2013-07-03 17:14:17 +04:00
u8 rand_mod ;
2013-08-21 17:12:06 +04:00
int rc ;
2012-05-15 17:57:06 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev ,
2013-04-05 23:27:37 +04:00
" %s: im protocols 0x%x tm protocols 0x%x \n " ,
__func__ , im_protocols , tm_protocols ) ;
2012-05-15 17:57:06 +04:00
if ( dev - > tgt_active_prot ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Cannot poll with a target already activated \n " ) ;
2012-05-15 17:57:06 +04:00
return - EBUSY ;
}
2012-05-31 22:01:32 +04:00
if ( dev - > tgt_mode ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Cannot poll while already being activated \n " ) ;
2012-05-31 22:01:32 +04:00
return - EBUSY ;
}
2012-05-30 19:20:25 +04:00
if ( tm_protocols ) {
dev - > gb = nfc_get_local_general_bytes ( nfc_dev , & dev - > gb_len ) ;
if ( dev - > gb = = NULL )
tm_protocols = 0 ;
}
2012-05-31 01:54:55 +04:00
2012-05-30 19:20:25 +04:00
pn533_poll_create_mod_list ( dev , im_protocols , tm_protocols ) ;
dev - > poll_protocols = im_protocols ;
dev - > listen_protocols = tm_protocols ;
2012-05-31 01:54:55 +04:00
2013-07-03 17:14:17 +04:00
/* Do not always start polling from the same modulation */
get_random_bytes ( & rand_mod , sizeof ( rand_mod ) ) ;
rand_mod % = dev - > poll_mod_count ;
dev - > poll_mod_curr = rand_mod ;
2013-08-21 17:12:06 +04:00
cur_mod = dev - > poll_mod_active [ dev - > poll_mod_curr ] ;
rc = pn533_send_poll_frame ( dev ) ;
/* Start listen timer */
if ( ! rc & & cur_mod - > len = = 0 & & dev - > poll_mod_count > 1 )
mod_timer ( & dev - > listen_timer , jiffies + PN533_LISTEN_TIME * HZ ) ;
return rc ;
2012-05-15 17:57:06 +04:00
}
2011-07-02 02:31:37 +04:00
static void pn533_stop_poll ( struct nfc_dev * nfc_dev )
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
2012-05-30 19:20:25 +04:00
del_timer ( & dev - > listen_timer ) ;
2011-07-02 02:31:37 +04:00
if ( ! dev - > poll_mod_count ) {
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev ,
2013-04-05 23:27:37 +04:00
" Polling operation was not running \n " ) ;
2011-07-02 02:31:37 +04:00
return ;
}
2016-03-25 17:46:53 +03:00
dev - > phy_ops - > abort_cmd ( dev , GFP_KERNEL ) ;
2013-07-03 16:50:36 +04:00
flush_delayed_work ( & dev - > poll_work ) ;
2012-05-21 18:20:01 +04:00
pn533_poll_reset_mod_list ( dev ) ;
2011-07-02 02:31:37 +04:00
}
static int pn533_activate_target_nfcdep ( struct pn533 * dev )
{
2012-11-26 17:18:38 +04:00
struct pn533_cmd_activate_response * rsp ;
2011-12-14 19:43:10 +04:00
u16 gt_len ;
2011-07-02 02:31:37 +04:00
int rc ;
2012-11-26 17:18:38 +04:00
struct sk_buff * skb ;
struct sk_buff * resp ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , sizeof ( u8 ) * 2 ) ; /*TG + Next*/
2012-11-26 17:18:38 +04:00
if ( ! skb )
return - ENOMEM ;
2011-07-02 02:31:37 +04:00
2012-11-26 17:18:38 +04:00
* skb_put ( skb , sizeof ( u8 ) ) = 1 ; /* TG */
* skb_put ( skb , sizeof ( u8 ) ) = 0 ; /* Next */
2011-07-02 02:31:37 +04:00
2012-11-26 17:18:38 +04:00
resp = pn533_send_cmd_sync ( dev , PN533_CMD_IN_ATR , skb ) ;
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:42:50 +04:00
rsp = ( struct pn533_cmd_activate_response * ) resp - > data ;
2012-11-26 17:18:38 +04:00
rc = rsp - > status & PN533_CMD_RET_MASK ;
2012-12-21 13:39:01 +04:00
if ( rc ! = PN533_CMD_RET_SUCCESS ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Target activation failed (error 0x%x) \n " , rc ) ;
2012-11-26 17:18:38 +04:00
dev_kfree_skb ( resp ) ;
2011-07-02 02:31:37 +04:00
return - EIO ;
2012-12-21 13:39:01 +04:00
}
2011-07-02 02:31:37 +04:00
2011-12-14 19:43:10 +04:00
/* ATR_RES general bytes are located at offset 16 */
2012-11-26 17:18:38 +04:00
gt_len = resp - > len - 16 ;
rc = nfc_set_remote_general_bytes ( dev - > nfc_dev , rsp - > gt , gt_len ) ;
2011-12-14 19:43:10 +04:00
2012-11-26 17:18:38 +04:00
dev_kfree_skb ( resp ) ;
2011-12-14 19:43:10 +04:00
return rc ;
2011-07-02 02:31:37 +04:00
}
2012-05-07 14:31:13 +04:00
static int pn533_activate_target ( struct nfc_dev * nfc_dev ,
struct nfc_target * target , u32 protocol )
2011-07-02 02:31:37 +04:00
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s: protocol=%u \n " , __func__ , protocol ) ;
2011-07-02 02:31:37 +04:00
if ( dev - > poll_mod_count ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:37 +04:00
" Cannot activate while polling \n " ) ;
2011-07-02 02:31:37 +04:00
return - EBUSY ;
}
if ( dev - > tgt_active_prot ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" There is already an active target \n " ) ;
2011-07-02 02:31:37 +04:00
return - EBUSY ;
}
if ( ! dev - > tgt_available_prots ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" There is no available target to activate \n " ) ;
2011-07-02 02:31:37 +04:00
return - EINVAL ;
}
if ( ! ( dev - > tgt_available_prots & ( 1 < < protocol ) ) ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Target doesn't support requested proto %u \n " ,
protocol ) ;
2011-07-02 02:31:37 +04:00
return - EINVAL ;
}
if ( protocol = = NFC_PROTO_NFC_DEP ) {
rc = pn533_activate_target_nfcdep ( dev ) ;
if ( rc ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Activating target with DEP failed %d \n " , rc ) ;
2011-07-02 02:31:37 +04:00
return rc ;
}
}
dev - > tgt_active_prot = protocol ;
dev - > tgt_available_prots = 0 ;
return 0 ;
}
2016-03-25 17:46:52 +03:00
static int pn533_deactivate_target_complete ( struct pn533 * dev , void * arg ,
struct sk_buff * resp )
{
int rc = 0 ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2016-03-25 17:46:52 +03:00
if ( IS_ERR ( resp ) ) {
rc = PTR_ERR ( resp ) ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Target release error %d \n " , rc ) ;
2016-03-25 17:46:52 +03:00
return rc ;
}
rc = resp - > data [ 0 ] & PN533_CMD_RET_MASK ;
if ( rc ! = PN533_CMD_RET_SUCCESS )
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2016-03-25 17:46:52 +03:00
" Error 0x%x when releasing the target \n " , rc ) ;
dev_kfree_skb ( resp ) ;
return rc ;
}
2012-05-07 14:31:13 +04:00
static void pn533_deactivate_target ( struct nfc_dev * nfc_dev ,
2015-10-26 00:54:43 +03:00
struct nfc_target * target , u8 mode )
2011-07-02 02:31:37 +04:00
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
2012-11-26 17:18:38 +04:00
struct sk_buff * skb ;
2011-07-02 02:31:37 +04:00
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2011-07-02 02:31:37 +04:00
if ( ! dev - > tgt_active_prot ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " There is no active target \n " ) ;
2011-07-02 02:31:37 +04:00
return ;
}
dev - > tgt_active_prot = 0 ;
2012-04-10 21:43:18 +04:00
skb_queue_purge ( & dev - > resp_q ) ;
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , sizeof ( u8 ) ) ;
2012-11-26 17:18:38 +04:00
if ( ! skb )
return ;
2011-07-02 02:31:37 +04:00
2012-11-26 17:18:38 +04:00
* skb_put ( skb , 1 ) = 1 ; /* TG*/
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:52 +03:00
rc = pn533_send_cmd_async ( dev , PN533_CMD_IN_RELEASE , skb ,
pn533_deactivate_target_complete , NULL ) ;
if ( rc < 0 ) {
dev_kfree_skb ( skb ) ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Target release error %d \n " , rc ) ;
2016-03-25 17:46:52 +03:00
}
2011-07-02 02:31:37 +04:00
}
2011-12-14 19:43:11 +04:00
static int pn533_in_dep_link_up_complete ( struct pn533 * dev , void * arg ,
2012-12-10 17:42:45 +04:00
struct sk_buff * resp )
2011-12-14 19:43:11 +04:00
{
2012-12-10 17:42:45 +04:00
struct pn533_cmd_jump_dep_response * rsp ;
2011-12-14 19:43:11 +04:00
u8 target_gt_len ;
int rc ;
2012-12-10 17:42:45 +04:00
u8 active = * ( u8 * ) arg ;
2012-10-11 16:04:00 +04:00
kfree ( arg ) ;
2011-12-14 19:43:11 +04:00
2012-12-10 17:42:45 +04:00
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
2011-12-14 19:43:11 +04:00
if ( dev - > tgt_available_prots & &
! ( dev - > tgt_available_prots & ( 1 < < NFC_PROTO_NFC_DEP ) ) ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" The target does not support DEP \n " ) ;
2012-12-10 17:42:45 +04:00
rc = - EINVAL ;
goto error ;
2011-12-14 19:43:11 +04:00
}
2012-12-10 17:42:45 +04:00
rsp = ( struct pn533_cmd_jump_dep_response * ) resp - > data ;
rc = rsp - > status & PN533_CMD_RET_MASK ;
2011-12-14 19:43:11 +04:00
if ( rc ! = PN533_CMD_RET_SUCCESS ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Bringing DEP link up failed (error 0x%x) \n " , rc ) ;
2012-12-10 17:42:45 +04:00
goto error ;
2011-12-14 19:43:11 +04:00
}
if ( ! dev - > tgt_available_prots ) {
2012-12-10 17:42:45 +04:00
struct nfc_target nfc_target ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " Creating new target \n " ) ;
2011-12-14 19:43:11 +04:00
nfc_target . supported_protocols = NFC_PROTO_NFC_DEP_MASK ;
2012-03-05 04:03:47 +04:00
nfc_target . nfcid1_len = 10 ;
2012-12-10 17:42:45 +04:00
memcpy ( nfc_target . nfcid1 , rsp - > nfcid3t , nfc_target . nfcid1_len ) ;
2011-12-14 19:43:11 +04:00
rc = nfc_targets_found ( dev - > nfc_dev , & nfc_target , 1 ) ;
if ( rc )
2012-12-10 17:42:45 +04:00
goto error ;
2011-12-14 19:43:11 +04:00
dev - > tgt_available_prots = 0 ;
}
dev - > tgt_active_prot = NFC_PROTO_NFC_DEP ;
/* ATR_RES general bytes are located at offset 17 */
2012-12-10 17:42:45 +04:00
target_gt_len = resp - > len - 17 ;
2011-12-14 19:43:11 +04:00
rc = nfc_set_remote_general_bytes ( dev - > nfc_dev ,
2012-12-10 17:42:45 +04:00
rsp - > gt , target_gt_len ) ;
2011-12-14 19:43:11 +04:00
if ( rc = = 0 )
rc = nfc_dep_link_is_up ( dev - > nfc_dev ,
2012-12-10 17:42:45 +04:00
dev - > nfc_dev - > targets [ 0 ] . idx ,
! active , NFC_RF_INITIATOR ) ;
2011-12-14 19:43:11 +04:00
2012-12-10 17:42:45 +04:00
error :
dev_kfree_skb ( resp ) ;
return rc ;
2011-12-14 19:43:11 +04:00
}
2013-06-26 20:16:21 +04:00
static int pn533_rf_field ( struct nfc_dev * nfc_dev , u8 rf ) ;
2012-05-07 14:31:13 +04:00
static int pn533_dep_link_up ( struct nfc_dev * nfc_dev , struct nfc_target * target ,
2012-12-10 17:42:50 +04:00
u8 comm_mode , u8 * gb , size_t gb_len )
2011-12-14 19:43:11 +04:00
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
2012-12-10 17:42:45 +04:00
struct sk_buff * skb ;
2013-07-01 12:58:12 +04:00
int rc , skb_len ;
u8 * next , * arg , nfcid3 [ NFC_NFCID3_MAXSIZE ] ;
2012-05-29 23:45:21 +04:00
u8 passive_data [ PASSIVE_DATA_LEN ] = { 0x00 , 0xff , 0xff , 0x00 , 0x3 } ;
2011-12-14 19:43:11 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2011-12-14 19:43:11 +04:00
if ( dev - > poll_mod_count ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Cannot bring the DEP link up while polling \n " ) ;
2011-12-14 19:43:11 +04:00
return - EBUSY ;
}
if ( dev - > tgt_active_prot ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" There is already an active target \n " ) ;
2011-12-14 19:43:11 +04:00
return - EBUSY ;
}
2012-12-10 17:42:45 +04:00
skb_len = 3 + gb_len ; /* ActPass + BR + Next */
2013-07-01 12:58:12 +04:00
skb_len + = PASSIVE_DATA_LEN ;
2012-05-29 23:45:21 +04:00
2013-07-01 12:58:12 +04:00
/* NFCID3 */
skb_len + = NFC_NFCID3_MAXSIZE ;
if ( target & & ! target - > nfcid2_len ) {
nfcid3 [ 0 ] = 0x1 ;
nfcid3 [ 1 ] = 0xfe ;
get_random_bytes ( nfcid3 + 2 , 6 ) ;
}
2013-05-27 17:29:11 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , skb_len ) ;
2012-12-10 17:42:45 +04:00
if ( ! skb )
2011-12-14 19:43:11 +04:00
return - ENOMEM ;
2012-12-10 17:42:45 +04:00
* skb_put ( skb , 1 ) = ! comm_mode ; /* ActPass */
2013-07-01 12:58:12 +04:00
* skb_put ( skb , 1 ) = 0x02 ; /* 424 kbps */
2012-12-10 17:42:45 +04:00
next = skb_put ( skb , 1 ) ; /* Next */
* next = 0 ;
2011-12-14 19:43:11 +04:00
2013-07-01 12:58:12 +04:00
/* Copy passive data */
memcpy ( skb_put ( skb , PASSIVE_DATA_LEN ) , passive_data , PASSIVE_DATA_LEN ) ;
* next | = 1 ;
2012-05-29 23:45:21 +04:00
2013-07-01 12:58:12 +04:00
/* Copy NFCID3 (which is NFCID2 from SENSF_RES) */
if ( target & & target - > nfcid2_len )
2013-05-27 17:29:11 +04:00
memcpy ( skb_put ( skb , NFC_NFCID3_MAXSIZE ) , target - > nfcid2 ,
target - > nfcid2_len ) ;
2013-07-01 12:58:12 +04:00
else
memcpy ( skb_put ( skb , NFC_NFCID3_MAXSIZE ) , nfcid3 ,
NFC_NFCID3_MAXSIZE ) ;
* next | = 2 ;
2013-05-27 17:29:11 +04:00
2012-03-05 04:03:50 +04:00
if ( gb ! = NULL & & gb_len > 0 ) {
2012-12-10 17:42:45 +04:00
memcpy ( skb_put ( skb , gb_len ) , gb , gb_len ) ;
* next | = 4 ; /* We have some Gi */
2011-12-14 19:43:11 +04:00
} else {
2012-12-10 17:42:45 +04:00
* next = 0 ;
2011-12-14 19:43:11 +04:00
}
2012-12-10 17:42:45 +04:00
arg = kmalloc ( sizeof ( * arg ) , GFP_KERNEL ) ;
if ( ! arg ) {
dev_kfree_skb ( skb ) ;
return - ENOMEM ;
}
2011-12-14 19:43:11 +04:00
2012-12-10 17:42:45 +04:00
* arg = ! comm_mode ;
2011-12-14 19:43:11 +04:00
2013-06-26 20:16:21 +04:00
pn533_rf_field ( dev - > nfc_dev , 0 ) ;
2012-12-10 17:42:45 +04:00
rc = pn533_send_cmd_async ( dev , PN533_CMD_IN_JUMP_FOR_DEP , skb ,
pn533_in_dep_link_up_complete , arg ) ;
if ( rc < 0 ) {
dev_kfree_skb ( skb ) ;
kfree ( arg ) ;
}
2011-12-14 19:43:11 +04:00
return rc ;
}
static int pn533_dep_link_down ( struct nfc_dev * nfc_dev )
{
2012-05-30 19:20:25 +04:00
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-12-10 17:42:55 +04:00
2012-05-30 19:20:25 +04:00
pn533_poll_reset_mod_list ( dev ) ;
2013-04-03 10:02:14 +04:00
if ( dev - > tgt_mode | | dev - > tgt_active_prot )
2016-03-25 17:46:53 +03:00
dev - > phy_ops - > abort_cmd ( dev , GFP_KERNEL ) ;
2012-05-31 22:01:32 +04:00
dev - > tgt_active_prot = 0 ;
dev - > tgt_mode = 0 ;
skb_queue_purge ( & dev - > resp_q ) ;
2011-12-14 19:43:11 +04:00
return 0 ;
}
2011-07-02 02:31:37 +04:00
struct pn533_data_exchange_arg {
data_exchange_cb_t cb ;
void * cb_context ;
} ;
2012-04-10 21:43:18 +04:00
static struct sk_buff * pn533_build_response ( struct pn533 * dev )
{
struct sk_buff * skb , * tmp , * t ;
unsigned int skb_len = 0 , tmp_len = 0 ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-04-10 21:43:18 +04:00
if ( skb_queue_empty ( & dev - > resp_q ) )
return NULL ;
if ( skb_queue_len ( & dev - > resp_q ) = = 1 ) {
skb = skb_dequeue ( & dev - > resp_q ) ;
goto out ;
}
skb_queue_walk_safe ( & dev - > resp_q , tmp , t )
skb_len + = tmp - > len ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s total length %d \n " ,
2013-04-05 23:27:37 +04:00
__func__ , skb_len ) ;
2012-04-10 21:43:18 +04:00
skb = alloc_skb ( skb_len , GFP_KERNEL ) ;
if ( skb = = NULL )
goto out ;
skb_put ( skb , skb_len ) ;
skb_queue_walk_safe ( & dev - > resp_q , tmp , t ) {
memcpy ( skb - > data + tmp_len , tmp - > data , tmp - > len ) ;
tmp_len + = tmp - > len ;
}
out :
skb_queue_purge ( & dev - > resp_q ) ;
return skb ;
}
2011-07-02 02:31:37 +04:00
static int pn533_data_exchange_complete ( struct pn533 * dev , void * _arg ,
2012-12-10 17:42:46 +04:00
struct sk_buff * resp )
2011-07-02 02:31:37 +04:00
{
struct pn533_data_exchange_arg * arg = _arg ;
2012-12-10 17:42:46 +04:00
struct sk_buff * skb ;
int rc = 0 ;
u8 status , ret , mi ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:42:46 +04:00
if ( IS_ERR ( resp ) ) {
rc = PTR_ERR ( resp ) ;
goto _error ;
2011-07-02 02:31:37 +04:00
}
2012-12-10 17:42:46 +04:00
status = resp - > data [ 0 ] ;
ret = status & PN533_CMD_RET_MASK ;
mi = status & PN533_CMD_MI_MASK ;
skb_pull ( resp , sizeof ( status ) ) ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:42:46 +04:00
if ( ret ! = PN533_CMD_RET_SUCCESS ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Exchanging data failed (error 0x%x) \n " , ret ) ;
2012-12-10 17:42:46 +04:00
rc = - EIO ;
2011-07-02 02:31:37 +04:00
goto error ;
}
2012-12-10 17:42:46 +04:00
skb_queue_tail ( & dev - > resp_q , resp ) ;
2012-04-10 21:43:18 +04:00
2012-12-10 17:42:46 +04:00
if ( mi ) {
dev - > cmd_complete_mi_arg = arg ;
2013-06-13 17:43:28 +04:00
queue_work ( dev - > wq , & dev - > mi_rx_work ) ;
return - EINPROGRESS ;
}
/* Prepare for the next round */
if ( skb_queue_len ( & dev - > fragment_skb ) > 0 ) {
dev - > cmd_complete_dep_arg = arg ;
queue_work ( dev - > wq , & dev - > mi_tx_work ) ;
2012-04-10 21:43:18 +04:00
return - EINPROGRESS ;
2011-07-02 02:31:37 +04:00
}
2012-04-10 21:43:18 +04:00
skb = pn533_build_response ( dev ) ;
2015-04-05 15:06:36 +03:00
if ( ! skb ) {
rc = - ENOMEM ;
2012-04-10 21:43:18 +04:00
goto error ;
2015-04-05 15:06:36 +03:00
}
2011-07-02 02:31:37 +04:00
2012-04-10 21:43:18 +04:00
arg - > cb ( arg - > cb_context , skb , 0 ) ;
2011-07-02 02:31:37 +04:00
kfree ( arg ) ;
return 0 ;
error :
2012-12-10 17:42:46 +04:00
dev_kfree_skb ( resp ) ;
_error :
2012-04-10 21:43:18 +04:00
skb_queue_purge ( & dev - > resp_q ) ;
2012-12-10 17:42:46 +04:00
arg - > cb ( arg - > cb_context , NULL , rc ) ;
2011-07-02 02:31:37 +04:00
kfree ( arg ) ;
2012-12-10 17:42:46 +04:00
return rc ;
2011-07-02 02:31:37 +04:00
}
2016-03-25 17:46:53 +03:00
/*
* Receive an incoming pn533 frame . skb contains only header and payload .
* If skb = = NULL , it is a notification that the link below is dead .
*/
void pn533_recv_frame ( struct pn533 * dev , struct sk_buff * skb , int status )
{
dev - > cmd - > status = status ;
if ( skb = = NULL ) {
pr_err ( " NULL Frame -> link is dead \n " ) ;
goto sched_wq ;
}
if ( pn533_rx_frame_is_ack ( skb - > data ) ) {
dev_dbg ( dev - > dev , " %s: Received ACK frame \n " , __func__ ) ;
dev_kfree_skb ( skb ) ;
return ;
}
print_hex_dump_debug ( " PN533 RX: " , DUMP_PREFIX_NONE , 16 , 1 , skb - > data ,
dev - > ops - > rx_frame_size ( skb - > data ) , false ) ;
if ( ! dev - > ops - > rx_is_frame_valid ( skb - > data , dev ) ) {
nfc_err ( dev - > dev , " Received an invalid frame \n " ) ;
dev - > cmd - > status = - EIO ;
} else if ( ! pn533_rx_frame_is_cmd_response ( dev , skb - > data ) ) {
nfc_err ( dev - > dev , " It it not the response to the last command \n " ) ;
dev - > cmd - > status = - EIO ;
}
dev - > cmd - > resp = skb ;
sched_wq :
queue_work ( dev - > wq , & dev - > cmd_complete_work ) ;
}
EXPORT_SYMBOL ( pn533_recv_frame ) ;
2013-06-13 17:43:28 +04:00
/* Split the Tx skb into small chunks */
static int pn533_fill_fragment_skbs ( struct pn533 * dev , struct sk_buff * skb )
{
struct sk_buff * frag ;
int frag_size ;
do {
/* Remaining size */
if ( skb - > len > PN533_CMD_DATAFRAME_MAXLEN )
frag_size = PN533_CMD_DATAFRAME_MAXLEN ;
else
frag_size = skb - > len ;
/* Allocate and reserve */
frag = pn533_alloc_skb ( dev , frag_size ) ;
if ( ! frag ) {
skb_queue_purge ( & dev - > fragment_skb ) ;
break ;
}
2013-09-23 14:24:37 +04:00
if ( ! dev - > tgt_mode ) {
/* Reserve the TG/MI byte */
skb_reserve ( frag , 1 ) ;
/* MI + TG */
if ( frag_size = = PN533_CMD_DATAFRAME_MAXLEN )
* skb_push ( frag , sizeof ( u8 ) ) =
( PN533_CMD_MI_MASK | 1 ) ;
else
* skb_push ( frag , sizeof ( u8 ) ) = 1 ; /* TG */
}
2013-06-13 17:43:28 +04:00
memcpy ( skb_put ( frag , frag_size ) , skb - > data , frag_size ) ;
/* Reduce the size of incoming buffer */
skb_pull ( skb , frag_size ) ;
/* Add this to skb_queue */
skb_queue_tail ( & dev - > fragment_skb , frag ) ;
} while ( skb - > len > 0 ) ;
dev_kfree_skb ( skb ) ;
return skb_queue_len ( & dev - > fragment_skb ) ;
}
2012-05-16 17:55:48 +04:00
static int pn533_transceive ( struct nfc_dev * nfc_dev ,
struct nfc_target * target , struct sk_buff * skb ,
data_exchange_cb_t cb , void * cb_context )
2011-07-02 02:31:37 +04:00
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
2012-12-10 17:42:46 +04:00
struct pn533_data_exchange_arg * arg = NULL ;
2011-07-02 02:31:37 +04:00
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2011-07-02 02:31:37 +04:00
if ( ! dev - > tgt_active_prot ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Can't exchange data if there is no active target \n " ) ;
2011-07-02 02:31:37 +04:00
rc = - EINVAL ;
goto error ;
}
2012-12-10 17:42:46 +04:00
arg = kmalloc ( sizeof ( * arg ) , GFP_KERNEL ) ;
2011-07-02 02:31:37 +04:00
if ( ! arg ) {
rc = - ENOMEM ;
2012-12-10 17:42:46 +04:00
goto error ;
2011-07-02 02:31:37 +04:00
}
arg - > cb = cb ;
arg - > cb_context = cb_context ;
2012-12-10 17:42:46 +04:00
switch ( dev - > device_type ) {
case PN533_DEVICE_PASORI :
if ( dev - > tgt_active_prot = = NFC_PROTO_FELICA ) {
rc = pn533_send_data_async ( dev , PN533_CMD_IN_COMM_THRU ,
skb ,
pn533_data_exchange_complete ,
arg ) ;
break ;
}
default :
2013-06-13 17:43:28 +04:00
/* jumbo frame ? */
if ( skb - > len > PN533_CMD_DATAEXCH_DATA_MAXLEN ) {
rc = pn533_fill_fragment_skbs ( dev , skb ) ;
if ( rc < = 0 )
goto error ;
skb = skb_dequeue ( & dev - > fragment_skb ) ;
if ( ! skb ) {
rc = - EIO ;
goto error ;
}
} else {
* skb_push ( skb , sizeof ( u8 ) ) = 1 ; /* TG */
}
2012-12-10 17:42:46 +04:00
rc = pn533_send_data_async ( dev , PN533_CMD_IN_DATA_EXCHANGE ,
skb , pn533_data_exchange_complete ,
arg ) ;
break ;
2011-07-02 02:31:37 +04:00
}
2012-12-10 17:42:46 +04:00
if ( rc < 0 ) /* rc from send_async */
goto error ;
2011-07-02 02:31:37 +04:00
return 0 ;
error :
2012-12-10 17:42:46 +04:00
kfree ( arg ) ;
dev_kfree_skb ( skb ) ;
2011-07-02 02:31:37 +04:00
return rc ;
}
2012-05-31 02:09:11 +04:00
static int pn533_tm_send_complete ( struct pn533 * dev , void * arg ,
2012-12-10 17:42:44 +04:00
struct sk_buff * resp )
2012-05-31 02:09:11 +04:00
{
2012-12-10 17:42:44 +04:00
u8 status ;
2012-11-15 21:24:28 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-05-31 02:09:11 +04:00
2012-12-10 17:42:44 +04:00
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
2012-11-15 21:24:28 +04:00
2012-12-10 17:42:44 +04:00
status = resp - > data [ 0 ] ;
2012-05-31 02:09:11 +04:00
2013-09-23 14:24:39 +04:00
/* Prepare for the next round */
if ( skb_queue_len ( & dev - > fragment_skb ) > 0 ) {
queue_work ( dev - > wq , & dev - > mi_tm_tx_work ) ;
return - EINPROGRESS ;
}
2012-12-10 17:42:44 +04:00
dev_kfree_skb ( resp ) ;
2012-05-31 02:09:11 +04:00
2012-12-10 17:42:44 +04:00
if ( status ! = 0 ) {
2012-05-31 02:09:11 +04:00
nfc_tm_deactivated ( dev - > nfc_dev ) ;
2012-05-31 22:01:32 +04:00
dev - > tgt_mode = 0 ;
2012-05-31 02:09:11 +04:00
return 0 ;
}
queue_work ( dev - > wq , & dev - > tg_work ) ;
return 0 ;
}
static int pn533_tm_send ( struct nfc_dev * nfc_dev , struct sk_buff * skb )
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-05-31 02:09:11 +04:00
2013-09-23 14:24:39 +04:00
/* let's split in multiple chunks if size's too big */
2012-12-10 17:42:44 +04:00
if ( skb - > len > PN533_CMD_DATAEXCH_DATA_MAXLEN ) {
2013-09-23 14:24:39 +04:00
rc = pn533_fill_fragment_skbs ( dev , skb ) ;
if ( rc < = 0 )
goto error ;
/* get the first skb */
skb = skb_dequeue ( & dev - > fragment_skb ) ;
if ( ! skb ) {
rc = - EIO ;
goto error ;
}
rc = pn533_send_data_async ( dev , PN533_CMD_TG_SET_META_DATA , skb ,
pn533_tm_send_complete , NULL ) ;
} else {
/* Send th skb */
rc = pn533_send_data_async ( dev , PN533_CMD_TG_SET_DATA , skb ,
pn533_tm_send_complete , NULL ) ;
2012-05-31 02:09:11 +04:00
}
2013-09-23 14:24:39 +04:00
error :
if ( rc < 0 ) {
2012-12-10 17:42:44 +04:00
dev_kfree_skb ( skb ) ;
2013-09-23 14:24:39 +04:00
skb_queue_purge ( & dev - > fragment_skb ) ;
}
2012-05-31 02:09:11 +04:00
return rc ;
}
2012-04-10 21:43:18 +04:00
static void pn533_wq_mi_recv ( struct work_struct * work )
{
2013-06-13 17:43:28 +04:00
struct pn533 * dev = container_of ( work , struct pn533 , mi_rx_work ) ;
2012-12-10 17:42:46 +04:00
struct sk_buff * skb ;
2012-04-10 21:43:18 +04:00
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-04-10 21:43:18 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , PN533_CMD_DATAEXCH_HEAD_LEN ) ;
2012-12-10 17:42:46 +04:00
if ( ! skb )
goto error ;
2012-04-10 21:43:18 +04:00
2012-12-10 17:42:46 +04:00
switch ( dev - > device_type ) {
case PN533_DEVICE_PASORI :
if ( dev - > tgt_active_prot = = NFC_PROTO_FELICA ) {
rc = pn533_send_cmd_direct_async ( dev ,
PN533_CMD_IN_COMM_THRU ,
skb ,
pn533_data_exchange_complete ,
dev - > cmd_complete_mi_arg ) ;
2012-04-10 21:43:18 +04:00
2012-12-10 17:42:46 +04:00
break ;
}
default :
* skb_put ( skb , sizeof ( u8 ) ) = 1 ; /*TG*/
2012-04-10 21:43:18 +04:00
2012-12-10 17:42:46 +04:00
rc = pn533_send_cmd_direct_async ( dev ,
PN533_CMD_IN_DATA_EXCHANGE ,
skb ,
pn533_data_exchange_complete ,
dev - > cmd_complete_mi_arg ) ;
2012-11-26 17:18:32 +04:00
2012-12-10 17:42:46 +04:00
break ;
2012-04-10 21:43:18 +04:00
}
2012-12-10 17:42:46 +04:00
if ( rc = = 0 ) /* success */
2012-04-10 21:43:18 +04:00
return ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Error %d when trying to perform data_exchange \n " , rc ) ;
2012-04-10 21:43:18 +04:00
2012-12-10 17:42:46 +04:00
dev_kfree_skb ( skb ) ;
2013-04-03 10:02:07 +04:00
kfree ( dev - > cmd_complete_mi_arg ) ;
2012-04-10 21:43:18 +04:00
2012-12-10 17:42:46 +04:00
error :
2016-03-25 17:46:53 +03:00
dev - > phy_ops - > send_ack ( dev , GFP_KERNEL ) ;
2012-08-18 01:47:54 +04:00
queue_work ( dev - > wq , & dev - > cmd_work ) ;
2012-04-10 21:43:18 +04:00
}
2013-06-13 17:43:28 +04:00
static void pn533_wq_mi_send ( struct work_struct * work )
{
struct pn533 * dev = container_of ( work , struct pn533 , mi_tx_work ) ;
struct sk_buff * skb ;
int rc ;
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2013-06-13 17:43:28 +04:00
/* Grab the first skb in the queue */
skb = skb_dequeue ( & dev - > fragment_skb ) ;
if ( skb = = NULL ) { /* No more data */
/* Reset the queue for future use */
skb_queue_head_init ( & dev - > fragment_skb ) ;
goto error ;
}
switch ( dev - > device_type ) {
case PN533_DEVICE_PASORI :
if ( dev - > tgt_active_prot ! = NFC_PROTO_FELICA ) {
rc = - EIO ;
break ;
}
rc = pn533_send_cmd_direct_async ( dev , PN533_CMD_IN_COMM_THRU ,
skb ,
pn533_data_exchange_complete ,
dev - > cmd_complete_dep_arg ) ;
break ;
default :
/* Still some fragments? */
2016-03-25 17:46:53 +03:00
rc = pn533_send_cmd_direct_async ( dev ,
PN533_CMD_IN_DATA_EXCHANGE ,
2013-06-13 17:43:28 +04:00
skb ,
pn533_data_exchange_complete ,
dev - > cmd_complete_dep_arg ) ;
break ;
}
if ( rc = = 0 ) /* success */
return ;
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Error %d when trying to perform data_exchange \n " , rc ) ;
2013-06-13 17:43:28 +04:00
dev_kfree_skb ( skb ) ;
kfree ( dev - > cmd_complete_dep_arg ) ;
error :
2016-03-25 17:46:53 +03:00
dev - > phy_ops - > send_ack ( dev , GFP_KERNEL ) ;
2013-06-13 17:43:28 +04:00
queue_work ( dev - > wq , & dev - > cmd_work ) ;
}
2011-07-02 02:31:37 +04:00
static int pn533_set_configuration ( struct pn533 * dev , u8 cfgitem , u8 * cfgdata ,
u8 cfgdata_len )
{
2012-11-26 17:18:38 +04:00
struct sk_buff * skb ;
struct sk_buff * resp ;
int skb_len ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2011-07-02 02:31:37 +04:00
2012-11-26 17:18:38 +04:00
skb_len = sizeof ( cfgitem ) + cfgdata_len ; /* cfgitem + cfgdata */
2011-07-02 02:31:37 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , skb_len ) ;
2012-11-26 17:18:38 +04:00
if ( ! skb )
return - ENOMEM ;
2011-07-02 02:31:37 +04:00
2012-11-26 17:18:38 +04:00
* skb_put ( skb , sizeof ( cfgitem ) ) = cfgitem ;
memcpy ( skb_put ( skb , cfgdata_len ) , cfgdata , cfgdata_len ) ;
2011-07-02 02:31:37 +04:00
2012-11-26 17:18:38 +04:00
resp = pn533_send_cmd_sync ( dev , PN533_CMD_RF_CONFIGURATION , skb ) ;
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
2011-07-02 02:31:37 +04:00
2012-11-26 17:18:38 +04:00
dev_kfree_skb ( resp ) ;
return 0 ;
}
static int pn533_get_firmware_version ( struct pn533 * dev ,
struct pn533_fw_version * fv )
{
struct sk_buff * skb ;
struct sk_buff * resp ;
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , 0 ) ;
2012-11-26 17:18:38 +04:00
if ( ! skb )
return - ENOMEM ;
resp = pn533_send_cmd_sync ( dev , PN533_CMD_GET_FIRMWARE_VERSION , skb ) ;
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
fv - > ic = resp - > data [ 0 ] ;
fv - > ver = resp - > data [ 1 ] ;
fv - > rev = resp - > data [ 2 ] ;
fv - > support = resp - > data [ 3 ] ;
dev_kfree_skb ( resp ) ;
return 0 ;
2011-07-02 02:31:37 +04:00
}
2013-04-03 10:02:02 +04:00
static int pn533_pasori_fw_reset ( struct pn533 * dev )
2012-07-02 22:04:01 +04:00
{
2012-11-26 17:18:38 +04:00
struct sk_buff * skb ;
struct sk_buff * resp ;
2012-07-02 22:04:01 +04:00
2016-03-25 17:46:53 +03:00
dev_dbg ( dev - > dev , " %s \n " , __func__ ) ;
2012-07-02 22:04:01 +04:00
2012-12-10 17:43:01 +04:00
skb = pn533_alloc_skb ( dev , sizeof ( u8 ) ) ;
2012-11-26 17:18:38 +04:00
if ( ! skb )
return - ENOMEM ;
2012-07-02 22:04:01 +04:00
2012-11-26 17:18:38 +04:00
* skb_put ( skb , sizeof ( u8 ) ) = 0x1 ;
2012-07-02 22:04:01 +04:00
2012-11-26 17:18:38 +04:00
resp = pn533_send_cmd_sync ( dev , 0x18 , skb ) ;
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
2012-07-02 22:04:01 +04:00
2012-11-26 17:18:38 +04:00
dev_kfree_skb ( resp ) ;
2012-07-02 22:04:01 +04:00
2012-11-26 17:18:36 +04:00
return 0 ;
2012-07-02 22:04:01 +04:00
}
2013-04-11 13:45:41 +04:00
static int pn533_rf_field ( struct nfc_dev * nfc_dev , u8 rf )
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
u8 rf_field = ! ! rf ;
int rc ;
2013-07-01 19:26:58 +04:00
rf_field | = PN533_CFGITEM_RF_FIELD_AUTO_RFCA ;
2013-04-11 13:45:41 +04:00
rc = pn533_set_configuration ( dev , PN533_CFGITEM_RF_FIELD ,
( u8 * ) & rf_field , 1 ) ;
if ( rc ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Error on setting RF field \n " ) ;
2013-04-11 13:45:41 +04:00
return rc ;
}
return rc ;
}
2016-03-25 17:46:54 +03:00
static int pn532_sam_configuration ( struct nfc_dev * nfc_dev )
{
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
struct sk_buff * skb ;
struct sk_buff * resp ;
skb = pn533_alloc_skb ( dev , 1 ) ;
if ( ! skb )
return - ENOMEM ;
* skb_put ( skb , 1 ) = 0x01 ;
resp = pn533_send_cmd_sync ( dev , PN533_CMD_SAM_CONFIGURATION , skb ) ;
if ( IS_ERR ( resp ) )
return PTR_ERR ( resp ) ;
dev_kfree_skb ( resp ) ;
return 0 ;
}
2013-09-20 13:00:41 +04:00
static int pn533_dev_up ( struct nfc_dev * nfc_dev )
2013-04-11 13:45:41 +04:00
{
2016-03-25 17:46:54 +03:00
struct pn533 * dev = nfc_get_drvdata ( nfc_dev ) ;
if ( dev - > device_type = = PN533_DEVICE_PN532 ) {
int rc = pn532_sam_configuration ( nfc_dev ) ;
if ( rc )
return rc ;
}
2013-04-11 13:45:41 +04:00
return pn533_rf_field ( nfc_dev , 1 ) ;
}
2013-09-20 13:00:41 +04:00
static int pn533_dev_down ( struct nfc_dev * nfc_dev )
2013-04-11 13:45:41 +04:00
{
return pn533_rf_field ( nfc_dev , 0 ) ;
}
2012-07-02 22:04:01 +04:00
static struct nfc_ops pn533_nfc_ops = {
2013-04-11 13:45:41 +04:00
. dev_up = pn533_dev_up ,
. dev_down = pn533_dev_down ,
2011-12-14 19:43:11 +04:00
. dep_link_up = pn533_dep_link_up ,
. dep_link_down = pn533_dep_link_down ,
2011-07-02 02:31:37 +04:00
. start_poll = pn533_start_poll ,
. stop_poll = pn533_stop_poll ,
. activate_target = pn533_activate_target ,
. deactivate_target = pn533_deactivate_target ,
2012-05-16 17:55:48 +04:00
. im_transceive = pn533_transceive ,
2012-05-31 02:09:11 +04:00
. tm_send = pn533_tm_send ,
2011-07-02 02:31:37 +04:00
} ;
2012-07-02 22:04:01 +04:00
static int pn533_setup ( struct pn533 * dev )
{
struct pn533_config_max_retries max_retries ;
struct pn533_config_timing timing ;
u8 pasori_cfg [ 3 ] = { 0x08 , 0x01 , 0x08 } ;
int rc ;
switch ( dev - > device_type ) {
case PN533_DEVICE_STD :
case PN533_DEVICE_PASORI :
NFC: pn533: Add support for ACS ACR122U reader
ACS ACR122U is an USB NFC reader, PC/SC and CCID compilant, based
on NXP PN532 chip.
Internally, it's build of MCU, PN532 and an antenna. MCU makes the
device CCID and PC/SC compilant and provide USB connection.
In this achitecture, a host cannot talk directly to PN532 and must
rely on MCU. Luckily, MCU exposes pseud-APDU through PC/SC Escape
mechanism which let the host to transmit standard PN532 commands
directly to PN532 chip with some limitations.
The frame roughly looks like:
CCID header | APDU header | PN532 header
(pc_to_rdr_escape) | (pseudo apdu Direct Tramsmit) | (len, TFI, cmd, params)
Accordign to limitations, ACR122U does't provide any mechanism to
abort last issued command.
Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2013-04-03 10:02:13 +04:00
case PN533_DEVICE_ACR122U :
2016-03-25 17:46:54 +03:00
case PN533_DEVICE_PN532 :
2012-07-02 22:04:01 +04:00
max_retries . mx_rty_atr = 0x2 ;
max_retries . mx_rty_psl = 0x1 ;
max_retries . mx_rty_passive_act =
PN533_CONFIG_MAX_RETRIES_NO_RETRY ;
timing . rfu = PN533_CONFIG_TIMING_102 ;
timing . atr_res_timeout = PN533_CONFIG_TIMING_102 ;
timing . dep_timeout = PN533_CONFIG_TIMING_204 ;
break ;
default :
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Unknown device type %d \n " ,
2013-04-05 23:27:38 +04:00
dev - > device_type ) ;
2012-07-02 22:04:01 +04:00
return - EINVAL ;
}
rc = pn533_set_configuration ( dev , PN533_CFGITEM_MAX_RETRIES ,
( u8 * ) & max_retries , sizeof ( max_retries ) ) ;
if ( rc ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Error on setting MAX_RETRIES config \n " ) ;
2012-07-02 22:04:01 +04:00
return rc ;
}
rc = pn533_set_configuration ( dev , PN533_CFGITEM_TIMING ,
( u8 * ) & timing , sizeof ( timing ) ) ;
if ( rc ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev , " Error on setting RF timings \n " ) ;
2012-07-02 22:04:01 +04:00
return rc ;
}
switch ( dev - > device_type ) {
case PN533_DEVICE_STD :
2016-03-25 17:46:54 +03:00
case PN533_DEVICE_PN532 :
2012-07-02 22:04:01 +04:00
break ;
case PN533_DEVICE_PASORI :
2013-04-03 10:02:02 +04:00
pn533_pasori_fw_reset ( dev ) ;
2012-07-02 22:04:01 +04:00
rc = pn533_set_configuration ( dev , PN533_CFGITEM_PASORI ,
pasori_cfg , 3 ) ;
if ( rc ) {
2016-03-25 17:46:53 +03:00
nfc_err ( dev - > dev ,
2013-04-05 23:27:38 +04:00
" Error while settings PASORI config \n " ) ;
2012-07-02 22:04:01 +04:00
return rc ;
}
2013-04-03 10:02:02 +04:00
pn533_pasori_fw_reset ( dev ) ;
2012-07-02 22:04:01 +04:00
break ;
}
return 0 ;
}
2016-03-25 17:46:53 +03:00
struct pn533 * pn533_register_device ( u32 device_type ,
u32 protocols ,
enum pn533_protocol_type protocol_type ,
void * phy ,
struct pn533_phy_ops * phy_ops ,
struct pn533_frame_ops * fops ,
struct device * dev )
2011-07-02 02:31:37 +04:00
{
2012-11-26 17:18:38 +04:00
struct pn533_fw_version fw_ver ;
2016-03-25 17:46:53 +03:00
struct pn533 * priv ;
2011-07-02 02:31:37 +04:00
int rc = - ENOMEM ;
2016-03-25 17:46:53 +03:00
priv = kzalloc ( sizeof ( * priv ) , GFP_KERNEL ) ;
if ( ! priv )
return ERR_PTR ( - ENOMEM ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
priv - > phy = phy ;
priv - > phy_ops = phy_ops ;
priv - > dev = dev ;
if ( fops ! = NULL )
priv - > ops = fops ;
else
priv - > ops = & pn533_std_frame_ops ;
priv - > protocol_type = protocol_type ;
priv - > device_type = device_type ;
mutex_init ( & priv - > cmd_lock ) ;
INIT_WORK ( & priv - > cmd_work , pn533_wq_cmd ) ;
INIT_WORK ( & priv - > cmd_complete_work , pn533_wq_cmd_complete ) ;
INIT_WORK ( & priv - > mi_rx_work , pn533_wq_mi_recv ) ;
INIT_WORK ( & priv - > mi_tx_work , pn533_wq_mi_send ) ;
INIT_WORK ( & priv - > tg_work , pn533_wq_tg_get_data ) ;
INIT_WORK ( & priv - > mi_tm_rx_work , pn533_wq_tm_mi_recv ) ;
INIT_WORK ( & priv - > mi_tm_tx_work , pn533_wq_tm_mi_send ) ;
INIT_DELAYED_WORK ( & priv - > poll_work , pn533_wq_poll ) ;
INIT_WORK ( & priv - > rf_work , pn533_wq_rf ) ;
priv - > wq = alloc_ordered_workqueue ( " pn533 " , 0 ) ;
if ( priv - > wq = = NULL )
2012-04-10 21:43:17 +04:00
goto error ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
init_timer ( & priv - > listen_timer ) ;
priv - > listen_timer . data = ( unsigned long ) priv ;
priv - > listen_timer . function = pn533_listen_mode_timer ;
2012-07-02 22:04:01 +04:00
2016-03-25 17:46:53 +03:00
skb_queue_head_init ( & priv - > resp_q ) ;
skb_queue_head_init ( & priv - > fragment_skb ) ;
NFC: pn533: Add support for ACS ACR122U reader
ACS ACR122U is an USB NFC reader, PC/SC and CCID compilant, based
on NXP PN532 chip.
Internally, it's build of MCU, PN532 and an antenna. MCU makes the
device CCID and PC/SC compilant and provide USB connection.
In this achitecture, a host cannot talk directly to PN532 and must
rely on MCU. Luckily, MCU exposes pseud-APDU through PC/SC Escape
mechanism which let the host to transmit standard PN532 commands
directly to PN532 chip with some limitations.
The frame roughly looks like:
CCID header | APDU header | PN532 header
(pc_to_rdr_escape) | (pseudo apdu Direct Tramsmit) | (len, TFI, cmd, params)
Accordign to limitations, ACR122U does't provide any mechanism to
abort last issued command.
Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2013-04-03 10:02:13 +04:00
2016-03-25 17:46:53 +03:00
INIT_LIST_HEAD ( & priv - > cmd_queue ) ;
2011-07-02 02:31:37 +04:00
2012-12-10 17:43:01 +04:00
memset ( & fw_ver , 0 , sizeof ( fw_ver ) ) ;
2016-03-25 17:46:53 +03:00
rc = pn533_get_firmware_version ( priv , & fw_ver ) ;
2012-12-10 17:43:01 +04:00
if ( rc < 0 )
goto destroy_wq ;
2016-03-25 17:46:53 +03:00
nfc_info ( dev , " NXP PN5%02X firmware ver %d.%d now attached \n " ,
2013-04-05 23:27:38 +04:00
fw_ver . ic , fw_ver . ver , fw_ver . rev ) ;
2012-12-10 17:43:01 +04:00
2016-03-25 17:46:53 +03:00
priv - > nfc_dev = nfc_allocate_device ( & pn533_nfc_ops , protocols ,
priv - > ops - > tx_header_len +
2011-08-19 17:47:11 +04:00
PN533_CMD_DATAEXCH_HEAD_LEN ,
2016-03-25 17:46:53 +03:00
priv - > ops - > tx_tail_len ) ;
if ( ! priv - > nfc_dev ) {
2013-05-07 16:07:52 +04:00
rc = - ENOMEM ;
2012-04-10 21:43:17 +04:00
goto destroy_wq ;
2013-05-07 16:07:52 +04:00
}
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
nfc_set_drvdata ( priv - > nfc_dev , priv ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
rc = nfc_register_device ( priv - > nfc_dev ) ;
2011-07-02 02:31:37 +04:00
if ( rc )
goto free_nfc_dev ;
2016-03-25 17:46:53 +03:00
rc = pn533_setup ( priv ) ;
2012-07-02 22:04:01 +04:00
if ( rc )
2012-05-29 23:34:08 +04:00
goto unregister_nfc_dev ;
2016-03-25 17:46:53 +03:00
return priv ;
2011-07-02 02:31:37 +04:00
2012-05-29 23:28:58 +04:00
unregister_nfc_dev :
2016-03-25 17:46:53 +03:00
nfc_unregister_device ( priv - > nfc_dev ) ;
2012-05-29 23:28:58 +04:00
2011-07-02 02:31:37 +04:00
free_nfc_dev :
2016-03-25 17:46:53 +03:00
nfc_free_device ( priv - > nfc_dev ) ;
2012-05-29 23:28:58 +04:00
2012-04-10 21:43:17 +04:00
destroy_wq :
2016-03-25 17:46:53 +03:00
destroy_workqueue ( priv - > wq ) ;
2011-07-02 02:31:37 +04:00
error :
2016-03-25 17:46:53 +03:00
kfree ( priv ) ;
return ERR_PTR ( rc ) ;
2011-07-02 02:31:37 +04:00
}
2016-03-25 17:46:53 +03:00
EXPORT_SYMBOL_GPL ( pn533_register_device ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
void pn533_unregister_device ( struct pn533 * priv )
2011-07-02 02:31:37 +04:00
{
2012-08-18 01:47:54 +04:00
struct pn533_cmd * cmd , * n ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
nfc_unregister_device ( priv - > nfc_dev ) ;
nfc_free_device ( priv - > nfc_dev ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
flush_delayed_work ( & priv - > poll_work ) ;
destroy_workqueue ( priv - > wq ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
skb_queue_purge ( & priv - > resp_q ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
del_timer ( & priv - > listen_timer ) ;
2011-07-02 02:31:37 +04:00
2016-03-25 17:46:53 +03:00
list_for_each_entry_safe ( cmd , n , & priv - > cmd_queue , queue ) {
2012-08-18 01:47:54 +04:00
list_del ( & cmd - > queue ) ;
kfree ( cmd ) ;
}
2016-03-25 17:46:53 +03:00
kfree ( priv ) ;
2011-07-02 02:31:37 +04:00
}
2016-03-25 17:46:53 +03:00
EXPORT_SYMBOL_GPL ( pn533_unregister_device ) ;
2011-07-02 02:31:37 +04:00
2013-04-03 10:02:01 +04:00
MODULE_AUTHOR ( " Lauro Ramos Venancio <lauro.venancio@openbossa.org> " ) ;
MODULE_AUTHOR ( " Aloisio Almeida Jr <aloisio.almeida@openbossa.org> " ) ;
MODULE_AUTHOR ( " Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> " ) ;
2016-03-25 17:46:53 +03:00
MODULE_DESCRIPTION ( " PN533 driver ver " VERSION ) ;
2011-07-02 02:31:37 +04:00
MODULE_VERSION ( VERSION ) ;
MODULE_LICENSE ( " GPL " ) ;