Linux wireless drivers development
 help / color / mirror / Atom feed
From: Samuel Ortiz <samuel@sortiz.org>
To: "Elias, Ilan" <ilane@ti.com>
Cc: "aloisio.almeida@openbossa.org" <aloisio.almeida@openbossa.org>,
	"lauro.venancio@openbossa.org" <lauro.venancio@openbossa.org>,
	"linville@tuxdriver.com" <linville@tuxdriver.com>,
	"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Subject: Re: [PATCH 3/4] NFC: Basic NFC NCI protocol implementation
Date: Thu, 18 Aug 2011 18:13:20 +0200	[thread overview]
Message-ID: <1313684000.3345.21.camel@sortiz-mobl> (raw)
In-Reply-To: <AC090B9732AB2B4DB7FF476E907FE6600131E1C33B@dnce02.ent.ti.com>

Hi Ilan,

On Tue, 2011-08-16 at 19:36 +0200, Elias, Ilan wrote:
> The NFC Controller Interface (NCI) is a standard communication protocol between an NFC Controller (NFCC) and a Device Host (DH), defined by the NFC Forum.
> 
> Signed-off-by: Ilan Elias <ilane@ti.com>
> ---
>  include/net/nfc/nci.h      |  313 ++++++++++++++++++
>  include/net/nfc/nci_core.h |  177 +++++++++++
>  net/nfc/Kconfig            |    2 +
>  net/nfc/Makefile           |    1 +
>  net/nfc/nci/Kconfig        |   10 +
>  net/nfc/nci/Makefile       |    7 +
>  net/nfc/nci/nci_core.c     |  750 ++++++++++++++++++++++++++++++++++++++++++++
>  net/nfc/nci/nci_data.c     |  252 +++++++++++++++
>  net/nfc/nci/nci_lib.c      |   94 ++++++
>  net/nfc/nci/nci_ntf.c      |  264 ++++++++++++++++
>  net/nfc/nci/nci_rsp.c      |  226 +++++++++++++
>  11 files changed, 2096 insertions(+), 0 deletions(-)
>  create mode 100644 include/net/nfc/nci.h
>  create mode 100644 include/net/nfc/nci_core.h
>  create mode 100644 net/nfc/nci/Kconfig
>  create mode 100644 net/nfc/nci/Makefile
>  create mode 100644 net/nfc/nci/nci_core.c
>  create mode 100644 net/nfc/nci/nci_data.c
>  create mode 100644 net/nfc/nci/nci_lib.c
>  create mode 100644 net/nfc/nci/nci_ntf.c
>  create mode 100644 net/nfc/nci/nci_rsp.c
In general, I prefer the nci/core.c, nci/data.c, etc naming scheme as opposed to the more redundant one you're using here.

> +/* NCI Discovery Types */
> +#define NCI_DISCOVERY_TYPE_POLL_A_PASSIVE              0x00
Identation fix.


> +#define        NCI_DISCOVERY_TYPE_POLL_B_PASSIVE               0x01
> +#define        NCI_DISCOVERY_TYPE_POLL_F_PASSIVE               0x02
> +#define        NCI_DISCOVERY_TYPE_POLL_A_ACTIVE                0x03
> +#define        NCI_DISCOVERY_TYPE_POLL_F_ACTIVE                0x05
> +#define        NCI_DISCOVERY_TYPE_WAKEUP_A_PASSIVE             0x06
> +#define        NCI_DISCOVERY_TYPE_WAKEUP_B_PASSIVE             0x07
> +#define        NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE              0x09
> +#define        NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE             0x80
> +#define        NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE             0x81
> +#define        NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE             0x82
> +#define        NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE              0x83
> +#define        NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE              0x85

> +#define NCI_MT_DATA_PKT                        0x00
Ditto.

> +#define NCI_MT_CMD_PKT                  0x01
> +#define NCI_MT_RSP_PKT                 0x02
> +#define NCI_MT_NTF_PKT                 0x03

> +/* Reserved for drivers usage */
> +#define NCI_SKB_RESERVE        4
Do we expect all drivers to need at most 4 bytes ?

> +#define nci_req_lock(ndev)             mutex_lock(&ndev->req_lock)
> +#define nci_req_unlock(ndev)           mutex_unlock(&ndev->req_lock)
This kind of abstraction doesn't bring much to the table. I'd prefer to
use the mutex API directly.



