Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
staging
bcm
InterfaceIdleMode.c
Go to the documentation of this file.
1
#include "
headers.h
"
2
3
/*
4
Function: InterfaceIdleModeWakeup
5
6
Description: This is the hardware specific Function for waking up HW device from Idle mode.
7
A software abort pattern is written to the device to wake it and necessary power state
8
transitions from host are performed here.
9
10
Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context
11
12
13
Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface was successful.
14
Other - If an error occurred.
15
*/
16
17
18
/*
19
Function: InterfaceIdleModeRespond
20
21
Description: This is the hardware specific Function for responding to Idle mode request from target.
22
Necessary power state transitions from host for idle mode or other device specific
23
initializations are performed here.
24
25
Input parameters: IN struct bcm_mini_adapter * Adapter - Miniport Adapter Context
26
27
28
Return: BCM_STATUS_SUCCESS - If Idle mode response related HW configuration was successful.
29
Other - If an error occurred.
30
*/
31
32
/*
33
"dmem bfc02f00 100" tells how many time device went in Idle mode.
34
this value will be at address bfc02fa4.just before value d0ea1dle.
35
36
Set time value by writing at bfc02f98 7d0
37
38
checking the Ack timer expire on kannon by running command
39
d qcslog .. if it shows e means host has not send response to f/w with in 200 ms. Response should be
40
send to f/w with in 200 ms after the Idle/Shutdown req issued
41
42
*/
43
44
45
int
InterfaceIdleModeRespond
(
struct
bcm_mini_adapter
*
Adapter
,
unsigned
int
* puiBuffer)
46
{
47
int
status
=
STATUS_SUCCESS
;
48
unsigned
int
uiRegRead = 0;
49
int
bytes
;
50
51
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"SubType of Message :0x%X"
,
ntohl
(*puiBuffer));
52
53
if
(
ntohl
(*puiBuffer) ==
GO_TO_IDLE_MODE_PAYLOAD
)
54
{
55
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
" Got GO_TO_IDLE_MODE_PAYLOAD(210) Msg Subtype"
);
56
if
(
ntohl
(*(puiBuffer+1)) == 0 )
57
{
58
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Got IDLE MODE WAKE UP Response From F/W"
);
59
60
status =
wrmalt
(Adapter,
SW_ABORT_IDLEMODE_LOC
, &uiRegRead,
sizeof
(uiRegRead));
61
if
(status)
62
{
63
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"wrm failed while clearing Idle Mode Reg"
);
64
return
status
;
65
}
66
67
if
(Adapter->
ulPowerSaveMode
==
DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING
)
68
{
69
uiRegRead = 0x00000000 ;
70
status =
wrmalt
(Adapter,
DEBUG_INTERRUPT_GENERATOR_REGISTOR
, &uiRegRead,
sizeof
(uiRegRead));
71
if
(status)
72
{
73
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"wrm failed while clearing Idle Mode Reg"
);
74
return
status
;
75
}
76
}
77
//Below Register should not br read in case of Manual and Protocol Idle mode.
78
else
if
(Adapter->
ulPowerSaveMode
!=
DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE
)
79
{
80
//clear on read Register
81
bytes =
rdmalt
(Adapter,
DEVICE_INT_OUT_EP_REG0
, &uiRegRead,
sizeof
(uiRegRead));
82
if
(bytes < 0) {
83
status =
bytes
;
84
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"rdm failed while clearing H/W Abort Reg0"
);
85
return
status
;
86
}
87
//clear on read Register
88
bytes =
rdmalt
(Adapter,
DEVICE_INT_OUT_EP_REG1
, &uiRegRead,
sizeof
(uiRegRead));
89
if
(bytes < 0) {
90
status =
bytes
;
91
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"rdm failed while clearing H/W Abort Reg1"
);
92
return
status
;
93
}
94
}
95
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Device Up from Idle Mode"
);
96
97
// Set Idle Mode Flag to False and Clear IdleMode reg.
98
Adapter->
IdleMode
=
FALSE
;
99
Adapter->
bTriedToWakeUpFromlowPowerMode
=
FALSE
;
100
101
wake_up
(&Adapter->
lowpower_mode_wait_queue
);
102
103
}
104
else
105
{
106
if
(
TRUE
== Adapter->
IdleMode
)
107
{
108
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Device is already in Idle mode...."
);
109
return
status
;
110
}
111
112
uiRegRead = 0;
113
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Got Req from F/W to go in IDLE mode \n"
);
114
115
if
(Adapter->
chip_id
==
BCS220_2
||
116
Adapter->
chip_id
==
BCS220_2BC
||
117
Adapter->
chip_id
==
BCS250_BC
||
118
Adapter->
chip_id
==
BCS220_3
)
119
{
120
121
bytes =
rdmalt
(Adapter,
HPM_CONFIG_MSW
, &uiRegRead,
sizeof
(uiRegRead));
122
if
(bytes < 0) {
123
status =
bytes
;
124
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n"
);
125
return
status
;
126
}
127
128
129
uiRegRead |= (1<<17);
130
131
status =
wrmalt
(Adapter,
HPM_CONFIG_MSW
, &uiRegRead,
sizeof
(uiRegRead));
132
if
(status)
133
{
134
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"wrm failed while clearing Idle Mode Reg\n"
);
135
return
status
;
136
}
137
138
}
139
SendIdleModeResponse
(Adapter);
140
}
141
}
142
else
if
(
ntohl
(*puiBuffer) ==
IDLE_MODE_SF_UPDATE_MSG
)
143
{
144
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"OverRiding Service Flow Params"
);
145
OverrideServiceFlowParams
(Adapter,puiBuffer);
146
}
147
return
status
;
148
}
149
150
static
int
InterfaceAbortIdlemode(
struct
bcm_mini_adapter
*
Adapter
,
unsigned
int
Pattern)
151
{
152
int
status
=
STATUS_SUCCESS
;
153
unsigned
int
value
;
154
unsigned
int
chip_id
;
155
unsigned
long
timeout
= 0 ,itr = 0;
156
157
int
lenwritten = 0;
158
unsigned
char
aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
159
PS_INTERFACE_ADAPTER
psInterfaceAdapter = Adapter->
pvInterfaceAdapter
;
160
161
//Abort Bus suspend if its already suspended
162
if
((
TRUE
== psInterfaceAdapter->
bSuspended
) && (
TRUE
== Adapter->
bDoSuspend
))
163
{
164
status = usb_autopm_get_interface(psInterfaceAdapter->
interface
);
165
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Bus got wakeup..Aborting Idle mode... status:%d \n"
,status);
166
167
}
168
169
if
((Adapter->
ulPowerSaveMode
==
DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING
)
170
||
171
(Adapter->
ulPowerSaveMode
==
DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE
))
172
{
173
//write the SW abort pattern.
174
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n"
, Pattern);
175
status =
wrmalt
(Adapter,
SW_ABORT_IDLEMODE_LOC
, &Pattern,
sizeof
(Pattern));
176
if
(status)
177
{
178
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"WRM to Register SW_ABORT_IDLEMODE_LOC failed.."
);
179
return
status
;
180
}
181
}
182
183
if
(Adapter->
ulPowerSaveMode
==
DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING
)
184
{
185
value = 0x80000000;
186
status =
wrmalt
(Adapter,
DEBUG_INTERRUPT_GENERATOR_REGISTOR
, &value,
sizeof
(value));
187
if
(status)
188
{
189
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed"
);
190
return
status
;
191
}
192
}
193
else
if
(Adapter->
ulPowerSaveMode
!=
DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE
)
194
{
195
/*
196
* Get a Interrupt Out URB and send 8 Bytes Down
197
* To be Done in Thread Context.
198
* Not using Asynchronous Mechanism.
199
*/
200
status =
usb_interrupt_msg
(psInterfaceAdapter->
udev
,
201
usb_sndintpipe(psInterfaceAdapter->
udev
,
202
psInterfaceAdapter->
sIntrOut
.
int_out_endpointAddr
),
203
aucAbortPattern,
204
8,
205
&lenwritten,
206
5000);
207
if
(status)
208
{
209
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Sending Abort pattern down fails with status:%d..\n"
,status);
210
return
status
;
211
}
212
else
213
{
214
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"NOB Sent down :%d"
, lenwritten);
215
}
216
217
//mdelay(25);
218
219
timeout=
jiffies
+
msecs_to_jiffies
(50) ;
220
while
( timeout > jiffies )
221
{
222
itr++ ;
223
rdmalt
(Adapter,
CHIP_ID_REG
, &chip_id,
sizeof
(
UINT
));
224
if
(0xbece3200==(chip_id&~(0xF0)))
225
{
226
chip_id = chip_id&~(0xF0);
227
}
228
if
(chip_id == Adapter->
chip_id
)
229
break
;
230
}
231
if
(timeout < jiffies )
232
{
233
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Not able to read chip-id even after 25 msec"
);
234
}
235
else
236
{
237
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Number of completed iteration to read chip-id :%lu"
, itr);
238
}
239
240
status =
wrmalt
(Adapter,
SW_ABORT_IDLEMODE_LOC
, &Pattern,
sizeof
(status));
241
if
(status)
242
{
243
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"WRM to Register SW_ABORT_IDLEMODE_LOC failed.."
);
244
return
status
;
245
}
246
}
247
return
status
;
248
}
249
int
InterfaceIdleModeWakeup
(
struct
bcm_mini_adapter
*Adapter)
250
{
251
ULONG
Status
= 0;
252
if
(Adapter->
bTriedToWakeUpFromlowPowerMode
)
253
{
254
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Wake up already attempted.. ignoring\n"
);
255
}
256
else
257
{
258
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_OTHERS
,
IDLE_MODE
,
DBG_LVL_ALL
,
"Writing Low Power Mode Abort pattern to the Device\n"
);
259
Adapter->
bTriedToWakeUpFromlowPowerMode
=
TRUE
;
260
InterfaceAbortIdlemode(Adapter, Adapter->
usIdleModePattern
);
261
262
}
263
return
Status
;
264
}
265
266
void
InterfaceHandleShutdownModeWakeup
(
struct
bcm_mini_adapter
*Adapter)
267
{
268
unsigned
int
uiRegVal = 0;
269
INT
Status
= 0;
270
int
bytes
;
271
272
if
(Adapter->
ulPowerSaveMode
==
DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING
)
273
{
274
// clear idlemode interrupt.
275
uiRegVal = 0;
276
Status =
wrmalt
(Adapter,
DEBUG_INTERRUPT_GENERATOR_REGISTOR
, &uiRegVal,
sizeof
(uiRegVal));
277
if
(Status)
278
{
279
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d"
, Status);
280
return
;
281
}
282
}
283
284
else
285
{
286
287
//clear Interrupt EP registers.
288
bytes =
rdmalt
(Adapter,
DEVICE_INT_OUT_EP_REG0
, &uiRegVal,
sizeof
(uiRegVal));
289
if
(bytes < 0) {
290
Status =
bytes
;
291
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d"
, Status);
292
return
;
293
}
294
295
bytes =
rdmalt
(Adapter,
DEVICE_INT_OUT_EP_REG1
, &uiRegVal,
sizeof
(uiRegVal));
296
if
(bytes < 0) {
297
Status =
bytes
;
298
BCM_DEBUG_PRINT
(Adapter,
DBG_TYPE_PRINTK
, 0, 0,
"RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d"
, Status);
299
return
;
300
}
301
}
302
}
303
Generated on Thu Jan 10 2013 14:25:58 for Linux Kernel by
1.8.2