diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-03-16 15:37:24 -0400 |
---|---|---|
committer | Reinette Chatre <reinette.chatre@intel.com> | 2010-03-25 14:18:20 -0400 |
commit | 741a626627e42812afd957f875c34c89be8a103e (patch) | |
tree | c45d47757df649ed33f2d583ceff0edc96955080 | |
parent | 19e6cda094002e9756a3d181cbb4c31ef2a9b6bb (diff) |
iwlwifi: move ucode alive related code to separate file
uCode alive for iwlagn based devices share the same functions.
Move those functions from iwl-5000.c to iwl-agn-ucode.c.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-1000.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 239 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-6000.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 230 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 12 |
5 files changed, 251 insertions, 242 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index f866410ea9d8..9d211606c040 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -178,8 +178,8 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
178 | .dump_nic_error_log = iwl_dump_nic_error_log, | 178 | .dump_nic_error_log = iwl_dump_nic_error_log, |
179 | .dump_csr = iwl_dump_csr, | 179 | .dump_csr = iwl_dump_csr, |
180 | .dump_fh = iwl_dump_fh, | 180 | .dump_fh = iwl_dump_fh, |
181 | .init_alive_start = iwl5000_init_alive_start, | 181 | .init_alive_start = iwlagn_init_alive_start, |
182 | .alive_notify = iwl5000_alive_notify, | 182 | .alive_notify = iwlagn_alive_notify, |
183 | .send_tx_power = iwl5000_send_tx_power, | 183 | .send_tx_power = iwl5000_send_tx_power, |
184 | .update_chain_flags = iwl_update_chain_flags, | 184 | .update_chain_flags = iwl_update_chain_flags, |
185 | .apm_ops = { | 185 | .apm_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index a41af47c1926..9128ccd8dfae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -65,19 +65,6 @@ | |||
65 | #define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" | 65 | #define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" |
66 | #define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) | 66 | #define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) |
67 | 67 | ||
68 | static const s8 iwl5000_default_queue_to_tx_fifo[] = { | ||
69 | IWL_TX_FIFO_VO, | ||
70 | IWL_TX_FIFO_VI, | ||
71 | IWL_TX_FIFO_BE, | ||
72 | IWL_TX_FIFO_BK, | ||
73 | IWLAGN_CMD_FIFO_NUM, | ||
74 | IWL_TX_FIFO_UNUSED, | ||
75 | IWL_TX_FIFO_UNUSED, | ||
76 | IWL_TX_FIFO_UNUSED, | ||
77 | IWL_TX_FIFO_UNUSED, | ||
78 | IWL_TX_FIFO_UNUSED, | ||
79 | }; | ||
80 | |||
81 | /* NIC configuration for 5000 series */ | 68 | /* NIC configuration for 5000 series */ |
82 | void iwl5000_nic_config(struct iwl_priv *priv) | 69 | void iwl5000_nic_config(struct iwl_priv *priv) |
83 | { | 70 | { |
@@ -240,220 +227,6 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
240 | priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; | 227 | priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; |
241 | } | 228 | } |
242 | 229 | ||
243 | /* | ||
244 | * Calibration | ||
245 | */ | ||
246 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) | ||
247 | { | ||
248 | struct iwl_calib_xtal_freq_cmd cmd; | ||
249 | __le16 *xtal_calib = | ||
250 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); | ||
251 | |||
252 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; | ||
253 | cmd.hdr.first_group = 0; | ||
254 | cmd.hdr.groups_num = 1; | ||
255 | cmd.hdr.data_valid = 1; | ||
256 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | ||
257 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); | ||
258 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], | ||
259 | (u8 *)&cmd, sizeof(cmd)); | ||
260 | } | ||
261 | |||
262 | static int iwl5000_send_calib_cfg(struct iwl_priv *priv) | ||
263 | { | ||
264 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | ||
265 | struct iwl_host_cmd cmd = { | ||
266 | .id = CALIBRATION_CFG_CMD, | ||
267 | .len = sizeof(struct iwl_calib_cfg_cmd), | ||
268 | .data = &calib_cfg_cmd, | ||
269 | }; | ||
270 | |||
271 | memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); | ||
272 | calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; | ||
273 | calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL; | ||
274 | calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL; | ||
275 | calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL; | ||
276 | |||
277 | return iwl_send_cmd(priv, &cmd); | ||
278 | } | ||
279 | |||
280 | static void iwl5000_rx_calib_result(struct iwl_priv *priv, | ||
281 | struct iwl_rx_mem_buffer *rxb) | ||
282 | { | ||
283 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
284 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; | ||
285 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
286 | int index; | ||
287 | |||
288 | /* reduce the size of the length field itself */ | ||
289 | len -= 4; | ||
290 | |||
291 | /* Define the order in which the results will be sent to the runtime | ||
292 | * uCode. iwl_send_calib_results sends them in a row according to their | ||
293 | * index. We sort them here */ | ||
294 | switch (hdr->op_code) { | ||
295 | case IWL_PHY_CALIBRATE_DC_CMD: | ||
296 | index = IWL_CALIB_DC; | ||
297 | break; | ||
298 | case IWL_PHY_CALIBRATE_LO_CMD: | ||
299 | index = IWL_CALIB_LO; | ||
300 | break; | ||
301 | case IWL_PHY_CALIBRATE_TX_IQ_CMD: | ||
302 | index = IWL_CALIB_TX_IQ; | ||
303 | break; | ||
304 | case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD: | ||
305 | index = IWL_CALIB_TX_IQ_PERD; | ||
306 | break; | ||
307 | case IWL_PHY_CALIBRATE_BASE_BAND_CMD: | ||
308 | index = IWL_CALIB_BASE_BAND; | ||
309 | break; | ||
310 | default: | ||
311 | IWL_ERR(priv, "Unknown calibration notification %d\n", | ||
312 | hdr->op_code); | ||
313 | return; | ||
314 | } | ||
315 | iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); | ||
316 | } | ||
317 | |||
318 | static void iwl5000_rx_calib_complete(struct iwl_priv *priv, | ||
319 | struct iwl_rx_mem_buffer *rxb) | ||
320 | { | ||
321 | IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n"); | ||
322 | queue_work(priv->workqueue, &priv->restart); | ||
323 | } | ||
324 | |||
325 | void iwl5000_init_alive_start(struct iwl_priv *priv) | ||
326 | { | ||
327 | int ret = 0; | ||
328 | |||
329 | /* Check alive response for "valid" sign from uCode */ | ||
330 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
331 | /* We had an error bringing up the hardware, so take it | ||
332 | * all the way back down so we can try again */ | ||
333 | IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); | ||
334 | goto restart; | ||
335 | } | ||
336 | |||
337 | /* initialize uCode was loaded... verify inst image. | ||
338 | * This is a paranoid check, because we would not have gotten the | ||
339 | * "initialize" alive if code weren't properly loaded. */ | ||
340 | if (iwl_verify_ucode(priv)) { | ||
341 | /* Runtime instruction load was bad; | ||
342 | * take it all the way back down so we can try again */ | ||
343 | IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); | ||
344 | goto restart; | ||
345 | } | ||
346 | |||
347 | ret = priv->cfg->ops->lib->alive_notify(priv); | ||
348 | if (ret) { | ||
349 | IWL_WARN(priv, | ||
350 | "Could not complete ALIVE transition: %d\n", ret); | ||
351 | goto restart; | ||
352 | } | ||
353 | |||
354 | iwl5000_send_calib_cfg(priv); | ||
355 | return; | ||
356 | |||
357 | restart: | ||
358 | /* real restart (first load init_ucode) */ | ||
359 | queue_work(priv->workqueue, &priv->restart); | ||
360 | } | ||
361 | |||
362 | int iwl5000_alive_notify(struct iwl_priv *priv) | ||
363 | { | ||
364 | u32 a; | ||
365 | unsigned long flags; | ||
366 | int i, chan; | ||
367 | u32 reg_val; | ||
368 | |||
369 | spin_lock_irqsave(&priv->lock, flags); | ||
370 | |||
371 | priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR); | ||
372 | a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET; | ||
373 | for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET; | ||
374 | a += 4) | ||
375 | iwl_write_targ_mem(priv, a, 0); | ||
376 | for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET; | ||
377 | a += 4) | ||
378 | iwl_write_targ_mem(priv, a, 0); | ||
379 | for (; a < priv->scd_base_addr + | ||
380 | IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) | ||
381 | iwl_write_targ_mem(priv, a, 0); | ||
382 | |||
383 | iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR, | ||
384 | priv->scd_bc_tbls.dma >> 10); | ||
385 | |||
386 | /* Enable DMA channel */ | ||
387 | for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++) | ||
388 | iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | ||
389 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
390 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | ||
391 | |||
392 | /* Update FH chicken bits */ | ||
393 | reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); | ||
394 | iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, | ||
395 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | ||
396 | |||
397 | iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, | ||
398 | IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num)); | ||
399 | iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0); | ||
400 | |||
401 | /* initiate the queues */ | ||
402 | for (i = 0; i < priv->hw_params.max_txq_num; i++) { | ||
403 | iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0); | ||
404 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); | ||
405 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
406 | IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0); | ||
407 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
408 | IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) + | ||
409 | sizeof(u32), | ||
410 | ((SCD_WIN_SIZE << | ||
411 | IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | ||
412 | IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | ||
413 | ((SCD_FRAME_LIMIT << | ||
414 | IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | ||
415 | IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | ||
416 | } | ||
417 | |||
418 | iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK, | ||
419 | IWL_MASK(0, priv->hw_params.max_txq_num)); | ||
420 | |||
421 | /* Activate all Tx DMA/FIFO channels */ | ||
422 | priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); | ||
423 | |||
424 | iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); | ||
425 | |||
426 | /* make sure all queue are not stopped */ | ||
427 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); | ||
428 | for (i = 0; i < 4; i++) | ||
429 | atomic_set(&priv->queue_stop_count[i], 0); | ||
430 | |||
431 | /* reset to 0 to enable all the queue first */ | ||
432 | priv->txq_ctx_active_msk = 0; | ||
433 | /* map qos queues to fifos one-to-one */ | ||
434 | BUILD_BUG_ON(ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo) != 10); | ||
435 | |||
436 | for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { | ||
437 | int ac = iwl5000_default_queue_to_tx_fifo[i]; | ||
438 | |||
439 | iwl_txq_ctx_activate(priv, i); | ||
440 | |||
441 | if (ac == IWL_TX_FIFO_UNUSED) | ||
442 | continue; | ||
443 | |||
444 | iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0); | ||
445 | } | ||
446 | |||
447 | spin_unlock_irqrestore(&priv->lock, flags); | ||
448 | |||
449 | iwl_send_wimax_coex(priv); | ||
450 | |||
451 | iwl5000_set_Xtal_calib(priv); | ||
452 | iwl_send_calib_results(priv); | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 230 | int iwl5000_hw_set_hw_params(struct iwl_priv *priv) |
458 | { | 231 | { |
459 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | 232 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && |
@@ -733,9 +506,9 @@ void iwl5000_rx_handler_setup(struct iwl_priv *priv) | |||
733 | { | 506 | { |
734 | /* init calibration handlers */ | 507 | /* init calibration handlers */ |
735 | priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = | 508 | priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = |
736 | iwl5000_rx_calib_result; | 509 | iwlagn_rx_calib_result; |
737 | priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] = | 510 | priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] = |
738 | iwl5000_rx_calib_complete; | 511 | iwlagn_rx_calib_complete; |
739 | priv->rx_handlers[REPLY_TX] = iwl5000_rx_reply_tx; | 512 | priv->rx_handlers[REPLY_TX] = iwl5000_rx_reply_tx; |
740 | } | 513 | } |
741 | 514 | ||
@@ -851,8 +624,8 @@ struct iwl_lib_ops iwl5000_lib = { | |||
851 | .dump_csr = iwl_dump_csr, | 624 | .dump_csr = iwl_dump_csr, |
852 | .dump_fh = iwl_dump_fh, | 625 | .dump_fh = iwl_dump_fh, |
853 | .load_ucode = iwlagn_load_ucode, | 626 | .load_ucode = iwlagn_load_ucode, |
854 | .init_alive_start = iwl5000_init_alive_start, | 627 | .init_alive_start = iwlagn_init_alive_start, |
855 | .alive_notify = iwl5000_alive_notify, | 628 | .alive_notify = iwlagn_alive_notify, |
856 | .send_tx_power = iwl5000_send_tx_power, | 629 | .send_tx_power = iwl5000_send_tx_power, |
857 | .update_chain_flags = iwl_update_chain_flags, | 630 | .update_chain_flags = iwl_update_chain_flags, |
858 | .set_channel_switch = iwl5000_hw_channel_switch, | 631 | .set_channel_switch = iwl5000_hw_channel_switch, |
@@ -908,8 +681,8 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
908 | .dump_nic_error_log = iwl_dump_nic_error_log, | 681 | .dump_nic_error_log = iwl_dump_nic_error_log, |
909 | .dump_csr = iwl_dump_csr, | 682 | .dump_csr = iwl_dump_csr, |
910 | .load_ucode = iwlagn_load_ucode, | 683 | .load_ucode = iwlagn_load_ucode, |
911 | .init_alive_start = iwl5000_init_alive_start, | 684 | .init_alive_start = iwlagn_init_alive_start, |
912 | .alive_notify = iwl5000_alive_notify, | 685 | .alive_notify = iwlagn_alive_notify, |
913 | .send_tx_power = iwl5000_send_tx_power, | 686 | .send_tx_power = iwl5000_send_tx_power, |
914 | .update_chain_flags = iwl_update_chain_flags, | 687 | .update_chain_flags = iwl_update_chain_flags, |
915 | .set_channel_switch = iwl5000_hw_channel_switch, | 688 | .set_channel_switch = iwl5000_hw_channel_switch, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 2bbff18694c8..96f4fa6e0e21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -242,8 +242,8 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
242 | .dump_nic_error_log = iwl_dump_nic_error_log, | 242 | .dump_nic_error_log = iwl_dump_nic_error_log, |
243 | .dump_csr = iwl_dump_csr, | 243 | .dump_csr = iwl_dump_csr, |
244 | .dump_fh = iwl_dump_fh, | 244 | .dump_fh = iwl_dump_fh, |
245 | .init_alive_start = iwl5000_init_alive_start, | 245 | .init_alive_start = iwlagn_init_alive_start, |
246 | .alive_notify = iwl5000_alive_notify, | 246 | .alive_notify = iwlagn_alive_notify, |
247 | .send_tx_power = iwl5000_send_tx_power, | 247 | .send_tx_power = iwl5000_send_tx_power, |
248 | .update_chain_flags = iwl_update_chain_flags, | 248 | .update_chain_flags = iwl_update_chain_flags, |
249 | .set_channel_switch = iwl6000_hw_channel_switch, | 249 | .set_channel_switch = iwl6000_hw_channel_switch, |
@@ -309,8 +309,8 @@ static struct iwl_lib_ops iwl6050_lib = { | |||
309 | .dump_nic_error_log = iwl_dump_nic_error_log, | 309 | .dump_nic_error_log = iwl_dump_nic_error_log, |
310 | .dump_csr = iwl_dump_csr, | 310 | .dump_csr = iwl_dump_csr, |
311 | .dump_fh = iwl_dump_fh, | 311 | .dump_fh = iwl_dump_fh, |
312 | .init_alive_start = iwl5000_init_alive_start, | 312 | .init_alive_start = iwlagn_init_alive_start, |
313 | .alive_notify = iwl5000_alive_notify, | 313 | .alive_notify = iwlagn_alive_notify, |
314 | .send_tx_power = iwl5000_send_tx_power, | 314 | .send_tx_power = iwl5000_send_tx_power, |
315 | .update_chain_flags = iwl_update_chain_flags, | 315 | .update_chain_flags = iwl_update_chain_flags, |
316 | .set_channel_switch = iwl6000_hw_channel_switch, | 316 | .set_channel_switch = iwl6000_hw_channel_switch, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index f0af3881b74c..52ae157968b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -35,7 +35,22 @@ | |||
35 | #include "iwl-dev.h" | 35 | #include "iwl-dev.h" |
36 | #include "iwl-core.h" | 36 | #include "iwl-core.h" |
37 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
38 | #include "iwl-helpers.h" | ||
38 | #include "iwl-agn-hw.h" | 39 | #include "iwl-agn-hw.h" |
40 | #include "iwl-agn.h" | ||
41 | |||
42 | static const s8 iwlagn_default_queue_to_tx_fifo[] = { | ||
43 | IWL_TX_FIFO_VO, | ||
44 | IWL_TX_FIFO_VI, | ||
45 | IWL_TX_FIFO_BE, | ||
46 | IWL_TX_FIFO_BK, | ||
47 | IWLAGN_CMD_FIFO_NUM, | ||
48 | IWL_TX_FIFO_UNUSED, | ||
49 | IWL_TX_FIFO_UNUSED, | ||
50 | IWL_TX_FIFO_UNUSED, | ||
51 | IWL_TX_FIFO_UNUSED, | ||
52 | IWL_TX_FIFO_UNUSED, | ||
53 | }; | ||
39 | 54 | ||
40 | /* | 55 | /* |
41 | * ucode | 56 | * ucode |
@@ -184,3 +199,218 @@ struct iwl_ucode_ops iwlagn_ucode = { | |||
184 | .get_boot_size = iwlagn_ucode_get_boot_size, | 199 | .get_boot_size = iwlagn_ucode_get_boot_size, |
185 | .get_data = iwlagn_ucode_get_data, | 200 | .get_data = iwlagn_ucode_get_data, |
186 | }; | 201 | }; |
202 | |||
203 | /* | ||
204 | * Calibration | ||
205 | */ | ||
206 | static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) | ||
207 | { | ||
208 | struct iwl_calib_xtal_freq_cmd cmd; | ||
209 | __le16 *xtal_calib = | ||
210 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); | ||
211 | |||
212 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; | ||
213 | cmd.hdr.first_group = 0; | ||
214 | cmd.hdr.groups_num = 1; | ||
215 | cmd.hdr.data_valid = 1; | ||
216 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | ||
217 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); | ||
218 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], | ||
219 | (u8 *)&cmd, sizeof(cmd)); | ||
220 | } | ||
221 | |||
222 | static int iwlagn_send_calib_cfg(struct iwl_priv *priv) | ||
223 | { | ||
224 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | ||
225 | struct iwl_host_cmd cmd = { | ||
226 | .id = CALIBRATION_CFG_CMD, | ||
227 | .len = sizeof(struct iwl_calib_cfg_cmd), | ||
228 | .data = &calib_cfg_cmd, | ||
229 | }; | ||
230 | |||
231 | memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); | ||
232 | calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; | ||
233 | calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL; | ||
234 | calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL; | ||
235 | calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL; | ||
236 | |||
237 | return iwl_send_cmd(priv, &cmd); | ||
238 | } | ||
239 | |||
240 | void iwlagn_rx_calib_result(struct iwl_priv *priv, | ||
241 | struct iwl_rx_mem_buffer *rxb) | ||
242 | { | ||
243 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
244 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; | ||
245 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
246 | int index; | ||
247 | |||
248 | /* reduce the size of the length field itself */ | ||
249 | len -= 4; | ||
250 | |||
251 | /* Define the order in which the results will be sent to the runtime | ||
252 | * uCode. iwl_send_calib_results sends them in a row according to | ||
253 | * their index. We sort them here | ||
254 | */ | ||
255 | switch (hdr->op_code) { | ||
256 | case IWL_PHY_CALIBRATE_DC_CMD: | ||
257 | index = IWL_CALIB_DC; | ||
258 | break; | ||
259 | case IWL_PHY_CALIBRATE_LO_CMD: | ||
260 | index = IWL_CALIB_LO; | ||
261 | break; | ||
262 | case IWL_PHY_CALIBRATE_TX_IQ_CMD: | ||
263 | index = IWL_CALIB_TX_IQ; | ||
264 | break; | ||
265 | case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD: | ||
266 | index = IWL_CALIB_TX_IQ_PERD; | ||
267 | break; | ||
268 | case IWL_PHY_CALIBRATE_BASE_BAND_CMD: | ||
269 | index = IWL_CALIB_BASE_BAND; | ||
270 | break; | ||
271 | default: | ||
272 | IWL_ERR(priv, "Unknown calibration notification %d\n", | ||
273 | hdr->op_code); | ||
274 | return; | ||
275 | } | ||
276 | iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); | ||
277 | } | ||
278 | |||
279 | void iwlagn_rx_calib_complete(struct iwl_priv *priv, | ||
280 | struct iwl_rx_mem_buffer *rxb) | ||
281 | { | ||
282 | IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n"); | ||
283 | queue_work(priv->workqueue, &priv->restart); | ||
284 | } | ||
285 | |||
286 | void iwlagn_init_alive_start(struct iwl_priv *priv) | ||
287 | { | ||
288 | int ret = 0; | ||
289 | |||
290 | /* Check alive response for "valid" sign from uCode */ | ||
291 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
292 | /* We had an error bringing up the hardware, so take it | ||
293 | * all the way back down so we can try again */ | ||
294 | IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); | ||
295 | goto restart; | ||
296 | } | ||
297 | |||
298 | /* initialize uCode was loaded... verify inst image. | ||
299 | * This is a paranoid check, because we would not have gotten the | ||
300 | * "initialize" alive if code weren't properly loaded. */ | ||
301 | if (iwl_verify_ucode(priv)) { | ||
302 | /* Runtime instruction load was bad; | ||
303 | * take it all the way back down so we can try again */ | ||
304 | IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); | ||
305 | goto restart; | ||
306 | } | ||
307 | |||
308 | ret = priv->cfg->ops->lib->alive_notify(priv); | ||
309 | if (ret) { | ||
310 | IWL_WARN(priv, | ||
311 | "Could not complete ALIVE transition: %d\n", ret); | ||
312 | goto restart; | ||
313 | } | ||
314 | |||
315 | iwlagn_send_calib_cfg(priv); | ||
316 | return; | ||
317 | |||
318 | restart: | ||
319 | /* real restart (first load init_ucode) */ | ||
320 | queue_work(priv->workqueue, &priv->restart); | ||
321 | } | ||
322 | |||
323 | int iwlagn_alive_notify(struct iwl_priv *priv) | ||
324 | { | ||
325 | u32 a; | ||
326 | unsigned long flags; | ||
327 | int i, chan; | ||
328 | u32 reg_val; | ||
329 | |||
330 | spin_lock_irqsave(&priv->lock, flags); | ||
331 | |||
332 | priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR); | ||
333 | a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET; | ||
334 | for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET; | ||
335 | a += 4) | ||
336 | iwl_write_targ_mem(priv, a, 0); | ||
337 | for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET; | ||
338 | a += 4) | ||
339 | iwl_write_targ_mem(priv, a, 0); | ||
340 | for (; a < priv->scd_base_addr + | ||
341 | IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) | ||
342 | iwl_write_targ_mem(priv, a, 0); | ||
343 | |||
344 | iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR, | ||
345 | priv->scd_bc_tbls.dma >> 10); | ||
346 | |||
347 | /* Enable DMA channel */ | ||
348 | for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++) | ||
349 | iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | ||
350 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
351 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | ||
352 | |||
353 | /* Update FH chicken bits */ | ||
354 | reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); | ||
355 | iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, | ||
356 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | ||
357 | |||
358 | iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, | ||
359 | IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num)); | ||
360 | iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0); | ||
361 | |||
362 | /* initiate the queues */ | ||
363 | for (i = 0; i < priv->hw_params.max_txq_num; i++) { | ||
364 | iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0); | ||
365 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); | ||
366 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
367 | IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0); | ||
368 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
369 | IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) + | ||
370 | sizeof(u32), | ||
371 | ((SCD_WIN_SIZE << | ||
372 | IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | ||
373 | IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | ||
374 | ((SCD_FRAME_LIMIT << | ||
375 | IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | ||
376 | IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | ||
377 | } | ||
378 | |||
379 | iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK, | ||
380 | IWL_MASK(0, priv->hw_params.max_txq_num)); | ||
381 | |||
382 | /* Activate all Tx DMA/FIFO channels */ | ||
383 | priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); | ||
384 | |||
385 | iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); | ||
386 | |||
387 | /* make sure all queue are not stopped */ | ||
388 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); | ||
389 | for (i = 0; i < 4; i++) | ||
390 | atomic_set(&priv->queue_stop_count[i], 0); | ||
391 | |||
392 | /* reset to 0 to enable all the queue first */ | ||
393 | priv->txq_ctx_active_msk = 0; | ||
394 | /* map qos queues to fifos one-to-one */ | ||
395 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); | ||
396 | |||
397 | for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) { | ||
398 | int ac = iwlagn_default_queue_to_tx_fifo[i]; | ||
399 | |||
400 | iwl_txq_ctx_activate(priv, i); | ||
401 | |||
402 | if (ac == IWL_TX_FIFO_UNUSED) | ||
403 | continue; | ||
404 | |||
405 | iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0); | ||
406 | } | ||
407 | |||
408 | spin_unlock_irqrestore(&priv->lock, flags); | ||
409 | |||
410 | iwl_send_wimax_coex(priv); | ||
411 | |||
412 | iwlagn_set_Xtal_calib(priv); | ||
413 | iwl_send_calib_results(priv); | ||
414 | |||
415 | return 0; | ||
416 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 2ff7b8f5df7f..9b6676569827 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -77,9 +77,6 @@ irqreturn_t iwl_isr_ict(int irq, void *data); | |||
77 | bool iwl_good_ack_health(struct iwl_priv *priv, | 77 | bool iwl_good_ack_health(struct iwl_priv *priv, |
78 | struct iwl_rx_packet *pkt); | 78 | struct iwl_rx_packet *pkt); |
79 | 79 | ||
80 | /* uCode */ | ||
81 | int iwlagn_load_ucode(struct iwl_priv *priv); | ||
82 | |||
83 | /* tx queue */ | 80 | /* tx queue */ |
84 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, | 81 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, |
85 | int txq_id, u32 index); | 82 | int txq_id, u32 index); |
@@ -97,4 +94,13 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
97 | u16 ssn_idx, u8 tx_fifo); | 94 | u16 ssn_idx, u8 tx_fifo); |
98 | void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); | 95 | void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); |
99 | 96 | ||
97 | /* uCode */ | ||
98 | int iwlagn_load_ucode(struct iwl_priv *priv); | ||
99 | void iwlagn_rx_calib_result(struct iwl_priv *priv, | ||
100 | struct iwl_rx_mem_buffer *rxb); | ||
101 | void iwlagn_rx_calib_complete(struct iwl_priv *priv, | ||
102 | struct iwl_rx_mem_buffer *rxb); | ||
103 | void iwlagn_init_alive_start(struct iwl_priv *priv); | ||
104 | int iwlagn_alive_notify(struct iwl_priv *priv); | ||
105 | |||
100 | #endif /* __iwl_agn_h__ */ | 106 | #endif /* __iwl_agn_h__ */ |