> +/* Execute request and wait for completion. */
> +static int __nci_request(struct nci_dev *ndev,
> +       void (*req)(struct nci_dev *ndev, unsigned long opt),
> +       unsigned long opt,
> +       __u32 timeout)
> +{
> +       DECLARE_WAITQUEUE(wait, current);
> +       int rc = 0;
> +
> +       ndev->req_status = NCI_REQ_PEND;
> +
> +       add_wait_queue(&ndev->req_wait_q, &wait);
> +       set_current_state(TASK_INTERRUPTIBLE);
> +
> +       req(ndev, opt);
> +       schedule_timeout(timeout);
> +
> +       remove_wait_queue(&ndev->req_wait_q, &wait);
> +
> +       if (signal_pending(current))
> +               return -EINTR;
> +
> +       switch (ndev->req_status) {
> +       case NCI_REQ_DONE:
> +               rc = nci_to_errno(ndev->req_result);
> +               break;
> +
> +       case NCI_REQ_CANCELED:
> +               rc = -ndev->req_result;
> +               break;
> +
> +       default:
> +               rc = -ETIMEDOUT;
> +               break;
> +       }
> +
> +       ndev->req_status = ndev->req_result = 0;
> +
> +       return rc;
> +}
So here, I wonder: Can't we just use simple completion and the
wait_for_completion_* APIs ? One completion structure per ndev and you
should be fine. Especially since you seem to be serializing (as
expected) the requests below.


> +/* Send NCI command */
> +int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload)
> +{
> +       struct nci_ctrl_hdr *hdr;
> +       struct sk_buff *skb;
> +
> +       nfc_dbg("entry, opcode 0x%x, plen %d", opcode, plen);
> +
> +       skb = nci_skb_alloc((NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL);
> +       if (!skb) {
> +               nfc_err("no memory for command");
> +               return -ENOMEM;
> +       }
> +
> +       hdr = (struct nci_ctrl_hdr *) skb_put(skb, NCI_CTRL_HDR_SIZE);
> +       hdr->gid = nci_opcode_gid(opcode);
> +       hdr->oid = nci_opcode_oid(opcode);
> +       hdr->plen = plen;
> +
> +       nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT);
> +       nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST);
> +
> +       if (plen)
> +               memcpy(skb_put(skb, plen), payload, plen);
> +
> +       skb->dev = (void *) ndev;
> +
> +       skb_queue_tail(&ndev->cmd_q, skb);
> +       tasklet_schedule(&ndev->cmd_task);
> +
> +       return 0;
> +}
So I have 2 comments on this one:

1) Do we have a compelling reason for deferring the command queue
handling ? In which case can you queue a command while the previous one
is not completed yet ?
2) If we do, we certainly don't want a tasklet for that. Using a tasklet
puts some additional constraints on what we can call for it, the
tradeoff being a supposedly lower latency. I don't think we need it,
workqueues (for cmd, tx and rx) would be just fine.




> +/* Send NCI data */
> +int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb)
> +{
> +       int rc = 0;
> +
> +       nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len);
> +
> +       /* check if the packet need to be fragmented */
> +       if (skb->len <= ndev->max_pkt_payload_size) {
> +               /* no need to fragment packet */
> +
> +               /* reserve header space for nci and driver */
> +               if (skb_cow_head(skb, (NCI_DATA_HDR_SIZE + NCI_SKB_RESERVE))) {
I think this kind of reallocations could be avoided with a couple
patches that I will post soon. We could basically tell the NFC core in
advance which head room we need.
See
http://git.kernel.org/?p=linux/kernel/git/sameo/nfc-2.6.git;a=commit;h=ba108daaec65f5d02daaf9084fa5f8f2375d0d92

Cheers,
Samuel.


  reply	other threads:[~2011-08-18 16:11 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-16 17:36 [PATCH 3/4] NFC: Basic NFC NCI protocol implementation Elias, Ilan
2011-08-18 16:13 ` Samuel Ortiz [this message]
2011-09-08  8:26   ` Elias, Ilan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1313684000.3345.21.camel@sortiz-mobl \
    --to=samuel@sortiz.org \
    --cc=aloisio.almeida@openbossa.org \
    --cc=ilane@ti.com \
    --cc=lauro.venancio@openbossa.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox