Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4bf98b2 authored by Ilan Elias's avatar Ilan Elias Committed by John W. Linville
Browse files

NFC: Add NCI data exchange timer



Add NCI data exchange timer to catch timeouts,
and call the data exchange callback with an error.

Signed-off-by: default avatarIlan Elias <ilane@ti.com>
Acked-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 889cbb91
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ enum {
	NCI_DISCOVERY,
	NCI_POLL_ACTIVE,
	NCI_DATA_EXCHANGE,
	NCI_DATA_EXCHANGE_TO,
};

/* NCI timeouts */
@@ -49,6 +50,7 @@ enum {
#define NCI_RF_DISC_TIMEOUT			5000
#define NCI_RF_DEACTIVATE_TIMEOUT		30000
#define NCI_CMD_TIMEOUT				5000
#define NCI_DATA_TIMEOUT			700

struct nci_dev;

@@ -74,6 +76,7 @@ struct nci_dev {
	atomic_t		credits_cnt;

	struct timer_list	cmd_timer;
	struct timer_list	data_timer;

	struct workqueue_struct	*cmd_wq;
	struct work_struct	cmd_work;
+24 −0
Original line number Diff line number Diff line
@@ -286,6 +286,7 @@ static int nci_close_device(struct nci_dev *ndev)

	if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
		del_timer_sync(&ndev->cmd_timer);
		del_timer_sync(&ndev->data_timer);
		mutex_unlock(&ndev->req_lock);
		return 0;
	}
@@ -331,6 +332,15 @@ static void nci_cmd_timer(unsigned long arg)
	queue_work(ndev->cmd_wq, &ndev->cmd_work);
}

/* NCI data exchange timer function */
static void nci_data_timer(unsigned long arg)
{
	struct nci_dev *ndev = (void *) arg;

	set_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
	queue_work(ndev->rx_wq, &ndev->rx_work);
}

static int nci_dev_up(struct nfc_dev *nfc_dev)
{
	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
@@ -585,6 +595,8 @@ int nci_register_device(struct nci_dev *ndev)

	setup_timer(&ndev->cmd_timer, nci_cmd_timer,
			(unsigned long) ndev);
	setup_timer(&ndev->data_timer, nci_data_timer,
			(unsigned long) ndev);

	mutex_init(&ndev->req_lock);

@@ -722,6 +734,9 @@ static void nci_tx_work(struct work_struct *work)
			 nci_plen(skb->data));

		nci_send_frame(skb);

		mod_timer(&ndev->data_timer,
			jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
	}
}

@@ -753,6 +768,15 @@ static void nci_rx_work(struct work_struct *work)
			break;
		}
	}

	/* check if a data exchange timout has occurred */
	if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) {
		/* complete the data exchange transaction, if exists */
		if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
			nci_data_exchange_complete(ndev, NULL, -ETIMEDOUT);

		clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
	}
}

/* ----- NCI TX CMD worker thread ----- */
+4 −0
Original line number Diff line number Diff line
@@ -44,6 +44,10 @@ void nci_data_exchange_complete(struct nci_dev *ndev,

	pr_debug("len %d, err %d\n", skb ? skb->len : 0, err);

	/* data exchange is complete, stop the data timer */
	del_timer_sync(&ndev->data_timer);
	clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);

	if (cb) {
		ndev->data_exchange_cb = NULL;
		ndev->data_exchange_cb_context = 0;