58
58
#include "reg.h"
59
59
#include "debug.h"
60
60
61
- enum {
62
- ATH_LED_TX ,
63
- ATH_LED_RX ,
64
- };
65
-
66
61
static int ath5k_calinterval = 10 ; /* Calibrate PHY every 10 secs (TODO: Fixme) */
67
62
68
63
@@ -309,13 +304,10 @@ static void ath5k_tasklet_reset(unsigned long data);
309
304
310
305
static void ath5k_calibrate (unsigned long data );
311
306
/* LED functions */
312
- static void ath5k_led_off (unsigned long data );
313
- static void ath5k_led_blink (struct ath5k_softc * sc ,
314
- unsigned int on ,
315
- unsigned int off );
316
- static void ath5k_led_event (struct ath5k_softc * sc ,
317
- int event );
318
-
307
+ static int ath5k_init_leds (struct ath5k_softc * sc );
308
+ static void ath5k_led_enable (struct ath5k_softc * sc );
309
+ static void ath5k_led_off (struct ath5k_softc * sc );
310
+ static void ath5k_unregister_leds (struct ath5k_softc * sc );
319
311
320
312
/*
321
313
* Module init/exit functions
@@ -596,8 +588,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
596
588
struct ieee80211_hw * hw = pci_get_drvdata (pdev );
597
589
struct ath5k_softc * sc = hw -> priv ;
598
590
599
- if (test_bit (ATH_STAT_LEDSOFT , sc -> status ))
600
- ath5k_hw_set_gpio (sc -> ah , sc -> led_pin , 1 );
591
+ ath5k_led_off (sc );
601
592
602
593
ath5k_stop_hw (sc );
603
594
pci_save_state (pdev );
@@ -632,10 +623,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
632
623
pci_write_config_byte (pdev , 0x41 , 0 );
633
624
634
625
ath5k_init (sc );
635
- if (test_bit (ATH_STAT_LEDSOFT , sc -> status )) {
636
- ath5k_hw_set_gpio_output (ah , sc -> led_pin );
637
- ath5k_hw_set_gpio (ah , sc -> led_pin , 0 );
638
- }
626
+ ath5k_led_enable (sc );
639
627
640
628
/*
641
629
* Reset the key cache since some parts do not
@@ -742,27 +730,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
742
730
tasklet_init (& sc -> txtq , ath5k_tasklet_tx , (unsigned long )sc );
743
731
tasklet_init (& sc -> restq , ath5k_tasklet_reset , (unsigned long )sc );
744
732
setup_timer (& sc -> calib_tim , ath5k_calibrate , (unsigned long )sc );
745
- setup_timer (& sc -> led_tim , ath5k_led_off , (unsigned long )sc );
746
-
747
- sc -> led_on = 0 ; /* low true */
748
- /*
749
- * Auto-enable soft led processing for IBM cards and for
750
- * 5211 minipci cards.
751
- */
752
- if (pdev -> device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
753
- pdev -> device == PCI_DEVICE_ID_ATHEROS_AR5211 ) {
754
- __set_bit (ATH_STAT_LEDSOFT , sc -> status );
755
- sc -> led_pin = 0 ;
756
- }
757
- /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
758
- if (pdev -> subsystem_vendor == PCI_VENDOR_ID_COMPAQ ) {
759
- __set_bit (ATH_STAT_LEDSOFT , sc -> status );
760
- sc -> led_pin = 0 ;
761
- }
762
- if (test_bit (ATH_STAT_LEDSOFT , sc -> status )) {
763
- ath5k_hw_set_gpio_output (ah , sc -> led_pin );
764
- ath5k_hw_set_gpio (ah , sc -> led_pin , !sc -> led_on );
765
- }
766
733
767
734
ath5k_hw_get_lladdr (ah , mac );
768
735
SET_IEEE80211_PERM_ADDR (hw , mac );
@@ -776,6 +743,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
776
743
goto err_queues ;
777
744
}
778
745
746
+ ath5k_init_leds (sc );
747
+
779
748
return 0 ;
780
749
err_queues :
781
750
ath5k_txq_release (sc );
@@ -809,6 +778,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
809
778
ath5k_desc_free (sc , pdev );
810
779
ath5k_txq_release (sc );
811
780
ath5k_hw_release_tx_queue (sc -> ah , sc -> bhalq );
781
+ ath5k_unregister_leds (sc );
812
782
813
783
/*
814
784
* NB: can't reclaim these until after ieee80211_ifdetach
@@ -1060,65 +1030,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
1060
1030
return 0 ;
1061
1031
}
1062
1032
1063
- /*
1064
- * TODO: CLEAN THIS !!!
1065
- */
1066
1033
static void
1067
1034
ath5k_setcurmode (struct ath5k_softc * sc , unsigned int mode )
1068
1035
{
1069
- if (unlikely (test_bit (ATH_STAT_LEDSOFT , sc -> status ))) {
1070
- /* from Atheros NDIS driver, w/ permission */
1071
- static const struct {
1072
- u16 rate ; /* tx/rx 802.11 rate */
1073
- u16 timeOn ; /* LED on time (ms) */
1074
- u16 timeOff ; /* LED off time (ms) */
1075
- } blinkrates [] = {
1076
- { 108 , 40 , 10 },
1077
- { 96 , 44 , 11 },
1078
- { 72 , 50 , 13 },
1079
- { 48 , 57 , 14 },
1080
- { 36 , 67 , 16 },
1081
- { 24 , 80 , 20 },
1082
- { 22 , 100 , 25 },
1083
- { 18 , 133 , 34 },
1084
- { 12 , 160 , 40 },
1085
- { 10 , 200 , 50 },
1086
- { 6 , 240 , 58 },
1087
- { 4 , 267 , 66 },
1088
- { 2 , 400 , 100 },
1089
- { 0 , 500 , 130 }
1090
- };
1091
- const struct ath5k_rate_table * rt =
1092
- ath5k_hw_get_rate_table (sc -> ah , mode );
1093
- unsigned int i , j ;
1094
-
1095
- BUG_ON (rt == NULL );
1096
-
1097
- memset (sc -> hwmap , 0 , sizeof (sc -> hwmap ));
1098
- for (i = 0 ; i < 32 ; i ++ ) {
1099
- u8 ix = rt -> rate_code_to_index [i ];
1100
- if (ix == 0xff ) {
1101
- sc -> hwmap [i ].ledon = msecs_to_jiffies (500 );
1102
- sc -> hwmap [i ].ledoff = msecs_to_jiffies (130 );
1103
- continue ;
1104
- }
1105
- sc -> hwmap [i ].txflags = IEEE80211_RADIOTAP_F_DATAPAD ;
1106
- /* receive frames include FCS */
1107
- sc -> hwmap [i ].rxflags = sc -> hwmap [i ].txflags |
1108
- IEEE80211_RADIOTAP_F_FCS ;
1109
- /* setup blink rate table to avoid per-packet lookup */
1110
- for (j = 0 ; j < ARRAY_SIZE (blinkrates ) - 1 ; j ++ )
1111
- if (blinkrates [j ].rate == /* XXX why 7f? */
1112
- (rt -> rates [ix ].dot11_rate & 0x7f ))
1113
- break ;
1114
-
1115
- sc -> hwmap [i ].ledon = msecs_to_jiffies (blinkrates [j ].
1116
- timeOn );
1117
- sc -> hwmap [i ].ledoff = msecs_to_jiffies (blinkrates [j ].
1118
- timeOff );
1119
- }
1120
- }
1121
-
1122
1036
sc -> curmode = mode ;
1123
1037
1124
1038
if (mode == AR5K_MODE_11A ) {
@@ -1900,8 +1814,6 @@ ath5k_tasklet_rx(unsigned long data)
1900
1814
ath5k_check_ibss_tsf (sc , skb , & rxs );
1901
1815
1902
1816
__ieee80211_rx (sc -> hw , skb , & rxs );
1903
- sc -> led_rxrate = rs .rs_rate ;
1904
- ath5k_led_event (sc , ATH_LED_RX );
1905
1817
next :
1906
1818
list_move_tail (& bf -> list , & sc -> rxbuf );
1907
1819
} while (ath5k_rxbuf_setup (sc , bf ) == 0 );
@@ -1982,13 +1894,9 @@ ath5k_tasklet_tx(unsigned long data)
1982
1894
struct ath5k_softc * sc = (void * )data ;
1983
1895
1984
1896
ath5k_tx_processq (sc , sc -> txq );
1985
-
1986
- ath5k_led_event (sc , ATH_LED_TX );
1987
1897
}
1988
1898
1989
1899
1990
-
1991
-
1992
1900
/*****************\
1993
1901
* Beacon handling *
1994
1902
\*****************/
@@ -2363,11 +2271,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
2363
2271
ieee80211_stop_queues (sc -> hw );
2364
2272
2365
2273
if (!test_bit (ATH_STAT_INVALID , sc -> status )) {
2366
- if (test_bit (ATH_STAT_LEDSOFT , sc -> status )) {
2367
- del_timer_sync (& sc -> led_tim );
2368
- ath5k_hw_set_gpio (ah , sc -> led_pin , !sc -> led_on );
2369
- __clear_bit (ATH_STAT_LEDBLINKING , sc -> status );
2370
- }
2274
+ ath5k_led_off (sc );
2371
2275
ath5k_hw_set_intr (ah , 0 );
2372
2276
}
2373
2277
ath5k_txq_cleanup (sc );
@@ -2563,54 +2467,123 @@ ath5k_calibrate(unsigned long data)
2563
2467
\***************/
2564
2468
2565
2469
static void
2566
- ath5k_led_off ( unsigned long data )
2470
+ ath5k_led_enable ( struct ath5k_softc * sc )
2567
2471
{
2568
- struct ath5k_softc * sc = (void * )data ;
2569
-
2570
- if (test_bit (ATH_STAT_LEDENDBLINK , sc -> status ))
2571
- __clear_bit (ATH_STAT_LEDBLINKING , sc -> status );
2572
- else {
2573
- __set_bit (ATH_STAT_LEDENDBLINK , sc -> status );
2574
- ath5k_hw_set_gpio (sc -> ah , sc -> led_pin , !sc -> led_on );
2575
- mod_timer (& sc -> led_tim , jiffies + sc -> led_off );
2472
+ if (test_bit (ATH_STAT_LEDSOFT , sc -> status )) {
2473
+ ath5k_hw_set_gpio_output (sc -> ah , sc -> led_pin );
2474
+ ath5k_led_off (sc );
2576
2475
}
2577
2476
}
2578
2477
2579
- /*
2580
- * Blink the LED according to the specified on/off times.
2581
- */
2582
2478
static void
2583
- ath5k_led_blink (struct ath5k_softc * sc , unsigned int on ,
2584
- unsigned int off )
2479
+ ath5k_led_on (struct ath5k_softc * sc )
2585
2480
{
2586
- ATH5K_DBG (sc , ATH5K_DEBUG_LED , "on %u off %u\n" , on , off );
2481
+ if (!test_bit (ATH_STAT_LEDSOFT , sc -> status ))
2482
+ return ;
2587
2483
ath5k_hw_set_gpio (sc -> ah , sc -> led_pin , sc -> led_on );
2588
- __set_bit (ATH_STAT_LEDBLINKING , sc -> status );
2589
- __clear_bit (ATH_STAT_LEDENDBLINK , sc -> status );
2590
- sc -> led_off = off ;
2591
- mod_timer (& sc -> led_tim , jiffies + on );
2592
2484
}
2593
2485
2594
2486
static void
2595
- ath5k_led_event (struct ath5k_softc * sc , int event )
2487
+ ath5k_led_off (struct ath5k_softc * sc )
2596
2488
{
2597
- if (likely ( !test_bit (ATH_STAT_LEDSOFT , sc -> status ) ))
2489
+ if (!test_bit (ATH_STAT_LEDSOFT , sc -> status ))
2598
2490
return ;
2599
- if (unlikely (test_bit (ATH_STAT_LEDBLINKING , sc -> status )))
2600
- return ; /* don't interrupt active blink */
2601
- switch (event ) {
2602
- case ATH_LED_TX :
2603
- ath5k_led_blink (sc , sc -> hwmap [sc -> led_txrate ].ledon ,
2604
- sc -> hwmap [sc -> led_txrate ].ledoff );
2605
- break ;
2606
- case ATH_LED_RX :
2607
- ath5k_led_blink (sc , sc -> hwmap [sc -> led_rxrate ].ledon ,
2608
- sc -> hwmap [sc -> led_rxrate ].ledoff );
2609
- break ;
2491
+ ath5k_hw_set_gpio (sc -> ah , sc -> led_pin , !sc -> led_on );
2492
+ }
2493
+
2494
+ static void
2495
+ ath5k_led_brightness_set (struct led_classdev * led_dev ,
2496
+ enum led_brightness brightness )
2497
+ {
2498
+ struct ath5k_led * led = container_of (led_dev , struct ath5k_led ,
2499
+ led_dev );
2500
+
2501
+ if (brightness == LED_OFF )
2502
+ ath5k_led_off (led -> sc );
2503
+ else
2504
+ ath5k_led_on (led -> sc );
2505
+ }
2506
+
2507
+ static int
2508
+ ath5k_register_led (struct ath5k_softc * sc , struct ath5k_led * led ,
2509
+ const char * name , char * trigger )
2510
+ {
2511
+ int err ;
2512
+
2513
+ led -> sc = sc ;
2514
+ strncpy (led -> name , name , sizeof (led -> name ));
2515
+ led -> led_dev .name = led -> name ;
2516
+ led -> led_dev .default_trigger = trigger ;
2517
+ led -> led_dev .brightness_set = ath5k_led_brightness_set ;
2518
+
2519
+ err = led_classdev_register (& sc -> pdev -> dev , & led -> led_dev );
2520
+ if (err )
2521
+ {
2522
+ ATH5K_WARN (sc , "could not register LED %s\n" , name );
2523
+ led -> sc = NULL ;
2610
2524
}
2525
+ return err ;
2526
+ }
2527
+
2528
+ static void
2529
+ ath5k_unregister_led (struct ath5k_led * led )
2530
+ {
2531
+ if (!led -> sc )
2532
+ return ;
2533
+ led_classdev_unregister (& led -> led_dev );
2534
+ ath5k_led_off (led -> sc );
2535
+ led -> sc = NULL ;
2536
+ }
2537
+
2538
+ static void
2539
+ ath5k_unregister_leds (struct ath5k_softc * sc )
2540
+ {
2541
+ ath5k_unregister_led (& sc -> rx_led );
2542
+ ath5k_unregister_led (& sc -> tx_led );
2611
2543
}
2612
2544
2613
2545
2546
+ static int
2547
+ ath5k_init_leds (struct ath5k_softc * sc )
2548
+ {
2549
+ int ret = 0 ;
2550
+ struct ieee80211_hw * hw = sc -> hw ;
2551
+ struct pci_dev * pdev = sc -> pdev ;
2552
+ char name [ATH5K_LED_MAX_NAME_LEN + 1 ];
2553
+
2554
+ sc -> led_on = 0 ; /* active low */
2555
+
2556
+ /*
2557
+ * Auto-enable soft led processing for IBM cards and for
2558
+ * 5211 minipci cards.
2559
+ */
2560
+ if (pdev -> device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
2561
+ pdev -> device == PCI_DEVICE_ID_ATHEROS_AR5211 ) {
2562
+ __set_bit (ATH_STAT_LEDSOFT , sc -> status );
2563
+ sc -> led_pin = 0 ;
2564
+ }
2565
+ /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
2566
+ if (pdev -> subsystem_vendor == PCI_VENDOR_ID_COMPAQ ) {
2567
+ __set_bit (ATH_STAT_LEDSOFT , sc -> status );
2568
+ sc -> led_pin = 1 ;
2569
+ }
2570
+ if (!test_bit (ATH_STAT_LEDSOFT , sc -> status ))
2571
+ goto out ;
2572
+
2573
+ ath5k_led_enable (sc );
2574
+
2575
+ snprintf (name , sizeof (name ), "ath5k-%s::rx" , wiphy_name (hw -> wiphy ));
2576
+ ret = ath5k_register_led (sc , & sc -> rx_led , name ,
2577
+ ieee80211_get_rx_led_name (hw ));
2578
+ if (ret )
2579
+ goto out ;
2580
+
2581
+ snprintf (name , sizeof (name ), "ath5k-%s::tx" , wiphy_name (hw -> wiphy ));
2582
+ ret = ath5k_register_led (sc , & sc -> tx_led , name ,
2583
+ ieee80211_get_tx_led_name (hw ));
2584
+ out :
2585
+ return ret ;
2586
+ }
2614
2587
2615
2588
2616
2589
/********************\
@@ -2648,8 +2621,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2648
2621
memmove (skb -> data , skb -> data + pad , hdrlen );
2649
2622
}
2650
2623
2651
- sc -> led_txrate = ieee80211_get_tx_rate (hw , info )-> hw_value ;
2652
-
2653
2624
spin_lock_irqsave (& sc -> txbuflock , flags );
2654
2625
if (list_empty (& sc -> txbuf )) {
2655
2626
ATH5K_ERR (sc , "no further txbuf available, dropping packet\n" );
0 commit comments