aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-trans.c
diff options
context:
space:
mode:
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 cc3fc237d320..739087f3025c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -60,6 +60,8 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#include <linux/interrupt.h>
64
63#include "iwl-dev.h" 65#include "iwl-dev.h"
64#include "iwl-trans.h" 66#include "iwl-trans.h"
65#include "iwl-core.h" 67#include "iwl-core.h"
@@ -218,7 +220,7 @@ static int iwl_rx_init(struct iwl_priv *priv)
218 return 0; 220 return 0;
219} 221}
220 222
221static void iwl_trans_rx_free(struct iwl_priv *priv) 223static void iwl_trans_pcie_rx_free(struct iwl_priv *priv)
222{ 224{
223 struct iwl_rx_queue *rxq = &priv->rxq; 225 struct iwl_rx_queue *rxq = &priv->rxq;
224 unsigned long flags; 226 unsigned long flags;
@@ -453,7 +455,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
453 * 455 *
454 * Destroy all TX DMA queues and structures 456 * Destroy all TX DMA queues and structures
455 */ 457 */
456static void iwl_trans_tx_free(struct iwl_priv *priv) 458static void iwl_trans_pcie_tx_free(struct iwl_priv *priv)
457{ 459{
458 int txq_id; 460 int txq_id;
459 461
@@ -528,7 +530,7 @@ static int iwl_trans_tx_alloc(struct iwl_priv *priv)
528 return 0; 530 return 0;
529 531
530error: 532error:
531 trans_tx_free(&priv->trans); 533 iwl_trans_tx_free(trans(priv));
532 534
533 return ret; 535 return ret;
534} 536}
@@ -572,7 +574,7 @@ static int iwl_tx_init(struct iwl_priv *priv)
572error: 574error:
573 /*Upon error, free only if we allocated something */ 575 /*Upon error, free only if we allocated something */
574 if (alloc) 576 if (alloc)
575 trans_tx_free(&priv->trans); 577 iwl_trans_tx_free(trans(priv));
576 return ret; 578 return ret;
577} 579}
578 580
@@ -649,7 +651,7 @@ static int iwl_set_hw_ready(struct iwl_priv *priv)
649} 651}
650 652
651/* Note: returns standard 0/-ERROR code */ 653/* Note: returns standard 0/-ERROR code */
652static int iwl_trans_prepare_card_hw(struct iwl_priv *priv) 654static int iwl_trans_pcie_prepare_card_hw(struct iwl_priv *priv)
653{ 655{
654 int ret; 656 int ret;
655 657
@@ -677,14 +679,14 @@ static int iwl_trans_prepare_card_hw(struct iwl_priv *priv)
677 return ret; 679 return ret;
678} 680}
679 681
680static int iwl_trans_start_device(struct iwl_priv *priv) 682static int iwl_trans_pcie_start_device(struct iwl_priv *priv)
681{ 683{
682 int ret; 684 int ret;
683 685
684 priv->ucode_owner = IWL_OWNERSHIP_DRIVER; 686 priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
685 687
686 if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) && 688 if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
687 iwl_trans_prepare_card_hw(priv)) { 689 iwl_trans_pcie_prepare_card_hw(priv)) {
688 IWL_WARN(priv, "Exit HW not ready\n"); 690 IWL_WARN(priv, "Exit HW not ready\n");
689 return -EIO; 691 return -EIO;
690 } 692 }
@@ -768,7 +770,7 @@ static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
768 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, 770 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
769 { IWL_TX_FIFO_AUX, IWL_AC_UNSET, }, 771 { IWL_TX_FIFO_AUX, IWL_AC_UNSET, },
770}; 772};
771static void iwl_trans_tx_start(struct iwl_priv *priv) 773static void iwl_trans_pcie_tx_start(struct iwl_priv *priv)
772{ 774{
773 const struct queue_to_fifo_ac *queue_to_fifo; 775 const struct queue_to_fifo_ac *queue_to_fifo;
774 struct iwl_rxon_context *ctx; 776 struct iwl_rxon_context *ctx;
@@ -916,7 +918,7 @@ static int iwl_trans_tx_stop(struct iwl_priv *priv)
916 return 0; 918 return 0;
917} 919}
918 920
919static void iwl_trans_stop_device(struct iwl_priv *priv) 921static void iwl_trans_pcie_stop_device(struct iwl_priv *priv)
920{ 922{
921 unsigned long flags; 923 unsigned long flags;
922 924
@@ -927,7 +929,7 @@ static void iwl_trans_stop_device(struct iwl_priv *priv)
927 spin_lock_irqsave(&priv->shrd->lock, flags); 929 spin_lock_irqsave(&priv->shrd->lock, flags);
928 iwl_disable_interrupts(priv); 930 iwl_disable_interrupts(priv);
929 spin_unlock_irqrestore(&priv->shrd->lock, flags); 931 spin_unlock_irqrestore(&priv->shrd->lock, flags);
930 trans_sync_irq(&priv->trans); 932 iwl_trans_sync_irq(trans(priv));
931 933
932 /* device going down, Stop using ICT table */ 934 /* device going down, Stop using ICT table */
933 iwl_disable_ict(priv); 935 iwl_disable_ict(priv);
@@ -956,7 +958,7 @@ static void iwl_trans_stop_device(struct iwl_priv *priv)
956 iwl_apm_stop(priv); 958 iwl_apm_stop(priv);
957} 959}
958 960
959static struct iwl_tx_cmd *iwl_trans_get_tx_cmd(struct iwl_priv *priv, 961static struct iwl_tx_cmd *iwl_trans_pcie_get_tx_cmd(struct iwl_priv *priv,
960 int txq_id) 962 int txq_id)
961{ 963{
962 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 964 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,
980 return &dev_cmd->cmd.tx; 982 return &dev_cmd->cmd.tx;
981} 983}
982 984
983static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb, 985static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
984 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu, 986 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu,
985 struct iwl_rxon_context *ctx) 987 struct iwl_rxon_context *ctx)
986{ 988{
@@ -1109,71 +1111,88 @@ static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
1109 return 0; 1111 return 0;
1110} 1112}
1111 1113
1112static void iwl_trans_kick_nic(struct iwl_priv *priv) 1114static void iwl_trans_pcie_kick_nic(struct iwl_priv *priv)
1113{ 1115{
1114 /* Remove all resets to allow NIC to operate */ 1116 /* Remove all resets to allow NIC to operate */
1115 iwl_write32(priv, CSR_RESET, 0); 1117 iwl_write32(priv, CSR_RESET, 0);
1116} 1118}
1117 1119
1118static void iwl_trans_sync_irq(struct iwl_priv *priv) 1120static int iwl_trans_pcie_request_irq(struct iwl_trans *trans)
1121{
1122 struct iwl_priv *priv = priv(trans);
1123 int err;
1124
1125 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
1126 iwl_irq_tasklet, (unsigned long)priv);
1127
1128 iwl_alloc_isr_ict(priv);
1129
1130 err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED,
1131 DRV_NAME, priv);
1132 if (err) {
1133 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus->irq);
1134 iwl_free_isr_ict(priv);
1135 return err;
1136 }
1137
1138 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
1139 return 0;
1140}
1141
1142static void iwl_trans_pcie_sync_irq(struct iwl_priv *priv)
1119{ 1143{
1120 /* wait to make sure we flush pending tasklet*/ 1144 /* wait to make sure we flush pending tasklet*/
1121 synchronize_irq(priv->bus->irq); 1145 synchronize_irq(priv->bus->irq);
1122 tasklet_kill(&priv->irq_tasklet); 1146 tasklet_kill(&priv->irq_tasklet);
1123} 1147}
1124 1148
1125static void iwl_trans_free(struct iwl_priv *priv) 1149static void iwl_trans_pcie_free(struct iwl_priv *priv)
1126{ 1150{
1127 free_irq(priv->bus->irq, priv); 1151 free_irq(priv->bus->irq, priv);
1128 iwl_free_isr_ict(priv); 1152 iwl_free_isr_ict(priv);
1153 kfree(trans(priv));
1154 trans(priv) = NULL;
1129} 1155}
1130 1156
1131static const struct iwl_trans_ops trans_ops = { 1157const struct iwl_trans_ops trans_ops_pcie;
1132 .start_device = iwl_trans_start_device,
1133 .prepare_card_hw = iwl_trans_prepare_card_hw,
1134 .stop_device = iwl_trans_stop_device,
1135
1136 .tx_start = iwl_trans_tx_start,
1137 1158
1138 .rx_free = iwl_trans_rx_free, 1159static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
1139 .tx_free = iwl_trans_tx_free, 1160{
1161 struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) +
1162 sizeof(struct iwl_trans_pcie),
1163 GFP_KERNEL);
1164 if (iwl_trans) {
1165 iwl_trans->ops = &trans_ops_pcie;
1166 iwl_trans->shrd = shrd;
1167 }
1140 1168
1141 .send_cmd = iwl_send_cmd, 1169 return iwl_trans;
1142 .send_cmd_pdu = iwl_send_cmd_pdu, 1170}
1143 1171
1144 .get_tx_cmd = iwl_trans_get_tx_cmd, 1172const struct iwl_trans_ops trans_ops_pcie = {
1145 .tx = iwl_trans_tx, 1173 .alloc = iwl_trans_pcie_alloc,
1174 .request_irq = iwl_trans_pcie_request_irq,
1175 .start_device = iwl_trans_pcie_start_device,
1176 .prepare_card_hw = iwl_trans_pcie_prepare_card_hw,
1177 .stop_device = iwl_trans_pcie_stop_device,
1146 1178
1147 .txq_agg_disable = iwl_trans_txq_agg_disable, 1179 .tx_start = iwl_trans_pcie_tx_start,
1148 .txq_agg_setup = iwl_trans_txq_agg_setup,
1149 1180
1150 .kick_nic = iwl_trans_kick_nic, 1181 .rx_free = iwl_trans_pcie_rx_free,
1182 .tx_free = iwl_trans_pcie_tx_free,
1151 1183
1152 .sync_irq = iwl_trans_sync_irq, 1184 .send_cmd = iwl_trans_pcie_send_cmd,
1153 .free = iwl_trans_free, 1185 .send_cmd_pdu = iwl_trans_pcie_send_cmd_pdu,
1154};
1155 1186
1156int iwl_trans_register(struct iwl_trans *trans, struct iwl_priv *priv) 1187 .get_tx_cmd = iwl_trans_pcie_get_tx_cmd,
1157{ 1188 .tx = iwl_trans_pcie_tx,
1158 int err;
1159 1189
1160 priv->trans.ops = &trans_ops; 1190 .txq_agg_disable = iwl_trans_pcie_txq_agg_disable,
1161 priv->trans.priv = priv; 1191 .txq_agg_setup = iwl_trans_pcie_txq_agg_setup,
1162 1192
1163 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 1193 .kick_nic = iwl_trans_pcie_kick_nic,
1164 iwl_irq_tasklet, (unsigned long)priv);
1165 1194
1166 iwl_alloc_isr_ict(priv); 1195 .sync_irq = iwl_trans_pcie_sync_irq,
1167 1196 .free = iwl_trans_pcie_free,
1168 err = request_irq(priv->bus->irq, iwl_isr_ict, IRQF_SHARED, 1197};
1169 DRV_NAME, priv);
1170 if (err) {
1171 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus->irq);
1172 iwl_free_isr_ict(priv);
1173 return err;
1174 }
1175
1176 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
1177 1198
1178 return 0;
1179}