summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl-trans.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-08-26 06:10:48 (GMT)
committerJohn W. Linville <linville@tuxdriver.com>2011-08-29 19:25:32 (GMT)
commite6bb4c9c00892c488f3218ea317dc6a71674faf4 (patch)
tree3afe043aee2c5e73978259393b8242baf2acd886 /drivers/net/wireless/iwlwifi/iwl-trans.c
parentf39c95e8d7a152b409977687a999356f0e54bde6 (diff)
downloadlinux-fsl-qoriq-e6bb4c9c00892c488f3218ea317dc6a71674faf4.tar.xz
iwlagn: bus layer chooses its transport layer
Remove iwl_transport_register which was a W/A. The bus layer knows what transport to use. So now, the bus layer gives the upper layer a pointer to the iwl_trans_ops struct that it wants to use. The upper layer then, allocates the desired transport layer using iwl_trans_ops->alloc function. As a result of this, priv->trans, no longer exists, priv holds a pointer to iwl_shared, which holds a pointer to iwl_trans. This required to change all the calls to the transport layer from upper layer. While we were at it, trans_X inlines have been renamed to iwl_trans_X to avoid confusions, which of course required to rename the functions inside the transport layer because of conflicts in names. So the static API functions inside the transport layer implementation have been renamed to iwl_trans_pcie_X. Until now, the IRQ / Tasklet were initialized in iwl_transport_layer. This is confusing since the registration doesn't mean to request IRQ, so I added a handler for that. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c125
1 files changed, 72 insertions, 53 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index cc3fc23..739087f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -60,6 +60,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
+#include <linux/interrupt.h>
+
#include "iwl-dev.h"
#include "iwl-trans.h"
#include "iwl-core.h"
@@ -218,7 +220,7 @@ static int iwl_rx_init(struct iwl_priv *priv)
return 0;
}
-static void iwl_trans_rx_free(struct iwl_priv *priv)
+static void iwl_trans_pcie_rx_free(struct iwl_priv *priv)
{
struct iwl_rx_queue *rxq = &priv->rxq;
unsigned long flags;
@@ -453,7 +455,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
*
* Destroy all TX DMA queues and structures
*/
-static void iwl_trans_tx_free(struct iwl_priv *priv)
+static void iwl_trans_pcie_tx_free(struct iwl_priv *priv)
{
int txq_id;
@@ -528,7 +530,7 @@ static int iwl_trans_tx_alloc(struct iwl_priv *priv)
return 0;
error:
- trans_tx_free(&priv->trans);
+ iwl_trans_tx_free(trans(priv));
return ret;
}
@@ -572,7 +574,7 @@ static int iwl_tx_init(struct iwl_priv *priv)
error:
/*Upon error, free only if we allocated something */
if (alloc)
- trans_tx_free(&priv->trans);
+ iwl_trans_tx_free(trans(priv));
return ret;
}
@@ -649,7 +651,7 @@ static int iwl_set_hw_ready(struct iwl_priv *priv)
}
/* Note: returns standard 0/-ERROR code */
-static int iwl_trans_prepare_card_hw(struct iwl_priv *priv)
+static int iwl_trans_pcie_prepare_card_hw(struct iwl_priv *priv)
{
int ret;
@@ -677,14 +679,14 @@ static int iwl_trans_prepare_card_hw(struct iwl_priv *priv)
return ret;
}
-static int iwl_trans_start_device(struct iwl_priv *priv)
+static int iwl_trans_pcie_start_device(struct iwl_priv *priv)
{
int ret;
priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
- iwl_trans_prepare_card_hw(priv)) {
+ iwl_trans_pcie_prepare_card_hw(priv)) {
IWL_WARN(priv, "Exit HW not ready\n");
return -EIO;
}
@@ -768,7 +770,7 @@ static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
{ IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
{ IWL_TX_FIFO_AUX, IWL_AC_UNSET, },
};
-static void iwl_trans_tx_start(struct iwl_priv *priv)
+static void iwl_trans_pcie_tx_start(struct iwl_priv *priv)
{
const struct queue_to_fifo_ac *queue_to_fifo;
struct iwl_rxon_context *ctx;
@@ -916,7 +918,7 @@ static int iwl_trans_tx_stop(struct iwl_priv *priv)
return 0;
}
-static void iwl_trans_stop_device(struct iwl_priv *priv)
+static void iwl_trans_pcie_stop_device(struct iwl_priv *priv)
{
unsigned long flags;
@@ -927,7 +929,7 @@ static void iwl_trans_stop_device(struct iwl_priv *priv)
spin_lock_irqsave(&priv->shrd->lock, flags);
iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->shrd->lock, flags);
- trans_sync_irq(&priv->trans);
+ iwl_trans_sync_irq(trans(priv));
/* device going down, Stop using ICT table */
iwl_disable_ict(priv);
@@ -956,7 +958,7 @@ static void iwl_trans_stop_device(struct iwl_priv *priv)
iwl_apm_stop(priv);
}
-static struct iwl_tx_cmd *iwl_trans_get_tx_cmd(struct iwl_priv *priv,
+static struct iwl_tx_cmd *iwl_trans_pcie_get_tx_cmd(struct iwl_priv *priv,
int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
@@ -980,7 +982,7 @@ static struct iwl_tx_cmd *iwl_trans_get_tx_cmd(struct iwl_priv *priv,
return &dev_cmd->cmd.tx;
}
-static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
+static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu,
struct iwl_rxon_context *ctx)
{
@@ -1109,71 +1111,88 @@ static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
return 0;
}
-static void iwl_trans_kick_nic(struct iwl_priv *priv)
+static void iwl_trans_pcie_kick_nic(struct iwl_priv *priv)
{
/* Remove all resets to allow NIC to operate */
iwl_write32(priv, CSR_RESET, 0);
}
-static void iwl_trans_sync_irq(struct iwl_priv *priv)
+static int iwl_trans_pcie_request_irq(struct iwl_trans *trans)
+{
+ struct iwl_priv *priv = priv(trans);
+ int err;
+
+ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ iwl_irq_tasklet, (unsigned long)priv);
+
+ iwl_alloc_isr_ict(priv);
+
+ err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED,
+ DRV_NAME, priv);
+ if (err) {
+ IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus->irq);
+ iwl_free_isr_ict(priv);
+ return err;
+ }
+
+ INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
+ return 0;
+}
+
+static void iwl_trans_pcie_sync_irq(struct iwl_priv *priv)
{
/* wait to make sure we flush pending tasklet*/
synchronize_irq(priv->bus->irq);
tasklet_kill(&priv->irq_tasklet);
}
-static void iwl_trans_free(struct iwl_priv *priv)
+static void iwl_trans_pcie_free(struct iwl_priv *priv)
{
free_irq(priv->bus->irq, priv);
iwl_free_isr_ict(priv);
+ kfree(trans(priv));
+ trans(priv) = NULL;
}
-static const struct iwl_trans_ops trans_ops = {
- .start_device = iwl_trans_start_device,
- .prepare_card_hw = iwl_trans_prepare_card_hw,
- .stop_device = iwl_trans_stop_device,
-
- .tx_start = iwl_trans_tx_start,
+const struct iwl_trans_ops trans_ops_pcie;
- .rx_free = iwl_trans_rx_free,
- .tx_free = iwl_trans_tx_free,
+static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
+{
+ struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) +
+ sizeof(struct iwl_trans_pcie),
+ GFP_KERNEL);
+ if (iwl_trans) {
+ iwl_trans->ops = &trans_ops_pcie;
+ iwl_trans->shrd = shrd;
+ }
- .send_cmd = iwl_send_cmd,
- .send_cmd_pdu = iwl_send_cmd_pdu,
+ return iwl_trans;
+}
- .get_tx_cmd = iwl_trans_get_tx_cmd,
- .tx = iwl_trans_tx,
+const struct iwl_trans_ops trans_ops_pcie = {
+ .alloc = iwl_trans_pcie_alloc,
+ .request_irq = iwl_trans_pcie_request_irq,
+ .start_device = iwl_trans_pcie_start_device,
+ .prepare_card_hw = iwl_trans_pcie_prepare_card_hw,
+ .stop_device = iwl_trans_pcie_stop_device,
- .txq_agg_disable = iwl_trans_txq_agg_disable,
- .txq_agg_setup = iwl_trans_txq_agg_setup,
+ .tx_start = iwl_trans_pcie_tx_start,
- .kick_nic = iwl_trans_kick_nic,
+ .rx_free = iwl_trans_pcie_rx_free,
+ .tx_free = iwl_trans_pcie_tx_free,
- .sync_irq = iwl_trans_sync_irq,
- .free = iwl_trans_free,
-};
+ .send_cmd = iwl_trans_pcie_send_cmd,
+ .send_cmd_pdu = iwl_trans_pcie_send_cmd_pdu,
-int iwl_trans_register(struct iwl_trans *trans, struct iwl_priv *priv)
-{
- int err;
+ .get_tx_cmd = iwl_trans_pcie_get_tx_cmd,
+ .tx = iwl_trans_pcie_tx,
- priv->trans.ops = &trans_ops;
- priv->trans.priv = priv;
+ .txq_agg_disable = iwl_trans_pcie_txq_agg_disable,
+ .txq_agg_setup = iwl_trans_pcie_txq_agg_setup,
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
- iwl_irq_tasklet, (unsigned long)priv);
+ .kick_nic = iwl_trans_pcie_kick_nic,
- iwl_alloc_isr_ict(priv);
-
- err = request_irq(priv->bus->irq, iwl_isr_ict, IRQF_SHARED,
- DRV_NAME, priv);
- if (err) {
- IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus->irq);
- iwl_free_isr_ict(priv);
- return err;
- }
-
- INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
+ .sync_irq = iwl_trans_pcie_sync_irq,
+ .free = iwl_trans_pcie_free,
+};
- return 0;
-}