diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/init.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 80cae53a33e..27703a5e48d 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -23,6 +23,11 @@ | |||
| 23 | 23 | ||
| 24 | #include "ath9k.h" | 24 | #include "ath9k.h" |
| 25 | 25 | ||
| 26 | struct ath9k_eeprom_ctx { | ||
| 27 | struct completion complete; | ||
| 28 | struct ath_hw *ah; | ||
| 29 | }; | ||
| 30 | |||
| 26 | static char *dev_info = "ath9k"; | 31 | static char *dev_info = "ath9k"; |
| 27 | 32 | ||
| 28 | MODULE_AUTHOR("Atheros Communications"); | 33 | MODULE_AUTHOR("Atheros Communications"); |
| @@ -506,6 +511,51 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
| 506 | sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; | 511 | sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; |
| 507 | } | 512 | } |
| 508 | 513 | ||
| 514 | static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob, | ||
| 515 | void *ctx) | ||
| 516 | { | ||
| 517 | struct ath9k_eeprom_ctx *ec = ctx; | ||
| 518 | |||
| 519 | if (eeprom_blob) | ||
| 520 | ec->ah->eeprom_blob = eeprom_blob; | ||
| 521 | |||
| 522 | complete(&ec->complete); | ||
| 523 | } | ||
| 524 | |||
| 525 | static int ath9k_eeprom_request(struct ath_softc *sc, const char *name) | ||
| 526 | { | ||
| 527 | struct ath9k_eeprom_ctx ec; | ||
| 528 | struct ath_hw *ah = ah = sc->sc_ah; | ||
| 529 | int err; | ||
| 530 | |||
| 531 | /* try to load the EEPROM content asynchronously */ | ||
| 532 | init_completion(&ec.complete); | ||
| 533 | ec.ah = sc->sc_ah; | ||
| 534 | |||
| 535 | err = request_firmware_nowait(THIS_MODULE, 1, name, sc->dev, GFP_KERNEL, | ||
| 536 | &ec, ath9k_eeprom_request_cb); | ||
| 537 | if (err < 0) { | ||
| 538 | ath_err(ath9k_hw_common(ah), | ||
| 539 | "EEPROM request failed\n"); | ||
| 540 | return err; | ||
| 541 | } | ||
| 542 | |||
| 543 | wait_for_completion(&ec.complete); | ||
| 544 | |||
| 545 | if (!ah->eeprom_blob) { | ||
| 546 | ath_err(ath9k_hw_common(ah), | ||
| 547 | "Unable to load EEPROM file %s\n", name); | ||
| 548 | return -EINVAL; | ||
| 549 | } | ||
| 550 | |||
| 551 | return 0; | ||
| 552 | } | ||
| 553 | |||
| 554 | static void ath9k_eeprom_release(struct ath_softc *sc) | ||
| 555 | { | ||
| 556 | release_firmware(sc->sc_ah->eeprom_blob); | ||
| 557 | } | ||
| 558 | |||
| 509 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | 559 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, |
| 510 | const struct ath_bus_ops *bus_ops) | 560 | const struct ath_bus_ops *bus_ops) |
| 511 | { | 561 | { |
| @@ -583,6 +633,12 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
| 583 | ath_read_cachesize(common, &csz); | 633 | ath_read_cachesize(common, &csz); |
| 584 | common->cachelsz = csz << 2; /* convert to bytes */ | 634 | common->cachelsz = csz << 2; /* convert to bytes */ |
| 585 | 635 | ||
| 636 | if (pdata->eeprom_name) { | ||
| 637 | ret = ath9k_eeprom_request(sc, pdata->eeprom_name); | ||
| 638 | if (ret) | ||
| 639 | goto err_eeprom; | ||
| 640 | } | ||
| 641 | |||
| 586 | /* Initializes the hardware for all supported chipsets */ | 642 | /* Initializes the hardware for all supported chipsets */ |
| 587 | ret = ath9k_hw_init(ah); | 643 | ret = ath9k_hw_init(ah); |
| 588 | if (ret) | 644 | if (ret) |
| @@ -619,7 +675,8 @@ err_btcoex: | |||
| 619 | err_queues: | 675 | err_queues: |
| 620 | ath9k_hw_deinit(ah); | 676 | ath9k_hw_deinit(ah); |
| 621 | err_hw: | 677 | err_hw: |
| 622 | 678 | ath9k_eeprom_release(sc); | |
| 679 | err_eeprom: | ||
| 623 | kfree(ah); | 680 | kfree(ah); |
| 624 | sc->sc_ah = NULL; | 681 | sc->sc_ah = NULL; |
| 625 | 682 | ||
| @@ -882,6 +939,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
| 882 | if (sc->dfs_detector != NULL) | 939 | if (sc->dfs_detector != NULL) |
| 883 | sc->dfs_detector->exit(sc->dfs_detector); | 940 | sc->dfs_detector->exit(sc->dfs_detector); |
| 884 | 941 | ||
| 942 | ath9k_eeprom_release(sc); | ||
| 885 | kfree(sc->sc_ah); | 943 | kfree(sc->sc_ah); |
| 886 | sc->sc_ah = NULL; | 944 | sc->sc_ah = NULL; |
| 887 | } | 945 | } |
