Skip to content

Commit

Permalink
Merge tag 'nfc-next-3.6-1' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/sameo/nfc-3.0
  • Loading branch information
John W. Linville committed Jun 11, 2012
2 parents 934b9d1 + 51ad304 commit 2e48686
Show file tree
Hide file tree
Showing 16 changed files with 1,106 additions and 392 deletions.
662 changes: 543 additions & 119 deletions drivers/nfc/pn533.c

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions drivers/nfc/pn544_hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,15 +576,17 @@ 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;
int r;
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);
Expand All @@ -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 */
}
Expand Down
12 changes: 12 additions & 0 deletions include/linux/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
};
Expand All @@ -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,
Expand All @@ -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
};
Expand All @@ -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
Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion include/net/nfc/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 11 additions & 3 deletions include/net/nfc/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -62,9 +63,10 @@ struct nfc_ops {
u32 protocol);
void (*deactivate_target)(struct nfc_dev *dev,
struct nfc_target *target);
int (*data_exchange)(struct nfc_dev *dev, struct nfc_target *target,
int (*im_transceive)(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);
};

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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 */
3 changes: 2 additions & 1 deletion include/net/nfc/shdlc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
119 changes: 89 additions & 30 deletions net/nfc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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 +
Expand Down Expand Up @@ -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);
Expand All @@ -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
*
Expand Down Expand Up @@ -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_exchange)
!ops->deactivate_target || !ops->im_transceive)
return NULL;

if (!supported_protocols)
Expand Down
13 changes: 7 additions & 6 deletions net/nfc/hci/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -511,9 +512,9 @@ static void hci_deactivate_target(struct nfc_dev *nfc_dev,
{
}

static int hci_data_exchange(struct nfc_dev *nfc_dev, struct nfc_target *target,
struct sk_buff *skb, data_exchange_cb_t cb,
void *cb_context)
static int hci_transceive(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;
Expand Down Expand Up @@ -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_exchange,
.im_transceive = hci_transceive,
.check_presence = hci_check_presence,
};

Expand Down
Loading

0 comments on commit 2e48686

Please sign in to comment.