aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2009-10-09 16:20:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:47:59 -0400
commit88804e2b33b6ab3974ff2330cd045ca53d6750c5 (patch)
tree1e8d7f27f59774c159e80ad0a9f3bfd6100a525f /drivers
parent008a9e3e3c37abd7f56d2478fe92d5874de3630a (diff)
iwlwifi: dynamic allocate tx queue structure
Instead of always allocate the max number of tx queue structure, use dynamic allocation based on the number of queues in device configuration. With these changes, device does not have to allocate more memory than the h/w can support. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c36
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1
11 files changed, 144 insertions, 59 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 1fc38142a491..a00f947bd59c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -158,6 +158,8 @@ struct iwl_cfg iwl1000_bgn_cfg = {
158 .eeprom_size = OTP_LOW_IMAGE_SIZE, 158 .eeprom_size = OTP_LOW_IMAGE_SIZE,
159 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, 159 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
160 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 160 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
161 .num_of_queues = IWL50_NUM_QUEUES,
162 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
161 .mod_params = &iwl50_mod_params, 163 .mod_params = &iwl50_mod_params,
162 .valid_tx_ant = ANT_A, 164 .valid_tx_ant = ANT_A,
163 .valid_rx_ant = ANT_AB, 165 .valid_rx_ant = ANT_AB,
@@ -179,6 +181,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
179 .eeprom_size = OTP_LOW_IMAGE_SIZE, 181 .eeprom_size = OTP_LOW_IMAGE_SIZE,
180 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, 182 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
181 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 183 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
184 .num_of_queues = IWL50_NUM_QUEUES,
185 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
182 .mod_params = &iwl50_mod_params, 186 .mod_params = &iwl50_mod_params,
183 .valid_tx_ant = ANT_A, 187 .valid_tx_ant = ANT_A,
184 .valid_rx_ant = ANT_AB, 188 .valid_rx_ant = ANT_AB,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 4e15a8e20d09..314cae773646 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -958,6 +958,11 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
958 958
959 iwl3945_hw_txq_ctx_free(priv); 959 iwl3945_hw_txq_ctx_free(priv);
960 960
961 /* allocate tx queue structure */
962 rc = iwl_alloc_txq_mem(priv);
963 if (rc)
964 return rc;
965
961 /* Tx CMD queue */ 966 /* Tx CMD queue */
962 rc = iwl3945_tx_reset(priv); 967 rc = iwl3945_tx_reset(priv);
963 if (rc) 968 if (rc)
@@ -1170,12 +1175,16 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
1170 int txq_id; 1175 int txq_id;
1171 1176
1172 /* Tx queues */ 1177 /* Tx queues */
1173 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) 1178 if (priv->txq)
1174 if (txq_id == IWL_CMD_QUEUE_NUM) 1179 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
1175 iwl_cmd_queue_free(priv); 1180 txq_id++)
1176 else 1181 if (txq_id == IWL_CMD_QUEUE_NUM)
1177 iwl_tx_queue_free(priv, txq_id); 1182 iwl_cmd_queue_free(priv);
1183 else
1184 iwl_tx_queue_free(priv, txq_id);
1178 1185
1186 /* free tx queue structure */
1187 iwl_free_txq_mem(priv);
1179} 1188}
1180 1189
1181void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) 1190void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
@@ -2503,7 +2512,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2503 } 2512 }
2504 2513
2505 /* Assign number of Usable TX queues */ 2514 /* Assign number of Usable TX queues */
2506 priv->hw_params.max_txq_num = IWL39_NUM_QUEUES; 2515 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
2507 2516
2508 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); 2517 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
2509 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K; 2518 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
@@ -2838,6 +2847,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2838 .eeprom_size = IWL3945_EEPROM_IMG_SIZE, 2847 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2839 .eeprom_ver = EEPROM_3945_EEPROM_VERSION, 2848 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2840 .ops = &iwl3945_ops, 2849 .ops = &iwl3945_ops,
2850 .num_of_queues = IWL39_NUM_QUEUES,
2841 .mod_params = &iwl3945_mod_params, 2851 .mod_params = &iwl3945_mod_params,
2842 .use_isr_legacy = true, 2852 .use_isr_legacy = true,
2843 .ht_greenfield_support = false, 2853 .ht_greenfield_support = false,
@@ -2853,6 +2863,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2853 .eeprom_size = IWL3945_EEPROM_IMG_SIZE, 2863 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2854 .eeprom_ver = EEPROM_3945_EEPROM_VERSION, 2864 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2855 .ops = &iwl3945_ops, 2865 .ops = &iwl3945_ops,
2866 .num_of_queues = IWL39_NUM_QUEUES,
2856 .mod_params = &iwl3945_mod_params, 2867 .mod_params = &iwl3945_mod_params,
2857 .use_isr_legacy = true, 2868 .use_isr_legacy = true,
2858 .ht_greenfield_support = false, 2869 .ht_greenfield_support = false,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 966858587e25..c9d90169ab1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -62,8 +62,6 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
62 62
63/* module parameters */ 63/* module parameters */
64static struct iwl_mod_params iwl4965_mod_params = { 64static struct iwl_mod_params iwl4965_mod_params = {
65 .num_of_queues = IWL49_NUM_QUEUES,
66 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
67 .amsdu_size_8K = 1, 65 .amsdu_size_8K = 1,
68 .restart_fw = 1, 66 .restart_fw = 1,
69 /* the rest are 0 by default */ 67 /* the rest are 0 by default */
@@ -698,19 +696,16 @@ static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
698 */ 696 */
699static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) 697static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
700{ 698{
699 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
700 priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES)
701 priv->cfg->num_of_queues =
702 priv->cfg->mod_params->num_of_queues;
701 703
702 if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) || 704 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
703 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
704 IWL_ERR(priv,
705 "invalid queues_num, should be between %d and %d\n",
706 IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
707 return -EINVAL;
708 }
709
710 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
711 priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; 705 priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
712 priv->hw_params.scd_bc_tbls_size = 706 priv->hw_params.scd_bc_tbls_size =
713 IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); 707 priv->cfg->num_of_queues *
708 sizeof(struct iwl4965_scd_bc_tbl);
714 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 709 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
715 priv->hw_params.max_stations = IWL4965_STATION_COUNT; 710 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
716 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; 711 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
@@ -1739,11 +1734,13 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1739 u16 ssn_idx, u8 tx_fifo) 1734 u16 ssn_idx, u8 tx_fifo)
1740{ 1735{
1741 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || 1736 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1742 (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { 1737 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
1738 <= txq_id)) {
1743 IWL_WARN(priv, 1739 IWL_WARN(priv,
1744 "queue number out of range: %d, must be %d to %d\n", 1740 "queue number out of range: %d, must be %d to %d\n",
1745 txq_id, IWL49_FIRST_AMPDU_QUEUE, 1741 txq_id, IWL49_FIRST_AMPDU_QUEUE,
1746 IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); 1742 IWL49_FIRST_AMPDU_QUEUE +
1743 priv->cfg->num_of_ampdu_queues - 1);
1747 return -EINVAL; 1744 return -EINVAL;
1748 } 1745 }
1749 1746
@@ -1804,11 +1801,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1804 u16 ra_tid; 1801 u16 ra_tid;
1805 1802
1806 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || 1803 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1807 (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { 1804 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
1805 <= txq_id)) {
1808 IWL_WARN(priv, 1806 IWL_WARN(priv,
1809 "queue number out of range: %d, must be %d to %d\n", 1807 "queue number out of range: %d, must be %d to %d\n",
1810 txq_id, IWL49_FIRST_AMPDU_QUEUE, 1808 txq_id, IWL49_FIRST_AMPDU_QUEUE,
1811 IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); 1809 IWL49_FIRST_AMPDU_QUEUE +
1810 priv->cfg->num_of_ampdu_queues - 1);
1812 return -EINVAL; 1811 return -EINVAL;
1813 } 1812 }
1814 1813
@@ -2286,6 +2285,8 @@ struct iwl_cfg iwl4965_agn_cfg = {
2286 .eeprom_ver = EEPROM_4965_EEPROM_VERSION, 2285 .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
2287 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, 2286 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
2288 .ops = &iwl4965_ops, 2287 .ops = &iwl4965_ops,
2288 .num_of_queues = IWL49_NUM_QUEUES,
2289 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
2289 .mod_params = &iwl4965_mod_params, 2290 .mod_params = &iwl4965_mod_params,
2290 .use_isr_legacy = true, 2291 .use_isr_legacy = true,
2291 .ht_greenfield_support = false, 2292 .ht_greenfield_support = false,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a9d1aa3ad57b..ab5b9d8d66be 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -749,18 +749,16 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
749 749
750int iwl5000_hw_set_hw_params(struct iwl_priv *priv) 750int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
751{ 751{
752 if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || 752 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
753 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { 753 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
754 IWL_ERR(priv, 754 priv->cfg->num_of_queues =
755 "invalid queues_num, should be between %d and %d\n", 755 priv->cfg->mod_params->num_of_queues;
756 IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
757 return -EINVAL;
758 }
759 756
760 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 757 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
761 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 758 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
762 priv->hw_params.scd_bc_tbls_size = 759 priv->hw_params.scd_bc_tbls_size =
763 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); 760 priv->cfg->num_of_queues *
761 sizeof(struct iwl5000_scd_bc_tbl);
764 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 762 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
765 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 763 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
766 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 764 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
@@ -912,11 +910,13 @@ int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
912 u16 ra_tid; 910 u16 ra_tid;
913 911
914 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || 912 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
915 (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { 913 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
914 <= txq_id)) {
916 IWL_WARN(priv, 915 IWL_WARN(priv,
917 "queue number out of range: %d, must be %d to %d\n", 916 "queue number out of range: %d, must be %d to %d\n",
918 txq_id, IWL50_FIRST_AMPDU_QUEUE, 917 txq_id, IWL50_FIRST_AMPDU_QUEUE,
919 IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); 918 IWL50_FIRST_AMPDU_QUEUE +
919 priv->cfg->num_of_ampdu_queues - 1);
920 return -EINVAL; 920 return -EINVAL;
921 } 921 }
922 922
@@ -970,11 +970,13 @@ int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
970 u16 ssn_idx, u8 tx_fifo) 970 u16 ssn_idx, u8 tx_fifo)
971{ 971{
972 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || 972 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
973 (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { 973 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
974 <= txq_id)) {
974 IWL_ERR(priv, 975 IWL_ERR(priv,
975 "queue number out of range: %d, must be %d to %d\n", 976 "queue number out of range: %d, must be %d to %d\n",
976 txq_id, IWL50_FIRST_AMPDU_QUEUE, 977 txq_id, IWL50_FIRST_AMPDU_QUEUE,
977 IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); 978 IWL50_FIRST_AMPDU_QUEUE +
979 priv->cfg->num_of_ampdu_queues - 1);
978 return -EINVAL; 980 return -EINVAL;
979 } 981 }
980 982
@@ -1584,8 +1586,6 @@ static struct iwl_ops iwl5150_ops = {
1584}; 1586};
1585 1587
1586struct iwl_mod_params iwl50_mod_params = { 1588struct iwl_mod_params iwl50_mod_params = {
1587 .num_of_queues = IWL50_NUM_QUEUES,
1588 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1589 .amsdu_size_8K = 1, 1589 .amsdu_size_8K = 1,
1590 .restart_fw = 1, 1590 .restart_fw = 1,
1591 /* the rest are 0 by default */ 1591 /* the rest are 0 by default */
@@ -1602,6 +1602,8 @@ struct iwl_cfg iwl5300_agn_cfg = {
1602 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1602 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1603 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1603 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1604 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1604 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1605 .num_of_queues = IWL50_NUM_QUEUES,
1606 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1605 .mod_params = &iwl50_mod_params, 1607 .mod_params = &iwl50_mod_params,
1606 .valid_tx_ant = ANT_ABC, 1608 .valid_tx_ant = ANT_ABC,
1607 .valid_rx_ant = ANT_ABC, 1609 .valid_rx_ant = ANT_ABC,
@@ -1621,6 +1623,8 @@ struct iwl_cfg iwl5100_bg_cfg = {
1621 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1623 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1622 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1624 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1623 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1625 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1626 .num_of_queues = IWL50_NUM_QUEUES,
1627 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1624 .mod_params = &iwl50_mod_params, 1628 .mod_params = &iwl50_mod_params,
1625 .valid_tx_ant = ANT_B, 1629 .valid_tx_ant = ANT_B,
1626 .valid_rx_ant = ANT_AB, 1630 .valid_rx_ant = ANT_AB,
@@ -1640,6 +1644,8 @@ struct iwl_cfg iwl5100_abg_cfg = {
1640 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1644 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1641 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1645 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1642 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1646 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1647 .num_of_queues = IWL50_NUM_QUEUES,
1648 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1643 .mod_params = &iwl50_mod_params, 1649 .mod_params = &iwl50_mod_params,
1644 .valid_tx_ant = ANT_B, 1650 .valid_tx_ant = ANT_B,
1645 .valid_rx_ant = ANT_AB, 1651 .valid_rx_ant = ANT_AB,
@@ -1659,6 +1665,8 @@ struct iwl_cfg iwl5100_agn_cfg = {
1659 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1665 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1660 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 1666 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1661 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 1667 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1668 .num_of_queues = IWL50_NUM_QUEUES,
1669 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1662 .mod_params = &iwl50_mod_params, 1670 .mod_params = &iwl50_mod_params,
1663 .valid_tx_ant = ANT_B, 1671 .valid_tx_ant = ANT_B,
1664 .valid_rx_ant = ANT_AB, 1672 .valid_rx_ant = ANT_AB,
@@ -1678,6 +1686,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
1678 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1686 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1679 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 1687 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1680 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 1688 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1689 .num_of_queues = IWL50_NUM_QUEUES,
1690 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1681 .mod_params = &iwl50_mod_params, 1691 .mod_params = &iwl50_mod_params,
1682 .valid_tx_ant = ANT_ABC, 1692 .valid_tx_ant = ANT_ABC,
1683 .valid_rx_ant = ANT_ABC, 1693 .valid_rx_ant = ANT_ABC,
@@ -1697,6 +1707,8 @@ struct iwl_cfg iwl5150_agn_cfg = {
1697 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 1707 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
1698 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 1708 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1699 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 1709 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1710 .num_of_queues = IWL50_NUM_QUEUES,
1711 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
1700 .mod_params = &iwl50_mod_params, 1712 .mod_params = &iwl50_mod_params,
1701 .valid_tx_ant = ANT_A, 1713 .valid_tx_ant = ANT_A,
1702 .valid_rx_ant = ANT_AB, 1714 .valid_rx_ant = ANT_AB,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index dda1dd6ed40a..bdc1c74b6820 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -129,18 +129,16 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
129 129
130static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) 130static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
131{ 131{
132 if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || 132 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
133 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { 133 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
134 IWL_ERR(priv, 134 priv->cfg->num_of_queues =
135 "invalid queues_num, should be between %d and %d\n", 135 priv->cfg->mod_params->num_of_queues;
136 IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
137 return -EINVAL;
138 }
139 136
140 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 137 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
141 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 138 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
142 priv->hw_params.scd_bc_tbls_size = 139 priv->hw_params.scd_bc_tbls_size =
143 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); 140 priv->cfg->num_of_queues *
141 sizeof(struct iwl5000_scd_bc_tbl);
144 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 142 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
145 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 143 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
146 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 144 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
@@ -248,6 +246,8 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
248 .eeprom_size = OTP_LOW_IMAGE_SIZE, 246 .eeprom_size = OTP_LOW_IMAGE_SIZE,
249 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 247 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
250 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 248 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
249 .num_of_queues = IWL50_NUM_QUEUES,
250 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
251 .mod_params = &iwl50_mod_params, 251 .mod_params = &iwl50_mod_params,
252 .valid_tx_ant = ANT_AB, 252 .valid_tx_ant = ANT_AB,
253 .valid_rx_ant = ANT_AB, 253 .valid_rx_ant = ANT_AB,
@@ -272,6 +272,8 @@ struct iwl_cfg iwl6000h_2abg_cfg = {
272 .eeprom_size = OTP_LOW_IMAGE_SIZE, 272 .eeprom_size = OTP_LOW_IMAGE_SIZE,
273 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 273 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
274 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 274 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
275 .num_of_queues = IWL50_NUM_QUEUES,
276 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
275 .mod_params = &iwl50_mod_params, 277 .mod_params = &iwl50_mod_params,
276 .valid_tx_ant = ANT_AB, 278 .valid_tx_ant = ANT_AB,
277 .valid_rx_ant = ANT_AB, 279 .valid_rx_ant = ANT_AB,
@@ -295,6 +297,8 @@ struct iwl_cfg iwl6000h_2bg_cfg = {
295 .eeprom_size = OTP_LOW_IMAGE_SIZE, 297 .eeprom_size = OTP_LOW_IMAGE_SIZE,
296 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 298 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
297 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 299 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
300 .num_of_queues = IWL50_NUM_QUEUES,
301 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
298 .mod_params = &iwl50_mod_params, 302 .mod_params = &iwl50_mod_params,
299 .valid_tx_ant = ANT_AB, 303 .valid_tx_ant = ANT_AB,
300 .valid_rx_ant = ANT_AB, 304 .valid_rx_ant = ANT_AB,
@@ -321,6 +325,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
321 .eeprom_size = OTP_LOW_IMAGE_SIZE, 325 .eeprom_size = OTP_LOW_IMAGE_SIZE,
322 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 326 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
323 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 327 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
328 .num_of_queues = IWL50_NUM_QUEUES,
329 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
324 .mod_params = &iwl50_mod_params, 330 .mod_params = &iwl50_mod_params,
325 .valid_tx_ant = ANT_BC, 331 .valid_tx_ant = ANT_BC,
326 .valid_rx_ant = ANT_BC, 332 .valid_rx_ant = ANT_BC,
@@ -345,6 +351,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
345 .eeprom_size = OTP_LOW_IMAGE_SIZE, 351 .eeprom_size = OTP_LOW_IMAGE_SIZE,
346 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 352 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
347 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 353 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
354 .num_of_queues = IWL50_NUM_QUEUES,
355 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
348 .mod_params = &iwl50_mod_params, 356 .mod_params = &iwl50_mod_params,
349 .valid_tx_ant = ANT_BC, 357 .valid_tx_ant = ANT_BC,
350 .valid_rx_ant = ANT_BC, 358 .valid_rx_ant = ANT_BC,
@@ -368,6 +376,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
368 .eeprom_size = OTP_LOW_IMAGE_SIZE, 376 .eeprom_size = OTP_LOW_IMAGE_SIZE,
369 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 377 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
370 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 378 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
379 .num_of_queues = IWL50_NUM_QUEUES,
380 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
371 .mod_params = &iwl50_mod_params, 381 .mod_params = &iwl50_mod_params,
372 .valid_tx_ant = ANT_BC, 382 .valid_tx_ant = ANT_BC,
373 .valid_rx_ant = ANT_BC, 383 .valid_rx_ant = ANT_BC,
@@ -391,6 +401,8 @@ struct iwl_cfg iwl6050_2agn_cfg = {
391 .eeprom_size = OTP_LOW_IMAGE_SIZE, 401 .eeprom_size = OTP_LOW_IMAGE_SIZE,
392 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 402 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
393 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 403 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
404 .num_of_queues = IWL50_NUM_QUEUES,
405 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
394 .mod_params = &iwl50_mod_params, 406 .mod_params = &iwl50_mod_params,
395 .valid_tx_ant = ANT_AB, 407 .valid_tx_ant = ANT_AB,
396 .valid_rx_ant = ANT_AB, 408 .valid_rx_ant = ANT_AB,
@@ -415,6 +427,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
415 .eeprom_size = OTP_LOW_IMAGE_SIZE, 427 .eeprom_size = OTP_LOW_IMAGE_SIZE,
416 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 428 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
417 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 429 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
430 .num_of_queues = IWL50_NUM_QUEUES,
431 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
418 .mod_params = &iwl50_mod_params, 432 .mod_params = &iwl50_mod_params,
419 .valid_tx_ant = ANT_AB, 433 .valid_tx_ant = ANT_AB,
420 .valid_rx_ant = ANT_AB, 434 .valid_rx_ant = ANT_AB,
@@ -438,6 +452,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
438 .eeprom_size = OTP_LOW_IMAGE_SIZE, 452 .eeprom_size = OTP_LOW_IMAGE_SIZE,
439 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 453 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
440 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 454 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
455 .num_of_queues = IWL50_NUM_QUEUES,
456 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
441 .mod_params = &iwl50_mod_params, 457 .mod_params = &iwl50_mod_params,
442 .valid_tx_ant = ANT_ABC, 458 .valid_tx_ant = ANT_ABC,
443 .valid_rx_ant = ANT_ABC, 459 .valid_rx_ant = ANT_ABC,
@@ -462,6 +478,8 @@ struct iwl_cfg iwl6050_3agn_cfg = {
462 .eeprom_size = OTP_LOW_IMAGE_SIZE, 478 .eeprom_size = OTP_LOW_IMAGE_SIZE,
463 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 479 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
464 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 480 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
481 .num_of_queues = IWL50_NUM_QUEUES,
482 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
465 .mod_params = &iwl50_mod_params, 483 .mod_params = &iwl50_mod_params,
466 .valid_tx_ant = ANT_ABC, 484 .valid_tx_ant = ANT_ABC,
467 .valid_rx_ant = ANT_ABC, 485 .valid_rx_ant = ANT_ABC,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index dc7fd87bed98..c40c7e2dacf8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2826,6 +2826,27 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2826} 2826}
2827EXPORT_SYMBOL(iwl_mac_reset_tsf); 2827EXPORT_SYMBOL(iwl_mac_reset_tsf);
2828 2828
2829int iwl_alloc_txq_mem(struct iwl_priv *priv)
2830{
2831 if (!priv->txq)
2832 priv->txq = kzalloc(
2833 sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues,
2834 GFP_KERNEL);
2835 if (!priv->txq) {
2836 IWL_ERR(priv, "Not enough memory for txq \n");
2837 return -ENOMEM;
2838 }
2839 return 0;
2840}
2841EXPORT_SYMBOL(iwl_alloc_txq_mem);
2842
2843void iwl_free_txq_mem(struct iwl_priv *priv)
2844{
2845 kfree(priv->txq);
2846 priv->txq = NULL;
2847}
2848EXPORT_SYMBOL(iwl_free_txq_mem);
2849
2829#ifdef CONFIG_IWLWIFI_DEBUGFS 2850#ifdef CONFIG_IWLWIFI_DEBUGFS
2830 2851
2831#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES) 2852#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 447eb64e1f69..3679c2ced04d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -204,7 +204,6 @@ struct iwl_mod_params {
204 int sw_crypto; /* def: 0 = using hardware encryption */ 204 int sw_crypto; /* def: 0 = using hardware encryption */
205 int disable_hw_scan; /* def: 0 = use h/w scan */ 205 int disable_hw_scan; /* def: 0 = use h/w scan */
206 int num_of_queues; /* def: HW dependent */ 206 int num_of_queues; /* def: HW dependent */
207 int num_of_ampdu_queues;/* def: HW dependent */
208 int disable_11n; /* def: 0 = 11n capabilities enabled */ 207 int disable_11n; /* def: 0 = 11n capabilities enabled */
209 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ 208 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
210 int antenna; /* def: 0 = both antennas (use diversity) */ 209 int antenna; /* def: 0 = both antennas (use diversity) */
@@ -257,6 +256,8 @@ struct iwl_cfg {
257 int eeprom_size; 256 int eeprom_size;
258 u16 eeprom_ver; 257 u16 eeprom_ver;
259 u16 eeprom_calib_ver; 258 u16 eeprom_calib_ver;
259 int num_of_queues; /* def: HW dependent */
260 int num_of_ampdu_queues;/* def: HW dependent */
260 const struct iwl_ops *ops; 261 const struct iwl_ops *ops;
261 const struct iwl_mod_params *mod_params; 262 const struct iwl_mod_params *mod_params;
262 u8 valid_tx_ant; 263 u8 valid_tx_ant;
@@ -326,6 +327,8 @@ void iwl_config_ap(struct iwl_priv *priv);
326int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, 327int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
327 struct ieee80211_tx_queue_stats *stats); 328 struct ieee80211_tx_queue_stats *stats);
328void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 329void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
330int iwl_alloc_txq_mem(struct iwl_priv *priv);
331void iwl_free_txq_mem(struct iwl_priv *priv);
329#ifdef CONFIG_IWLWIFI_DEBUGFS 332#ifdef CONFIG_IWLWIFI_DEBUGFS
330int iwl_alloc_traffic_mem(struct iwl_priv *priv); 333int iwl_alloc_traffic_mem(struct iwl_priv *priv);
331void iwl_free_traffic_mem(struct iwl_priv *priv); 334void iwl_free_traffic_mem(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index aa62357c9151..028d4bf8dcd8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -884,10 +884,14 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
884 struct iwl_rx_queue *rxq = &priv->rxq; 884 struct iwl_rx_queue *rxq = &priv->rxq;
885 char *buf; 885 char *buf;
886 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + 886 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
887 (IWL_MAX_NUM_QUEUES * 32 * 8) + 400; 887 (priv->cfg->num_of_queues * 32 * 8) + 400;
888 const u8 *ptr; 888 const u8 *ptr;
889 ssize_t ret; 889 ssize_t ret;
890 890
891 if (!priv->txq) {
892 IWL_ERR(priv, "txq not ready\n");
893 return -EAGAIN;
894 }
891 buf = kzalloc(bufsz, GFP_KERNEL); 895 buf = kzalloc(bufsz, GFP_KERNEL);
892 if (!buf) { 896 if (!buf) {
893 IWL_ERR(priv, "Can not allocate buffer\n"); 897 IWL_ERR(priv, "Can not allocate buffer\n");
@@ -979,8 +983,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
979 int pos = 0; 983 int pos = 0;
980 int cnt; 984 int cnt;
981 int ret; 985 int ret;
982 const size_t bufsz = sizeof(char) * 60 * IWL_MAX_NUM_QUEUES; 986 const size_t bufsz = sizeof(char) * 60 * priv->cfg->num_of_queues;
983 987
988 if (!priv->txq) {
989 IWL_ERR(priv, "txq not ready\n");
990 return -EAGAIN;
991 }
984 buf = kzalloc(bufsz, GFP_KERNEL); 992 buf = kzalloc(bufsz, GFP_KERNEL);
985 if (!buf) 993 if (!buf)
986 return -ENOMEM; 994 return -ENOMEM;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index c1b07e2045e6..6d7c2350d8c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -974,8 +974,6 @@ struct traffic_stats {
974}; 974};
975#endif 975#endif
976 976
977#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
978
979struct iwl_priv { 977struct iwl_priv {
980 978
981 /* ieee device used by generic ieee processing code */ 979 /* ieee device used by generic ieee processing code */
@@ -1103,7 +1101,7 @@ struct iwl_priv {
1103 1101
1104 /* Rx and Tx DMA processing queues */ 1102 /* Rx and Tx DMA processing queues */
1105 struct iwl_rx_queue rxq; 1103 struct iwl_rx_queue rxq;
1106 struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES]; 1104 struct iwl_tx_queue *txq;
1107 unsigned long txq_ctx_active_msk; 1105 unsigned long txq_ctx_active_msk;
1108 struct iwl_dma_ptr kw; /* keep warm address */ 1106 struct iwl_dma_ptr kw; /* keep warm address */
1109 struct iwl_dma_ptr scd_bc_tbls; 1107 struct iwl_dma_ptr scd_bc_tbls;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index c832ba085dba..625da63d01ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -405,15 +405,19 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
405 int txq_id; 405 int txq_id;
406 406
407 /* Tx queues */ 407 /* Tx queues */
408 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) 408 if (priv->txq)
409 if (txq_id == IWL_CMD_QUEUE_NUM) 409 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
410 iwl_cmd_queue_free(priv); 410 txq_id++)
411 else 411 if (txq_id == IWL_CMD_QUEUE_NUM)
412 iwl_tx_queue_free(priv, txq_id); 412 iwl_cmd_queue_free(priv);
413 413 else
414 iwl_tx_queue_free(priv, txq_id);
414 iwl_free_dma_ptr(priv, &priv->kw); 415 iwl_free_dma_ptr(priv, &priv->kw);
415 416
416 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); 417 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
418
419 /* free tx queue structure */
420 iwl_free_txq_mem(priv);
417} 421}
418EXPORT_SYMBOL(iwl_hw_txq_ctx_free); 422EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
419 423
@@ -445,6 +449,12 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
445 IWL_ERR(priv, "Keep Warm allocation failed\n"); 449 IWL_ERR(priv, "Keep Warm allocation failed\n");
446 goto error_kw; 450 goto error_kw;
447 } 451 }
452
453 /* allocate tx queue structure */
454 ret = iwl_alloc_txq_mem(priv);
455 if (ret)
456 goto error;
457
448 spin_lock_irqsave(&priv->lock, flags); 458 spin_lock_irqsave(&priv->lock, flags);
449 459
450 /* Turn off all Tx DMA fifos */ 460 /* Turn off all Tx DMA fifos */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index e0e566c932c5..66da441fe366 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -88,7 +88,6 @@ MODULE_LICENSE("GPL");
88 88
89 /* module parameters */ 89 /* module parameters */
90struct iwl_mod_params iwl3945_mod_params = { 90struct iwl_mod_params iwl3945_mod_params = {
91 .num_of_queues = IWL39_NUM_QUEUES, /* Not used */
92 .sw_crypto = 1, 91 .sw_crypto = 1,
93 .restart_fw = 1, 92 .restart_fw = 1,
94 /* the rest are 0 by default */ 93 /* the rest are 0 by default */