1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Copyright (c) 2002-2006 Neterion, Inc.
22 */
23
24/*
25 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26 * Use is subject to license terms.
27 */
28
29#include "xgehal-device.h"
30#include "xgehal-channel.h"
31#include "xgehal-fifo.h"
32#include "xgehal-ring.h"
33#include "xgehal-driver.h"
34#include "xgehal-mgmt.h"
35
36#define SWITCH_SIGN	0xA5A5A5A5A5A5A5A5ULL
37#define	END_SIGN	0x0
38
39#ifdef XGE_HAL_HERC_EMULATION
40#undef XGE_HAL_PROCESS_LINK_INT_IN_ISR
41#endif
42
43/*
44 * Jenkins hash key length(in bytes)
45 */
46#define XGE_HAL_JHASH_MSG_LEN 50
47
48/*
49 * mix(a,b,c) used in Jenkins hash algorithm
50 */
51#define mix(a,b,c) { \
52	a -= b; a -= c; a ^= (c>>13); \
53	b -= c; b -= a; b ^= (a<<8);  \
54	c -= a; c -= b; c ^= (b>>13); \
55	a -= b; a -= c; a ^= (c>>12); \
56	b -= c; b -= a; b ^= (a<<16); \
57	c -= a; c -= b; c ^= (b>>5);  \
58	a -= b; a -= c; a ^= (c>>3);  \
59	b -= c; b -= a; b ^= (a<<10); \
60	c -= a; c -= b; c ^= (b>>15); \
61}
62
63
64/*
65 * __hal_device_event_queued
66 * @data: pointer to xge_hal_device_t structure
67 *
68 * Will be called when new event succesfully queued.
69 */
70void
71__hal_device_event_queued(void *data, int event_type)
72{
73	xge_assert(((xge_hal_device_t*)data)->magic == XGE_HAL_MAGIC);
74	if (g_xge_hal_driver->uld_callbacks.event_queued) {
75		g_xge_hal_driver->uld_callbacks.event_queued(data, event_type);
76	}
77}
78
79/*
80 * __hal_pio_mem_write32_upper
81 *
82 * Endiann-aware implementation of xge_os_pio_mem_write32().
83 * Since Xframe has 64bit registers, we differintiate uppper and lower
84 * parts.
85 */
86void
87__hal_pio_mem_write32_upper(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
88{
89#if defined(XGE_OS_HOST_BIG_ENDIAN) && !defined(XGE_OS_PIO_LITTLE_ENDIAN)
90	xge_os_pio_mem_write32(pdev, regh, val, addr);
91#else
92	xge_os_pio_mem_write32(pdev, regh, val, (void *)((char *)addr + 4));
93#endif
94}
95
96/*
97 * __hal_pio_mem_write32_upper
98 *
99 * Endiann-aware implementation of xge_os_pio_mem_write32().
100 * Since Xframe has 64bit registers, we differintiate uppper and lower
101 * parts.
102 */
103void
104__hal_pio_mem_write32_lower(pci_dev_h pdev, pci_reg_h regh, u32 val,
105                            void *addr)
106{
107#if defined(XGE_OS_HOST_BIG_ENDIAN) && !defined(XGE_OS_PIO_LITTLE_ENDIAN)
108	xge_os_pio_mem_write32(pdev, regh, val,
109                               (void *) ((char *)addr +	4));
110#else
111	xge_os_pio_mem_write32(pdev, regh, val, addr);
112#endif
113}
114
115/*
116 * __hal_device_register_poll
117 * @hldev: pointer to xge_hal_device_t structure
118 * @reg: register to poll for
119 * @op: 0 - bit reset, 1 - bit set
120 * @mask: mask for logical "and" condition based on %op
121 * @max_millis: maximum time to try to poll in milliseconds
122 *
123 * Will poll certain register for specified amount of time.
124 * Will poll until masked bit is not cleared.
125 */
126xge_hal_status_e
127__hal_device_register_poll(xge_hal_device_t *hldev, u64 *reg,
128			   int op, u64 mask, int max_millis)
129{
130	u64 val64;
131	int i = 0;
132	xge_hal_status_e ret = XGE_HAL_FAIL;
133
134	xge_os_udelay(10);
135
136	do {
137		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, reg);
138		if (op == 0 && !(val64 & mask))
139			return XGE_HAL_OK;
140		else if (op == 1 && (val64 & mask) == mask)
141			return XGE_HAL_OK;
142		xge_os_udelay(100);
143	} while (++i <= 9);
144
145	do {
146		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, reg);
147		if (op == 0 && !(val64 & mask))
148			return XGE_HAL_OK;
149		else if (op == 1 && (val64 & mask) == mask)
150			return XGE_HAL_OK;
151		xge_os_udelay(1000);
152	} while (++i < max_millis);
153
154	return ret;
155}
156
157/*
158 * __hal_device_wait_quiescent
159 * @hldev: the device
160 * @hw_status: hw_status in case of error
161 *
162 * Will wait until device is quiescent for some blocks.
163 */
164static xge_hal_status_e
165__hal_device_wait_quiescent(xge_hal_device_t *hldev, u64 *hw_status)
166{
167	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
168
169	/* poll and wait first */
170#ifdef XGE_HAL_HERC_EMULATION
171	(void) __hal_device_register_poll(hldev, &bar0->adapter_status, 1,
172			(XGE_HAL_ADAPTER_STATUS_TDMA_READY |
173			 XGE_HAL_ADAPTER_STATUS_RDMA_READY |
174			 XGE_HAL_ADAPTER_STATUS_PFC_READY |
175			 XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY |
176			 XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT |
177			 XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY |
178			 XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY |
179			 XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK),
180			 XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS);
181#else
182	(void) __hal_device_register_poll(hldev, &bar0->adapter_status, 1,
183			(XGE_HAL_ADAPTER_STATUS_TDMA_READY |
184			 XGE_HAL_ADAPTER_STATUS_RDMA_READY |
185			 XGE_HAL_ADAPTER_STATUS_PFC_READY |
186			 XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY |
187			 XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT |
188			 XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY |
189			 XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY |
190			 XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK |
191			 XGE_HAL_ADAPTER_STATUS_P_PLL_LOCK),
192			 XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS);
193#endif
194
195	return xge_hal_device_status(hldev, hw_status);
196}
197
198/**
199 * xge_hal_device_is_slot_freeze
200 * @devh: the device
201 *
202 * Returns non-zero if the slot is freezed.
203 * The determination is made based on the adapter_status
204 * register which will never give all FFs, unless PCI read
205 * cannot go through.
206 */
207int
208xge_hal_device_is_slot_freeze(xge_hal_device_h devh)
209{
210	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
211	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
212	u16 device_id;
213	u64 adapter_status =
214		xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
215				      &bar0->adapter_status);
216	xge_os_pci_read16(hldev->pdev,hldev->cfgh,
217			xge_offsetof(xge_hal_pci_config_le_t, device_id),
218			&device_id);
219#ifdef TX_DEBUG
220	if (adapter_status == XGE_HAL_ALL_FOXES)
221	{
222		u64 dummy;
223		dummy = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
224						&bar0->pcc_enable);
225		printf(">>> Slot is frozen!\n");
226		brkpoint(0);
227	}
228#endif
229	return((adapter_status == XGE_HAL_ALL_FOXES) || (device_id == 0xffff));
230}
231
232
233/*
234 * __hal_device_led_actifity_fix
235 * @hldev: pointer to xge_hal_device_t structure
236 *
237 * SXE-002: Configure link and activity LED to turn it off
238 */
239static void
240__hal_device_led_actifity_fix(xge_hal_device_t *hldev)
241{
242	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
243	u16 subid;
244	u64 val64;
245
246	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
247		xge_offsetof(xge_hal_pci_config_le_t, subsystem_id), &subid);
248
249	/*
250	 *  In the case of Herc, there is a new register named beacon control
251	 *  is added which was not present in Xena.
252	 *  Beacon control register in Herc is at the same offset as
253	 *  gpio control register in Xena.  It means they are one and same in
254	 *  the case of Xena. Also, gpio control register offset in Herc and
255	 *  Xena is different.
256	 *  The current register map represents Herc(It means we have
257	 *  both beacon  and gpio control registers in register map).
258	 *  WRT transition from Xena to Herc, all the code in Xena which was
259	 *  using  gpio control register for LED handling would  have to
260	 *  use beacon control register in Herc and the rest of the code
261	 *  which uses gpio control in Xena  would use the same register
262	 *  in Herc.
263	 *  WRT LED handling(following code), In the case of Herc, beacon
264	 *  control register has to be used. This is applicable for Xena also,
265	 *  since it represents the gpio control register in Xena.
266	 */
267	if ((subid & 0xFF) >= 0x07) {
268		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
269		                            &bar0->beacon_control);
270		val64 |= 0x0000800000000000ULL;
271		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
272				     val64, &bar0->beacon_control);
273		val64 = 0x0411040400000000ULL;
274		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
275				    (void *) ((u8 *)bar0 + 0x2700));
276	}
277}
278
279/* Constants for Fixing the MacAddress problem seen mostly on
280 * Alpha machines.
281 */
282static u64 xena_fix_mac[] = {
283	0x0060000000000000ULL, 0x0060600000000000ULL,
284	0x0040600000000000ULL, 0x0000600000000000ULL,
285	0x0020600000000000ULL, 0x0060600000000000ULL,
286	0x0020600000000000ULL, 0x0060600000000000ULL,
287	0x0020600000000000ULL, 0x0060600000000000ULL,
288	0x0020600000000000ULL, 0x0060600000000000ULL,
289	0x0020600000000000ULL, 0x0060600000000000ULL,
290	0x0020600000000000ULL, 0x0060600000000000ULL,
291	0x0020600000000000ULL, 0x0060600000000000ULL,
292	0x0020600000000000ULL, 0x0060600000000000ULL,
293	0x0020600000000000ULL, 0x0060600000000000ULL,
294	0x0020600000000000ULL, 0x0060600000000000ULL,
295	0x0020600000000000ULL, 0x0000600000000000ULL,
296	0x0040600000000000ULL, 0x0060600000000000ULL,
297	END_SIGN
298};
299
300/*
301 * __hal_device_fix_mac
302 * @hldev: HAL device handle.
303 *
304 * Fix for all "FFs" MAC address problems observed on Alpha platforms.
305 */
306static void
307__hal_device_xena_fix_mac(xge_hal_device_t *hldev)
308{
309	int i = 0;
310	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
311
312	/*
313	 *  In the case of Herc, there is a new register named beacon control
314	 *  is added which was not present in Xena.
315	 *  Beacon control register in Herc is at the same offset as
316	 *  gpio control register in Xena.  It means they are one and same in
317	 *  the case of Xena. Also, gpio control register offset in Herc and
318	 *  Xena is different.
319	 *  The current register map represents Herc(It means we have
320	 *  both beacon  and gpio control registers in register map).
321	 *  WRT transition from Xena to Herc, all the code in Xena which was
322	 *  using  gpio control register for LED handling would  have to
323	 *  use beacon control register in Herc and the rest of the code
324	 *  which uses gpio control in Xena  would use the same register
325	 *  in Herc.
326	 *  In the following code(xena_fix_mac), beacon control register has
327	 *  to be used in the case of Xena, since it represents gpio control
328	 *  register. In the case of Herc, there is no change required.
329	 */
330	while (xena_fix_mac[i] != END_SIGN) {
331		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
332				xena_fix_mac[i++], &bar0->beacon_control);
333		xge_os_mdelay(1);
334	}
335}
336
337/*
338 * xge_hal_device_bcast_enable
339 * @hldev: HAL device handle.
340 *
341 * Enable receiving broadcasts.
342 * The host must first write RMAC_CFG_KEY "key"
343 * register, and then - MAC_CFG register.
344 */
345void
346xge_hal_device_bcast_enable(xge_hal_device_h devh)
347{
348	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
349	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
350	u64 val64;
351
352	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
353	&bar0->mac_cfg);
354		val64 |= XGE_HAL_MAC_RMAC_BCAST_ENABLE;
355
356	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
357		XGE_HAL_RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
358
359    __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
360		(u32)(val64 >> 32), &bar0->mac_cfg);
361
362	xge_debug_device(XGE_TRACE, "mac_cfg 0x"XGE_OS_LLXFMT": broadcast %s",
363		(unsigned long long)val64,
364		hldev->config.mac.rmac_bcast_en ? "enabled" : "disabled");
365}
366
367/*
368 * xge_hal_device_bcast_disable
369 * @hldev: HAL device handle.
370 *
371 * Disable receiving broadcasts.
372 * The host must first write RMAC_CFG_KEY "key"
373 * register, and then - MAC_CFG register.
374 */
375void
376xge_hal_device_bcast_disable(xge_hal_device_h devh)
377{
378	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
379	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
380	u64 val64;
381
382	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
383	&bar0->mac_cfg);
384
385	val64 &= ~(XGE_HAL_MAC_RMAC_BCAST_ENABLE);
386	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
387		     XGE_HAL_RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
388
389        __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
390		    (u32)(val64 >> 32), &bar0->mac_cfg);
391
392	xge_debug_device(XGE_TRACE, "mac_cfg 0x"XGE_OS_LLXFMT": broadcast %s",
393		(unsigned long long)val64,
394		hldev->config.mac.rmac_bcast_en ? "enabled" : "disabled");
395}
396
397/*
398 * __hal_device_shared_splits_configure
399 * @hldev: HAL device handle.
400 *
401 * TxDMA will stop Read request if the number of read split had exceeded
402 * the limit set by shared_splits
403 */
404static void
405__hal_device_shared_splits_configure(xge_hal_device_t *hldev)
406{
407	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
408	u64 val64;
409
410	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
411	                            &bar0->pic_control);
412	val64 |=
413	XGE_HAL_PIC_CNTL_SHARED_SPLITS(hldev->config.shared_splits);
414	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
415			     &bar0->pic_control);
416	xge_debug_device(XGE_TRACE, "%s", "shared splits configured");
417}
418
419/*
420 * __hal_device_rmac_padding_configure
421 * @hldev: HAL device handle.
422 *
423 * Configure RMAC frame padding. Depends on configuration, it
424 * can be send to host or removed by MAC.
425 */
426static void
427__hal_device_rmac_padding_configure(xge_hal_device_t *hldev)
428{
429	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
430	u64 val64;
431
432	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
433		    XGE_HAL_RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
434	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
435	&bar0->mac_cfg);
436	val64 &= ( ~XGE_HAL_MAC_RMAC_ALL_ADDR_ENABLE );
437	val64 &= ( ~XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE );
438	val64 |= XGE_HAL_MAC_CFG_TMAC_APPEND_PAD;
439
440	/*
441	 * If the RTH enable bit is not set, strip the FCS
442	 */
443	if (!hldev->config.rth_en ||
444	    !(xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
445			   &bar0->rts_rth_cfg) & XGE_HAL_RTS_RTH_EN)) {
446		val64 |= XGE_HAL_MAC_CFG_RMAC_STRIP_FCS;
447	}
448
449	val64 &= ( ~XGE_HAL_MAC_CFG_RMAC_STRIP_PAD );
450	val64 |= XGE_HAL_MAC_RMAC_DISCARD_PFRM;
451
452	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
453		    (u32)(val64 >> 32), (char*)&bar0->mac_cfg);
454	xge_os_mdelay(1);
455
456	xge_debug_device(XGE_TRACE,
457		  "mac_cfg 0x"XGE_OS_LLXFMT": frame padding configured",
458		  (unsigned long long)val64);
459}
460
461/*
462 * __hal_device_pause_frames_configure
463 * @hldev: HAL device handle.
464 *
465 * Set Pause threshold.
466 *
467 * Pause frame is generated if the amount of data outstanding
468 * on any queue exceeded the ratio of
469 * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256
470 */
471static void
472__hal_device_pause_frames_configure(xge_hal_device_t *hldev)
473{
474	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
475	int i;
476	u64 val64;
477
478	switch (hldev->config.mac.media) {
479		case XGE_HAL_MEDIA_SR:
480		case XGE_HAL_MEDIA_SW:
481			val64=0xfffbfffbfffbfffbULL;
482			break;
483		case XGE_HAL_MEDIA_LR:
484		case XGE_HAL_MEDIA_LW:
485			val64=0xffbbffbbffbbffbbULL;
486			break;
487		case XGE_HAL_MEDIA_ER:
488		case XGE_HAL_MEDIA_EW:
489		default:
490			val64=0xffbbffbbffbbffbbULL;
491			break;
492	}
493
494	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
495			val64, &bar0->mc_pause_thresh_q0q3);
496	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
497			val64, &bar0->mc_pause_thresh_q4q7);
498
499	/* Set the time value  to be inserted in the pause frame generated
500	 * by Xframe */
501	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
502	                            &bar0->rmac_pause_cfg);
503	if (hldev->config.mac.rmac_pause_gen_en)
504		val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
505	else
506		val64 &= ~(XGE_HAL_RMAC_PAUSE_GEN_EN);
507	if (hldev->config.mac.rmac_pause_rcv_en)
508		val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
509	else
510		val64 &= ~(XGE_HAL_RMAC_PAUSE_RCV_EN);
511	val64 &= ~(XGE_HAL_RMAC_PAUSE_HG_PTIME(0xffff));
512	val64 |= XGE_HAL_RMAC_PAUSE_HG_PTIME(hldev->config.mac.rmac_pause_time);
513	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
514			     &bar0->rmac_pause_cfg);
515
516	val64 = 0;
517	for (i = 0; i<4; i++) {
518		val64 |=
519		     (((u64)0xFF00|hldev->config.mac.mc_pause_threshold_q0q3)
520							<<(i*2*8));
521	}
522	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
523			     &bar0->mc_pause_thresh_q0q3);
524
525	val64 = 0;
526	for (i = 0; i<4; i++) {
527		val64 |=
528		     (((u64)0xFF00|hldev->config.mac.mc_pause_threshold_q4q7)
529							<<(i*2*8));
530	}
531	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
532			     &bar0->mc_pause_thresh_q4q7);
533	xge_debug_device(XGE_TRACE, "%s", "pause frames configured");
534}
535
536/*
537 * Herc's clock rate doubled, unless the slot is 33MHz.
538 */
539unsigned int __hal_fix_time_ival_herc(xge_hal_device_t *hldev,
540				      unsigned int time_ival)
541{
542	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
543		return time_ival;
544
545	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC);
546
547	if (hldev->bus_frequency != XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN &&
548	    hldev->bus_frequency != XGE_HAL_PCI_BUS_FREQUENCY_33MHZ)
549		time_ival *= 2;
550
551	return time_ival;
552}
553
554
555/*
556 * __hal_device_bus_master_disable
557 * @hldev: HAL device handle.
558 *
559 * Disable bus mastership.
560 */
561static void
562__hal_device_bus_master_disable (xge_hal_device_t *hldev)
563{
564	u16 cmd;
565	u16 bus_master = 4;
566
567	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
568			xge_offsetof(xge_hal_pci_config_le_t, command), &cmd);
569	cmd &= ~bus_master;
570	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
571			 xge_offsetof(xge_hal_pci_config_le_t, command), cmd);
572}
573
574/*
575 * __hal_device_bus_master_enable
576 * @hldev: HAL device handle.
577 *
578 * Disable bus mastership.
579 */
580static void
581__hal_device_bus_master_enable (xge_hal_device_t *hldev)
582{
583	u16 cmd;
584	u16 bus_master = 4;
585
586	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
587			xge_offsetof(xge_hal_pci_config_le_t, command), &cmd);
588
589	/* already enabled? do nothing */
590	if (cmd & bus_master)
591		return;
592
593	cmd |= bus_master;
594	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
595			 xge_offsetof(xge_hal_pci_config_le_t, command), cmd);
596}
597/*
598 * __hal_device_intr_mgmt
599 * @hldev: HAL device handle.
600 * @mask: mask indicating which Intr block must be modified.
601 * @flag: if true - enable, otherwise - disable interrupts.
602 *
603 * Disable or enable device interrupts. Mask is used to specify
604 * which hardware blocks should produce interrupts. For details
605 * please refer to Xframe User Guide.
606 */
607static void
608__hal_device_intr_mgmt(xge_hal_device_t *hldev, u64 mask, int flag)
609{
610	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
611	u64 val64 = 0, temp64 = 0;
612	u64 gim, gim_saved;
613
614	gim_saved = gim = xge_os_pio_mem_read64(hldev->pdev,
615                              hldev->regh0, &bar0->general_int_mask);
616
617	/* Top level interrupt classification */
618	/* PIC Interrupts */
619	if ((mask & (XGE_HAL_TX_PIC_INTR/* | XGE_HAL_RX_PIC_INTR*/))) {
620		/* Enable PIC Intrs in the general intr mask register */
621		val64 = XGE_HAL_TXPIC_INT_M/* | XGE_HAL_PIC_RX_INT_M*/;
622		if (flag) {
623			gim &= ~((u64) val64);
624			temp64 = xge_os_pio_mem_read64(hldev->pdev,
625					hldev->regh0, &bar0->pic_int_mask);
626
627			temp64 &= ~XGE_HAL_PIC_INT_TX;
628#ifdef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
629			if (xge_hal_device_check_id(hldev) ==
630							XGE_HAL_CARD_HERC) {
631				temp64 &= ~XGE_HAL_PIC_INT_MISC;
632			}
633#endif
634			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
635					     temp64, &bar0->pic_int_mask);
636#ifdef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
637			if (xge_hal_device_check_id(hldev) ==
638							XGE_HAL_CARD_HERC) {
639				/*
640				 * Unmask only Link Up interrupt
641				 */
642				temp64 = xge_os_pio_mem_read64(hldev->pdev,
643					hldev->regh0, &bar0->misc_int_mask);
644				temp64 &= ~XGE_HAL_MISC_INT_REG_LINK_UP_INT;
645				xge_os_pio_mem_write64(hldev->pdev,
646					      hldev->regh0, temp64,
647					      &bar0->misc_int_mask);
648				xge_debug_device(XGE_TRACE,
649					"unmask link up flag "XGE_OS_LLXFMT,
650					(unsigned long long)temp64);
651			}
652#endif
653		} else { /* flag == 0 */
654
655#ifdef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
656			if (xge_hal_device_check_id(hldev) ==
657							XGE_HAL_CARD_HERC) {
658				/*
659				 * Mask both Link Up and Down interrupts
660				 */
661				temp64 = xge_os_pio_mem_read64(hldev->pdev,
662					hldev->regh0, &bar0->misc_int_mask);
663				temp64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
664				temp64 |= XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
665				xge_os_pio_mem_write64(hldev->pdev,
666					      hldev->regh0, temp64,
667					      &bar0->misc_int_mask);
668				xge_debug_device(XGE_TRACE,
669					"mask link up/down flag "XGE_OS_LLXFMT,
670					(unsigned long long)temp64);
671			}
672#endif
673			/* Disable PIC Intrs in the general intr mask
674			 * register */
675			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
676					     XGE_HAL_ALL_INTRS_DIS,
677			                     &bar0->pic_int_mask);
678			gim |= val64;
679		}
680	}
681
682	/*  DMA Interrupts */
683	/*  Enabling/Disabling Tx DMA interrupts */
684	if (mask & XGE_HAL_TX_DMA_INTR) {
685		/*  Enable TxDMA Intrs in the general intr mask register */
686		val64 = XGE_HAL_TXDMA_INT_M;
687		if (flag) {
688			gim &= ~((u64) val64);
689			/* Enable all TxDMA interrupts */
690			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
691					     0x0, &bar0->txdma_int_mask);
692			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
693					     0x0, &bar0->pfc_err_mask);
694			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
695					     0x0, &bar0->tda_err_mask);
696			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
697					     0x0, &bar0->pcc_err_mask);
698			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
699					     0x0, &bar0->tti_err_mask);
700			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
701					     0x0, &bar0->lso_err_mask);
702			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
703					     0x0, &bar0->tpa_err_mask);
704			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
705					     0x0, &bar0->sm_err_mask);
706
707		} else { /* flag == 0 */
708
709			/*  Disable TxDMA Intrs in the general intr mask
710			 *  register */
711			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
712					     XGE_HAL_ALL_INTRS_DIS,
713			                     &bar0->txdma_int_mask);
714			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
715					     XGE_HAL_ALL_INTRS_DIS,
716			                     &bar0->pfc_err_mask);
717
718			gim |= val64;
719		}
720	}
721
722	/*  Enabling/Disabling Rx DMA interrupts */
723	if (mask & XGE_HAL_RX_DMA_INTR) {
724		/*  Enable RxDMA Intrs in the general intr mask register */
725		val64 = XGE_HAL_RXDMA_INT_M;
726		if (flag) {
727
728			gim &= ~((u64) val64);
729			/* All RxDMA block interrupts are disabled for now
730			 * TODO */
731			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
732					     XGE_HAL_ALL_INTRS_DIS,
733			                     &bar0->rxdma_int_mask);
734
735		} else { /* flag == 0 */
736
737			/*  Disable RxDMA Intrs in the general intr mask
738			 *  register */
739			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
740					     XGE_HAL_ALL_INTRS_DIS,
741			                     &bar0->rxdma_int_mask);
742
743			gim |= val64;
744		}
745	}
746
747	/*  MAC Interrupts */
748	/*  Enabling/Disabling MAC interrupts */
749	if (mask & (XGE_HAL_TX_MAC_INTR | XGE_HAL_RX_MAC_INTR)) {
750		val64 = XGE_HAL_TXMAC_INT_M | XGE_HAL_RXMAC_INT_M;
751		if (flag) {
752
753			gim &= ~((u64) val64);
754
755			/* All MAC block error inter. are disabled for now. */
756			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
757			     XGE_HAL_ALL_INTRS_DIS, &bar0->mac_int_mask);
758			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
759			     XGE_HAL_ALL_INTRS_DIS, &bar0->mac_rmac_err_mask);
760
761		} else { /* flag == 0 */
762
763			/* Disable MAC Intrs in the general intr mask
764			 * register */
765			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
766			     XGE_HAL_ALL_INTRS_DIS, &bar0->mac_int_mask);
767			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
768			     XGE_HAL_ALL_INTRS_DIS, &bar0->mac_rmac_err_mask);
769
770			gim |= val64;
771		}
772	}
773
774	/*  XGXS Interrupts */
775	if (mask & (XGE_HAL_TX_XGXS_INTR | XGE_HAL_RX_XGXS_INTR)) {
776		val64 = XGE_HAL_TXXGXS_INT_M | XGE_HAL_RXXGXS_INT_M;
777		if (flag) {
778
779			gim &= ~((u64) val64);
780			/* All XGXS block error interrupts are disabled for now
781			 * TODO */
782			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
783			     XGE_HAL_ALL_INTRS_DIS, &bar0->xgxs_int_mask);
784
785		} else { /* flag == 0 */
786
787			/* Disable MC Intrs in the general intr mask register */
788			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
789				XGE_HAL_ALL_INTRS_DIS, &bar0->xgxs_int_mask);
790
791			gim |= val64;
792		}
793	}
794
795	/*  Memory Controller(MC) interrupts */
796	if (mask & XGE_HAL_MC_INTR) {
797		val64 = XGE_HAL_MC_INT_M;
798		if (flag) {
799
800			gim &= ~((u64) val64);
801
802			/* Enable all MC blocks error interrupts */
803			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
804				     0x0ULL, &bar0->mc_int_mask);
805
806		} else { /* flag == 0 */
807
808			/* Disable MC Intrs in the general intr mask
809			 * register */
810			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
811				     XGE_HAL_ALL_INTRS_DIS, &bar0->mc_int_mask);
812
813			gim |= val64;
814		}
815	}
816
817
818	/*  Tx traffic interrupts */
819	if (mask & XGE_HAL_TX_TRAFFIC_INTR) {
820		val64 = XGE_HAL_TXTRAFFIC_INT_M;
821		if (flag) {
822
823			gim &= ~((u64) val64);
824
825			/* Enable all the Tx side interrupts */
826			/* '0' Enables all 64 TX interrupt levels. */
827			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x0,
828			                    &bar0->tx_traffic_mask);
829
830		} else { /* flag == 0 */
831
832			/* Disable Tx Traffic Intrs in the general intr mask
833			 * register. */
834			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
835			                     XGE_HAL_ALL_INTRS_DIS,
836			                     &bar0->tx_traffic_mask);
837			gim |= val64;
838		}
839	}
840
841	/*  Rx traffic interrupts */
842	if (mask & XGE_HAL_RX_TRAFFIC_INTR) {
843		val64 = XGE_HAL_RXTRAFFIC_INT_M;
844		if (flag) {
845			gim &= ~((u64) val64);
846			/* '0' Enables all 8 RX interrupt levels. */
847			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x0,
848			                    &bar0->rx_traffic_mask);
849
850		} else { /* flag == 0 */
851
852			/* Disable Rx Traffic Intrs in the general intr mask
853			 * register.
854			 */
855			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
856			                     XGE_HAL_ALL_INTRS_DIS,
857			                     &bar0->rx_traffic_mask);
858
859			gim |= val64;
860		}
861	}
862
863	/* Sched Timer interrupt */
864	if (mask & XGE_HAL_SCHED_INTR) {
865		if (flag) {
866			temp64 = xge_os_pio_mem_read64(hldev->pdev,
867					hldev->regh0, &bar0->txpic_int_mask);
868			temp64 &= ~XGE_HAL_TXPIC_INT_SCHED_INTR;
869			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
870					temp64, &bar0->txpic_int_mask);
871
872			xge_hal_device_sched_timer(hldev,
873					hldev->config.sched_timer_us,
874					hldev->config.sched_timer_one_shot);
875		} else {
876			temp64 = xge_os_pio_mem_read64(hldev->pdev,
877					hldev->regh0, &bar0->txpic_int_mask);
878			temp64 |= XGE_HAL_TXPIC_INT_SCHED_INTR;
879
880			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
881					temp64, &bar0->txpic_int_mask);
882
883			xge_hal_device_sched_timer(hldev,
884					XGE_HAL_SCHED_TIMER_DISABLED,
885					XGE_HAL_SCHED_TIMER_ON_SHOT_ENABLE);
886		}
887	}
888
889	if (gim != gim_saved) {
890		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, gim,
891			&bar0->general_int_mask);
892		xge_debug_device(XGE_TRACE, "general_int_mask updated "
893			 XGE_OS_LLXFMT" => "XGE_OS_LLXFMT,
894			(unsigned long long)gim_saved, (unsigned long long)gim);
895	}
896}
897
898/*
899 * __hal_device_bimodal_configure
900 * @hldev: HAL device handle.
901 *
902 * Bimodal parameters initialization.
903 */
904static void
905__hal_device_bimodal_configure(xge_hal_device_t *hldev)
906{
907	int i;
908
909	for (i=0; i<XGE_HAL_MAX_RING_NUM; i++) {
910		xge_hal_tti_config_t *tti;
911		xge_hal_rti_config_t *rti;
912
913		if (!hldev->config.ring.queue[i].configured)
914			continue;
915		rti = &hldev->config.ring.queue[i].rti;
916		tti = &hldev->bimodal_tti[i];
917
918		tti->enabled = 1;
919		tti->urange_a = hldev->bimodal_urange_a_en * 10;
920		tti->urange_b = 20;
921		tti->urange_c = 30;
922		tti->ufc_a = hldev->bimodal_urange_a_en * 8;
923		tti->ufc_b = 16;
924		tti->ufc_c = 32;
925		tti->ufc_d = 64;
926		tti->timer_val_us = hldev->bimodal_timer_val_us;
927		tti->timer_ac_en = 1;
928		tti->timer_ci_en = 0;
929
930		rti->urange_a = 10;
931		rti->urange_b = 20;
932		rti->urange_c = 30;
933		rti->ufc_a = 1; /* <= for netpipe type of tests */
934		rti->ufc_b = 4;
935		rti->ufc_c = 4;
936		rti->ufc_d = 4; /* <= 99% of a bandwidth traffic counts here */
937		rti->timer_ac_en = 1;
938		rti->timer_val_us = 5; /* for optimal bus efficiency usage */
939	}
940}
941
942/*
943 * __hal_device_tti_apply
944 * @hldev: HAL device handle.
945 *
946 * apply TTI configuration.
947 */
948static xge_hal_status_e
949__hal_device_tti_apply(xge_hal_device_t *hldev, xge_hal_tti_config_t *tti,
950		       int num, int runtime)
951{
952	u64 val64, data1 = 0, data2 = 0;
953	xge_hal_pci_bar0_t *bar0;
954
955	if (runtime)
956		bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
957	else
958		bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
959
960	if (tti->timer_val_us) {
961		unsigned int tx_interval;
962
963		if (hldev->config.pci_freq_mherz) {
964			tx_interval = hldev->config.pci_freq_mherz *
965					tti->timer_val_us / 64;
966			tx_interval =
967				__hal_fix_time_ival_herc(hldev,
968							 tx_interval);
969		} else {
970			tx_interval = tti->timer_val_us;
971		}
972		data1 |= XGE_HAL_TTI_DATA1_MEM_TX_TIMER_VAL(tx_interval);
973		if (tti->timer_ac_en) {
974			data1 |= XGE_HAL_TTI_DATA1_MEM_TX_TIMER_AC_EN;
975		}
976		if (tti->timer_ci_en) {
977			data1 |= XGE_HAL_TTI_DATA1_MEM_TX_TIMER_CI_EN;
978		}
979
980		if (!runtime) {
981			xge_debug_device(XGE_TRACE, "TTI[%d] timer enabled to %d, ci %s",
982				  num, tx_interval, tti->timer_ci_en ?
983				  "enabled": "disabled");
984		}
985	}
986
987	if (tti->urange_a ||
988	    tti->urange_b ||
989	    tti->urange_c ||
990	    tti->ufc_a ||
991	    tti->ufc_b ||
992	    tti->ufc_c ||
993	    tti->ufc_d ) {
994		data1 |= XGE_HAL_TTI_DATA1_MEM_TX_URNG_A(tti->urange_a) |
995			 XGE_HAL_TTI_DATA1_MEM_TX_URNG_B(tti->urange_b) |
996			 XGE_HAL_TTI_DATA1_MEM_TX_URNG_C(tti->urange_c);
997
998		data2 |= XGE_HAL_TTI_DATA2_MEM_TX_UFC_A(tti->ufc_a) |
999			 XGE_HAL_TTI_DATA2_MEM_TX_UFC_B(tti->ufc_b) |
1000			 XGE_HAL_TTI_DATA2_MEM_TX_UFC_C(tti->ufc_c) |
1001			 XGE_HAL_TTI_DATA2_MEM_TX_UFC_D(tti->ufc_d);
1002	}
1003
1004	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1005	    data1, &bar0->tti_data1_mem);
1006	(void)xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1007	    &bar0->tti_data1_mem);
1008	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1009	    data2, &bar0->tti_data2_mem);
1010	(void)xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1011	    &bar0->tti_data2_mem);
1012	xge_os_wmb();
1013
1014	val64 = XGE_HAL_TTI_CMD_MEM_WE | XGE_HAL_TTI_CMD_MEM_STROBE_NEW_CMD |
1015	      XGE_HAL_TTI_CMD_MEM_OFFSET(num);
1016	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1017		&bar0->tti_command_mem);
1018
1019	if (!runtime && __hal_device_register_poll(hldev, &bar0->tti_command_mem,
1020		   0, XGE_HAL_TTI_CMD_MEM_STROBE_NEW_CMD,
1021		   XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1022		/* upper layer may require to repeat */
1023		return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1024	}
1025
1026	if (!runtime) {
1027		xge_debug_device(XGE_TRACE, "TTI[%d] configured: tti_data1_mem 0x"
1028		   XGE_OS_LLXFMT, num,
1029		   (unsigned long long)xge_os_pio_mem_read64(hldev->pdev,
1030		   hldev->regh0, &bar0->tti_data1_mem));
1031	}
1032
1033	return XGE_HAL_OK;
1034}
1035
1036/*
1037 * __hal_device_tti_configure
1038 * @hldev: HAL device handle.
1039 *
1040 * TTI Initialization.
1041 * Initialize Transmit Traffic Interrupt Scheme.
1042 */
1043static xge_hal_status_e
1044__hal_device_tti_configure(xge_hal_device_t *hldev, int runtime)
1045{
1046	int i;
1047
1048	for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
1049		int j;
1050
1051		if (!hldev->config.fifo.queue[i].configured)
1052			continue;
1053
1054		for (j=0; j<XGE_HAL_MAX_FIFO_TTI_NUM; j++) {
1055			xge_hal_status_e status;
1056
1057			if (!hldev->config.fifo.queue[i].tti[j].enabled)
1058				continue;
1059
1060			/* at least some TTI enabled. Record it. */
1061			hldev->tti_enabled = 1;
1062
1063			status = __hal_device_tti_apply(hldev,
1064				&hldev->config.fifo.queue[i].tti[j],
1065				i * XGE_HAL_MAX_FIFO_TTI_NUM + j, runtime);
1066			if (status != XGE_HAL_OK)
1067				return status;
1068		}
1069	}
1070
1071	/* processing bimodal TTIs */
1072	for (i=0; i<XGE_HAL_MAX_RING_NUM; i++) {
1073		xge_hal_status_e status;
1074
1075		if (!hldev->bimodal_tti[i].enabled)
1076			continue;
1077
1078		/* at least some bimodal TTI enabled. Record it. */
1079		hldev->tti_enabled = 1;
1080
1081		status = __hal_device_tti_apply(hldev, &hldev->bimodal_tti[i],
1082				XGE_HAL_MAX_FIFO_TTI_RING_0 + i, runtime);
1083		if (status != XGE_HAL_OK)
1084			return status;
1085
1086	}
1087
1088	return XGE_HAL_OK;
1089}
1090
1091/*
1092 * __hal_device_rti_configure
1093 * @hldev: HAL device handle.
1094 *
1095 * RTI Initialization.
1096 * Initialize Receive Traffic Interrupt Scheme.
1097 */
1098xge_hal_status_e
1099__hal_device_rti_configure(xge_hal_device_t *hldev, int runtime)
1100{
1101	xge_hal_pci_bar0_t *bar0;
1102	u64 val64, data1 = 0, data2 = 0;
1103	int i;
1104
1105	if (runtime) {
1106		/*
1107		 * we don't want to re-configure RTI in case when
1108		 * bimodal interrupts are in use. Instead reconfigure TTI
1109		 * with new RTI values.
1110		 */
1111		if (hldev->config.bimodal_interrupts) {
1112			__hal_device_bimodal_configure(hldev);
1113			return __hal_device_tti_configure(hldev, 1);
1114		}
1115		bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
1116	} else
1117		bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1118
1119	for (i=0; i<XGE_HAL_MAX_RING_NUM; i++) {
1120		xge_hal_rti_config_t *rti = &hldev->config.ring.queue[i].rti;
1121
1122		if (!hldev->config.ring.queue[i].configured)
1123			continue;
1124
1125		if (rti->timer_val_us) {
1126			unsigned int rx_interval;
1127
1128			if (hldev->config.pci_freq_mherz) {
1129				rx_interval = hldev->config.pci_freq_mherz *
1130						rti->timer_val_us / 8;
1131				rx_interval =
1132					__hal_fix_time_ival_herc(hldev,
1133								 rx_interval);
1134			} else {
1135				rx_interval = rti->timer_val_us;
1136			}
1137			data1 |=XGE_HAL_RTI_DATA1_MEM_RX_TIMER_VAL(rx_interval);
1138			if (rti->timer_ac_en) {
1139				data1 |= XGE_HAL_RTI_DATA1_MEM_RX_TIMER_AC_EN;
1140			}
1141			data1 |= XGE_HAL_RTI_DATA1_MEM_RX_TIMER_CI_EN;
1142		}
1143
1144		if (rti->urange_a ||
1145		    rti->urange_b ||
1146		    rti->urange_c ||
1147		    rti->ufc_a ||
1148		    rti->ufc_b ||
1149		    rti->ufc_c ||
1150		    rti->ufc_d) {
1151			data1 |=XGE_HAL_RTI_DATA1_MEM_RX_URNG_A(rti->urange_a) |
1152				XGE_HAL_RTI_DATA1_MEM_RX_URNG_B(rti->urange_b) |
1153				XGE_HAL_RTI_DATA1_MEM_RX_URNG_C(rti->urange_c);
1154
1155			data2 |= XGE_HAL_RTI_DATA2_MEM_RX_UFC_A(rti->ufc_a) |
1156				 XGE_HAL_RTI_DATA2_MEM_RX_UFC_B(rti->ufc_b) |
1157				 XGE_HAL_RTI_DATA2_MEM_RX_UFC_C(rti->ufc_c) |
1158				 XGE_HAL_RTI_DATA2_MEM_RX_UFC_D(rti->ufc_d);
1159		}
1160
1161		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1162		    data1, &bar0->rti_data1_mem);
1163		(void)xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1164		    &bar0->rti_data1_mem);
1165		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1166		    data2, &bar0->rti_data2_mem);
1167		(void)xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1168		    &bar0->rti_data2_mem);
1169
1170		xge_os_wmb();
1171
1172		val64 = XGE_HAL_RTI_CMD_MEM_WE |
1173		XGE_HAL_RTI_CMD_MEM_STROBE_NEW_CMD;
1174		val64 |= XGE_HAL_RTI_CMD_MEM_OFFSET(i);
1175		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1176		                    &bar0->rti_command_mem);
1177
1178		if (!runtime && __hal_device_register_poll(hldev,
1179			&bar0->rti_command_mem, 0,
1180			XGE_HAL_RTI_CMD_MEM_STROBE_NEW_CMD,
1181			XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1182			/* upper layer may require to repeat */
1183			return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1184		}
1185
1186		if (!runtime) {
1187			xge_debug_device(XGE_TRACE,
1188			  "RTI[%d] configured: rti_data1_mem 0x"XGE_OS_LLXFMT,
1189			  i,
1190			  (unsigned long long)xge_os_pio_mem_read64(hldev->pdev,
1191					  hldev->regh0, &bar0->rti_data1_mem));
1192		}
1193	}
1194
1195	return XGE_HAL_OK;
1196}
1197
1198
1199/* Constants to be programmed into the Xena's registers to configure
1200 * the XAUI. */
1201static u64 default_xena_mdio_cfg[] = {
1202	/* Reset PMA PLL */
1203	0xC001010000000000ULL, 0xC0010100000000E0ULL,
1204	0xC0010100008000E4ULL,
1205	/* Remove Reset from PMA PLL */
1206	0xC001010000000000ULL, 0xC0010100000000E0ULL,
1207	0xC0010100000000E4ULL,
1208	END_SIGN
1209};
1210
1211static u64 default_herc_mdio_cfg[] = {
1212	END_SIGN
1213};
1214
1215static u64 default_xena_dtx_cfg[] = {
1216	0x8000051500000000ULL, 0x80000515000000E0ULL,
1217	0x80000515D93500E4ULL, 0x8001051500000000ULL,
1218	0x80010515000000E0ULL, 0x80010515001E00E4ULL,
1219	0x8002051500000000ULL, 0x80020515000000E0ULL,
1220	0x80020515F21000E4ULL,
1221	/* Set PADLOOPBACKN */
1222	0x8002051500000000ULL, 0x80020515000000E0ULL,
1223	0x80020515B20000E4ULL, 0x8003051500000000ULL,
1224	0x80030515000000E0ULL, 0x80030515B20000E4ULL,
1225	0x8004051500000000ULL, 0x80040515000000E0ULL,
1226	0x80040515B20000E4ULL, 0x8005051500000000ULL,
1227	0x80050515000000E0ULL, 0x80050515B20000E4ULL,
1228	SWITCH_SIGN,
1229	/* Remove PADLOOPBACKN */
1230	0x8002051500000000ULL, 0x80020515000000E0ULL,
1231	0x80020515F20000E4ULL, 0x8003051500000000ULL,
1232	0x80030515000000E0ULL, 0x80030515F20000E4ULL,
1233	0x8004051500000000ULL, 0x80040515000000E0ULL,
1234	0x80040515F20000E4ULL, 0x8005051500000000ULL,
1235	0x80050515000000E0ULL, 0x80050515F20000E4ULL,
1236	END_SIGN
1237};
1238
1239/*
1240static u64 default_herc_dtx_cfg[] = {
1241	0x80000515BA750000ULL, 0x80000515BA7500E0ULL,
1242	0x80000515BA750004ULL, 0x80000515BA7500E4ULL,
1243	0x80010515003F0000ULL, 0x80010515003F00E0ULL,
1244	0x80010515003F0004ULL, 0x80010515003F00E4ULL,
1245	0x80020515F2100000ULL, 0x80020515F21000E0ULL,
1246	0x80020515F2100004ULL, 0x80020515F21000E4ULL,
1247	END_SIGN
1248};
1249*/
1250
1251static u64 default_herc_dtx_cfg[] = {
1252    0x8000051536750000ULL, 0x80000515367500E0ULL,
1253    0x8000051536750004ULL, 0x80000515367500E4ULL,
1254
1255    0x80010515003F0000ULL, 0x80010515003F00E0ULL,
1256    0x80010515003F0004ULL, 0x80010515003F00E4ULL,
1257
1258    0x801205150D440000ULL, 0x801205150D4400E0ULL,
1259    0x801205150D440004ULL, 0x801205150D4400E4ULL,
1260
1261    0x80020515F2100000ULL, 0x80020515F21000E0ULL,
1262    0x80020515F2100004ULL, 0x80020515F21000E4ULL,
1263    END_SIGN
1264};
1265
1266
1267void
1268__hal_serial_mem_write64(xge_hal_device_t *hldev, u64 value, u64 *reg)
1269{
1270	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
1271		    (u32)(value>>32), reg);
1272	xge_os_wmb();
1273	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
1274		    (u32)value, reg);
1275	xge_os_wmb();
1276	xge_os_mdelay(1);
1277}
1278
1279u64
1280__hal_serial_mem_read64(xge_hal_device_t *hldev, u64 *reg)
1281{
1282	u64 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1283			reg);
1284	xge_os_mdelay(1);
1285	return val64;
1286}
1287
1288/*
1289 * __hal_device_xaui_configure
1290 * @hldev: HAL device handle.
1291 *
1292 * Configure XAUI Interface of Xena.
1293 *
1294 * To Configure the Xena's XAUI, one has to write a series
1295 * of 64 bit values into two registers in a particular
1296 * sequence. Hence a macro 'SWITCH_SIGN' has been defined
1297 * which will be defined in the array of configuration values
1298 * (default_dtx_cfg & default_mdio_cfg) at appropriate places
1299 * to switch writing from one regsiter to another. We continue
1300 * writing these values until we encounter the 'END_SIGN' macro.
1301 * For example, After making a series of 21 writes into
1302 * dtx_control register the 'SWITCH_SIGN' appears and hence we
1303 * start writing into mdio_control until we encounter END_SIGN.
1304 */
1305static void
1306__hal_device_xaui_configure(xge_hal_device_t *hldev)
1307{
1308	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1309	int mdio_cnt = 0, dtx_cnt = 0;
1310	u64 *default_dtx_cfg = NULL, *default_mdio_cfg = NULL;
1311
1312	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
1313		default_dtx_cfg = default_xena_dtx_cfg;
1314		default_mdio_cfg = default_xena_mdio_cfg;
1315	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
1316		default_dtx_cfg = default_herc_dtx_cfg;
1317		default_mdio_cfg = default_herc_mdio_cfg;
1318	} else {
1319		xge_assert(default_dtx_cfg);
1320    return;
1321  }
1322
1323	do {
1324	    dtx_cfg:
1325		while (default_dtx_cfg[dtx_cnt] != END_SIGN) {
1326			if (default_dtx_cfg[dtx_cnt] == SWITCH_SIGN) {
1327				dtx_cnt++;
1328				goto mdio_cfg;
1329			}
1330			__hal_serial_mem_write64(hldev, default_dtx_cfg[dtx_cnt],
1331					       &bar0->dtx_control);
1332			dtx_cnt++;
1333		}
1334	    mdio_cfg:
1335		while (default_mdio_cfg[mdio_cnt] != END_SIGN) {
1336			if (default_mdio_cfg[mdio_cnt] == SWITCH_SIGN) {
1337				mdio_cnt++;
1338				goto dtx_cfg;
1339			}
1340			__hal_serial_mem_write64(hldev, default_mdio_cfg[mdio_cnt],
1341				&bar0->mdio_control);
1342			mdio_cnt++;
1343		}
1344	} while ( !((default_dtx_cfg[dtx_cnt] == END_SIGN) &&
1345		    (default_mdio_cfg[mdio_cnt] == END_SIGN)) );
1346
1347	xge_debug_device(XGE_TRACE, "%s", "XAUI interface configured");
1348}
1349
1350/*
1351 * __hal_device_mac_link_util_set
1352 * @hldev: HAL device handle.
1353 *
1354 * Set sampling rate to calculate link utilization.
1355 */
1356static void
1357__hal_device_mac_link_util_set(xge_hal_device_t *hldev)
1358{
1359	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1360	u64 val64;
1361
1362	val64 = XGE_HAL_MAC_TX_LINK_UTIL_VAL(
1363			hldev->config.mac.tmac_util_period) |
1364		XGE_HAL_MAC_RX_LINK_UTIL_VAL(
1365			hldev->config.mac.rmac_util_period);
1366	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1367	                     &bar0->mac_link_util);
1368	xge_debug_device(XGE_TRACE, "%s",
1369			  "bandwidth link utilization configured");
1370}
1371
1372/*
1373 * __hal_device_set_swapper
1374 * @hldev: HAL device handle.
1375 *
1376 * Set the Xframe's byte "swapper" in accordance with
1377 * endianness of the host.
1378 */
1379xge_hal_status_e
1380__hal_device_set_swapper(xge_hal_device_t *hldev)
1381{
1382	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1383	u64 val64;
1384
1385	/*
1386	 * from 32bit errarta:
1387	 *
1388	 * The SWAPPER_CONTROL register determines how the adapter accesses
1389	 * host memory as well as how it responds to read and write requests
1390	 * from the host system. Writes to this register should be performed
1391	 * carefully, since the byte swappers could reverse the order of bytes.
1392	 * When configuring this register keep in mind that writes to the PIF
1393	 * read and write swappers could reverse the order of the upper and
1394	 * lower 32-bit words. This means that the driver may have to write
1395	 * to the upper 32 bits of the SWAPPER_CONTROL twice in order to
1396	 * configure the entire register. */
1397
1398	/*
1399	 * The device by default set to a big endian format, so a big endian
1400	 * driver need not set anything.
1401	 */
1402
1403#if defined(XGE_HAL_CUSTOM_HW_SWAPPER)
1404
1405	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1406			0xffffffffffffffffULL, &bar0->swapper_ctrl);
1407
1408	val64 = XGE_HAL_CUSTOM_HW_SWAPPER;
1409
1410	xge_os_wmb();
1411	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1412			     &bar0->swapper_ctrl);
1413
1414	xge_debug_device(XGE_TRACE, "using custom HW swapper 0x"XGE_OS_LLXFMT,
1415			(unsigned long long)val64);
1416
1417#elif !defined(XGE_OS_HOST_BIG_ENDIAN)
1418
1419	/*
1420	 * Initially we enable all bits to make it accessible by the driver,
1421	 * then we selectively enable only those bits that we want to set.
1422	 * i.e. force swapper to swap for the first time since second write
1423	 * will overwrite with the final settings.
1424	 *
1425	 * Use only for little endian platforms.
1426	 */
1427	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1428			0xffffffffffffffffULL, &bar0->swapper_ctrl);
1429	xge_os_wmb();
1430	val64 = (XGE_HAL_SWAPPER_CTRL_PIF_R_FE |
1431		 XGE_HAL_SWAPPER_CTRL_PIF_R_SE |
1432		 XGE_HAL_SWAPPER_CTRL_PIF_W_FE |
1433		 XGE_HAL_SWAPPER_CTRL_PIF_W_SE |
1434		 XGE_HAL_SWAPPER_CTRL_RTH_FE |
1435		 XGE_HAL_SWAPPER_CTRL_RTH_SE |
1436		 XGE_HAL_SWAPPER_CTRL_TXP_FE |
1437		 XGE_HAL_SWAPPER_CTRL_TXP_SE |
1438		 XGE_HAL_SWAPPER_CTRL_TXD_R_FE |
1439		 XGE_HAL_SWAPPER_CTRL_TXD_R_SE |
1440		 XGE_HAL_SWAPPER_CTRL_TXD_W_FE |
1441		 XGE_HAL_SWAPPER_CTRL_TXD_W_SE |
1442		 XGE_HAL_SWAPPER_CTRL_TXF_R_FE |
1443		 XGE_HAL_SWAPPER_CTRL_RXD_R_FE |
1444		 XGE_HAL_SWAPPER_CTRL_RXD_R_SE |
1445		 XGE_HAL_SWAPPER_CTRL_RXD_W_FE |
1446		 XGE_HAL_SWAPPER_CTRL_RXD_W_SE |
1447		 XGE_HAL_SWAPPER_CTRL_RXF_W_FE |
1448		 XGE_HAL_SWAPPER_CTRL_XMSI_FE |
1449		 XGE_HAL_SWAPPER_CTRL_STATS_FE | XGE_HAL_SWAPPER_CTRL_STATS_SE);
1450
1451	/*
1452	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
1453		 val64 |= XGE_HAL_SWAPPER_CTRL_XMSI_SE;
1454	} */
1455	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0, (u32)val64,
1456	                     &bar0->swapper_ctrl);
1457	xge_os_wmb();
1458	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, (u32)(val64>>32),
1459	                     &bar0->swapper_ctrl);
1460	xge_os_wmb();
1461	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, (u32)(val64>>32),
1462	                     &bar0->swapper_ctrl);
1463	xge_debug_device(XGE_TRACE, "%s", "using little endian set");
1464#endif
1465
1466	/*  Verifying if endian settings are accurate by reading a feedback
1467	 *  register.  */
1468	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1469	                            &bar0->pif_rd_swapper_fb);
1470	if (val64 != XGE_HAL_IF_RD_SWAPPER_FB) {
1471		xge_debug_device(XGE_ERR, "pif_rd_swapper_fb read "XGE_OS_LLXFMT,
1472			  (unsigned long long) val64);
1473		return XGE_HAL_ERR_SWAPPER_CTRL;
1474	}
1475
1476	xge_debug_device(XGE_TRACE, "%s", "be/le swapper enabled");
1477
1478	return XGE_HAL_OK;
1479}
1480
1481/*
1482 * __hal_device_rts_mac_configure - Configure RTS steering based on
1483 * destination mac address.
1484 * @hldev: HAL device handle.
1485 *
1486 */
1487xge_hal_status_e
1488__hal_device_rts_mac_configure(xge_hal_device_t *hldev)
1489{
1490	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1491	u64 val64;
1492
1493	if (!hldev->config.rts_mac_en) {
1494		return XGE_HAL_OK;
1495	}
1496
1497	/*
1498	* Set the receive traffic steering mode from default(classic)
1499	* to enhanced.
1500	*/
1501	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1502					&bar0->rts_ctrl);
1503	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
1504	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1505				val64, &bar0->rts_ctrl);
1506	return XGE_HAL_OK;
1507}
1508
1509/*
1510 * __hal_device_rts_port_configure - Configure RTS steering based on
1511 * destination or source port number.
1512 * @hldev: HAL device handle.
1513 *
1514 */
1515xge_hal_status_e
1516__hal_device_rts_port_configure(xge_hal_device_t *hldev)
1517{
1518	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1519	u64 val64;
1520	int rnum;
1521
1522	if (!hldev->config.rts_port_en) {
1523		return XGE_HAL_OK;
1524	}
1525
1526	/*
1527	 * Set the receive traffic steering mode from default(classic)
1528	 * to enhanced.
1529	 */
1530	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1531					&bar0->rts_ctrl);
1532	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
1533	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1534				val64, &bar0->rts_ctrl);
1535
1536	/*
1537	 * Initiate port steering according to per-ring configuration
1538	 */
1539	for (rnum = 0; rnum < XGE_HAL_MAX_RING_NUM; rnum++) {
1540		int pnum;
1541		xge_hal_ring_queue_t *queue = &hldev->config.ring.queue[rnum];
1542
1543		if (!queue->configured || queue->rts_port_en)
1544			continue;
1545
1546		for (pnum = 0; pnum < XGE_HAL_MAX_STEERABLE_PORTS; pnum++) {
1547			xge_hal_rts_port_t *port = &queue->rts_ports[pnum];
1548
1549			/*
1550			 * Skip and clear empty ports
1551			 */
1552			if (!port->num) {
1553				/*
1554				 * Clear CAM memory
1555				 */
1556				xge_os_pio_mem_write64(hldev->pdev,
1557				       hldev->regh0, 0ULL,
1558				       &bar0->rts_pn_cam_data);
1559
1560				val64 = BIT(7) | BIT(15);
1561			} else {
1562				/*
1563				 * Assign new Port values according
1564				 * to configuration
1565				 */
1566				val64 = vBIT(port->num,8,16) |
1567					vBIT(rnum,37,3) | BIT(63);
1568				if (port->src)
1569					val64 = BIT(47);
1570				if (!port->udp)
1571					val64 = BIT(7);
1572				xge_os_pio_mem_write64(hldev->pdev,
1573					       hldev->regh0, val64,
1574					       &bar0->rts_pn_cam_data);
1575
1576				val64 = BIT(7) | BIT(15) | vBIT(pnum,24,8);
1577			}
1578
1579			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1580					       val64, &bar0->rts_pn_cam_ctrl);
1581
1582			/* poll until done */
1583			if (__hal_device_register_poll(hldev,
1584			       &bar0->rts_pn_cam_ctrl, 0,
1585			       XGE_HAL_RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED,
1586			       XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) !=
1587								XGE_HAL_OK) {
1588				/* upper layer may require to repeat */
1589				return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1590			}
1591		}
1592	}
1593	return XGE_HAL_OK;
1594}
1595
1596/*
1597 * __hal_device_rts_qos_configure - Configure RTS steering based on
1598 * qos.
1599 * @hldev: HAL device handle.
1600 *
1601 */
1602xge_hal_status_e
1603__hal_device_rts_qos_configure(xge_hal_device_t *hldev)
1604{
1605	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1606	u64 val64;
1607	int j, rx_ring_num;
1608
1609	if (!hldev->config.rts_qos_en) {
1610		return XGE_HAL_OK;
1611	}
1612
1613	/* First clear the RTS_DS_MEM_DATA */
1614	val64 = 0;
1615	for (j = 0; j < 64; j++ )
1616	{
1617		/* First clear the value */
1618		val64 = XGE_HAL_RTS_DS_MEM_DATA(0);
1619
1620		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1621				       &bar0->rts_ds_mem_data);
1622
1623		val64 = XGE_HAL_RTS_DS_MEM_CTRL_WE |
1624			XGE_HAL_RTS_DS_MEM_CTRL_STROBE_NEW_CMD |
1625			XGE_HAL_RTS_DS_MEM_CTRL_OFFSET ( j );
1626
1627		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1628				       &bar0->rts_ds_mem_ctrl);
1629
1630
1631		/* poll until done */
1632		if (__hal_device_register_poll(hldev,
1633		       &bar0->rts_ds_mem_ctrl, 0,
1634		       XGE_HAL_RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
1635		       XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1636			/* upper layer may require to repeat */
1637			return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1638		}
1639
1640	}
1641
1642	rx_ring_num = 0;
1643	for (j = 0; j < XGE_HAL_MAX_RING_NUM; j++) {
1644		if (hldev->config.ring.queue[j].configured)
1645			rx_ring_num++;
1646	}
1647
1648	switch (rx_ring_num) {
1649	case 1:
1650		val64 = 0x0;
1651		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1652		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1653		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1654		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1655		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1656		break;
1657	case 2:
1658		val64 = 0x0001000100010001ULL;
1659		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1660		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1661		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1662		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1663		val64 = 0x0001000100000000ULL;
1664		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1665		break;
1666	case 3:
1667		val64 = 0x0001020001020001ULL;
1668		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1669		val64 = 0x0200010200010200ULL;
1670		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1671		val64 = 0x0102000102000102ULL;
1672		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1673		val64 = 0x0001020001020001ULL;
1674		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1675		val64 = 0x0200010200000000ULL;
1676		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1677		break;
1678	case 4:
1679		val64 = 0x0001020300010203ULL;
1680		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1681		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1682		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1683		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1684		val64 = 0x0001020300000000ULL;
1685		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1686		break;
1687	case 5:
1688		val64 = 0x0001020304000102ULL;
1689		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1690		val64 = 0x0304000102030400ULL;
1691		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1692		val64 = 0x0102030400010203ULL;
1693		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1694		val64 = 0x0400010203040001ULL;
1695		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1696		val64 = 0x0203040000000000ULL;
1697		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1698		break;
1699	case 6:
1700		val64 = 0x0001020304050001ULL;
1701		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1702		val64 = 0x0203040500010203ULL;
1703		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1704		val64 = 0x0405000102030405ULL;
1705		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1706		val64 = 0x0001020304050001ULL;
1707		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1708		val64 = 0x0203040500000000ULL;
1709		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1710		break;
1711	case 7:
1712		val64 = 0x0001020304050600ULL;
1713		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1714		val64 = 0x0102030405060001ULL;
1715		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1716		val64 = 0x0203040506000102ULL;
1717		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1718		val64 = 0x0304050600010203ULL;
1719		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1720		val64 = 0x0405060000000000ULL;
1721		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1722		break;
1723	case 8:
1724		val64 = 0x0001020304050607ULL;
1725		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1726		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1727		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1728		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1729		val64 = 0x0001020300000000ULL;
1730		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1731		break;
1732	}
1733
1734	return XGE_HAL_OK;
1735}
1736
1737/*
1738 * xge__hal_device_rts_mac_enable
1739 *
1740 * @devh: HAL device handle.
1741 * @index: index number where the MAC addr will be stored
1742 * @macaddr: MAC address
1743 *
1744 * - Enable RTS steering for the given MAC address. This function has to be
1745 * called with lock acquired.
1746 *
1747 * NOTE:
1748 * 1. ULD has to call this function with the index value which
1749 *    statisfies the following condition:
1750 *	ring_num = (index % 8)
1751 * 2.ULD also needs to make sure that the index is not
1752 *   occupied by any MAC address. If that index has any MAC address
1753 *   it will be overwritten and HAL will not check for it.
1754 *
1755 */
1756xge_hal_status_e
1757xge_hal_device_rts_mac_enable(xge_hal_device_h devh, int index, macaddr_t macaddr)
1758{
1759	int max_addr = XGE_HAL_MAX_MAC_ADDRESSES;
1760	xge_hal_status_e status;
1761
1762	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
1763
1764	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
1765		max_addr = XGE_HAL_MAX_MAC_ADDRESSES_HERC;
1766
1767	if ( index >= max_addr )
1768		return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
1769
1770	/*
1771	 * Set the MAC address at the given location marked by index.
1772	 */
1773	status = xge_hal_device_macaddr_set(hldev, index, macaddr);
1774	if (status != XGE_HAL_OK) {
1775		xge_debug_device(XGE_ERR, "%s",
1776			"Not able to set the mac addr");
1777		return status;
1778	}
1779
1780	return xge_hal_device_rts_section_enable(hldev, index);
1781}
1782
1783/*
1784 * xge__hal_device_rts_mac_disable
1785 * @hldev: HAL device handle.
1786 * @index: index number where to disable the MAC addr
1787 *
1788 * Disable RTS Steering based on the MAC address.
1789 * This function should be called with lock acquired.
1790 *
1791 */
1792xge_hal_status_e
1793xge_hal_device_rts_mac_disable(xge_hal_device_h devh, int index)
1794{
1795	xge_hal_status_e status;
1796	u8 macaddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1797	int max_addr = XGE_HAL_MAX_MAC_ADDRESSES;
1798
1799	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
1800
1801	xge_debug_ll(XGE_TRACE, "the index value is %d ", index);
1802
1803	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
1804		max_addr = XGE_HAL_MAX_MAC_ADDRESSES_HERC;
1805
1806	if ( index >= max_addr )
1807		return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
1808
1809	/*
1810	 * Disable MAC address @ given index location
1811	 */
1812	status = xge_hal_device_macaddr_set(hldev, index, macaddr);
1813	if (status != XGE_HAL_OK) {
1814		xge_debug_device(XGE_ERR, "%s",
1815			"Not able to set the mac addr");
1816		return status;
1817	}
1818
1819	return XGE_HAL_OK;
1820}
1821
1822
1823/*
1824 * __hal_device_rth_configure - Configure RTH for the device
1825 * @hldev: HAL device handle.
1826 *
1827 * Using IT (Indirection Table).
1828 */
1829xge_hal_status_e
1830__hal_device_rth_it_configure(xge_hal_device_t *hldev)
1831{
1832	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1833	u64 val64;
1834	int rings[XGE_HAL_MAX_RING_NUM]={0};
1835	int rnum;
1836	int rmax;
1837	int buckets_num;
1838	int bucket;
1839
1840	if (!hldev->config.rth_en) {
1841		return XGE_HAL_OK;
1842	}
1843
1844	/*
1845	 * Set the receive traffic steering mode from default(classic)
1846	 * to enhanced.
1847	 */
1848	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1849				      &bar0->rts_ctrl);
1850	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
1851	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1852			       val64, &bar0->rts_ctrl);
1853
1854	buckets_num = (1 << hldev->config.rth_bucket_size);
1855
1856	rmax=0;
1857	for (rnum = 0; rnum < XGE_HAL_MAX_RING_NUM; rnum++) {
1858		if (hldev->config.ring.queue[rnum].configured &&
1859				hldev->config.ring.queue[rnum].rth_en)
1860				rings[rmax++] = rnum;
1861	}
1862
1863	rnum = 0;
1864	/* for starters: fill in all the buckets with rings "equally" */
1865	for (bucket = 0; bucket < buckets_num; bucket++) {
1866
1867	    if (rnum == rmax)
1868           rnum = 0;
1869
1870		/* write data */
1871		val64 = XGE_HAL_RTS_RTH_MAP_MEM_DATA_ENTRY_EN |
1872		        XGE_HAL_RTS_RTH_MAP_MEM_DATA(rings[rnum]);
1873		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1874				     &bar0->rts_rth_map_mem_data);
1875
1876		/* execute */
1877		val64 = XGE_HAL_RTS_RTH_MAP_MEM_CTRL_WE |
1878			XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE |
1879			XGE_HAL_RTS_RTH_MAP_MEM_CTRL_OFFSET(bucket);
1880		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1881				     &bar0->rts_rth_map_mem_ctrl);
1882
1883		/* poll until done */
1884		if (__hal_device_register_poll(hldev,
1885			&bar0->rts_rth_map_mem_ctrl, 0,
1886			XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE,
1887			XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1888			return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1889		}
1890
1891        rnum++;
1892	}
1893
1894	val64 = XGE_HAL_RTS_RTH_EN;
1895	val64 |= XGE_HAL_RTS_RTH_BUCKET_SIZE(hldev->config.rth_bucket_size);
1896	val64 |= XGE_HAL_RTS_RTH_TCP_IPV4_EN | XGE_HAL_RTS_RTH_UDP_IPV4_EN | XGE_HAL_RTS_RTH_IPV4_EN |
1897			 XGE_HAL_RTS_RTH_TCP_IPV6_EN |XGE_HAL_RTS_RTH_UDP_IPV6_EN | XGE_HAL_RTS_RTH_IPV6_EN |
1898			 XGE_HAL_RTS_RTH_TCP_IPV6_EX_EN | XGE_HAL_RTS_RTH_UDP_IPV6_EX_EN | XGE_HAL_RTS_RTH_IPV6_EX_EN;
1899
1900	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1901			     &bar0->rts_rth_cfg);
1902
1903	xge_debug_device(XGE_TRACE, "RTH configured, bucket_size %d",
1904			  hldev->config.rth_bucket_size);
1905
1906	return XGE_HAL_OK;
1907}
1908
1909
1910/*
1911 * __hal_spdm_entry_add - Add a new entry to the SPDM table.
1912 *
1913 * Add a new entry to the SPDM table
1914 *
1915 * This function add a new entry to the SPDM table.
1916 *
1917 * Note:
1918 *   This function should be called with spdm_lock.
1919 *
1920 * See also: xge_hal_spdm_entry_add , xge_hal_spdm_entry_remove.
1921 */
1922static xge_hal_status_e
1923__hal_spdm_entry_add(xge_hal_device_t *hldev, xge_hal_ipaddr_t *src_ip,
1924		xge_hal_ipaddr_t *dst_ip, u16 l4_sp, u16 l4_dp, u8 is_tcp,
1925		u8 is_ipv4, u8 tgt_queue, u32 jhash_value, u16 spdm_entry)
1926{
1927	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1928	u64 val64;
1929	u64 spdm_line_arr[8];
1930	u8 line_no;
1931
1932	/*
1933	 * Clear the SPDM READY bit
1934	 */
1935	val64 = XGE_HAL_RX_PIC_INT_REG_SPDM_READY;
1936	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1937			       &bar0->rxpic_int_reg);
1938
1939	xge_debug_device(XGE_TRACE,
1940			"L4 SP %x:DP %x: hash %x tgt_queue %d ",
1941			l4_sp, l4_dp, jhash_value, tgt_queue);
1942
1943	xge_os_memzero(&spdm_line_arr, sizeof(spdm_line_arr));
1944
1945	/*
1946	 * Construct the SPDM entry.
1947	 */
1948	spdm_line_arr[0] = vBIT(l4_sp,0,16) |
1949			   vBIT(l4_dp,16,32) |
1950			   vBIT(tgt_queue,53,3)	|
1951			   vBIT(is_tcp,59,1) |
1952			   vBIT(is_ipv4,63,1);
1953
1954
1955	if (is_ipv4) {
1956		spdm_line_arr[1] = vBIT(src_ip->ipv4.addr,0,32) |
1957				   vBIT(dst_ip->ipv4.addr,32,32);
1958
1959	} else {
1960		xge_os_memcpy(&spdm_line_arr[1], &src_ip->ipv6.addr[0], 8);
1961		xge_os_memcpy(&spdm_line_arr[2], &src_ip->ipv6.addr[1], 8);
1962		xge_os_memcpy(&spdm_line_arr[3], &dst_ip->ipv6.addr[0], 8);
1963		xge_os_memcpy(&spdm_line_arr[4], &dst_ip->ipv6.addr[1], 8);
1964	}
1965
1966	spdm_line_arr[7] = vBIT(jhash_value,0,32) |
1967				BIT(63);  /* entry enable bit */
1968
1969	/*
1970	 * Add the entry to the SPDM table
1971	 */
1972	for(line_no = 0; line_no < 8; line_no++) {
1973		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1974				spdm_line_arr[line_no],
1975				(void *)((char *)hldev->spdm_mem_base +
1976						(spdm_entry * 64) +
1977						(line_no * 8)));
1978	}
1979
1980	/*
1981	 * Wait for the operation to be completed.
1982	 */
1983	if (__hal_device_register_poll(hldev, &bar0->rxpic_int_reg, 1,
1984			XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
1985			XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1986		return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1987	}
1988
1989	/*
1990	 * Add this information to a local SPDM table. The purpose of
1991	 * maintaining a local SPDM table is to avoid a search in the
1992	 * adapter SPDM table for spdm entry lookup which is very costly
1993	 * in terms of time.
1994	 */
1995	hldev->spdm_table[spdm_entry]->in_use = 1;
1996	xge_os_memcpy(&hldev->spdm_table[spdm_entry]->src_ip, src_ip,
1997		    sizeof(xge_hal_ipaddr_t));
1998	xge_os_memcpy(&hldev->spdm_table[spdm_entry]->dst_ip, dst_ip,
1999		    sizeof(xge_hal_ipaddr_t));
2000	hldev->spdm_table[spdm_entry]->l4_sp = l4_sp;
2001	hldev->spdm_table[spdm_entry]->l4_dp = l4_dp;
2002	hldev->spdm_table[spdm_entry]->is_tcp = is_tcp;
2003	hldev->spdm_table[spdm_entry]->is_ipv4 = is_ipv4;
2004	hldev->spdm_table[spdm_entry]->tgt_queue = tgt_queue;
2005	hldev->spdm_table[spdm_entry]->jhash_value = jhash_value;
2006	hldev->spdm_table[spdm_entry]->spdm_entry = spdm_entry;
2007
2008	return XGE_HAL_OK;
2009}
2010
2011/*
2012 * __hal_device_rth_spdm_configure - Configure RTH for the device
2013 * @hldev: HAL device handle.
2014 *
2015 * Using SPDM (Socket-Pair Direct Match).
2016 */
2017xge_hal_status_e
2018__hal_device_rth_spdm_configure(xge_hal_device_t *hldev)
2019{
2020	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
2021	u64 val64;
2022	u8 spdm_bar_num;
2023	u32 spdm_bar_offset;
2024	int spdm_table_size;
2025	int i;
2026
2027	if (!hldev->config.rth_spdm_en) {
2028		return XGE_HAL_OK;
2029	}
2030
2031	/*
2032	 * Retrieve the base address of SPDM Table.
2033	 */
2034	val64 = xge_os_pio_mem_read64(hldev->pdev,
2035			hldev->regh0, &bar0->spdm_bir_offset);
2036
2037	spdm_bar_num	= XGE_HAL_SPDM_PCI_BAR_NUM(val64);
2038	spdm_bar_offset	= XGE_HAL_SPDM_PCI_BAR_OFFSET(val64);
2039
2040
2041	/*
2042	 * spdm_bar_num specifies the PCI bar num register used to
2043	 * address the memory space. spdm_bar_offset specifies the offset
2044	 * of the SPDM memory with in the bar num memory space.
2045	 */
2046	switch (spdm_bar_num) {
2047		case 0:
2048		{
2049			hldev->spdm_mem_base = (char *)bar0 +
2050						(spdm_bar_offset * 8);
2051			break;
2052		}
2053		case 1:
2054		{
2055			char *bar1 = (char *)hldev->bar1;
2056			hldev->spdm_mem_base = bar1 + (spdm_bar_offset * 8);
2057			break;
2058		}
2059		default:
2060			xge_assert(((spdm_bar_num != 0) && (spdm_bar_num != 1)));
2061	}
2062
2063	/*
2064	 * Retrieve the size of SPDM table(number of entries).
2065	 */
2066	val64 = xge_os_pio_mem_read64(hldev->pdev,
2067			hldev->regh0, &bar0->spdm_structure);
2068	hldev->spdm_max_entries = XGE_HAL_SPDM_MAX_ENTRIES(val64);
2069
2070
2071	spdm_table_size = hldev->spdm_max_entries *
2072					sizeof(xge_hal_spdm_entry_t);
2073	if (hldev->spdm_table == NULL) {
2074		void *mem;
2075
2076		/*
2077		 * Allocate memory to hold the copy of SPDM table.
2078		 */
2079		if ((hldev->spdm_table = (xge_hal_spdm_entry_t **)
2080					xge_os_malloc(
2081					 hldev->pdev,
2082					 (sizeof(xge_hal_spdm_entry_t *) *
2083					 hldev->spdm_max_entries))) == NULL) {
2084			return XGE_HAL_ERR_OUT_OF_MEMORY;
2085		}
2086
2087		if ((mem = xge_os_malloc(hldev->pdev, spdm_table_size)) == NULL)
2088		{
2089			xge_os_free(hldev->pdev, hldev->spdm_table,
2090				  (sizeof(xge_hal_spdm_entry_t *) *
2091					 hldev->spdm_max_entries));
2092			return XGE_HAL_ERR_OUT_OF_MEMORY;
2093		}
2094
2095		xge_os_memzero(mem, spdm_table_size);
2096		for (i = 0; i < hldev->spdm_max_entries; i++) {
2097			hldev->spdm_table[i] = (xge_hal_spdm_entry_t *)
2098					((char *)mem +
2099					 i * sizeof(xge_hal_spdm_entry_t));
2100		}
2101		xge_os_spin_lock_init(&hldev->spdm_lock, hldev->pdev);
2102	} else {
2103		/*
2104		 * We are here because the host driver tries to
2105		 * do a soft reset on the device.
2106		 * Since the device soft reset clears the SPDM table, copy
2107		 * the entries from the local SPDM table to the actual one.
2108		 */
2109		xge_os_spin_lock(&hldev->spdm_lock);
2110		for (i = 0; i < hldev->spdm_max_entries; i++) {
2111			xge_hal_spdm_entry_t *spdm_entry = hldev->spdm_table[i];
2112
2113			if (spdm_entry->in_use) {
2114				if (__hal_spdm_entry_add(hldev,
2115							 &spdm_entry->src_ip,
2116							 &spdm_entry->dst_ip,
2117							 spdm_entry->l4_sp,
2118							 spdm_entry->l4_dp,
2119							 spdm_entry->is_tcp,
2120							 spdm_entry->is_ipv4,
2121							 spdm_entry->tgt_queue,
2122							 spdm_entry->jhash_value,
2123							 spdm_entry->spdm_entry)
2124						!= XGE_HAL_OK) {
2125					/* Log an warning */
2126					xge_debug_device(XGE_ERR,
2127						"SPDM table update from local"
2128						" memory failed");
2129				}
2130			}
2131		}
2132		xge_os_spin_unlock(&hldev->spdm_lock);
2133	}
2134
2135	/*
2136	 * Set the receive traffic steering mode from default(classic)
2137	 * to enhanced.
2138	 */
2139	val64 = xge_os_pio_mem_read64(hldev->pdev,
2140				    hldev->regh0, &bar0->rts_ctrl);
2141	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
2142	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2143			     val64, &bar0->rts_ctrl);
2144
2145	/*
2146	 * We may not need to configure rts_rth_jhash_cfg register as the
2147	 * default values are good enough to calculate the hash.
2148	 */
2149
2150	/*
2151	 * As of now, set all the rth mask registers to zero. TODO.
2152	 */
2153	for(i = 0; i < 5; i++) {
2154		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2155				     0, &bar0->rts_rth_hash_mask[i]);
2156	}
2157
2158	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2159			     0, &bar0->rts_rth_hash_mask_5);
2160
2161	if (hldev->config.rth_spdm_use_l4) {
2162		val64 = XGE_HAL_RTH_STATUS_SPDM_USE_L4;
2163		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2164				     val64, &bar0->rts_rth_status);
2165	}
2166
2167	val64 = XGE_HAL_RTS_RTH_EN;
2168	val64 |= XGE_HAL_RTS_RTH_IPV4_EN | XGE_HAL_RTS_RTH_TCP_IPV4_EN;
2169	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2170			     &bar0->rts_rth_cfg);
2171
2172
2173	return XGE_HAL_OK;
2174}
2175
2176/*
2177 * __hal_device_pci_init
2178 * @hldev: HAL device handle.
2179 *
2180 * Initialize certain PCI/PCI-X configuration registers
2181 * with recommended values. Save config space for future hw resets.
2182 */
2183static void
2184__hal_device_pci_init(xge_hal_device_t *hldev)
2185{
2186	int i, pcisize = 0;
2187	u16 cmd = 0;
2188	u8  val;
2189
2190	/* Store PCI device ID and revision for future references where in we
2191	 * decide Xena revision using PCI sub system ID */
2192	xge_os_pci_read16(hldev->pdev,hldev->cfgh,
2193			xge_offsetof(xge_hal_pci_config_le_t, device_id),
2194			&hldev->device_id);
2195	xge_os_pci_read8(hldev->pdev,hldev->cfgh,
2196			xge_offsetof(xge_hal_pci_config_le_t, revision),
2197			&hldev->revision);
2198
2199	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
2200		pcisize = XGE_HAL_PCISIZE_HERC;
2201	else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
2202		pcisize = XGE_HAL_PCISIZE_XENA;
2203
2204	/* save original PCI config space to restore it on device_terminate() */
2205	for (i = 0; i < pcisize; i++) {
2206		xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
2207		                (u32*)&hldev->pci_config_space_bios + i);
2208	}
2209
2210	/* Set the PErr Repconse bit and SERR in PCI command register. */
2211	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2212			xge_offsetof(xge_hal_pci_config_le_t, command), &cmd);
2213	cmd |= 0x140;
2214	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2215			 xge_offsetof(xge_hal_pci_config_le_t, command), cmd);
2216
2217	/* Set user spcecified value for the PCI Latency Timer */
2218	if (hldev->config.latency_timer &&
2219	    hldev->config.latency_timer != XGE_HAL_USE_BIOS_DEFAULT_LATENCY) {
2220		xge_os_pci_write8(hldev->pdev, hldev->cfgh,
2221	                 xge_offsetof(xge_hal_pci_config_le_t,
2222	                 latency_timer),
2223			 (u8)hldev->config.latency_timer);
2224	}
2225	/* Read back latency timer to reflect it into user level */
2226	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
2227		xge_offsetof(xge_hal_pci_config_le_t, latency_timer), &val);
2228	hldev->config.latency_timer = val;
2229
2230	/* Enable Data Parity Error Recovery in PCI-X command register. */
2231	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2232		xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
2233	cmd |= 1;
2234	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2235		 xge_offsetof(xge_hal_pci_config_le_t, pcix_command), cmd);
2236
2237	/* Set MMRB count in PCI-X command register. */
2238	if (hldev->config.mmrb_count != XGE_HAL_DEFAULT_BIOS_MMRB_COUNT) {
2239		cmd &= 0xFFF3;
2240		cmd |= hldev->config.mmrb_count << 2;
2241		xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2242		       xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2243		       cmd);
2244	}
2245	/* Read back MMRB count to reflect it into user level */
2246	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2247		        xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2248		        &cmd);
2249	cmd &= 0x000C;
2250	hldev->config.mmrb_count = cmd>>2;
2251
2252	/*  Setting Maximum outstanding splits based on system type. */
2253	if (hldev->config.max_splits_trans != XGE_HAL_USE_BIOS_DEFAULT_SPLITS)  {
2254		xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2255			xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2256			&cmd);
2257		cmd &= 0xFF8F;
2258		cmd |= hldev->config.max_splits_trans << 4;
2259		xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2260			xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2261			cmd);
2262	}
2263
2264	/* Read back max split trans to reflect it into user level */
2265	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2266		xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
2267	cmd &= 0x0070;
2268	hldev->config.max_splits_trans = cmd>>4;
2269
2270	/* Forcibly disabling relaxed ordering capability of the card. */
2271	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2272		xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
2273	cmd &= 0xFFFD;
2274	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2275		 xge_offsetof(xge_hal_pci_config_le_t, pcix_command), cmd);
2276
2277	/* save PCI config space for future resets */
2278	for (i = 0; i < pcisize; i++) {
2279		xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
2280		                (u32*)&hldev->pci_config_space + i);
2281	}
2282}
2283
2284/*
2285 * __hal_device_pci_info_get - Get PCI bus informations such as width, frequency
2286 *                               and mode.
2287 * @devh: HAL device handle.
2288 * @pci_mode:		pointer to a variable of enumerated type
2289 *			xge_hal_pci_mode_e{}.
2290 * @bus_frequency:	pointer to a variable of enumerated type
2291 *			xge_hal_pci_bus_frequency_e{}.
2292 * @bus_width:		pointer to a variable of enumerated type
2293 *			xge_hal_pci_bus_width_e{}.
2294 *
2295 * Get pci mode, frequency, and PCI bus width.
2296 *
2297 * Returns: one of the xge_hal_status_e{} enumerated types.
2298 * XGE_HAL_OK			- for success.
2299 * XGE_HAL_ERR_INVALID_PCI_INFO - for invalid PCI information from the card.
2300 * XGE_HAL_ERR_BAD_DEVICE_ID	- for invalid card.
2301 *
2302 * See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
2303 */
2304static xge_hal_status_e
2305__hal_device_pci_info_get(xge_hal_device_h devh, xge_hal_pci_mode_e *pci_mode,
2306		xge_hal_pci_bus_frequency_e *bus_frequency,
2307		xge_hal_pci_bus_width_e *bus_width)
2308{
2309	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
2310	xge_hal_status_e rc_status = XGE_HAL_OK;
2311	xge_hal_card_e card_id	   = xge_hal_device_check_id (devh);
2312
2313#ifdef XGE_HAL_HERC_EMULATION
2314	hldev->config.pci_freq_mherz =
2315		XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2316	*bus_frequency	=
2317		XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2318	*pci_mode = XGE_HAL_PCI_66MHZ_MODE;
2319#else
2320	if (card_id == XGE_HAL_CARD_HERC) {
2321		xge_hal_pci_bar0_t *bar0 =
2322		(xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2323		u64 pci_info = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2324				    &bar0->pci_info);
2325		if (XGE_HAL_PCI_32_BIT & pci_info)
2326			*bus_width = XGE_HAL_PCI_BUS_WIDTH_32BIT;
2327		else
2328			*bus_width = XGE_HAL_PCI_BUS_WIDTH_64BIT;
2329		switch((pci_info & XGE_HAL_PCI_INFO)>>60)
2330		{
2331			case XGE_HAL_PCI_33MHZ_MODE:
2332				 *bus_frequency	=
2333					 XGE_HAL_PCI_BUS_FREQUENCY_33MHZ;
2334				 *pci_mode = XGE_HAL_PCI_33MHZ_MODE;
2335				 break;
2336			case XGE_HAL_PCI_66MHZ_MODE:
2337				 *bus_frequency	=
2338					 XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2339				 *pci_mode = XGE_HAL_PCI_66MHZ_MODE;
2340				 break;
2341			case XGE_HAL_PCIX_M1_66MHZ_MODE:
2342				 *bus_frequency	=
2343					 XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2344				 *pci_mode = XGE_HAL_PCIX_M1_66MHZ_MODE;
2345				 break;
2346			case XGE_HAL_PCIX_M1_100MHZ_MODE:
2347				 *bus_frequency	=
2348					 XGE_HAL_PCI_BUS_FREQUENCY_100MHZ;
2349				 *pci_mode = XGE_HAL_PCIX_M1_100MHZ_MODE;
2350				 break;
2351			case XGE_HAL_PCIX_M1_133MHZ_MODE:
2352				 *bus_frequency	=
2353					 XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
2354				 *pci_mode = XGE_HAL_PCIX_M1_133MHZ_MODE;
2355				 break;
2356			case XGE_HAL_PCIX_M2_66MHZ_MODE:
2357				 *bus_frequency	=
2358					 XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
2359				 *pci_mode = XGE_HAL_PCIX_M2_66MHZ_MODE;
2360				 break;
2361			case XGE_HAL_PCIX_M2_100MHZ_MODE:
2362				 *bus_frequency	=
2363					 XGE_HAL_PCI_BUS_FREQUENCY_200MHZ;
2364				 *pci_mode = XGE_HAL_PCIX_M2_100MHZ_MODE;
2365				 break;
2366			case XGE_HAL_PCIX_M2_133MHZ_MODE:
2367				 *bus_frequency	=
2368					 XGE_HAL_PCI_BUS_FREQUENCY_266MHZ;
2369				 *pci_mode = XGE_HAL_PCIX_M2_133MHZ_MODE;
2370				  break;
2371			case XGE_HAL_PCIX_M1_RESERVED:
2372			case XGE_HAL_PCIX_M1_66MHZ_NS:
2373			case XGE_HAL_PCIX_M1_100MHZ_NS:
2374			case XGE_HAL_PCIX_M1_133MHZ_NS:
2375			case XGE_HAL_PCIX_M2_RESERVED:
2376			case XGE_HAL_PCIX_533_RESERVED:
2377			default:
2378				 rc_status = XGE_HAL_ERR_INVALID_PCI_INFO;
2379				 xge_debug_device(XGE_ERR,
2380					  "invalid pci info "XGE_OS_LLXFMT,
2381					 (unsigned long long)pci_info);
2382				 break;
2383		}
2384		if (rc_status != XGE_HAL_ERR_INVALID_PCI_INFO)
2385			xge_debug_device(XGE_TRACE, "PCI info: mode %d width "
2386				"%d frequency %d", *pci_mode, *bus_width,
2387				*bus_frequency);
2388		if (hldev->config.pci_freq_mherz ==
2389				XGE_HAL_DEFAULT_USE_HARDCODE) {
2390			hldev->config.pci_freq_mherz = *bus_frequency;
2391		}
2392	}
2393	/* for XENA, we report PCI mode, only. PCI bus frequency, and bus width
2394	 * are set to unknown */
2395	else if (card_id == XGE_HAL_CARD_XENA) {
2396		u32 pcix_status;
2397		u8 dev_num, bus_num;
2398		/* initialize defaults for XENA */
2399		*bus_frequency	= XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN;
2400		*bus_width	= XGE_HAL_PCI_BUS_WIDTH_UNKNOWN;
2401		xge_os_pci_read32(hldev->pdev, hldev->cfgh,
2402			xge_offsetof(xge_hal_pci_config_le_t, pcix_status),
2403			&pcix_status);
2404		dev_num = (u8)((pcix_status & 0xF8) >> 3);
2405		bus_num = (u8)((pcix_status & 0xFF00) >> 8);
2406		if (dev_num == 0 && bus_num == 0)
2407			*pci_mode = XGE_HAL_PCI_BASIC_MODE;
2408		else
2409			*pci_mode = XGE_HAL_PCIX_BASIC_MODE;
2410		xge_debug_device(XGE_TRACE, "PCI info: mode %d", *pci_mode);
2411		if (hldev->config.pci_freq_mherz ==
2412				XGE_HAL_DEFAULT_USE_HARDCODE) {
2413			/*
2414			 * There is no way to detect BUS frequency on Xena,
2415			 * so, in case of automatic configuration we hopelessly
2416			 * assume 133MHZ.
2417			 */
2418			hldev->config.pci_freq_mherz =
2419				XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
2420		}
2421	} else if (card_id == XGE_HAL_CARD_TITAN) {
2422		*bus_width = XGE_HAL_PCI_BUS_WIDTH_64BIT;
2423		*bus_frequency	= XGE_HAL_PCI_BUS_FREQUENCY_250MHZ;
2424		if (hldev->config.pci_freq_mherz ==
2425				XGE_HAL_DEFAULT_USE_HARDCODE) {
2426			hldev->config.pci_freq_mherz = *bus_frequency;
2427		}
2428	} else{
2429		rc_status =  XGE_HAL_ERR_BAD_DEVICE_ID;
2430		xge_debug_device(XGE_ERR, "invalid device id %d", card_id);
2431	}
2432#endif
2433
2434	return rc_status;
2435}
2436
2437/*
2438 * __hal_device_handle_link_up_ind
2439 * @hldev: HAL device handle.
2440 *
2441 * Link up indication handler. The function is invoked by HAL when
2442 * Xframe indicates that the link is up for programmable amount of time.
2443 */
2444static int
2445__hal_device_handle_link_up_ind(xge_hal_device_t *hldev)
2446{
2447	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2448	u64 val64;
2449
2450	/*
2451	 * If the previous link state is not down, return.
2452	 */
2453	if (hldev->link_state == XGE_HAL_LINK_UP) {
2454#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
2455		if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC){
2456			val64 = xge_os_pio_mem_read64(
2457				hldev->pdev, hldev->regh0,
2458				&bar0->misc_int_mask);
2459			val64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
2460			val64 &= ~XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
2461			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2462				val64, &bar0->misc_int_mask);
2463		}
2464#endif
2465		xge_debug_device(XGE_TRACE,
2466			"link up indication while link is up, ignoring..");
2467		return 0;
2468	}
2469
2470	/* Now re-enable it as due to noise, hardware turned it off */
2471	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2472				     &bar0->adapter_control);
2473	val64 |= XGE_HAL_ADAPTER_CNTL_EN;
2474	val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN); /* ECC enable */
2475	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2476			     &bar0->adapter_control);
2477
2478	/* Turn on the Laser */
2479	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2480				    &bar0->adapter_control);
2481	val64 = val64|(XGE_HAL_ADAPTER_EOI_TX_ON |
2482			XGE_HAL_ADAPTER_LED_ON);
2483	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2484			     &bar0->adapter_control);
2485
2486#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
2487	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2488	        val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2489				              &bar0->adapter_status);
2490	        if (val64 & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
2491		             XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) {
2492		        xge_debug_device(XGE_TRACE, "%s",
2493				          "fail to transition link to up...");
2494			return 0;
2495	        }
2496	        else {
2497		        /*
2498		         * Mask the Link Up interrupt and unmask the Link Down
2499		         * interrupt.
2500		         */
2501		        val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2502					              &bar0->misc_int_mask);
2503		        val64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
2504		        val64 &= ~XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
2505		        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2506				               &bar0->misc_int_mask);
2507		        xge_debug_device(XGE_TRACE, "calling link up..");
2508		        hldev->link_state = XGE_HAL_LINK_UP;
2509
2510		        /* notify ULD */
2511		        if (g_xge_hal_driver->uld_callbacks.link_up) {
2512			        g_xge_hal_driver->uld_callbacks.link_up(
2513					        hldev->upper_layer_info);
2514		        }
2515			return 1;
2516	        }
2517        }
2518#endif
2519	xge_os_mdelay(1);
2520	if (__hal_device_register_poll(hldev, &bar0->adapter_status, 0,
2521			(XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
2522			XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT),
2523			XGE_HAL_DEVICE_FAULT_WAIT_MAX_MILLIS) == XGE_HAL_OK) {
2524
2525		/* notify ULD */
2526		(void) xge_queue_produce_context(hldev->queueh,
2527						 XGE_HAL_EVENT_LINK_IS_UP, hldev);
2528		/* link is up after been enabled */
2529		return 1;
2530	} else {
2531		xge_debug_device(XGE_TRACE, "%s",
2532				  "fail to transition link to up...");
2533		return 0;
2534	}
2535}
2536
2537/*
2538 * __hal_device_handle_link_down_ind
2539 * @hldev: HAL device handle.
2540 *
2541 * Link down indication handler. The function is invoked by HAL when
2542 * Xframe indicates that the link is down.
2543 */
2544static int
2545__hal_device_handle_link_down_ind(xge_hal_device_t *hldev)
2546{
2547	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2548	u64 val64;
2549
2550	/*
2551	 * If the previous link state is not up, return.
2552	 */
2553	if (hldev->link_state == XGE_HAL_LINK_DOWN) {
2554#ifdef	XGE_HAL_PROCESS_LINK_INT_IN_ISR
2555		if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC){
2556			val64 = xge_os_pio_mem_read64(
2557				hldev->pdev, hldev->regh0,
2558				&bar0->misc_int_mask);
2559			val64 |= XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
2560			val64 &= ~XGE_HAL_MISC_INT_REG_LINK_UP_INT;
2561			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2562				val64, &bar0->misc_int_mask);
2563		}
2564#endif
2565		xge_debug_device(XGE_TRACE,
2566			"link down indication while link is down, ignoring..");
2567		return 0;
2568	}
2569	xge_os_mdelay(1);
2570
2571	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2572				      &bar0->adapter_control);
2573
2574	/* try to debounce the link only if the adapter is enabled. */
2575	if (val64 & XGE_HAL_ADAPTER_CNTL_EN) {
2576		if (__hal_device_register_poll(hldev, &bar0->adapter_status, 0,
2577			(XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
2578			XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT),
2579			XGE_HAL_DEVICE_FAULT_WAIT_MAX_MILLIS) == XGE_HAL_OK) {
2580			xge_debug_device(XGE_TRACE,
2581				"link is actually up (possible noisy link?), ignoring.");
2582			return(0);
2583		}
2584	}
2585
2586	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2587				    &bar0->adapter_control);
2588	/* turn off LED */
2589	val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
2590	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2591			       &bar0->adapter_control);
2592
2593#ifdef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
2594	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2595		/*
2596		 * Mask the Link Down interrupt and unmask the Link up
2597		 * interrupt
2598		 */
2599		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2600					      &bar0->misc_int_mask);
2601		val64 |= XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
2602		val64 &= ~XGE_HAL_MISC_INT_REG_LINK_UP_INT;
2603		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2604				       &bar0->misc_int_mask);
2605
2606		/* link is down */
2607		xge_debug_device(XGE_TRACE, "calling link down..");
2608		hldev->link_state = XGE_HAL_LINK_DOWN;
2609
2610		/* notify ULD */
2611		if (g_xge_hal_driver->uld_callbacks.link_down) {
2612				g_xge_hal_driver->uld_callbacks.link_down(
2613					hldev->upper_layer_info);
2614		}
2615		return 1;
2616	}
2617#endif
2618	/* notify ULD */
2619	(void) xge_queue_produce_context(hldev->queueh,
2620					 XGE_HAL_EVENT_LINK_IS_DOWN, hldev);
2621	/* link is down */
2622	return 1;
2623}
2624/*
2625 * __hal_device_handle_link_state_change
2626 * @hldev: HAL device handle.
2627 *
2628 * Link state change handler. The function is invoked by HAL when
2629 * Xframe indicates link state change condition. The code here makes sure to
2630 * 1) ignore redundant state change indications;
2631 * 2) execute link-up sequence, and handle the failure to bring the link up;
2632 * 3) generate XGE_HAL_LINK_UP/DOWN event for the subsequent handling by
2633 *    upper-layer driver (ULD).
2634 */
2635static int
2636__hal_device_handle_link_state_change(xge_hal_device_t *hldev)
2637{
2638	u64 hw_status;
2639	int hw_link_state;
2640	int retcode;
2641	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2642	u64 val64;
2643	int i = 0;
2644
2645	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2646					&bar0->adapter_control);
2647
2648	/* If the adapter is not enabled but the hal thinks we are in the up
2649	 * state then transition to the down state.
2650	 */
2651	if ( !(val64 & XGE_HAL_ADAPTER_CNTL_EN) &&
2652	     (hldev->link_state == XGE_HAL_LINK_UP) ) {
2653		return(__hal_device_handle_link_down_ind(hldev));
2654	}
2655
2656	do {
2657		xge_os_mdelay(1);
2658		(void) xge_hal_device_status(hldev, &hw_status);
2659		hw_link_state = (hw_status &
2660			(XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
2661				XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) ?
2662				XGE_HAL_LINK_DOWN : XGE_HAL_LINK_UP;
2663
2664		/* check if the current link state is still considered
2665		 * to be changed. This way we will make sure that this is
2666		 * not a noise which needs to be filtered out */
2667		if (hldev->link_state == hw_link_state)
2668			break;
2669	} while (i++ < hldev->config.link_valid_cnt);
2670
2671	/* If the current link state is same as previous, just return */
2672	if (hldev->link_state == hw_link_state)
2673		retcode = 0;
2674	/* detected state change */
2675	else if (hw_link_state == XGE_HAL_LINK_UP)
2676		retcode = __hal_device_handle_link_up_ind(hldev);
2677	else
2678		retcode = __hal_device_handle_link_down_ind(hldev);
2679	return retcode;
2680}
2681
2682/*
2683 *
2684 */
2685static void
2686__hal_device_handle_serr(xge_hal_device_t *hldev, char *reg, u64 value)
2687{
2688	hldev->stats.sw_dev_err_stats.serr_cnt++;
2689	if (hldev->config.dump_on_serr) {
2690#ifdef XGE_HAL_USE_MGMT_AUX
2691		(void) xge_hal_aux_device_dump(hldev);
2692#endif
2693	}
2694
2695	(void) xge_queue_produce(hldev->queueh, XGE_HAL_EVENT_SERR, hldev,
2696			   1, sizeof(u64), (void *)&value);
2697
2698	xge_debug_device(XGE_ERR, "%s: read "XGE_OS_LLXFMT, reg,
2699				  (unsigned long long) value);
2700}
2701
2702/*
2703 *
2704 */
2705static void
2706__hal_device_handle_eccerr(xge_hal_device_t *hldev, char *reg, u64 value)
2707{
2708	if (hldev->config.dump_on_eccerr) {
2709#ifdef XGE_HAL_USE_MGMT_AUX
2710		(void) xge_hal_aux_device_dump(hldev);
2711#endif
2712	}
2713
2714	/* Herc smart enough to recover on its own! */
2715	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
2716		(void) xge_queue_produce(hldev->queueh,
2717			XGE_HAL_EVENT_ECCERR, hldev,
2718			1, sizeof(u64), (void *)&value);
2719	}
2720
2721        xge_debug_device(XGE_ERR, "%s: read "XGE_OS_LLXFMT, reg,
2722                                  (unsigned long long) value);
2723}
2724
2725/*
2726 *
2727 */
2728static void
2729__hal_device_handle_parityerr(xge_hal_device_t *hldev, char *reg, u64 value)
2730{
2731	if (hldev->config.dump_on_parityerr) {
2732#ifdef XGE_HAL_USE_MGMT_AUX
2733		(void) xge_hal_aux_device_dump(hldev);
2734#endif
2735	}
2736	(void) xge_queue_produce_context(hldev->queueh,
2737			XGE_HAL_EVENT_PARITYERR, hldev);
2738
2739        xge_debug_device(XGE_ERR, "%s: read "XGE_OS_LLXFMT, reg,
2740                                  (unsigned long long) value);
2741}
2742
2743/*
2744 *
2745 */
2746static void
2747__hal_device_handle_targetabort(xge_hal_device_t *hldev)
2748{
2749	(void) xge_queue_produce_context(hldev->queueh,
2750			XGE_HAL_EVENT_TARGETABORT, hldev);
2751}
2752
2753
2754/*
2755 * __hal_device_hw_initialize
2756 * @hldev: HAL device handle.
2757 *
2758 * Initialize Xframe hardware.
2759 */
2760static xge_hal_status_e
2761__hal_device_hw_initialize(xge_hal_device_t *hldev)
2762{
2763	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2764	xge_hal_status_e status;
2765	u64 val64;
2766
2767	/* Set proper endian settings and verify the same by reading the PIF
2768	 * Feed-back register. */
2769	status = __hal_device_set_swapper(hldev);
2770	if (status != XGE_HAL_OK) {
2771		return status;
2772	}
2773
2774	/* update the pci mode, frequency, and width */
2775	if (__hal_device_pci_info_get(hldev, &hldev->pci_mode,
2776		&hldev->bus_frequency, &hldev->bus_width) != XGE_HAL_OK){
2777		hldev->pci_mode	= XGE_HAL_PCI_INVALID_MODE;
2778		hldev->bus_frequency = XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN;
2779		hldev->bus_width = XGE_HAL_PCI_BUS_WIDTH_UNKNOWN;
2780		/*
2781		 * FIXME: this cannot happen.
2782		 * But if it happens we cannot continue just like that
2783		 */
2784		xge_debug_device(XGE_ERR, "unable to get pci info");
2785	}
2786
2787	if ((hldev->pci_mode == XGE_HAL_PCI_33MHZ_MODE) ||
2788		(hldev->pci_mode == XGE_HAL_PCI_66MHZ_MODE) ||
2789		(hldev->pci_mode == XGE_HAL_PCI_BASIC_MODE)) {
2790		/* PCI optimization: set TxReqTimeOut
2791		 * register (0x800+0x120) to 0x1ff or
2792		 * something close to this.
2793		 * Note: not to be used for PCI-X! */
2794
2795		val64 = XGE_HAL_TXREQTO_VAL(0x1FF);
2796		val64 |= XGE_HAL_TXREQTO_EN;
2797		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2798				     &bar0->txreqtimeout);
2799
2800		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0ULL,
2801				     &bar0->read_retry_delay);
2802
2803		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0ULL,
2804				     &bar0->write_retry_delay);
2805
2806		xge_debug_device(XGE_TRACE, "%s", "optimizing for PCI mode");
2807	}
2808
2809	if (hldev->bus_frequency == XGE_HAL_PCI_BUS_FREQUENCY_266MHZ ||
2810	    hldev->bus_frequency == XGE_HAL_PCI_BUS_FREQUENCY_250MHZ) {
2811
2812		/* Optimizing for PCI-X 266/250 */
2813
2814		val64 = XGE_HAL_TXREQTO_VAL(0x7F);
2815		val64 |= XGE_HAL_TXREQTO_EN;
2816		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2817				     &bar0->txreqtimeout);
2818
2819		xge_debug_device(XGE_TRACE, "%s", "optimizing for PCI-X 266/250 modes");
2820	}
2821
2822	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2823		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x4000000000000ULL,
2824				     &bar0->read_retry_delay);
2825
2826		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x4000000000000ULL,
2827				     &bar0->write_retry_delay);
2828	}
2829
2830	/* added this to set the no of bytes used to update lso_bytes_sent
2831	   returned TxD0 */
2832	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2833				      &bar0->pic_control_2);
2834	val64 &= ~XGE_HAL_TXD_WRITE_BC(0x2);
2835	val64 |= XGE_HAL_TXD_WRITE_BC(0x4);
2836	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2837			       &bar0->pic_control_2);
2838	/* added this to clear the EOI_RESET field while leaving XGXS_RESET
2839	 * in reset, then a 1-second delay */
2840	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2841			XGE_HAL_SW_RESET_XGXS, &bar0->sw_reset);
2842	xge_os_mdelay(1000);
2843
2844	/* Clear the XGXS_RESET field of the SW_RESET register in order to
2845	 * release the XGXS from reset. Its reset value is 0xA5; write 0x00
2846	 * to activate the XGXS. The core requires a minimum 500 us reset.*/
2847        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0, &bar0->sw_reset);
2848	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2849				&bar0->sw_reset);
2850	xge_os_mdelay(1);
2851
2852	/* read registers in all blocks */
2853	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2854				   &bar0->mac_int_mask);
2855	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2856				   &bar0->mc_int_mask);
2857	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2858				   &bar0->xgxs_int_mask);
2859
2860	/* set default MTU and steer based on length*/
2861	__hal_ring_mtu_set(hldev, hldev->config.mtu+22); // Alway set 22 bytes extra for steering to work
2862
2863	if (hldev->config.mac.rmac_bcast_en) {
2864        xge_hal_device_bcast_enable(hldev);
2865	} else {
2866	    xge_hal_device_bcast_disable(hldev);
2867	}
2868
2869#ifndef XGE_HAL_HERC_EMULATION
2870	__hal_device_xaui_configure(hldev);
2871#endif
2872	__hal_device_mac_link_util_set(hldev);
2873
2874	__hal_device_mac_link_util_set(hldev);
2875
2876	/*
2877	 * Keep its PCI REQ# line asserted during a write
2878	 * transaction up to the end of the transaction
2879	 */
2880	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2881				&bar0->misc_control);
2882
2883	val64 |= XGE_HAL_MISC_CONTROL_EXT_REQ_EN;
2884
2885	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2886				val64, &bar0->misc_control);
2887
2888	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2889		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2890					&bar0->misc_control);
2891
2892		val64 |= XGE_HAL_MISC_CONTROL_LINK_FAULT;
2893
2894		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2895					val64, &bar0->misc_control);
2896	}
2897
2898	/*
2899	 * bimodal interrupts is when all Rx traffic interrupts
2900	 * will go to TTI, so we need to adjust RTI settings and
2901	 * use adaptive TTI timer. We need to make sure RTI is
2902	 * properly configured to sane value which will not
2903	 * distrupt bimodal behavior.
2904	 */
2905	if (hldev->config.bimodal_interrupts) {
2906		int i;
2907
2908		/* force polling_cnt to be "0", otherwise
2909		 * IRQ workload statistics will be screwed. This could
2910		 * be worked out in TXPIC handler later. */
2911		hldev->config.isr_polling_cnt = 0;
2912		hldev->config.sched_timer_us = 10000;
2913
2914		/* disable all TTI < 56 */
2915		for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
2916			int j;
2917			if (!hldev->config.fifo.queue[i].configured)
2918				continue;
2919			for (j=0; j<XGE_HAL_MAX_FIFO_TTI_NUM; j++) {
2920			    if (hldev->config.fifo.queue[i].tti[j].enabled)
2921				hldev->config.fifo.queue[i].tti[j].enabled = 0;
2922			}
2923		}
2924
2925		/* now configure bimodal interrupts */
2926		__hal_device_bimodal_configure(hldev);
2927	}
2928
2929	status = __hal_device_tti_configure(hldev, 0);
2930	if (status != XGE_HAL_OK)
2931		return status;
2932
2933	status = __hal_device_rti_configure(hldev, 0);
2934	if (status != XGE_HAL_OK)
2935		return status;
2936
2937	status = __hal_device_rth_it_configure(hldev);
2938	if (status != XGE_HAL_OK)
2939		return status;
2940
2941	status = __hal_device_rth_spdm_configure(hldev);
2942	if (status != XGE_HAL_OK)
2943		return status;
2944
2945	status = __hal_device_rts_mac_configure(hldev);
2946	if (status != XGE_HAL_OK) {
2947		xge_debug_device(XGE_ERR, "__hal_device_rts_mac_configure Failed ");
2948		return status;
2949	}
2950
2951	status = __hal_device_rts_port_configure(hldev);
2952	if (status != XGE_HAL_OK) {
2953		xge_debug_device(XGE_ERR, "__hal_device_rts_port_configure Failed ");
2954		return status;
2955	}
2956
2957	status = __hal_device_rts_qos_configure(hldev);
2958	if (status != XGE_HAL_OK) {
2959		xge_debug_device(XGE_ERR, "__hal_device_rts_qos_configure Failed ");
2960		return status;
2961	}
2962
2963	__hal_device_pause_frames_configure(hldev);
2964	__hal_device_rmac_padding_configure(hldev);
2965	__hal_device_shared_splits_configure(hldev);
2966
2967	/* make sure all interrupts going to be disabled at the moment */
2968	__hal_device_intr_mgmt(hldev, XGE_HAL_ALL_INTRS, 0);
2969
2970	/* SXE-008 Transmit DMA arbitration issue */
2971	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA &&
2972	    hldev->revision < 4) {
2973		xge_os_pio_mem_write64(hldev->pdev,hldev->regh0,
2974				XGE_HAL_ADAPTER_PCC_ENABLE_FOUR,
2975				&bar0->pcc_enable);
2976	}
2977	__hal_fifo_hw_initialize(hldev);
2978	__hal_ring_hw_initialize(hldev);
2979
2980	if (__hal_device_wait_quiescent(hldev, &val64)) {
2981		return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
2982	}
2983
2984	if (__hal_device_register_poll(hldev, &bar0->adapter_status, 1,
2985		XGE_HAL_ADAPTER_STATUS_RC_PRC_QUIESCENT,
2986		 XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
2987		xge_debug_device(XGE_TRACE, "%s", "PRC is not QUIESCENT!");
2988		return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
2989	}
2990
2991	xge_debug_device(XGE_TRACE, "device 0x"XGE_OS_LLXFMT" is quiescent",
2992			  (unsigned long long)(ulong_t)hldev);
2993
2994	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX ||
2995	    hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSI) {
2996		/*
2997		 * If MSI is enabled, ensure that One Shot for MSI in PCI_CTRL
2998		 * is disabled.
2999		 */
3000		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3001					    &bar0->pic_control);
3002		val64 &= ~(XGE_HAL_PIC_CNTL_ONE_SHOT_TINT);
3003		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
3004					    &bar0->pic_control);
3005	}
3006
3007	hldev->hw_is_initialized = 1;
3008	hldev->terminating = 0;
3009	return XGE_HAL_OK;
3010}
3011
3012/*
3013 * __hal_device_reset - Reset device only.
3014 * @hldev: HAL device handle.
3015 *
3016 * Reset the device, and subsequently restore
3017 * the previously saved PCI configuration space.
3018 */
3019#define XGE_HAL_MAX_PCI_CONFIG_SPACE_REINIT 50
3020static xge_hal_status_e
3021__hal_device_reset(xge_hal_device_t *hldev)
3022{
3023	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
3024	int i, j, swap_done, pcisize = 0;
3025	u64 val64, rawval = 0ULL;
3026
3027	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
3028		if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
3029			if ( hldev->bar2 ) {
3030			    u64 *msix_vetor_table = (u64 *)hldev->bar2;
3031
3032			    // 2 64bit words for each entry
3033			    for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2;
3034			         i++) {
3035			          hldev->msix_vector_table[i] =
3036				       xge_os_pio_mem_read64(hldev->pdev,
3037			                  hldev->regh2, &msix_vetor_table[i]);
3038			    }
3039			}
3040		}
3041	}
3042	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3043	                            &bar0->pif_rd_swapper_fb);
3044	swap_done = (val64 == XGE_HAL_IF_RD_SWAPPER_FB);
3045
3046	if (swap_done) {
3047		__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
3048		     (u32)(XGE_HAL_SW_RESET_ALL>>32), (char *)&bar0->sw_reset);
3049	} else {
3050		u32 val = (u32)(XGE_HAL_SW_RESET_ALL >> 32);
3051#if defined(XGE_OS_HOST_LITTLE_ENDIAN) || defined(XGE_OS_PIO_LITTLE_ENDIAN)
3052		/* swap it */
3053		val = (((val & (u32)0x000000ffUL) << 24) |
3054		       ((val & (u32)0x0000ff00UL) <<  8) |
3055		       ((val & (u32)0x00ff0000UL) >>  8) |
3056		       ((val & (u32)0xff000000UL) >> 24));
3057#endif
3058		xge_os_pio_mem_write32(hldev->pdev, hldev->regh0, val,
3059				     &bar0->sw_reset);
3060	}
3061
3062	pcisize = (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)?
3063			   XGE_HAL_PCISIZE_HERC : XGE_HAL_PCISIZE_XENA;
3064
3065	xge_os_mdelay(20); /* Wait for 20 ms after reset */
3066
3067	{
3068		/* Poll for no more than 1 second */
3069		for (i = 0; i < XGE_HAL_MAX_PCI_CONFIG_SPACE_REINIT; i++)
3070		{
3071			for (j = 0; j < pcisize; j++) {
3072				xge_os_pci_write32(hldev->pdev, hldev->cfgh, j * 4,
3073					*((u32*)&hldev->pci_config_space + j));
3074			}
3075
3076			xge_os_pci_read16(hldev->pdev,hldev->cfgh,
3077				xge_offsetof(xge_hal_pci_config_le_t, device_id),
3078				&hldev->device_id);
3079
3080			if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_UNKNOWN)
3081				break;
3082			xge_os_mdelay(20);
3083		}
3084	}
3085
3086	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_UNKNOWN)
3087	{
3088		xge_debug_device(XGE_ERR, "device reset failed");
3089			return XGE_HAL_ERR_RESET_FAILED;
3090	}
3091
3092	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
3093		int cnt = 0;
3094
3095		rawval = XGE_HAL_SW_RESET_RAW_VAL_HERC;
3096		pcisize = XGE_HAL_PCISIZE_HERC;
3097		xge_os_mdelay(1);
3098		do {
3099			val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3100				&bar0->sw_reset);
3101			if (val64 != rawval) {
3102				break;
3103			}
3104			cnt++;
3105			xge_os_mdelay(1); /* Wait for 1ms before retry */
3106		} while(cnt < 20);
3107	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
3108		rawval = XGE_HAL_SW_RESET_RAW_VAL_XENA;
3109		pcisize = XGE_HAL_PCISIZE_XENA;
3110		xge_os_mdelay(XGE_HAL_DEVICE_RESET_WAIT_MAX_MILLIS);
3111	}
3112
3113	/* Restore MSI-X vector table */
3114	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
3115		if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
3116			if ( hldev->bar2 ) {
3117			    /*
3118			     * 94: MSIXTable 00000004  ( BIR:4  Offset:0x0 )
3119			     * 98: PBATable  00000404  ( BIR:4  Offset:0x400 )
3120			     */
3121			     u64 *msix_vetor_table = (u64 *)hldev->bar2;
3122
3123			     /* 2 64bit words for each entry */
3124			     for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2;
3125				  i++) {
3126			         xge_os_pio_mem_write64(hldev->pdev,
3127					hldev->regh2,
3128					hldev->msix_vector_table[i],
3129					&msix_vetor_table[i]);
3130			     }
3131			}
3132		}
3133	}
3134
3135	hldev->link_state = XGE_HAL_LINK_DOWN;
3136	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3137                                      &bar0->sw_reset);
3138
3139	if (val64 != rawval) {
3140		xge_debug_device(XGE_ERR, "device has not been reset "
3141			"got 0x"XGE_OS_LLXFMT", expected 0x"XGE_OS_LLXFMT,
3142			(unsigned long long)val64, (unsigned long long)rawval);
3143	        return XGE_HAL_ERR_RESET_FAILED;
3144	}
3145
3146	hldev->hw_is_initialized = 0;
3147	return XGE_HAL_OK;
3148}
3149
3150/*
3151 * __hal_device_poll - General private routine to poll the device.
3152 * @hldev: HAL device handle.
3153 *
3154 * Returns: one of the xge_hal_status_e{} enumerated types.
3155 * XGE_HAL_OK			- for success.
3156 * XGE_HAL_ERR_CRITICAL         - when encounters critical error.
3157 */
3158static xge_hal_status_e
3159__hal_device_poll(xge_hal_device_t *hldev)
3160{
3161	xge_hal_pci_bar0_t *bar0;
3162	u64 err_reg;
3163
3164	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
3165
3166	/* Handling SERR errors by forcing a H/W reset. */
3167	err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3168				      &bar0->serr_source);
3169	if (err_reg & XGE_HAL_SERR_SOURCE_ANY) {
3170		__hal_device_handle_serr(hldev, "serr_source", err_reg);
3171		return XGE_HAL_ERR_CRITICAL;
3172	}
3173
3174	err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3175					&bar0->misc_int_reg);
3176
3177	if (err_reg & XGE_HAL_MISC_INT_REG_DP_ERR_INT) {
3178		hldev->stats.sw_dev_err_stats.parity_err_cnt++;
3179		__hal_device_handle_parityerr(hldev, "misc_int_reg", err_reg);
3180		return XGE_HAL_ERR_CRITICAL;
3181	}
3182
3183#ifdef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
3184	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) ||
3185		(hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX))
3186#endif
3187	{
3188
3189		/* Handling link status change error Intr */
3190		err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3191						&bar0->mac_rmac_err_reg);
3192		if (__hal_device_handle_link_state_change(hldev))
3193			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3194				       err_reg, &bar0->mac_rmac_err_reg);
3195	}
3196
3197	if (hldev->inject_serr != 0) {
3198		err_reg = hldev->inject_serr;
3199		hldev->inject_serr = 0;
3200		__hal_device_handle_serr(hldev, "inject_serr", err_reg);
3201		return XGE_HAL_ERR_CRITICAL;
3202        }
3203
3204        if (hldev->inject_ecc != 0) {
3205                err_reg = hldev->inject_ecc;
3206                hldev->inject_ecc = 0;
3207		hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
3208                __hal_device_handle_eccerr(hldev, "inject_ecc", err_reg);
3209		return XGE_HAL_ERR_CRITICAL;
3210        }
3211
3212	if (hldev->inject_bad_tcode != 0) {
3213		u8 t_code = hldev->inject_bad_tcode;
3214		xge_hal_channel_t channel;
3215		xge_hal_fifo_txd_t txd;
3216		xge_hal_ring_rxd_1_t rxd;
3217
3218		channel.devh =  hldev;
3219
3220		if (hldev->inject_bad_tcode_for_chan_type ==
3221						XGE_HAL_CHANNEL_TYPE_FIFO) {
3222			channel.type = XGE_HAL_CHANNEL_TYPE_FIFO;
3223
3224		} else {
3225			channel.type = XGE_HAL_CHANNEL_TYPE_RING;
3226		}
3227
3228                hldev->inject_bad_tcode = 0;
3229
3230		if (channel.type == XGE_HAL_CHANNEL_TYPE_FIFO)
3231			return xge_hal_device_handle_tcode(&channel, &txd,
3232			                                   t_code);
3233		else
3234			return xge_hal_device_handle_tcode(&channel, &rxd,
3235			                                   t_code);
3236        }
3237
3238	return XGE_HAL_OK;
3239}
3240
3241/*
3242 * __hal_verify_pcc_idle - Verify All Enbled PCC are IDLE or not
3243 * @hldev: HAL device handle.
3244 * @adp_status: Adapter Status value
3245 * Usage: See xge_hal_device_enable{}.
3246 */
3247xge_hal_status_e
3248__hal_verify_pcc_idle(xge_hal_device_t *hldev, u64 adp_status)
3249{
3250	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA &&
3251	    hldev->revision < 4) {
3252		/*
3253		 * For Xena 1,2,3 we enable only 4 PCCs Due to
3254		 * SXE-008 (Transmit DMA arbitration issue)
3255		 */
3256		if ((adp_status & XGE_HAL_ADAPTER_STATUS_RMAC_PCC_4_IDLE)
3257			!= XGE_HAL_ADAPTER_STATUS_RMAC_PCC_4_IDLE) {
3258			xge_debug_device(XGE_TRACE, "%s",
3259			    "PCC is not IDLE after adapter enabled!");
3260			return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
3261		}
3262	} else {
3263		if ((adp_status & XGE_HAL_ADAPTER_STATUS_RMAC_PCC_IDLE) !=
3264			XGE_HAL_ADAPTER_STATUS_RMAC_PCC_IDLE) {
3265			xge_debug_device(XGE_TRACE, "%s",
3266			"PCC is not IDLE after adapter enabled!");
3267			return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
3268		}
3269	}
3270	return XGE_HAL_OK;
3271}
3272
3273static void
3274__hal_update_bimodal(xge_hal_device_t *hldev, int ring_no)
3275{
3276	int tval, d, iwl_avg, len_avg, bytes_avg, bytes_hist, d_hist;
3277	int iwl_rxcnt, iwl_txcnt, iwl_txavg, len_rxavg, iwl_rxavg, len_txavg;
3278	int iwl_cnt, i;
3279
3280#define _HIST_SIZE	50 /* 0.5 sec history */
3281#define _HIST_ADJ_TIMER	1
3282#define _STEP		2
3283
3284	static int bytes_avg_history[_HIST_SIZE] = {0};
3285	static int d_avg_history[_HIST_SIZE] = {0};
3286	static int history_idx = 0;
3287	static int pstep = 1;
3288	static int hist_adj_timer = 0;
3289
3290	/*
3291	 * tval - current value of this bimodal timer
3292	 */
3293	tval = hldev->bimodal_tti[ring_no].timer_val_us;
3294
3295	/*
3296	 * d - how many interrupts we were getting since last
3297	 *     bimodal timer tick.
3298	 */
3299	d = hldev->stats.sw_dev_info_stats.tx_traffic_intr_cnt -
3300		hldev->bimodal_intr_cnt;
3301
3302	/* advance bimodal interrupt counter */
3303	hldev->bimodal_intr_cnt =
3304		hldev->stats.sw_dev_info_stats.tx_traffic_intr_cnt;
3305
3306	/*
3307	 * iwl_cnt - how many interrupts we've got since last
3308	 *           bimodal timer tick.
3309	 */
3310	iwl_rxcnt = (hldev->irq_workload_rxcnt[ring_no] ?
3311                     hldev->irq_workload_rxcnt[ring_no] : 1);
3312	iwl_txcnt = (hldev->irq_workload_txcnt[ring_no] ?
3313                     hldev->irq_workload_txcnt[ring_no] : 1);
3314	iwl_cnt = iwl_rxcnt + iwl_txcnt;
3315	iwl_cnt = iwl_cnt; /* just to remove the lint warning */
3316
3317	/*
3318	 * we need to take hldev->config.isr_polling_cnt into account
3319	 * but for some reason this line causing GCC to produce wrong
3320	 * code on Solaris. As of now, if bimodal_interrupts is configured
3321	 * hldev->config.isr_polling_cnt is forced to be "0".
3322	 *
3323	 * iwl_cnt = iwl_cnt / (hldev->config.isr_polling_cnt + 1); */
3324
3325	/*
3326	 * iwl_avg - how many RXDs on avarage been processed since
3327	 *           last bimodal timer tick. This indirectly includes
3328	 *           CPU utilizations.
3329	 */
3330	iwl_rxavg = hldev->irq_workload_rxd[ring_no] / iwl_rxcnt;
3331	iwl_txavg = hldev->irq_workload_txd[ring_no] / iwl_txcnt;
3332	iwl_avg = iwl_rxavg + iwl_txavg;
3333	iwl_avg = iwl_avg == 0 ? 1 : iwl_avg;
3334
3335	/*
3336	 * len_avg - how many bytes on avarage been processed since
3337	 *           last bimodal timer tick. i.e. avarage frame size.
3338	 */
3339	len_rxavg = 1 + hldev->irq_workload_rxlen[ring_no] /
3340		       (hldev->irq_workload_rxd[ring_no] ?
3341		        hldev->irq_workload_rxd[ring_no] : 1);
3342	len_txavg = 1 + hldev->irq_workload_txlen[ring_no] /
3343		       (hldev->irq_workload_txd[ring_no] ?
3344		        hldev->irq_workload_txd[ring_no] : 1);
3345	len_avg = len_rxavg + len_txavg;
3346	if (len_avg < 60)
3347		len_avg = 60;
3348
3349	/* align on low boundary */
3350	if ((tval -_STEP) < hldev->config.bimodal_timer_lo_us)
3351		tval = hldev->config.bimodal_timer_lo_us;
3352
3353	/* reset faster */
3354	if (iwl_avg == 1) {
3355		tval = hldev->config.bimodal_timer_lo_us;
3356		/* reset history */
3357		for (i = 0; i < _HIST_SIZE; i++)
3358			bytes_avg_history[i] = d_avg_history[i] = 0;
3359		history_idx = 0;
3360		pstep = 1;
3361		hist_adj_timer = 0;
3362	}
3363
3364	/* always try to ajust timer to the best throughput value */
3365	bytes_avg = iwl_avg * len_avg;
3366	history_idx %= _HIST_SIZE;
3367	bytes_avg_history[history_idx] = bytes_avg;
3368	d_avg_history[history_idx] = d;
3369	history_idx++;
3370	d_hist = bytes_hist = 0;
3371	for (i = 0; i < _HIST_SIZE; i++) {
3372		/* do not re-configure until history is gathered */
3373		if (!bytes_avg_history[i]) {
3374			tval = hldev->config.bimodal_timer_lo_us;
3375			goto _end;
3376		}
3377		bytes_hist += bytes_avg_history[i];
3378		d_hist += d_avg_history[i];
3379	}
3380	bytes_hist /= _HIST_SIZE;
3381	d_hist /= _HIST_SIZE;
3382
3383//	xge_os_printf("d %d iwl_avg %d len_avg %d:%d:%d tval %d avg %d hist %d pstep %d",
3384//		      d, iwl_avg, len_txavg, len_rxavg, len_avg, tval, d*bytes_avg,
3385//		      d_hist*bytes_hist, pstep);
3386
3387	/* make an adaptive step */
3388	if (d * bytes_avg < d_hist * bytes_hist && hist_adj_timer++ > _HIST_ADJ_TIMER) {
3389		pstep = !pstep;
3390		hist_adj_timer = 0;
3391	}
3392
3393	if (pstep &&
3394	    (tval + _STEP) <= hldev->config.bimodal_timer_hi_us) {
3395		tval += _STEP;
3396		hldev->stats.sw_dev_info_stats.bimodal_hi_adjust_cnt++;
3397	} else if ((tval - _STEP) >= hldev->config.bimodal_timer_lo_us) {
3398		tval -= _STEP;
3399		hldev->stats.sw_dev_info_stats.bimodal_lo_adjust_cnt++;
3400	}
3401
3402	/* enable TTI range A for better latencies */
3403	hldev->bimodal_urange_a_en = 0;
3404	if (tval <= hldev->config.bimodal_timer_lo_us && iwl_avg > 2)
3405		hldev->bimodal_urange_a_en = 1;
3406
3407_end:
3408	/* reset workload statistics counters */
3409	hldev->irq_workload_rxcnt[ring_no] = 0;
3410	hldev->irq_workload_rxd[ring_no] = 0;
3411	hldev->irq_workload_rxlen[ring_no] = 0;
3412	hldev->irq_workload_txcnt[ring_no] = 0;
3413	hldev->irq_workload_txd[ring_no] = 0;
3414	hldev->irq_workload_txlen[ring_no] = 0;
3415
3416	/* reconfigure TTI56 + ring_no with new timer value */
3417	hldev->bimodal_timer_val_us = tval;
3418	(void) __hal_device_rti_configure(hldev, 1);
3419}
3420
3421static void
3422__hal_update_rxufca(xge_hal_device_t *hldev, int ring_no)
3423{
3424	int ufc, ic, i;
3425
3426	ufc = hldev->config.ring.queue[ring_no].rti.ufc_a;
3427	ic = hldev->stats.sw_dev_info_stats.rx_traffic_intr_cnt;
3428
3429	/* urange_a adaptive coalescing */
3430	if (hldev->rxufca_lbolt > hldev->rxufca_lbolt_time) {
3431		if (ic > hldev->rxufca_intr_thres) {
3432			if (ufc < hldev->config.rxufca_hi_lim) {
3433				ufc += 1;
3434				for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
3435				   hldev->config.ring.queue[i].rti.ufc_a = ufc;
3436				(void) __hal_device_rti_configure(hldev, 1);
3437				hldev->stats.sw_dev_info_stats.rxufca_hi_adjust_cnt++;
3438			}
3439			hldev->rxufca_intr_thres = ic +
3440				hldev->config.rxufca_intr_thres; /* def: 30 */
3441		} else {
3442			if (ufc > hldev->config.rxufca_lo_lim) {
3443				ufc -= 1;
3444				for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
3445				   hldev->config.ring.queue[i].rti.ufc_a = ufc;
3446				(void) __hal_device_rti_configure(hldev, 1);
3447				hldev->stats.sw_dev_info_stats.rxufca_lo_adjust_cnt++;
3448			}
3449		}
3450		hldev->rxufca_lbolt_time = hldev->rxufca_lbolt +
3451			hldev->config.rxufca_lbolt_period;
3452	}
3453	hldev->rxufca_lbolt++;
3454}
3455
3456/*
3457 * __hal_device_handle_mc - Handle MC interrupt reason
3458 * @hldev: HAL device handle.
3459 * @reason: interrupt reason
3460 */
3461xge_hal_status_e
3462__hal_device_handle_mc(xge_hal_device_t *hldev, u64 reason)
3463{
3464	xge_hal_pci_bar0_t *isrbar0 =
3465	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3466	u64 val64;
3467
3468	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3469				&isrbar0->mc_int_status);
3470	if (!(val64 & XGE_HAL_MC_INT_STATUS_MC_INT))
3471		return XGE_HAL_OK;
3472
3473	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3474				&isrbar0->mc_err_reg);
3475	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3476				val64, &isrbar0->mc_err_reg);
3477
3478	if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_SG_ERR_L ||
3479	    val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_SG_ERR_U ||
3480	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_SG_ERR_0 ||
3481	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_SG_ERR_1 ||
3482	    (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_XENA &&
3483	     (val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_SG_ERR_L ||
3484	      val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_SG_ERR_U ||
3485	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_SG_ERR_L ||
3486	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_SG_ERR_U))) {
3487		hldev->stats.sw_dev_err_stats.single_ecc_err_cnt++;
3488		hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
3489	}
3490
3491	if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_DB_ERR_L ||
3492	    val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_DB_ERR_U ||
3493	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_0 ||
3494	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_1 ||
3495	    (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_XENA &&
3496	     (val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_DB_ERR_L ||
3497	      val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_DB_ERR_U ||
3498	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_DB_ERR_L ||
3499	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_DB_ERR_U))) {
3500		hldev->stats.sw_dev_err_stats.double_ecc_err_cnt++;
3501		hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
3502	}
3503
3504	if (val64 & XGE_HAL_MC_ERR_REG_SM_ERR) {
3505		hldev->stats.sw_dev_err_stats.sm_err_cnt++;
3506	}
3507
3508	/* those two should result in device reset */
3509	if (val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_0 ||
3510	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_1) {
3511                __hal_device_handle_eccerr(hldev, "mc_err_reg", val64);
3512		return XGE_HAL_ERR_CRITICAL;
3513	}
3514
3515	return XGE_HAL_OK;
3516}
3517
3518/*
3519 * __hal_device_handle_pic - Handle non-traffic PIC interrupt reason
3520 * @hldev: HAL device handle.
3521 * @reason: interrupt reason
3522 */
3523xge_hal_status_e
3524__hal_device_handle_pic(xge_hal_device_t *hldev, u64 reason)
3525{
3526	xge_hal_pci_bar0_t *isrbar0 =
3527	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3528	u64 val64;
3529
3530	if (reason & XGE_HAL_PIC_INT_FLSH) {
3531		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3532					&isrbar0->flsh_int_reg);
3533		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3534				       val64, &isrbar0->flsh_int_reg);
3535		/* FIXME: handle register */
3536	}
3537	if (reason & XGE_HAL_PIC_INT_MDIO) {
3538		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3539					&isrbar0->mdio_int_reg);
3540		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3541				       val64, &isrbar0->mdio_int_reg);
3542		/* FIXME: handle register */
3543	}
3544	if (reason & XGE_HAL_PIC_INT_IIC) {
3545		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3546					&isrbar0->iic_int_reg);
3547		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3548				       val64, &isrbar0->iic_int_reg);
3549		/* FIXME: handle register */
3550	}
3551	if (reason & XGE_HAL_PIC_INT_MISC) {
3552		val64 = xge_os_pio_mem_read64(hldev->pdev,
3553				hldev->regh0, &isrbar0->misc_int_reg);
3554#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
3555		if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) &&
3556			(hldev->config.intr_mode != XGE_HAL_INTR_MODE_MSIX)) {
3557			/*  Check for Link interrupts. If both Link Up/Down
3558			 *  bits are set, clear both and check adapter status
3559			 */
3560			if ((val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) &&
3561			    (val64 & XGE_HAL_MISC_INT_REG_LINK_DOWN_INT)) {
3562				u64 temp64;
3563
3564				xge_debug_device(XGE_TRACE,
3565				"both link up and link down detected "XGE_OS_LLXFMT,
3566				(unsigned long long)val64);
3567
3568				temp64 = (XGE_HAL_MISC_INT_REG_LINK_DOWN_INT |
3569					  XGE_HAL_MISC_INT_REG_LINK_UP_INT);
3570				xge_os_pio_mem_write64(hldev->pdev,
3571						       hldev->regh0, temp64,
3572						       &isrbar0->misc_int_reg);
3573			}
3574			else if (val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) {
3575				xge_debug_device(XGE_TRACE,
3576					"link up call request, misc_int "XGE_OS_LLXFMT,
3577					(unsigned long long)val64);
3578				__hal_device_handle_link_up_ind(hldev);
3579			}
3580			else if (val64 & XGE_HAL_MISC_INT_REG_LINK_DOWN_INT){
3581				xge_debug_device(XGE_TRACE,
3582					"link down request, misc_int "XGE_OS_LLXFMT,
3583					(unsigned long long)val64);
3584				__hal_device_handle_link_down_ind(hldev);
3585			}
3586		} else
3587#endif
3588		{
3589			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3590				       val64, &isrbar0->misc_int_reg);
3591		}
3592	}
3593
3594	return XGE_HAL_OK;
3595}
3596
3597/*
3598 * __hal_device_handle_txpic - Handle TxPIC interrupt reason
3599 * @hldev: HAL device handle.
3600 * @reason: interrupt reason
3601 */
3602xge_hal_status_e
3603__hal_device_handle_txpic(xge_hal_device_t *hldev, u64 reason)
3604{
3605	xge_hal_status_e status = XGE_HAL_OK;
3606	xge_hal_pci_bar0_t *isrbar0 =
3607	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3608	volatile u64 val64;
3609
3610	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3611				&isrbar0->pic_int_status);
3612	if ( val64 & (XGE_HAL_PIC_INT_FLSH |
3613		      XGE_HAL_PIC_INT_MDIO |
3614		      XGE_HAL_PIC_INT_IIC |
3615		      XGE_HAL_PIC_INT_MISC) ) {
3616		status =  __hal_device_handle_pic(hldev, val64);
3617		xge_os_wmb();
3618	}
3619
3620	if (!(val64 & XGE_HAL_PIC_INT_TX))
3621		return status;
3622
3623	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3624				&isrbar0->txpic_int_reg);
3625	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3626			       val64, &isrbar0->txpic_int_reg);
3627	xge_os_wmb();
3628
3629	if (val64 & XGE_HAL_TXPIC_INT_SCHED_INTR) {
3630		int i;
3631
3632		if (g_xge_hal_driver->uld_callbacks.sched_timer != NULL)
3633			g_xge_hal_driver->uld_callbacks.sched_timer(
3634					  hldev, hldev->upper_layer_info);
3635		/*
3636		 * This feature implements adaptive receive interrupt
3637		 * coalecing. It is disabled by default. To enable it
3638		 * set hldev->config.rxufca_lo_lim to be not equal to
3639		 * hldev->config.rxufca_hi_lim.
3640		 *
3641		 * We are using HW timer for this feature, so
3642		 * use needs to configure hldev->config.rxufca_lbolt_period
3643		 * which is essentially a time slice of timer.
3644		 *
3645		 * For those who familiar with Linux, lbolt means jiffies
3646		 * of this timer. I.e. timer tick.
3647		 */
3648		if (hldev->config.rxufca_lo_lim !=
3649				hldev->config.rxufca_hi_lim &&
3650		    hldev->config.rxufca_lo_lim != 0) {
3651			for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
3652				if (!hldev->config.ring.queue[i].configured)
3653					continue;
3654				if (hldev->config.ring.queue[i].rti.urange_a)
3655					__hal_update_rxufca(hldev, i);
3656			}
3657		}
3658
3659		/*
3660		 * This feature implements adaptive TTI timer re-calculation
3661		 * based on host utilization, number of interrupt processed,
3662		 * number of RXD per tick and avarage length of packets per
3663		 * tick.
3664		 */
3665		if (hldev->config.bimodal_interrupts) {
3666			for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
3667				if (!hldev->config.ring.queue[i].configured)
3668					continue;
3669				if (hldev->bimodal_tti[i].enabled)
3670					__hal_update_bimodal(hldev, i);
3671			}
3672		}
3673	}
3674
3675	return XGE_HAL_OK;
3676}
3677
3678/*
3679 * __hal_device_handle_txdma - Handle TxDMA interrupt reason
3680 * @hldev: HAL device handle.
3681 * @reason: interrupt reason
3682 */
3683xge_hal_status_e
3684__hal_device_handle_txdma(xge_hal_device_t *hldev, u64 reason)
3685{
3686	xge_hal_pci_bar0_t *isrbar0 =
3687	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3688	u64 val64, temp64, err;
3689
3690	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3691				&isrbar0->txdma_int_status);
3692	if (val64 & XGE_HAL_TXDMA_PFC_INT) {
3693		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3694				&isrbar0->pfc_err_reg);
3695		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3696				err, &isrbar0->pfc_err_reg);
3697		hldev->stats.sw_dev_info_stats.pfc_err_cnt++;
3698		temp64 = XGE_HAL_PFC_ECC_DB_ERR|XGE_HAL_PFC_SM_ERR_ALARM
3699			|XGE_HAL_PFC_MISC_0_ERR|XGE_HAL_PFC_MISC_1_ERR
3700			|XGE_HAL_PFC_PCIX_ERR;
3701		if (val64 & temp64)
3702			goto reset;
3703	}
3704	if (val64 & XGE_HAL_TXDMA_TDA_INT) {
3705		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3706				&isrbar0->tda_err_reg);
3707		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3708				err, &isrbar0->tda_err_reg);
3709		hldev->stats.sw_dev_info_stats.tda_err_cnt++;
3710		temp64 = XGE_HAL_TDA_Fn_ECC_DB_ERR|XGE_HAL_TDA_SM0_ERR_ALARM
3711			|XGE_HAL_TDA_SM1_ERR_ALARM;
3712		if (val64 & temp64)
3713			goto reset;
3714	}
3715	if (val64 & XGE_HAL_TXDMA_PCC_INT) {
3716		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3717				&isrbar0->pcc_err_reg);
3718		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3719				err, &isrbar0->pcc_err_reg);
3720		hldev->stats.sw_dev_info_stats.pcc_err_cnt++;
3721		temp64 = XGE_HAL_PCC_FB_ECC_DB_ERR|XGE_HAL_PCC_TXB_ECC_DB_ERR
3722			|XGE_HAL_PCC_SM_ERR_ALARM|XGE_HAL_PCC_WR_ERR_ALARM
3723			|XGE_HAL_PCC_N_SERR|XGE_HAL_PCC_6_COF_OV_ERR
3724			|XGE_HAL_PCC_7_COF_OV_ERR|XGE_HAL_PCC_6_LSO_OV_ERR
3725			|XGE_HAL_PCC_7_LSO_OV_ERR;
3726		if (val64 & temp64)
3727			goto reset;
3728	}
3729	if (val64 & XGE_HAL_TXDMA_TTI_INT) {
3730		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3731				&isrbar0->tti_err_reg);
3732		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3733				err, &isrbar0->tti_err_reg);
3734		hldev->stats.sw_dev_info_stats.tti_err_cnt++;
3735		temp64 = XGE_HAL_TTI_SM_ERR_ALARM;
3736		if (val64 & temp64)
3737			goto reset;
3738	}
3739	if (val64 & XGE_HAL_TXDMA_LSO_INT) {
3740		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3741				&isrbar0->lso_err_reg);
3742		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3743				err, &isrbar0->lso_err_reg);
3744		hldev->stats.sw_dev_info_stats.lso_err_cnt++;
3745		temp64 = XGE_HAL_LSO6_ABORT|XGE_HAL_LSO7_ABORT
3746			|XGE_HAL_LSO6_SM_ERR_ALARM|XGE_HAL_LSO7_SM_ERR_ALARM;
3747		if (val64 & temp64)
3748			goto reset;
3749	}
3750	if (val64 & XGE_HAL_TXDMA_TPA_INT) {
3751		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3752				&isrbar0->tpa_err_reg);
3753		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3754				err, &isrbar0->tpa_err_reg);
3755		hldev->stats.sw_dev_info_stats.tpa_err_cnt++;
3756		temp64 = XGE_HAL_TPA_SM_ERR_ALARM;
3757		if (val64 & temp64)
3758			goto reset;
3759	}
3760	if (val64 & XGE_HAL_TXDMA_SM_INT) {
3761		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3762				&isrbar0->sm_err_reg);
3763		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3764				err, &isrbar0->sm_err_reg);
3765		hldev->stats.sw_dev_info_stats.sm_err_cnt++;
3766		temp64 = XGE_HAL_SM_SM_ERR_ALARM;
3767		if (val64 & temp64)
3768			goto reset;
3769	}
3770
3771	return XGE_HAL_OK;
3772
3773reset : (void) xge_hal_device_reset(hldev);
3774	(void) xge_hal_device_enable(hldev);
3775	xge_hal_device_intr_enable(hldev);
3776	return XGE_HAL_OK;
3777}
3778
3779/*
3780 * __hal_device_handle_txmac - Handle TxMAC interrupt reason
3781 * @hldev: HAL device handle.
3782 * @reason: interrupt reason
3783 */
3784xge_hal_status_e
3785__hal_device_handle_txmac(xge_hal_device_t *hldev, u64 reason)
3786{
3787	xge_hal_pci_bar0_t *isrbar0 =
3788	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3789	u64 val64, temp64;
3790
3791	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3792				&isrbar0->mac_int_status);
3793	if (!(val64 & XGE_HAL_MAC_INT_STATUS_TMAC_INT))
3794		return XGE_HAL_OK;
3795
3796	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3797				&isrbar0->mac_tmac_err_reg);
3798	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3799				val64, &isrbar0->mac_tmac_err_reg);
3800	hldev->stats.sw_dev_info_stats.mac_tmac_err_cnt++;
3801	temp64 = XGE_HAL_TMAC_TX_BUF_OVRN|XGE_HAL_TMAC_TX_SM_ERR;
3802	if (val64 & temp64) {
3803		(void) xge_hal_device_reset(hldev);
3804		(void) xge_hal_device_enable(hldev);
3805		xge_hal_device_intr_enable(hldev);
3806	}
3807
3808	return XGE_HAL_OK;
3809}
3810
3811/*
3812 * __hal_device_handle_txxgxs - Handle TxXGXS interrupt reason
3813 * @hldev: HAL device handle.
3814 * @reason: interrupt reason
3815 */
3816xge_hal_status_e
3817__hal_device_handle_txxgxs(xge_hal_device_t *hldev, u64 reason)
3818{
3819	xge_hal_pci_bar0_t *isrbar0 =
3820	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3821	u64 val64, temp64;
3822
3823	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3824				&isrbar0->xgxs_int_status);
3825	if (!(val64 & XGE_HAL_XGXS_INT_STATUS_TXGXS))
3826		return XGE_HAL_OK;
3827
3828	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3829				&isrbar0->xgxs_txgxs_err_reg);
3830	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3831				val64, &isrbar0->xgxs_txgxs_err_reg);
3832	hldev->stats.sw_dev_info_stats.xgxs_txgxs_err_cnt++;
3833	temp64 = XGE_HAL_TXGXS_ESTORE_UFLOW|XGE_HAL_TXGXS_TX_SM_ERR;
3834	if (val64 & temp64) {
3835		(void) xge_hal_device_reset(hldev);
3836		(void) xge_hal_device_enable(hldev);
3837		xge_hal_device_intr_enable(hldev);
3838	}
3839
3840	return XGE_HAL_OK;
3841}
3842
3843/*
3844 * __hal_device_handle_rxpic - Handle RxPIC interrupt reason
3845 * @hldev: HAL device handle.
3846 * @reason: interrupt reason
3847 */
3848xge_hal_status_e
3849__hal_device_handle_rxpic(xge_hal_device_t *hldev, u64 reason)
3850{
3851	/* FIXME: handle register */
3852
3853	return XGE_HAL_OK;
3854}
3855
3856/*
3857 * __hal_device_handle_rxdma - Handle RxDMA interrupt reason
3858 * @hldev: HAL device handle.
3859 * @reason: interrupt reason
3860 */
3861xge_hal_status_e
3862__hal_device_handle_rxdma(xge_hal_device_t *hldev, u64 reason)
3863{
3864	xge_hal_pci_bar0_t *isrbar0 =
3865	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3866	u64 val64, err, temp64;
3867
3868	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3869				&isrbar0->rxdma_int_status);
3870	if (val64 & XGE_HAL_RXDMA_RC_INT) {
3871		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3872				&isrbar0->rc_err_reg);
3873		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3874				err, &isrbar0->rc_err_reg);
3875		hldev->stats.sw_dev_info_stats.rc_err_cnt++;
3876		temp64 = XGE_HAL_RC_PRCn_ECC_DB_ERR|XGE_HAL_RC_FTC_ECC_DB_ERR
3877			|XGE_HAL_RC_PRCn_SM_ERR_ALARM
3878			|XGE_HAL_RC_FTC_SM_ERR_ALARM;
3879		if (val64 & temp64)
3880			goto reset;
3881	}
3882	if (val64 & XGE_HAL_RXDMA_RPA_INT) {
3883		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3884				&isrbar0->rpa_err_reg);
3885		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3886				err, &isrbar0->rpa_err_reg);
3887		hldev->stats.sw_dev_info_stats.rpa_err_cnt++;
3888		temp64 = XGE_HAL_RPA_SM_ERR_ALARM|XGE_HAL_RPA_CREDIT_ERR;
3889		if (val64 & temp64)
3890			goto reset;
3891	}
3892	if (val64 & XGE_HAL_RXDMA_RDA_INT) {
3893		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3894				&isrbar0->rda_err_reg);
3895		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3896				err, &isrbar0->rda_err_reg);
3897		hldev->stats.sw_dev_info_stats.rda_err_cnt++;
3898		temp64 = XGE_HAL_RDA_RXDn_ECC_DB_ERR
3899			|XGE_HAL_RDA_FRM_ECC_DB_N_AERR
3900			|XGE_HAL_RDA_SM1_ERR_ALARM|XGE_HAL_RDA_SM0_ERR_ALARM
3901			|XGE_HAL_RDA_RXD_ECC_DB_SERR;
3902		if (val64 & temp64)
3903			goto reset;
3904	}
3905	if (val64 & XGE_HAL_RXDMA_RTI_INT) {
3906		err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3907				&isrbar0->rti_err_reg);
3908		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3909				err, &isrbar0->rti_err_reg);
3910		hldev->stats.sw_dev_info_stats.rti_err_cnt++;
3911		temp64 = XGE_HAL_RTI_SM_ERR_ALARM;
3912		if (val64 & temp64)
3913			goto reset;
3914	}
3915
3916	return XGE_HAL_OK;
3917
3918reset : (void) xge_hal_device_reset(hldev);
3919	(void) xge_hal_device_enable(hldev);
3920	xge_hal_device_intr_enable(hldev);
3921	return XGE_HAL_OK;
3922}
3923
3924/*
3925 * __hal_device_handle_rxmac - Handle RxMAC interrupt reason
3926 * @hldev: HAL device handle.
3927 * @reason: interrupt reason
3928 */
3929xge_hal_status_e
3930__hal_device_handle_rxmac(xge_hal_device_t *hldev, u64 reason)
3931{
3932	xge_hal_pci_bar0_t *isrbar0 =
3933	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3934	u64 val64, temp64;
3935
3936	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3937				&isrbar0->mac_int_status);
3938	if (!(val64 & XGE_HAL_MAC_INT_STATUS_RMAC_INT))
3939		return XGE_HAL_OK;
3940
3941	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3942				&isrbar0->mac_rmac_err_reg);
3943	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3944				val64, &isrbar0->mac_rmac_err_reg);
3945	hldev->stats.sw_dev_info_stats.mac_rmac_err_cnt++;
3946	temp64 = XGE_HAL_RMAC_RX_BUFF_OVRN|XGE_HAL_RMAC_RX_SM_ERR;
3947	if (val64 & temp64) {
3948		(void) xge_hal_device_reset(hldev);
3949		(void) xge_hal_device_enable(hldev);
3950		xge_hal_device_intr_enable(hldev);
3951	}
3952
3953	return XGE_HAL_OK;
3954}
3955
3956/*
3957 * __hal_device_handle_rxxgxs - Handle RxXGXS interrupt reason
3958 * @hldev: HAL device handle.
3959 * @reason: interrupt reason
3960 */
3961xge_hal_status_e
3962__hal_device_handle_rxxgxs(xge_hal_device_t *hldev, u64 reason)
3963{
3964	xge_hal_pci_bar0_t *isrbar0 =
3965	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3966	u64 val64, temp64;
3967
3968	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3969				&isrbar0->xgxs_int_status);
3970	if (!(val64 & XGE_HAL_XGXS_INT_STATUS_RXGXS))
3971		return XGE_HAL_OK;
3972
3973	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3974				&isrbar0->xgxs_rxgxs_err_reg);
3975	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3976				val64, &isrbar0->xgxs_rxgxs_err_reg);
3977	hldev->stats.sw_dev_info_stats.xgxs_rxgxs_err_cnt++;
3978	temp64 = XGE_HAL_RXGXS_ESTORE_OFLOW|XGE_HAL_RXGXS_RX_SM_ERR;
3979	if (val64 & temp64) {
3980		(void) xge_hal_device_reset(hldev);
3981		(void) xge_hal_device_enable(hldev);
3982		xge_hal_device_intr_enable(hldev);
3983	}
3984
3985	return XGE_HAL_OK;
3986}
3987
3988/**
3989 * xge_hal_device_enable - Enable device.
3990 * @hldev: HAL device handle.
3991 *
3992 * Enable the specified device: bring up the link/interface.
3993 * Returns:  XGE_HAL_OK - success.
3994 * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device
3995 * to a "quiescent" state.
3996 *
3997 * See also: xge_hal_status_e{}.
3998 *
3999 * Usage: See ex_open{}.
4000 */
4001xge_hal_status_e
4002xge_hal_device_enable(xge_hal_device_t *hldev)
4003{
4004	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4005	u64 val64;
4006	u64 adp_status;
4007	int i, j;
4008
4009	if (!hldev->hw_is_initialized) {
4010		xge_hal_status_e status;
4011
4012		status = __hal_device_hw_initialize(hldev);
4013		if (status != XGE_HAL_OK) {
4014			return status;
4015		}
4016	}
4017
4018	/*
4019	 * Not needed in most cases, i.e.
4020	 * when device_disable() is followed by reset -
4021	 * the latter copies back PCI config space, along with
4022	 * the bus mastership - see __hal_device_reset().
4023	 * However, there are/may-in-future be other cases, and
4024	 * does not hurt.
4025	 */
4026	__hal_device_bus_master_enable(hldev);
4027
4028	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
4029		/*
4030		 * Configure the link stability period.
4031		 */
4032		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4033					      &bar0->misc_control);
4034		if (hldev->config.link_stability_period !=
4035				XGE_HAL_DEFAULT_USE_HARDCODE) {
4036
4037			val64 |= XGE_HAL_MISC_CONTROL_LINK_STABILITY_PERIOD(
4038					hldev->config.link_stability_period);
4039		} else {
4040			/*
4041			 * Use the link stability period 1 ms as default
4042			 */
4043			val64 |= XGE_HAL_MISC_CONTROL_LINK_STABILITY_PERIOD(
4044					XGE_HAL_DEFAULT_LINK_STABILITY_PERIOD);
4045		}
4046		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4047				       val64, &bar0->misc_control);
4048
4049		/*
4050		 * Clearing any possible Link up/down interrupts that
4051		 * could have popped up just before Enabling the card.
4052		 */
4053		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4054					      &bar0->misc_int_reg);
4055		if (val64) {
4056			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4057					       val64, &bar0->misc_int_reg);
4058			xge_debug_device(XGE_TRACE, "%s","link state cleared");
4059		}
4060	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
4061		/*
4062		 * Clearing any possible Link state change interrupts that
4063		 * could have popped up just before Enabling the card.
4064		 */
4065		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4066			&bar0->mac_rmac_err_reg);
4067		if (val64) {
4068			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4069					       val64, &bar0->mac_rmac_err_reg);
4070			xge_debug_device(XGE_TRACE, "%s", "link state cleared");
4071		}
4072	}
4073
4074	if (__hal_device_wait_quiescent(hldev, &val64)) {
4075		return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4076	}
4077
4078	/* Enabling Laser. */
4079	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4080				    &bar0->adapter_control);
4081	val64 |= XGE_HAL_ADAPTER_EOI_TX_ON;
4082	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4083	                     &bar0->adapter_control);
4084
4085	/* let link establish */
4086	xge_os_mdelay(1);
4087
4088	/* set link down untill poll() routine will set it up (maybe) */
4089	hldev->link_state = XGE_HAL_LINK_DOWN;
4090
4091	/* If link is UP (adpter is connected) then enable the adapter */
4092	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4093	                            &bar0->adapter_status);
4094	if( val64 & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
4095		     XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT) ) {
4096		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4097		                        &bar0->adapter_control);
4098		val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
4099	} else {
4100		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4101		                           &bar0->adapter_control);
4102		val64 = val64 | ( XGE_HAL_ADAPTER_EOI_TX_ON |
4103				  XGE_HAL_ADAPTER_LED_ON );
4104	}
4105
4106	val64 = val64 | XGE_HAL_ADAPTER_CNTL_EN;   /* adapter enable */
4107	val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN); /* ECC enable */
4108	xge_os_pio_mem_write64 (hldev->pdev, hldev->regh0, val64,
4109			      &bar0->adapter_control);
4110
4111	/* We spin here waiting for the Link to come up.
4112	 * This is the fix for the Link being unstable after the reset. */
4113	i = 0;
4114	j = 0;
4115	do
4116	{
4117		adp_status = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4118		                                &bar0->adapter_status);
4119
4120		/* Read the adapter control register for Adapter_enable bit */
4121		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4122		                           &bar0->adapter_control);
4123		if (!(adp_status & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
4124				    XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) &&
4125		    (val64 & XGE_HAL_ADAPTER_CNTL_EN)) {
4126			j++;
4127			if (j >= hldev->config.link_valid_cnt) {
4128				if (xge_hal_device_status(hldev, &adp_status) ==
4129							XGE_HAL_OK) {
4130					if (__hal_verify_pcc_idle(hldev,
4131						  adp_status) != XGE_HAL_OK) {
4132					   return
4133					    XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4134					}
4135					xge_debug_device(XGE_TRACE,
4136					      "adp_status: "XGE_OS_LLXFMT
4137					      ", link is up on "
4138					      "adapter enable!",
4139					      (unsigned long long)adp_status);
4140					val64 = xge_os_pio_mem_read64(
4141							hldev->pdev,
4142							hldev->regh0,
4143							&bar0->adapter_control);
4144					val64 = val64|
4145						(XGE_HAL_ADAPTER_EOI_TX_ON |
4146						 XGE_HAL_ADAPTER_LED_ON );
4147					xge_os_pio_mem_write64(hldev->pdev,
4148					                hldev->regh0, val64,
4149					                &bar0->adapter_control);
4150					xge_os_mdelay(1);
4151
4152					val64 = xge_os_pio_mem_read64(
4153							hldev->pdev,
4154							hldev->regh0,
4155							&bar0->adapter_control);
4156					break;    /* out of for loop */
4157				} else {
4158				       return
4159					   XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4160				}
4161			}
4162		} else {
4163			j = 0;  /* Reset the count */
4164			/* Turn on the Laser */
4165			val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4166			                &bar0->adapter_control);
4167			val64 = val64 | XGE_HAL_ADAPTER_EOI_TX_ON;
4168			xge_os_pio_mem_write64 (hldev->pdev, hldev->regh0,
4169						val64, &bar0->adapter_control);
4170
4171			xge_os_mdelay(1);
4172
4173			/* Now re-enable it as due to noise, hardware
4174			 * turned it off */
4175			val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4176			                            &bar0->adapter_control);
4177			val64 |= XGE_HAL_ADAPTER_CNTL_EN;
4178			val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN);/*ECC enable*/
4179			xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4180			                    &bar0->adapter_control);
4181		}
4182		xge_os_mdelay(1); /* Sleep for 1 msec */
4183		i++;
4184	} while (i < hldev->config.link_retry_cnt);
4185
4186	__hal_device_led_actifity_fix(hldev);
4187
4188#ifndef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
4189	/* Here we are performing soft reset on XGXS to force link down.
4190	 * Since link is already up, we will get link state change
4191	 * poll notificatoin after adapter is enabled */
4192
4193	__hal_serial_mem_write64(hldev, 0x80010515001E0000ULL,
4194				 &bar0->dtx_control);
4195	(void) __hal_serial_mem_read64(hldev, &bar0->dtx_control);
4196
4197	__hal_serial_mem_write64(hldev, 0x80010515001E00E0ULL,
4198				 &bar0->dtx_control);
4199	(void) __hal_serial_mem_read64(hldev, &bar0->dtx_control);
4200
4201	__hal_serial_mem_write64(hldev, 0x80070515001F00E4ULL,
4202				 &bar0->dtx_control);
4203	(void) __hal_serial_mem_read64(hldev, &bar0->dtx_control);
4204
4205	xge_os_mdelay(100); /* Sleep for 500 msec */
4206#else
4207	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
4208#endif
4209	{
4210		/*
4211		 * With some switches the link state change interrupt does not
4212		 * occur even though the xgxs reset is done as per SPN-006. So,
4213		 * poll the adapter status register and check if the link state
4214		 * is ok.
4215		 */
4216		adp_status = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4217						   &bar0->adapter_status);
4218		if (!(adp_status & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
4219		      XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
4220		{
4221			xge_debug_device(XGE_TRACE, "%s",
4222			     "enable device causing link state change ind..");
4223			(void) __hal_device_handle_link_state_change(hldev);
4224		}
4225	}
4226
4227	if (hldev->config.stats_refresh_time_sec !=
4228	    XGE_HAL_STATS_REFRESH_DISABLE)
4229	        __hal_stats_enable(&hldev->stats);
4230
4231	return XGE_HAL_OK;
4232}
4233
4234/**
4235 * xge_hal_device_disable - Disable Xframe adapter.
4236 * @hldev: Device handle.
4237 *
4238 * Disable this device. To gracefully reset the adapter, the host should:
4239 *
4240 *	- call xge_hal_device_disable();
4241 *
4242 *	- call xge_hal_device_intr_disable();
4243 *
4244 *	- close all opened channels and clean up outstanding resources;
4245 *
4246 *	- do some work (error recovery, change mtu, reset, etc);
4247 *
4248 *	- call xge_hal_device_enable();
4249 *
4250 *	- open channels, replenish RxDs, etc.
4251 *
4252 *	- call xge_hal_device_intr_enable().
4253 *
4254 * Note: Disabling the device does _not_ include disabling of interrupts.
4255 * After disabling the device stops receiving new frames but those frames
4256 * that were already in the pipe will keep coming for some few milliseconds.
4257 *
4258 * Returns:  XGE_HAL_OK - success.
4259 * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
4260 * a "quiescent" state.
4261 *
4262 * See also: xge_hal_status_e{}.
4263 */
4264xge_hal_status_e
4265xge_hal_device_disable(xge_hal_device_t *hldev)
4266{
4267	xge_hal_status_e status = XGE_HAL_OK;
4268	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4269	u64 val64;
4270
4271	xge_debug_device(XGE_TRACE, "%s", "turn off laser, cleanup hardware");
4272
4273	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4274	                            &bar0->adapter_control);
4275	val64 = val64 & (~XGE_HAL_ADAPTER_CNTL_EN);
4276	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4277	                     &bar0->adapter_control);
4278
4279	if (__hal_device_wait_quiescent(hldev, &val64) != XGE_HAL_OK) {
4280		status = XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4281	}
4282
4283	if (__hal_device_register_poll(hldev, &bar0->adapter_status, 1,
4284		 XGE_HAL_ADAPTER_STATUS_RC_PRC_QUIESCENT,
4285		 XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4286		xge_debug_device(XGE_TRACE, "%s", "PRC is not QUIESCENT!");
4287		status = XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4288	}
4289
4290	if (hldev->config.stats_refresh_time_sec !=
4291	    XGE_HAL_STATS_REFRESH_DISABLE)
4292                __hal_stats_disable(&hldev->stats);
4293#ifdef XGE_DEBUG_ASSERT
4294        else
4295	        xge_assert(!hldev->stats.is_enabled);
4296#endif
4297
4298#ifndef XGE_HAL_DONT_DISABLE_BUS_MASTER_ON_STOP
4299	__hal_device_bus_master_disable(hldev);
4300#endif
4301
4302	return status;
4303}
4304
4305/**
4306 * xge_hal_device_reset - Reset device.
4307 * @hldev: HAL device handle.
4308 *
4309 * Soft-reset the device, reset the device stats except reset_cnt.
4310 *
4311 * After reset is done, will try to re-initialize HW.
4312 *
4313 * Returns:  XGE_HAL_OK - success.
4314 * XGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
4315 * XGE_HAL_ERR_RESET_FAILED - Reset failed.
4316 *
4317 * See also: xge_hal_status_e{}.
4318 */
4319xge_hal_status_e
4320xge_hal_device_reset(xge_hal_device_t *hldev)
4321{
4322	xge_hal_status_e status;
4323
4324	/* increment the soft reset counter */
4325	u32 reset_cnt = hldev->stats.sw_dev_info_stats.soft_reset_cnt;
4326
4327	xge_debug_device(XGE_TRACE, "%s (%d)", "resetting the device", reset_cnt);
4328
4329	if (!hldev->is_initialized)
4330		return XGE_HAL_ERR_DEVICE_NOT_INITIALIZED;
4331
4332	/* actual "soft" reset of the adapter */
4333	status = __hal_device_reset(hldev);
4334
4335	/* reset all stats including saved */
4336	__hal_stats_soft_reset(hldev, 1);
4337
4338	/* increment reset counter */
4339	hldev->stats.sw_dev_info_stats.soft_reset_cnt = reset_cnt + 1;
4340
4341	/* re-initialize rxufca_intr_thres */
4342	hldev->rxufca_intr_thres = hldev->config.rxufca_intr_thres;
4343
4344        hldev->reset_needed_after_close = 0;
4345
4346	return status;
4347}
4348
4349/**
4350 * xge_hal_device_status - Check whether Xframe hardware is ready for
4351 * operation.
4352 * @hldev: HAL device handle.
4353 * @hw_status: Xframe status register. Returned by HAL.
4354 *
4355 * Check whether Xframe hardware is ready for operation.
4356 * The checking includes TDMA, RDMA, PFC, PIC, MC_DRAM, and the rest
4357 * hardware functional blocks.
4358 *
4359 * Returns: XGE_HAL_OK if the device is ready for operation. Otherwise
4360 * returns XGE_HAL_FAIL. Also, fills in  adapter status (in @hw_status).
4361 *
4362 * See also: xge_hal_status_e{}.
4363 * Usage: See ex_open{}.
4364 */
4365xge_hal_status_e
4366xge_hal_device_status(xge_hal_device_t *hldev, u64 *hw_status)
4367{
4368	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4369	u64 tmp64;
4370
4371	tmp64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4372	                            &bar0->adapter_status);
4373
4374	*hw_status = tmp64;
4375
4376	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TDMA_READY)) {
4377		xge_debug_device(XGE_TRACE, "%s", "TDMA is not ready!");
4378		return XGE_HAL_FAIL;
4379	}
4380	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_RDMA_READY)) {
4381		xge_debug_device(XGE_TRACE, "%s", "RDMA is not ready!");
4382		return XGE_HAL_FAIL;
4383	}
4384	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PFC_READY)) {
4385		xge_debug_device(XGE_TRACE, "%s", "PFC is not ready!");
4386		return XGE_HAL_FAIL;
4387	}
4388	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY)) {
4389		xge_debug_device(XGE_TRACE, "%s", "TMAC BUF is not empty!");
4390		return XGE_HAL_FAIL;
4391	}
4392	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT)) {
4393		xge_debug_device(XGE_TRACE, "%s", "PIC is not QUIESCENT!");
4394		return XGE_HAL_FAIL;
4395	}
4396	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY)) {
4397		xge_debug_device(XGE_TRACE, "%s", "MC_DRAM is not ready!");
4398		return XGE_HAL_FAIL;
4399	}
4400	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY)) {
4401		xge_debug_device(XGE_TRACE, "%s", "MC_QUEUES is not ready!");
4402		return XGE_HAL_FAIL;
4403	}
4404	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK)) {
4405		xge_debug_device(XGE_TRACE, "%s", "M_PLL is not locked!");
4406		return XGE_HAL_FAIL;
4407	}
4408#ifndef XGE_HAL_HERC_EMULATION
4409	/*
4410	 * Andrew: in PCI 33 mode, the P_PLL is not used, and therefore,
4411	 * the the P_PLL_LOCK bit in the adapter_status register will
4412	 * not be asserted.
4413	 */
4414	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_P_PLL_LOCK) &&
4415	     xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC &&
4416	     hldev->pci_mode != XGE_HAL_PCI_33MHZ_MODE) {
4417		xge_debug_device(XGE_TRACE, "%s", "P_PLL is not locked!");
4418		return XGE_HAL_FAIL;
4419	}
4420#endif
4421
4422	return XGE_HAL_OK;
4423}
4424
4425void
4426__hal_device_msi_intr_endis(xge_hal_device_t *hldev, int flag)
4427{
4428	u16 msi_control_reg;
4429
4430	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
4431	     xge_offsetof(xge_hal_pci_config_le_t,
4432			  msi_control), &msi_control_reg);
4433
4434	if (flag)
4435		msi_control_reg |= 0x1;
4436	else
4437		msi_control_reg &= ~0x1;
4438
4439	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
4440	     xge_offsetof(xge_hal_pci_config_le_t,
4441			     msi_control), msi_control_reg);
4442}
4443
4444void
4445__hal_device_msix_intr_endis(xge_hal_device_t *hldev,
4446			      xge_hal_channel_t *channel, int flag)
4447{
4448	u64 val64;
4449	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
4450
4451	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4452		&bar0->xmsi_mask_reg);
4453
4454	if (flag)
4455		val64 &= ~(1LL << ( 63 - channel->msix_idx ));
4456	else
4457		val64 |= (1LL << ( 63 - channel->msix_idx ));
4458	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4459		&bar0->xmsi_mask_reg);
4460}
4461
4462/**
4463 * xge_hal_device_intr_enable - Enable Xframe interrupts.
4464 * @hldev: HAL device handle.
4465 * @op: One of the xge_hal_device_intr_e enumerated values specifying
4466 *      the type(s) of interrupts to enable.
4467 *
4468 * Enable Xframe interrupts. The function is to be executed the last in
4469 * Xframe initialization sequence.
4470 *
4471 * See also: xge_hal_device_intr_disable()
4472 */
4473void
4474xge_hal_device_intr_enable(xge_hal_device_t *hldev)
4475{
4476	xge_list_t *item;
4477	u64 val64;
4478
4479	/* PRC initialization and configuration */
4480	xge_list_for_each(item, &hldev->ring_channels) {
4481		xge_hal_channel_h channel;
4482		channel = xge_container_of(item, xge_hal_channel_t, item);
4483		__hal_ring_prc_enable(channel);
4484	}
4485
4486	/* enable traffic only interrupts */
4487	if (hldev->config.intr_mode != XGE_HAL_INTR_MODE_IRQLINE) {
4488		/*
4489		 * make sure all interrupts going to be disabled if MSI
4490		 * is enabled.
4491		 */
4492#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
4493		__hal_device_intr_mgmt(hldev, XGE_HAL_TX_PIC_INTR, 1);
4494#else
4495		__hal_device_intr_mgmt(hldev, XGE_HAL_ALL_INTRS, 0);
4496#endif
4497	} else {
4498		/*
4499		 * Enable the Tx traffic interrupts only if the TTI feature is
4500		 * enabled.
4501		 */
4502		val64 = 0;
4503		if (hldev->tti_enabled)
4504			val64 = XGE_HAL_TX_TRAFFIC_INTR;
4505
4506		if (!hldev->config.bimodal_interrupts)
4507			val64 |= XGE_HAL_RX_TRAFFIC_INTR;
4508
4509		if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
4510			val64 |= XGE_HAL_RX_TRAFFIC_INTR;
4511
4512		val64 |=XGE_HAL_TX_PIC_INTR |
4513			XGE_HAL_MC_INTR |
4514			XGE_HAL_TX_DMA_INTR |
4515			(hldev->config.sched_timer_us !=
4516			 XGE_HAL_SCHED_TIMER_DISABLED ? XGE_HAL_SCHED_INTR : 0);
4517		__hal_device_intr_mgmt(hldev, val64, 1);
4518	}
4519
4520	/*
4521	 * Enable MSI-X interrupts
4522	 */
4523	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
4524
4525		if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
4526			/*
4527			 * To enable MSI-X, MSI also needs to be enabled,
4528			 * due to a bug in the herc NIC.
4529			 */
4530			__hal_device_msi_intr_endis(hldev, 1);
4531		}
4532
4533
4534		/* Enable the MSI-X interrupt for each configured channel */
4535		xge_list_for_each(item, &hldev->fifo_channels) {
4536			xge_hal_channel_t *channel;
4537
4538			channel = xge_container_of(item,
4539					   xge_hal_channel_t, item);
4540
4541			/* 0 vector is reserved for alarms */
4542			if (!channel->msix_idx)
4543				continue;
4544
4545			__hal_device_msix_intr_endis(hldev, channel, 1);
4546		}
4547
4548		xge_list_for_each(item, &hldev->ring_channels) {
4549			xge_hal_channel_t *channel;
4550
4551			channel = xge_container_of(item,
4552					   xge_hal_channel_t, item);
4553
4554			/* 0 vector is reserved for alarms */
4555			if (!channel->msix_idx)
4556				continue;
4557
4558			__hal_device_msix_intr_endis(hldev, channel, 1);
4559		}
4560	}
4561
4562	xge_debug_device(XGE_TRACE, "%s", "interrupts are enabled");
4563}
4564
4565
4566/**
4567 * xge_hal_device_intr_disable - Disable Xframe interrupts.
4568 * @hldev: HAL device handle.
4569 * @op: One of the xge_hal_device_intr_e enumerated values specifying
4570 *      the type(s) of interrupts to disable.
4571 *
4572 * Disable Xframe interrupts.
4573 *
4574 * See also: xge_hal_device_intr_enable()
4575 */
4576void
4577xge_hal_device_intr_disable(xge_hal_device_t *hldev)
4578{
4579	xge_list_t *item;
4580	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4581	u64 val64;
4582
4583	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
4584
4585		if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
4586			/*
4587			 * To disable MSI-X, MSI also needs to be disabled,
4588			 * due to a bug in the herc NIC.
4589			 */
4590			__hal_device_msi_intr_endis(hldev, 0);
4591		}
4592
4593		/* Disable the MSI-X interrupt for each configured channel */
4594		xge_list_for_each(item, &hldev->fifo_channels) {
4595			xge_hal_channel_t *channel;
4596
4597			channel = xge_container_of(item,
4598					   xge_hal_channel_t, item);
4599
4600			/* 0 vector is reserved for alarms */
4601			if (!channel->msix_idx)
4602				continue;
4603
4604			__hal_device_msix_intr_endis(hldev, channel, 0);
4605
4606		}
4607
4608		xge_os_pio_mem_write64(hldev->pdev,
4609			hldev->regh0, 0xFFFFFFFFFFFFFFFFULL,
4610			&bar0->tx_traffic_mask);
4611
4612		xge_list_for_each(item, &hldev->ring_channels) {
4613			xge_hal_channel_t *channel;
4614
4615			channel = xge_container_of(item,
4616					   xge_hal_channel_t, item);
4617
4618			/* 0 vector is reserved for alarms */
4619			if (!channel->msix_idx)
4620				continue;
4621
4622			__hal_device_msix_intr_endis(hldev, channel, 0);
4623		}
4624
4625		xge_os_pio_mem_write64(hldev->pdev,
4626			hldev->regh0, 0xFFFFFFFFFFFFFFFFULL,
4627			&bar0->rx_traffic_mask);
4628	}
4629
4630	/*
4631	 * Disable traffic only interrupts.
4632	 * Tx traffic interrupts are used only if the TTI feature is
4633	 * enabled.
4634	 */
4635	val64 = 0;
4636	if (hldev->tti_enabled)
4637		val64 = XGE_HAL_TX_TRAFFIC_INTR;
4638
4639	val64 |= XGE_HAL_RX_TRAFFIC_INTR |
4640		 XGE_HAL_TX_PIC_INTR |
4641		 XGE_HAL_MC_INTR |
4642		 (hldev->config.sched_timer_us != XGE_HAL_SCHED_TIMER_DISABLED ?
4643						XGE_HAL_SCHED_INTR : 0);
4644	__hal_device_intr_mgmt(hldev, val64, 0);
4645
4646	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4647	                     0xFFFFFFFFFFFFFFFFULL,
4648			     &bar0->general_int_mask);
4649
4650
4651	/* disable all configured PRCs */
4652	xge_list_for_each(item, &hldev->ring_channels) {
4653		xge_hal_channel_h channel;
4654		channel = xge_container_of(item, xge_hal_channel_t, item);
4655		__hal_ring_prc_disable(channel);
4656	}
4657
4658	xge_debug_device(XGE_TRACE, "%s", "interrupts are disabled");
4659}
4660
4661
4662/**
4663 * xge_hal_device_mcast_enable - Enable Xframe multicast addresses.
4664 * @hldev: HAL device handle.
4665 *
4666 * Enable Xframe multicast addresses.
4667 * Returns: XGE_HAL_OK on success.
4668 * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to enable mcast
4669 * feature within the time(timeout).
4670 *
4671 * See also: xge_hal_device_mcast_disable(), xge_hal_status_e{}.
4672 */
4673xge_hal_status_e
4674xge_hal_device_mcast_enable(xge_hal_device_t *hldev)
4675{
4676	u64 val64;
4677	xge_hal_pci_bar0_t *bar0;
4678	int mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET;
4679
4680	if (hldev == NULL)
4681		return XGE_HAL_ERR_INVALID_DEVICE;
4682
4683	if (hldev->mcast_refcnt)
4684		return XGE_HAL_OK;
4685
4686	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
4687		mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET_HERC;
4688
4689	hldev->mcast_refcnt = 1;
4690
4691	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4692
4693	/*  Enable all Multicast addresses */
4694	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4695	      XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0x010203040506ULL),
4696	      &bar0->rmac_addr_data0_mem);
4697	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4698	      XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0xfeffffffffffULL),
4699	      &bar0->rmac_addr_data1_mem);
4700	val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
4701		XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4702		XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET(mc_offset);
4703	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4704		            &bar0->rmac_addr_cmd_mem);
4705
4706	if (__hal_device_register_poll(hldev,
4707		&bar0->rmac_addr_cmd_mem, 0,
4708		XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4709		XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4710		/* upper layer may require to repeat */
4711		return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
4712	}
4713
4714	return XGE_HAL_OK;
4715}
4716
4717/**
4718 * xge_hal_device_mcast_disable - Disable Xframe multicast addresses.
4719 * @hldev: HAL device handle.
4720 *
4721 * Disable Xframe multicast addresses.
4722 * Returns: XGE_HAL_OK - success.
4723 * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to disable mcast
4724 * feature within the time(timeout).
4725 *
4726 * See also: xge_hal_device_mcast_enable(), xge_hal_status_e{}.
4727 */
4728xge_hal_status_e
4729xge_hal_device_mcast_disable(xge_hal_device_t *hldev)
4730{
4731	u64 val64;
4732	xge_hal_pci_bar0_t *bar0;
4733	int mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET;
4734
4735	if (hldev == NULL)
4736		return XGE_HAL_ERR_INVALID_DEVICE;
4737
4738	if (hldev->mcast_refcnt == 0)
4739		return XGE_HAL_OK;
4740
4741	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
4742		mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET_HERC;
4743
4744	hldev->mcast_refcnt = 0;
4745
4746	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4747
4748	/*  Disable all Multicast addresses */
4749	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4750	       XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0xffffffffffffULL),
4751		       &bar0->rmac_addr_data0_mem);
4752	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4753	       XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0),
4754		       &bar0->rmac_addr_data1_mem);
4755
4756	val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
4757		XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4758		XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET(mc_offset);
4759	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4760		            &bar0->rmac_addr_cmd_mem);
4761
4762	if (__hal_device_register_poll(hldev,
4763		&bar0->rmac_addr_cmd_mem, 0,
4764		XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4765		XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4766		/* upper layer may require to repeat */
4767		return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
4768	}
4769
4770	return XGE_HAL_OK;
4771}
4772
4773/**
4774 * xge_hal_device_promisc_enable - Enable promiscuous mode.
4775 * @hldev: HAL device handle.
4776 *
4777 * Enable promiscuous mode of Xframe operation.
4778 *
4779 * See also: xge_hal_device_promisc_disable().
4780 */
4781void
4782xge_hal_device_promisc_enable(xge_hal_device_t *hldev)
4783{
4784	u64 val64;
4785	xge_hal_pci_bar0_t *bar0;
4786
4787	xge_assert(hldev);
4788
4789	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4790
4791	if (!hldev->is_promisc) {
4792		/*  Put the NIC into promiscuous mode */
4793		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4794		                            &bar0->mac_cfg);
4795		val64 |= XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE;
4796
4797		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4798			       XGE_HAL_RMAC_CFG_KEY(0x4C0D),
4799			       &bar0->rmac_cfg_key);
4800
4801		__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
4802				      (u32)(val64 >> 32),
4803				      &bar0->mac_cfg);
4804
4805		hldev->is_promisc = 1;
4806		xge_debug_device(XGE_TRACE,
4807			"mac_cfg 0x"XGE_OS_LLXFMT": promisc enabled",
4808			(unsigned long long)val64);
4809	}
4810}
4811
4812/**
4813 * xge_hal_device_promisc_disable - Disable promiscuous mode.
4814 * @hldev: HAL device handle.
4815 *
4816 * Disable promiscuous mode of Xframe operation.
4817 *
4818 * See also: xge_hal_device_promisc_enable().
4819 */
4820void
4821xge_hal_device_promisc_disable(xge_hal_device_t *hldev)
4822{
4823	u64 val64;
4824	xge_hal_pci_bar0_t *bar0;
4825
4826	xge_assert(hldev);
4827
4828	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4829
4830	if (hldev->is_promisc) {
4831		/*  Remove the NIC from promiscuous mode */
4832		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4833					    &bar0->mac_cfg);
4834		val64 &= ~XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE;
4835
4836		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4837			       XGE_HAL_RMAC_CFG_KEY(0x4C0D),
4838			       &bar0->rmac_cfg_key);
4839
4840		__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
4841				      (u32)(val64 >> 32),
4842				      &bar0->mac_cfg);
4843
4844		hldev->is_promisc = 0;
4845		xge_debug_device(XGE_TRACE,
4846			"mac_cfg 0x"XGE_OS_LLXFMT": promisc disabled",
4847			(unsigned long long)val64);
4848	}
4849}
4850
4851/**
4852 * xge_hal_device_macaddr_get - Get MAC addresses.
4853 * @hldev: HAL device handle.
4854 * @index: MAC address index, in the range from 0 to
4855 * XGE_HAL_MAX_MAC_ADDRESSES.
4856 * @macaddr: MAC address. Returned by HAL.
4857 *
4858 * Retrieve one of the stored MAC addresses by reading non-volatile
4859 * memory on the chip.
4860 *
4861 * Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
4862 *
4863 * Returns: XGE_HAL_OK - success.
4864 * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
4865 * address within the time(timeout).
4866 * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
4867 *
4868 * See also: xge_hal_device_macaddr_set(), xge_hal_status_e{}.
4869 */
4870xge_hal_status_e
4871xge_hal_device_macaddr_get(xge_hal_device_t *hldev, int index,
4872			macaddr_t *macaddr)
4873{
4874	xge_hal_pci_bar0_t *bar0;
4875	u64 val64;
4876	int i;
4877
4878	if (hldev == NULL) {
4879		return XGE_HAL_ERR_INVALID_DEVICE;
4880	}
4881
4882	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4883
4884	if ( index >= XGE_HAL_MAX_MAC_ADDRESSES ) {
4885		return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
4886	}
4887
4888#ifdef XGE_HAL_HERC_EMULATION
4889	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,0x0000010000000000,
4890	                            &bar0->rmac_addr_data0_mem);
4891	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,0x0000000000000000,
4892	                            &bar0->rmac_addr_data1_mem);
4893    val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_RD |
4894				 XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4895				 XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index));
4896	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4897	                     &bar0->rmac_addr_cmd_mem);
4898
4899		/* poll until done */
4900	__hal_device_register_poll(hldev,
4901		       &bar0->rmac_addr_cmd_mem, 0,
4902		       XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD,
4903		       XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS);
4904
4905#endif
4906
4907	val64 = ( XGE_HAL_RMAC_ADDR_CMD_MEM_RD |
4908		  XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4909		  XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index)) );
4910	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4911	                     &bar0->rmac_addr_cmd_mem);
4912
4913	if (__hal_device_register_poll(hldev, &bar0->rmac_addr_cmd_mem, 0,
4914		   XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4915		   XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4916		/* upper layer may require to repeat */
4917		return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
4918	}
4919
4920	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4921	                            &bar0->rmac_addr_data0_mem);
4922	for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
4923		(*macaddr)[i] = (u8)(val64 >> ((64 - 8) - (i * 8)));
4924	}
4925
4926#ifdef XGE_HAL_HERC_EMULATION
4927	for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
4928		(*macaddr)[i] = (u8)0;
4929	}
4930	(*macaddr)[1] = (u8)1;
4931
4932#endif
4933
4934	return XGE_HAL_OK;
4935}
4936
4937/**
4938 * xge_hal_device_macaddr_set - Set MAC address.
4939 * @hldev: HAL device handle.
4940 * @index: MAC address index, in the range from 0 to
4941 * XGE_HAL_MAX_MAC_ADDRESSES.
4942 * @macaddr: New MAC address to configure.
4943 *
4944 * Configure one of the available MAC address "slots".
4945 *
4946 * Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
4947 *
4948 * Returns: XGE_HAL_OK - success.
4949 * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to set the new mac
4950 * address within the time(timeout).
4951 * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
4952 *
4953 * See also: xge_hal_device_macaddr_get(), xge_hal_status_e{}.
4954 */
4955xge_hal_status_e
4956xge_hal_device_macaddr_set(xge_hal_device_t *hldev, int index,
4957			macaddr_t macaddr)
4958{
4959	xge_hal_pci_bar0_t *bar0 =
4960		(xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4961	u64 val64, temp64;
4962	int i;
4963
4964	if ( index >= XGE_HAL_MAX_MAC_ADDRESSES )
4965		return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
4966
4967	temp64 = 0;
4968	for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
4969		temp64 |= macaddr[i];
4970		temp64 <<= 8;
4971	}
4972	temp64 >>= 8;
4973
4974	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4975	                XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(temp64),
4976		        &bar0->rmac_addr_data0_mem);
4977
4978	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4979	                XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0ULL),
4980		        &bar0->rmac_addr_data1_mem);
4981
4982	val64 = ( XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
4983		  XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4984		  XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index)) );
4985
4986	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4987	                     &bar0->rmac_addr_cmd_mem);
4988
4989	if (__hal_device_register_poll(hldev, &bar0->rmac_addr_cmd_mem, 0,
4990		   XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4991		   XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4992		/* upper layer may require to repeat */
4993		return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
4994	}
4995
4996	return XGE_HAL_OK;
4997}
4998
4999/**
5000 * xge_hal_device_macaddr_clear - Set MAC address.
5001 * @hldev: HAL device handle.
5002 * @index: MAC address index, in the range from 0 to
5003 * XGE_HAL_MAX_MAC_ADDRESSES.
5004 *
5005 * Clear one of the available MAC address "slots".
5006 *
5007 * Returns: XGE_HAL_OK - success.
5008 * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to set the new mac
5009 * address within the time(timeout).
5010 * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
5011 *
5012 * See also: xge_hal_device_macaddr_set(), xge_hal_status_e{}.
5013 */
5014xge_hal_status_e
5015xge_hal_device_macaddr_clear(xge_hal_device_t *hldev, int index)
5016{
5017	xge_hal_status_e status;
5018	u8 macaddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
5019
5020	status = xge_hal_device_macaddr_set(hldev, index, macaddr);
5021	if (status != XGE_HAL_OK) {
5022		xge_debug_device(XGE_ERR, "%s",
5023			"Not able to set the mac addr");
5024		return status;
5025	}
5026
5027	return XGE_HAL_OK;
5028}
5029
5030/**
5031 * xge_hal_device_macaddr_find - Finds index in the rmac table.
5032 * @hldev: HAL device handle.
5033 * @wanted: Wanted MAC address.
5034 *
5035 * See also: xge_hal_device_macaddr_set().
5036 */
5037int
5038xge_hal_device_macaddr_find(xge_hal_device_t *hldev, macaddr_t wanted)
5039{
5040	int i;
5041	macaddr_t macaddr;
5042
5043	if (hldev == NULL) {
5044		return XGE_HAL_ERR_INVALID_DEVICE;
5045	}
5046
5047	for (i=0; i<XGE_HAL_MAX_MAC_ADDRESSES; i++) {
5048		(void) xge_hal_device_macaddr_get(hldev, i, &macaddr);
5049		if (!xge_os_memcmp(macaddr, wanted, sizeof(macaddr_t))) {
5050			return i;
5051		}
5052	}
5053
5054	return -1;
5055}
5056
5057/**
5058 * xge_hal_device_mtu_set - Set MTU.
5059 * @hldev: HAL device handle.
5060 * @new_mtu: New MTU size to configure.
5061 *
5062 * Set new MTU value. Example, to use jumbo frames:
5063 * xge_hal_device_mtu_set(my_device, my_channel, 9600);
5064 *
5065 * Returns: XGE_HAL_OK on success.
5066 * XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control
5067 * register.
5068 * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to initialize TTI/RTI
5069 * schemes.
5070 * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
5071 * a "quiescent" state.
5072 */
5073xge_hal_status_e
5074xge_hal_device_mtu_set(xge_hal_device_t *hldev, int new_mtu)
5075{
5076	xge_hal_status_e status;
5077
5078	/*
5079	 * reset needed if 1) new MTU differs, and
5080	 * 2a) device was closed or
5081	 * 2b) device is being upped for first time.
5082	 */
5083	if (hldev->config.mtu != new_mtu) {
5084		if (hldev->reset_needed_after_close ||
5085			!hldev->mtu_first_time_set) {
5086			status = xge_hal_device_reset(hldev);
5087			if (status != XGE_HAL_OK) {
5088				xge_debug_device(XGE_TRACE, "%s",
5089					  "fatal: can not reset the device");
5090				return status;
5091			}
5092		}
5093		/* store the new MTU in device, reset will use it */
5094		hldev->config.mtu = new_mtu;
5095		xge_debug_device(XGE_TRACE, "new MTU %d applied",
5096				 new_mtu);
5097	}
5098
5099	if (!hldev->mtu_first_time_set)
5100		hldev->mtu_first_time_set = 1;
5101
5102	return XGE_HAL_OK;
5103}
5104
5105/**
5106 * xge_hal_device_initialize - Initialize Xframe device.
5107 * @hldev: HAL device handle.
5108 * @attr: pointer to xge_hal_device_attr_t structure
5109 * @device_config: Configuration to be _applied_ to the device,
5110 *                 For the Xframe configuration "knobs" please
5111 *                 refer to xge_hal_device_config_t and Xframe
5112 *                 User Guide.
5113 *
5114 * Initialize Xframe device. Note that all the arguments of this public API
5115 * are 'IN', including @hldev. Upper-layer driver (ULD) cooperates with
5116 * OS to find new Xframe device, locate its PCI and memory spaces.
5117 *
5118 * When done, the ULD allocates sizeof(xge_hal_device_t) bytes for HAL
5119 * to enable the latter to perform Xframe hardware initialization.
5120 *
5121 * Returns: XGE_HAL_OK - success.
5122 * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - Driver is not initialized.
5123 * XGE_HAL_ERR_BAD_DEVICE_CONFIG - Device configuration params are not
5124 * valid.
5125 * XGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed.
5126 * XGE_HAL_ERR_BAD_SUBSYSTEM_ID - Device subsystem id is invalid.
5127 * XGE_HAL_ERR_INVALID_MAC_ADDRESS - Device mac address in not valid.
5128 * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
5129 * address within the time(timeout) or TTI/RTI initialization failed.
5130 * XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control.
5131 * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT -Device is not queiscent.
5132 *
5133 * See also: xge_hal_device_terminate(), xge_hal_status_e{}
5134 * xge_hal_device_attr_t{}.
5135 */
5136xge_hal_status_e
5137xge_hal_device_initialize(xge_hal_device_t *hldev, xge_hal_device_attr_t *attr,
5138		xge_hal_device_config_t *device_config)
5139{
5140	int i;
5141	xge_hal_status_e status;
5142	xge_hal_channel_t *channel;
5143	u16 subsys_device;
5144	u16 subsys_vendor;
5145	int total_dram_size, ring_auto_dram_cfg, left_dram_size;
5146	int total_dram_size_max = 0;
5147
5148	xge_debug_device(XGE_TRACE, "device 0x"XGE_OS_LLXFMT" is initializing",
5149			 (unsigned long long)(ulong_t)hldev);
5150
5151	/* sanity check */
5152	if (g_xge_hal_driver == NULL ||
5153	    !g_xge_hal_driver->is_initialized) {
5154		return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
5155	}
5156
5157	xge_os_memzero(hldev, sizeof(xge_hal_device_t));
5158
5159	/*
5160	 * validate a common part of Xframe-I/II configuration
5161	 * (and run check_card() later, once PCI inited - see below)
5162	 */
5163	status = __hal_device_config_check_common(device_config);
5164	if (status != XGE_HAL_OK)
5165		return status;
5166
5167	/* apply config */
5168	xge_os_memcpy(&hldev->config, device_config,
5169                      sizeof(xge_hal_device_config_t));
5170
5171	/* save original attr */
5172	xge_os_memcpy(&hldev->orig_attr, attr,
5173                      sizeof(xge_hal_device_attr_t));
5174
5175	/* initialize rxufca_intr_thres */
5176	hldev->rxufca_intr_thres = hldev->config.rxufca_intr_thres;
5177
5178	hldev->regh0 = attr->regh0;
5179	hldev->regh1 = attr->regh1;
5180	hldev->regh2 = attr->regh2;
5181	hldev->isrbar0 = hldev->bar0 = attr->bar0;
5182	hldev->bar1 = attr->bar1;
5183	hldev->bar2 = attr->bar2;
5184	hldev->pdev = attr->pdev;
5185	hldev->irqh = attr->irqh;
5186	hldev->cfgh = attr->cfgh;
5187
5188	/* set initial bimodal timer for bimodal adaptive schema */
5189	hldev->bimodal_timer_val_us = hldev->config.bimodal_timer_lo_us;
5190
5191	hldev->queueh = xge_queue_create(hldev->pdev, hldev->irqh,
5192				  g_xge_hal_driver->config.queue_size_initial,
5193				  g_xge_hal_driver->config.queue_size_max,
5194				  __hal_device_event_queued, hldev);
5195	if (hldev->queueh == NULL)
5196		return XGE_HAL_ERR_OUT_OF_MEMORY;
5197
5198	hldev->magic = XGE_HAL_MAGIC;
5199
5200	xge_assert(hldev->regh0);
5201	xge_assert(hldev->regh1);
5202	xge_assert(hldev->bar0);
5203	xge_assert(hldev->bar1);
5204	xge_assert(hldev->pdev);
5205	xge_assert(hldev->irqh);
5206	xge_assert(hldev->cfgh);
5207
5208	/* initialize some PCI/PCI-X fields of this PCI device. */
5209	__hal_device_pci_init(hldev);
5210
5211	/*
5212	 * initlialize lists to properly handling a potential
5213	 * terminate request
5214	 */
5215	xge_list_init(&hldev->free_channels);
5216	xge_list_init(&hldev->fifo_channels);
5217	xge_list_init(&hldev->ring_channels);
5218
5219	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
5220		/* fixups for xena */
5221		hldev->config.rth_en = 0;
5222		hldev->config.rth_spdm_en = 0;
5223		hldev->config.rts_mac_en = 0;
5224		total_dram_size_max = XGE_HAL_MAX_RING_QUEUE_SIZE_XENA;
5225
5226		status = __hal_device_config_check_xena(device_config);
5227		if (status != XGE_HAL_OK) {
5228			xge_hal_device_terminate(hldev);
5229			return status;
5230		}
5231		if (hldev->config.bimodal_interrupts == 1) {
5232			xge_hal_device_terminate(hldev);
5233			return XGE_HAL_BADCFG_BIMODAL_XENA_NOT_ALLOWED;
5234		} else if (hldev->config.bimodal_interrupts ==
5235		    XGE_HAL_DEFAULT_USE_HARDCODE)
5236			hldev->config.bimodal_interrupts = 0;
5237	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
5238		/* fixups for herc */
5239		total_dram_size_max = XGE_HAL_MAX_RING_QUEUE_SIZE_HERC;
5240		status = __hal_device_config_check_herc(device_config);
5241		if (status != XGE_HAL_OK) {
5242			xge_hal_device_terminate(hldev);
5243			return status;
5244		}
5245		if (hldev->config.bimodal_interrupts ==
5246		    XGE_HAL_DEFAULT_USE_HARDCODE)
5247			hldev->config.bimodal_interrupts = 1;
5248	} else {
5249		xge_debug_device(XGE_ERR,
5250			  "detected unknown device_id 0x%x", hldev->device_id);
5251		xge_hal_device_terminate(hldev);
5252		return XGE_HAL_ERR_BAD_DEVICE_ID;
5253	}
5254
5255
5256	/* allocate and initialize FIFO types of channels according to
5257	 * configuration */
5258	for (i = 0; i < XGE_HAL_MAX_FIFO_NUM; i++) {
5259		if (!device_config->fifo.queue[i].configured)
5260			continue;
5261
5262		channel = __hal_channel_allocate(hldev, i,
5263						 XGE_HAL_CHANNEL_TYPE_FIFO);
5264		if (channel == NULL) {
5265			xge_debug_device(XGE_ERR,
5266				"fifo: __hal_channel_allocate failed");
5267			xge_hal_device_terminate(hldev);
5268			return XGE_HAL_ERR_OUT_OF_MEMORY;
5269		}
5270		/* add new channel to the device */
5271		xge_list_insert(&channel->item, &hldev->free_channels);
5272	}
5273
5274	/*
5275	 * automatic DRAM adjustment
5276	 */
5277	total_dram_size = 0;
5278	ring_auto_dram_cfg = 0;
5279	for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
5280		if (!device_config->ring.queue[i].configured)
5281			continue;
5282		if (device_config->ring.queue[i].dram_size_mb ==
5283		    XGE_HAL_DEFAULT_USE_HARDCODE) {
5284			ring_auto_dram_cfg++;
5285			continue;
5286		}
5287		total_dram_size += device_config->ring.queue[i].dram_size_mb;
5288	}
5289	left_dram_size = total_dram_size_max - total_dram_size;
5290	if (left_dram_size < 0 ||
5291	    (ring_auto_dram_cfg && left_dram_size / ring_auto_dram_cfg == 0))  {
5292		xge_debug_device(XGE_ERR,
5293			 "ring config: exceeded DRAM size %d MB",
5294			 total_dram_size_max);
5295		xge_hal_device_terminate(hldev);
5296                return XGE_HAL_BADCFG_RING_QUEUE_SIZE;
5297        }
5298
5299	/*
5300	 * allocate and initialize RING types of channels according to
5301	 * configuration
5302	 */
5303	for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
5304		if (!device_config->ring.queue[i].configured)
5305			continue;
5306
5307		if (device_config->ring.queue[i].dram_size_mb ==
5308		    XGE_HAL_DEFAULT_USE_HARDCODE) {
5309			hldev->config.ring.queue[i].dram_size_mb =
5310				device_config->ring.queue[i].dram_size_mb =
5311					left_dram_size / ring_auto_dram_cfg;
5312		}
5313
5314		channel = __hal_channel_allocate(hldev, i,
5315						 XGE_HAL_CHANNEL_TYPE_RING);
5316		if (channel == NULL) {
5317			xge_debug_device(XGE_ERR,
5318				"ring: __hal_channel_allocate failed");
5319			xge_hal_device_terminate(hldev);
5320			return XGE_HAL_ERR_OUT_OF_MEMORY;
5321		}
5322		/* add new channel to the device */
5323		xge_list_insert(&channel->item, &hldev->free_channels);
5324	}
5325
5326	/* get subsystem IDs */
5327	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
5328		xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
5329		&subsys_device);
5330	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
5331		xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
5332		&subsys_vendor);
5333	xge_debug_device(XGE_TRACE,
5334                         "subsystem_id %04x:%04x",
5335                         subsys_vendor, subsys_device);
5336
5337	/* reset device initially */
5338	(void) __hal_device_reset(hldev);
5339
5340	/* set host endian before, to assure proper action */
5341	status = __hal_device_set_swapper(hldev);
5342	if (status != XGE_HAL_OK) {
5343		xge_debug_device(XGE_ERR,
5344			"__hal_device_set_swapper failed");
5345		xge_hal_device_terminate(hldev);
5346		(void) __hal_device_reset(hldev);
5347		return status;
5348	}
5349
5350#ifndef XGE_HAL_HERC_EMULATION
5351	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
5352		__hal_device_xena_fix_mac(hldev);
5353#endif
5354
5355	/*  MAC address initialization.
5356	 *  For now only one mac address will be read and used.  */
5357	status = xge_hal_device_macaddr_get(hldev, 0, &hldev->macaddr[0]);
5358	if (status != XGE_HAL_OK) {
5359		xge_debug_device(XGE_ERR,
5360			"xge_hal_device_macaddr_get failed");
5361		xge_hal_device_terminate(hldev);
5362		return status;
5363	}
5364
5365	if (hldev->macaddr[0][0] == 0xFF &&
5366	    hldev->macaddr[0][1] == 0xFF &&
5367	    hldev->macaddr[0][2] == 0xFF &&
5368	    hldev->macaddr[0][3] == 0xFF &&
5369	    hldev->macaddr[0][4] == 0xFF &&
5370	    hldev->macaddr[0][5] == 0xFF) {
5371		xge_debug_device(XGE_ERR,
5372			"xge_hal_device_macaddr_get returns all FFs");
5373		xge_hal_device_terminate(hldev);
5374		return XGE_HAL_ERR_INVALID_MAC_ADDRESS;
5375	}
5376
5377	xge_debug_device(XGE_TRACE,
5378			  "default macaddr: 0x%02x-%02x-%02x-%02x-%02x-%02x",
5379			  hldev->macaddr[0][0], hldev->macaddr[0][1],
5380			  hldev->macaddr[0][2], hldev->macaddr[0][3],
5381			  hldev->macaddr[0][4], hldev->macaddr[0][5]);
5382
5383	status = __hal_stats_initialize(&hldev->stats, hldev);
5384	if (status != XGE_HAL_OK) {
5385		xge_debug_device(XGE_ERR,
5386			"__hal_stats_initialize failed");
5387		xge_hal_device_terminate(hldev);
5388		return status;
5389	}
5390
5391	status = __hal_device_hw_initialize(hldev);
5392	if (status != XGE_HAL_OK) {
5393		xge_debug_device(XGE_ERR,
5394			"__hal_device_hw_initialize failed");
5395		xge_hal_device_terminate(hldev);
5396		return status;
5397	}
5398	hldev->dump_buf=(char*)xge_os_malloc(hldev->pdev, XGE_HAL_DUMP_BUF_SIZE);
5399	if (hldev->dump_buf == NULL)  {
5400		xge_debug_device(XGE_ERR,
5401			"__hal_device_hw_initialize failed");
5402		xge_hal_device_terminate(hldev);
5403                return XGE_HAL_ERR_OUT_OF_MEMORY;
5404	}
5405
5406
5407	/* Xena-only: need to serialize fifo posts across all device fifos */
5408#if defined(XGE_HAL_TX_MULTI_POST)
5409	xge_os_spin_lock_init(&hldev->xena_post_lock, hldev->pdev);
5410#elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
5411	xge_os_spin_lock_init_irq(&hldev->xena_post_lock, hldev->irqh);
5412#endif
5413	 /* Getting VPD data */
5414        __hal_device_get_vpd_data(hldev);
5415
5416	hldev->is_initialized = 1;
5417
5418	return XGE_HAL_OK;
5419}
5420
5421/**
5422 * xge_hal_device_terminating - Mark the device as 'terminating'.
5423 * @devh: HAL device handle.
5424 *
5425 * Mark the device as 'terminating', going to terminate. Can be used
5426 * to serialize termination with other running processes/contexts.
5427 *
5428 * See also: xge_hal_device_terminate().
5429 */
5430void
5431xge_hal_device_terminating(xge_hal_device_h devh)
5432{
5433	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
5434	xge_list_t *item;
5435	xge_hal_channel_t *channel;
5436#if defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
5437	unsigned long flags = 0;
5438#endif
5439
5440	/*
5441	 * go through each opened tx channel and aquire
5442	 * lock, so it will serialize with HAL termination flag
5443	 */
5444	xge_list_for_each(item, &hldev->fifo_channels) {
5445		channel = xge_container_of(item, xge_hal_channel_t, item);
5446#if defined(XGE_HAL_TX_MULTI_RESERVE)
5447	xge_os_spin_lock(&channel->reserve_lock);
5448#elif defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
5449	xge_os_spin_lock_irq(&channel->reserve_lock, flags);
5450#endif
5451
5452	channel->terminating = 1;
5453
5454#if defined(XGE_HAL_TX_MULTI_RESERVE)
5455	xge_os_spin_unlock(&channel->reserve_lock);
5456#elif defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
5457	xge_os_spin_unlock_irq(&channel->reserve_lock, flags);
5458#endif
5459	}
5460
5461	hldev->terminating = 1;
5462}
5463
5464/**
5465 * xge_hal_device_terminate - Terminate Xframe device.
5466 * @hldev: HAL device handle.
5467 *
5468 * Terminate HAL device.
5469 *
5470 * See also: xge_hal_device_initialize().
5471 */
5472void
5473xge_hal_device_terminate(xge_hal_device_t *hldev)
5474{
5475	xge_assert(g_xge_hal_driver != NULL);
5476	xge_assert(hldev != NULL);
5477	xge_assert(hldev->magic == XGE_HAL_MAGIC);
5478
5479	xge_queue_flush(hldev->queueh);
5480
5481	hldev->terminating = 1;
5482	hldev->is_initialized = 0;
5483        hldev->in_poll = 0;
5484	hldev->magic = XGE_HAL_DEAD;
5485
5486#if defined(XGE_HAL_TX_MULTI_POST)
5487	xge_os_spin_lock_destroy(&hldev->xena_post_lock, hldev->pdev);
5488#elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
5489	xge_os_spin_lock_destroy_irq(&hldev->xena_post_lock, hldev->pdev);
5490#endif
5491
5492	xge_debug_device(XGE_TRACE, "device "XGE_OS_LLXFMT" is terminating",
5493				(unsigned long long)(ulong_t)hldev);
5494
5495	xge_assert(xge_list_is_empty(&hldev->fifo_channels));
5496	xge_assert(xge_list_is_empty(&hldev->ring_channels));
5497
5498	if (hldev->stats.is_initialized) {
5499		__hal_stats_terminate(&hldev->stats);
5500	}
5501
5502	/* close if open and free all channels */
5503	while (!xge_list_is_empty(&hldev->free_channels)) {
5504		xge_hal_channel_t *channel = (xge_hal_channel_t*)
5505					hldev->free_channels.next;
5506
5507		xge_assert(!channel->is_open);
5508		xge_list_remove(&channel->item);
5509		__hal_channel_free(channel);
5510	}
5511
5512	if (hldev->queueh) {
5513		xge_queue_destroy(hldev->queueh);
5514	}
5515
5516	if (hldev->spdm_table) {
5517		xge_os_free(hldev->pdev,
5518			  hldev->spdm_table[0],
5519			  (sizeof(xge_hal_spdm_entry_t) *
5520				hldev->spdm_max_entries));
5521		xge_os_free(hldev->pdev,
5522			  hldev->spdm_table,
5523			  (sizeof(xge_hal_spdm_entry_t *) *
5524				hldev->spdm_max_entries));
5525		xge_os_spin_lock_destroy(&hldev->spdm_lock, hldev->pdev);
5526		hldev->spdm_table = NULL;
5527	}
5528
5529	if (hldev->dump_buf)  {
5530	        xge_os_free(hldev->pdev, hldev->dump_buf,
5531			    XGE_HAL_DUMP_BUF_SIZE);
5532		hldev->dump_buf = NULL;
5533	}
5534
5535	if (hldev->device_id != 0) {
5536		int j, pcisize;
5537
5538		pcisize = (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)?
5539				   XGE_HAL_PCISIZE_HERC : XGE_HAL_PCISIZE_XENA;
5540		for (j = 0; j < pcisize; j++) {
5541			xge_os_pci_write32(hldev->pdev, hldev->cfgh, j * 4,
5542				*((u32*)&hldev->pci_config_space_bios + j));
5543		}
5544	}
5545}
5546/**
5547 * __hal_device_get_vpd_data - Getting vpd_data.
5548 *
5549 *   @hldev: HAL device handle.
5550 *
5551 *   Getting  product name and serial number from vpd capabilites structure
5552 *
5553 */
5554void
5555__hal_device_get_vpd_data(xge_hal_device_t *hldev)
5556{
5557    u8 * vpd_data;
5558    u8   data;
5559    int  index = 0, count, fail = 0;
5560    u8   vpd_addr = XGE_HAL_CARD_XENA_VPD_ADDR;
5561    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
5562        vpd_addr = XGE_HAL_CARD_HERC_VPD_ADDR;
5563
5564    xge_os_strlcpy((char *) hldev->vpd_data.product_name,
5565                "10 Gigabit Ethernet Adapter",
5566		sizeof(hldev->vpd_data.product_name));
5567
5568    xge_os_strlcpy((char *) hldev->vpd_data.serial_num,
5569		"not available",
5570		sizeof(hldev->vpd_data.serial_num));
5571
5572    vpd_data = ( u8*) xge_os_malloc(hldev->pdev, XGE_HAL_VPD_BUFFER_SIZE + 16);
5573    if ( vpd_data == 0 )
5574        return;
5575
5576    for (index = 0; index < XGE_HAL_VPD_BUFFER_SIZE; index +=4 ) {
5577        xge_os_pci_write8(hldev->pdev, hldev->cfgh, (vpd_addr + 2), (u8)index);
5578        xge_os_pci_read8(hldev->pdev, hldev->cfgh,(vpd_addr + 2), &data);
5579        xge_os_pci_write8(hldev->pdev, hldev->cfgh, (vpd_addr + 3), 0);
5580        for (count = 0; count < 5; count++ ) {
5581            xge_os_mdelay(2);
5582            xge_os_pci_read8(hldev->pdev, hldev->cfgh,(vpd_addr + 3), &data);
5583            if (data == XGE_HAL_VPD_READ_COMPLETE)
5584                break;
5585        }
5586
5587        if (count >= 5) {
5588            xge_os_printf("ERR, Reading VPD data failed");
5589            fail = 1;
5590            break;
5591        }
5592
5593        xge_os_pci_read32(hldev->pdev, hldev->cfgh,(vpd_addr + 4),
5594                (u32 *)&vpd_data[index]);
5595    }
5596
5597    if(!fail) {
5598
5599        /* read serial number of adapter */
5600        for (count = 0; count < XGE_HAL_VPD_BUFFER_SIZE; count++) {
5601            if ((vpd_data[count] == 'S')     &&
5602                (vpd_data[count + 1] == 'N') &&
5603                (vpd_data[count + 2] < XGE_HAL_VPD_LENGTH)) {
5604                    (void) memset(hldev->vpd_data.serial_num, 0, XGE_HAL_VPD_LENGTH);
5605                    (void) memcpy(hldev->vpd_data.serial_num, &vpd_data[count + 3],
5606                        vpd_data[count + 2]);
5607                    break;
5608            }
5609        }
5610
5611        if (vpd_data[1] < XGE_HAL_VPD_LENGTH) {
5612            (void) memset(hldev->vpd_data.product_name, 0, vpd_data[1]);
5613            (void) memcpy(hldev->vpd_data.product_name, &vpd_data[3], vpd_data[1]);
5614        }
5615
5616    }
5617
5618    xge_os_free(hldev->pdev, vpd_data, XGE_HAL_VPD_BUFFER_SIZE + 16);
5619}
5620
5621
5622/**
5623 * xge_hal_device_handle_tcode - Handle transfer code.
5624 * @channelh: Channel handle.
5625 * @dtrh: Descriptor handle.
5626 * @t_code: One of the enumerated (and documented in the Xframe user guide)
5627 *          "transfer codes".
5628 *
5629 * Handle descriptor's transfer code. The latter comes with each completed
5630 * descriptor, see xge_hal_fifo_dtr_next_completed() and
5631 * xge_hal_ring_dtr_next_completed().
5632 * Transfer codes are enumerated in xgehal-fifo.h and xgehal-ring.h.
5633 *
5634 * Returns: one of the xge_hal_status_e{} enumerated types.
5635 * XGE_HAL_OK			- for success.
5636 * XGE_HAL_ERR_CRITICAL         - when encounters critical error.
5637 */
5638xge_hal_status_e
5639xge_hal_device_handle_tcode (xge_hal_channel_h channelh,
5640			     xge_hal_dtr_h dtrh, u8 t_code)
5641{
5642	xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
5643	xge_hal_device_t *hldev = (xge_hal_device_t *)channel->devh;
5644
5645	if (t_code > 15) {
5646		xge_os_printf("invalid t_code %d", t_code);
5647		return XGE_HAL_OK;
5648	}
5649
5650	if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
5651	        hldev->stats.sw_dev_err_stats.txd_t_code_err_cnt[t_code]++;
5652
5653#if defined(XGE_HAL_DEBUG_BAD_TCODE)
5654        xge_hal_fifo_txd_t *txdp = (xge_hal_fifo_txd_t *)dtrh;
5655        xge_os_printf(""XGE_OS_LLXFMT":"XGE_OS_LLXFMT":"
5656		XGE_OS_LLXFMT":"XGE_OS_LLXFMT,
5657		txdp->control_1, txdp->control_2, txdp->buffer_pointer,
5658		txdp->host_control);
5659#endif
5660
5661		/* handle link "down" immediately without going through
5662		 * xge_hal_device_poll() routine. */
5663		if (t_code == XGE_HAL_TXD_T_CODE_LOSS_OF_LINK) {
5664			/* link is down */
5665			if (hldev->link_state != XGE_HAL_LINK_DOWN) {
5666				xge_hal_pci_bar0_t *bar0 =
5667				(xge_hal_pci_bar0_t *)(void *)hldev->bar0;
5668				u64 val64;
5669
5670				hldev->link_state = XGE_HAL_LINK_DOWN;
5671
5672				val64 = xge_os_pio_mem_read64(hldev->pdev,
5673				    hldev->regh0, &bar0->adapter_control);
5674
5675				/* turn off LED */
5676				val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
5677				xge_os_pio_mem_write64(hldev->pdev,
5678						hldev->regh0, val64,
5679						&bar0->adapter_control);
5680
5681				g_xge_hal_driver->uld_callbacks.link_down(
5682						hldev->upper_layer_info);
5683			}
5684		} else if (t_code == XGE_HAL_TXD_T_CODE_ABORT_BUFFER ||
5685		           t_code == XGE_HAL_TXD_T_CODE_ABORT_DTOR) {
5686                        __hal_device_handle_targetabort(hldev);
5687			return XGE_HAL_ERR_CRITICAL;
5688		}
5689		return XGE_HAL_ERR_PKT_DROP;
5690	} else if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
5691	        hldev->stats.sw_dev_err_stats.rxd_t_code_err_cnt[t_code]++;
5692
5693#if defined(XGE_HAL_DEBUG_BAD_TCODE)
5694		xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
5695		xge_os_printf(""XGE_OS_LLXFMT":"XGE_OS_LLXFMT":"XGE_OS_LLXFMT
5696			":"XGE_OS_LLXFMT, rxdp->control_1,
5697			rxdp->control_2, rxdp->buffer0_ptr,
5698			rxdp->host_control);
5699#endif
5700		if (t_code == XGE_HAL_RXD_T_CODE_BAD_ECC) {
5701			hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
5702			__hal_device_handle_eccerr(hldev, "rxd_t_code",
5703						   (u64)t_code);
5704			return XGE_HAL_ERR_CRITICAL;
5705		} else if (t_code == XGE_HAL_RXD_T_CODE_PARITY ||
5706			   t_code == XGE_HAL_RXD_T_CODE_PARITY_ABORT) {
5707			hldev->stats.sw_dev_err_stats.parity_err_cnt++;
5708			__hal_device_handle_parityerr(hldev, "rxd_t_code",
5709						      (u64)t_code);
5710			return XGE_HAL_ERR_CRITICAL;
5711		/* do not drop if detected unknown IPv6 extension */
5712		} else if (t_code != XGE_HAL_RXD_T_CODE_UNKNOWN_PROTO) {
5713			return XGE_HAL_ERR_PKT_DROP;
5714		}
5715	}
5716	return XGE_HAL_OK;
5717}
5718
5719/**
5720 * xge_hal_device_link_state - Get link state.
5721 * @devh: HAL device handle.
5722 * @ls: Link state, see xge_hal_device_link_state_e{}.
5723 *
5724 * Get link state.
5725 * Returns: XGE_HAL_OK.
5726 * See also: xge_hal_device_link_state_e{}.
5727 */
5728xge_hal_status_e xge_hal_device_link_state(xge_hal_device_h devh,
5729			xge_hal_device_link_state_e *ls)
5730{
5731	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5732
5733	xge_assert(ls != NULL);
5734	*ls = hldev->link_state;
5735	return XGE_HAL_OK;
5736}
5737
5738/**
5739 * xge_hal_device_sched_timer - Configure scheduled device interrupt.
5740 * @devh: HAL device handle.
5741 * @interval_us: Time interval, in miscoseconds.
5742 *            Unlike transmit and receive interrupts,
5743 *            the scheduled interrupt is generated independently of
5744 *            traffic, but purely based on time.
5745 * @one_shot: 1 - generate scheduled interrupt only once.
5746 *            0 - generate scheduled interrupt periodically at the specified
5747 *            @interval_us interval.
5748 *
5749 * (Re-)configure scheduled interrupt. Can be called at runtime to change
5750 * the setting, generate one-shot interrupts based on the resource and/or
5751 * traffic conditions, other purposes.
5752 * See also: xge_hal_device_config_t{}.
5753 */
5754void xge_hal_device_sched_timer(xge_hal_device_h devh, int interval_us,
5755			int one_shot)
5756{
5757	u64 val64;
5758	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5759	xge_hal_pci_bar0_t *bar0 =
5760		(xge_hal_pci_bar0_t *)(void *)hldev->bar0;
5761	unsigned int interval = hldev->config.pci_freq_mherz * interval_us;
5762
5763	interval = __hal_fix_time_ival_herc(hldev, interval);
5764
5765	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
5766				    &bar0->scheduled_int_ctrl);
5767	if (interval) {
5768		val64 &= XGE_HAL_SCHED_INT_PERIOD_MASK;
5769		val64 |= XGE_HAL_SCHED_INT_PERIOD(interval);
5770		if (one_shot) {
5771			val64 |= XGE_HAL_SCHED_INT_CTRL_ONE_SHOT;
5772		}
5773		val64 |= XGE_HAL_SCHED_INT_CTRL_TIMER_EN;
5774	} else {
5775		val64 &= ~XGE_HAL_SCHED_INT_CTRL_TIMER_EN;
5776	}
5777
5778	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
5779			     val64, &bar0->scheduled_int_ctrl);
5780
5781	xge_debug_device(XGE_TRACE, "sched_timer 0x"XGE_OS_LLXFMT": %s",
5782			  (unsigned long long)val64,
5783			  interval ? "enabled" : "disabled");
5784}
5785
5786/**
5787 * xge_hal_device_check_id - Verify device ID.
5788 * @devh: HAL device handle.
5789 *
5790 * Verify device ID.
5791 * Returns: one of the xge_hal_card_e{} enumerated types.
5792 * See also: xge_hal_card_e{}.
5793 */
5794xge_hal_card_e
5795xge_hal_device_check_id(xge_hal_device_h devh)
5796{
5797	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5798	switch (hldev->device_id) {
5799	case XGE_PCI_DEVICE_ID_XENA_1:
5800	case XGE_PCI_DEVICE_ID_XENA_2:
5801		return XGE_HAL_CARD_XENA;
5802	case XGE_PCI_DEVICE_ID_HERC_1:
5803	case XGE_PCI_DEVICE_ID_HERC_2:
5804		return XGE_HAL_CARD_HERC;
5805	case XGE_PCI_DEVICE_ID_TITAN_1:
5806	case XGE_PCI_DEVICE_ID_TITAN_2:
5807		return XGE_HAL_CARD_TITAN;
5808	default:
5809		return XGE_HAL_CARD_UNKNOWN;
5810	}
5811}
5812
5813/**
5814 * xge_hal_device_pci_info_get - Get PCI bus informations such as width,
5815 *			 frequency, and mode from previously stored values.
5816 * @devh:		HAL device handle.
5817 * @pci_mode:		pointer to a variable of enumerated type
5818 *			xge_hal_pci_mode_e{}.
5819 * @bus_frequency:	pointer to a variable of enumerated type
5820 *			xge_hal_pci_bus_frequency_e{}.
5821 * @bus_width:		pointer to a variable of enumerated type
5822 *			xge_hal_pci_bus_width_e{}.
5823 *
5824 * Get pci mode, frequency, and PCI bus width.
5825 * Returns: one of the xge_hal_status_e{} enumerated types.
5826 * XGE_HAL_OK			- for success.
5827 * XGE_HAL_ERR_INVALID_DEVICE	- for invalid device handle.
5828 * See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
5829 */
5830xge_hal_status_e
5831xge_hal_device_pci_info_get(xge_hal_device_h devh, xge_hal_pci_mode_e *pci_mode,
5832		xge_hal_pci_bus_frequency_e *bus_frequency,
5833		xge_hal_pci_bus_width_e *bus_width)
5834{
5835	xge_hal_status_e rc_status;
5836	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5837
5838	if (!hldev || !hldev->is_initialized || hldev->magic != XGE_HAL_MAGIC) {
5839		rc_status =  XGE_HAL_ERR_INVALID_DEVICE;
5840		xge_debug_device(XGE_ERR,
5841		        "xge_hal_device_pci_info_get error, rc %d for device %p",
5842			rc_status, hldev);
5843
5844		return rc_status;
5845	}
5846
5847	*pci_mode	= hldev->pci_mode;
5848	*bus_frequency	= hldev->bus_frequency;
5849	*bus_width	= hldev->bus_width;
5850	rc_status	= XGE_HAL_OK;
5851	return rc_status;
5852}
5853
5854/**
5855 * xge_hal_reinitialize_hw
5856 * @hldev: private member of the device structure.
5857 *
5858 * This function will soft reset the NIC and re-initalize all the
5859 * I/O registers to the values they had after it's inital initialization
5860 * through the probe function.
5861 */
5862int xge_hal_reinitialize_hw(xge_hal_device_t * hldev)
5863{
5864	(void) xge_hal_device_reset(hldev);
5865	if (__hal_device_hw_initialize(hldev) != XGE_HAL_OK) {
5866		xge_hal_device_terminate(hldev);
5867		(void) __hal_device_reset(hldev);
5868		return 1;
5869	}
5870	return 0;
5871}
5872
5873
5874/*
5875 * __hal_read_spdm_entry_line
5876 * @hldev: pointer to xge_hal_device_t structure
5877 * @spdm_line: spdm line in the spdm entry to be read.
5878 * @spdm_entry: spdm entry of the spdm_line in the SPDM table.
5879 * @spdm_line_val: Contains the value stored in the spdm line.
5880 *
5881 * SPDM table contains upto a maximum of 256 spdm entries.
5882 * Each spdm entry contains 8 lines and each line stores 8 bytes.
5883 * This function reads the spdm line(addressed by @spdm_line)
5884 * of the spdm entry(addressed by @spdm_entry) in
5885 * the SPDM table.
5886 */
5887xge_hal_status_e
5888__hal_read_spdm_entry_line(xge_hal_device_t *hldev, u8 spdm_line,
5889			u16 spdm_entry, u64 *spdm_line_val)
5890{
5891	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
5892	u64 val64;
5893
5894	val64 = XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_STROBE |
5895		XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_LINE_SEL(spdm_line) |
5896		XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_OFFSET(spdm_entry);
5897
5898	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
5899			&bar0->rts_rth_spdm_mem_ctrl);
5900
5901	/* poll until done */
5902	if (__hal_device_register_poll(hldev,
5903		&bar0->rts_rth_spdm_mem_ctrl, 0,
5904		XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_STROBE,
5905		XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
5906
5907		return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
5908	}
5909
5910	*spdm_line_val = xge_os_pio_mem_read64(hldev->pdev,
5911				hldev->regh0, &bar0->rts_rth_spdm_mem_data);
5912	return XGE_HAL_OK;
5913}
5914
5915
5916/*
5917 * __hal_get_free_spdm_entry
5918 * @hldev: pointer to xge_hal_device_t structure
5919 * @spdm_entry: Contains an index to the unused spdm entry in the SPDM table.
5920 *
5921 * This function returns an index of unused spdm entry in the SPDM
5922 * table.
5923 */
5924static xge_hal_status_e
5925__hal_get_free_spdm_entry(xge_hal_device_t *hldev, u16 *spdm_entry)
5926{
5927	xge_hal_status_e status;
5928	u64 spdm_line_val=0;
5929
5930	/*
5931	 * Search in the local SPDM table for a free slot.
5932	 */
5933	*spdm_entry = 0;
5934	for(; *spdm_entry < hldev->spdm_max_entries; (*spdm_entry)++) {
5935		if (hldev->spdm_table[*spdm_entry]->in_use) {
5936			break;
5937		}
5938	}
5939
5940	if (*spdm_entry >= hldev->spdm_max_entries) {
5941		return XGE_HAL_ERR_SPDM_TABLE_FULL;
5942	}
5943
5944	/*
5945	 * Make sure that the corresponding spdm entry in the SPDM
5946	 * table is free.
5947	 * Seventh line of the spdm entry contains information about
5948	 * whether the entry is free or not.
5949	 */
5950	if ((status = __hal_read_spdm_entry_line(hldev, 7, *spdm_entry,
5951					&spdm_line_val)) != XGE_HAL_OK) {
5952		return status;
5953	}
5954
5955	/* BIT(63) in spdm_line 7 corresponds to entry_enable bit */
5956	if ((spdm_line_val & BIT(63))) {
5957		/*
5958		 * Log a warning
5959		 */
5960		xge_debug_device(XGE_ERR, "Local SPDM table is not "
5961			  "consistent with the actual one for the spdm "
5962			  "entry %d", *spdm_entry);
5963		return XGE_HAL_ERR_SPDM_TABLE_DATA_INCONSISTENT;
5964	}
5965
5966	return XGE_HAL_OK;
5967}
5968
5969
5970/*
5971 * __hal_calc_jhash - Calculate Jenkins hash.
5972 * @msg: Jenkins hash algorithm key.
5973 * @length: Length of the key.
5974 * @golden_ratio: Jenkins hash golden ratio.
5975 * @init_value: Jenkins hash initial value.
5976 *
5977 * This function implements the Jenkins based algorithm used for the
5978 * calculation of the RTH hash.
5979 * Returns:  Jenkins hash value.
5980 *
5981 */
5982static u32
5983__hal_calc_jhash(u8 *msg, u32 length, u32 golden_ratio, u32 init_value)
5984{
5985
5986	register u32 a,b,c,len;
5987
5988	/*
5989	 * Set up the internal state
5990	 */
5991	len = length;
5992	a = b = golden_ratio;  /* the golden ratio; an arbitrary value */
5993	c = init_value;         /* the previous hash value */
5994
5995	/*  handle most of the key */
5996	while (len >= 12)
5997	{
5998		a += (msg[0] + ((u32)msg[1]<<8) + ((u32)msg[2]<<16)
5999						 + ((u32)msg[3]<<24));
6000		b += (msg[4] + ((u32)msg[5]<<8) + ((u32)msg[6]<<16)
6001						 + ((u32)msg[7]<<24));
6002		c += (msg[8] + ((u32)msg[9]<<8) + ((u32)msg[10]<<16)
6003						 + ((u32)msg[11]<<24));
6004		mix(a,b,c);
6005		msg += 12; len -= 12;
6006	}
6007
6008	/*  handle the last 11 bytes */
6009	c += length;
6010	switch(len)  /* all the case statements fall through */
6011	{
6012		case 11: c+= ((u32)msg[10]<<24);
6013			 break;
6014		case 10: c+= ((u32)msg[9]<<16);
6015			 break;
6016		case 9 : c+= ((u32)msg[8]<<8);