diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-12-02 04:26:56 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-02 15:17:50 -0500 |
commit | 132b1c3ee38ea6fa0501004fd0f19acb554e5a44 (patch) | |
tree | 3bb52a5ef7738b56581f17ffeececbf647f34a97 /drivers/net/wireless/ath | |
parent | aeae4ac9090462ea38387dcdbac4f01b944af6a4 (diff) |
ath5k: Introduce ath5k_init_softc function as in ath9k
Split pci initialization into hardware specific
functions and softc structure initialization.
Make function naming similar to ones ath9k.
Introduce ath_bus_opts in ath5k for later
AHB bus integration.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/attach.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 344 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.c | 2 |
5 files changed, 217 insertions, 153 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 899bf4b99b76..a74f448f7d72 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1146,9 +1146,11 @@ struct ath5k_hw { | |||
1146 | * Prototypes | 1146 | * Prototypes |
1147 | */ | 1147 | */ |
1148 | 1148 | ||
1149 | /* Attach/Detach Functions */ | 1149 | /* Initialization and detach functions */ |
1150 | int ath5k_hw_attach(struct ath5k_softc *sc); | 1150 | int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops); |
1151 | void ath5k_hw_detach(struct ath5k_hw *ah); | 1151 | void ath5k_deinit_softc(struct ath5k_softc *sc); |
1152 | int ath5k_hw_init(struct ath5k_softc *sc); | ||
1153 | void ath5k_hw_deinit(struct ath5k_hw *ah); | ||
1152 | 1154 | ||
1153 | int ath5k_sysfs_register(struct ath5k_softc *sc); | 1155 | int ath5k_sysfs_register(struct ath5k_softc *sc); |
1154 | void ath5k_sysfs_unregister(struct ath5k_softc *sc); | 1156 | void ath5k_sysfs_unregister(struct ath5k_softc *sc); |
@@ -1332,6 +1334,11 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | |||
1332 | iowrite32(val, ah->ah_iobase + reg); | 1334 | iowrite32(val, ah->ah_iobase + reg); |
1333 | } | 1335 | } |
1334 | 1336 | ||
1337 | static inline void ath5k_read_cachesize(struct ath_common *common, int *csz) | ||
1338 | { | ||
1339 | common->bus_ops->read_cachesize(common, csz); | ||
1340 | } | ||
1341 | |||
1335 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) | 1342 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) |
1336 | { | 1343 | { |
1337 | u32 retval = 0, bit, i; | 1344 | u32 retval = 0, bit, i; |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index ed86b9dde1b4..a84782a63e0a 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -93,16 +93,16 @@ static int ath5k_hw_post(struct ath5k_hw *ah) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * ath5k_hw_attach - Check if hw is supported and init the needed structs | 96 | * ath5k_hw_init - Check if hw is supported and init the needed structs |
97 | * | 97 | * |
98 | * @sc: The &struct ath5k_softc we got from the driver's attach function | 98 | * @sc: The &struct ath5k_softc we got from the driver's init_softc function |
99 | * | 99 | * |
100 | * Check if the device is supported, perform a POST and initialize the needed | 100 | * Check if the device is supported, perform a POST and initialize the needed |
101 | * structs. Returns -ENOMEM if we don't have memory for the needed structs, | 101 | * structs. Returns -ENOMEM if we don't have memory for the needed structs, |
102 | * -ENODEV if the device is not supported or prints an error msg if something | 102 | * -ENODEV if the device is not supported or prints an error msg if something |
103 | * else went wrong. | 103 | * else went wrong. |
104 | */ | 104 | */ |
105 | int ath5k_hw_attach(struct ath5k_softc *sc) | 105 | int ath5k_hw_init(struct ath5k_softc *sc) |
106 | { | 106 | { |
107 | struct ath5k_hw *ah = sc->ah; | 107 | struct ath5k_hw *ah = sc->ah; |
108 | struct ath_common *common = ath5k_hw_common(ah); | 108 | struct ath_common *common = ath5k_hw_common(ah); |
@@ -346,11 +346,11 @@ err: | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /** | 348 | /** |
349 | * ath5k_hw_detach - Free the ath5k_hw struct | 349 | * ath5k_hw_deinit - Free the ath5k_hw struct |
350 | * | 350 | * |
351 | * @ah: The &struct ath5k_hw | 351 | * @ah: The &struct ath5k_hw |
352 | */ | 352 | */ |
353 | void ath5k_hw_detach(struct ath5k_hw *ah) | 353 | void ath5k_hw_deinit(struct ath5k_hw *ah) |
354 | { | 354 | { |
355 | __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); | 355 | __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); |
356 | 356 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2d7d8bac4610..b11ea3d2872d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -80,6 +80,7 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | |||
80 | MODULE_LICENSE("Dual BSD/GPL"); | 80 | MODULE_LICENSE("Dual BSD/GPL"); |
81 | MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); | 81 | MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); |
82 | 82 | ||
83 | static int ath5k_init(struct ieee80211_hw *hw); | ||
83 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, | 84 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, |
84 | bool skip_pcu); | 85 | bool skip_pcu); |
85 | static int ath5k_beacon_update(struct ieee80211_hw *hw, | 86 | static int ath5k_beacon_update(struct ieee80211_hw *hw, |
@@ -192,6 +193,32 @@ static const struct ieee80211_rate ath5k_rates[] = { | |||
192 | /* XR missing */ | 193 | /* XR missing */ |
193 | }; | 194 | }; |
194 | 195 | ||
196 | /* return bus cachesize in 4B word units */ | ||
197 | static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) | ||
198 | { | ||
199 | struct ath5k_softc *sc = (struct ath5k_softc *) common->priv; | ||
200 | u8 u8tmp; | ||
201 | |||
202 | pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp); | ||
203 | *csz = (int)u8tmp; | ||
204 | |||
205 | /* | ||
206 | * This check was put in to avoid "unplesant" consequences if | ||
207 | * the bootrom has not fully initialized all PCI devices. | ||
208 | * Sometimes the cache line size register is not set | ||
209 | */ | ||
210 | |||
211 | if (*csz == 0) | ||
212 | *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ | ||
213 | } | ||
214 | |||
215 | /* Common ath_bus_opts structure */ | ||
216 | static const struct ath_bus_ops ath_pci_bus_ops = { | ||
217 | .ath_bus_type = ATH_PCI, | ||
218 | .read_cachesize = ath5k_pci_read_cachesize, | ||
219 | }; | ||
220 | |||
221 | |||
195 | static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, | 222 | static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, |
196 | struct ath5k_buf *bf) | 223 | struct ath5k_buf *bf) |
197 | { | 224 | { |
@@ -2152,7 +2179,7 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) | |||
2152 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ | 2179 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ |
2153 | } | 2180 | } |
2154 | 2181 | ||
2155 | static irqreturn_t | 2182 | irqreturn_t |
2156 | ath5k_intr(int irq, void *dev_id) | 2183 | ath5k_intr(int irq, void *dev_id) |
2157 | { | 2184 | { |
2158 | struct ath5k_softc *sc = dev_id; | 2185 | struct ath5k_softc *sc = dev_id; |
@@ -2338,6 +2365,158 @@ ath5k_tx_complete_poll_work(struct work_struct *work) | |||
2338 | * Initialization routines * | 2365 | * Initialization routines * |
2339 | \*************************/ | 2366 | \*************************/ |
2340 | 2367 | ||
2368 | int | ||
2369 | ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) | ||
2370 | { | ||
2371 | struct ieee80211_hw *hw = sc->hw; | ||
2372 | struct ath_common *common; | ||
2373 | int ret; | ||
2374 | int csz; | ||
2375 | |||
2376 | /* Initialize driver private data */ | ||
2377 | SET_IEEE80211_DEV(hw, sc->dev); | ||
2378 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
2379 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2380 | IEEE80211_HW_SIGNAL_DBM; | ||
2381 | |||
2382 | hw->wiphy->interface_modes = | ||
2383 | BIT(NL80211_IFTYPE_AP) | | ||
2384 | BIT(NL80211_IFTYPE_STATION) | | ||
2385 | BIT(NL80211_IFTYPE_ADHOC) | | ||
2386 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
2387 | |||
2388 | hw->extra_tx_headroom = 2; | ||
2389 | hw->channel_change_time = 5000; | ||
2390 | |||
2391 | /* | ||
2392 | * Mark the device as detached to avoid processing | ||
2393 | * interrupts until setup is complete. | ||
2394 | */ | ||
2395 | __set_bit(ATH_STAT_INVALID, sc->status); | ||
2396 | |||
2397 | sc->opmode = NL80211_IFTYPE_STATION; | ||
2398 | sc->bintval = 1000; | ||
2399 | mutex_init(&sc->lock); | ||
2400 | spin_lock_init(&sc->rxbuflock); | ||
2401 | spin_lock_init(&sc->txbuflock); | ||
2402 | spin_lock_init(&sc->block); | ||
2403 | |||
2404 | |||
2405 | /* Setup interrupt handler */ | ||
2406 | ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | ||
2407 | if (ret) { | ||
2408 | ATH5K_ERR(sc, "request_irq failed\n"); | ||
2409 | goto err; | ||
2410 | } | ||
2411 | |||
2412 | /* If we passed the test, malloc an ath5k_hw struct */ | ||
2413 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
2414 | if (!sc->ah) { | ||
2415 | ret = -ENOMEM; | ||
2416 | ATH5K_ERR(sc, "out of memory\n"); | ||
2417 | goto err_irq; | ||
2418 | } | ||
2419 | |||
2420 | sc->ah->ah_sc = sc; | ||
2421 | sc->ah->ah_iobase = sc->iobase; | ||
2422 | common = ath5k_hw_common(sc->ah); | ||
2423 | common->ops = &ath5k_common_ops; | ||
2424 | common->bus_ops = bus_ops; | ||
2425 | common->ah = sc->ah; | ||
2426 | common->hw = hw; | ||
2427 | common->priv = sc; | ||
2428 | |||
2429 | /* | ||
2430 | * Cache line size is used to size and align various | ||
2431 | * structures used to communicate with the hardware. | ||
2432 | */ | ||
2433 | ath5k_read_cachesize(common, &csz); | ||
2434 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
2435 | |||
2436 | spin_lock_init(&common->cc_lock); | ||
2437 | |||
2438 | /* Initialize device */ | ||
2439 | ret = ath5k_hw_init(sc); | ||
2440 | if (ret) | ||
2441 | goto err_free_ah; | ||
2442 | |||
2443 | /* set up multi-rate retry capabilities */ | ||
2444 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
2445 | hw->max_rates = 4; | ||
2446 | hw->max_rate_tries = 11; | ||
2447 | } | ||
2448 | |||
2449 | hw->vif_data_size = sizeof(struct ath5k_vif); | ||
2450 | |||
2451 | /* Finish private driver data initialization */ | ||
2452 | ret = ath5k_init(hw); | ||
2453 | if (ret) | ||
2454 | goto err_ah; | ||
2455 | |||
2456 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | ||
2457 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), | ||
2458 | sc->ah->ah_mac_srev, | ||
2459 | sc->ah->ah_phy_revision); | ||
2460 | |||
2461 | if (!sc->ah->ah_single_chip) { | ||
2462 | /* Single chip radio (!RF5111) */ | ||
2463 | if (sc->ah->ah_radio_5ghz_revision && | ||
2464 | !sc->ah->ah_radio_2ghz_revision) { | ||
2465 | /* No 5GHz support -> report 2GHz radio */ | ||
2466 | if (!test_bit(AR5K_MODE_11A, | ||
2467 | sc->ah->ah_capabilities.cap_mode)) { | ||
2468 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
2469 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2470 | sc->ah->ah_radio_5ghz_revision), | ||
2471 | sc->ah->ah_radio_5ghz_revision); | ||
2472 | /* No 2GHz support (5110 and some | ||
2473 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
2474 | } else if (!test_bit(AR5K_MODE_11B, | ||
2475 | sc->ah->ah_capabilities.cap_mode)) { | ||
2476 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
2477 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2478 | sc->ah->ah_radio_5ghz_revision), | ||
2479 | sc->ah->ah_radio_5ghz_revision); | ||
2480 | /* Multiband radio */ | ||
2481 | } else { | ||
2482 | ATH5K_INFO(sc, "RF%s multiband radio found" | ||
2483 | " (0x%x)\n", | ||
2484 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2485 | sc->ah->ah_radio_5ghz_revision), | ||
2486 | sc->ah->ah_radio_5ghz_revision); | ||
2487 | } | ||
2488 | } | ||
2489 | /* Multi chip radio (RF5111 - RF2111) -> | ||
2490 | * report both 2GHz/5GHz radios */ | ||
2491 | else if (sc->ah->ah_radio_5ghz_revision && | ||
2492 | sc->ah->ah_radio_2ghz_revision){ | ||
2493 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
2494 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2495 | sc->ah->ah_radio_5ghz_revision), | ||
2496 | sc->ah->ah_radio_5ghz_revision); | ||
2497 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
2498 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2499 | sc->ah->ah_radio_2ghz_revision), | ||
2500 | sc->ah->ah_radio_2ghz_revision); | ||
2501 | } | ||
2502 | } | ||
2503 | |||
2504 | ath5k_debug_init_device(sc); | ||
2505 | |||
2506 | /* ready to process interrupts */ | ||
2507 | __clear_bit(ATH_STAT_INVALID, sc->status); | ||
2508 | |||
2509 | return 0; | ||
2510 | err_ah: | ||
2511 | ath5k_hw_deinit(sc->ah); | ||
2512 | err_free_ah: | ||
2513 | kfree(sc->ah); | ||
2514 | err_irq: | ||
2515 | free_irq(sc->irq, sc); | ||
2516 | err: | ||
2517 | return ret; | ||
2518 | } | ||
2519 | |||
2341 | static int | 2520 | static int |
2342 | ath5k_stop_locked(struct ath5k_softc *sc) | 2521 | ath5k_stop_locked(struct ath5k_softc *sc) |
2343 | { | 2522 | { |
@@ -2377,7 +2556,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) | |||
2377 | } | 2556 | } |
2378 | 2557 | ||
2379 | static int | 2558 | static int |
2380 | ath5k_init(struct ath5k_softc *sc) | 2559 | ath5k_init_hw(struct ath5k_softc *sc) |
2381 | { | 2560 | { |
2382 | struct ath5k_hw *ah = sc->ah; | 2561 | struct ath5k_hw *ah = sc->ah; |
2383 | struct ath_common *common = ath5k_hw_common(ah); | 2562 | struct ath_common *common = ath5k_hw_common(ah); |
@@ -2575,8 +2754,9 @@ static void ath5k_reset_work(struct work_struct *work) | |||
2575 | } | 2754 | } |
2576 | 2755 | ||
2577 | static int | 2756 | static int |
2578 | ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | 2757 | ath5k_init(struct ieee80211_hw *hw) |
2579 | { | 2758 | { |
2759 | |||
2580 | struct ath5k_softc *sc = hw->priv; | 2760 | struct ath5k_softc *sc = hw->priv; |
2581 | struct ath5k_hw *ah = sc->ah; | 2761 | struct ath5k_hw *ah = sc->ah; |
2582 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); | 2762 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); |
@@ -2584,7 +2764,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
2584 | u8 mac[ETH_ALEN] = {}; | 2764 | u8 mac[ETH_ALEN] = {}; |
2585 | int ret; | 2765 | int ret; |
2586 | 2766 | ||
2587 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); | ||
2588 | 2767 | ||
2589 | /* | 2768 | /* |
2590 | * Check if the MAC has multi-rate retry support. | 2769 | * Check if the MAC has multi-rate retry support. |
@@ -2725,10 +2904,10 @@ err: | |||
2725 | return ret; | 2904 | return ret; |
2726 | } | 2905 | } |
2727 | 2906 | ||
2728 | static void | 2907 | void |
2729 | ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | 2908 | ath5k_deinit_softc(struct ath5k_softc *sc) |
2730 | { | 2909 | { |
2731 | struct ath5k_softc *sc = hw->priv; | 2910 | struct ieee80211_hw *hw = sc->hw; |
2732 | 2911 | ||
2733 | /* | 2912 | /* |
2734 | * NB: the order of these is important: | 2913 | * NB: the order of these is important: |
@@ -2743,6 +2922,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
2743 | * XXX: ??? detach ath5k_hw ??? | 2922 | * XXX: ??? detach ath5k_hw ??? |
2744 | * Other than that, it's straightforward... | 2923 | * Other than that, it's straightforward... |
2745 | */ | 2924 | */ |
2925 | ath5k_debug_finish_device(sc); | ||
2746 | ieee80211_unregister_hw(hw); | 2926 | ieee80211_unregister_hw(hw); |
2747 | ath5k_desc_free(sc); | 2927 | ath5k_desc_free(sc); |
2748 | ath5k_txq_release(sc); | 2928 | ath5k_txq_release(sc); |
@@ -2755,6 +2935,8 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
2755 | * returns because we'll get called back to reclaim node | 2935 | * returns because we'll get called back to reclaim node |
2756 | * state and potentially want to use them. | 2936 | * state and potentially want to use them. |
2757 | */ | 2937 | */ |
2938 | ath5k_hw_deinit(sc->ah); | ||
2939 | free_irq(sc->irq, sc); | ||
2758 | } | 2940 | } |
2759 | 2941 | ||
2760 | /********************\ | 2942 | /********************\ |
@@ -2777,7 +2959,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2777 | 2959 | ||
2778 | static int ath5k_start(struct ieee80211_hw *hw) | 2960 | static int ath5k_start(struct ieee80211_hw *hw) |
2779 | { | 2961 | { |
2780 | return ath5k_init(hw->priv); | 2962 | return ath5k_init_hw(hw->priv); |
2781 | } | 2963 | } |
2782 | 2964 | ||
2783 | static void ath5k_stop(struct ieee80211_hw *hw) | 2965 | static void ath5k_stop(struct ieee80211_hw *hw) |
@@ -3422,7 +3604,7 @@ static int ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) | |||
3422 | return 0; | 3604 | return 0; |
3423 | } | 3605 | } |
3424 | 3606 | ||
3425 | static const struct ieee80211_ops ath5k_hw_ops = { | 3607 | const struct ieee80211_ops ath5k_hw_ops = { |
3426 | .tx = ath5k_tx, | 3608 | .tx = ath5k_tx, |
3427 | .start = ath5k_start, | 3609 | .start = ath5k_start, |
3428 | .stop = ath5k_stop, | 3610 | .stop = ath5k_stop, |
@@ -3456,7 +3638,6 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
3456 | { | 3638 | { |
3457 | void __iomem *mem; | 3639 | void __iomem *mem; |
3458 | struct ath5k_softc *sc; | 3640 | struct ath5k_softc *sc; |
3459 | struct ath_common *common; | ||
3460 | struct ieee80211_hw *hw; | 3641 | struct ieee80211_hw *hw; |
3461 | int ret; | 3642 | int ret; |
3462 | u8 csz; | 3643 | u8 csz; |
@@ -3552,146 +3733,24 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
3552 | 3733 | ||
3553 | dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); | 3734 | dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); |
3554 | 3735 | ||
3555 | /* Initialize driver private data */ | ||
3556 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
3557 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
3558 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
3559 | IEEE80211_HW_SIGNAL_DBM; | ||
3560 | |||
3561 | hw->wiphy->interface_modes = | ||
3562 | BIT(NL80211_IFTYPE_AP) | | ||
3563 | BIT(NL80211_IFTYPE_STATION) | | ||
3564 | BIT(NL80211_IFTYPE_ADHOC) | | ||
3565 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
3566 | |||
3567 | hw->extra_tx_headroom = 2; | ||
3568 | hw->channel_change_time = 5000; | ||
3569 | sc = hw->priv; | 3736 | sc = hw->priv; |
3570 | sc->hw = hw; | 3737 | sc->hw = hw; |
3571 | sc->pdev = pdev; | 3738 | sc->pdev = pdev; |
3572 | sc->dev = &pdev->dev; | 3739 | sc->dev = &pdev->dev; |
3573 | sc->irq = pdev->irq; | 3740 | sc->irq = pdev->irq; |
3574 | 3741 | sc->devid = id->device; | |
3575 | /* | ||
3576 | * Mark the device as detached to avoid processing | ||
3577 | * interrupts until setup is complete. | ||
3578 | */ | ||
3579 | __set_bit(ATH_STAT_INVALID, sc->status); | ||
3580 | |||
3581 | sc->iobase = mem; /* So we can unmap it on detach */ | 3742 | sc->iobase = mem; /* So we can unmap it on detach */ |
3582 | sc->opmode = NL80211_IFTYPE_STATION; | ||
3583 | sc->bintval = 1000; | ||
3584 | mutex_init(&sc->lock); | ||
3585 | spin_lock_init(&sc->rxbuflock); | ||
3586 | spin_lock_init(&sc->txbuflock); | ||
3587 | spin_lock_init(&sc->block); | ||
3588 | 3743 | ||
3589 | /* Set private data */ | 3744 | /* Initialize */ |
3590 | pci_set_drvdata(pdev, sc); | 3745 | ret = ath5k_init_softc(sc, &ath_pci_bus_ops); |
3591 | |||
3592 | /* Setup interrupt handler */ | ||
3593 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | ||
3594 | if (ret) { | 3746 | if (ret) { |
3595 | ATH5K_ERR(sc, "request_irq failed\n"); | ||
3596 | goto err_free; | 3747 | goto err_free; |
3597 | } | 3748 | } |
3598 | 3749 | ||
3599 | /* If we passed the test, malloc an ath5k_hw struct */ | 3750 | /* Set private data */ |
3600 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | 3751 | pci_set_drvdata(pdev, hw); |
3601 | if (!sc->ah) { | ||
3602 | ret = -ENOMEM; | ||
3603 | ATH5K_ERR(sc, "out of memory\n"); | ||
3604 | goto err_irq; | ||
3605 | } | ||
3606 | |||
3607 | sc->ah->ah_sc = sc; | ||
3608 | sc->ah->ah_iobase = sc->iobase; | ||
3609 | common = ath5k_hw_common(sc->ah); | ||
3610 | common->ops = &ath5k_common_ops; | ||
3611 | common->ah = sc->ah; | ||
3612 | common->hw = hw; | ||
3613 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
3614 | spin_lock_init(&common->cc_lock); | ||
3615 | |||
3616 | /* Initialize device */ | ||
3617 | ret = ath5k_hw_attach(sc); | ||
3618 | if (ret) { | ||
3619 | goto err_free_ah; | ||
3620 | } | ||
3621 | |||
3622 | /* set up multi-rate retry capabilities */ | ||
3623 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
3624 | hw->max_rates = 4; | ||
3625 | hw->max_rate_tries = 11; | ||
3626 | } | ||
3627 | |||
3628 | hw->vif_data_size = sizeof(struct ath5k_vif); | ||
3629 | |||
3630 | /* Finish private driver data initialization */ | ||
3631 | ret = ath5k_attach(pdev, hw); | ||
3632 | if (ret) | ||
3633 | goto err_ah; | ||
3634 | |||
3635 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | ||
3636 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), | ||
3637 | sc->ah->ah_mac_srev, | ||
3638 | sc->ah->ah_phy_revision); | ||
3639 | |||
3640 | if (!sc->ah->ah_single_chip) { | ||
3641 | /* Single chip radio (!RF5111) */ | ||
3642 | if (sc->ah->ah_radio_5ghz_revision && | ||
3643 | !sc->ah->ah_radio_2ghz_revision) { | ||
3644 | /* No 5GHz support -> report 2GHz radio */ | ||
3645 | if (!test_bit(AR5K_MODE_11A, | ||
3646 | sc->ah->ah_capabilities.cap_mode)) { | ||
3647 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
3648 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3649 | sc->ah->ah_radio_5ghz_revision), | ||
3650 | sc->ah->ah_radio_5ghz_revision); | ||
3651 | /* No 2GHz support (5110 and some | ||
3652 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
3653 | } else if (!test_bit(AR5K_MODE_11B, | ||
3654 | sc->ah->ah_capabilities.cap_mode)) { | ||
3655 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
3656 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3657 | sc->ah->ah_radio_5ghz_revision), | ||
3658 | sc->ah->ah_radio_5ghz_revision); | ||
3659 | /* Multiband radio */ | ||
3660 | } else { | ||
3661 | ATH5K_INFO(sc, "RF%s multiband radio found" | ||
3662 | " (0x%x)\n", | ||
3663 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3664 | sc->ah->ah_radio_5ghz_revision), | ||
3665 | sc->ah->ah_radio_5ghz_revision); | ||
3666 | } | ||
3667 | } | ||
3668 | /* Multi chip radio (RF5111 - RF2111) -> | ||
3669 | * report both 2GHz/5GHz radios */ | ||
3670 | else if (sc->ah->ah_radio_5ghz_revision && | ||
3671 | sc->ah->ah_radio_2ghz_revision){ | ||
3672 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
3673 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3674 | sc->ah->ah_radio_5ghz_revision), | ||
3675 | sc->ah->ah_radio_5ghz_revision); | ||
3676 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
3677 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
3678 | sc->ah->ah_radio_2ghz_revision), | ||
3679 | sc->ah->ah_radio_2ghz_revision); | ||
3680 | } | ||
3681 | } | ||
3682 | |||
3683 | ath5k_debug_init_device(sc); | ||
3684 | |||
3685 | /* ready to process interrupts */ | ||
3686 | __clear_bit(ATH_STAT_INVALID, sc->status); | ||
3687 | 3752 | ||
3688 | return 0; | 3753 | return 0; |
3689 | err_ah: | ||
3690 | ath5k_hw_detach(sc->ah); | ||
3691 | err_free_ah: | ||
3692 | kfree(sc->ah); | ||
3693 | err_irq: | ||
3694 | free_irq(pdev->irq, sc); | ||
3695 | err_free: | 3754 | err_free: |
3696 | ieee80211_free_hw(hw); | 3755 | ieee80211_free_hw(hw); |
3697 | err_map: | 3756 | err_map: |
@@ -3707,17 +3766,14 @@ err: | |||
3707 | static void __devexit | 3766 | static void __devexit |
3708 | ath5k_pci_remove(struct pci_dev *pdev) | 3767 | ath5k_pci_remove(struct pci_dev *pdev) |
3709 | { | 3768 | { |
3710 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | 3769 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
3770 | struct ath5k_softc *sc = hw->priv; | ||
3711 | 3771 | ||
3712 | ath5k_debug_finish_device(sc); | 3772 | ath5k_deinit_softc(sc); |
3713 | ath5k_detach(pdev, sc->hw); | ||
3714 | ath5k_hw_detach(sc->ah); | ||
3715 | kfree(sc->ah); | ||
3716 | free_irq(pdev->irq, sc); | ||
3717 | pci_iounmap(pdev, sc->iobase); | 3773 | pci_iounmap(pdev, sc->iobase); |
3718 | pci_release_region(pdev, 0); | 3774 | pci_release_region(pdev, 0); |
3719 | pci_disable_device(pdev); | 3775 | pci_disable_device(pdev); |
3720 | ieee80211_free_hw(sc->hw); | 3776 | ieee80211_free_hw(hw); |
3721 | } | 3777 | } |
3722 | 3778 | ||
3723 | #ifdef CONFIG_PM_SLEEP | 3779 | #ifdef CONFIG_PM_SLEEP |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 0362f8eb9510..aa6c32aafb59 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -172,6 +172,7 @@ struct ath5k_softc { | |||
172 | struct pci_dev *pdev; | 172 | struct pci_dev *pdev; |
173 | struct device *dev; /* for dma mapping */ | 173 | struct device *dev; /* for dma mapping */ |
174 | int irq; | 174 | int irq; |
175 | u16 devid; | ||
175 | void __iomem *iobase; /* address of the device */ | 176 | void __iomem *iobase; /* address of the device */ |
176 | struct mutex lock; /* dev-level lock */ | 177 | struct mutex lock; /* dev-level lock */ |
177 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ | 178 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 033eab9ad4e7..a648957501e2 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -208,7 +208,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | |||
208 | * | 208 | * |
209 | * XXX: Serdes values seem to be fixed so | 209 | * XXX: Serdes values seem to be fixed so |
210 | * no need to read them here, we write them | 210 | * no need to read them here, we write them |
211 | * during ath5k_hw_attach */ | 211 | * during ath5k_hw_init */ |
212 | AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); | 212 | AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); |
213 | ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? | 213 | ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? |
214 | true : false; | 214 | true : false; |