Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 1 | #include "headers.h" |
| 2 | |
| 3 | #define STATUS_IMAGE_CHECKSUM_MISMATCH -199 |
| 4 | #define EVENT_SIGNALED 1 |
| 5 | |
| 6 | static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size) |
| 7 | { |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 8 | B_UINT16 u16CheckSum = 0; |
Pawel Lebioda | 89fa037 | 2014-07-09 17:59:29 +0200 | [diff] [blame] | 9 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 10 | while (u32Size--) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 11 | u16CheckSum += (B_UINT8)~(*pu8Buffer); |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 12 | pu8Buffer++; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 13 | } |
| 14 | return u16CheckSum; |
| 15 | } |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 16 | |
Lisa Nguyen | 3abd6f1 | 2013-10-28 01:35:59 -0700 | [diff] [blame] | 17 | bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 18 | { |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 19 | INT Status; |
Pawel Lebioda | 89fa037 | 2014-07-09 17:59:29 +0200 | [diff] [blame] | 20 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 21 | Status = (Adapter->gpioBitMap & gpios) ^ gpios; |
| 22 | if (Status) |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 23 | return false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 24 | else |
| 25 | return TRUE; |
| 26 | } |
| 27 | |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 28 | static INT LED_Blink(struct bcm_mini_adapter *Adapter, |
| 29 | UINT GPIO_Num, |
| 30 | UCHAR uiLedIndex, |
| 31 | ULONG timeout, |
| 32 | INT num_of_time, |
| 33 | enum bcm_led_events currdriverstate) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 34 | { |
| 35 | int Status = STATUS_SUCCESS; |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 36 | bool bInfinite = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 37 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 38 | /* Check if num_of_time is -ve. If yes, blink led in infinite loop */ |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 39 | if (num_of_time < 0) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 40 | bInfinite = TRUE; |
| 41 | num_of_time = 1; |
| 42 | } |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 43 | while (num_of_time) { |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 44 | if (currdriverstate == Adapter->DriverState) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 45 | TURN_ON_LED(Adapter, GPIO_Num, uiLedIndex); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 46 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 47 | /* Wait for timeout after setting on the LED */ |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 48 | Status = wait_event_interruptible_timeout( |
| 49 | Adapter->LEDInfo.notify_led_event, |
| 50 | currdriverstate != Adapter->DriverState || |
| 51 | kthread_should_stop(), |
| 52 | msecs_to_jiffies(timeout)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 53 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 54 | if (kthread_should_stop()) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 55 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
| 56 | DBG_LVL_ALL, |
| 57 | "Led thread got signal to exit..hence exiting"); |
| 58 | Adapter->LEDInfo.led_thread_running = |
| 59 | BCM_LED_THREAD_DISABLED; |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 60 | TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 61 | Status = EVENT_SIGNALED; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 62 | break; |
| 63 | } |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 64 | if (Status) { |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 65 | TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 66 | Status = EVENT_SIGNALED; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 67 | break; |
| 68 | } |
| 69 | |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 70 | TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 71 | Status = wait_event_interruptible_timeout( |
| 72 | Adapter->LEDInfo.notify_led_event, |
| 73 | currdriverstate != Adapter->DriverState || |
| 74 | kthread_should_stop(), |
| 75 | msecs_to_jiffies(timeout)); |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 76 | if (bInfinite == false) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 77 | num_of_time--; |
| 78 | } |
| 79 | return Status; |
| 80 | } |
| 81 | |
Arnd Bergmann | 44a17eff | 2010-09-30 10:24:12 +0200 | [diff] [blame] | 82 | static INT ScaleRateofTransfer(ULONG rate) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 83 | { |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 84 | if (rate <= 3) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 85 | return rate; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 86 | else if ((rate > 3) && (rate <= 100)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 87 | return 5; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 88 | else if ((rate > 100) && (rate <= 200)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 89 | return 6; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 90 | else if ((rate > 200) && (rate <= 300)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 91 | return 7; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 92 | else if ((rate > 300) && (rate <= 400)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 93 | return 8; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 94 | else if ((rate > 400) && (rate <= 500)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 95 | return 9; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 96 | else if ((rate > 500) && (rate <= 600)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 97 | return 10; |
| 98 | else |
| 99 | return MAX_NUM_OF_BLINKS; |
| 100 | } |
| 101 | |
Matthias Beyer | 60654a8 | 2014-06-23 21:18:23 +0200 | [diff] [blame] | 102 | static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad, |
Matthias Beyer | 9c805bd | 2014-06-23 21:18:26 +0200 | [diff] [blame] | 103 | INT *time, |
| 104 | INT *time_tx, |
| 105 | INT *time_rx, |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 106 | UCHAR GPIO_Num_tx, |
| 107 | UCHAR uiTxLedIndex, |
| 108 | UCHAR GPIO_Num_rx, |
| 109 | UCHAR uiRxLedIndex, |
| 110 | enum bcm_led_events currdriverstate, |
| 111 | ulong *timeout) |
| 112 | { |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 113 | /* |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 114 | * Assign minimum number of blinks of |
| 115 | * either Tx or Rx. |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 116 | */ |
Matthias Beyer | 8955051 | 2014-06-23 21:18:27 +0200 | [diff] [blame] | 117 | *time = (*time_tx > *time_rx ? *time_rx : *time_tx); |
| 118 | |
Matthias Beyer | 9c805bd | 2014-06-23 21:18:26 +0200 | [diff] [blame] | 119 | if (*time > 0) { |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 120 | /* Blink both Tx and Rx LEDs */ |
Matthias Beyer | a143aa2 | 2014-06-23 21:18:28 +0200 | [diff] [blame] | 121 | if ((LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout, |
| 122 | *time, currdriverstate) == EVENT_SIGNALED) || |
| 123 | (LED_Blink(ad, 1 << GPIO_Num_rx, uiRxLedIndex, *timeout, |
| 124 | *time, currdriverstate) == EVENT_SIGNALED)) |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 125 | return EVENT_SIGNALED; |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 126 | } |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 127 | |
Matthias Beyer | 9c805bd | 2014-06-23 21:18:26 +0200 | [diff] [blame] | 128 | if (*time == *time_tx) { |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 129 | /* Blink pending rate of Rx */ |
Matthias Beyer | 60e66d8 | 2014-06-23 21:18:25 +0200 | [diff] [blame] | 130 | if (LED_Blink(ad, (1 << GPIO_Num_rx), uiRxLedIndex, *timeout, |
Matthias Beyer | 9c805bd | 2014-06-23 21:18:26 +0200 | [diff] [blame] | 131 | *time_rx - *time, |
Matthias Beyer | 60e66d8 | 2014-06-23 21:18:25 +0200 | [diff] [blame] | 132 | currdriverstate) == EVENT_SIGNALED) |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 133 | return EVENT_SIGNALED; |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 134 | |
Matthias Beyer | 9c805bd | 2014-06-23 21:18:26 +0200 | [diff] [blame] | 135 | *time = *time_rx; |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 136 | } else { |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 137 | /* Blink pending rate of Tx */ |
Matthias Beyer | 60e66d8 | 2014-06-23 21:18:25 +0200 | [diff] [blame] | 138 | if (LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout, |
Matthias Beyer | 9c805bd | 2014-06-23 21:18:26 +0200 | [diff] [blame] | 139 | *time_tx - *time, |
Matthias Beyer | 60e66d8 | 2014-06-23 21:18:25 +0200 | [diff] [blame] | 140 | currdriverstate) == EVENT_SIGNALED) |
Matthias Beyer | ea20548 | 2014-06-23 21:18:24 +0200 | [diff] [blame] | 141 | return EVENT_SIGNALED; |
| 142 | |
Matthias Beyer | 9c805bd | 2014-06-23 21:18:26 +0200 | [diff] [blame] | 143 | *time = *time_tx; |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 144 | } |
| 145 | |
| 146 | return 0; |
| 147 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 148 | |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 149 | static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, |
| 150 | UCHAR GPIO_Num_tx, |
| 151 | UCHAR uiTxLedIndex, |
| 152 | UCHAR GPIO_Num_rx, |
| 153 | UCHAR uiRxLedIndex, |
| 154 | enum bcm_led_events currdriverstate) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 155 | { |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 156 | /* Initial values of TX and RX packets */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 157 | ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0; |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 158 | /* values of TX and RX packets after 1 sec */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 159 | ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0; |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 160 | /* Rate of transfer of Tx and Rx in 1 sec */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 161 | ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0; |
| 162 | int Status = STATUS_SUCCESS; |
| 163 | INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0; |
| 164 | UINT remDelay = 0; |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 165 | /* UINT GPIO_num = DISABLE_GPIO_NUM; */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 166 | ulong timeout = 0; |
| 167 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 168 | /* Read initial value of packets sent/received */ |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 169 | Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets; |
| 170 | Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets; |
| 171 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 172 | /* Scale the rate of transfer to no of blinks. */ |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 173 | num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx); |
| 174 | num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 175 | |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 176 | while ((Adapter->device_removed == false)) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 177 | timeout = 50; |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 178 | |
Matthias Beyer | 4fb9ab4 | 2014-06-23 21:18:22 +0200 | [diff] [blame] | 179 | if (EVENT_SIGNALED == blink_in_normal_bandwidth(Adapter, |
| 180 | &num_of_time, |
| 181 | &num_of_time_tx, |
| 182 | &num_of_time_rx, |
| 183 | GPIO_Num_tx, |
| 184 | uiTxLedIndex, |
| 185 | GPIO_Num_rx, |
| 186 | uiRxLedIndex, |
| 187 | currdriverstate, |
| 188 | &timeout)) |
| 189 | return EVENT_SIGNALED; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 190 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 191 | |
| 192 | /* |
| 193 | * If Tx/Rx rate is less than maximum blinks per second, |
| 194 | * wait till delay completes to 1 second |
| 195 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 196 | remDelay = MAX_NUM_OF_BLINKS - num_of_time; |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 197 | if (remDelay > 0) { |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 198 | timeout = 100 * remDelay; |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 199 | Status = wait_event_interruptible_timeout( |
| 200 | Adapter->LEDInfo.notify_led_event, |
| 201 | currdriverstate != Adapter->DriverState |
| 202 | || kthread_should_stop(), |
| 203 | msecs_to_jiffies(timeout)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 204 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 205 | if (kthread_should_stop()) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 206 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, |
| 207 | LED_DUMP_INFO, DBG_LVL_ALL, |
| 208 | "Led thread got signal to exit..hence exiting"); |
| 209 | Adapter->LEDInfo.led_thread_running = |
| 210 | BCM_LED_THREAD_DISABLED; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 211 | return EVENT_SIGNALED; |
| 212 | } |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 213 | if (Status) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 214 | return EVENT_SIGNALED; |
| 215 | } |
| 216 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 217 | /* Turn off both Tx and Rx LEDs before next second */ |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 218 | TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex); |
| 219 | TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 220 | |
| 221 | /* |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 222 | * Read the Tx & Rx packets transmission after 1 second and |
| 223 | * calculate rate of transfer |
| 224 | */ |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 225 | Final_num_of_packts_tx = Adapter->dev->stats.tx_packets; |
| 226 | Final_num_of_packts_rx = Adapter->dev->stats.rx_packets; |
| 227 | |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 228 | rate_of_transfer_tx = Final_num_of_packts_tx - |
| 229 | Initial_num_of_packts_tx; |
| 230 | rate_of_transfer_rx = Final_num_of_packts_rx - |
| 231 | Initial_num_of_packts_rx; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 232 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 233 | /* Read initial value of packets sent/received */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 234 | Initial_num_of_packts_tx = Final_num_of_packts_tx; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 235 | Initial_num_of_packts_rx = Final_num_of_packts_rx; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 236 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 237 | /* Scale the rate of transfer to no of blinks. */ |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 238 | num_of_time_tx = |
| 239 | ScaleRateofTransfer((ULONG)rate_of_transfer_tx); |
| 240 | num_of_time_rx = |
| 241 | ScaleRateofTransfer((ULONG)rate_of_transfer_rx); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 242 | |
| 243 | } |
| 244 | return Status; |
| 245 | } |
| 246 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 247 | /* |
| 248 | * ----------------------------------------------------------------------------- |
| 249 | * Procedure: ValidateDSDParamsChecksum |
| 250 | * |
| 251 | * Description: Reads DSD Params and validates checkusm. |
| 252 | * |
| 253 | * Arguments: |
| 254 | * Adapter - Pointer to Adapter structure. |
| 255 | * ulParamOffset - Start offset of the DSD parameter to be read and |
| 256 | * validated. |
| 257 | * usParamLen - Length of the DSD Parameter. |
| 258 | * |
| 259 | * Returns: |
| 260 | * <OSAL_STATUS_CODE> |
| 261 | * ----------------------------------------------------------------------------- |
| 262 | */ |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 263 | static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, |
| 264 | ULONG ulParamOffset, |
| 265 | USHORT usParamLen) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 266 | { |
| 267 | INT Status = STATUS_SUCCESS; |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 268 | PUCHAR puBuffer = NULL; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 269 | USHORT usChksmOrg = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 270 | USHORT usChecksumCalculated = 0; |
| 271 | |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 272 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 273 | "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X", |
| 274 | ulParamOffset, usParamLen); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 275 | |
Stephen Hemminger | 082e889 | 2010-11-01 09:35:21 -0400 | [diff] [blame] | 276 | puBuffer = kmalloc(usParamLen, GFP_KERNEL); |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 277 | if (!puBuffer) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 278 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 279 | DBG_LVL_ALL, |
| 280 | "LED Thread: ValidateDSDParamsChecksum Allocation failed"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 281 | return -ENOMEM; |
| 282 | |
| 283 | } |
| 284 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 285 | /* Read the DSD data from the parameter offset. */ |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 286 | if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 287 | ulParamOffset, usParamLen)) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 288 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 289 | DBG_LVL_ALL, |
| 290 | "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 291 | Status = STATUS_IMAGE_CHECKSUM_MISMATCH; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 292 | goto exit; |
| 293 | } |
| 294 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 295 | /* Calculate the checksum of the data read from the DSD parameter. */ |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 296 | usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen); |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 297 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 298 | "LED Thread: usCheckSumCalculated = 0x%x\n", |
| 299 | usChecksumCalculated); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 300 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 301 | /* |
| 302 | * End of the DSD parameter will have a TWO bytes checksum stored in it. |
| 303 | * Read it and compare with the calculated Checksum. |
| 304 | */ |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 305 | if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 306 | ulParamOffset+usParamLen, 2)) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 307 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 308 | DBG_LVL_ALL, |
| 309 | "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 310 | Status = STATUS_IMAGE_CHECKSUM_MISMATCH; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 311 | goto exit; |
| 312 | } |
| 313 | usChksmOrg = ntohs(usChksmOrg); |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 314 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 315 | "LED Thread: usChksmOrg = 0x%x", usChksmOrg); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 316 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 317 | /* |
| 318 | * Compare the checksum calculated with the checksum read |
| 319 | * from DSD section |
| 320 | */ |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 321 | if (usChecksumCalculated ^ usChksmOrg) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 322 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 323 | DBG_LVL_ALL, |
| 324 | "LED Thread: ValidateDSDParamsChecksum: Checksums don't match"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 325 | Status = STATUS_IMAGE_CHECKSUM_MISMATCH; |
| 326 | goto exit; |
| 327 | } |
| 328 | |
| 329 | exit: |
Stephen Hemminger | 082e889 | 2010-11-01 09:35:21 -0400 | [diff] [blame] | 330 | kfree(puBuffer); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 331 | return Status; |
| 332 | } |
| 333 | |
| 334 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 335 | /* |
| 336 | * ----------------------------------------------------------------------------- |
| 337 | * Procedure: ValidateHWParmStructure |
| 338 | * |
| 339 | * Description: Validates HW Parameters. |
| 340 | * |
| 341 | * Arguments: |
| 342 | * Adapter - Pointer to Adapter structure. |
| 343 | * ulHwParamOffset - Start offset of the HW parameter Section to be read |
| 344 | * and validated. |
| 345 | * |
| 346 | * Returns: |
| 347 | * <OSAL_STATUS_CODE> |
| 348 | * ----------------------------------------------------------------------------- |
| 349 | */ |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 350 | static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter, |
| 351 | ULONG ulHwParamOffset) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 352 | { |
| 353 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 354 | INT Status = STATUS_SUCCESS; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 355 | USHORT HwParamLen = 0; |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 356 | /* |
| 357 | * Add DSD start offset to the hwParamOffset to get |
| 358 | * the actual address. |
| 359 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 360 | ulHwParamOffset += DSD_START_OFFSET; |
| 361 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 362 | /* Read the Length of HW_PARAM structure */ |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 363 | BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 364 | HwParamLen = ntohs(HwParamLen); |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 365 | if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 366 | return STATUS_IMAGE_CHECKSUM_MISMATCH; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 367 | |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 368 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 369 | "LED Thread:HwParamLen = 0x%x", HwParamLen); |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 370 | Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 371 | HwParamLen); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 372 | return Status; |
| 373 | } /* ValidateHWParmStructure() */ |
| 374 | |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 375 | static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter, |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 376 | UCHAR GPIO_Array[]) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 377 | { |
| 378 | int Status = STATUS_SUCCESS; |
| 379 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 380 | ULONG dwReadValue = 0; |
| 381 | USHORT usHwParamData = 0; |
| 382 | USHORT usEEPROMVersion = 0; |
| 383 | UCHAR ucIndex = 0; |
| 384 | UCHAR ucGPIOInfo[32] = {0}; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 385 | |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 386 | BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 387 | EEPROM_VERSION_OFFSET, 2); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 388 | |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 389 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 390 | "usEEPROMVersion: Minor:0x%X Major:0x%x", |
| 391 | usEEPROMVersion & 0xFF, |
| 392 | ((usEEPROMVersion >> 8) & 0xFF)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 393 | |
| 394 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 395 | if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 396 | BeceemNVMRead(Adapter, (PUINT)&usHwParamData, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 397 | EEPROM_HW_PARAM_POINTER_ADDRESS, 2); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 398 | usHwParamData = ntohs(usHwParamData); |
| 399 | dwReadValue = usHwParamData; |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 400 | } else { |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 401 | /* |
| 402 | * Validate Compatibility section and then read HW param |
| 403 | * if compatibility section is valid. |
| 404 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 405 | Status = ValidateDSDParamsChecksum(Adapter, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 406 | DSD_START_OFFSET, |
| 407 | COMPATIBILITY_SECTION_LENGTH_MAP5); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 408 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 409 | if (Status != STATUS_SUCCESS) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 410 | return Status; |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 411 | |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 412 | BeceemNVMRead(Adapter, (PUINT)&dwReadValue, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 413 | EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 414 | dwReadValue = ntohl(dwReadValue); |
| 415 | } |
| 416 | |
| 417 | |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 418 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 419 | "LED Thread: Start address of HW_PARAM structure = 0x%lx", |
| 420 | dwReadValue); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 421 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 422 | /* |
| 423 | * Validate if the address read out is within the DSD. |
| 424 | * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit. |
| 425 | * lower limit should be above DSD_START_OFFSET and |
| 426 | * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET) |
| 427 | */ |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 428 | if (dwReadValue < DSD_START_OFFSET || |
| 429 | dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 430 | return STATUS_IMAGE_CHECKSUM_MISMATCH; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 431 | |
| 432 | Status = ValidateHWParmStructure(Adapter, dwReadValue); |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 433 | if (Status) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 434 | return Status; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 435 | |
| 436 | /* |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 437 | * Add DSD_START_OFFSET to the offset read from the EEPROM. |
| 438 | * This will give the actual start HW Parameters start address. |
| 439 | * To read GPIO section, add GPIO offset further. |
| 440 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 441 | |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 442 | dwReadValue += DSD_START_OFFSET; |
| 443 | /* = start address of hw param section. */ |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 444 | dwReadValue += GPIO_SECTION_START_OFFSET; |
| 445 | /* = GPIO start offset within HW Param section. */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 446 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 447 | /* |
| 448 | * Read the GPIO values for 32 GPIOs from EEPROM and map the function |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 449 | * number to GPIO pin number to GPIO_Array |
| 450 | */ |
| 451 | BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32); |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 452 | for (ucIndex = 0; ucIndex < 32; ucIndex++) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 453 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 454 | switch (ucGPIOInfo[ucIndex]) { |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 455 | case RED_LED: |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 456 | GPIO_Array[RED_LED] = ucIndex; |
| 457 | Adapter->gpioBitMap |= (1 << ucIndex); |
| 458 | break; |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 459 | case BLUE_LED: |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 460 | GPIO_Array[BLUE_LED] = ucIndex; |
| 461 | Adapter->gpioBitMap |= (1 << ucIndex); |
| 462 | break; |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 463 | case YELLOW_LED: |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 464 | GPIO_Array[YELLOW_LED] = ucIndex; |
| 465 | Adapter->gpioBitMap |= (1 << ucIndex); |
| 466 | break; |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 467 | case GREEN_LED: |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 468 | GPIO_Array[GREEN_LED] = ucIndex; |
| 469 | Adapter->gpioBitMap |= (1 << ucIndex); |
| 470 | break; |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 471 | default: |
| 472 | break; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 473 | } |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 474 | |
| 475 | } |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 476 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 477 | "GPIO's bit map correspond to LED :0x%X", |
| 478 | Adapter->gpioBitMap); |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 479 | return Status; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 480 | } |
| 481 | |
| 482 | |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 483 | static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 484 | bool *bEnableThread) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 485 | { |
| 486 | int Status = STATUS_SUCCESS; |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 487 | /* Array to store GPIO numbers from EEPROM */ |
| 488 | UCHAR GPIO_Array[NUM_OF_LEDS+1]; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 489 | UINT uiIndex = 0; |
| 490 | UINT uiNum_of_LED_Type = 0; |
| 491 | PUCHAR puCFGData = NULL; |
| 492 | UCHAR bData = 0; |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 493 | struct bcm_led_state_info *curr_led_state; |
Pawel Lebioda | 89fa037 | 2014-07-09 17:59:29 +0200 | [diff] [blame] | 494 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 495 | memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1); |
| 496 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 497 | if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) { |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 498 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
| 499 | DBG_LVL_ALL, "Target Params not Avail.\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 500 | return -ENOENT; |
| 501 | } |
| 502 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 503 | /* Populate GPIO_Array with GPIO numbers for LED functions */ |
| 504 | /* Read the GPIO numbers from EEPROM */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 505 | Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array); |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 506 | if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) { |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 507 | *bEnableThread = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 508 | return STATUS_SUCCESS; |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 509 | } else if (Status) { |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 510 | *bEnableThread = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 511 | return Status; |
| 512 | } |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 513 | |
| 514 | /* |
| 515 | * CONFIG file read successfully. Deallocate the memory of |
| 516 | * uiFileNameBufferSize |
| 517 | */ |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 518 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 519 | "LED Thread: Config file read successfully\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 520 | puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1; |
| 521 | |
| 522 | /* |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 523 | * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which |
| 524 | * will have the information of LED type, LED on state for different |
| 525 | * driver state and LED blink state. |
| 526 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 527 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 528 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 529 | bData = *puCFGData; |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 530 | curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 531 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 532 | /* |
| 533 | * Check Bit 8 for polarity. If it is set, |
| 534 | * polarity is reverse polarity |
| 535 | */ |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 536 | if (bData & 0x80) { |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 537 | curr_led_state->BitPolarity = 0; |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 538 | /* unset the bit 8 */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 539 | bData = bData & 0x7f; |
| 540 | } |
| 541 | |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 542 | curr_led_state->LED_Type = bData; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 543 | if (bData <= NUM_OF_LEDS) |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 544 | curr_led_state->GPIO_Num = GPIO_Array[bData]; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 545 | else |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 546 | curr_led_state->GPIO_Num = DISABLE_GPIO_NUM; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 547 | |
| 548 | puCFGData++; |
| 549 | bData = *puCFGData; |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 550 | curr_led_state->LED_On_State = bData; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 551 | puCFGData++; |
| 552 | bData = *puCFGData; |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 553 | curr_led_state->LED_Blink_State = bData; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 554 | puCFGData++; |
| 555 | } |
| 556 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 557 | /* |
| 558 | * Check if all the LED settings are disabled. If it is disabled, |
| 559 | * dont launch the LED control thread. |
| 560 | */ |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 561 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { |
Matthias Beyer | 76a60d5 | 2014-06-23 21:18:29 +0200 | [diff] [blame] | 562 | curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; |
| 563 | |
| 564 | if ((curr_led_state->LED_Type == DISABLE_GPIO_NUM) || |
| 565 | (curr_led_state->LED_Type == 0x7f) || |
| 566 | (curr_led_state->LED_Type == 0)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 567 | uiNum_of_LED_Type++; |
| 568 | } |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 569 | if (uiNum_of_LED_Type >= NUM_OF_LEDS) |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 570 | *bEnableThread = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 571 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 572 | return Status; |
| 573 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 574 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 575 | /* |
| 576 | * ----------------------------------------------------------------------------- |
| 577 | * Procedure: LedGpioInit |
| 578 | * |
| 579 | * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode |
| 580 | * and make the initial state to be OFF. |
| 581 | * |
| 582 | * Arguments: |
| 583 | * Adapter - Pointer to MINI_ADAPTER structure. |
| 584 | * |
| 585 | * Returns: VOID |
| 586 | * |
| 587 | * ----------------------------------------------------------------------------- |
| 588 | */ |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 589 | static VOID LedGpioInit(struct bcm_mini_adapter *Adapter) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 590 | { |
| 591 | UINT uiResetValue = 0; |
| 592 | UINT uiIndex = 0; |
Matthias Beyer | 2d2ea21 | 2014-06-23 21:18:30 +0200 | [diff] [blame] | 593 | struct bcm_led_state_info *curr_led_state; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 594 | |
| 595 | /* Set all LED GPIO Mode to output mode */ |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 596 | if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 597 | sizeof(uiResetValue)) < 0) |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 598 | BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
| 599 | DBG_LVL_ALL, "LED Thread: RDM Failed\n"); |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 600 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { |
Matthias Beyer | 2d2ea21 | 2014-06-23 21:18:30 +0200 | [diff] [blame] | 601 | curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; |
| 602 | |
| 603 | if (curr_led_state->GPIO_Num != DISABLE_GPIO_NUM) |
| 604 | uiResetValue |= (1 << curr_led_state->GPIO_Num); |
| 605 | |
| 606 | TURN_OFF_LED(Adapter, 1 << curr_led_state->GPIO_Num, uiIndex); |
| 607 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 608 | } |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 609 | if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 610 | sizeof(uiResetValue)) < 0) |
| 611 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
| 612 | DBG_LVL_ALL, "LED Thread: WRM Failed\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 613 | |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 614 | Adapter->LEDInfo.bIdle_led_off = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 615 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 616 | |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 617 | static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter, |
| 618 | UCHAR *GPIO_num_tx, |
| 619 | UCHAR *GPIO_num_rx, |
| 620 | UCHAR *uiLedTxIndex, |
| 621 | UCHAR *uiLedRxIndex, |
| 622 | enum bcm_led_events currdriverstate) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 623 | { |
| 624 | UINT uiIndex = 0; |
Matthias Beyer | e4e9d83 | 2014-06-23 21:18:21 +0200 | [diff] [blame] | 625 | struct bcm_led_state_info *led_state_info; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 626 | |
| 627 | *GPIO_num_tx = DISABLE_GPIO_NUM; |
| 628 | *GPIO_num_rx = DISABLE_GPIO_NUM; |
| 629 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 630 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { |
Matthias Beyer | e4e9d83 | 2014-06-23 21:18:21 +0200 | [diff] [blame] | 631 | led_state_info = &Adapter->LEDInfo.LEDState[uiIndex]; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 632 | |
Matthias Beyer | 7a0304c | 2014-06-23 21:18:20 +0200 | [diff] [blame] | 633 | if (((currdriverstate == NORMAL_OPERATION) || |
| 634 | (currdriverstate == IDLEMODE_EXIT) || |
| 635 | (currdriverstate == FW_DOWNLOAD)) && |
Matthias Beyer | f4367df | 2014-06-23 21:18:31 +0200 | [diff] [blame] | 636 | (led_state_info->LED_Blink_State & currdriverstate) && |
| 637 | (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) { |
| 638 | if (*GPIO_num_tx == DISABLE_GPIO_NUM) { |
| 639 | *GPIO_num_tx = led_state_info->GPIO_Num; |
| 640 | *uiLedTxIndex = uiIndex; |
| 641 | } else { |
| 642 | *GPIO_num_rx = led_state_info->GPIO_Num; |
| 643 | *uiLedRxIndex = uiIndex; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 644 | } |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 645 | } else { |
Matthias Beyer | e4e9d83 | 2014-06-23 21:18:21 +0200 | [diff] [blame] | 646 | if ((led_state_info->LED_On_State & currdriverstate) && |
| 647 | (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) { |
| 648 | *GPIO_num_tx = led_state_info->GPIO_Num; |
Matthias Beyer | 7a0304c | 2014-06-23 21:18:20 +0200 | [diff] [blame] | 649 | *uiLedTxIndex = uiIndex; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 650 | } |
| 651 | } |
| 652 | } |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 653 | return STATUS_SUCCESS; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 654 | } |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 655 | |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 656 | static void handle_adapter_driver_state(struct bcm_mini_adapter *ad, |
| 657 | enum bcm_led_events currdriverstate, |
| 658 | UCHAR GPIO_num, |
| 659 | UCHAR dummyGPIONum, |
| 660 | UCHAR uiLedIndex, |
| 661 | UCHAR dummyIndex, |
| 662 | ulong timeout, |
| 663 | UINT uiResetValue, |
| 664 | UINT uiIndex) |
| 665 | { |
| 666 | switch (ad->DriverState) { |
| 667 | case DRIVER_INIT: |
| 668 | currdriverstate = DRIVER_INIT; |
| 669 | /* ad->DriverState; */ |
| 670 | BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, |
| 671 | &uiLedIndex, &dummyIndex, |
| 672 | currdriverstate); |
| 673 | |
| 674 | if (GPIO_num != DISABLE_GPIO_NUM) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 675 | TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 676 | |
| 677 | break; |
| 678 | case FW_DOWNLOAD: |
| 679 | /* |
| 680 | * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, |
| 681 | * LED_DUMP_INFO, DBG_LVL_ALL, |
| 682 | * "LED Thread: FW_DN_DONE called\n"); |
| 683 | */ |
| 684 | currdriverstate = FW_DOWNLOAD; |
| 685 | BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, |
| 686 | &uiLedIndex, &dummyIndex, |
| 687 | currdriverstate); |
| 688 | |
| 689 | if (GPIO_num != DISABLE_GPIO_NUM) { |
| 690 | timeout = 50; |
| 691 | LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout, |
| 692 | -1, currdriverstate); |
| 693 | } |
| 694 | break; |
| 695 | case FW_DOWNLOAD_DONE: |
| 696 | currdriverstate = FW_DOWNLOAD_DONE; |
| 697 | BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, |
| 698 | &uiLedIndex, &dummyIndex, currdriverstate); |
| 699 | if (GPIO_num != DISABLE_GPIO_NUM) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 700 | TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 701 | break; |
| 702 | |
| 703 | case SHUTDOWN_EXIT: |
| 704 | /* |
| 705 | * no break, continue to NO_NETWORK_ENTRY |
| 706 | * state as well. |
| 707 | */ |
| 708 | case NO_NETWORK_ENTRY: |
| 709 | currdriverstate = NO_NETWORK_ENTRY; |
| 710 | BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, |
| 711 | &uiLedIndex, &dummyGPIONum, currdriverstate); |
| 712 | if (GPIO_num != DISABLE_GPIO_NUM) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 713 | TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 714 | break; |
| 715 | case NORMAL_OPERATION: |
| 716 | { |
| 717 | UCHAR GPIO_num_tx = DISABLE_GPIO_NUM; |
| 718 | UCHAR GPIO_num_rx = DISABLE_GPIO_NUM; |
| 719 | UCHAR uiLEDTx = 0; |
| 720 | UCHAR uiLEDRx = 0; |
Pawel Lebioda | 89fa037 | 2014-07-09 17:59:29 +0200 | [diff] [blame] | 721 | |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 722 | currdriverstate = NORMAL_OPERATION; |
| 723 | ad->LEDInfo.bIdle_led_off = false; |
| 724 | |
| 725 | BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx, |
| 726 | &uiLEDTx, &uiLEDRx, currdriverstate); |
| 727 | if ((GPIO_num_tx == DISABLE_GPIO_NUM) && |
| 728 | (GPIO_num_rx == DISABLE_GPIO_NUM)) { |
| 729 | GPIO_num = DISABLE_GPIO_NUM; |
| 730 | } else { |
| 731 | /* |
| 732 | * If single LED is selected, use same |
| 733 | * for both Tx and Rx |
| 734 | */ |
| 735 | if (GPIO_num_tx == DISABLE_GPIO_NUM) { |
| 736 | GPIO_num_tx = GPIO_num_rx; |
| 737 | uiLEDTx = uiLEDRx; |
| 738 | } else if (GPIO_num_rx == DISABLE_GPIO_NUM) { |
| 739 | GPIO_num_rx = GPIO_num_tx; |
| 740 | uiLEDRx = uiLEDTx; |
| 741 | } |
| 742 | /* |
| 743 | * Blink the LED in proportionate |
| 744 | * to Tx and Rx transmissions. |
| 745 | */ |
| 746 | LED_Proportional_Blink(ad, |
| 747 | GPIO_num_tx, uiLEDTx, |
| 748 | GPIO_num_rx, uiLEDRx, |
| 749 | currdriverstate); |
| 750 | } |
| 751 | } |
| 752 | break; |
| 753 | case LOWPOWER_MODE_ENTER: |
| 754 | currdriverstate = LOWPOWER_MODE_ENTER; |
| 755 | if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == |
| 756 | ad->ulPowerSaveMode) { |
| 757 | /* Turn OFF all the LED */ |
| 758 | uiResetValue = 0; |
| 759 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { |
| 760 | if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 761 | TURN_OFF_LED(ad, |
| 762 | (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), |
| 763 | uiIndex); |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 764 | } |
| 765 | |
| 766 | } |
| 767 | /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */ |
| 768 | ad->LEDInfo.bLedInitDone = false; |
| 769 | ad->LEDInfo.bIdle_led_off = TRUE; |
| 770 | wake_up(&ad->LEDInfo.idleModeSyncEvent); |
| 771 | GPIO_num = DISABLE_GPIO_NUM; |
| 772 | break; |
| 773 | case IDLEMODE_CONTINUE: |
| 774 | currdriverstate = IDLEMODE_CONTINUE; |
| 775 | GPIO_num = DISABLE_GPIO_NUM; |
| 776 | break; |
| 777 | case IDLEMODE_EXIT: |
| 778 | break; |
| 779 | case DRIVER_HALT: |
| 780 | currdriverstate = DRIVER_HALT; |
| 781 | GPIO_num = DISABLE_GPIO_NUM; |
| 782 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { |
| 783 | if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != |
| 784 | DISABLE_GPIO_NUM) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 785 | TURN_OFF_LED(ad, |
| 786 | (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), |
| 787 | uiIndex); |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 788 | } |
| 789 | /* ad->DriverState = DRIVER_INIT; */ |
| 790 | break; |
| 791 | case LED_THREAD_INACTIVE: |
| 792 | BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
| 793 | DBG_LVL_ALL, "InActivating LED thread..."); |
| 794 | currdriverstate = LED_THREAD_INACTIVE; |
| 795 | ad->LEDInfo.led_thread_running = |
| 796 | BCM_LED_THREAD_RUNNING_INACTIVELY; |
| 797 | ad->LEDInfo.bLedInitDone = false; |
| 798 | /* disable ALL LED */ |
| 799 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { |
| 800 | if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != |
| 801 | DISABLE_GPIO_NUM) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 802 | TURN_OFF_LED(ad, |
| 803 | (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), |
| 804 | uiIndex); |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 805 | } |
| 806 | break; |
| 807 | case LED_THREAD_ACTIVE: |
| 808 | BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
| 809 | DBG_LVL_ALL, "Activating LED thread again..."); |
| 810 | if (ad->LinkUpStatus == false) |
| 811 | ad->DriverState = NO_NETWORK_ENTRY; |
| 812 | else |
| 813 | ad->DriverState = NORMAL_OPERATION; |
| 814 | |
| 815 | ad->LEDInfo.led_thread_running = |
| 816 | BCM_LED_THREAD_RUNNING_ACTIVELY; |
| 817 | break; |
| 818 | /* return; */ |
| 819 | default: |
| 820 | break; |
| 821 | } |
| 822 | } |
| 823 | |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 824 | static VOID LEDControlThread(struct bcm_mini_adapter *Adapter) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 825 | { |
| 826 | UINT uiIndex = 0; |
| 827 | UCHAR GPIO_num = 0; |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 828 | UCHAR uiLedIndex = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 829 | UINT uiResetValue = 0; |
Kevin McKinney | b3d9a8f | 2012-12-14 19:26:52 -0500 | [diff] [blame] | 830 | enum bcm_led_events currdriverstate = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 831 | ulong timeout = 0; |
| 832 | |
| 833 | INT Status = 0; |
| 834 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 835 | UCHAR dummyGPIONum = 0; |
| 836 | UCHAR dummyIndex = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 837 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 838 | /* currdriverstate = Adapter->DriverState; */ |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 839 | Adapter->LEDInfo.bIdleMode_tx_from_host = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 840 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 841 | /* |
| 842 | * Wait till event is triggered |
| 843 | * |
| 844 | * wait_event(Adapter->LEDInfo.notify_led_event, |
| 845 | * currdriverstate!= Adapter->DriverState); |
| 846 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 847 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 848 | GPIO_num = DISABLE_GPIO_NUM; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 849 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 850 | while (TRUE) { |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 851 | /* Wait till event is triggered */ |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 852 | if ((GPIO_num == DISABLE_GPIO_NUM) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 853 | || |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 854 | ((currdriverstate != FW_DOWNLOAD) && |
| 855 | (currdriverstate != NORMAL_OPERATION) && |
| 856 | (currdriverstate != LOWPOWER_MODE_ENTER)) |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 857 | || |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 858 | (currdriverstate == LED_THREAD_INACTIVE)) |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 859 | Status = wait_event_interruptible( |
| 860 | Adapter->LEDInfo.notify_led_event, |
| 861 | currdriverstate != Adapter->DriverState |
| 862 | || kthread_should_stop()); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 863 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 864 | if (kthread_should_stop() || Adapter->device_removed) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 865 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
| 866 | DBG_LVL_ALL, |
| 867 | "Led thread got signal to exit..hence exiting"); |
| 868 | Adapter->LEDInfo.led_thread_running = |
| 869 | BCM_LED_THREAD_DISABLED; |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 870 | TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex); |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 871 | return; /* STATUS_FAILURE; */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 872 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 873 | |
Johannes Tenschert | c1eb22d | 2011-12-07 18:25:06 +0100 | [diff] [blame] | 874 | if (GPIO_num != DISABLE_GPIO_NUM) |
Matthias Beyer | a1082a4 | 2014-06-23 21:18:19 +0200 | [diff] [blame] | 875 | TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 876 | |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 877 | if (Adapter->LEDInfo.bLedInitDone == false) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 878 | LedGpioInit(Adapter); |
| 879 | Adapter->LEDInfo.bLedInitDone = TRUE; |
| 880 | } |
| 881 | |
Matthias Beyer | ce2705c | 2014-06-23 21:18:18 +0200 | [diff] [blame] | 882 | handle_adapter_driver_state(Adapter, |
| 883 | currdriverstate, |
| 884 | GPIO_num, |
| 885 | dummyGPIONum, |
| 886 | uiLedIndex, |
| 887 | dummyIndex, |
| 888 | timeout, |
| 889 | uiResetValue, |
| 890 | uiIndex |
| 891 | ); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 892 | } |
| 893 | Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; |
| 894 | } |
| 895 | |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 896 | int InitLedSettings(struct bcm_mini_adapter *Adapter) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 897 | { |
| 898 | int Status = STATUS_SUCCESS; |
Lisa Nguyen | 3abd6f1 | 2013-10-28 01:35:59 -0700 | [diff] [blame] | 899 | bool bEnableThread = TRUE; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 900 | UCHAR uiIndex = 0; |
| 901 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 902 | /* |
| 903 | * Initially set BitPolarity to normal polarity. The bit 8 of LED type |
| 904 | * is used to change the polarity of the LED. |
| 905 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 906 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 907 | for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 908 | Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 909 | |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 910 | /* |
| 911 | * Read the LED settings of CONFIG file and map it |
| 912 | * to GPIO numbers in EEPROM |
| 913 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 914 | Status = ReadConfigFileStructure(Adapter, &bEnableThread); |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 915 | if (STATUS_SUCCESS != Status) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 916 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 917 | DBG_LVL_ALL, |
| 918 | "LED Thread: FAILED in ReadConfigFileStructure\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 919 | return Status; |
| 920 | } |
| 921 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 922 | if (Adapter->LEDInfo.led_thread_running) { |
| 923 | if (bEnableThread) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 924 | ; |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 925 | } else { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 926 | Adapter->DriverState = DRIVER_HALT; |
| 927 | wake_up(&Adapter->LEDInfo.notify_led_event); |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 928 | Adapter->LEDInfo.led_thread_running = |
| 929 | BCM_LED_THREAD_DISABLED; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 930 | } |
| 931 | |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 932 | } else if (bEnableThread) { |
Johannes Tenschert | f5d8c26 | 2011-12-07 18:25:08 +0100 | [diff] [blame] | 933 | /* Create secondary thread to handle the LEDs */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 934 | init_waitqueue_head(&Adapter->LEDInfo.notify_led_event); |
| 935 | init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent); |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 936 | Adapter->LEDInfo.led_thread_running = |
| 937 | BCM_LED_THREAD_RUNNING_ACTIVELY; |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 938 | Adapter->LEDInfo.bIdle_led_off = false; |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 939 | Adapter->LEDInfo.led_cntrl_threadid = |
| 940 | kthread_run((int (*)(void *)) LEDControlThread, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 941 | Adapter, "led_control_thread"); |
Johannes Tenschert | d9ce353 | 2011-12-07 18:25:09 +0100 | [diff] [blame] | 942 | if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) { |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 943 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, |
Matthias Beyer | 9bcfab20 | 2014-06-23 21:18:17 +0200 | [diff] [blame] | 944 | DBG_LVL_ALL, |
| 945 | "Not able to spawn Kernel Thread\n"); |
Johannes Tenschert | 4219001 | 2011-12-07 18:25:10 +0100 | [diff] [blame] | 946 | Adapter->LEDInfo.led_thread_running = |
| 947 | BCM_LED_THREAD_DISABLED; |
Johannes Tenschert | 34e98e7 | 2011-12-07 18:25:07 +0100 | [diff] [blame] | 948 | return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid); |
| 949 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 950 | } |
| 951 | return Status; |
| 952 | } |