Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
2e486868
Commit
2e486868
authored
Jun 11, 2012
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'nfc-next-3.6-1' of
git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-3.0
parents
934b9d1e
51ad304c
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1106 additions
and
392 deletions
+1106
-392
drivers/nfc/pn533.c
drivers/nfc/pn533.c
+543
-119
drivers/nfc/pn544_hci.c
drivers/nfc/pn544_hci.c
+6
-4
include/linux/nfc.h
include/linux/nfc.h
+12
-0
include/net/nfc/hci.h
include/net/nfc/hci.h
+2
-1
include/net/nfc/nfc.h
include/net/nfc/nfc.h
+11
-3
include/net/nfc/shdlc.h
include/net/nfc/shdlc.h
+2
-1
net/nfc/core.c
net/nfc/core.c
+89
-30
net/nfc/hci/core.c
net/nfc/hci/core.c
+7
-6
net/nfc/hci/shdlc.c
net/nfc/hci/shdlc.c
+4
-2
net/nfc/llcp/commands.c
net/nfc/llcp/commands.c
+44
-10
net/nfc/llcp/llcp.c
net/nfc/llcp/llcp.c
+251
-170
net/nfc/llcp/llcp.h
net/nfc/llcp/llcp.h
+20
-6
net/nfc/llcp/sock.c
net/nfc/llcp/sock.c
+19
-28
net/nfc/nci/core.c
net/nfc/nci/core.c
+8
-7
net/nfc/netlink.c
net/nfc/netlink.c
+77
-4
net/nfc/nfc.h
net/nfc/nfc.h
+11
-1
No files found.
drivers/nfc/pn533.c
View file @
2e486868
This diff is collapsed.
Click to expand it.
drivers/nfc/pn544_hci.c
View file @
2e486868
...
...
@@ -576,7 +576,8 @@ static int pn544_hci_xmit(struct nfc_shdlc *shdlc, struct sk_buff *skb)
return
pn544_hci_i2c_write
(
client
,
skb
->
data
,
skb
->
len
);
}
static
int
pn544_hci_start_poll
(
struct
nfc_shdlc
*
shdlc
,
u32
protocols
)
static
int
pn544_hci_start_poll
(
struct
nfc_shdlc
*
shdlc
,
u32
im_protocols
,
u32
tm_protocols
)
{
struct
nfc_hci_dev
*
hdev
=
nfc_shdlc_get_hci_dev
(
shdlc
);
u8
phases
=
0
;
...
...
@@ -584,7 +585,8 @@ static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, u32 protocols)
u8
duration
[
2
];
u8
activated
;
pr_info
(
DRIVER_DESC
": %s protocols = %d
\n
"
,
__func__
,
protocols
);
pr_info
(
DRIVER_DESC
": %s protocols 0x%x 0x%x
\n
"
,
__func__
,
im_protocols
,
tm_protocols
);
r
=
nfc_hci_send_event
(
hdev
,
NFC_HCI_RF_READER_A_GATE
,
NFC_HCI_EVT_END_OPERATION
,
NULL
,
0
);
...
...
@@ -604,10 +606,10 @@ static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, u32 protocols)
if
(
r
<
0
)
return
r
;
if
(
protocols
&
(
NFC_PROTO_ISO14443_MASK
|
NFC_PROTO_MIFARE_MASK
|
if
(
im_
protocols
&
(
NFC_PROTO_ISO14443_MASK
|
NFC_PROTO_MIFARE_MASK
|
NFC_PROTO_JEWEL_MASK
))
phases
|=
1
;
/* Type A */
if
(
protocols
&
NFC_PROTO_FELICA_MASK
)
{
if
(
im_
protocols
&
NFC_PROTO_FELICA_MASK
)
{
phases
|=
(
1
<<
2
);
/* Type F 212 */
phases
|=
(
1
<<
3
);
/* Type F 424 */
}
...
...
include/linux/nfc.h
View file @
2e486868
...
...
@@ -56,6 +56,10 @@
* %NFC_ATTR_PROTOCOLS)
* @NFC_EVENT_DEVICE_REMOVED: event emitted when a device is removed
* (it sends %NFC_ATTR_DEVICE_INDEX)
* @NFC_EVENT_TM_ACTIVATED: event emitted when the adapter is activated in
* target mode.
* @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated
* from target mode.
*/
enum
nfc_commands
{
NFC_CMD_UNSPEC
,
...
...
@@ -71,6 +75,8 @@ enum nfc_commands {
NFC_EVENT_DEVICE_ADDED
,
NFC_EVENT_DEVICE_REMOVED
,
NFC_EVENT_TARGET_LOST
,
NFC_EVENT_TM_ACTIVATED
,
NFC_EVENT_TM_DEACTIVATED
,
/* private: internal use only */
__NFC_CMD_AFTER_LAST
};
...
...
@@ -94,6 +100,8 @@ enum nfc_commands {
* @NFC_ATTR_TARGET_SENSF_RES: NFC-F targets extra information, max 18 bytes
* @NFC_ATTR_COMM_MODE: Passive or active mode
* @NFC_ATTR_RF_MODE: Initiator or target
* @NFC_ATTR_IM_PROTOCOLS: Initiator mode protocols to poll for
* @NFC_ATTR_TM_PROTOCOLS: Target mode protocols to listen for
*/
enum
nfc_attrs
{
NFC_ATTR_UNSPEC
,
...
...
@@ -109,6 +117,8 @@ enum nfc_attrs {
NFC_ATTR_COMM_MODE
,
NFC_ATTR_RF_MODE
,
NFC_ATTR_DEVICE_POWERED
,
NFC_ATTR_IM_PROTOCOLS
,
NFC_ATTR_TM_PROTOCOLS
,
/* private: internal use only */
__NFC_ATTR_AFTER_LAST
};
...
...
@@ -118,6 +128,7 @@ enum nfc_attrs {
#define NFC_NFCID1_MAXSIZE 10
#define NFC_SENSB_RES_MAXSIZE 12
#define NFC_SENSF_RES_MAXSIZE 18
#define NFC_GB_MAXSIZE 48
/* NFC protocols */
#define NFC_PROTO_JEWEL 1
...
...
@@ -135,6 +146,7 @@ enum nfc_attrs {
/* NFC RF modes */
#define NFC_RF_INITIATOR 0
#define NFC_RF_TARGET 1
#define NFC_RF_NONE 2
/* NFC protocols masks used in bitsets */
#define NFC_PROTO_JEWEL_MASK (1 << NFC_PROTO_JEWEL)
...
...
include/net/nfc/hci.h
View file @
2e486868
...
...
@@ -31,7 +31,8 @@ struct nfc_hci_ops {
void
(
*
close
)
(
struct
nfc_hci_dev
*
hdev
);
int
(
*
hci_ready
)
(
struct
nfc_hci_dev
*
hdev
);
int
(
*
xmit
)
(
struct
nfc_hci_dev
*
hdev
,
struct
sk_buff
*
skb
);
int
(
*
start_poll
)
(
struct
nfc_hci_dev
*
hdev
,
u32
protocols
);
int
(
*
start_poll
)
(
struct
nfc_hci_dev
*
hdev
,
u32
im_protocols
,
u32
tm_protocols
);
int
(
*
target_from_gate
)
(
struct
nfc_hci_dev
*
hdev
,
u8
gate
,
struct
nfc_target
*
target
);
int
(
*
complete_target_discovered
)
(
struct
nfc_hci_dev
*
hdev
,
u8
gate
,
...
...
include/net/nfc/nfc.h
View file @
2e486868
...
...
@@ -53,7 +53,8 @@ struct nfc_target;
struct
nfc_ops
{
int
(
*
dev_up
)(
struct
nfc_dev
*
dev
);
int
(
*
dev_down
)(
struct
nfc_dev
*
dev
);
int
(
*
start_poll
)(
struct
nfc_dev
*
dev
,
u32
protocols
);
int
(
*
start_poll
)(
struct
nfc_dev
*
dev
,
u32
im_protocols
,
u32
tm_protocols
);
void
(
*
stop_poll
)(
struct
nfc_dev
*
dev
);
int
(
*
dep_link_up
)(
struct
nfc_dev
*
dev
,
struct
nfc_target
*
target
,
u8
comm_mode
,
u8
*
gb
,
size_t
gb_len
);
...
...
@@ -62,9 +63,10 @@ struct nfc_ops {
u32
protocol
);
void
(
*
deactivate_target
)(
struct
nfc_dev
*
dev
,
struct
nfc_target
*
target
);
int
(
*
data_exchang
e
)(
struct
nfc_dev
*
dev
,
struct
nfc_target
*
target
,
int
(
*
im_transceiv
e
)(
struct
nfc_dev
*
dev
,
struct
nfc_target
*
target
,
struct
sk_buff
*
skb
,
data_exchange_cb_t
cb
,
void
*
cb_context
);
int
(
*
tm_send
)(
struct
nfc_dev
*
dev
,
struct
sk_buff
*
skb
);
int
(
*
check_presence
)(
struct
nfc_dev
*
dev
,
struct
nfc_target
*
target
);
};
...
...
@@ -99,10 +101,10 @@ struct nfc_dev {
int
targets_generation
;
struct
device
dev
;
bool
dev_up
;
u8
rf_mode
;
bool
polling
;
struct
nfc_target
*
active_target
;
bool
dep_link_up
;
u32
dep_rf_mode
;
struct
nfc_genl_data
genl_data
;
u32
supported_protocols
;
...
...
@@ -188,6 +190,7 @@ struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
int
nfc_set_remote_general_bytes
(
struct
nfc_dev
*
dev
,
u8
*
gt
,
u8
gt_len
);
u8
*
nfc_get_local_general_bytes
(
struct
nfc_dev
*
dev
,
size_t
*
gb_len
);
int
nfc_targets_found
(
struct
nfc_dev
*
dev
,
struct
nfc_target
*
targets
,
int
ntargets
);
...
...
@@ -196,4 +199,9 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx);
int
nfc_dep_link_is_up
(
struct
nfc_dev
*
dev
,
u32
target_idx
,
u8
comm_mode
,
u8
rf_mode
);
int
nfc_tm_activated
(
struct
nfc_dev
*
dev
,
u32
protocol
,
u8
comm_mode
,
u8
*
gb
,
size_t
gb_len
);
int
nfc_tm_deactivated
(
struct
nfc_dev
*
dev
);
int
nfc_tm_data_received
(
struct
nfc_dev
*
dev
,
struct
sk_buff
*
skb
);
#endif
/* __NET_NFC_H */
include/net/nfc/shdlc.h
View file @
2e486868
...
...
@@ -27,7 +27,8 @@ struct nfc_shdlc_ops {
void
(
*
close
)
(
struct
nfc_shdlc
*
shdlc
);
int
(
*
hci_ready
)
(
struct
nfc_shdlc
*
shdlc
);
int
(
*
xmit
)
(
struct
nfc_shdlc
*
shdlc
,
struct
sk_buff
*
skb
);
int
(
*
start_poll
)
(
struct
nfc_shdlc
*
shdlc
,
u32
protocols
);
int
(
*
start_poll
)
(
struct
nfc_shdlc
*
shdlc
,
u32
im_protocols
,
u32
tm_protocols
);
int
(
*
target_from_gate
)
(
struct
nfc_shdlc
*
shdlc
,
u8
gate
,
struct
nfc_target
*
target
);
int
(
*
complete_target_discovered
)
(
struct
nfc_shdlc
*
shdlc
,
u8
gate
,
...
...
net/nfc/core.c
View file @
2e486868
...
...
@@ -121,14 +121,14 @@ int nfc_dev_down(struct nfc_dev *dev)
* The device remains polling for targets until a target is found or
* the nfc_stop_poll function is called.
*/
int
nfc_start_poll
(
struct
nfc_dev
*
dev
,
u32
protocols
)
int
nfc_start_poll
(
struct
nfc_dev
*
dev
,
u32
im_protocols
,
u32
tm_
protocols
)
{
int
rc
;
pr_debug
(
"dev_name
=%s protocols=
0x%x
\n
"
,
dev_name
(
&
dev
->
dev
),
protocols
);
pr_debug
(
"dev_name
%s initiator protocols 0x%x target protocols
0x%x
\n
"
,
dev_name
(
&
dev
->
dev
),
im_protocols
,
tm_
protocols
);
if
(
!
protocols
)
if
(
!
im_protocols
&&
!
tm_
protocols
)
return
-
EINVAL
;
device_lock
(
&
dev
->
dev
);
...
...
@@ -143,9 +143,11 @@ int nfc_start_poll(struct nfc_dev *dev, u32 protocols)
goto
error
;
}
rc
=
dev
->
ops
->
start_poll
(
dev
,
protocols
);
if
(
!
rc
)
rc
=
dev
->
ops
->
start_poll
(
dev
,
im_protocols
,
tm_
protocols
);
if
(
!
rc
)
{
dev
->
polling
=
true
;
dev
->
rf_mode
=
NFC_RF_NONE
;
}
error:
device_unlock
(
&
dev
->
dev
);
...
...
@@ -235,8 +237,10 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
}
rc
=
dev
->
ops
->
dep_link_up
(
dev
,
target
,
comm_mode
,
gb
,
gb_len
);
if
(
!
rc
)
if
(
!
rc
)
{
dev
->
active_target
=
target
;
dev
->
rf_mode
=
NFC_RF_INITIATOR
;
}
error:
device_unlock
(
&
dev
->
dev
);
...
...
@@ -264,11 +268,6 @@ int nfc_dep_link_down(struct nfc_dev *dev)
goto
error
;
}
if
(
dev
->
dep_rf_mode
==
NFC_RF_TARGET
)
{
rc
=
-
EOPNOTSUPP
;
goto
error
;
}
rc
=
dev
->
ops
->
dep_link_down
(
dev
);
if
(
!
rc
)
{
dev
->
dep_link_up
=
false
;
...
...
@@ -286,7 +285,6 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
u8
comm_mode
,
u8
rf_mode
)
{
dev
->
dep_link_up
=
true
;
dev
->
dep_rf_mode
=
rf_mode
;
nfc_llcp_mac_is_up
(
dev
,
target_idx
,
comm_mode
,
rf_mode
);
...
...
@@ -330,6 +328,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol)
rc
=
dev
->
ops
->
activate_target
(
dev
,
target
,
protocol
);
if
(
!
rc
)
{
dev
->
active_target
=
target
;
dev
->
rf_mode
=
NFC_RF_INITIATOR
;
if
(
dev
->
ops
->
check_presence
)
mod_timer
(
&
dev
->
check_pres_timer
,
jiffies
+
...
...
@@ -409,27 +408,30 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
goto
error
;
}
if
(
dev
->
active_target
==
NULL
)
{
rc
=
-
ENOTCONN
;
kfree_skb
(
skb
);
goto
error
;
}
if
(
dev
->
rf_mode
==
NFC_RF_INITIATOR
&&
dev
->
active_target
!=
NULL
)
{
if
(
dev
->
active_target
->
idx
!=
target_idx
)
{
rc
=
-
EADDRNOTAVAIL
;
kfree_skb
(
skb
);
goto
error
;
}
if
(
dev
->
active_target
->
idx
!=
target_idx
)
{
rc
=
-
EADDRNOTAVAIL
;
if
(
dev
->
ops
->
check_presence
)
del_timer_sync
(
&
dev
->
check_pres_timer
);
rc
=
dev
->
ops
->
im_transceive
(
dev
,
dev
->
active_target
,
skb
,
cb
,
cb_context
);
if
(
!
rc
&&
dev
->
ops
->
check_presence
)
mod_timer
(
&
dev
->
check_pres_timer
,
jiffies
+
msecs_to_jiffies
(
NFC_CHECK_PRES_FREQ_MS
));
}
else
if
(
dev
->
rf_mode
==
NFC_RF_TARGET
&&
dev
->
ops
->
tm_send
!=
NULL
)
{
rc
=
dev
->
ops
->
tm_send
(
dev
,
skb
);
}
else
{
rc
=
-
ENOTCONN
;
kfree_skb
(
skb
);
goto
error
;
}
if
(
dev
->
ops
->
check_presence
)
del_timer_sync
(
&
dev
->
check_pres_timer
);
rc
=
dev
->
ops
->
data_exchange
(
dev
,
dev
->
active_target
,
skb
,
cb
,
cb_context
);
if
(
!
rc
&&
dev
->
ops
->
check_presence
)
mod_timer
(
&
dev
->
check_pres_timer
,
jiffies
+
msecs_to_jiffies
(
NFC_CHECK_PRES_FREQ_MS
));
error:
device_unlock
(
&
dev
->
dev
);
...
...
@@ -447,6 +449,63 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
}
EXPORT_SYMBOL
(
nfc_set_remote_general_bytes
);
u8
*
nfc_get_local_general_bytes
(
struct
nfc_dev
*
dev
,
size_t
*
gb_len
)
{
pr_debug
(
"dev_name=%s
\n
"
,
dev_name
(
&
dev
->
dev
));
return
nfc_llcp_general_bytes
(
dev
,
gb_len
);
}
EXPORT_SYMBOL
(
nfc_get_local_general_bytes
);
int
nfc_tm_data_received
(
struct
nfc_dev
*
dev
,
struct
sk_buff
*
skb
)
{
/* Only LLCP target mode for now */
if
(
dev
->
dep_link_up
==
false
)
{
kfree_skb
(
skb
);
return
-
ENOLINK
;
}
return
nfc_llcp_data_received
(
dev
,
skb
);
}
EXPORT_SYMBOL
(
nfc_tm_data_received
);
int
nfc_tm_activated
(
struct
nfc_dev
*
dev
,
u32
protocol
,
u8
comm_mode
,
u8
*
gb
,
size_t
gb_len
)
{
int
rc
;
device_lock
(
&
dev
->
dev
);
dev
->
polling
=
false
;
if
(
gb
!=
NULL
)
{
rc
=
nfc_set_remote_general_bytes
(
dev
,
gb
,
gb_len
);
if
(
rc
<
0
)
goto
out
;
}
dev
->
rf_mode
=
NFC_RF_TARGET
;
if
(
protocol
==
NFC_PROTO_NFC_DEP_MASK
)
nfc_dep_link_is_up
(
dev
,
0
,
comm_mode
,
NFC_RF_TARGET
);
rc
=
nfc_genl_tm_activated
(
dev
,
protocol
);
out:
device_unlock
(
&
dev
->
dev
);
return
rc
;
}
EXPORT_SYMBOL
(
nfc_tm_activated
);
int
nfc_tm_deactivated
(
struct
nfc_dev
*
dev
)
{
dev
->
dep_link_up
=
false
;
return
nfc_genl_tm_deactivated
(
dev
);
}
EXPORT_SYMBOL
(
nfc_tm_deactivated
);
/**
* nfc_alloc_send_skb - allocate a skb for data exchange responses
*
...
...
@@ -678,7 +737,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
struct
nfc_dev
*
dev
;
if
(
!
ops
->
start_poll
||
!
ops
->
stop_poll
||
!
ops
->
activate_target
||
!
ops
->
deactivate_target
||
!
ops
->
data_exchang
e
)
!
ops
->
deactivate_target
||
!
ops
->
im_transceiv
e
)
return
NULL
;
if
(
!
supported_protocols
)
...
...
net/nfc/hci/core.c
View file @
2e486868
...
...
@@ -481,12 +481,13 @@ static int hci_dev_down(struct nfc_dev *nfc_dev)
return
0
;
}
static
int
hci_start_poll
(
struct
nfc_dev
*
nfc_dev
,
u32
protocols
)
static
int
hci_start_poll
(
struct
nfc_dev
*
nfc_dev
,
u32
im_protocols
,
u32
tm_protocols
)
{
struct
nfc_hci_dev
*
hdev
=
nfc_get_drvdata
(
nfc_dev
);
if
(
hdev
->
ops
->
start_poll
)
return
hdev
->
ops
->
start_poll
(
hdev
,
protocols
);
return
hdev
->
ops
->
start_poll
(
hdev
,
im_protocols
,
tm_
protocols
);
else
return
nfc_hci_send_event
(
hdev
,
NFC_HCI_RF_READER_A_GATE
,
NFC_HCI_EVT_READER_REQUESTED
,
NULL
,
0
);
...
...
@@ -511,9 +512,9 @@ static void hci_deactivate_target(struct nfc_dev *nfc_dev,
{
}
static
int
hci_
data_exchang
e
(
struct
nfc_dev
*
nfc_dev
,
struct
nfc_target
*
target
,
struct
sk_buff
*
skb
,
data_exchange_cb_t
cb
,
void
*
cb_context
)
static
int
hci_
transceiv
e
(
struct
nfc_dev
*
nfc_dev
,
struct
nfc_target
*
target
,
struct
sk_buff
*
skb
,
data_exchange_cb_t
cb
,
void
*
cb_context
)
{
struct
nfc_hci_dev
*
hdev
=
nfc_get_drvdata
(
nfc_dev
);
int
r
;
...
...
@@ -579,7 +580,7 @@ static struct nfc_ops hci_nfc_ops = {
.
stop_poll
=
hci_stop_poll
,
.
activate_target
=
hci_activate_target
,
.
deactivate_target
=
hci_deactivate_target
,
.
data_exchange
=
hci_data_exchang
e
,
.
im_transceive
=
hci_transceiv
e
,
.
check_presence
=
hci_check_presence
,
};
...
...
net/nfc/hci/shdlc.c
View file @
2e486868
...
...
@@ -765,14 +765,16 @@ static int nfc_shdlc_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb)
return
0
;
}
static
int
nfc_shdlc_start_poll
(
struct
nfc_hci_dev
*
hdev
,
u32
protocols
)
static
int
nfc_shdlc_start_poll
(
struct
nfc_hci_dev
*
hdev
,
u32
im_protocols
,
u32
tm_protocols
)
{
struct
nfc_shdlc
*
shdlc
=
nfc_hci_get_clientdata
(
hdev
);
pr_debug
(
"
\n
"
);
if
(
shdlc
->
ops
->
start_poll
)
return
shdlc
->
ops
->
start_poll
(
shdlc
,
protocols
);
return
shdlc
->
ops
->
start_poll
(
shdlc
,
im_protocols
,
tm_protocols
);
return
0
;
}
...
...
net/nfc/llcp/commands.c
View file @
2e486868
...
...
@@ -51,7 +51,7 @@ static u8 llcp_tlv8(u8 *tlv, u8 type)
return
tlv
[
2
];
}
static
u
8
llcp_tlv16
(
u8
*
tlv
,
u8
type
)
static
u
16
llcp_tlv16
(
u8
*
tlv
,
u8
type
)
{
if
(
tlv
[
0
]
!=
type
||
tlv
[
1
]
!=
llcp_tlv_length
[
tlv
[
0
]])
return
0
;
...
...
@@ -67,7 +67,7 @@ static u8 llcp_tlv_version(u8 *tlv)
static
u16
llcp_tlv_miux
(
u8
*
tlv
)
{
return
llcp_tlv16
(
tlv
,
LLCP_TLV_MIUX
)
&
0x7f
;
return
llcp_tlv16
(
tlv
,
LLCP_TLV_MIUX
)
&
0x7f
f
;
}
static
u16
llcp_tlv_wks
(
u8
*
tlv
)
...
...
@@ -117,8 +117,8 @@ u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
return
tlv
;
}
int
nfc_llcp_parse_tlv
(
struct
nfc_llcp_local
*
local
,
u8
*
tlv_array
,
u16
tlv_array_len
)
int
nfc_llcp_parse_
gb_
tlv
(
struct
nfc_llcp_local
*
local
,
u8
*
tlv_array
,
u16
tlv_array_len
)
{
u8
*
tlv
=
tlv_array
,
type
,
length
,
offset
=
0
;
...
...
@@ -149,8 +149,45 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
case
LLCP_TLV_OPT
:
local
->
remote_opt
=
llcp_tlv_opt
(
tlv
);
break
;
default:
pr_err
(
"Invalid gt tlv value 0x%x
\n
"
,
type
);
break
;
}
offset
+=
length
+
2
;
tlv
+=
length
+
2
;
}
pr_debug
(
"version 0x%x miu %d lto %d opt 0x%x wks 0x%x
\n
"
,
local
->
remote_version
,
local
->
remote_miu
,
local
->
remote_lto
,
local
->
remote_opt
,
local
->
remote_wks
);
return
0
;
}
int
nfc_llcp_parse_connection_tlv
(
struct
nfc_llcp_sock
*
sock
,
u8
*
tlv_array
,
u16
tlv_array_len
)
{
u8
*
tlv
=
tlv_array
,
type
,
length
,
offset
=
0
;
pr_debug
(
"TLV array length %d
\n
"
,
tlv_array_len
);
if
(
sock
==
NULL
)
return
-
ENOTCONN
;
while
(
offset
<
tlv_array_len
)
{
type
=
tlv
[
0
];
length
=
tlv
[
1
];
pr_debug
(
"type 0x%x length %d
\n
"
,
type
,
length
);
switch
(
type
)
{
case
LLCP_TLV_MIUX
:
sock
->
miu
=
llcp_tlv_miux
(
tlv
)
+
128
;
break
;
case
LLCP_TLV_RW
:
local
->
remote_
rw
=
llcp_tlv_rw
(
tlv
);
sock
->
rw
=
llcp_tlv_rw
(
tlv
);
break
;
case
LLCP_TLV_SN
:
break
;
...
...
@@ -163,10 +200,7 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
tlv
+=
length
+
2
;
}
pr_debug
(
"version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d
\n
"
,
local
->
remote_version
,
local
->
remote_miu
,
local
->
remote_lto
,
local
->
remote_opt
,
local
->
remote_wks
,
local
->
remote_rw
);
pr_debug
(
"sock %p rw %d miu %d
\n
"
,
sock
,
sock
->
rw
,
sock
->
miu
);
return
0
;
}
...
...
@@ -474,7 +508,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
while
(
remaining_len
>
0
)
{
frag_len
=
min_t
(
size_t
,
local
->
remote_
miu
,
remaining_len
);
frag_len
=
min_t
(
size_t
,
sock
->
miu
,
remaining_len
);
pr_debug
(
"Fragment %zd bytes remaining %zd"
,
frag_len
,
remaining_len
);
...
...
net/nfc/llcp/llcp.c
View file @
2e486868
This diff is collapsed.
Click to expand it.
net/nfc/llcp/llcp.h
View file @
2e486868
...
...
@@ -40,12 +40,18 @@ enum llcp_state {
struct
nfc_llcp_sock
;
struct
llcp_sock_list
{
struct
hlist_head
head
;
rwlock_t
lock
;
};
struct
nfc_llcp_local
{
struct
list_head
list
;
struct
nfc_dev
*
dev
;
struct
kref
ref
;
struct
mutex
sdp_lock
;
struct
mutex
socket_lock
;
struct
timer_list
link_timer
;
struct
sk_buff_head
tx_queue
;
...
...
@@ -77,24 +83,26 @@ struct nfc_llcp_local {
u16
remote_lto
;
u8
remote_opt
;
u16
remote_wks
;
u8
remote_rw
;
/* sockets array */
struct
nfc_llcp_sock
*
sockets
[
LLCP_MAX_SAP
];
struct
llcp_sock_list
sockets
;
struct
llcp_sock_list
connecting_sockets
;
};
struct
nfc_llcp_sock
{
struct
sock
sk
;
struct
list_head
list
;
struct
nfc_dev
*
dev
;
struct
nfc_llcp_local
*
local
;
u32
target_idx
;
u32
nfc_protocol
;
/* Link parameters */
u8
ssap
;
u8
dsap
;
char
*
service_name
;
size_t
service_name_len
;
u8
rw
;
u16
miu
;
/* Link variables */
u8
send_n
;
...
...
@@ -164,7 +172,11 @@ struct nfc_llcp_sock {
#define LLCP_DM_REJ 0x03
void
nfc_llcp_sock_link
(
struct
llcp_sock_list
*
l
,
struct
sock
*
s
);
void
nfc_llcp_sock_unlink
(
struct
llcp_sock_list
*
l
,
struct
sock
*
s
);
struct
nfc_llcp_local
*
nfc_llcp_find_local
(
struct
nfc_dev
*
dev
);
struct
nfc_llcp_local
*
nfc_llcp_local_get
(
struct
nfc_llcp_local
*
local
);
int
nfc_llcp_local_put
(
struct
nfc_llcp_local
*
local
);
u8
nfc_llcp_get_sdp_ssap
(
struct
nfc_llcp_local
*
local
,
struct
nfc_llcp_sock
*
sock
);
u8
nfc_llcp_get_local_ssap
(
struct
nfc_llcp_local
*
local
);
...
...
@@ -179,8 +191,10 @@ void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk);
struct
sock
*
nfc_llcp_accept_dequeue
(
struct
sock
*
sk
,
struct
socket
*
newsock
);
/* TLV API */
int
nfc_llcp_parse_tlv
(
struct
nfc_llcp_local
*
local
,
u8
*
tlv_array
,
u16
tlv_array_len
);
int
nfc_llcp_parse_gb_tlv
(
struct
nfc_llcp_local
*
local
,
u8
*
tlv_array
,
u16
tlv_array_len
);
int
nfc_llcp_parse_connection_tlv
(
struct
nfc_llcp_sock
*
sock
,
u8
*
tlv_array
,
u16
tlv_array_len
);
/* Commands API */
void
nfc_llcp_recv
(
void
*
data
,
struct
sk_buff
*
skb
,
int
err
);
...
...
net/nfc/llcp/sock.c
View file @
2e486868
...
...
@@ -111,7 +111,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
}
llcp_sock
->
dev
=
dev
;
llcp_sock
->
local
=
local
;
llcp_sock
->
local
=
nfc_llcp_local_get
(
local
)
;
llcp_sock
->
nfc_protocol
=
llcp_addr
.
nfc_protocol
;
llcp_sock
->
service_name_len
=
min_t
(
unsigned
int
,
llcp_addr
.
service_name_len
,
...
...
@@ -124,7 +124,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if
(
llcp_sock
->
ssap
==
LLCP_MAX_SAP
)
goto
put_dev
;
local
->
sockets
[
llcp_sock
->
ssap
]
=
llcp_sock
;
nfc_llcp_sock_link
(
&
local
->
sockets
,
sk
)
;
pr_debug
(
"Socket bound to SAP %d
\n
"
,
llcp_sock
->
ssap
);
...
...
@@ -379,15 +379,6 @@ static int llcp_sock_release(struct socket *sock)
goto
out
;
}
mutex_lock
(
&
local
->
socket_lock
);
if
(
llcp_sock
==
local
->
sockets
[
llcp_sock
->
ssap
])
local
->
sockets
[
llcp_sock
->
ssap
]
=
NULL
;
else
list_del_init
(
&
llcp_sock
->
list
);
mutex_unlock
(
&
local
->
socket_lock
);
lock_sock
(
sk
);
/* Send a DISC */
...
...
@@ -412,14 +403,12 @@ static int llcp_sock_release(struct socket *sock)
}
}
/* Freeing the SAP */
if
((
sk
->
sk_state
==
LLCP_CONNECTED
&&
llcp_sock
->
ssap
>
LLCP_LOCAL_SAP_OFFSET
)
||
sk
->
sk_state
==
LLCP_BOUND
||
sk
->
sk_state
==
LLCP_LISTEN
)
nfc_llcp_put_ssap
(
llcp_sock
->
local
,
llcp_sock
->
ssap
);
nfc_llcp_put_ssap
(
llcp_sock
->
local
,
llcp_sock
->
ssap
);
release_sock
(
sk
);
nfc_llcp_sock_unlink
(
&
local
->
sockets
,
sk
);
out:
sock_orphan
(
sk
);
sock_put
(
sk
);
...
...
@@ -487,7 +476,8 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
}
llcp_sock
->
dev
=
dev
;
llcp_sock
->
local
=
local
;
llcp_sock
->
local
=
nfc_llcp_local_get
(
local
);
llcp_sock
->
miu
=
llcp_sock
->
local
->
remote_miu
;
llcp_sock
->
ssap
=
nfc_llcp_get_local_ssap
(
local
);
if
(
llcp_sock
->
ssap
==
LLCP_SAP_MAX
)
{
ret
=
-
ENOMEM
;
...
...
@@ -505,21 +495,26 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
llcp_sock
->
service_name_len
,
GFP_KERNEL
);
local
->
sockets
[
llcp_sock
->
ssap
]
=
llcp_sock
;
nfc_llcp_sock_link
(
&
local
->
connecting_sockets
,
sk
)
;
ret
=
nfc_llcp_send_connect
(
llcp_sock
);
if
(
ret
)
goto
put_dev
;
goto
sock_unlink
;
ret
=
sock_wait_state
(
sk
,
LLCP_CONNECTED
,
sock_sndtimeo
(
sk
,
flags
&
O_NONBLOCK
));
if
(
ret
)
goto
put_dev
;
goto
sock_unlink
;
release_sock
(
sk
);
return
0
;
sock_unlink:
nfc_llcp_put_ssap
(
local
,
llcp_sock
->
ssap
);
nfc_llcp_sock_unlink
(
&
local
->
connecting_sockets
,
sk
);
put_dev:
nfc_put_device
(
dev
);
...
...
@@ -684,13 +679,14 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
llcp_sock
->
ssap
=
0
;
llcp_sock
->
dsap
=
LLCP_SAP_SDP
;
llcp_sock
->
rw
=
LLCP_DEFAULT_RW
;
llcp_sock
->
miu
=
LLCP_DEFAULT_MIU
;
llcp_sock
->
send_n
=
llcp_sock
->
send_ack_n
=
0
;
llcp_sock
->
recv_n
=
llcp_sock
->
recv_ack_n
=
0
;
llcp_sock
->
remote_ready
=
1
;
skb_queue_head_init
(
&
llcp_sock
->
tx_queue
);
skb_queue_head_init
(
&
llcp_sock
->
tx_pending_queue
);
skb_queue_head_init
(
&
llcp_sock
->
tx_backlog_queue
);
INIT_LIST_HEAD
(
&
llcp_sock
->
list
);
INIT_LIST_HEAD
(
&
llcp_sock
->
accept_queue
);
if
(
sock
!=
NULL
)
...
...
@@ -701,8 +697,6 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
void
nfc_llcp_sock_free
(
struct
nfc_llcp_sock
*
sock
)
{
struct
nfc_llcp_local
*
local
=
sock
->
local
;
kfree
(
sock
->
service_name
);
skb_queue_purge
(
&
sock
->
tx_queue
);
...
...
@@ -711,12 +705,9 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
list_del_init
(
&
sock
->
accept_queue
);
if
(
local
!=
NULL
&&
sock
==
local
->
sockets
[
sock
->
ssap
])
local
->
sockets
[
sock
->
ssap
]
=
NULL
;
else
list_del_init
(
&
sock
->
list
);
sock
->
parent
=
NULL
;
nfc_llcp_local_put
(
sock
->
local
);
}
static
int
llcp_sock_create
(
struct
net
*
net
,
struct
socket
*
sock
,
...
...
net/nfc/nci/core.c
View file @
2e486868
...
...
@@ -387,7 +387,8 @@ static int nci_dev_down(struct nfc_dev *nfc_dev)
return
nci_close_device
(
ndev
);
}
static
int
nci_start_poll
(
struct
nfc_dev
*
nfc_dev
,
__u32
protocols
)
static
int
nci_start_poll
(
struct
nfc_dev
*
nfc_dev
,
__u32
im_protocols
,
__u32
tm_protocols
)
{
struct
nci_dev
*
ndev
=
nfc_get_drvdata
(
nfc_dev
);
int
rc
;
...
...
@@ -413,11 +414,11 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
return
-
EBUSY
;
}
rc
=
nci_request
(
ndev
,
nci_rf_discover_req
,
protocols
,
rc
=
nci_request
(
ndev
,
nci_rf_discover_req
,
im_
protocols
,
msecs_to_jiffies
(
NCI_RF_DISC_TIMEOUT
));
if
(
!
rc
)
ndev
->
poll_prots
=
protocols
;
ndev
->
poll_prots
=
im_
protocols
;
return
rc
;
}
...
...
@@ -521,9 +522,9 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev,
}
}
static
int
nci_
data_exchang
e
(
struct
nfc_dev
*
nfc_dev
,
struct
nfc_target
*
target
,
struct
sk_buff
*
skb
,
data_exchange_cb_t
cb
,
void
*
cb_context
)
static
int
nci_
transceiv
e
(
struct
nfc_dev
*
nfc_dev
,
struct
nfc_target
*
target
,
struct
sk_buff
*
skb
,
data_exchange_cb_t
cb
,
void
*
cb_context
)
{
struct
nci_dev
*
ndev
=
nfc_get_drvdata
(
nfc_dev
);
int
rc
;
...
...
@@ -556,7 +557,7 @@ static struct nfc_ops nci_nfc_ops = {
.
stop_poll
=
nci_stop_poll
,
.
activate_target
=
nci_activate_target
,
.
deactivate_target
=
nci_deactivate_target
,
.
data_exchange
=
nci_data_exchang
e
,
.
im_transceive
=
nci_transceiv
e
,
};
/* ---- Interface to NCI drivers ---- */
...
...
net/nfc/netlink.c
View file @
2e486868
...
...
@@ -49,6 +49,8 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
[
NFC_ATTR_COMM_MODE
]
=
{
.
type
=
NLA_U8
},
[
NFC_ATTR_RF_MODE
]
=
{
.
type
=
NLA_U8
},
[
NFC_ATTR_DEVICE_POWERED
]
=
{
.
type
=
NLA_U8
},
[
NFC_ATTR_IM_PROTOCOLS
]
=
{
.
type
=
NLA_U32
},
[
NFC_ATTR_TM_PROTOCOLS
]
=
{
.
type
=
NLA_U32
},
};
static
int
nfc_genl_send_target
(
struct
sk_buff
*
msg
,
struct
nfc_target
*
target
,
...
...
@@ -219,6 +221,68 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
return
-
EMSGSIZE
;
}
int
nfc_genl_tm_activated
(
struct
nfc_dev
*
dev
,
u32
protocol
)
{
struct
sk_buff
*
msg
;
void
*
hdr
;
msg
=
nlmsg_new
(
NLMSG_GOODSIZE
,
GFP_KERNEL
);
if
(
!
msg
)
return
-
ENOMEM
;
hdr
=
genlmsg_put
(
msg
,
0
,
0
,
&
nfc_genl_family
,
0
,
NFC_EVENT_TM_ACTIVATED
);
if
(
!
hdr
)
goto
free_msg
;
if
(
nla_put_u32
(
msg
,
NFC_ATTR_DEVICE_INDEX
,
dev
->
idx
))
goto
nla_put_failure
;
if
(
nla_put_u32
(
msg
,
NFC_ATTR_TM_PROTOCOLS
,
protocol
))
goto
nla_put_failure
;
genlmsg_end
(
msg
,
hdr
);
genlmsg_multicast
(
msg
,
0
,
nfc_genl_event_mcgrp
.
id
,
GFP_KERNEL
);
return
0
;
nla_put_failure:
genlmsg_cancel
(
msg
,
hdr
);
free_msg:
nlmsg_free
(
msg
);
return
-
EMSGSIZE
;
}
int
nfc_genl_tm_deactivated
(
struct
nfc_dev
*
dev
)
{
struct
sk_buff
*
msg
;
void
*
hdr
;
msg
=
nlmsg_new
(
NLMSG_GOODSIZE
,
GFP_KERNEL
);
if
(
!
msg
)
return
-
ENOMEM
;
hdr
=
genlmsg_put
(
msg
,
0
,
0
,
&
nfc_genl_family
,
0
,
NFC_EVENT_TM_DEACTIVATED
);
if
(
!
hdr
)
goto
free_msg
;
if
(
nla_put_u32
(
msg
,
NFC_ATTR_DEVICE_INDEX
,
dev
->
idx
))
goto
nla_put_failure
;
genlmsg_end
(
msg
,
hdr
);
genlmsg_multicast
(
msg
,
0
,
nfc_genl_event_mcgrp
.
id
,
GFP_KERNEL
);
return
0
;
nla_put_failure:
genlmsg_cancel
(
msg
,
hdr
);
free_msg:
nlmsg_free
(
msg
);
return
-
EMSGSIZE
;
}
int
nfc_genl_device_added
(
struct
nfc_dev
*
dev
)
{
struct
sk_buff
*
msg
;
...
...
@@ -519,16 +583,25 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
struct
nfc_dev
*
dev
;
int
rc
;
u32
idx
;
u32
protocols
;
u32
im_protocols
=
0
,
tm_protocols
=
0
;
pr_debug
(
"Poll start
\n
"
);
if
(
!
info
->
attrs
[
NFC_ATTR_DEVICE_INDEX
]
||
!
info
->
attrs
[
NFC_ATTR_PROTOCOLS
])
((
!
info
->
attrs
[
NFC_ATTR_IM_PROTOCOLS
]
&&
!
info
->
attrs
[
NFC_ATTR_PROTOCOLS
])
&&
!
info
->
attrs
[
NFC_ATTR_TM_PROTOCOLS
]))
return
-
EINVAL
;
idx
=
nla_get_u32
(
info
->
attrs
[
NFC_ATTR_DEVICE_INDEX
]);
protocols
=
nla_get_u32
(
info
->
attrs
[
NFC_ATTR_PROTOCOLS
]);
if
(
info
->
attrs
[
NFC_ATTR_TM_PROTOCOLS
])
tm_protocols
=
nla_get_u32
(
info
->
attrs
[
NFC_ATTR_TM_PROTOCOLS
]);
if
(
info
->
attrs
[
NFC_ATTR_IM_PROTOCOLS
])
im_protocols
=
nla_get_u32
(
info
->
attrs
[
NFC_ATTR_IM_PROTOCOLS
]);
else
if
(
info
->
attrs
[
NFC_ATTR_PROTOCOLS
])
im_protocols
=
nla_get_u32
(
info
->
attrs
[
NFC_ATTR_PROTOCOLS
]);
dev
=
nfc_get_device
(
idx
);
if
(
!
dev
)
...
...
@@ -536,7 +609,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
mutex_lock
(
&
dev
->
genl_data
.
genl_data_mutex
);
rc
=
nfc_start_poll
(
dev
,
protocols
);
rc
=
nfc_start_poll
(
dev
,
im_protocols
,
tm_
protocols
);
if
(
!
rc
)
dev
->
genl_data
.
poll_req_pid
=
info
->
snd_pid
;
...
...
net/nfc/nfc.h
View file @
2e486868
...
...
@@ -55,6 +55,7 @@ int nfc_llcp_register_device(struct nfc_dev *dev);
void
nfc_llcp_unregister_device
(
struct
nfc_dev
*
dev
);
int
nfc_llcp_set_remote_gb
(
struct
nfc_dev
*
dev
,
u8
*
gb
,
u8
gb_len
);
u8
*
nfc_llcp_general_bytes
(
struct
nfc_dev
*
dev
,
size_t
*
general_bytes_len
);
int
nfc_llcp_data_received
(
struct
nfc_dev
*
dev
,
struct
sk_buff
*
skb
);
int
__init
nfc_llcp_init
(
void
);
void
nfc_llcp_exit
(
void
);
...
...
@@ -90,6 +91,12 @@ static inline u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *gb_len)
return
NULL
;
}
static
inline
int
nfc_llcp_data_received
(
struct
nfc_dev
*
dev
,
struct
sk_buff
*
skb
)
{
return
0
;
}
static
inline
int
nfc_llcp_init
(
void
)
{
return
0
;
...
...
@@ -128,6 +135,9 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
u8
comm_mode
,
u8
rf_mode
);
int
nfc_genl_dep_link_down_event
(
struct
nfc_dev
*
dev
);
int
nfc_genl_tm_activated
(
struct
nfc_dev
*
dev
,
u32
protocol
);
int
nfc_genl_tm_deactivated
(
struct
nfc_dev
*
dev
);
struct
nfc_dev
*
nfc_get_device
(
unsigned
int
idx
);
static
inline
void
nfc_put_device
(
struct
nfc_dev
*
dev
)
...
...
@@ -158,7 +168,7 @@ int nfc_dev_up(struct nfc_dev *dev);
int
nfc_dev_down
(
struct
nfc_dev
*
dev
);
int
nfc_start_poll
(
struct
nfc_dev
*
dev
,
u32
protocols
);
int
nfc_start_poll
(
struct
nfc_dev
*
dev
,
u32
im_protocols
,
u32
tm_
protocols
);
int
nfc_stop_poll
(
struct
nfc_dev
*
dev
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment