Lines Matching refs:priv
45 typedef int (*cw1200_wsm_handler)(struct cw1200_common *priv,
50 struct cw1200_common *priv = in cw1200_bh_work() local
52 cw1200_bh(priv); in cw1200_bh_work()
55 int cw1200_register_bh(struct cw1200_common *priv) in cw1200_register_bh() argument
59 priv->bh_workqueue = alloc_workqueue("cw1200_bh", in cw1200_register_bh()
63 if (!priv->bh_workqueue) in cw1200_register_bh()
66 INIT_WORK(&priv->bh_work, cw1200_bh_work); in cw1200_register_bh()
70 atomic_set(&priv->bh_rx, 0); in cw1200_register_bh()
71 atomic_set(&priv->bh_tx, 0); in cw1200_register_bh()
72 atomic_set(&priv->bh_term, 0); in cw1200_register_bh()
73 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED); in cw1200_register_bh()
74 priv->bh_error = 0; in cw1200_register_bh()
75 priv->hw_bufs_used = 0; in cw1200_register_bh()
76 priv->buf_id_tx = 0; in cw1200_register_bh()
77 priv->buf_id_rx = 0; in cw1200_register_bh()
78 init_waitqueue_head(&priv->bh_wq); in cw1200_register_bh()
79 init_waitqueue_head(&priv->bh_evt_wq); in cw1200_register_bh()
81 err = !queue_work(priv->bh_workqueue, &priv->bh_work); in cw1200_register_bh()
86 void cw1200_unregister_bh(struct cw1200_common *priv) in cw1200_unregister_bh() argument
88 atomic_add(1, &priv->bh_term); in cw1200_unregister_bh()
89 wake_up(&priv->bh_wq); in cw1200_unregister_bh()
91 flush_workqueue(priv->bh_workqueue); in cw1200_unregister_bh()
93 destroy_workqueue(priv->bh_workqueue); in cw1200_unregister_bh()
94 priv->bh_workqueue = NULL; in cw1200_unregister_bh()
99 void cw1200_irq_handler(struct cw1200_common *priv) in cw1200_irq_handler() argument
105 __cw1200_irq_enable(priv, 0); in cw1200_irq_handler()
107 if (/* WARN_ON */(priv->bh_error)) in cw1200_irq_handler()
110 if (atomic_add_return(1, &priv->bh_rx) == 1) in cw1200_irq_handler()
111 wake_up(&priv->bh_wq); in cw1200_irq_handler()
115 void cw1200_bh_wakeup(struct cw1200_common *priv) in cw1200_bh_wakeup() argument
118 if (priv->bh_error) { in cw1200_bh_wakeup()
123 if (atomic_add_return(1, &priv->bh_tx) == 1) in cw1200_bh_wakeup()
124 wake_up(&priv->bh_wq); in cw1200_bh_wakeup()
127 int cw1200_bh_suspend(struct cw1200_common *priv) in cw1200_bh_suspend() argument
130 if (priv->bh_error) { in cw1200_bh_suspend()
131 wiphy_warn(priv->hw->wiphy, "BH error -- can't suspend\n"); in cw1200_bh_suspend()
135 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPEND); in cw1200_bh_suspend()
136 wake_up(&priv->bh_wq); in cw1200_bh_suspend()
137 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error || in cw1200_bh_suspend()
138 (CW1200_BH_SUSPENDED == atomic_read(&priv->bh_suspend)), in cw1200_bh_suspend()
142 int cw1200_bh_resume(struct cw1200_common *priv) in cw1200_bh_resume() argument
145 if (priv->bh_error) { in cw1200_bh_resume()
146 wiphy_warn(priv->hw->wiphy, "BH error -- can't resume\n"); in cw1200_bh_resume()
150 atomic_set(&priv->bh_suspend, CW1200_BH_RESUME); in cw1200_bh_resume()
151 wake_up(&priv->bh_wq); in cw1200_bh_resume()
152 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error || in cw1200_bh_resume()
153 (CW1200_BH_RESUMED == atomic_read(&priv->bh_suspend)), in cw1200_bh_resume()
157 static inline void wsm_alloc_tx_buffer(struct cw1200_common *priv) in wsm_alloc_tx_buffer() argument
159 ++priv->hw_bufs_used; in wsm_alloc_tx_buffer()
162 int wsm_release_tx_buffer(struct cw1200_common *priv, int count) in wsm_release_tx_buffer() argument
165 int hw_bufs_used = priv->hw_bufs_used; in wsm_release_tx_buffer()
167 priv->hw_bufs_used -= count; in wsm_release_tx_buffer()
168 if (WARN_ON(priv->hw_bufs_used < 0)) in wsm_release_tx_buffer()
170 else if (hw_bufs_used >= priv->wsm_caps.input_buffers) in wsm_release_tx_buffer()
172 if (!priv->hw_bufs_used) in wsm_release_tx_buffer()
173 wake_up(&priv->bh_evt_wq); in wsm_release_tx_buffer()
177 static int cw1200_bh_read_ctrl_reg(struct cw1200_common *priv, in cw1200_bh_read_ctrl_reg() argument
182 ret = cw1200_reg_read_16(priv, in cw1200_bh_read_ctrl_reg()
185 ret = cw1200_reg_read_16(priv, in cw1200_bh_read_ctrl_reg()
194 static int cw1200_device_wakeup(struct cw1200_common *priv) in cw1200_device_wakeup() argument
202 ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID, in cw1200_device_wakeup()
203 cw1200_dpll_from_clk(priv->hw_refclk)); in cw1200_device_wakeup()
208 ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, in cw1200_device_wakeup()
213 ret = cw1200_bh_read_ctrl_reg(priv, &ctrl_reg); in cw1200_device_wakeup()
229 void cw1200_enable_powersave(struct cw1200_common *priv, in cw1200_enable_powersave() argument
234 priv->powersave_enabled = enable; in cw1200_enable_powersave()
237 static int cw1200_bh_rx_helper(struct cw1200_common *priv, in cw1200_bh_rx_helper() argument
268 alloc_len = priv->hwbus_ops->align_size( in cw1200_bh_rx_helper()
269 priv->hwbus_priv, read_len); in cw1200_bh_rx_helper()
287 if (WARN_ON(cw1200_data_read(priv, data, alloc_len))) { in cw1200_bh_rx_helper()
301 if (priv->wsm_enable_wsm_dumps) in cw1200_bh_rx_helper()
312 wsm_handle_exception(priv, in cw1200_bh_rx_helper()
317 if (WARN_ON(wsm_seq != priv->wsm_rx_seq)) in cw1200_bh_rx_helper()
320 priv->wsm_rx_seq = (wsm_seq + 1) & 7; in cw1200_bh_rx_helper()
324 int rc = wsm_release_tx_buffer(priv, 1); in cw1200_bh_rx_helper()
332 if (WARN_ON(wsm_handle_rx(priv, wsm_id, wsm, &skb_rx))) in cw1200_bh_rx_helper()
350 static int cw1200_bh_tx_helper(struct cw1200_common *priv, in cw1200_bh_tx_helper() argument
359 if (priv->device_can_sleep) { in cw1200_bh_tx_helper()
360 ret = cw1200_device_wakeup(priv); in cw1200_bh_tx_helper()
365 priv->device_can_sleep = false; in cw1200_bh_tx_helper()
372 wsm_alloc_tx_buffer(priv); in cw1200_bh_tx_helper()
373 ret = wsm_get_tx(priv, &data, &tx_len, tx_burst); in cw1200_bh_tx_helper()
375 wsm_release_tx_buffer(priv, 1); in cw1200_bh_tx_helper()
385 atomic_add(1, &priv->bh_tx); in cw1200_bh_tx_helper()
387 tx_len = priv->hwbus_ops->align_size( in cw1200_bh_tx_helper()
388 priv->hwbus_priv, tx_len); in cw1200_bh_tx_helper()
395 wsm->id |= __cpu_to_le16(WSM_TX_SEQ(priv->wsm_tx_seq)); in cw1200_bh_tx_helper()
397 if (WARN_ON(cw1200_data_write(priv, data, tx_len))) { in cw1200_bh_tx_helper()
399 wsm_release_tx_buffer(priv, 1); in cw1200_bh_tx_helper()
403 if (priv->wsm_enable_wsm_dumps) in cw1200_bh_tx_helper()
409 wsm_txed(priv, data); in cw1200_bh_tx_helper()
410 priv->wsm_tx_seq = (priv->wsm_tx_seq + 1) & WSM_TX_SEQ_MAX; in cw1200_bh_tx_helper()
413 cw1200_debug_tx_burst(priv); in cw1200_bh_tx_helper()
422 struct cw1200_common *priv = arg; in cw1200_bh() local
433 if (!priv->hw_bufs_used && in cw1200_bh()
434 priv->powersave_enabled && in cw1200_bh()
435 !priv->device_can_sleep && in cw1200_bh()
436 !atomic_read(&priv->recent_scan)) { in cw1200_bh()
439 cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, 0); in cw1200_bh()
440 priv->device_can_sleep = true; in cw1200_bh()
441 } else if (priv->hw_bufs_used) { in cw1200_bh()
449 if ((priv->hw_type != -1) && in cw1200_bh()
450 (atomic_read(&priv->bh_rx) == 0) && in cw1200_bh()
451 (atomic_read(&priv->bh_tx) == 0)) in cw1200_bh()
452 cw1200_reg_read(priv, ST90TDS_CONFIG_REG_ID, in cw1200_bh()
456 status = wait_event_interruptible_timeout(priv->bh_wq, ({ in cw1200_bh()
457 rx = atomic_xchg(&priv->bh_rx, 0); in cw1200_bh()
458 tx = atomic_xchg(&priv->bh_tx, 0); in cw1200_bh()
459 term = atomic_xchg(&priv->bh_term, 0); in cw1200_bh()
461 0 : atomic_read(&priv->bh_suspend); in cw1200_bh()
462 (rx || tx || term || suspend || priv->bh_error); in cw1200_bh()
466 rx, tx, term, suspend, priv->bh_error, status); in cw1200_bh()
470 term || priv->bh_error) { in cw1200_bh()
480 if (priv->hw_bufs_used && (!rx || !tx)) { in cw1200_bh()
481 wiphy_warn(priv->hw->wiphy, in cw1200_bh()
483 priv->hw_bufs_used); in cw1200_bh()
489 &priv->tx_queue[i], in cw1200_bh()
491 priv->pending_frame_id); in cw1200_bh()
504 wiphy_warn(priv->hw->wiphy, in cw1200_bh()
506 priv->hw_bufs_used, pending, in cw1200_bh()
510 } else if (!priv->device_can_sleep && in cw1200_bh()
511 !atomic_read(&priv->recent_scan)) { in cw1200_bh()
513 cw1200_reg_write_16(priv, in cw1200_bh()
515 priv->device_can_sleep = true; in cw1200_bh()
520 if (priv->powersave_enabled) { in cw1200_bh()
522 cw1200_reg_write_16(priv, in cw1200_bh()
524 priv->device_can_sleep = true; in cw1200_bh()
527 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPENDED); in cw1200_bh()
528 wake_up(&priv->bh_evt_wq); in cw1200_bh()
529 status = wait_event_interruptible(priv->bh_wq, in cw1200_bh()
530 CW1200_BH_RESUME == atomic_read(&priv->bh_suspend)); in cw1200_bh()
532 wiphy_err(priv->hw->wiphy, in cw1200_bh()
538 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED); in cw1200_bh()
539 wake_up(&priv->bh_evt_wq); in cw1200_bh()
540 atomic_add(1, &priv->bh_rx); in cw1200_bh()
548 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg)) in cw1200_bh()
553 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx); in cw1200_bh()
558 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx); in cw1200_bh()
568 BUG_ON(priv->hw_bufs_used > priv->wsm_caps.input_buffers); in cw1200_bh()
569 tx_burst = priv->wsm_caps.input_buffers - priv->hw_bufs_used; in cw1200_bh()
579 ret = cw1200_bh_tx_helper(priv, &pending_tx, &tx_burst); in cw1200_bh()
586 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg)) in cw1200_bh()
591 if (priv->bh_error) in cw1200_bh()
600 priv->hwbus_ops->lock(priv->hwbus_priv); in cw1200_bh()
601 __cw1200_irq_enable(priv, 1); in cw1200_bh()
602 priv->hwbus_ops->unlock(priv->hwbus_priv); in cw1200_bh()
606 priv->hwbus_ops->lock(priv->hwbus_priv); in cw1200_bh()
607 __cw1200_irq_enable(priv, 0); in cw1200_bh()
608 priv->hwbus_ops->unlock(priv->hwbus_priv); in cw1200_bh()
612 priv->bh_error = 1; in cw1200_bh()