aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-12-02 04:26:56 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-02 15:17:50 -0500
commit132b1c3ee38ea6fa0501004fd0f19acb554e5a44 (patch)
tree3bb52a5ef7738b56581f17ffeececbf647f34a97
parentaeae4ac9090462ea38387dcdbac4f01b944af6a4 (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>
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h13
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c10
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c344
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c2
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 899bf4b99b7..a74f448f7d7 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 */
1150int ath5k_hw_attach(struct ath5k_softc *sc); 1150int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops);
1151void ath5k_hw_detach(struct ath5k_hw *ah); 1151void ath5k_deinit_softc(struct ath5k_softc *sc);
1152int ath5k_hw_init(struct ath5k_softc *sc);
1153void ath5k_hw_deinit(struct ath5k_hw *ah);
1152 1154
1153int ath5k_sysfs_register(struct ath5k_softc *sc); 1155int ath5k_sysfs_register(struct ath5k_softc *sc);
1154void ath5k_sysfs_unregister(struct ath5k_softc *sc); 1156void 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
1337static inline void ath5k_read_cachesize(struct ath_common *common, int *csz)
1338{
1339 common->bus_ops->read_cachesize(common, csz);
1340}
1341
1335static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) 1342static 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 ed86b9dde1b..a84782a63e0 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 */
105int ath5k_hw_attach(struct ath5k_softc *sc) 105int 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 */
353void ath5k_hw_detach(struct ath5k_hw *ah) 353void 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 2d7d8bac461..b11ea3d2872 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");
80MODULE_LICENSE("Dual BSD/GPL"); 80MODULE_LICENSE("Dual BSD/GPL");
81MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); 81MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
82 82
83static int ath5k_init(struct ieee80211_hw *hw);
83static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, 84static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
84 bool skip_pcu); 85 bool skip_pcu);
85static int ath5k_beacon_update(struct ieee80211_hw *hw, 86static 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 */
197static 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 */
216static 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
195static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, 222static 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
2155static irqreturn_t 2182irqreturn_t
2156ath5k_intr(int irq, void *dev_id) 2183ath5k_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
2368int
2369ath5k_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;
2510err_ah:
2511 ath5k_hw_deinit(sc->ah);
2512err_free_ah:
2513 kfree(sc->ah);
2514err_irq:
2515 free_irq(sc->irq, sc);
2516err:
2517 return ret;
2518}
2519
2341static int 2520static int
2342ath5k_stop_locked(struct ath5k_softc *sc) 2521ath5k_stop_locked(struct ath5k_softc *sc)
2343{ 2522{
@@ -2377,7 +2556,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
2377} 2556}
2378 2557
2379static int 2558static int
2380ath5k_init(struct ath5k_softc *sc) 2559ath5k_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
2577static int 2756static int
2578ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) 2757ath5k_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
2728static void 2907void
2729ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) 2908ath5k_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
2778static int ath5k_start(struct ieee80211_hw *hw) 2960static 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
2783static void ath5k_stop(struct ieee80211_hw *hw) 2965static 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
3425static const struct ieee80211_ops ath5k_hw_ops = { 3607const 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;
3689err_ah:
3690 ath5k_hw_detach(sc->ah);
3691err_free_ah:
3692 kfree(sc->ah);
3693err_irq:
3694 free_irq(pdev->irq, sc);
3695err_free: 3754err_free:
3696 ieee80211_free_hw(hw); 3755 ieee80211_free_hw(hw);
3697err_map: 3756err_map:
@@ -3707,17 +3766,14 @@ err:
3707static void __devexit 3766static void __devexit
3708ath5k_pci_remove(struct pci_dev *pdev) 3767ath5k_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 0362f8eb951..aa6c32aafb5 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 033eab9ad4e..a648957501e 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;