165ee41721b8637568df655b13b7b17b582ea66f
[openwrt/openwrt.git] / target / linux / mediatek / files-5.10 / drivers / net / phy / rtk / rtl8367c / interrupt.c
1 /*
2 * Copyright (C) 2013 Realtek Semiconductor Corp.
3 * All Rights Reserved.
4 *
5 * Unless you and Realtek execute a separate written software license
6 * agreement governing use of this software, this software is licensed
7 * to you under the terms of the GNU General Public License version 2,
8 * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
9 *
10 * $Revision: 76306 $
11 * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $
12 *
13 * Purpose : RTK switch high-level API for RTL8367/RTL8367C
14 * Feature : Here is a list of all functions and variables in Interrupt module.
15 *
16 */
17
18 #include <rtk_switch.h>
19 #include <rtk_error.h>
20 #include <interrupt.h>
21 #include <string.h>
22
23 #include <rtl8367c_asicdrv.h>
24 #include <rtl8367c_asicdrv_interrupt.h>
25
26 /* Function Name:
27 * rtk_int_polarity_set
28 * Description:
29 * Set interrupt polarity configuration.
30 * Input:
31 * type - Interruptpolarity type.
32 * Output:
33 * None
34 * Return:
35 * RT_ERR_OK - OK
36 * RT_ERR_FAILED - Failed
37 * RT_ERR_SMI - SMI access error
38 * RT_ERR_INPUT - Invalid input parameters.
39 * Note:
40 * The API can set interrupt polarity configuration.
41 */
42 rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type)
43 {
44 rtk_api_ret_t retVal;
45
46 /* Check initialization state */
47 RTK_CHK_INIT_STATE();
48
49 if(type >= INT_POLAR_END)
50 return RT_ERR_INPUT;
51
52 if ((retVal = rtl8367c_setAsicInterruptPolarity(type)) != RT_ERR_OK)
53 return retVal;
54
55 return RT_ERR_OK;
56 }
57
58 /* Function Name:
59 * rtk_int_polarity_get
60 * Description:
61 * Get interrupt polarity configuration.
62 * Input:
63 * None
64 * Output:
65 * pType - Interruptpolarity type.
66 * Return:
67 * RT_ERR_OK - OK
68 * RT_ERR_FAILED - Failed
69 * RT_ERR_SMI - SMI access error
70 * Note:
71 * The API can get interrupt polarity configuration.
72 */
73 rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType)
74 {
75 rtk_api_ret_t retVal;
76
77 /* Check initialization state */
78 RTK_CHK_INIT_STATE();
79
80 if(NULL == pType)
81 return RT_ERR_NULL_POINTER;
82
83 if ((retVal = rtl8367c_getAsicInterruptPolarity(pType)) != RT_ERR_OK)
84 return retVal;
85
86 return RT_ERR_OK;
87 }
88
89 /* Function Name:
90 * rtk_int_control_set
91 * Description:
92 * Set interrupt trigger status configuration.
93 * Input:
94 * type - Interrupt type.
95 * enable - Interrupt status.
96 * Output:
97 * None
98 * Return:
99 * RT_ERR_OK - OK
100 * RT_ERR_FAILED - Failed
101 * RT_ERR_SMI - SMI access error
102 * RT_ERR_INPUT - Invalid input parameters.
103 * RT_ERR_ENABLE - Invalid enable input.
104 * Note:
105 * The API can set interrupt status configuration.
106 * The interrupt trigger status is shown in the following:
107 * - INT_TYPE_LINK_STATUS
108 * - INT_TYPE_METER_EXCEED
109 * - INT_TYPE_LEARN_LIMIT
110 * - INT_TYPE_LINK_SPEED
111 * - INT_TYPE_CONGEST
112 * - INT_TYPE_GREEN_FEATURE
113 * - INT_TYPE_LOOP_DETECT
114 * - INT_TYPE_8051,
115 * - INT_TYPE_CABLE_DIAG,
116 * - INT_TYPE_ACL,
117 * - INT_TYPE_SLIENT
118 */
119 rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable)
120 {
121 rtk_api_ret_t retVal;
122 rtk_uint32 mask;
123
124 /* Check initialization state */
125 RTK_CHK_INIT_STATE();
126
127 if (type >= INT_TYPE_END)
128 return RT_ERR_INPUT;
129
130 if (type == INT_TYPE_RESERVED)
131 return RT_ERR_INPUT;
132
133 if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK)
134 return retVal;
135
136 if (ENABLED == enable)
137 mask = mask | (1<<type);
138 else if (DISABLED == enable)
139 mask = mask & ~(1<<type);
140 else
141 return RT_ERR_INPUT;
142
143 if ((retVal = rtl8367c_setAsicInterruptMask(mask)) != RT_ERR_OK)
144 return retVal;
145
146
147 return RT_ERR_OK;
148 }
149
150 /* Function Name:
151 * rtk_int_control_get
152 * Description:
153 * Get interrupt trigger status configuration.
154 * Input:
155 * type - Interrupt type.
156 * Output:
157 * pEnable - Interrupt status.
158 * Return:
159 * RT_ERR_OK - OK
160 * RT_ERR_FAILED - Failed
161 * RT_ERR_SMI - SMI access error
162 * RT_ERR_INPUT - Invalid input parameters.
163 * Note:
164 * The API can get interrupt status configuration.
165 * The interrupt trigger status is shown in the following:
166 * - INT_TYPE_LINK_STATUS
167 * - INT_TYPE_METER_EXCEED
168 * - INT_TYPE_LEARN_LIMIT
169 * - INT_TYPE_LINK_SPEED
170 * - INT_TYPE_CONGEST
171 * - INT_TYPE_GREEN_FEATURE
172 * - INT_TYPE_LOOP_DETECT
173 * - INT_TYPE_8051,
174 * - INT_TYPE_CABLE_DIAG,
175 * - INT_TYPE_ACL,
176 * - INT_TYPE_UPS,
177 * - INT_TYPE_SLIENT
178 */
179 rtk_api_ret_t rtk_int_control_get(rtk_int_type_t type, rtk_enable_t *pEnable)
180 {
181 rtk_api_ret_t retVal;
182 rtk_uint32 mask;
183
184 /* Check initialization state */
185 RTK_CHK_INIT_STATE();
186
187 if(NULL == pEnable)
188 return RT_ERR_NULL_POINTER;
189
190 if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK)
191 return retVal;
192
193 if (0 == (mask&(1<<type)))
194 *pEnable=DISABLED;
195 else
196 *pEnable=ENABLED;
197
198 return RT_ERR_OK;
199 }
200
201 /* Function Name:
202 * rtk_int_status_set
203 * Description:
204 * Set interrupt trigger status to clean.
205 * Input:
206 * None
207 * Output:
208 * pStatusMask - Interrupt status bit mask.
209 * Return:
210 * RT_ERR_OK - OK
211 * RT_ERR_FAILED - Failed
212 * RT_ERR_SMI - SMI access error
213 * RT_ERR_INPUT - Invalid input parameters.
214 * Note:
215 * The API can clean interrupt trigger status when interrupt happened.
216 * The interrupt trigger status is shown in the following:
217 * - INT_TYPE_LINK_STATUS (value[0] (Bit0))
218 * - INT_TYPE_METER_EXCEED (value[0] (Bit1))
219 * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2))
220 * - INT_TYPE_LINK_SPEED (value[0] (Bit3))
221 * - INT_TYPE_CONGEST (value[0] (Bit4))
222 * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5))
223 * - INT_TYPE_LOOP_DETECT (value[0] (Bit6))
224 * - INT_TYPE_8051 (value[0] (Bit7))
225 * - INT_TYPE_CABLE_DIAG (value[0] (Bit8))
226 * - INT_TYPE_ACL (value[0] (Bit9))
227 * - INT_TYPE_SLIENT (value[0] (Bit11))
228 * The status will be cleared after execute this API.
229 */
230 rtk_api_ret_t rtk_int_status_set(rtk_int_status_t *pStatusMask)
231 {
232 rtk_api_ret_t retVal;
233
234 /* Check initialization state */
235 RTK_CHK_INIT_STATE();
236
237 if(NULL == pStatusMask)
238 return RT_ERR_NULL_POINTER;
239
240 if(pStatusMask->value[0] & (0x0001 << INT_TYPE_RESERVED))
241 return RT_ERR_INPUT;
242
243 if(pStatusMask->value[0] >= (0x0001 << INT_TYPE_END))
244 return RT_ERR_INPUT;
245
246 if ((retVal = rtl8367c_setAsicInterruptStatus((rtk_uint32)pStatusMask->value[0]))!=RT_ERR_OK)
247 return retVal;
248
249 return RT_ERR_OK;
250 }
251
252 /* Function Name:
253 * rtk_int_status_get
254 * Description:
255 * Get interrupt trigger status.
256 * Input:
257 * None
258 * Output:
259 * pStatusMask - Interrupt status bit mask.
260 * Return:
261 * RT_ERR_OK - OK
262 * RT_ERR_FAILED - Failed
263 * RT_ERR_SMI - SMI access error
264 * RT_ERR_INPUT - Invalid input parameters.
265 * Note:
266 * The API can get interrupt trigger status when interrupt happened.
267 * The interrupt trigger status is shown in the following:
268 * - INT_TYPE_LINK_STATUS (value[0] (Bit0))
269 * - INT_TYPE_METER_EXCEED (value[0] (Bit1))
270 * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2))
271 * - INT_TYPE_LINK_SPEED (value[0] (Bit3))
272 * - INT_TYPE_CONGEST (value[0] (Bit4))
273 * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5))
274 * - INT_TYPE_LOOP_DETECT (value[0] (Bit6))
275 * - INT_TYPE_8051 (value[0] (Bit7))
276 * - INT_TYPE_CABLE_DIAG (value[0] (Bit8))
277 * - INT_TYPE_ACL (value[0] (Bit9))
278 * - INT_TYPE_SLIENT (value[0] (Bit11))
279 *
280 */
281 rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask)
282 {
283 rtk_api_ret_t retVal;
284 rtk_uint32 ims_mask;
285
286 /* Check initialization state */
287 RTK_CHK_INIT_STATE();
288
289 if(NULL == pStatusMask)
290 return RT_ERR_NULL_POINTER;
291
292 if ((retVal = rtl8367c_getAsicInterruptStatus(&ims_mask)) != RT_ERR_OK)
293 return retVal;
294
295 pStatusMask->value[0] = (ims_mask & 0x00000FFF);
296 return RT_ERR_OK;
297 }
298
299 #define ADV_NOT_SUPPORT (0xFFFF)
300 static rtk_api_ret_t _rtk_int_Advidx_get(rtk_int_advType_t adv_type, rtk_uint32 *pAsic_idx)
301 {
302 rtk_uint32 asic_idx[ADV_END] =
303 {
304 INTRST_L2_LEARN,
305 INTRST_SPEED_CHANGE,
306 INTRST_SPECIAL_CONGESTION,
307 INTRST_PORT_LINKDOWN,
308 INTRST_PORT_LINKUP,
309 ADV_NOT_SUPPORT,
310 INTRST_RLDP_LOOPED,
311 INTRST_RLDP_RELEASED,
312 };
313
314 if(adv_type >= ADV_END)
315 return RT_ERR_INPUT;
316
317 if(asic_idx[adv_type] == ADV_NOT_SUPPORT)
318 return RT_ERR_CHIP_NOT_SUPPORTED;
319
320 *pAsic_idx = asic_idx[adv_type];
321 return RT_ERR_OK;
322 }
323
324 /* Function Name:
325 * rtk_int_advanceInfo_get
326 * Description:
327 * Get interrupt advanced information.
328 * Input:
329 * adv_type - Advanced interrupt type.
330 * Output:
331 * info - Information per type.
332 * Return:
333 * RT_ERR_OK - OK
334 * RT_ERR_FAILED - Failed
335 * RT_ERR_SMI - SMI access error
336 * RT_ERR_INPUT - Invalid input parameters.
337 * Note:
338 * This API can get advanced information when interrupt happened.
339 * The status will be cleared after execute this API.
340 */
341 rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t *pInfo)
342 {
343 rtk_api_ret_t retVal;
344 rtk_uint32 data;
345 rtk_uint32 intAdvType;
346
347 /* Check initialization state */
348 RTK_CHK_INIT_STATE();
349
350 if(adv_type >= ADV_END)
351 return RT_ERR_INPUT;
352
353 if(NULL == pInfo)
354 return RT_ERR_NULL_POINTER;
355
356 if(adv_type != ADV_METER_EXCEED_MASK)
357 {
358 if((retVal = _rtk_int_Advidx_get(adv_type, &intAdvType)) != RT_ERR_OK)
359 return retVal;
360 }
361
362 switch(adv_type)
363 {
364 case ADV_L2_LEARN_PORT_MASK:
365 /* Get physical portmask */
366 if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK)
367 return retVal;
368
369 /* Clear Advanced Info */
370 if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK)
371 return retVal;
372
373 /* Translate to logical portmask */
374 if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK)
375 return retVal;
376
377 /* Get system learn */
378 if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_SYS_LEARN, &data)) != RT_ERR_OK)
379 return retVal;
380
381 /* Clear system learn */
382 if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_SYS_LEARN, 0x0001)) != RT_ERR_OK)
383 return retVal;
384
385 pInfo->systemLearnOver = data;
386 break;
387 case ADV_SPEED_CHANGE_PORT_MASK:
388 case ADV_SPECIAL_CONGESTION_PORT_MASK:
389 case ADV_PORT_LINKDOWN_PORT_MASK:
390 case ADV_PORT_LINKUP_PORT_MASK:
391 case ADV_RLDP_LOOPED:
392 case ADV_RLDP_RELEASED:
393 /* Get physical portmask */
394 if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK)
395 return retVal;
396
397 /* Clear Advanced Info */
398 if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK)
399 return retVal;
400
401 /* Translate to logical portmask */
402 if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK)
403 return retVal;
404
405 break;
406 case ADV_METER_EXCEED_MASK:
407 /* Get Meter Mask */
408 if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER0_15, &data)) != RT_ERR_OK)
409 return retVal;
410
411 /* Clear Advanced Info */
412 if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER0_15, 0xFFFF)) != RT_ERR_OK)
413 return retVal;
414
415 pInfo->meterMask = data & 0xFFFF;
416
417 /* Get Meter Mask */
418 if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER16_31, &data)) != RT_ERR_OK)
419 return retVal;
420
421 /* Clear Advanced Info */
422 if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER16_31, 0xFFFF)) != RT_ERR_OK)
423 return retVal;
424
425 pInfo->meterMask = pInfo->meterMask | ((data << 16) & 0xFFFF0000);
426
427 break;
428 default:
429 return RT_ERR_INPUT;
430 }
431
432 return RT_ERR_OK;
433 }
434