lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20200316230537.GQ144492@google.com>
Date:   Mon, 16 Mar 2020 16:05:37 -0700
From:   Matthias Kaehlcke <mka@...omium.org>
To:     Marcel Holtmann <marcel@...tmann.org>,
        Johan Hedberg <johan.hedberg@...il.com>
Cc:     Harish Bandi <c-hbandi@...eaurora.org>,
        Balakrishna Godavarthi <bgodavar@...eaurora.org>,
        Abhishek Pandit-Subedi <abhishekpandit@...omium.org>,
        Venkata Lakshmi Narayana Gubba <gubbaven@...eaurora.org>,
        Rocky Liao <rjliao@...eaurora.org>,
        linux-bluetooth@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 1/2] WIP: Bluetooth: hci_qca: consolidate IBS fields in a
 struct

On Mon, Mar 16, 2020 at 04:02:32PM -0700, Matthias Kaehlcke wrote:

> Subject: WIP: Bluetooth: hci_qca: consolidate IBS fields in a struct

The WIP prefix wasn't intended, I'll remove it in the next version.

> About two thirds of the fields in 'struct qca_data' are related with
> in band sleep (IBS). Move these fields to a dedicated IBS struct which
> is part of 'struct qca_data'. Also congregate the IBS stats fields for
> debugfs in a separate sub-struct.
> 
> Signed-off-by: Matthias Kaehlcke <mka@...omium.org>
> ---
> 
>  drivers/bluetooth/hci_qca.c | 362 +++++++++++++++++++-----------------
>  1 file changed, 191 insertions(+), 171 deletions(-)
> 
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 3abf4e68de7a8c..c578c7c92680a6 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -125,51 +125,60 @@ struct qca_dump_size {
>  	u32 dump_size;
>  } __packed;
>  
> -struct qca_data {
> -	struct hci_uart *hu;
> -	struct sk_buff *rx_skb;
> -	struct sk_buff_head txq;
> +struct qca_ibs_stats {
> +	/* For debugging purpose */
> +	u64 sent_wacks;
> +	u64 sent_slps;
> +	u64 sent_wakes;
> +	u64 recv_wacks;
> +	u64 recv_slps;
> +	u64 recv_wakes;
> +	u64 vote_last_jif;
> +	u32 vote_on_ms;
> +	u32 vote_off_ms;
> +	u64 tx_votes_on;
> +	u64 rx_votes_on;
> +	u64 tx_votes_off;
> +	u64 rx_votes_off;
> +	u64 votes_on;
> +	u64 votes_off;
> +};
> +
> +struct qca_ibs {
>  	struct sk_buff_head tx_wait_q;	/* HCI_IBS wait queue	*/
> -	struct sk_buff_head rx_memdump_q;	/* Memdump wait queue	*/
> -	spinlock_t hci_ibs_lock;	/* HCI_IBS state lock	*/
> -	u8 tx_ibs_state;	/* HCI_IBS transmit side power state*/
> -	u8 rx_ibs_state;	/* HCI_IBS receive side power state */
> +	spinlock_t lock;	/* HCI_IBS state lock	*/
> +	u8 tx_state;		/* HCI_IBS transmit side power state*/
> +	u8 rx_state;		/* HCI_IBS receive side power state */
>  	bool tx_vote;		/* Clock must be on for TX */
>  	bool rx_vote;		/* Clock must be on for RX */
>  	struct timer_list tx_idle_timer;
>  	u32 tx_idle_delay;
>  	struct timer_list wake_retrans_timer;
>  	u32 wake_retrans;
> -	struct workqueue_struct *workqueue;
> +
>  	struct work_struct ws_awake_rx;
>  	struct work_struct ws_awake_device;
>  	struct work_struct ws_rx_vote_off;
>  	struct work_struct ws_tx_vote_off;
> +
> +	struct qca_ibs_stats stats;
> +};
> +
> +struct qca_data {
> +	struct hci_uart *hu;
> +	struct sk_buff *rx_skb;
> +	struct sk_buff_head txq;
> +	struct sk_buff_head rx_memdump_q;	/* Memdump wait queue	*/
> +	struct workqueue_struct *workqueue;
>  	struct work_struct ctrl_memdump_evt;
>  	struct delayed_work ctrl_memdump_timeout;
>  	struct qca_memdump_data *qca_memdump;
> +	struct qca_ibs ibs;
>  	unsigned long flags;
>  	struct completion drop_ev_comp;
>  	wait_queue_head_t suspend_wait_q;
>  	enum qca_memdump_states memdump_state;
>  	struct mutex hci_memdump_lock;
> -
> -	/* For debugging purpose */
> -	u64 ibs_sent_wacks;
> -	u64 ibs_sent_slps;
> -	u64 ibs_sent_wakes;
> -	u64 ibs_recv_wacks;
> -	u64 ibs_recv_slps;
> -	u64 ibs_recv_wakes;
> -	u64 vote_last_jif;
> -	u32 vote_on_ms;
> -	u32 vote_off_ms;
> -	u64 tx_votes_on;
> -	u64 rx_votes_on;
> -	u64 tx_votes_off;
> -	u64 rx_votes_off;
> -	u64 votes_on;
> -	u64 votes_off;
>  };
>  
>  enum qca_speed_type {
> @@ -267,41 +276,41 @@ static void serial_clock_vote(unsigned long vote, struct hci_uart *hu)
>  	struct qca_data *qca = hu->priv;
>  	unsigned int diff;
>  
> -	bool old_vote = (qca->tx_vote | qca->rx_vote);
> +	bool old_vote = (qca->ibs.tx_vote | qca->ibs.rx_vote);
>  	bool new_vote;
>  
>  	switch (vote) {
>  	case HCI_IBS_VOTE_STATS_UPDATE:
> -		diff = jiffies_to_msecs(jiffies - qca->vote_last_jif);
> +		diff = jiffies_to_msecs(jiffies - qca->ibs.stats.vote_last_jif);
>  
>  		if (old_vote)
> -			qca->vote_off_ms += diff;
> +			qca->ibs.stats.vote_off_ms += diff;
>  		else
> -			qca->vote_on_ms += diff;
> +			qca->ibs.stats.vote_on_ms += diff;
>  		return;
>  
>  	case HCI_IBS_TX_VOTE_CLOCK_ON:
> -		qca->tx_vote = true;
> -		qca->tx_votes_on++;
> +		qca->ibs.tx_vote = true;
> +		qca->ibs.stats.tx_votes_on++;
>  		new_vote = true;
>  		break;
>  
>  	case HCI_IBS_RX_VOTE_CLOCK_ON:
> -		qca->rx_vote = true;
> -		qca->rx_votes_on++;
> +		qca->ibs.rx_vote = true;
> +		qca->ibs.stats.rx_votes_on++;
>  		new_vote = true;
>  		break;
>  
>  	case HCI_IBS_TX_VOTE_CLOCK_OFF:
> -		qca->tx_vote = false;
> -		qca->tx_votes_off++;
> -		new_vote = qca->rx_vote | qca->tx_vote;
> +		qca->ibs.tx_vote = false;
> +		qca->ibs.stats.tx_votes_off++;
> +		new_vote = qca->ibs.rx_vote | qca->ibs.tx_vote;
>  		break;
>  
>  	case HCI_IBS_RX_VOTE_CLOCK_OFF:
> -		qca->rx_vote = false;
> -		qca->rx_votes_off++;
> -		new_vote = qca->rx_vote | qca->tx_vote;
> +		qca->ibs.rx_vote = false;
> +		qca->ibs.stats.rx_votes_off++;
> +		new_vote = qca->ibs.rx_vote | qca->ibs.tx_vote;
>  		break;
>  
>  	default:
> @@ -318,16 +327,16 @@ static void serial_clock_vote(unsigned long vote, struct hci_uart *hu)
>  		BT_DBG("Vote serial clock %s(%s)", new_vote ? "true" : "false",
>  		       vote ? "true" : "false");
>  
> -		diff = jiffies_to_msecs(jiffies - qca->vote_last_jif);
> +		diff = jiffies_to_msecs(jiffies - qca->ibs.stats.vote_last_jif);
>  
>  		if (new_vote) {
> -			qca->votes_on++;
> -			qca->vote_off_ms += diff;
> +			qca->ibs.stats.votes_on++;
> +			qca->ibs.stats.vote_off_ms += diff;
>  		} else {
> -			qca->votes_off++;
> -			qca->vote_on_ms += diff;
> +			qca->ibs.stats.votes_off++;
> +			qca->ibs.stats.vote_on_ms += diff;
>  		}
> -		qca->vote_last_jif = jiffies;
> +		qca->ibs.stats.vote_last_jif = jiffies;
>  	}
>  }
>  
> @@ -359,7 +368,7 @@ static int send_hci_ibs_cmd(u8 cmd, struct hci_uart *hu)
>  static void qca_wq_awake_device(struct work_struct *work)
>  {
>  	struct qca_data *qca = container_of(work, struct qca_data,
> -					    ws_awake_device);
> +					    ibs.ws_awake_device);
>  	struct hci_uart *hu = qca->hu;
>  	unsigned long retrans_delay;
>  	unsigned long flags;
> @@ -369,19 +378,19 @@ static void qca_wq_awake_device(struct work_struct *work)
>  	/* Vote for serial clock */
>  	serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);
>  
> -	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
> +	spin_lock_irqsave(&qca->ibs.lock, flags);
>  
>  	/* Send wake indication to device */
>  	if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
>  		BT_ERR("Failed to send WAKE to device");
>  
> -	qca->ibs_sent_wakes++;
> +	qca->ibs.stats.sent_wakes++;
>  
>  	/* Start retransmit timer */
> -	retrans_delay = msecs_to_jiffies(qca->wake_retrans);
> -	mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);
> +	retrans_delay = msecs_to_jiffies(qca->ibs.wake_retrans);
> +	mod_timer(&qca->ibs.wake_retrans_timer, jiffies + retrans_delay);
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	/* Actually send the packets */
>  	hci_uart_tx_wakeup(hu);
> @@ -390,7 +399,7 @@ static void qca_wq_awake_device(struct work_struct *work)
>  static void qca_wq_awake_rx(struct work_struct *work)
>  {
>  	struct qca_data *qca = container_of(work, struct qca_data,
> -					    ws_awake_rx);
> +					    ibs.ws_awake_rx);
>  	struct hci_uart *hu = qca->hu;
>  	unsigned long flags;
>  
> @@ -398,8 +407,8 @@ static void qca_wq_awake_rx(struct work_struct *work)
>  
>  	serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
>  
> -	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
> -	qca->rx_ibs_state = HCI_IBS_RX_AWAKE;
> +	spin_lock_irqsave(&qca->ibs.lock, flags);
> +	qca->ibs.rx_state = HCI_IBS_RX_AWAKE;
>  
>  	/* Always acknowledge device wake up,
>  	 * sending IBS message doesn't count as TX ON.
> @@ -407,9 +416,9 @@ static void qca_wq_awake_rx(struct work_struct *work)
>  	if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0)
>  		BT_ERR("Failed to acknowledge device wake up");
>  
> -	qca->ibs_sent_wacks++;
> +	qca->ibs.stats.sent_wacks++;
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	/* Actually send the packets */
>  	hci_uart_tx_wakeup(hu);
> @@ -418,7 +427,7 @@ static void qca_wq_awake_rx(struct work_struct *work)
>  static void qca_wq_serial_rx_clock_vote_off(struct work_struct *work)
>  {
>  	struct qca_data *qca = container_of(work, struct qca_data,
> -					    ws_rx_vote_off);
> +					    ibs.ws_rx_vote_off);
>  	struct hci_uart *hu = qca->hu;
>  
>  	BT_DBG("hu %p rx clock vote off", hu);
> @@ -429,7 +438,7 @@ static void qca_wq_serial_rx_clock_vote_off(struct work_struct *work)
>  static void qca_wq_serial_tx_clock_vote_off(struct work_struct *work)
>  {
>  	struct qca_data *qca = container_of(work, struct qca_data,
> -					    ws_tx_vote_off);
> +					    ibs.ws_tx_vote_off);
>  	struct hci_uart *hu = qca->hu;
>  
>  	BT_DBG("hu %p tx clock vote off", hu);
> @@ -445,25 +454,25 @@ static void qca_wq_serial_tx_clock_vote_off(struct work_struct *work)
>  
>  static void hci_ibs_tx_idle_timeout(struct timer_list *t)
>  {
> -	struct qca_data *qca = from_timer(qca, t, tx_idle_timer);
> +	struct qca_data *qca = from_timer(qca, t, ibs.tx_idle_timer);
>  	struct hci_uart *hu = qca->hu;
>  	unsigned long flags;
>  
> -	BT_DBG("hu %p idle timeout in %d state", hu, qca->tx_ibs_state);
> +	BT_DBG("hu %p idle timeout in %d state", hu, qca->ibs.tx_state);
>  
> -	spin_lock_irqsave_nested(&qca->hci_ibs_lock,
> +	spin_lock_irqsave_nested(&qca->ibs.lock,
>  				 flags, SINGLE_DEPTH_NESTING);
>  
> -	switch (qca->tx_ibs_state) {
> +	switch (qca->ibs.tx_state) {
>  	case HCI_IBS_TX_AWAKE:
>  		/* TX_IDLE, go to SLEEP */
>  		if (send_hci_ibs_cmd(HCI_IBS_SLEEP_IND, hu) < 0) {
>  			BT_ERR("Failed to send SLEEP to device");
>  			break;
>  		}
> -		qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
> -		qca->ibs_sent_slps++;
> -		queue_work(qca->workqueue, &qca->ws_tx_vote_off);
> +		qca->ibs.tx_state = HCI_IBS_TX_ASLEEP;
> +		qca->ibs.stats.sent_slps++;
> +		queue_work(qca->workqueue, &qca->ibs.ws_tx_vote_off);
>  		break;
>  
>  	case HCI_IBS_TX_ASLEEP:
> @@ -471,33 +480,33 @@ static void hci_ibs_tx_idle_timeout(struct timer_list *t)
>  		/* Fall through */
>  
>  	default:
> -		BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
> +		BT_ERR("Spurious timeout tx state %d", qca->ibs.tx_state);
>  		break;
>  	}
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  }
>  
>  static void hci_ibs_wake_retrans_timeout(struct timer_list *t)
>  {
> -	struct qca_data *qca = from_timer(qca, t, wake_retrans_timer);
> +	struct qca_data *qca = from_timer(qca, t, ibs.wake_retrans_timer);
>  	struct hci_uart *hu = qca->hu;
>  	unsigned long flags, retrans_delay;
>  	bool retransmit = false;
>  
>  	BT_DBG("hu %p wake retransmit timeout in %d state",
> -		hu, qca->tx_ibs_state);
> +		hu, qca->ibs.tx_state);
>  
> -	spin_lock_irqsave_nested(&qca->hci_ibs_lock,
> +	spin_lock_irqsave_nested(&qca->ibs.lock,
>  				 flags, SINGLE_DEPTH_NESTING);
>  
>  	/* Don't retransmit the HCI_IBS_WAKE_IND when suspending. */
>  	if (test_bit(QCA_SUSPENDING, &qca->flags)) {
> -		spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +		spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  		return;
>  	}
>  
> -	switch (qca->tx_ibs_state) {
> +	switch (qca->ibs.tx_state) {
>  	case HCI_IBS_TX_WAKING:
>  		/* No WAKE_ACK, retransmit WAKE */
>  		retransmit = true;
> @@ -505,9 +514,10 @@ static void hci_ibs_wake_retrans_timeout(struct timer_list *t)
>  			BT_ERR("Failed to acknowledge device wake up");
>  			break;
>  		}
> -		qca->ibs_sent_wakes++;
> -		retrans_delay = msecs_to_jiffies(qca->wake_retrans);
> -		mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);
> +		qca->ibs.stats.sent_wakes++;
> +		retrans_delay = msecs_to_jiffies(qca->ibs.wake_retrans);
> +		mod_timer(&qca->ibs.wake_retrans_timer,
> +			  jiffies + retrans_delay);
>  		break;
>  
>  	case HCI_IBS_TX_ASLEEP:
> @@ -515,11 +525,11 @@ static void hci_ibs_wake_retrans_timeout(struct timer_list *t)
>  		/* Fall through */
>  
>  	default:
> -		BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
> +		BT_ERR("Spurious timeout tx state %d", qca->ibs.tx_state);
>  		break;
>  	}
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	if (retransmit)
>  		hci_uart_tx_wakeup(hu);
> @@ -563,9 +573,9 @@ static int qca_open(struct hci_uart *hu)
>  		return -ENOMEM;
>  
>  	skb_queue_head_init(&qca->txq);
> -	skb_queue_head_init(&qca->tx_wait_q);
> +	skb_queue_head_init(&qca->ibs.tx_wait_q);
>  	skb_queue_head_init(&qca->rx_memdump_q);
> -	spin_lock_init(&qca->hci_ibs_lock);
> +	spin_lock_init(&qca->ibs.lock);
>  	mutex_init(&qca->hci_memdump_lock);
>  	qca->workqueue = alloc_ordered_workqueue("qca_wq", 0);
>  	if (!qca->workqueue) {
> @@ -574,10 +584,10 @@ static int qca_open(struct hci_uart *hu)
>  		return -ENOMEM;
>  	}
>  
> -	INIT_WORK(&qca->ws_awake_rx, qca_wq_awake_rx);
> -	INIT_WORK(&qca->ws_awake_device, qca_wq_awake_device);
> -	INIT_WORK(&qca->ws_rx_vote_off, qca_wq_serial_rx_clock_vote_off);
> -	INIT_WORK(&qca->ws_tx_vote_off, qca_wq_serial_tx_clock_vote_off);
> +	INIT_WORK(&qca->ibs.ws_awake_rx, qca_wq_awake_rx);
> +	INIT_WORK(&qca->ibs.ws_awake_device, qca_wq_awake_device);
> +	INIT_WORK(&qca->ibs.ws_rx_vote_off, qca_wq_serial_rx_clock_vote_off);
> +	INIT_WORK(&qca->ibs.ws_tx_vote_off, qca_wq_serial_tx_clock_vote_off);
>  	INIT_WORK(&qca->ctrl_memdump_evt, qca_controller_memdump);
>  	INIT_DELAYED_WORK(&qca->ctrl_memdump_timeout,
>  			  qca_controller_memdump_timeout);
> @@ -587,10 +597,10 @@ static int qca_open(struct hci_uart *hu)
>  	init_completion(&qca->drop_ev_comp);
>  
>  	/* Assume we start with both sides asleep -- extra wakes OK */
> -	qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
> -	qca->rx_ibs_state = HCI_IBS_RX_ASLEEP;
> +	qca->ibs.tx_state = HCI_IBS_TX_ASLEEP;
> +	qca->ibs.rx_state = HCI_IBS_RX_ASLEEP;
>  
> -	qca->vote_last_jif = jiffies;
> +	qca->ibs.stats.vote_last_jif = jiffies;
>  
>  	hu->priv = qca;
>  
> @@ -602,14 +612,15 @@ static int qca_open(struct hci_uart *hu)
>  		}
>  	}
>  
> -	timer_setup(&qca->wake_retrans_timer, hci_ibs_wake_retrans_timeout, 0);
> -	qca->wake_retrans = IBS_WAKE_RETRANS_TIMEOUT_MS;
> +	timer_setup(&qca->ibs.wake_retrans_timer, hci_ibs_wake_retrans_timeout,
> +		    0);
> +	qca->ibs.wake_retrans = IBS_WAKE_RETRANS_TIMEOUT_MS;
>  
> -	timer_setup(&qca->tx_idle_timer, hci_ibs_tx_idle_timeout, 0);
> -	qca->tx_idle_delay = IBS_HOST_TX_IDLE_TIMEOUT_MS;
> +	timer_setup(&qca->ibs.tx_idle_timer, hci_ibs_tx_idle_timeout, 0);
> +	qca->ibs.tx_idle_delay = IBS_HOST_TX_IDLE_TIMEOUT_MS;
>  
>  	BT_DBG("HCI_UART_QCA open, tx_idle_delay=%u, wake_retrans=%u",
> -	       qca->tx_idle_delay, qca->wake_retrans);
> +	       qca->ibs.tx_idle_delay, qca->ibs.wake_retrans);
>  
>  	return 0;
>  }
> @@ -628,36 +639,45 @@ static void qca_debugfs_init(struct hci_dev *hdev)
>  
>  	/* read only */
>  	mode = S_IRUGO;
> -	debugfs_create_u8("tx_ibs_state", mode, ibs_dir, &qca->tx_ibs_state);
> -	debugfs_create_u8("rx_ibs_state", mode, ibs_dir, &qca->rx_ibs_state);
> +	debugfs_create_u8("tx_ibs_state", mode, ibs_dir, &qca->ibs.tx_state);
> +	debugfs_create_u8("rx_ibs_state", mode, ibs_dir, &qca->ibs.rx_state);
>  	debugfs_create_u64("ibs_sent_sleeps", mode, ibs_dir,
> -			   &qca->ibs_sent_slps);
> +			   &qca->ibs.stats.sent_slps);
>  	debugfs_create_u64("ibs_sent_wakes", mode, ibs_dir,
> -			   &qca->ibs_sent_wakes);
> +			   &qca->ibs.stats.sent_wakes);
>  	debugfs_create_u64("ibs_sent_wake_acks", mode, ibs_dir,
> -			   &qca->ibs_sent_wacks);
> +			   &qca->ibs.stats.sent_wacks);
>  	debugfs_create_u64("ibs_recv_sleeps", mode, ibs_dir,
> -			   &qca->ibs_recv_slps);
> +			   &qca->ibs.stats.recv_slps);
>  	debugfs_create_u64("ibs_recv_wakes", mode, ibs_dir,
> -			   &qca->ibs_recv_wakes);
> +			   &qca->ibs.stats.recv_wakes);
>  	debugfs_create_u64("ibs_recv_wake_acks", mode, ibs_dir,
> -			   &qca->ibs_recv_wacks);
> -	debugfs_create_bool("tx_vote", mode, ibs_dir, &qca->tx_vote);
> -	debugfs_create_u64("tx_votes_on", mode, ibs_dir, &qca->tx_votes_on);
> -	debugfs_create_u64("tx_votes_off", mode, ibs_dir, &qca->tx_votes_off);
> -	debugfs_create_bool("rx_vote", mode, ibs_dir, &qca->rx_vote);
> -	debugfs_create_u64("rx_votes_on", mode, ibs_dir, &qca->rx_votes_on);
> -	debugfs_create_u64("rx_votes_off", mode, ibs_dir, &qca->rx_votes_off);
> -	debugfs_create_u64("votes_on", mode, ibs_dir, &qca->votes_on);
> -	debugfs_create_u64("votes_off", mode, ibs_dir, &qca->votes_off);
> -	debugfs_create_u32("vote_on_ms", mode, ibs_dir, &qca->vote_on_ms);
> -	debugfs_create_u32("vote_off_ms", mode, ibs_dir, &qca->vote_off_ms);
> +			   &qca->ibs.stats.recv_wacks);
> +	debugfs_create_bool("tx_vote", mode, ibs_dir, &qca->ibs.tx_vote);
> +	debugfs_create_u64("tx_votes_on", mode, ibs_dir,
> +			   &qca->ibs.stats.tx_votes_on);
> +	debugfs_create_u64("tx_votes_off", mode, ibs_dir,
> +			   &qca->ibs.stats.tx_votes_off);
> +	debugfs_create_bool("rx_vote", mode, ibs_dir, &qca->ibs.rx_vote);
> +	debugfs_create_u64("rx_votes_on", mode, ibs_dir,
> +			   &qca->ibs.stats.rx_votes_on);
> +	debugfs_create_u64("rx_votes_off", mode, ibs_dir,
> +			   &qca->ibs.stats.rx_votes_off);
> +	debugfs_create_u64("votes_on", mode, ibs_dir,
> +			   &qca->ibs.stats.votes_on);
> +	debugfs_create_u64("votes_off", mode, ibs_dir,
> +			   &qca->ibs.stats.votes_off);
> +	debugfs_create_u32("vote_on_ms", mode, ibs_dir,
> +			   &qca->ibs.stats.vote_on_ms);
> +	debugfs_create_u32("vote_off_ms", mode, ibs_dir,
> +			   &qca->ibs.stats.vote_off_ms);
>  
>  	/* read/write */
>  	mode = S_IRUGO | S_IWUSR;
> -	debugfs_create_u32("wake_retrans", mode, ibs_dir, &qca->wake_retrans);
> +	debugfs_create_u32("wake_retrans", mode, ibs_dir,
> +			   &qca->ibs.wake_retrans);
>  	debugfs_create_u32("tx_idle_delay", mode, ibs_dir,
> -			   &qca->tx_idle_delay);
> +			   &qca->ibs.tx_idle_delay);
>  }
>  
>  /* Flush protocol data */
> @@ -667,7 +687,7 @@ static int qca_flush(struct hci_uart *hu)
>  
>  	BT_DBG("hu %p qca flush", hu);
>  
> -	skb_queue_purge(&qca->tx_wait_q);
> +	skb_queue_purge(&qca->ibs.tx_wait_q);
>  	skb_queue_purge(&qca->txq);
>  
>  	return 0;
> @@ -682,11 +702,11 @@ static int qca_close(struct hci_uart *hu)
>  
>  	serial_clock_vote(HCI_IBS_VOTE_STATS_UPDATE, hu);
>  
> -	skb_queue_purge(&qca->tx_wait_q);
> +	skb_queue_purge(&qca->ibs.tx_wait_q);
>  	skb_queue_purge(&qca->txq);
>  	skb_queue_purge(&qca->rx_memdump_q);
> -	del_timer(&qca->tx_idle_timer);
> -	del_timer(&qca->wake_retrans_timer);
> +	del_timer(&qca->ibs.tx_idle_timer);
> +	del_timer(&qca->ibs.wake_retrans_timer);
>  	destroy_workqueue(qca->workqueue);
>  	qca->hu = NULL;
>  
> @@ -710,23 +730,23 @@ static void device_want_to_wakeup(struct hci_uart *hu)
>  
>  	BT_DBG("hu %p want to wake up", hu);
>  
> -	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
> +	spin_lock_irqsave(&qca->ibs.lock, flags);
>  
> -	qca->ibs_recv_wakes++;
> +	qca->ibs.stats.recv_wakes++;
>  
>  	/* Don't wake the rx up when suspending. */
>  	if (test_bit(QCA_SUSPENDING, &qca->flags)) {
> -		spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +		spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  		return;
>  	}
>  
> -	switch (qca->rx_ibs_state) {
> +	switch (qca->ibs.rx_state) {
>  	case HCI_IBS_RX_ASLEEP:
>  		/* Make sure clock is on - we may have turned clock off since
>  		 * receiving the wake up indicator awake rx clock.
>  		 */
> -		queue_work(qca->workqueue, &qca->ws_awake_rx);
> -		spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +		queue_work(qca->workqueue, &qca->ibs.ws_awake_rx);
> +		spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  		return;
>  
>  	case HCI_IBS_RX_AWAKE:
> @@ -737,17 +757,17 @@ static void device_want_to_wakeup(struct hci_uart *hu)
>  			BT_ERR("Failed to acknowledge device wake up");
>  			break;
>  		}
> -		qca->ibs_sent_wacks++;
> +		qca->ibs.stats.sent_wacks++;
>  		break;
>  
>  	default:
>  		/* Any other state is illegal */
>  		BT_ERR("Received HCI_IBS_WAKE_IND in rx state %d",
> -		       qca->rx_ibs_state);
> +		       qca->ibs.rx_state);
>  		break;
>  	}
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	/* Actually send the packets */
>  	hci_uart_tx_wakeup(hu);
> @@ -760,18 +780,18 @@ static void device_want_to_sleep(struct hci_uart *hu)
>  	unsigned long flags;
>  	struct qca_data *qca = hu->priv;
>  
> -	BT_DBG("hu %p want to sleep in %d state", hu, qca->rx_ibs_state);
> +	BT_DBG("hu %p want to sleep in %d state", hu, qca->ibs.rx_state);
>  
> -	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
> +	spin_lock_irqsave(&qca->ibs.lock, flags);
>  
> -	qca->ibs_recv_slps++;
> +	qca->ibs.stats.recv_slps++;
>  
> -	switch (qca->rx_ibs_state) {
> +	switch (qca->ibs.rx_state) {
>  	case HCI_IBS_RX_AWAKE:
>  		/* Update state */
> -		qca->rx_ibs_state = HCI_IBS_RX_ASLEEP;
> +		qca->ibs.rx_state = HCI_IBS_RX_ASLEEP;
>  		/* Vote off rx clock under workqueue */
> -		queue_work(qca->workqueue, &qca->ws_rx_vote_off);
> +		queue_work(qca->workqueue, &qca->ibs.ws_rx_vote_off);
>  		break;
>  
>  	case HCI_IBS_RX_ASLEEP:
> @@ -780,13 +800,13 @@ static void device_want_to_sleep(struct hci_uart *hu)
>  	default:
>  		/* Any other state is illegal */
>  		BT_ERR("Received HCI_IBS_SLEEP_IND in rx state %d",
> -		       qca->rx_ibs_state);
> +		       qca->ibs.rx_state);
>  		break;
>  	}
>  
>  	wake_up_interruptible(&qca->suspend_wait_q);
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  }
>  
>  /* Called upon wake-up-acknowledgement from the device
> @@ -799,33 +819,33 @@ static void device_woke_up(struct hci_uart *hu)
>  
>  	BT_DBG("hu %p woke up", hu);
>  
> -	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
> +	spin_lock_irqsave(&qca->ibs.lock, flags);
>  
> -	qca->ibs_recv_wacks++;
> +	qca->ibs.stats.recv_wacks++;
>  
>  	/* Don't react to the wake-up-acknowledgment when suspending. */
>  	if (test_bit(QCA_SUSPENDING, &qca->flags)) {
> -		spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +		spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  		return;
>  	}
>  
> -	switch (qca->tx_ibs_state) {
> +	switch (qca->ibs.tx_state) {
>  	case HCI_IBS_TX_AWAKE:
>  		/* Expect one if we send 2 WAKEs */
>  		BT_DBG("Received HCI_IBS_WAKE_ACK in tx state %d",
> -		       qca->tx_ibs_state);
> +		       qca->ibs.tx_state);
>  		break;
>  
>  	case HCI_IBS_TX_WAKING:
>  		/* Send pending packets */
> -		while ((skb = skb_dequeue(&qca->tx_wait_q)))
> +		while ((skb = skb_dequeue(&qca->ibs.tx_wait_q)))
>  			skb_queue_tail(&qca->txq, skb);
>  
>  		/* Switch timers and change state to HCI_IBS_TX_AWAKE */
> -		del_timer(&qca->wake_retrans_timer);
> -		idle_delay = msecs_to_jiffies(qca->tx_idle_delay);
> -		mod_timer(&qca->tx_idle_timer, jiffies + idle_delay);
> -		qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
> +		del_timer(&qca->ibs.wake_retrans_timer);
> +		idle_delay = msecs_to_jiffies(qca->ibs.tx_idle_delay);
> +		mod_timer(&qca->ibs.tx_idle_timer, jiffies + idle_delay);
> +		qca->ibs.tx_state = HCI_IBS_TX_AWAKE;
>  		break;
>  
>  	case HCI_IBS_TX_ASLEEP:
> @@ -833,11 +853,11 @@ static void device_woke_up(struct hci_uart *hu)
>  
>  	default:
>  		BT_ERR("Received HCI_IBS_WAKE_ACK in tx state %d",
> -		       qca->tx_ibs_state);
> +		       qca->ibs.tx_state);
>  		break;
>  	}
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	/* Actually send the packets */
>  	hci_uart_tx_wakeup(hu);
> @@ -852,12 +872,12 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
>  	struct qca_data *qca = hu->priv;
>  
>  	BT_DBG("hu %p qca enq skb %p tx_ibs_state %d", hu, skb,
> -	       qca->tx_ibs_state);
> +	       qca->ibs.tx_state);
>  
>  	/* Prepend skb with frame type */
>  	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
>  
> -	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
> +	spin_lock_irqsave(&qca->ibs.lock, flags);
>  
>  	/* Don't go to sleep in middle of patch download or
>  	 * Out-Of-Band(GPIOs control) sleep is selected.
> @@ -866,43 +886,43 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
>  	if (!test_bit(QCA_IBS_ENABLED, &qca->flags) ||
>  	    test_bit(QCA_SUSPENDING, &qca->flags)) {
>  		skb_queue_tail(&qca->txq, skb);
> -		spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +		spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  		return 0;
>  	}
>  
>  	/* Act according to current state */
> -	switch (qca->tx_ibs_state) {
> +	switch (qca->ibs.tx_state) {
>  	case HCI_IBS_TX_AWAKE:
>  		BT_DBG("Device awake, sending normally");
>  		skb_queue_tail(&qca->txq, skb);
> -		idle_delay = msecs_to_jiffies(qca->tx_idle_delay);
> -		mod_timer(&qca->tx_idle_timer, jiffies + idle_delay);
> +		idle_delay = msecs_to_jiffies(qca->ibs.tx_idle_delay);
> +		mod_timer(&qca->ibs.tx_idle_timer, jiffies + idle_delay);
>  		break;
>  
>  	case HCI_IBS_TX_ASLEEP:
>  		BT_DBG("Device asleep, waking up and queueing packet");
>  		/* Save packet for later */
> -		skb_queue_tail(&qca->tx_wait_q, skb);
> +		skb_queue_tail(&qca->ibs.tx_wait_q, skb);
>  
> -		qca->tx_ibs_state = HCI_IBS_TX_WAKING;
> +		qca->ibs.tx_state = HCI_IBS_TX_WAKING;
>  		/* Schedule a work queue to wake up device */
> -		queue_work(qca->workqueue, &qca->ws_awake_device);
> +		queue_work(qca->workqueue, &qca->ibs.ws_awake_device);
>  		break;
>  
>  	case HCI_IBS_TX_WAKING:
>  		BT_DBG("Device waking up, queueing packet");
>  		/* Transient state; just keep packet for later */
> -		skb_queue_tail(&qca->tx_wait_q, skb);
> +		skb_queue_tail(&qca->ibs.tx_wait_q, skb);
>  		break;
>  
>  	default:
>  		BT_ERR("Illegal tx state: %d (losing packet)",
> -		       qca->tx_ibs_state);
> +		       qca->ibs.tx_state);
>  		kfree_skb(skb);
>  		break;
>  	}
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	return 0;
>  }
> @@ -1732,10 +1752,10 @@ static void qca_power_shutdown(struct hci_uart *hu)
>  	 * still open, stop queueing the IBS data and flush all the buffered
>  	 * data in skb's.
>  	 */
> -	spin_lock_irqsave(&qca->hci_ibs_lock, flags);
> +	spin_lock_irqsave(&qca->ibs.lock, flags);
>  	clear_bit(QCA_IBS_ENABLED, &qca->flags);
>  	qca_flush(hu);
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	hu->hdev->hw_error = NULL;
>  	hu->hdev->cmd_timeout = NULL;
> @@ -1959,18 +1979,18 @@ static int __maybe_unused qca_suspend(struct device *dev)
>  	if (!test_bit(QCA_IBS_ENABLED, &qca->flags))
>  		return 0;
>  
> -	cancel_work_sync(&qca->ws_awake_device);
> -	cancel_work_sync(&qca->ws_awake_rx);
> +	cancel_work_sync(&qca->ibs.ws_awake_device);
> +	cancel_work_sync(&qca->ibs.ws_awake_rx);
>  
> -	spin_lock_irqsave_nested(&qca->hci_ibs_lock,
> +	spin_lock_irqsave_nested(&qca->ibs.lock,
>  				 flags, SINGLE_DEPTH_NESTING);
>  
> -	switch (qca->tx_ibs_state) {
> +	switch (qca->ibs.tx_state) {
>  	case HCI_IBS_TX_WAKING:
> -		del_timer(&qca->wake_retrans_timer);
> +		del_timer(&qca->ibs.wake_retrans_timer);
>  		/* Fall through */
>  	case HCI_IBS_TX_AWAKE:
> -		del_timer(&qca->tx_idle_timer);
> +		del_timer(&qca->ibs.tx_idle_timer);
>  
>  		serdev_device_write_flush(hu->serdev);
>  		cmd = HCI_IBS_SLEEP_IND;
> @@ -1981,22 +2001,22 @@ static int __maybe_unused qca_suspend(struct device *dev)
>  			break;
>  		}
>  
> -		qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
> -		qca->ibs_sent_slps++;
> +		qca->ibs.tx_state = HCI_IBS_TX_ASLEEP;
> +		qca->ibs.stats.sent_slps++;
>  
> -		qca_wq_serial_tx_clock_vote_off(&qca->ws_tx_vote_off);
> +		qca_wq_serial_tx_clock_vote_off(&qca->ibs.ws_tx_vote_off);
>  		break;
>  
>  	case HCI_IBS_TX_ASLEEP:
>  		break;
>  
>  	default:
> -		BT_ERR("Spurious tx state %d", qca->tx_ibs_state);
> +		BT_ERR("Spurious tx state %d", qca->ibs.tx_state);
>  		ret = -EINVAL;
>  		break;
>  	}
>  
> -	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
> +	spin_unlock_irqrestore(&qca->ibs.lock, flags);
>  
>  	if (ret < 0)
>  		goto error;
> @@ -2009,7 +2029,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
>  	 */
>  
>  	ret = wait_event_interruptible_timeout(qca->suspend_wait_q,
> -			qca->rx_ibs_state == HCI_IBS_RX_ASLEEP,
> +			qca->ibs.rx_state == HCI_IBS_RX_ASLEEP,
>  			msecs_to_jiffies(IBS_BTSOC_TX_IDLE_TIMEOUT_MS));
>  
>  	if (ret > 0)
> -- 
> 2.25.1.481.gfbce0eb801-goog
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