aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-07-04 01:58:19 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-07-16 10:36:49 -0400
commit34c1b7ba127d1815b3dd1cb81cc4338ce0e712b7 (patch)
tree753b883841eb6772eef0f7e444f6b7ec3719b87c /drivers
parent47c1b496015e41e1068878814596af9a45d4fa84 (diff)
iwlagn: move the tasklet / irq to the transport layer
PCIe doesn't provide any ISR registration API, whereas other buses do. Hence, we need to move the tasklet and irq to the transport layer to allow this flexibility. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h7
6 files changed, 55 insertions, 29 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
index f1b40ec1c873..9a2eb1e426b5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -49,6 +49,10 @@ void iwl_free_isr_ict(struct iwl_priv *priv)
49 priv->_agn.ict_tbl_vir, 49 priv->_agn.ict_tbl_vir,
50 priv->_agn.ict_tbl_dma); 50 priv->_agn.ict_tbl_dma);
51 priv->_agn.ict_tbl_vir = NULL; 51 priv->_agn.ict_tbl_vir = NULL;
52 memset(&priv->_agn.ict_tbl_dma, 0,
53 sizeof(priv->_agn.ict_tbl_dma));
54 memset(&priv->_agn.aligned_ict_tbl_dma, 0,
55 sizeof(priv->_agn.aligned_ict_tbl_dma));
52 } 56 }
53} 57}
54 58
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 38a1e4f58829..598f16486aa6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -625,7 +625,7 @@ static void iwl_rx_handle(struct iwl_priv *priv)
625} 625}
626 626
627/* tasklet for iwlagn interrupt */ 627/* tasklet for iwlagn interrupt */
628static void iwl_irq_tasklet(struct iwl_priv *priv) 628void iwl_irq_tasklet(struct iwl_priv *priv)
629{ 629{
630 u32 inta = 0; 630 u32 inta = 0;
631 u32 handled = 0; 631 u32 handled = 0;
@@ -3227,9 +3227,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3227 init_timer(&priv->watchdog); 3227 init_timer(&priv->watchdog);
3228 priv->watchdog.data = (unsigned long)priv; 3228 priv->watchdog.data = (unsigned long)priv;
3229 priv->watchdog.function = iwl_bg_watchdog; 3229 priv->watchdog.function = iwl_bg_watchdog;
3230
3231 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3232 iwl_irq_tasklet, (unsigned long)priv);
3233} 3230}
3234 3231
3235static void iwl_cancel_deferred_work(struct iwl_priv *priv) 3232static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -3548,8 +3545,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
3548 priv->bus.ops->set_drv_data(&priv->bus, priv); 3545 priv->bus.ops->set_drv_data(&priv->bus, priv);
3549 priv->bus.dev = priv->bus.ops->get_dev(&priv->bus); 3546 priv->bus.dev = priv->bus.ops->get_dev(&priv->bus);
3550 3547
3551 iwl_trans_register(&priv->trans);
3552
3553 /* At this point both hw and priv are allocated. */ 3548 /* At this point both hw and priv are allocated. */
3554 3549
3555 SET_IEEE80211_DEV(hw, priv->bus.dev); 3550 SET_IEEE80211_DEV(hw, priv->bus.dev);
@@ -3558,6 +3553,10 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
3558 priv->cfg = cfg; 3553 priv->cfg = cfg;
3559 priv->inta_mask = CSR_INI_SET_MASK; 3554 priv->inta_mask = CSR_INI_SET_MASK;
3560 3555
3556 err = iwl_trans_register(priv);
3557 if (err)
3558 goto out_free_priv;
3559
3561 /* is antenna coupling more than 35dB ? */ 3560 /* is antenna coupling more than 35dB ? */
3562 priv->bt_ant_couple_ok = 3561 priv->bt_ant_couple_ok =
3563 (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? 3562 (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
@@ -3652,15 +3651,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
3652 /******************** 3651 /********************
3653 * 7. Setup services 3652 * 7. Setup services
3654 ********************/ 3653 ********************/
3655 iwl_alloc_isr_ict(priv);
3656
3657 err = request_irq(priv->bus.irq, iwl_isr_ict, IRQF_SHARED,
3658 DRV_NAME, priv);
3659 if (err) {
3660 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus.irq);
3661 goto out_uninit_drv;
3662 }
3663
3664 iwl_setup_deferred_work(priv); 3654 iwl_setup_deferred_work(priv);
3665 iwl_setup_rx_handlers(priv); 3655 iwl_setup_rx_handlers(priv);
3666 iwl_testmode_init(priv); 3656 iwl_testmode_init(priv);
@@ -3691,19 +3681,18 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
3691 3681
3692 return 0; 3682 return 0;
3693 3683
3694 out_destroy_workqueue: 3684out_destroy_workqueue:
3695 destroy_workqueue(priv->workqueue); 3685 destroy_workqueue(priv->workqueue);
3696 priv->workqueue = NULL; 3686 priv->workqueue = NULL;
3697 free_irq(priv->bus.irq, priv);
3698 iwl_free_isr_ict(priv);
3699 out_uninit_drv:
3700 iwl_uninit_drv(priv); 3687 iwl_uninit_drv(priv);
3701 out_free_eeprom: 3688out_free_eeprom:
3702 iwl_eeprom_free(priv); 3689 iwl_eeprom_free(priv);
3703 out_free_traffic_mem: 3690out_free_traffic_mem:
3704 iwl_free_traffic_mem(priv); 3691 iwl_free_traffic_mem(priv);
3692 trans_free(priv);
3693out_free_priv:
3705 ieee80211_free_hw(priv->hw); 3694 ieee80211_free_hw(priv->hw);
3706 out: 3695out:
3707 return err; 3696 return err;
3708} 3697}
3709 3698
@@ -3754,7 +3743,6 @@ void __devexit iwl_remove(struct iwl_priv * priv)
3754 3743
3755 iwl_eeprom_free(priv); 3744 iwl_eeprom_free(priv);
3756 3745
3757
3758 /*netif_stop_queue(dev); */ 3746 /*netif_stop_queue(dev); */
3759 flush_workqueue(priv->workqueue); 3747 flush_workqueue(priv->workqueue);
3760 3748
@@ -3765,13 +3753,12 @@ void __devexit iwl_remove(struct iwl_priv * priv)
3765 priv->workqueue = NULL; 3753 priv->workqueue = NULL;
3766 iwl_free_traffic_mem(priv); 3754 iwl_free_traffic_mem(priv);
3767 3755
3768 free_irq(priv->bus.irq, priv); 3756 trans_free(priv);
3757
3769 priv->bus.ops->set_drv_data(&priv->bus, NULL); 3758 priv->bus.ops->set_drv_data(&priv->bus, NULL);
3770 3759
3771 iwl_uninit_drv(priv); 3760 iwl_uninit_drv(priv);
3772 3761
3773 iwl_free_isr_ict(priv);
3774
3775 dev_kfree_skb(priv->beacon_skb); 3762 dev_kfree_skb(priv->beacon_skb);
3776 3763
3777 ieee80211_free_hw(priv->hw); 3764 ieee80211_free_hw(priv->hw);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index aed86c6cd933..70188550a4fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -188,6 +188,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
188void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 188void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
189 189
190/* rx */ 190/* rx */
191void iwl_irq_tasklet(struct iwl_priv *priv);
191void iwlagn_rx_queue_restock(struct iwl_priv *priv); 192void iwlagn_rx_queue_restock(struct iwl_priv *priv);
192void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority); 193void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority);
193void iwlagn_rx_replenish(struct iwl_priv *priv); 194void iwlagn_rx_replenish(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 173fad2ab240..b38b00cebd2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1243,6 +1243,8 @@ struct iwl_trans;
1243 * @tx_free: frees the tx memory 1243 * @tx_free: frees the tx memory
1244 * @send_cmd:send a host command 1244 * @send_cmd:send a host command
1245 * @send_cmd_pdu:send a host command: flags can be CMD_* 1245 * @send_cmd_pdu:send a host command: flags can be CMD_*
1246 * @free: release all the ressource for the transport layer itself such as
1247 * irq, tasklet etc...
1246 */ 1248 */
1247struct iwl_trans_ops { 1249struct iwl_trans_ops {
1248 int (*rx_init)(struct iwl_priv *priv); 1250 int (*rx_init)(struct iwl_priv *priv);
@@ -1261,6 +1263,8 @@ struct iwl_trans_ops {
1261 int (*tx)(struct iwl_priv *priv, struct sk_buff *skb, 1263 int (*tx)(struct iwl_priv *priv, struct sk_buff *skb,
1262 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu, 1264 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu,
1263 struct iwl_rxon_context *ctx); 1265 struct iwl_rxon_context *ctx);
1266
1267 void (*free)(struct iwl_priv *priv);
1264}; 1268};
1265 1269
1266struct iwl_trans { 1270struct iwl_trans {
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index acd2a5feec93..ecdda6d57b16 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -705,6 +705,12 @@ static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
705 return 0; 705 return 0;
706} 706}
707 707
708static void iwl_trans_free(struct iwl_priv *priv)
709{
710 free_irq(priv->bus.irq, priv);
711 iwl_free_isr_ict(priv);
712}
713
708static const struct iwl_trans_ops trans_ops = { 714static const struct iwl_trans_ops trans_ops = {
709 .rx_init = iwl_trans_rx_init, 715 .rx_init = iwl_trans_rx_init,
710 .rx_stop = iwl_trans_rx_stop, 716 .rx_stop = iwl_trans_rx_stop,
@@ -719,9 +725,28 @@ static const struct iwl_trans_ops trans_ops = {
719 725
720 .get_tx_cmd = iwl_trans_get_tx_cmd, 726 .get_tx_cmd = iwl_trans_get_tx_cmd,
721 .tx = iwl_trans_tx, 727 .tx = iwl_trans_tx,
728
729 .free = iwl_trans_free,
722}; 730};
723 731
724void iwl_trans_register(struct iwl_trans *trans) 732int iwl_trans_register(struct iwl_priv *priv)
725{ 733{
726 trans->ops = &trans_ops; 734 int err;
735
736 priv->trans.ops = &trans_ops;
737
738 iwl_alloc_isr_ict(priv);
739
740 err = request_irq(priv->bus.irq, iwl_isr_ict, IRQF_SHARED,
741 DRV_NAME, priv);
742 if (err) {
743 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus.irq);
744 iwl_free_isr_ict(priv);
745 return err;
746 }
747
748 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
749 iwl_irq_tasklet, (unsigned long)priv);
750
751 return 0;
727} 752}
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index f10bee8c1f88..f8133ea90aff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -115,4 +115,9 @@ static inline int trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
115 return priv->trans.ops->tx(priv, skb, tx_cmd, txq_id, fc, ampdu, ctx); 115 return priv->trans.ops->tx(priv, skb, tx_cmd, txq_id, fc, ampdu, ctx);
116} 116}
117 117
118void iwl_trans_register(struct iwl_trans *trans); 118static inline void trans_free(struct iwl_priv *priv)
119{
120 priv->trans.ops->free(priv);
121}
122
123int iwl_trans_register(struct iwl_priv *priv);