1 /*-
2 * Copyright (c) 2002-2007 Neterion, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: stable/10/sys/dev/nxge/xgehal/xgehal-mgmt.c 173139 2007-10-29 14:19:32Z rwatson $
27 */
28
29 #include <dev/nxge/include/xgehal-mgmt.h>
30 #include <dev/nxge/include/xgehal-driver.h>
31 #include <dev/nxge/include/xgehal-device.h>
32
33 /**
34 * xge_hal_mgmt_about - Retrieve about info.
35 * @devh: HAL device handle.
36 * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}.
37 * @size: Size of the @about_info buffer. HAL will return error if the
38 * size is smaller than sizeof(xge_hal_mgmt_about_info_t).
39 *
40 * Retrieve information such as PCI device and vendor IDs, board
41 * revision number, HAL version number, etc.
42 *
43 * Returns: XGE_HAL_OK - success;
44 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
45 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
46 * XGE_HAL_FAIL - Failed to retrieve the information.
47 *
48 * See also: xge_hal_mgmt_about_info_t{}.
49 */
50 xge_hal_status_e
xge_hal_mgmt_about(xge_hal_device_h devh,xge_hal_mgmt_about_info_t * about_info,int size)51 xge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info,
52 int size)
53 {
54 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
55
56 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
57 return XGE_HAL_ERR_INVALID_DEVICE;
58 }
59
60 if (size != sizeof(xge_hal_mgmt_about_info_t)) {
61 return XGE_HAL_ERR_VERSION_CONFLICT;
62 }
63
64 xge_os_pci_read16(hldev->pdev, hldev->cfgh,
65 xge_offsetof(xge_hal_pci_config_le_t, vendor_id),
66 &about_info->vendor);
67
68 xge_os_pci_read16(hldev->pdev, hldev->cfgh,
69 xge_offsetof(xge_hal_pci_config_le_t, device_id),
70 &about_info->device);
71
72 xge_os_pci_read16(hldev->pdev, hldev->cfgh,
73 xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
74 &about_info->subsys_vendor);
75
76 xge_os_pci_read16(hldev->pdev, hldev->cfgh,
77 xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
78 &about_info->subsys_device);
79
80 xge_os_pci_read8(hldev->pdev, hldev->cfgh,
81 xge_offsetof(xge_hal_pci_config_le_t, revision),
82 &about_info->board_rev);
83
84 xge_os_strcpy(about_info->vendor_name, XGE_DRIVER_VENDOR);
85 xge_os_strcpy(about_info->chip_name, XGE_CHIP_FAMILY);
86 xge_os_strcpy(about_info->media, XGE_SUPPORTED_MEDIA_0);
87
88 xge_os_strcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR);
89 xge_os_strcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR);
90 xge_os_strcpy(about_info->hal_fix, XGE_HAL_VERSION_FIX);
91 xge_os_strcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD);
92
93 xge_os_strcpy(about_info->ll_major, XGELL_VERSION_MAJOR);
94 xge_os_strcpy(about_info->ll_minor, XGELL_VERSION_MINOR);
95 xge_os_strcpy(about_info->ll_fix, XGELL_VERSION_FIX);
96 xge_os_strcpy(about_info->ll_build, XGELL_VERSION_BUILD);
97
98 about_info->transponder_temperature =
99 xge_hal_read_xfp_current_temp(devh);
100
101 return XGE_HAL_OK;
102 }
103
104 /**
105 * xge_hal_mgmt_reg_read - Read Xframe register.
106 * @devh: HAL device handle.
107 * @bar_id: 0 - for BAR0, 1- for BAR1.
108 * @offset: Register offset in the Base Address Register (BAR) space.
109 * @value: Register value. Returned by HAL.
110 * Read Xframe register.
111 *
112 * Returns: XGE_HAL_OK - success.
113 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
114 * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
115 * valid.
116 * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
117 *
118 * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read().
119 */
120 xge_hal_status_e
xge_hal_mgmt_reg_read(xge_hal_device_h devh,int bar_id,unsigned int offset,u64 * value)121 xge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset,
122 u64 *value)
123 {
124 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
125
126 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
127 return XGE_HAL_ERR_INVALID_DEVICE;
128 }
129
130 if (bar_id == 0) {
131 if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
132 return XGE_HAL_ERR_INVALID_OFFSET;
133 }
134 *value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
135 (void *)(hldev->bar0 + offset));
136 } else if (bar_id == 1 &&
137 (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
138 xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)) {
139 int i;
140 for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
141 if (offset == i*0x2000 || offset == i*0x2000+0x18) {
142 break;
143 }
144 }
145 if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
146 return XGE_HAL_ERR_INVALID_OFFSET;
147 }
148 *value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1,
149 (void *)(hldev->bar1 + offset));
150 } else if (bar_id == 1) {
151 /* FIXME: check TITAN BAR1 offsets */
152 } else {
153 return XGE_HAL_ERR_INVALID_BAR_ID;
154 }
155
156 return XGE_HAL_OK;
157 }
158
159 /**
160 * xge_hal_mgmt_reg_write - Write Xframe register.
161 * @devh: HAL device handle.
162 * @bar_id: 0 - for BAR0, 1- for BAR1.
163 * @offset: Register offset in the Base Address Register (BAR) space.
164 * @value: Register value.
165 *
166 * Write Xframe register.
167 *
168 * Returns: XGE_HAL_OK - success.
169 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
170 * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
171 * valid.
172 * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
173 *
174 * See also: xge_hal_aux_bar0_write().
175 */
176 xge_hal_status_e
xge_hal_mgmt_reg_write(xge_hal_device_h devh,int bar_id,unsigned int offset,u64 value)177 xge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset,
178 u64 value)
179 {
180 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
181
182 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
183 return XGE_HAL_ERR_INVALID_DEVICE;
184 }
185
186 if (bar_id == 0) {
187 if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
188 return XGE_HAL_ERR_INVALID_OFFSET;
189 }
190 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value,
191 (void *)(hldev->bar0 + offset));
192 } else if (bar_id == 1 &&
193 (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
194 xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)) {
195 int i;
196 for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
197 if (offset == i*0x2000 || offset == i*0x2000+0x18) {
198 break;
199 }
200 }
201 if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
202 return XGE_HAL_ERR_INVALID_OFFSET;
203 }
204 xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value,
205 (void *)(hldev->bar1 + offset));
206 } else if (bar_id == 1) {
207 /* FIXME: check TITAN BAR1 offsets */
208 } else {
209 return XGE_HAL_ERR_INVALID_BAR_ID;
210 }
211
212 return XGE_HAL_OK;
213 }
214
215 /**
216 * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics.
217 * @devh: HAL device handle.
218 * @hw_stats: Hardware statistics. Returned by HAL.
219 * See xge_hal_stats_hw_info_t{}.
220 * @size: Size of the @hw_stats buffer. HAL will return an error
221 * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
222 * Get Xframe hardware statistics.
223 *
224 * Returns: XGE_HAL_OK - success.
225 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
226 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
227 *
228 * See also: xge_hal_mgmt_sw_stats().
229 */
230 xge_hal_status_e
xge_hal_mgmt_hw_stats(xge_hal_device_h devh,xge_hal_mgmt_hw_stats_t * hw_stats,int size)231 xge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats,
232 int size)
233 {
234 xge_hal_status_e status;
235 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
236 xge_hal_stats_hw_info_t *hw_info;
237
238 xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
239
240 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
241 return XGE_HAL_ERR_INVALID_DEVICE;
242 }
243
244 if (size != sizeof(xge_hal_stats_hw_info_t)) {
245 return XGE_HAL_ERR_VERSION_CONFLICT;
246 }
247
248 if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
249 return status;
250 }
251
252 xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t));
253
254 return XGE_HAL_OK;
255 }
256
257 /**
258 * xge_hal_mgmt_hw_stats_off - TBD.
259 * @devh: HAL device handle.
260 * @off: TBD
261 * @size: TBD
262 * @out: TBD
263 *
264 * Returns: XGE_HAL_OK - success.
265 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
266 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
267 *
268 * See also: xge_hal_mgmt_sw_stats().
269 */
270 xge_hal_status_e
xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh,int off,int size,char * out)271 xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out)
272 {
273 xge_hal_status_e status;
274 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
275 xge_hal_stats_hw_info_t *hw_info;
276
277 xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
278
279 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
280 return XGE_HAL_ERR_INVALID_DEVICE;
281 }
282
283 if (off > sizeof(xge_hal_stats_hw_info_t)-4 ||
284 size > 8) {
285 return XGE_HAL_ERR_INVALID_OFFSET;
286 }
287
288 if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
289 return status;
290 }
291
292 xge_os_memcpy(out, (char*)hw_info + off, size);
293
294 return XGE_HAL_OK;
295 }
296
297 /**
298 * xge_hal_mgmt_pcim_stats - Get Titan hardware statistics.
299 * @devh: HAL device handle.
300 * @pcim_stats: PCIM statistics. Returned by HAL.
301 * See xge_hal_stats_hw_info_t{}.
302 * @size: Size of the @hw_stats buffer. HAL will return an error
303 * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
304 * Get Xframe hardware statistics.
305 *
306 * Returns: XGE_HAL_OK - success.
307 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
308 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
309 *
310 * See also: xge_hal_mgmt_sw_stats().
311 */
312 xge_hal_status_e
xge_hal_mgmt_pcim_stats(xge_hal_device_h devh,xge_hal_mgmt_pcim_stats_t * pcim_stats,int size)313 xge_hal_mgmt_pcim_stats(xge_hal_device_h devh,
314 xge_hal_mgmt_pcim_stats_t *pcim_stats, int size)
315 {
316 xge_hal_status_e status;
317 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
318 xge_hal_stats_pcim_info_t *pcim_info;
319
320 xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
321
322 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
323 return XGE_HAL_ERR_INVALID_DEVICE;
324 }
325
326 if (size != sizeof(xge_hal_stats_pcim_info_t)) {
327 return XGE_HAL_ERR_VERSION_CONFLICT;
328 }
329
330 if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
331 return status;
332 }
333
334 xge_os_memcpy(pcim_stats, pcim_info,
335 sizeof(xge_hal_stats_pcim_info_t));
336
337 return XGE_HAL_OK;
338 }
339
340 /**
341 * xge_hal_mgmt_pcim_stats_off - TBD.
342 * @devh: HAL device handle.
343 * @off: TBD
344 * @size: TBD
345 * @out: TBD
346 *
347 * Returns: XGE_HAL_OK - success.
348 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
349 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
350 *
351 * See also: xge_hal_mgmt_sw_stats().
352 */
353 xge_hal_status_e
xge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh,int off,int size,char * out)354 xge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh, int off, int size,
355 char *out)
356 {
357 xge_hal_status_e status;
358 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
359 xge_hal_stats_pcim_info_t *pcim_info;
360
361 xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
362
363 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
364 return XGE_HAL_ERR_INVALID_DEVICE;
365 }
366
367 if (off > sizeof(xge_hal_stats_pcim_info_t)-8 ||
368 size > 8) {
369 return XGE_HAL_ERR_INVALID_OFFSET;
370 }
371
372 if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
373 return status;
374 }
375
376 xge_os_memcpy(out, (char*)pcim_info + off, size);
377
378 return XGE_HAL_OK;
379 }
380
381 /**
382 * xge_hal_mgmt_sw_stats - Get per-device software statistics.
383 * @devh: HAL device handle.
384 * @sw_stats: Hardware statistics. Returned by HAL.
385 * See xge_hal_stats_sw_err_t{}.
386 * @size: Size of the @sw_stats buffer. HAL will return an error
387 * if the size is smaller than sizeof(xge_hal_stats_sw_err_t).
388 * Get device software statistics, including ECC and Parity error
389 * counters, etc.
390 *
391 * Returns: XGE_HAL_OK - success.
392 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
393 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
394 *
395 * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats().
396 */
397 xge_hal_status_e
xge_hal_mgmt_sw_stats(xge_hal_device_h devh,xge_hal_mgmt_sw_stats_t * sw_stats,int size)398 xge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats,
399 int size)
400 {
401 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
402
403 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
404 return XGE_HAL_ERR_INVALID_DEVICE;
405 }
406
407 if (size != sizeof(xge_hal_stats_sw_err_t)) {
408 return XGE_HAL_ERR_VERSION_CONFLICT;
409 }
410
411 if (!hldev->stats.is_initialized ||
412 !hldev->stats.is_enabled) {
413 return XGE_HAL_INF_STATS_IS_NOT_READY;
414 }
415
416 /* Updating xpak stats value */
417 __hal_updt_stats_xpak(hldev);
418
419 xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats,
420 sizeof(xge_hal_stats_sw_err_t));
421
422 return XGE_HAL_OK;
423 }
424
425 /**
426 * xge_hal_mgmt_device_stats - Get HAL device statistics.
427 * @devh: HAL device handle.
428 * @device_stats: HAL device "soft" statistics. Maintained by HAL itself.
429 * (as opposed to xge_hal_mgmt_hw_stats() - those are
430 * maintained by the Xframe hardware).
431 * Returned by HAL.
432 * See xge_hal_stats_device_info_t{}.
433 * @size: Size of the @device_stats buffer. HAL will return an error
434 * if the size is smaller than sizeof(xge_hal_stats_device_info_t).
435 *
436 * Get HAL (layer) statistic counters.
437 * Returns: XGE_HAL_OK - success.
438 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
439 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
440 * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
441 * currently available.
442 *
443 */
444 xge_hal_status_e
xge_hal_mgmt_device_stats(xge_hal_device_h devh,xge_hal_mgmt_device_stats_t * device_stats,int size)445 xge_hal_mgmt_device_stats(xge_hal_device_h devh,
446 xge_hal_mgmt_device_stats_t *device_stats, int size)
447 {
448 xge_hal_status_e status;
449 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
450 xge_hal_stats_device_info_t *device_info;
451
452 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
453 return XGE_HAL_ERR_INVALID_DEVICE;
454 }
455
456 if (size != sizeof(xge_hal_stats_device_info_t)) {
457 return XGE_HAL_ERR_VERSION_CONFLICT;
458 }
459
460 if ((status = xge_hal_stats_device (devh, &device_info)) !=
461 XGE_HAL_OK) {
462 return status;
463 }
464
465 xge_os_memcpy(device_stats, device_info,
466 sizeof(xge_hal_stats_device_info_t));
467
468 return XGE_HAL_OK;
469 }
470
471 /*
472 * __hal_update_ring_bump - Update the ring bump counter for the
473 * particular channel.
474 * @hldev: HAL device handle.
475 * @queue: the queue who's data is to be collected.
476 * @chinfo: pointer to the statistics structure of the given channel.
477 * Usage: See xge_hal_aux_stats_hal_read{}
478 */
479
480 static void
__hal_update_ring_bump(xge_hal_device_t * hldev,int queue,xge_hal_stats_channel_info_t * chinfo)481 __hal_update_ring_bump(xge_hal_device_t *hldev, int queue,
482 xge_hal_stats_channel_info_t *chinfo)
483 {
484 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
485 u64 rbc = 0;
486 int reg = (queue / 4);
487 void * addr;
488
489 addr = (reg == 1)? (&bar0->ring_bump_counter2) :
490 (&bar0->ring_bump_counter1);
491 rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr);
492 chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc);
493 }
494
495 /**
496 * xge_hal_mgmt_channel_stats - Get HAL channel statistics.
497 * @channelh: HAL channel handle.
498 * @channel_stats: HAL channel statistics. Maintained by HAL itself
499 * (as opposed to xge_hal_mgmt_hw_stats() - those are
500 * maintained by the Xframe hardware).
501 * Returned by HAL.
502 * See xge_hal_stats_channel_info_t{}.
503 * @size: Size of the @channel_stats buffer. HAL will return an error
504 * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t).
505 *
506 * Get HAL per-channel statistic counters.
507 *
508 * Returns: XGE_HAL_OK - success.
509 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
510 * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
511 * currently available.
512 *
513 */
514 xge_hal_status_e
xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,xge_hal_mgmt_channel_stats_t * channel_stats,int size)515 xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,
516 xge_hal_mgmt_channel_stats_t *channel_stats, int size)
517 {
518 xge_hal_status_e status;
519 xge_hal_stats_channel_info_t *channel_info;
520 xge_hal_channel_t *channel = (xge_hal_channel_t* ) channelh;
521
522 if (size != sizeof(xge_hal_stats_channel_info_t)) {
523 return XGE_HAL_ERR_VERSION_CONFLICT;
524 }
525
526 if ((status = xge_hal_stats_channel (channelh, &channel_info)) !=
527 XGE_HAL_OK) {
528 return status;
529 }
530
531 if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) {
532 __hal_update_ring_bump( (xge_hal_device_t *) channel->devh, channel->post_qid, channel_info);
533 }
534
535 xge_os_memcpy(channel_stats, channel_info,
536 sizeof(xge_hal_stats_channel_info_t));
537
538 return XGE_HAL_OK;
539 }
540
541 /**
542 * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
543 * offset.
544 * @devh: HAL device handle.
545 * @offset: Offset in the 256 byte PCI configuration space.
546 * @value_bits: 8, 16, or 32 (bits) to read.
547 * @value: Value returned by HAL.
548 *
549 * Read PCI configuration, given device and offset in the PCI space.
550 *
551 * Returns: XGE_HAL_OK - success.
552 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
553 * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
554 * valid.
555 * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
556 * values(8/16/32).
557 *
558 */
559 xge_hal_status_e
xge_hal_mgmt_pcireg_read(xge_hal_device_h devh,unsigned int offset,int value_bits,u32 * value)560 xge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset,
561 int value_bits, u32 *value)
562 {
563 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
564
565 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
566 return XGE_HAL_ERR_INVALID_DEVICE;
567 }
568
569 if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) {
570 return XGE_HAL_ERR_INVALID_OFFSET;
571 }
572
573 if (value_bits == 8) {
574 xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value);
575 } else if (value_bits == 16) {
576 xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset,
577 (u16*)value);
578 } else if (value_bits == 32) {
579 xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value);
580 } else {
581 return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE;
582 }
583
584 return XGE_HAL_OK;
585 }
586
587 /**
588 * xge_hal_mgmt_device_config - Retrieve device configuration.
589 * @devh: HAL device handle.
590 * @dev_config: Device configuration, see xge_hal_device_config_t{}.
591 * @size: Size of the @dev_config buffer. HAL will return an error
592 * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t).
593 *
594 * Get device configuration. Permits to retrieve at run-time configuration
595 * values that were used to initialize and configure the device.
596 *
597 * Returns: XGE_HAL_OK - success.
598 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
599 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
600 *
601 * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config().
602 */
603 xge_hal_status_e
xge_hal_mgmt_device_config(xge_hal_device_h devh,xge_hal_mgmt_device_config_t * dev_config,int size)604 xge_hal_mgmt_device_config(xge_hal_device_h devh,
605 xge_hal_mgmt_device_config_t *dev_config, int size)
606 {
607 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
608
609 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
610 return XGE_HAL_ERR_INVALID_DEVICE;
611 }
612
613 if (size != sizeof(xge_hal_mgmt_device_config_t)) {
614 return XGE_HAL_ERR_VERSION_CONFLICT;
615 }
616
617 xge_os_memcpy(dev_config, &hldev->config,
618 sizeof(xge_hal_device_config_t));
619
620 return XGE_HAL_OK;
621 }
622
623 /**
624 * xge_hal_mgmt_driver_config - Retrieve driver configuration.
625 * @drv_config: Device configuration, see xge_hal_driver_config_t{}.
626 * @size: Size of the @dev_config buffer. HAL will return an error
627 * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t).
628 *
629 * Get driver configuration. Permits to retrieve at run-time configuration
630 * values that were used to configure the device at load-time.
631 *
632 * Returns: XGE_HAL_OK - success.
633 * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
634 * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
635 *
636 * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config().
637 */
638 xge_hal_status_e
xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t * drv_config,int size)639 xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size)
640 {
641
642 if (g_xge_hal_driver == NULL) {
643 return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
644 }
645
646 if (size != sizeof(xge_hal_mgmt_driver_config_t)) {
647 return XGE_HAL_ERR_VERSION_CONFLICT;
648 }
649
650 xge_os_memcpy(drv_config, &g_xge_hal_driver->config,
651 sizeof(xge_hal_mgmt_driver_config_t));
652
653 return XGE_HAL_OK;
654 }
655
656 /**
657 * xge_hal_mgmt_pci_config - Retrieve PCI configuration.
658 * @devh: HAL device handle.
659 * @pci_config: 256 byte long buffer for PCI configuration space.
660 * @size: Size of the @ buffer. HAL will return an error
661 * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t).
662 *
663 * Get PCI configuration. Permits to retrieve at run-time configuration
664 * values that were used to configure the device at load-time.
665 *
666 * Returns: XGE_HAL_OK - success.
667 * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
668 * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
669 *
670 */
671 xge_hal_status_e
xge_hal_mgmt_pci_config(xge_hal_device_h devh,xge_hal_mgmt_pci_config_t * pci_config,int size)672 xge_hal_mgmt_pci_config(xge_hal_device_h devh,
673 xge_hal_mgmt_pci_config_t *pci_config, int size)
674 {
675 int i;
676 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
677
678 if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
679 return XGE_HAL_ERR_INVALID_DEVICE;
680 }
681
682 if (size != sizeof(xge_hal_mgmt_pci_config_t)) {
683 return XGE_HAL_ERR_VERSION_CONFLICT;
684 }
685
686 /* refresh PCI config space */
687 for (i = 0; i < 0x68/4+1; i++) {
688 xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
689 (u32*)&hldev->pci_config_space + i);
690 }
691
692 xge_os_memcpy(pci_config, &hldev->pci_config_space,
693 sizeof(xge_hal_mgmt_pci_config_t));
694
695 return XGE_HAL_OK;
696 }
697
698 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
699 /**
700 * xge_hal_mgmt_trace_read - Read trace buffer contents.
701 * @buffer: Buffer to store the trace buffer contents.
702 * @buf_size: Size of the buffer.
703 * @offset: Offset in the internal trace buffer to read data.
704 * @read_length: Size of the valid data in the buffer.
705 *
706 * Read HAL trace buffer contents starting from the offset
707 * upto the size of the buffer or till EOF is reached.
708 *
709 * Returns: XGE_HAL_OK - success.
710 * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
711 *
712 */
713 xge_hal_status_e
xge_hal_mgmt_trace_read(char * buffer,unsigned buf_size,unsigned * offset,unsigned * read_length)714 xge_hal_mgmt_trace_read (char *buffer,
715 unsigned buf_size,
716 unsigned *offset,
717 unsigned *read_length)
718 {
719 int data_offset;
720 int start_offset;
721
722 if ((g_xge_os_tracebuf == NULL) ||
723 (g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) {
724 return XGE_HAL_EOF_TRACE_BUF;
725 }
726
727 data_offset = g_xge_os_tracebuf->offset + 1;
728
729 if (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data +
730 data_offset)) {
731
732 return XGE_HAL_EOF_TRACE_BUF;
733 }
734
735 xge_os_memzero(buffer, buf_size);
736
737 start_offset = data_offset + *offset;
738 *read_length = xge_os_strlen(g_xge_os_tracebuf->data +
739 start_offset);
740
741 if (*read_length >= buf_size) {
742 *read_length = buf_size - 1;
743 }
744
745 xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset,
746 *read_length);
747
748 *offset += *read_length;
749 (*read_length) ++;
750
751 return XGE_HAL_OK;
752 }
753
754 #endif
755
756 /**
757 * xge_hal_restore_link_led - Restore link LED to its original state.
758 * @devh: HAL device handle.
759 */
760 void
xge_hal_restore_link_led(xge_hal_device_h devh)761 xge_hal_restore_link_led(xge_hal_device_h devh)
762 {
763 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
764 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
765 u64 val64;
766
767 /*
768 * If the current link state is UP, switch on LED else make it
769 * off.
770 */
771
772 /*
773 * For Xena 3 and lower revision cards, adapter control needs to be
774 * used for making LED ON/OFF.
775 */
776 if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
777 (xge_hal_device_rev(hldev) <= 3)) {
778 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
779 &bar0->adapter_control);
780 if (hldev->link_state == XGE_HAL_LINK_UP) {
781 val64 |= XGE_HAL_ADAPTER_LED_ON;
782 } else {
783 val64 &= ~XGE_HAL_ADAPTER_LED_ON;
784 }
785
786 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
787 &bar0->adapter_control);
788 return;
789 }
790
791 /*
792 * Use beacon control register to control the LED.
793 * LED link output corresponds to bit 8 of the beacon control
794 * register. Note that, in the case of Xena, beacon control register
795 * represents the gpio control register. In the case of Herc, LED
796 * handling is done by beacon control register as opposed to gpio
797 * control register in Xena. Beacon control is used only to toggle
798 * and the value written into it does not depend on the link state.
799 * It is upto the ULD to toggle the LED even number of times which
800 * brings the LED to it's original state.
801 */
802 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
803 &bar0->beacon_control);
804 val64 |= 0x0000800000000000ULL;
805 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
806 val64, &bar0->beacon_control);
807 }
808
809 /**
810 * xge_hal_flick_link_led - Flick (blink) link LED.
811 * @devh: HAL device handle.
812 *
813 * Depending on the card revision flicker the link LED by using the
814 * beacon control or the adapter_control register.
815 */
816 void
xge_hal_flick_link_led(xge_hal_device_h devh)817 xge_hal_flick_link_led(xge_hal_device_h devh)
818 {
819 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
820 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
821 u64 val64 = 0;
822
823 /*
824 * For Xena 3 and lower revision cards, adapter control needs to be
825 * used for making LED ON/OFF.
826 */
827 if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
828 (xge_hal_device_rev(hldev) <= 3)) {
829 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
830 &bar0->adapter_control);
831 val64 ^= XGE_HAL_ADAPTER_LED_ON;
832 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
833 &bar0->adapter_control);
834 return;
835 }
836
837 /*
838 * Use beacon control register to control the Link LED.
839 * Note that, in the case of Xena, beacon control register represents
840 * the gpio control register. In the case of Herc, LED handling is
841 * done by beacon control register as opposed to gpio control register
842 * in Xena.
843 */
844 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
845 &bar0->beacon_control);
846 val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0;
847 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
848 &bar0->beacon_control);
849 }
850
851 /**
852 * xge_hal_read_eeprom - Read 4 bytes of data from user given offset.
853 * @devh: HAL device handle.
854 * @off: offset at which the data must be written
855 * @data: output parameter where the data is stored.
856 *
857 * Read 4 bytes of data from the user given offset and return the
858 * read data.
859 * Note: will allow to read only part of the EEPROM visible through the
860 * I2C bus.
861 * Returns: -1 on failure, 0 on success.
862 */
863 xge_hal_status_e
xge_hal_read_eeprom(xge_hal_device_h devh,int off,u32 * data)864 xge_hal_read_eeprom(xge_hal_device_h devh, int off, u32* data)
865 {
866 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
867 xge_hal_status_e ret = XGE_HAL_FAIL;
868 u32 exit_cnt = 0;
869 u64 val64;
870 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
871
872 val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
873 XGE_HAL_I2C_CONTROL_ADDR(off) |
874 XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) |
875 XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START;
876
877 __hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
878
879 while (exit_cnt < 5) {
880 val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
881 if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
882 *data = XGE_HAL_I2C_CONTROL_GET_DATA(val64);
883 ret = XGE_HAL_OK;
884 break;
885 }
886 exit_cnt++;
887 }
888
889 return ret;
890 }
891
892 /*
893 * xge_hal_write_eeprom - actually writes the relevant part of the data
894 value.
895 * @devh: HAL device handle.
896 * @off: offset at which the data must be written
897 * @data : The data that is to be written
898 * @cnt : Number of bytes of the data that are actually to be written into
899 * the Eeprom. (max of 3)
900 *
901 * Actually writes the relevant part of the data value into the Eeprom
902 * through the I2C bus.
903 * Return value:
904 * 0 on success, -1 on failure.
905 */
906
907 xge_hal_status_e
xge_hal_write_eeprom(xge_hal_device_h devh,int off,u32 data,int cnt)908 xge_hal_write_eeprom(xge_hal_device_h devh, int off, u32 data, int cnt)
909 {
910 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
911 xge_hal_status_e ret = XGE_HAL_FAIL;
912 u32 exit_cnt = 0;
913 u64 val64;
914 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
915
916 val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
917 XGE_HAL_I2C_CONTROL_ADDR(off) |
918 XGE_HAL_I2C_CONTROL_BYTE_CNT(cnt) |
919 XGE_HAL_I2C_CONTROL_SET_DATA(data) |
920 XGE_HAL_I2C_CONTROL_CNTL_START;
921 __hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
922
923 while (exit_cnt < 5) {
924 val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
925 if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
926 if (!(val64 & XGE_HAL_I2C_CONTROL_NACK))
927 ret = XGE_HAL_OK;
928 break;
929 }
930 exit_cnt++;
931 }
932
933 return ret;
934 }
935
936 /*
937 * xge_hal_register_test - reads and writes into all clock domains.
938 * @hldev : private member of the device structure.
939 * xge_nic structure.
940 * @data : variable that returns the result of each of the test conducted b
941 * by the driver.
942 *
943 * Read and write into all clock domains. The NIC has 3 clock domains,
944 * see that registers in all the three regions are accessible.
945 * Return value:
946 * 0 on success.
947 */
948 xge_hal_status_e
xge_hal_register_test(xge_hal_device_h devh,u64 * data)949 xge_hal_register_test(xge_hal_device_h devh, u64 *data)
950 {
951 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
952 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
953 u64 val64 = 0;
954 int fail = 0;
955
956 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
957 &bar0->pif_rd_swapper_fb);
958 if (val64 != 0x123456789abcdefULL) {
959 fail = 1;
960 xge_debug_osdep(XGE_TRACE, "Read Test level 1 fails");
961 }
962
963 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
964 &bar0->rmac_pause_cfg);
965 if (val64 != 0xc000ffff00000000ULL) {
966 fail = 1;
967 xge_debug_osdep(XGE_TRACE, "Read Test level 2 fails");
968 }
969
970 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
971 &bar0->rx_queue_cfg);
972 if (val64 != 0x0808080808080808ULL) {
973 fail = 1;
974 xge_debug_osdep(XGE_TRACE, "Read Test level 3 fails");
975 }
976
977 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
978 &bar0->xgxs_efifo_cfg);
979 if (val64 != 0x000000001923141EULL) {
980 fail = 1;
981 xge_debug_osdep(XGE_TRACE, "Read Test level 4 fails");
982 }
983
984 val64 = 0x5A5A5A5A5A5A5A5AULL;
985 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
986 &bar0->xmsi_data);
987 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
988 &bar0->xmsi_data);
989 if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
990 fail = 1;
991 xge_debug_osdep(XGE_ERR, "Write Test level 1 fails");
992 }
993
994 val64 = 0xA5A5A5A5A5A5A5A5ULL;
995 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
996 &bar0->xmsi_data);
997 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
998 &bar0->xmsi_data);
999 if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
1000 fail = 1;
1001 xge_debug_osdep(XGE_ERR, "Write Test level 2 fails");
1002 }
1003
1004 *data = fail;
1005 return XGE_HAL_OK;
1006 }
1007
1008 /*
1009 * xge_hal_rldram_test - offline test for access to the RldRam chip on
1010 the NIC
1011 * @devh: HAL device handle.
1012 * @data: variable that returns the result of each of the test
1013 * conducted by the driver.
1014 *
1015 * This is one of the offline test that tests the read and write
1016 * access to the RldRam chip on the NIC.
1017 * Return value:
1018 * 0 on success.
1019 */
1020 xge_hal_status_e
xge_hal_rldram_test(xge_hal_device_h devh,u64 * data)1021 xge_hal_rldram_test(xge_hal_device_h devh, u64 *data)
1022 {
1023 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1024 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1025 u64 val64;
1026 int cnt, iteration = 0, test_pass = 0;
1027
1028 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1029 &bar0->adapter_control);
1030 val64 &= ~XGE_HAL_ADAPTER_ECC_EN;
1031 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1032 &bar0->adapter_control);
1033
1034 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1035 &bar0->mc_rldram_test_ctrl);
1036 val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE;
1037 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1038 &bar0->mc_rldram_test_ctrl);
1039
1040 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1041 &bar0->mc_rldram_mrs);
1042 val64 |= XGE_HAL_MC_RLDRAM_QUEUE_SIZE_ENABLE;
1043 __hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1044
1045 val64 |= XGE_HAL_MC_RLDRAM_MRS_ENABLE;
1046 __hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1047
1048 while (iteration < 2) {
1049 val64 = 0x55555555aaaa0000ULL;
1050 if (iteration == 1) {
1051 val64 ^= 0xFFFFFFFFFFFF0000ULL;
1052 }
1053 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1054 &bar0->mc_rldram_test_d0);
1055
1056 val64 = 0xaaaa5a5555550000ULL;
1057 if (iteration == 1) {
1058 val64 ^= 0xFFFFFFFFFFFF0000ULL;
1059 }
1060 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1061 &bar0->mc_rldram_test_d1);
1062
1063 val64 = 0x55aaaaaaaa5a0000ULL;
1064 if (iteration == 1) {
1065 val64 ^= 0xFFFFFFFFFFFF0000ULL;
1066 }
1067 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1068 &bar0->mc_rldram_test_d2);
1069
1070 val64 = (u64) (0x0000003fffff0000ULL);
1071 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1072 &bar0->mc_rldram_test_add);
1073
1074
1075 val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1076 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1077 &bar0->mc_rldram_test_ctrl);
1078
1079 val64 |=
1080 XGE_HAL_MC_RLDRAM_TEST_MODE | XGE_HAL_MC_RLDRAM_TEST_WRITE |
1081 XGE_HAL_MC_RLDRAM_TEST_GO;
1082 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1083 &bar0->mc_rldram_test_ctrl);
1084
1085 for (cnt = 0; cnt < 5; cnt++) {
1086 val64 = xge_os_pio_mem_read64(hldev->pdev,
1087 hldev->regh0, &bar0->mc_rldram_test_ctrl);
1088 if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1089 break;
1090 xge_os_mdelay(200);
1091 }
1092
1093 if (cnt == 5)
1094 break;
1095
1096 val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1097 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1098 &bar0->mc_rldram_test_ctrl);
1099
1100 val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE |
1101 XGE_HAL_MC_RLDRAM_TEST_GO;
1102 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1103 &bar0->mc_rldram_test_ctrl);
1104
1105 for (cnt = 0; cnt < 5; cnt++) {
1106 val64 = xge_os_pio_mem_read64(hldev->pdev,
1107 hldev->regh0, &bar0->mc_rldram_test_ctrl);
1108 if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1109 break;
1110 xge_os_mdelay(500);
1111 }
1112
1113 if (cnt == 5)
1114 break;
1115
1116 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1117 &bar0->mc_rldram_test_ctrl);
1118 if (val64 & XGE_HAL_MC_RLDRAM_TEST_PASS)
1119 test_pass = 1;
1120
1121 iteration++;
1122 }
1123
1124 if (!test_pass)
1125 *data = 1;
1126 else
1127 *data = 0;
1128
1129 return XGE_HAL_OK;
1130 }
1131
1132 /*
1133 * xge_hal_pma_loopback - Enable or disable PMA loopback
1134 * @devh: HAL device handle.
1135 * @enable:Boolean set to 1 to enable and 0 to disable.
1136 *
1137 * Enable or disable PMA loopback.
1138 * Return value:
1139 * 0 on success.
1140 */
1141 xge_hal_status_e
xge_hal_pma_loopback(xge_hal_device_h devh,int enable)1142 xge_hal_pma_loopback( xge_hal_device_h devh, int enable )
1143 {
1144 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1145 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1146 u64 val64;
1147 u16 data;
1148
1149 /*
1150 * This code if for MAC loopbak
1151 * Should be enabled through another parameter
1152 */
1153 #if 0
1154 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1155 &bar0->mac_cfg);
1156 if ( enable )
1157 {
1158 val64 |= ( XGE_HAL_MAC_CFG_TMAC_LOOPBACK | XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE );
1159 }
1160 __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
1161 (u32)(val64 >> 32), (char*)&bar0->mac_cfg);
1162 xge_os_mdelay(1);
1163 #endif
1164
1165 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0) |
1166 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1) |
1167 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1168 XGE_HAL_MDIO_CONTROL_MMD_CTRL(0) |
1169 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1170 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1171
1172 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1173 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1174
1175 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0) |
1176 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1) |
1177 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1178 XGE_HAL_MDIO_CONTROL_MMD_CTRL(0) |
1179 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1180 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1181
1182 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1183 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1184
1185 val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1186
1187 data = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
1188
1189 #define _HAL_LOOPBK_PMA 1
1190
1191 if( enable )
1192 data |= 1;
1193 else
1194 data &= 0xfe;
1195
1196 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0) |
1197 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1) |
1198 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1199 XGE_HAL_MDIO_CONTROL_MMD_CTRL(0) |
1200 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1201 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1202
1203 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1204 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1205
1206 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0) |
1207 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1) |
1208 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1209 XGE_HAL_MDIO_CONTROL_MMD_DATA(data) |
1210 XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0) |
1211 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
1212 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1213
1214 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1215 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1216
1217 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0) |
1218 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1) |
1219 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1220 XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0) |
1221 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1222 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1223
1224 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1225 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1226
1227 return XGE_HAL_OK;
1228 }
1229
1230 u16
xge_hal_mdio_read(xge_hal_device_h devh,u32 mmd_type,u64 addr)1231 xge_hal_mdio_read( xge_hal_device_h devh, u32 mmd_type, u64 addr )
1232 {
1233 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1234 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1235 u64 val64 = 0x0;
1236 u16 rval16 = 0x0;
1237 u8 i = 0;
1238
1239 /* address transaction */
1240 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr) |
1241 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type) |
1242 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1243 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1244 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1245
1246 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1247 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1248 do
1249 {
1250 val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1251 if (i++ > 10)
1252 {
1253 break;
1254 }
1255 }while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1256
1257 /* Data transaction */
1258 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr) |
1259 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type) |
1260 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1261 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1262 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1263
1264 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1265 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1266
1267 i = 0;
1268
1269 do
1270 {
1271 val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1272 if (i++ > 10)
1273 {
1274 break;
1275 }
1276 }while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1277
1278 rval16 = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
1279
1280 return rval16;
1281 }
1282
1283 xge_hal_status_e
xge_hal_mdio_write(xge_hal_device_h devh,u32 mmd_type,u64 addr,u32 value)1284 xge_hal_mdio_write( xge_hal_device_h devh, u32 mmd_type, u64 addr, u32 value )
1285 {
1286 u64 val64 = 0x0;
1287 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1288 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1289 u8 i = 0;
1290 /* address transaction */
1291
1292 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr) |
1293 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type) |
1294 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1295 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1296 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1297
1298 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1299 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1300
1301 do
1302 {
1303 val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1304 if (i++ > 10)
1305 {
1306 break;
1307 }
1308 } while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) !=
1309 XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1310
1311 /* Data transaction */
1312
1313 val64 = 0x0;
1314
1315 val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr) |
1316 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type) |
1317 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0) |
1318 XGE_HAL_MDIO_CONTROL_MMD_DATA(value) |
1319 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
1320 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1321
1322 val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1323 __hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1324
1325 i = 0;
1326
1327 do
1328 {
1329 val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1330 if (i++ > 10)
1331 {
1332 break;
1333 }
1334 }while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1335
1336 return XGE_HAL_OK;
1337 }
1338
1339 /*
1340 * xge_hal_eeprom_test - to verify that EEprom in the xena can be
1341 programmed.
1342 * @devh: HAL device handle.
1343 * @data:variable that returns the result of each of the test conducted by
1344 * the driver.
1345 *
1346 * Verify that EEPROM in the xena can be programmed using I2C_CONTROL
1347 * register.
1348 * Return value:
1349 * 0 on success.
1350 */
1351 xge_hal_status_e
xge_hal_eeprom_test(xge_hal_device_h devh,u64 * data)1352 xge_hal_eeprom_test(xge_hal_device_h devh, u64 *data)
1353 {
1354 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1355 int fail = 0;
1356 u32 ret_data = 0;
1357
1358 /* Test Write Error at offset 0 */
1359 if (!xge_hal_write_eeprom(hldev, 0, 0, 3))
1360 fail = 1;
1361
1362 /* Test Write at offset 4f0 */
1363 if (xge_hal_write_eeprom(hldev, 0x4F0, 0x01234567, 3))
1364 fail = 1;
1365 if (xge_hal_read_eeprom(hldev, 0x4F0, &ret_data))
1366 fail = 1;
1367
1368 if (ret_data != 0x01234567)
1369 fail = 1;
1370
1371 /* Reset the EEPROM data go FFFF */
1372 (void) xge_hal_write_eeprom(hldev, 0x4F0, 0xFFFFFFFF, 3);
1373
1374 /* Test Write Request Error at offset 0x7c */
1375 if (!xge_hal_write_eeprom(hldev, 0x07C, 0, 3))
1376 fail = 1;
1377
1378 /* Test Write Request at offset 0x7fc */
1379 if (xge_hal_write_eeprom(hldev, 0x7FC, 0x01234567, 3))
1380 fail = 1;
1381 if (xge_hal_read_eeprom(hldev, 0x7FC, &ret_data))
1382 fail = 1;
1383
1384 if (ret_data != 0x01234567)
1385 fail = 1;
1386
1387 /* Reset the EEPROM data go FFFF */
1388 (void) xge_hal_write_eeprom(hldev, 0x7FC, 0xFFFFFFFF, 3);
1389
1390 /* Test Write Error at offset 0x80 */
1391 if (!xge_hal_write_eeprom(hldev, 0x080, 0, 3))
1392 fail = 1;
1393
1394 /* Test Write Error at offset 0xfc */
1395 if (!xge_hal_write_eeprom(hldev, 0x0FC, 0, 3))
1396 fail = 1;
1397
1398 /* Test Write Error at offset 0x100 */
1399 if (!xge_hal_write_eeprom(hldev, 0x100, 0, 3))
1400 fail = 1;
1401
1402 /* Test Write Error at offset 4ec */
1403 if (!xge_hal_write_eeprom(hldev, 0x4EC, 0, 3))
1404 fail = 1;
1405
1406 *data = fail;
1407 return XGE_HAL_OK;
1408 }
1409
1410 /*
1411 * xge_hal_bist_test - invokes the MemBist test of the card .
1412 * @devh: HAL device handle.
1413 * xge_nic structure.
1414 * @data:variable that returns the result of each of the test conducted by
1415 * the driver.
1416 *
1417 * This invokes the MemBist test of the card. We give around
1418 * 2 secs time for the Test to complete. If it's still not complete
1419 * within this peiod, we consider that the test failed.
1420 * Return value:
1421 * 0 on success and -1 on failure.
1422 */
1423 xge_hal_status_e
xge_hal_bist_test(xge_hal_device_h devh,u64 * data)1424 xge_hal_bist_test(xge_hal_device_h devh, u64 *data)
1425 {
1426 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1427 u8 bist = 0;
1428 int cnt = 0;
1429 xge_hal_status_e ret = XGE_HAL_FAIL;
1430
1431 xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1432 bist |= 0x40;
1433 xge_os_pci_write8(hldev->pdev, hldev->cfgh, 0x0f, bist);
1434
1435 while (cnt < 20) {
1436 xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1437 if (!(bist & 0x40)) {
1438 *data = (bist & 0x0f);
1439 ret = XGE_HAL_OK;
1440 break;
1441 }
1442 xge_os_mdelay(100);
1443 cnt++;
1444 }
1445
1446 return ret;
1447 }
1448
1449 /*
1450 * xge_hal_link_test - verifies the link state of the nic
1451 * @devh: HAL device handle.
1452 * @data: variable that returns the result of each of the test conducted by
1453 * the driver.
1454 *
1455 * Verify the link state of the NIC and updates the input
1456 * argument 'data' appropriately.
1457 * Return value:
1458 * 0 on success.
1459 */
1460 xge_hal_status_e
xge_hal_link_test(xge_hal_device_h devh,u64 * data)1461 xge_hal_link_test(xge_hal_device_h devh, u64 *data)
1462 {
1463 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1464 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1465 u64 val64;
1466
1467 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1468 &bar0->adapter_status);
1469 if (val64 & XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)
1470 *data = 1;
1471
1472 return XGE_HAL_OK;
1473 }
1474
1475
1476 /**
1477 * xge_hal_getpause_data -Pause frame frame generation and reception.
1478 * @devh: HAL device handle.
1479 * @tx : A field to return the pause generation capability of the NIC.
1480 * @rx : A field to return the pause reception capability of the NIC.
1481 *
1482 * Returns the Pause frame generation and reception capability of the NIC.
1483 * Return value:
1484 * void
1485 */
xge_hal_getpause_data(xge_hal_device_h devh,int * tx,int * rx)1486 void xge_hal_getpause_data(xge_hal_device_h devh, int *tx, int *rx)
1487 {
1488 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1489 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1490 u64 val64;
1491
1492 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1493 &bar0->rmac_pause_cfg);
1494 if (val64 & XGE_HAL_RMAC_PAUSE_GEN_EN)
1495 *tx = 1;
1496 if (val64 & XGE_HAL_RMAC_PAUSE_RCV_EN)
1497 *rx = 1;
1498 }
1499
1500 /**
1501 * xge_hal_setpause_data - set/reset pause frame generation.
1502 * @devh: HAL device handle.
1503 * @tx: A field that indicates the pause generation capability to be
1504 * set on the NIC.
1505 * @rx: A field that indicates the pause reception capability to be
1506 * set on the NIC.
1507 *
1508 * It can be used to set or reset Pause frame generation or reception
1509 * support of the NIC.
1510 * Return value:
1511 * int, returns 0 on Success
1512 */
1513
xge_hal_setpause_data(xge_hal_device_h devh,int tx,int rx)1514 int xge_hal_setpause_data(xge_hal_device_h devh, int tx, int rx)
1515 {
1516 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1517 xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1518 u64 val64;
1519
1520 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1521 &bar0->rmac_pause_cfg);
1522 if (tx)
1523 val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
1524 else
1525 val64 &= ~XGE_HAL_RMAC_PAUSE_GEN_EN;
1526 if (rx)
1527 val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
1528 else
1529 val64 &= ~XGE_HAL_RMAC_PAUSE_RCV_EN;
1530 xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1531 val64, &bar0->rmac_pause_cfg);
1532 return 0;
1533 }
1534
1535 /**
1536 * xge_hal_read_xfp_current_temp -
1537 * @hldev: HAL device handle.
1538 *
1539 * This routine only gets the temperature for XFP modules. Also, updating of the
1540 * NVRAM can sometimes fail and so the reading we might get may not be uptodate.
1541 */
xge_hal_read_xfp_current_temp(xge_hal_device_h hldev)1542 u32 xge_hal_read_xfp_current_temp(xge_hal_device_h hldev)
1543 {
1544 u16 val_1, val_2, i = 0;
1545 u32 actual;
1546
1547 /* First update the NVRAM table of XFP. */
1548
1549 (void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000, 0x3);
1550
1551
1552 /* Now wait for the transfer to complete */
1553 do
1554 {
1555 xge_os_mdelay( 50 ); // wait 50 milliseonds
1556
1557 val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000);
1558
1559 if ( i++ > 10 )
1560 {
1561 // waited 500 ms which should be plenty of time.
1562 break;
1563 }
1564 }while (( val_1 & 0x000C ) != 0x0004);
1565
1566 /* Now NVRAM table of XFP should be updated, so read the temp */
1567 val_1 = (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8067);
1568 val_2 = (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8068);
1569
1570 actual = ((val_1 << 8) | val_2);
1571
1572 if (actual >= 32768)
1573 actual = actual- 65536;
1574 actual = actual/256;
1575
1576 return actual;
1577 }
1578
1579 /**
1580 * __hal_chk_xpak_counter - check the Xpak error count and log the msg.
1581 * @hldev: pointer to xge_hal_device_t structure
1582 * @type: xpak stats error type
1583 * @value: xpak stats value
1584 *
1585 * It is used to log the error message based on the xpak stats value
1586 * Return value:
1587 * None
1588 */
1589
__hal_chk_xpak_counter(xge_hal_device_t * hldev,int type,u32 value)1590 void __hal_chk_xpak_counter(xge_hal_device_t *hldev, int type, u32 value)
1591 {
1592 /*
1593 * If the value is high for three consecutive cylce,
1594 * log a error message
1595 */
1596 if(value == 3)
1597 {
1598 switch(type)
1599 {
1600 case 1:
1601 hldev->stats.sw_dev_err_stats.xpak_counter.
1602 excess_temp = 0;
1603
1604 /*
1605 * Notify the ULD on Excess Xpak temperature alarm msg
1606 */
1607 if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1608 g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1609 hldev->upper_layer_info,
1610 XGE_HAL_XPAK_ALARM_EXCESS_TEMP);
1611 }
1612 break;
1613 case 2:
1614 hldev->stats.sw_dev_err_stats.xpak_counter.
1615 excess_bias_current = 0;
1616
1617 /*
1618 * Notify the ULD on Excess xpak bias current alarm msg
1619 */
1620 if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1621 g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1622 hldev->upper_layer_info,
1623 XGE_HAL_XPAK_ALARM_EXCESS_BIAS_CURRENT);
1624 }
1625 break;
1626 case 3:
1627 hldev->stats.sw_dev_err_stats.xpak_counter.
1628 excess_laser_output = 0;
1629
1630 /*
1631 * Notify the ULD on Excess Xpak Laser o/p power
1632 * alarm msg
1633 */
1634 if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1635 g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1636 hldev->upper_layer_info,
1637 XGE_HAL_XPAK_ALARM_EXCESS_LASER_OUTPUT);
1638 }
1639 break;
1640 default:
1641 xge_debug_osdep(XGE_TRACE, "Incorrect XPAK Alarm "
1642 "type ");
1643 }
1644 }
1645
1646 }
1647
1648 /**
1649 * __hal_updt_stats_xpak - update the Xpak error count.
1650 * @hldev: pointer to xge_hal_device_t structure
1651 *
1652 * It is used to update the xpak stats value
1653 * Return value:
1654 * None
1655 */
__hal_updt_stats_xpak(xge_hal_device_t * hldev)1656 void __hal_updt_stats_xpak(xge_hal_device_t *hldev)
1657 {
1658 u16 val_1;
1659 u64 addr;
1660
1661 /* Check the communication with the MDIO slave */
1662 addr = 0x0000;
1663 val_1 = 0x0;
1664 val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1665 if((val_1 == 0xFFFF) || (val_1 == 0x0000))
1666 {
1667 xge_debug_osdep(XGE_TRACE, "ERR: MDIO slave access failed - "
1668 "Returned %x", val_1);
1669 return;
1670 }
1671
1672 /* Check for the expected value of 2040 at PMA address 0x0000 */
1673 if(val_1 != 0x2040)
1674 {
1675 xge_debug_osdep(XGE_TRACE, "Incorrect value at PMA address 0x0000 - ");
1676 xge_debug_osdep(XGE_TRACE, "Returned: %llx- Expected: 0x2040",
1677 (unsigned long long)(unsigned long)val_1);
1678 return;
1679 }
1680
1681 /* Loading the DOM register to MDIO register */
1682 addr = 0xA100;
1683 (void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr, 0x0);
1684 val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1685
1686 /*
1687 * Reading the Alarm flags
1688 */
1689 addr = 0xA070;
1690 val_1 = 0x0;
1691 val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1692 if(CHECKBIT(val_1, 0x7))
1693 {
1694 hldev->stats.sw_dev_err_stats.stats_xpak.
1695 alarm_transceiver_temp_high++;
1696 hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp++;
1697 __hal_chk_xpak_counter(hldev, 0x1,
1698 hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp);
1699 } else {
1700 hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp = 0;
1701 }
1702 if(CHECKBIT(val_1, 0x6))
1703 hldev->stats.sw_dev_err_stats.stats_xpak.
1704 alarm_transceiver_temp_low++;
1705
1706 if(CHECKBIT(val_1, 0x3))
1707 {
1708 hldev->stats.sw_dev_err_stats.stats_xpak.
1709 alarm_laser_bias_current_high++;
1710 hldev->stats.sw_dev_err_stats.xpak_counter.
1711 excess_bias_current++;
1712 __hal_chk_xpak_counter(hldev, 0x2,
1713 hldev->stats.sw_dev_err_stats.xpak_counter.
1714 excess_bias_current);
1715 } else {
1716 hldev->stats.sw_dev_err_stats.xpak_counter.
1717 excess_bias_current = 0;
1718 }
1719 if(CHECKBIT(val_1, 0x2))
1720 hldev->stats.sw_dev_err_stats.stats_xpak.
1721 alarm_laser_bias_current_low++;
1722
1723 if(CHECKBIT(val_1, 0x1))
1724 {
1725 hldev->stats.sw_dev_err_stats.stats_xpak.
1726 alarm_laser_output_power_high++;
1727 hldev->stats.sw_dev_err_stats.xpak_counter.
1728 excess_laser_output++;
1729 __hal_chk_xpak_counter(hldev, 0x3,
1730 hldev->stats.sw_dev_err_stats.xpak_counter.
1731 excess_laser_output);
1732 } else {
1733 hldev->stats.sw_dev_err_stats.xpak_counter.
1734 excess_laser_output = 0;
1735 }
1736 if(CHECKBIT(val_1, 0x0))
1737 hldev->stats.sw_dev_err_stats.stats_xpak.
1738 alarm_laser_output_power_low++;
1739
1740 /*
1741 * Reading the warning flags
1742 */
1743 addr = 0xA074;
1744 val_1 = 0x0;
1745 val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1746 if(CHECKBIT(val_1, 0x7))
1747 hldev->stats.sw_dev_err_stats.stats_xpak.
1748 warn_transceiver_temp_high++;
1749 if(CHECKBIT(val_1, 0x6))
1750 hldev->stats.sw_dev_err_stats.stats_xpak.
1751 warn_transceiver_temp_low++;
1752 if(CHECKBIT(val_1, 0x3))
1753 hldev->stats.sw_dev_err_stats.stats_xpak.
1754 warn_laser_bias_current_high++;
1755 if(CHECKBIT(val_1, 0x2))
1756 hldev->stats.sw_dev_err_stats.stats_xpak.
1757 warn_laser_bias_current_low++;
1758 if(CHECKBIT(val_1, 0x1))
1759 hldev->stats.sw_dev_err_stats.stats_xpak.
1760 warn_laser_output_power_high++;
1761 if(CHECKBIT(val_1, 0x0))
1762 hldev->stats.sw_dev_err_stats.stats_xpak.
1763 warn_laser_output_power_low++;
1764 }
1765