aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c412
1 files changed, 239 insertions, 173 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 527525cc0919..46288e724889 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -98,7 +98,6 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
98 * ... and set IWL_EVT_DISABLE to 1. */ 98 * ... and set IWL_EVT_DISABLE to 1. */
99void iwl3945_disable_events(struct iwl_priv *priv) 99void iwl3945_disable_events(struct iwl_priv *priv)
100{ 100{
101 int ret;
102 int i; 101 int i;
103 u32 base; /* SRAM address of event log header */ 102 u32 base; /* SRAM address of event log header */
104 u32 disable_ptr; /* SRAM address of event-disable bitmap array */ 103 u32 disable_ptr; /* SRAM address of event-disable bitmap array */
@@ -159,26 +158,17 @@ void iwl3945_disable_events(struct iwl_priv *priv)
159 return; 158 return;
160 } 159 }
161 160
162 ret = iwl_grab_nic_access(priv);
163 if (ret) {
164 IWL_WARN(priv, "Can not read from adapter at this time.\n");
165 return;
166 }
167
168 disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32))); 161 disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
169 array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32))); 162 array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
170 iwl_release_nic_access(priv);
171 163
172 if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { 164 if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
173 IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n", 165 IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
174 disable_ptr); 166 disable_ptr);
175 ret = iwl_grab_nic_access(priv);
176 for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) 167 for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
177 iwl_write_targ_mem(priv, 168 iwl_write_targ_mem(priv,
178 disable_ptr + (i * sizeof(u32)), 169 disable_ptr + (i * sizeof(u32)),
179 evt_disable[i]); 170 evt_disable[i]);
180 171
181 iwl_release_nic_access(priv);
182 } else { 172 } else {
183 IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n"); 173 IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n");
184 IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n"); 174 IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n");
@@ -779,35 +769,6 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
779 return ; 769 return ;
780} 770}
781 771
782u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
783{
784 int i, start = IWL_AP_ID;
785 int ret = IWL_INVALID_STATION;
786 unsigned long flags;
787
788 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
789 (priv->iw_mode == NL80211_IFTYPE_AP))
790 start = IWL_STA_ID;
791
792 if (is_broadcast_ether_addr(addr))
793 return priv->hw_params.bcast_sta_id;
794
795 spin_lock_irqsave(&priv->sta_lock, flags);
796 for (i = start; i < priv->hw_params.max_stations; i++)
797 if ((priv->stations_39[i].used) &&
798 (!compare_ether_addr
799 (priv->stations_39[i].sta.sta.addr, addr))) {
800 ret = i;
801 goto out;
802 }
803
804 IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
805 addr, priv->num_stations);
806 out:
807 spin_unlock_irqrestore(&priv->sta_lock, flags);
808 return ret;
809}
810
811/** 772/**
812 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: 773 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
813 * 774 *
@@ -885,13 +846,13 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
885u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) 846u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
886{ 847{
887 unsigned long flags_spin; 848 unsigned long flags_spin;
888 struct iwl3945_station_entry *station; 849 struct iwl_station_entry *station;
889 850
890 if (sta_id == IWL_INVALID_STATION) 851 if (sta_id == IWL_INVALID_STATION)
891 return IWL_INVALID_STATION; 852 return IWL_INVALID_STATION;
892 853
893 spin_lock_irqsave(&priv->sta_lock, flags_spin); 854 spin_lock_irqsave(&priv->sta_lock, flags_spin);
894 station = &priv->stations_39[sta_id]; 855 station = &priv->stations[sta_id];
895 856
896 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; 857 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
897 station->sta.rate_n_flags = cpu_to_le16(tx_rate); 858 station->sta.rate_n_flags = cpu_to_le16(tx_rate);
@@ -899,8 +860,7 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
899 860
900 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 861 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
901 862
902 iwl_send_add_sta(priv, 863 iwl_send_add_sta(priv, &station->sta, flags);
903 (struct iwl_addsta_cmd *)&station->sta, flags);
904 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", 864 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
905 sta_id, tx_rate); 865 sta_id, tx_rate);
906 return sta_id; 866 return sta_id;
@@ -908,55 +868,30 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
908 868
909static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) 869static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
910{ 870{
911 int ret;
912 unsigned long flags;
913
914 spin_lock_irqsave(&priv->lock, flags);
915 ret = iwl_grab_nic_access(priv);
916 if (ret) {
917 spin_unlock_irqrestore(&priv->lock, flags);
918 return ret;
919 }
920
921 if (src == IWL_PWR_SRC_VAUX) { 871 if (src == IWL_PWR_SRC_VAUX) {
922 if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { 872 if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
923 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, 873 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
924 APMG_PS_CTRL_VAL_PWR_SRC_VAUX, 874 APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
925 ~APMG_PS_CTRL_MSK_PWR_SRC); 875 ~APMG_PS_CTRL_MSK_PWR_SRC);
926 iwl_release_nic_access(priv);
927 876
928 iwl_poll_bit(priv, CSR_GPIO_IN, 877 iwl_poll_bit(priv, CSR_GPIO_IN,
929 CSR_GPIO_IN_VAL_VAUX_PWR_SRC, 878 CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
930 CSR_GPIO_IN_BIT_AUX_POWER, 5000); 879 CSR_GPIO_IN_BIT_AUX_POWER, 5000);
931 } else {
932 iwl_release_nic_access(priv);
933 } 880 }
934 } else { 881 } else {
935 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, 882 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
936 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, 883 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
937 ~APMG_PS_CTRL_MSK_PWR_SRC); 884 ~APMG_PS_CTRL_MSK_PWR_SRC);
938 885
939 iwl_release_nic_access(priv);
940 iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, 886 iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
941 CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ 887 CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */
942 } 888 }
943 spin_unlock_irqrestore(&priv->lock, flags);
944 889
945 return ret; 890 return 0;
946} 891}
947 892
948static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) 893static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
949{ 894{
950 int rc;
951 unsigned long flags;
952
953 spin_lock_irqsave(&priv->lock, flags);
954 rc = iwl_grab_nic_access(priv);
955 if (rc) {
956 spin_unlock_irqrestore(&priv->lock, flags);
957 return rc;
958 }
959
960 iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr); 895 iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr);
961 iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma); 896 iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
962 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0); 897 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
@@ -973,23 +908,11 @@ static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
973 /* fake read to flush all prev I/O */ 908 /* fake read to flush all prev I/O */
974 iwl_read_direct32(priv, FH39_RSSR_CTRL); 909 iwl_read_direct32(priv, FH39_RSSR_CTRL);
975 910
976 iwl_release_nic_access(priv);
977 spin_unlock_irqrestore(&priv->lock, flags);
978
979 return 0; 911 return 0;
980} 912}
981 913
982static int iwl3945_tx_reset(struct iwl_priv *priv) 914static int iwl3945_tx_reset(struct iwl_priv *priv)
983{ 915{
984 int rc;
985 unsigned long flags;
986
987 spin_lock_irqsave(&priv->lock, flags);
988 rc = iwl_grab_nic_access(priv);
989 if (rc) {
990 spin_unlock_irqrestore(&priv->lock, flags);
991 return rc;
992 }
993 916
994 /* bypass mode */ 917 /* bypass mode */
995 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2); 918 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
@@ -1017,8 +940,6 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
1017 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | 940 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
1018 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); 941 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
1019 942
1020 iwl_release_nic_access(priv);
1021 spin_unlock_irqrestore(&priv->lock, flags);
1022 943
1023 return 0; 944 return 0;
1024} 945}
@@ -1061,7 +982,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
1061 982
1062static int iwl3945_apm_init(struct iwl_priv *priv) 983static int iwl3945_apm_init(struct iwl_priv *priv)
1063{ 984{
1064 int ret = 0; 985 int ret;
1065 986
1066 iwl_power_initialize(priv); 987 iwl_power_initialize(priv);
1067 988
@@ -1083,10 +1004,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
1083 goto out; 1004 goto out;
1084 } 1005 }
1085 1006
1086 ret = iwl_grab_nic_access(priv);
1087 if (ret)
1088 goto out;
1089
1090 /* enable DMA */ 1007 /* enable DMA */
1091 iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT | 1008 iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
1092 APMG_CLK_VAL_BSM_CLK_RQT); 1009 APMG_CLK_VAL_BSM_CLK_RQT);
@@ -1097,7 +1014,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
1097 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, 1014 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
1098 APMG_PCIDEV_STT_VAL_L1_ACT_DIS); 1015 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1099 1016
1100 iwl_release_nic_access(priv);
1101out: 1017out:
1102 return ret; 1018 return ret;
1103} 1019}
@@ -1110,6 +1026,11 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
1110 1026
1111 spin_lock_irqsave(&priv->lock, flags); 1027 spin_lock_irqsave(&priv->lock, flags);
1112 1028
1029 /* Determine HW type */
1030 pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
1031
1032 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1033
1113 if (rev_id & PCI_CFG_REV_ID_BIT_RTP) 1034 if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
1114 IWL_DEBUG_INFO(priv, "RTP type \n"); 1035 IWL_DEBUG_INFO(priv, "RTP type \n");
1115 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { 1036 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
@@ -1163,7 +1084,6 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
1163 1084
1164int iwl3945_hw_nic_init(struct iwl_priv *priv) 1085int iwl3945_hw_nic_init(struct iwl_priv *priv)
1165{ 1086{
1166 u8 rev_id;
1167 int rc; 1087 int rc;
1168 unsigned long flags; 1088 unsigned long flags;
1169 struct iwl_rx_queue *rxq = &priv->rxq; 1089 struct iwl_rx_queue *rxq = &priv->rxq;
@@ -1172,12 +1092,6 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
1172 priv->cfg->ops->lib->apm_ops.init(priv); 1092 priv->cfg->ops->lib->apm_ops.init(priv);
1173 spin_unlock_irqrestore(&priv->lock, flags); 1093 spin_unlock_irqrestore(&priv->lock, flags);
1174 1094
1175 /* Determine HW type */
1176 rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
1177 if (rc)
1178 return rc;
1179 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1180
1181 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); 1095 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
1182 if (rc) 1096 if (rc)
1183 return rc; 1097 return rc;
@@ -1198,22 +1112,13 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
1198 1112
1199 iwl3945_rx_init(priv, rxq); 1113 iwl3945_rx_init(priv, rxq);
1200 1114
1201 spin_lock_irqsave(&priv->lock, flags);
1202 1115
1203 /* Look at using this instead: 1116 /* Look at using this instead:
1204 rxq->need_update = 1; 1117 rxq->need_update = 1;
1205 iwl_rx_queue_update_write_ptr(priv, rxq); 1118 iwl_rx_queue_update_write_ptr(priv, rxq);
1206 */ 1119 */
1207 1120
1208 rc = iwl_grab_nic_access(priv);
1209 if (rc) {
1210 spin_unlock_irqrestore(&priv->lock, flags);
1211 return rc;
1212 }
1213 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7); 1121 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
1214 iwl_release_nic_access(priv);
1215
1216 spin_unlock_irqrestore(&priv->lock, flags);
1217 1122
1218 rc = iwl3945_txq_ctx_reset(priv); 1123 rc = iwl3945_txq_ctx_reset(priv);
1219 if (rc) 1124 if (rc)
@@ -1245,14 +1150,6 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
1245void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) 1150void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
1246{ 1151{
1247 int txq_id; 1152 int txq_id;
1248 unsigned long flags;
1249
1250 spin_lock_irqsave(&priv->lock, flags);
1251 if (iwl_grab_nic_access(priv)) {
1252 spin_unlock_irqrestore(&priv->lock, flags);
1253 iwl3945_hw_txq_ctx_free(priv);
1254 return;
1255 }
1256 1153
1257 /* stop SCD */ 1154 /* stop SCD */
1258 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); 1155 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
@@ -1265,9 +1162,6 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
1265 1000); 1162 1000);
1266 } 1163 }
1267 1164
1268 iwl_release_nic_access(priv);
1269 spin_unlock_irqrestore(&priv->lock, flags);
1270
1271 iwl3945_hw_txq_ctx_free(priv); 1165 iwl3945_hw_txq_ctx_free(priv);
1272} 1166}
1273 1167
@@ -1312,12 +1206,8 @@ static void iwl3945_apm_stop(struct iwl_priv *priv)
1312 1206
1313static int iwl3945_apm_reset(struct iwl_priv *priv) 1207static int iwl3945_apm_reset(struct iwl_priv *priv)
1314{ 1208{
1315 int rc;
1316 unsigned long flags;
1317
1318 iwl3945_apm_stop_master(priv); 1209 iwl3945_apm_stop_master(priv);
1319 1210
1320 spin_lock_irqsave(&priv->lock, flags);
1321 1211
1322 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); 1212 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
1323 udelay(10); 1213 udelay(10);
@@ -1327,36 +1217,31 @@ static int iwl3945_apm_reset(struct iwl_priv *priv)
1327 iwl_poll_direct_bit(priv, CSR_GP_CNTRL, 1217 iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
1328 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); 1218 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
1329 1219
1330 rc = iwl_grab_nic_access(priv); 1220 iwl_write_prph(priv, APMG_CLK_CTRL_REG,
1331 if (!rc) { 1221 APMG_CLK_VAL_BSM_CLK_RQT);
1332 iwl_write_prph(priv, APMG_CLK_CTRL_REG,
1333 APMG_CLK_VAL_BSM_CLK_RQT);
1334 1222
1335 iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); 1223 iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
1336 iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 1224 iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
1337 0xFFFFFFFF); 1225 0xFFFFFFFF);
1338 1226
1339 /* enable DMA */ 1227 /* enable DMA */
1340 iwl_write_prph(priv, APMG_CLK_EN_REG, 1228 iwl_write_prph(priv, APMG_CLK_EN_REG,
1341 APMG_CLK_VAL_DMA_CLK_RQT | 1229 APMG_CLK_VAL_DMA_CLK_RQT |
1342 APMG_CLK_VAL_BSM_CLK_RQT); 1230 APMG_CLK_VAL_BSM_CLK_RQT);
1343 udelay(10); 1231 udelay(10);
1344 1232
1345 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, 1233 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
1346 APMG_PS_CTRL_VAL_RESET_REQ); 1234 APMG_PS_CTRL_VAL_RESET_REQ);
1347 udelay(5); 1235 udelay(5);
1348 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, 1236 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
1349 APMG_PS_CTRL_VAL_RESET_REQ); 1237 APMG_PS_CTRL_VAL_RESET_REQ);
1350 iwl_release_nic_access(priv);
1351 }
1352 1238
1353 /* Clear the 'host command active' bit... */ 1239 /* Clear the 'host command active' bit... */
1354 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1240 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1355 1241
1356 wake_up_interruptible(&priv->wait_command_queue); 1242 wake_up_interruptible(&priv->wait_command_queue);
1357 spin_unlock_irqrestore(&priv->lock, flags);
1358 1243
1359 return rc; 1244 return 0;
1360} 1245}
1361 1246
1362/** 1247/**
@@ -1964,6 +1849,193 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
1964 return 0; 1849 return 0;
1965} 1850}
1966 1851
1852static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1853{
1854 int rc = 0;
1855 struct iwl_rx_packet *res = NULL;
1856 struct iwl3945_rxon_assoc_cmd rxon_assoc;
1857 struct iwl_host_cmd cmd = {
1858 .id = REPLY_RXON_ASSOC,
1859 .len = sizeof(rxon_assoc),
1860 .meta.flags = CMD_WANT_SKB,
1861 .data = &rxon_assoc,
1862 };
1863 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
1864 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
1865
1866 if ((rxon1->flags == rxon2->flags) &&
1867 (rxon1->filter_flags == rxon2->filter_flags) &&
1868 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
1869 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
1870 IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
1871 return 0;
1872 }
1873
1874 rxon_assoc.flags = priv->staging_rxon.flags;
1875 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
1876 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
1877 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
1878 rxon_assoc.reserved = 0;
1879
1880 rc = iwl_send_cmd_sync(priv, &cmd);
1881 if (rc)
1882 return rc;
1883
1884 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
1885 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
1886 IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
1887 rc = -EIO;
1888 }
1889
1890 priv->alloc_rxb_skb--;
1891 dev_kfree_skb_any(cmd.meta.u.skb);
1892
1893 return rc;
1894}
1895
1896/**
1897 * iwl3945_commit_rxon - commit staging_rxon to hardware
1898 *
1899 * The RXON command in staging_rxon is committed to the hardware and
1900 * the active_rxon structure is updated with the new data. This
1901 * function correctly transitions out of the RXON_ASSOC_MSK state if
1902 * a HW tune is required based on the RXON structure changes.
1903 */
1904static int iwl3945_commit_rxon(struct iwl_priv *priv)
1905{
1906 /* cast away the const for active_rxon in this function */
1907 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
1908 struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
1909 int rc = 0;
1910 bool new_assoc =
1911 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
1912
1913 if (!iwl_is_alive(priv))
1914 return -1;
1915
1916 /* always get timestamp with Rx frame */
1917 staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
1918
1919 /* select antenna */
1920 staging_rxon->flags &=
1921 ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
1922 staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
1923
1924 rc = iwl_check_rxon_cmd(priv);
1925 if (rc) {
1926 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
1927 return -EINVAL;
1928 }
1929
1930 /* If we don't need to send a full RXON, we can use
1931 * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
1932 * and other flags for the current radio configuration. */
1933 if (!iwl_full_rxon_required(priv)) {
1934 rc = iwl_send_rxon_assoc(priv);
1935 if (rc) {
1936 IWL_ERR(priv, "Error setting RXON_ASSOC "
1937 "configuration (%d).\n", rc);
1938 return rc;
1939 }
1940
1941 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
1942
1943 return 0;
1944 }
1945
1946 /* If we are currently associated and the new config requires
1947 * an RXON_ASSOC and the new config wants the associated mask enabled,
1948 * we must clear the associated from the active configuration
1949 * before we apply the new config */
1950 if (iwl_is_associated(priv) && new_assoc) {
1951 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
1952 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1953
1954 /*
1955 * reserved4 and 5 could have been filled by the iwlcore code.
1956 * Let's clear them before pushing to the 3945.
1957 */
1958 active_rxon->reserved4 = 0;
1959 active_rxon->reserved5 = 0;
1960 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
1961 sizeof(struct iwl3945_rxon_cmd),
1962 &priv->active_rxon);
1963
1964 /* If the mask clearing failed then we set
1965 * active_rxon back to what it was previously */
1966 if (rc) {
1967 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
1968 IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
1969 "configuration (%d).\n", rc);
1970 return rc;
1971 }
1972 }
1973
1974 IWL_DEBUG_INFO(priv, "Sending RXON\n"
1975 "* with%s RXON_FILTER_ASSOC_MSK\n"
1976 "* channel = %d\n"
1977 "* bssid = %pM\n",
1978 (new_assoc ? "" : "out"),
1979 le16_to_cpu(staging_rxon->channel),
1980 staging_rxon->bssid_addr);
1981
1982 /*
1983 * reserved4 and 5 could have been filled by the iwlcore code.
1984 * Let's clear them before pushing to the 3945.
1985 */
1986 staging_rxon->reserved4 = 0;
1987 staging_rxon->reserved5 = 0;
1988
1989 iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
1990
1991 /* Apply the new configuration */
1992 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
1993 sizeof(struct iwl3945_rxon_cmd),
1994 staging_rxon);
1995 if (rc) {
1996 IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
1997 return rc;
1998 }
1999
2000 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
2001
2002 iwl_clear_stations_table(priv);
2003
2004 /* If we issue a new RXON command which required a tune then we must
2005 * send a new TXPOWER command or we won't be able to Tx any frames */
2006 rc = priv->cfg->ops->lib->send_tx_power(priv);
2007 if (rc) {
2008 IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
2009 return rc;
2010 }
2011
2012 /* Add the broadcast address so we can send broadcast frames */
2013 if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) ==
2014 IWL_INVALID_STATION) {
2015 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
2016 return -EIO;
2017 }
2018
2019 /* If we have set the ASSOC_MSK and we are in BSS mode then
2020 * add the IWL_AP_ID to the station rate table */
2021 if (iwl_is_associated(priv) &&
2022 (priv->iw_mode == NL80211_IFTYPE_STATION))
2023 if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
2024 true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
2025 IWL_ERR(priv, "Error adding AP address for transmit\n");
2026 return -EIO;
2027 }
2028
2029 /* Init the hardware's rate fallback order based on the band */
2030 rc = iwl3945_init_hw_rate_table(priv);
2031 if (rc) {
2032 IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
2033 return -EIO;
2034 }
2035
2036 return 0;
2037}
2038
1967/* will add 3945 channel switch cmd handling later */ 2039/* will add 3945 channel switch cmd handling later */
1968int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel) 2040int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1969{ 2041{
@@ -2314,14 +2386,6 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
2314int iwl3945_hw_rxq_stop(struct iwl_priv *priv) 2386int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
2315{ 2387{
2316 int rc; 2388 int rc;
2317 unsigned long flags;
2318
2319 spin_lock_irqsave(&priv->lock, flags);
2320 rc = iwl_grab_nic_access(priv);
2321 if (rc) {
2322 spin_unlock_irqrestore(&priv->lock, flags);
2323 return rc;
2324 }
2325 2389
2326 iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0); 2390 iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
2327 rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS, 2391 rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
@@ -2329,28 +2393,17 @@ int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
2329 if (rc < 0) 2393 if (rc < 0)
2330 IWL_ERR(priv, "Can't stop Rx DMA.\n"); 2394 IWL_ERR(priv, "Can't stop Rx DMA.\n");
2331 2395
2332 iwl_release_nic_access(priv);
2333 spin_unlock_irqrestore(&priv->lock, flags);
2334
2335 return 0; 2396 return 0;
2336} 2397}
2337 2398
2338int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) 2399int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
2339{ 2400{
2340 int rc;
2341 unsigned long flags;
2342 int txq_id = txq->q.id; 2401 int txq_id = txq->q.id;
2343 2402
2344 struct iwl3945_shared *shared_data = priv->shared_virt; 2403 struct iwl3945_shared *shared_data = priv->shared_virt;
2345 2404
2346 shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); 2405 shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
2347 2406
2348 spin_lock_irqsave(&priv->lock, flags);
2349 rc = iwl_grab_nic_access(priv);
2350 if (rc) {
2351 spin_unlock_irqrestore(&priv->lock, flags);
2352 return rc;
2353 }
2354 iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0); 2407 iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
2355 iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0); 2408 iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
2356 2409
@@ -2360,11 +2413,9 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
2360 FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | 2413 FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
2361 FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | 2414 FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
2362 FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); 2415 FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
2363 iwl_release_nic_access(priv);
2364 2416
2365 /* fake read to flush all prev. writes */ 2417 /* fake read to flush all prev. writes */
2366 iwl_read32(priv, FH39_TSSR_CBB_BASE); 2418 iwl_read32(priv, FH39_TSSR_CBB_BASE);
2367 spin_unlock_irqrestore(&priv->lock, flags);
2368 2419
2369 return 0; 2420 return 0;
2370} 2421}
@@ -2384,13 +2435,25 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
2384 } 2435 }
2385} 2436}
2386 2437
2438
2387static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 2439static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2388{ 2440{
2389 u16 size = (u16)sizeof(struct iwl3945_addsta_cmd); 2441 struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data;
2390 memcpy(data, cmd, size); 2442 addsta->mode = cmd->mode;
2391 return size; 2443 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
2444 memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
2445 addsta->station_flags = cmd->station_flags;
2446 addsta->station_flags_msk = cmd->station_flags_msk;
2447 addsta->tid_disable_tx = cpu_to_le16(0);
2448 addsta->rate_n_flags = cmd->rate_n_flags;
2449 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
2450 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
2451 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
2452
2453 return (u16)sizeof(struct iwl3945_addsta_cmd);
2392} 2454}
2393 2455
2456
2394/** 2457/**
2395 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table 2458 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
2396 */ 2459 */
@@ -2672,10 +2735,6 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
2672 inst_len = priv->ucode_init.len; 2735 inst_len = priv->ucode_init.len;
2673 data_len = priv->ucode_init_data.len; 2736 data_len = priv->ucode_init_data.len;
2674 2737
2675 rc = iwl_grab_nic_access(priv);
2676 if (rc)
2677 return rc;
2678
2679 iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); 2738 iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
2680 iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); 2739 iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
2681 iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); 2740 iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
@@ -2689,10 +2748,8 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
2689 le32_to_cpu(*image)); 2748 le32_to_cpu(*image));
2690 2749
2691 rc = iwl3945_verify_bsm(priv); 2750 rc = iwl3945_verify_bsm(priv);
2692 if (rc) { 2751 if (rc)
2693 iwl_release_nic_access(priv);
2694 return rc; 2752 return rc;
2695 }
2696 2753
2697 /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ 2754 /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
2698 iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); 2755 iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
@@ -2724,11 +2781,14 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
2724 iwl_write_prph(priv, BSM_WR_CTRL_REG, 2781 iwl_write_prph(priv, BSM_WR_CTRL_REG,
2725 BSM_WR_CTRL_REG_BIT_START_EN); 2782 BSM_WR_CTRL_REG_BIT_START_EN);
2726 2783
2727 iwl_release_nic_access(priv);
2728
2729 return 0; 2784 return 0;
2730} 2785}
2731 2786
2787static struct iwl_hcmd_ops iwl3945_hcmd = {
2788 .rxon_assoc = iwl3945_send_rxon_assoc,
2789 .commit_rxon = iwl3945_commit_rxon,
2790};
2791
2732static struct iwl_lib_ops iwl3945_lib = { 2792static struct iwl_lib_ops iwl3945_lib = {
2733 .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, 2793 .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
2734 .txq_free_tfd = iwl3945_hw_txq_free_tfd, 2794 .txq_free_tfd = iwl3945_hw_txq_free_tfd,
@@ -2758,6 +2818,9 @@ static struct iwl_lib_ops iwl3945_lib = {
2758 }, 2818 },
2759 .send_tx_power = iwl3945_send_tx_power, 2819 .send_tx_power = iwl3945_send_tx_power,
2760 .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, 2820 .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
2821 .post_associate = iwl3945_post_associate,
2822 .isr = iwl_isr_legacy,
2823 .config_ap = iwl3945_config_ap,
2761}; 2824};
2762 2825
2763static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2826static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2767,6 +2830,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2767 2830
2768static struct iwl_ops iwl3945_ops = { 2831static struct iwl_ops iwl3945_ops = {
2769 .lib = &iwl3945_lib, 2832 .lib = &iwl3945_lib,
2833 .hcmd = &iwl3945_hcmd,
2770 .utils = &iwl3945_hcmd_utils, 2834 .utils = &iwl3945_hcmd_utils,
2771}; 2835};
2772 2836
@@ -2779,7 +2843,8 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2779 .eeprom_size = IWL3945_EEPROM_IMG_SIZE, 2843 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2780 .eeprom_ver = EEPROM_3945_EEPROM_VERSION, 2844 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2781 .ops = &iwl3945_ops, 2845 .ops = &iwl3945_ops,
2782 .mod_params = &iwl3945_mod_params 2846 .mod_params = &iwl3945_mod_params,
2847 .use_isr_legacy = true
2783}; 2848};
2784 2849
2785static struct iwl_cfg iwl3945_abg_cfg = { 2850static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2791,7 +2856,8 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2791 .eeprom_size = IWL3945_EEPROM_IMG_SIZE, 2856 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2792 .eeprom_ver = EEPROM_3945_EEPROM_VERSION, 2857 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2793 .ops = &iwl3945_ops, 2858 .ops = &iwl3945_ops,
2794 .mod_params = &iwl3945_mod_params 2859 .mod_params = &iwl3945_mod_params,
2860 .use_isr_legacy = true
2795}; 2861};
2796 2862
2797struct pci_device_id iwl3945_hw_card_ids[] = { 2863struct pci_device_id iwl3945_hw_card_ids[] = {