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