diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-02-02 17:33:08 -0500 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2012-02-02 17:34:48 -0500 |
commit | a42a184458ae95937893cb873c988385637c5e14 (patch) | |
tree | 70638d63f2383c63485c5a58b03a31a89dfba085 | |
parent | b52e7ea109cfe4ea7fea99b1cd20f57ccd95476a (diff) |
iwlwifi: move the bus configuration to transport
All the bus configuration is now done in the transport
allocation fucntion.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-bus.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-pci.c | 93 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 169 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 5 |
5 files changed, 158 insertions, 117 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 941b9cb23442..37ed7b60aaf6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h | |||
@@ -148,7 +148,6 @@ struct iwl_bus_ops { | |||
148 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 148 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
149 | * NB: for the time being this needs to be set by the upper layer since | 149 | * NB: for the time being this needs to be set by the upper layer since |
150 | * it allocates the shared data | 150 | * it allocates the shared data |
151 | * @irq - the irq number for the device | ||
152 | * @reg_lock - protect hw register access | 151 | * @reg_lock - protect hw register access |
153 | */ | 152 | */ |
154 | struct iwl_bus { | 153 | struct iwl_bus { |
@@ -156,7 +155,6 @@ struct iwl_bus { | |||
156 | const struct iwl_bus_ops *ops; | 155 | const struct iwl_bus_ops *ops; |
157 | struct iwl_shared *shrd; | 156 | struct iwl_shared *shrd; |
158 | 157 | ||
159 | unsigned int irq; | ||
160 | spinlock_t reg_lock; | 158 | spinlock_t reg_lock; |
161 | 159 | ||
162 | /* pointer to bus specific struct */ | 160 | /* pointer to bus specific struct */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index c0d62e724956..631b67ca2b6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -367,7 +367,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
367 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | 367 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); |
368 | struct iwl_bus *bus; | 368 | struct iwl_bus *bus; |
369 | struct iwl_pci_bus *pci_bus; | 369 | struct iwl_pci_bus *pci_bus; |
370 | u16 pci_cmd; | ||
371 | int err; | 370 | int err; |
372 | 371 | ||
373 | bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); | 372 | bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); |
@@ -382,7 +381,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
382 | dev_printk(KERN_ERR, &pdev->dev, | 381 | dev_printk(KERN_ERR, &pdev->dev, |
383 | "Couldn't allocate iwl_shared"); | 382 | "Couldn't allocate iwl_shared"); |
384 | err = -ENOMEM; | 383 | err = -ENOMEM; |
385 | goto out_no_pci; | 384 | goto out_free_bus; |
386 | } | 385 | } |
387 | 386 | ||
388 | bus->shrd->bus = bus; | 387 | bus->shrd->bus = bus; |
@@ -391,82 +390,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
391 | 390 | ||
392 | pci_set_drvdata(pdev, bus); | 391 | pci_set_drvdata(pdev, bus); |
393 | 392 | ||
394 | /* W/A - seems to solve weird behavior. We need to remove this if we | ||
395 | * don't want to stay in L1 all the time. This wastes a lot of power */ | ||
396 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
397 | PCIE_LINK_STATE_CLKPM); | ||
398 | |||
399 | if (pci_enable_device(pdev)) { | ||
400 | err = -ENODEV; | ||
401 | goto out_no_pci; | ||
402 | } | ||
403 | |||
404 | pci_set_master(pdev); | ||
405 | |||
406 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
407 | if (!err) | ||
408 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
409 | if (err) { | ||
410 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
411 | if (!err) | ||
412 | err = pci_set_consistent_dma_mask(pdev, | ||
413 | DMA_BIT_MASK(32)); | ||
414 | /* both attempts failed: */ | ||
415 | if (err) { | ||
416 | dev_printk(KERN_ERR, bus->dev, | ||
417 | "No suitable DMA available.\n"); | ||
418 | goto out_pci_disable_device; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | err = pci_request_regions(pdev, DRV_NAME); | ||
423 | if (err) { | ||
424 | dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed"); | ||
425 | goto out_pci_disable_device; | ||
426 | } | ||
427 | |||
428 | pci_bus->hw_base = pci_iomap(pdev, 0, 0); | ||
429 | if (!pci_bus->hw_base) { | ||
430 | dev_printk(KERN_ERR, bus->dev, "pci_iomap failed"); | ||
431 | err = -ENODEV; | ||
432 | goto out_pci_release_regions; | ||
433 | } | ||
434 | |||
435 | dev_printk(KERN_INFO, &pdev->dev, | ||
436 | "pci_resource_len = 0x%08llx\n", | ||
437 | (unsigned long long) pci_resource_len(pdev, 0)); | ||
438 | dev_printk(KERN_INFO, &pdev->dev, | ||
439 | "pci_resource_base = %p\n", pci_bus->hw_base); | ||
440 | |||
441 | dev_printk(KERN_INFO, &pdev->dev, | ||
442 | "HW Revision ID = 0x%X\n", pdev->revision); | ||
443 | |||
444 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | ||
445 | * PCI Tx retries from interfering with C3 CPU state */ | ||
446 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
447 | |||
448 | err = pci_enable_msi(pdev); | ||
449 | if (err) | ||
450 | dev_printk(KERN_ERR, &pdev->dev, | ||
451 | "pci_enable_msi failed(0X%x)", err); | ||
452 | |||
453 | /* TODO: Move this away, not needed if not MSI */ | ||
454 | /* enable rfkill interrupt: hw bug w/a */ | ||
455 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | ||
456 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
457 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
458 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
459 | } | ||
460 | |||
461 | bus->dev = &pdev->dev; | 393 | bus->dev = &pdev->dev; |
462 | bus->irq = pdev->irq; | ||
463 | bus->ops = &bus_ops_pci; | 394 | bus->ops = &bus_ops_pci; |
464 | 395 | ||
465 | #ifdef CONFIG_IWLWIFI_IDI | 396 | #ifdef CONFIG_IWLWIFI_IDI |
466 | trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); | 397 | trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); |
467 | if (trans(bus) == NULL) { | 398 | if (trans(bus) == NULL) { |
468 | err = -ENOMEM; | 399 | err = -ENOMEM; |
469 | goto out_disable_msi; | 400 | goto out_free_bus; |
470 | } | 401 | } |
471 | 402 | ||
472 | err = iwl_probe(bus, &trans_ops_idi, cfg); | 403 | err = iwl_probe(bus, &trans_ops_idi, cfg); |
@@ -474,26 +405,20 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
474 | trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); | 405 | trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); |
475 | if (trans(bus) == NULL) { | 406 | if (trans(bus) == NULL) { |
476 | err = -ENOMEM; | 407 | err = -ENOMEM; |
477 | goto out_disable_msi; | 408 | goto out_free_bus; |
478 | } | 409 | } |
479 | 410 | ||
480 | err = iwl_probe(bus, &trans_ops_pcie, cfg); | 411 | err = iwl_probe(bus, &trans_ops_pcie, cfg); |
481 | #endif | 412 | #endif |
482 | if (err) | 413 | if (err) |
483 | goto out_free_trans; | 414 | goto out_free_trans; |
415 | |||
484 | return 0; | 416 | return 0; |
485 | 417 | ||
486 | out_free_trans: | 418 | out_free_trans: |
487 | iwl_trans_free(trans(bus)); | 419 | iwl_trans_free(trans(bus)); |
488 | out_disable_msi: | ||
489 | pci_disable_msi(pdev); | ||
490 | pci_iounmap(pdev, pci_bus->hw_base); | ||
491 | out_pci_release_regions: | ||
492 | pci_set_drvdata(pdev, NULL); | 420 | pci_set_drvdata(pdev, NULL); |
493 | pci_release_regions(pdev); | 421 | out_free_bus: |
494 | out_pci_disable_device: | ||
495 | pci_disable_device(pdev); | ||
496 | out_no_pci: | ||
497 | kfree(bus->shrd); | 422 | kfree(bus->shrd); |
498 | kfree(bus); | 423 | kfree(bus); |
499 | return err; | 424 | return err; |
@@ -502,18 +427,12 @@ out_no_pci: | |||
502 | static void __devexit iwl_pci_remove(struct pci_dev *pdev) | 427 | static void __devexit iwl_pci_remove(struct pci_dev *pdev) |
503 | { | 428 | { |
504 | struct iwl_bus *bus = pci_get_drvdata(pdev); | 429 | struct iwl_bus *bus = pci_get_drvdata(pdev); |
505 | struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); | ||
506 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
507 | struct iwl_shared *shrd = bus->shrd; | 430 | struct iwl_shared *shrd = bus->shrd; |
508 | 431 | ||
509 | iwl_remove(shrd->priv); | 432 | iwl_remove(shrd->priv); |
510 | iwl_trans_free(shrd->trans); | 433 | iwl_trans_free(shrd->trans); |
511 | 434 | ||
512 | pci_disable_msi(pci_dev); | 435 | pci_set_drvdata(pdev, NULL); |
513 | pci_iounmap(pci_dev, pci_bus->hw_base); | ||
514 | pci_release_regions(pci_dev); | ||
515 | pci_disable_device(pci_dev); | ||
516 | pci_set_drvdata(pci_dev, NULL); | ||
517 | 436 | ||
518 | kfree(bus->shrd); | 437 | kfree(bus->shrd); |
519 | kfree(bus); | 438 | kfree(bus); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 0f73778b73f7..47d27bdf2dfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -211,6 +211,8 @@ struct iwl_tx_queue { | |||
211 | * @txq_ctx_active_msk: what queue is active | 211 | * @txq_ctx_active_msk: what queue is active |
212 | * queue_stopped: tracks what queue is stopped | 212 | * queue_stopped: tracks what queue is stopped |
213 | * queue_stop_count: tracks what SW queue is stopped | 213 | * queue_stop_count: tracks what SW queue is stopped |
214 | * @pci_dev: basic pci-network driver stuff | ||
215 | * @hw_base: pci hardware address support | ||
214 | */ | 216 | */ |
215 | struct iwl_trans_pcie { | 217 | struct iwl_trans_pcie { |
216 | struct iwl_rx_queue rxq; | 218 | struct iwl_rx_queue rxq; |
@@ -241,6 +243,10 @@ struct iwl_trans_pcie { | |||
241 | #define IWL_MAX_HW_QUEUES 32 | 243 | #define IWL_MAX_HW_QUEUES 32 |
242 | unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; | 244 | unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; |
243 | atomic_t queue_stop_count[4]; | 245 | atomic_t queue_stop_count[4]; |
246 | |||
247 | /* PCI bus related data */ | ||
248 | struct pci_dev *pci_dev; | ||
249 | void __iomem *hw_base; | ||
244 | }; | 250 | }; |
245 | 251 | ||
246 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 252 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index f0d8cccbcb11..5d0cfe033407 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -60,6 +60,8 @@ | |||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | #include <linux/pci.h> | ||
64 | #include <linux/pci-aspm.h> | ||
63 | #include <linux/interrupt.h> | 65 | #include <linux/interrupt.h> |
64 | #include <linux/debugfs.h> | 66 | #include <linux/debugfs.h> |
65 | #include <linux/bitops.h> | 67 | #include <linux/bitops.h> |
@@ -1042,7 +1044,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1042 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1044 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
1043 | 1045 | ||
1044 | /* wait to make sure we flush pending tasklet*/ | 1046 | /* wait to make sure we flush pending tasklet*/ |
1045 | synchronize_irq(bus(trans)->irq); | 1047 | synchronize_irq(trans->irq); |
1046 | tasklet_kill(&trans_pcie->irq_tasklet); | 1048 | tasklet_kill(&trans_pcie->irq_tasklet); |
1047 | 1049 | ||
1048 | /* stop and reset the on-board processor */ | 1050 | /* stop and reset the on-board processor */ |
@@ -1246,10 +1248,10 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) | |||
1246 | 1248 | ||
1247 | iwl_alloc_isr_ict(trans); | 1249 | iwl_alloc_isr_ict(trans); |
1248 | 1250 | ||
1249 | err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED, | 1251 | err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, |
1250 | DRV_NAME, trans); | 1252 | DRV_NAME, trans); |
1251 | if (err) { | 1253 | if (err) { |
1252 | IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq); | 1254 | IWL_ERR(trans, "Error allocating IRQ %d\n", trans->irq); |
1253 | iwl_free_isr_ict(trans); | 1255 | iwl_free_isr_ict(trans); |
1254 | return err; | 1256 | return err; |
1255 | } | 1257 | } |
@@ -1299,13 +1301,22 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1299 | 1301 | ||
1300 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1302 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
1301 | { | 1303 | { |
1304 | struct iwl_trans_pcie *trans_pcie = | ||
1305 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1306 | |||
1302 | iwl_calib_free_results(trans); | 1307 | iwl_calib_free_results(trans); |
1303 | iwl_trans_pcie_tx_free(trans); | 1308 | iwl_trans_pcie_tx_free(trans); |
1304 | #ifndef CONFIG_IWLWIFI_IDI | 1309 | #ifndef CONFIG_IWLWIFI_IDI |
1305 | iwl_trans_pcie_rx_free(trans); | 1310 | iwl_trans_pcie_rx_free(trans); |
1306 | #endif | 1311 | #endif |
1307 | free_irq(bus(trans)->irq, trans); | 1312 | free_irq(trans->irq, trans); |
1308 | iwl_free_isr_ict(trans); | 1313 | iwl_free_isr_ict(trans); |
1314 | |||
1315 | pci_disable_msi(trans_pcie->pci_dev); | ||
1316 | pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); | ||
1317 | pci_release_regions(trans_pcie->pci_dev); | ||
1318 | pci_disable_device(trans_pcie->pci_dev); | ||
1319 | |||
1309 | trans->shrd->trans = NULL; | 1320 | trans->shrd->trans = NULL; |
1310 | kfree(trans); | 1321 | kfree(trans); |
1311 | } | 1322 | } |
@@ -1374,30 +1385,6 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | |||
1374 | } | 1385 | } |
1375 | } | 1386 | } |
1376 | 1387 | ||
1377 | const struct iwl_trans_ops trans_ops_pcie; | ||
1378 | |||
1379 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | ||
1380 | struct pci_dev *pdev, | ||
1381 | const struct pci_device_id *ent) | ||
1382 | { | ||
1383 | struct iwl_trans_pcie *trans_pcie; | ||
1384 | struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + | ||
1385 | sizeof(struct iwl_trans_pcie), | ||
1386 | GFP_KERNEL); | ||
1387 | |||
1388 | if (WARN_ON(!iwl_trans)) | ||
1389 | return NULL; | ||
1390 | |||
1391 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); | ||
1392 | |||
1393 | iwl_trans->ops = &trans_ops_pcie; | ||
1394 | iwl_trans->shrd = shrd; | ||
1395 | trans_pcie->trans = iwl_trans; | ||
1396 | spin_lock_init(&iwl_trans->hcmd_lock); | ||
1397 | |||
1398 | return iwl_trans; | ||
1399 | } | ||
1400 | |||
1401 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, | 1388 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, |
1402 | const char *msg) | 1389 | const char *msg) |
1403 | { | 1390 | { |
@@ -1949,3 +1936,129 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
1949 | .resume = iwl_trans_pcie_resume, | 1936 | .resume = iwl_trans_pcie_resume, |
1950 | #endif | 1937 | #endif |
1951 | }; | 1938 | }; |
1939 | |||
1940 | /* TODO: remove this hack - will be possible when all the io{write/read} ops | ||
1941 | * will be done through the transport | ||
1942 | */ | ||
1943 | struct iwl_pci_bus { | ||
1944 | /* basic pci-network driver stuff */ | ||
1945 | struct pci_dev *pci_dev; | ||
1946 | |||
1947 | /* pci hardware address support */ | ||
1948 | void __iomem *hw_base; | ||
1949 | }; | ||
1950 | |||
1951 | #define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ | ||
1952 | ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) | ||
1953 | |||
1954 | /* PCI registers */ | ||
1955 | #define PCI_CFG_RETRY_TIMEOUT 0x041 | ||
1956 | |||
1957 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | ||
1958 | struct pci_dev *pdev, | ||
1959 | const struct pci_device_id *ent) | ||
1960 | { | ||
1961 | struct iwl_pci_bus *iwl_pci_bus = IWL_BUS_GET_PCI_BUS(shrd->bus); | ||
1962 | struct iwl_trans_pcie *trans_pcie; | ||
1963 | struct iwl_trans *trans; | ||
1964 | u16 pci_cmd; | ||
1965 | int err; | ||
1966 | |||
1967 | trans = kzalloc(sizeof(struct iwl_trans) + | ||
1968 | sizeof(struct iwl_trans_pcie), GFP_KERNEL); | ||
1969 | |||
1970 | if (WARN_ON(!trans)) | ||
1971 | return NULL; | ||
1972 | |||
1973 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1974 | |||
1975 | trans->ops = &trans_ops_pcie; | ||
1976 | trans->shrd = shrd; | ||
1977 | trans_pcie->trans = trans; | ||
1978 | spin_lock_init(&trans->hcmd_lock); | ||
1979 | |||
1980 | /* W/A - seems to solve weird behavior. We need to remove this if we | ||
1981 | * don't want to stay in L1 all the time. This wastes a lot of power */ | ||
1982 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
1983 | PCIE_LINK_STATE_CLKPM); | ||
1984 | |||
1985 | if (pci_enable_device(pdev)) { | ||
1986 | err = -ENODEV; | ||
1987 | goto out_no_pci; | ||
1988 | } | ||
1989 | |||
1990 | pci_set_master(pdev); | ||
1991 | |||
1992 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
1993 | if (!err) | ||
1994 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
1995 | if (err) { | ||
1996 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
1997 | if (!err) | ||
1998 | err = pci_set_consistent_dma_mask(pdev, | ||
1999 | DMA_BIT_MASK(32)); | ||
2000 | /* both attempts failed: */ | ||
2001 | if (err) { | ||
2002 | dev_printk(KERN_ERR, &pdev->dev, | ||
2003 | "No suitable DMA available.\n"); | ||
2004 | goto out_pci_disable_device; | ||
2005 | } | ||
2006 | } | ||
2007 | |||
2008 | err = pci_request_regions(pdev, DRV_NAME); | ||
2009 | if (err) { | ||
2010 | dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed"); | ||
2011 | goto out_pci_disable_device; | ||
2012 | } | ||
2013 | |||
2014 | trans_pcie->hw_base = pci_iomap(pdev, 0, 0); | ||
2015 | if (!trans_pcie->hw_base) { | ||
2016 | dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); | ||
2017 | err = -ENODEV; | ||
2018 | goto out_pci_release_regions; | ||
2019 | } | ||
2020 | |||
2021 | /* TODO: remove this hack */ | ||
2022 | iwl_pci_bus->hw_base = trans_pcie->hw_base; | ||
2023 | |||
2024 | dev_printk(KERN_INFO, &pdev->dev, | ||
2025 | "pci_resource_len = 0x%08llx\n", | ||
2026 | (unsigned long long) pci_resource_len(pdev, 0)); | ||
2027 | dev_printk(KERN_INFO, &pdev->dev, | ||
2028 | "pci_resource_base = %p\n", trans_pcie->hw_base); | ||
2029 | |||
2030 | dev_printk(KERN_INFO, &pdev->dev, | ||
2031 | "HW Revision ID = 0x%X\n", pdev->revision); | ||
2032 | |||
2033 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | ||
2034 | * PCI Tx retries from interfering with C3 CPU state */ | ||
2035 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
2036 | |||
2037 | err = pci_enable_msi(pdev); | ||
2038 | if (err) | ||
2039 | dev_printk(KERN_ERR, &pdev->dev, | ||
2040 | "pci_enable_msi failed(0X%x)", err); | ||
2041 | |||
2042 | trans->dev = &pdev->dev; | ||
2043 | trans->irq = pdev->irq; | ||
2044 | trans_pcie->pci_dev = pdev; | ||
2045 | |||
2046 | /* TODO: Move this away, not needed if not MSI */ | ||
2047 | /* enable rfkill interrupt: hw bug w/a */ | ||
2048 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | ||
2049 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
2050 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
2051 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
2052 | } | ||
2053 | |||
2054 | return trans; | ||
2055 | |||
2056 | out_pci_release_regions: | ||
2057 | pci_release_regions(pdev); | ||
2058 | out_pci_disable_device: | ||
2059 | pci_disable_device(pdev); | ||
2060 | out_no_pci: | ||
2061 | kfree(trans); | ||
2062 | return NULL; | ||
2063 | } | ||
2064 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b1a7af26c570..9a8076194868 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -228,6 +228,8 @@ struct iwl_calib_result { | |||
228 | * @ops - pointer to iwl_trans_ops | 228 | * @ops - pointer to iwl_trans_ops |
229 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 229 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
230 | * @hcmd_lock: protects HCMD | 230 | * @hcmd_lock: protects HCMD |
231 | * @dev - pointer to struct device * that represents the device | ||
232 | * @irq - the irq number for the device | ||
231 | * @ucode_write_complete: indicates that the ucode has been copied. | 233 | * @ucode_write_complete: indicates that the ucode has been copied. |
232 | * @ucode_rt: run time ucode image | 234 | * @ucode_rt: run time ucode image |
233 | * @ucode_init: init ucode image | 235 | * @ucode_init: init ucode image |
@@ -240,6 +242,9 @@ struct iwl_trans { | |||
240 | struct iwl_shared *shrd; | 242 | struct iwl_shared *shrd; |
241 | spinlock_t hcmd_lock; | 243 | spinlock_t hcmd_lock; |
242 | 244 | ||
245 | struct device *dev; | ||
246 | unsigned int irq; | ||
247 | |||
243 | u8 ucode_write_complete; /* the image write is complete */ | 248 | u8 ucode_write_complete; /* the image write is complete */ |
244 | struct fw_img ucode_rt; | 249 | struct fw_img ucode_rt; |
245 | struct fw_img ucode_init; | 250 | struct fw_img ucode_init; |