1 /*-
2  * Copyright (c) 2002-2007 Neterion, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: stable/9/sys/dev/nxge/xgehal/xgehal-device.c 218909 2011-02-21 09:01:34Z brucec $
27  */
28 
29 #include <dev/nxge/include/xgehal-device.h>
30 #include <dev/nxge/include/xgehal-channel.h>
31 #include <dev/nxge/include/xgehal-fifo.h>
32 #include <dev/nxge/include/xgehal-ring.h>
33 #include <dev/nxge/include/xgehal-driver.h>
34 #include <dev/nxge/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  */
70 void
__hal_device_event_queued(void * data,int event_type)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  */
86 void
__hal_pio_mem_write32_upper(pci_dev_h pdev,pci_reg_h regh,u32 val,void * addr)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  */
103 void
__hal_pio_mem_write32_lower(pci_dev_h pdev,pci_reg_h regh,u32 val,void * addr)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  */
126 xge_hal_status_e
__hal_device_register_poll(xge_hal_device_t * hldev,u64 * reg,int op,u64 mask,int max_millis)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  */
164 static xge_hal_status_e
__hal_device_wait_quiescent(xge_hal_device_t * hldev,u64 * hw_status)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  */
207 int
xge_hal_device_is_slot_freeze(xge_hal_device_h devh)208 xge_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  */
239 static void
__hal_device_led_actifity_fix(xge_hal_device_t * hldev)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  */
282 static 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  */
306 static void
__hal_device_xena_fix_mac(xge_hal_device_t * hldev)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  */
345 void
xge_hal_device_bcast_enable(xge_hal_device_h devh)346 xge_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  */
375 void
xge_hal_device_bcast_disable(xge_hal_device_h devh)376 xge_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  */
404 static void
__hal_device_shared_splits_configure(xge_hal_device_t * hldev)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  */
426 static void
__hal_device_rmac_padding_configure(xge_hal_device_t * hldev)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  */
471 static void
__hal_device_pause_frames_configure(xge_hal_device_t * hldev)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  */
__hal_fix_time_ival_herc(xge_hal_device_t * hldev,unsigned int time_ival)539 unsigned 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  */
561 static void
__hal_device_bus_master_disable(xge_hal_device_t * hldev)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  */
580 static void
__hal_device_bus_master_enable(xge_hal_device_t * hldev)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  */
607 static void
__hal_device_intr_mgmt(xge_hal_device_t * hldev,u64 mask,int flag)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  */
904 static void
__hal_device_bimodal_configure(xge_hal_device_t * hldev)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  */
948 static xge_hal_status_e
__hal_device_tti_apply(xge_hal_device_t * hldev,xge_hal_tti_config_t * tti,int num,int runtime)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, data1,
1005 	             &bar0->tti_data1_mem);
1006 	(void)xge_os_pio_mem_read64(hldev->pdev,
1007 	      hldev->regh0, &bar0->tti_data1_mem);
1008 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, data2,
1009 	             &bar0->tti_data2_mem);
1010 	(void)xge_os_pio_mem_read64(hldev->pdev,
1011 	      hldev->regh0, &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  */
1043 static xge_hal_status_e
__hal_device_tti_configure(xge_hal_device_t * hldev,int runtime)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  */
1098 xge_hal_status_e
__hal_device_rti_configure(xge_hal_device_t * hldev,int runtime)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, data1,
1162 	                 &bar0->rti_data1_mem);
1163 	    (void)xge_os_pio_mem_read64(hldev->pdev,
1164 	          hldev->regh0, &bar0->rti_data1_mem);
1165 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, data2,
1166 	                     &bar0->rti_data2_mem);
1167 	    (void)xge_os_pio_mem_read64(hldev->pdev,
1168 	          hldev->regh0, &bar0->rti_data2_mem);
1169 	    xge_os_wmb();
1170 
1171 	    val64 = XGE_HAL_RTI_CMD_MEM_WE |
1172 	    XGE_HAL_RTI_CMD_MEM_STROBE_NEW_CMD;
1173 	    val64 |= XGE_HAL_RTI_CMD_MEM_OFFSET(i);
1174 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1175 	                        &bar0->rti_command_mem);
1176 
1177 	    if (!runtime && __hal_device_register_poll(hldev,
1178 	        &bar0->rti_command_mem, 0,
1179 	        XGE_HAL_RTI_CMD_MEM_STROBE_NEW_CMD,
1180 	        XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1181 	        /* upper layer may require to repeat */
1182 	        return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1183 	    }
1184 
1185 	    if (!runtime) {
1186 	        xge_debug_device(XGE_TRACE,
1187 	          "RTI[%d] configured: rti_data1_mem 0x"XGE_OS_LLXFMT,
1188 	          i,
1189 	          (unsigned long long)xge_os_pio_mem_read64(hldev->pdev,
1190 	                  hldev->regh0, &bar0->rti_data1_mem));
1191 	    }
1192 	}
1193 
1194 	return XGE_HAL_OK;
1195 }
1196 
1197 
1198 /* Constants to be programmed into the Xena's registers to configure
1199  * the XAUI. */
1200 static u64 default_xena_mdio_cfg[] = {
1201 	/* Reset PMA PLL */
1202 	0xC001010000000000ULL, 0xC0010100000000E0ULL,
1203 	0xC0010100008000E4ULL,
1204 	/* Remove Reset from PMA PLL */
1205 	0xC001010000000000ULL, 0xC0010100000000E0ULL,
1206 	0xC0010100000000E4ULL,
1207 	END_SIGN
1208 };
1209 
1210 static u64 default_herc_mdio_cfg[] = {
1211 	END_SIGN
1212 };
1213 
1214 static u64 default_xena_dtx_cfg[] = {
1215 	0x8000051500000000ULL, 0x80000515000000E0ULL,
1216 	0x80000515D93500E4ULL, 0x8001051500000000ULL,
1217 	0x80010515000000E0ULL, 0x80010515001E00E4ULL,
1218 	0x8002051500000000ULL, 0x80020515000000E0ULL,
1219 	0x80020515F21000E4ULL,
1220 	/* Set PADLOOPBACKN */
1221 	0x8002051500000000ULL, 0x80020515000000E0ULL,
1222 	0x80020515B20000E4ULL, 0x8003051500000000ULL,
1223 	0x80030515000000E0ULL, 0x80030515B20000E4ULL,
1224 	0x8004051500000000ULL, 0x80040515000000E0ULL,
1225 	0x80040515B20000E4ULL, 0x8005051500000000ULL,
1226 	0x80050515000000E0ULL, 0x80050515B20000E4ULL,
1227 	SWITCH_SIGN,
1228 	/* Remove PADLOOPBACKN */
1229 	0x8002051500000000ULL, 0x80020515000000E0ULL,
1230 	0x80020515F20000E4ULL, 0x8003051500000000ULL,
1231 	0x80030515000000E0ULL, 0x80030515F20000E4ULL,
1232 	0x8004051500000000ULL, 0x80040515000000E0ULL,
1233 	0x80040515F20000E4ULL, 0x8005051500000000ULL,
1234 	0x80050515000000E0ULL, 0x80050515F20000E4ULL,
1235 	END_SIGN
1236 };
1237 
1238 /*
1239 static u64 default_herc_dtx_cfg[] = {
1240 	0x80000515BA750000ULL, 0x80000515BA7500E0ULL,
1241 	0x80000515BA750004ULL, 0x80000515BA7500E4ULL,
1242 	0x80010515003F0000ULL, 0x80010515003F00E0ULL,
1243 	0x80010515003F0004ULL, 0x80010515003F00E4ULL,
1244 	0x80020515F2100000ULL, 0x80020515F21000E0ULL,
1245 	0x80020515F2100004ULL, 0x80020515F21000E4ULL,
1246 	END_SIGN
1247 };
1248 */
1249 
1250 static u64 default_herc_dtx_cfg[] = {
1251 	0x8000051536750000ULL, 0x80000515367500E0ULL,
1252 	0x8000051536750004ULL, 0x80000515367500E4ULL,
1253 
1254 	0x80010515003F0000ULL, 0x80010515003F00E0ULL,
1255 	0x80010515003F0004ULL, 0x80010515003F00E4ULL,
1256 
1257 	0x801205150D440000ULL, 0x801205150D4400E0ULL,
1258 	0x801205150D440004ULL, 0x801205150D4400E4ULL,
1259 
1260 	0x80020515F2100000ULL, 0x80020515F21000E0ULL,
1261 	0x80020515F2100004ULL, 0x80020515F21000E4ULL,
1262 	END_SIGN
1263 };
1264 
1265 
1266 void
__hal_serial_mem_write64(xge_hal_device_t * hldev,u64 value,u64 * reg)1267 __hal_serial_mem_write64(xge_hal_device_t *hldev, u64 value, u64 *reg)
1268 {
1269 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
1270 	        (u32)(value>>32), reg);
1271 	xge_os_wmb();
1272 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
1273 	        (u32)value, reg);
1274 	xge_os_wmb();
1275 	xge_os_mdelay(1);
1276 }
1277 
1278 u64
__hal_serial_mem_read64(xge_hal_device_t * hldev,u64 * reg)1279 __hal_serial_mem_read64(xge_hal_device_t *hldev, u64 *reg)
1280 {
1281 	u64 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1282 	        reg);
1283 	xge_os_mdelay(1);
1284 	return val64;
1285 }
1286 
1287 /*
1288  * __hal_device_xaui_configure
1289  * @hldev: HAL device handle.
1290  *
1291  * Configure XAUI Interface of Xena.
1292  *
1293  * To Configure the Xena's XAUI, one has to write a series
1294  * of 64 bit values into two registers in a particular
1295  * sequence. Hence a macro 'SWITCH_SIGN' has been defined
1296  * which will be defined in the array of configuration values
1297  * (default_dtx_cfg & default_mdio_cfg) at appropriate places
1298  * to switch writing from one regsiter to another. We continue
1299  * writing these values until we encounter the 'END_SIGN' macro.
1300  * For example, After making a series of 21 writes into
1301  * dtx_control register the 'SWITCH_SIGN' appears and hence we
1302  * start writing into mdio_control until we encounter END_SIGN.
1303  */
1304 static void
__hal_device_xaui_configure(xge_hal_device_t * hldev)1305 __hal_device_xaui_configure(xge_hal_device_t *hldev)
1306 {
1307 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1308 	int mdio_cnt = 0, dtx_cnt = 0;
1309 	u64 *default_dtx_cfg = NULL, *default_mdio_cfg = NULL;
1310 
1311 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
1312 	    default_dtx_cfg = default_xena_dtx_cfg;
1313 	    default_mdio_cfg = default_xena_mdio_cfg;
1314 	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
1315 	    default_dtx_cfg = default_herc_dtx_cfg;
1316 	    default_mdio_cfg = default_herc_mdio_cfg;
1317 	} else {
1318 	    xge_assert(default_dtx_cfg);
1319 	return;
1320   }
1321 
1322 	do {
1323 	    dtx_cfg:
1324 	    while (default_dtx_cfg[dtx_cnt] != END_SIGN) {
1325 	        if (default_dtx_cfg[dtx_cnt] == SWITCH_SIGN) {
1326 	            dtx_cnt++;
1327 	            goto mdio_cfg;
1328 	        }
1329 	        __hal_serial_mem_write64(hldev, default_dtx_cfg[dtx_cnt],
1330 	                       &bar0->dtx_control);
1331 	        dtx_cnt++;
1332 	    }
1333 	    mdio_cfg:
1334 	    while (default_mdio_cfg[mdio_cnt] != END_SIGN) {
1335 	        if (default_mdio_cfg[mdio_cnt] == SWITCH_SIGN) {
1336 	            mdio_cnt++;
1337 	            goto dtx_cfg;
1338 	        }
1339 	        __hal_serial_mem_write64(hldev, default_mdio_cfg[mdio_cnt],
1340 	            &bar0->mdio_control);
1341 	        mdio_cnt++;
1342 	    }
1343 	} while ( !((default_dtx_cfg[dtx_cnt] == END_SIGN) &&
1344 	        (default_mdio_cfg[mdio_cnt] == END_SIGN)) );
1345 
1346 	xge_debug_device(XGE_TRACE, "%s", "XAUI interface configured");
1347 }
1348 
1349 /*
1350  * __hal_device_mac_link_util_set
1351  * @hldev: HAL device handle.
1352  *
1353  * Set sampling rate to calculate link utilization.
1354  */
1355 static void
__hal_device_mac_link_util_set(xge_hal_device_t * hldev)1356 __hal_device_mac_link_util_set(xge_hal_device_t *hldev)
1357 {
1358 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1359 	u64 val64;
1360 
1361 	val64 = XGE_HAL_MAC_TX_LINK_UTIL_VAL(
1362 	        hldev->config.mac.tmac_util_period) |
1363 	    XGE_HAL_MAC_RX_LINK_UTIL_VAL(
1364 	        hldev->config.mac.rmac_util_period);
1365 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1366 	                     &bar0->mac_link_util);
1367 	xge_debug_device(XGE_TRACE, "%s",
1368 	          "bandwidth link utilization configured");
1369 }
1370 
1371 /*
1372  * __hal_device_set_swapper
1373  * @hldev: HAL device handle.
1374  *
1375  * Set the Xframe's byte "swapper" in accordance with
1376  * endianness of the host.
1377  */
1378 xge_hal_status_e
__hal_device_set_swapper(xge_hal_device_t * hldev)1379 __hal_device_set_swapper(xge_hal_device_t *hldev)
1380 {
1381 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1382 	u64 val64;
1383 
1384 	/*
1385 	 * from 32bit errarta:
1386 	 *
1387 	 * The SWAPPER_CONTROL register determines how the adapter accesses
1388 	 * host memory as well as how it responds to read and write requests
1389 	 * from the host system. Writes to this register should be performed
1390 	 * carefully, since the byte swappers could reverse the order of bytes.
1391 	 * When configuring this register keep in mind that writes to the PIF
1392 	 * read and write swappers could reverse the order of the upper and
1393 	 * lower 32-bit words. This means that the driver may have to write
1394 	 * to the upper 32 bits of the SWAPPER_CONTROL twice in order to
1395 	 * configure the entire register. */
1396 
1397 	/*
1398 	 * The device by default set to a big endian format, so a big endian
1399 	 * driver need not set anything.
1400 	 */
1401 
1402 #if defined(XGE_HAL_CUSTOM_HW_SWAPPER)
1403 
1404 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1405 	        0xffffffffffffffffULL, &bar0->swapper_ctrl);
1406 
1407 	val64 = XGE_HAL_CUSTOM_HW_SWAPPER;
1408 
1409 	xge_os_wmb();
1410 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1411 	             &bar0->swapper_ctrl);
1412 
1413 	xge_debug_device(XGE_TRACE, "using custom HW swapper 0x"XGE_OS_LLXFMT,
1414 	        (unsigned long long)val64);
1415 
1416 #elif !defined(XGE_OS_HOST_BIG_ENDIAN)
1417 
1418 	/*
1419 	 * Initially we enable all bits to make it accessible by the driver,
1420 	 * then we selectively enable only those bits that we want to set.
1421 	 * i.e. force swapper to swap for the first time since second write
1422 	 * will overwrite with the final settings.
1423 	 *
1424 	 * Use only for little endian platforms.
1425 	 */
1426 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1427 	        0xffffffffffffffffULL, &bar0->swapper_ctrl);
1428 	xge_os_wmb();
1429 	val64 = (XGE_HAL_SWAPPER_CTRL_PIF_R_FE |
1430 	     XGE_HAL_SWAPPER_CTRL_PIF_R_SE |
1431 	     XGE_HAL_SWAPPER_CTRL_PIF_W_FE |
1432 	     XGE_HAL_SWAPPER_CTRL_PIF_W_SE |
1433 	     XGE_HAL_SWAPPER_CTRL_RTH_FE |
1434 	     XGE_HAL_SWAPPER_CTRL_RTH_SE |
1435 	     XGE_HAL_SWAPPER_CTRL_TXP_FE |
1436 	     XGE_HAL_SWAPPER_CTRL_TXP_SE |
1437 	     XGE_HAL_SWAPPER_CTRL_TXD_R_FE |
1438 	     XGE_HAL_SWAPPER_CTRL_TXD_R_SE |
1439 	     XGE_HAL_SWAPPER_CTRL_TXD_W_FE |
1440 	     XGE_HAL_SWAPPER_CTRL_TXD_W_SE |
1441 	     XGE_HAL_SWAPPER_CTRL_TXF_R_FE |
1442 	     XGE_HAL_SWAPPER_CTRL_RXD_R_FE |
1443 	     XGE_HAL_SWAPPER_CTRL_RXD_R_SE |
1444 	     XGE_HAL_SWAPPER_CTRL_RXD_W_FE |
1445 	     XGE_HAL_SWAPPER_CTRL_RXD_W_SE |
1446 	     XGE_HAL_SWAPPER_CTRL_RXF_W_FE |
1447 	     XGE_HAL_SWAPPER_CTRL_XMSI_FE |
1448 	     XGE_HAL_SWAPPER_CTRL_STATS_FE | XGE_HAL_SWAPPER_CTRL_STATS_SE);
1449 
1450 	/*
1451 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
1452 	     val64 |= XGE_HAL_SWAPPER_CTRL_XMSI_SE;
1453 	} */
1454 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0, (u32)val64,
1455 	                     &bar0->swapper_ctrl);
1456 	xge_os_wmb();
1457 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, (u32)(val64>>32),
1458 	                     &bar0->swapper_ctrl);
1459 	xge_os_wmb();
1460 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, (u32)(val64>>32),
1461 	                     &bar0->swapper_ctrl);
1462 	xge_debug_device(XGE_TRACE, "%s", "using little endian set");
1463 #endif
1464 
1465 	/*  Verifying if endian settings are accurate by reading a feedback
1466 	 *  register.  */
1467 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1468 	                            &bar0->pif_rd_swapper_fb);
1469 	if (val64 != XGE_HAL_IF_RD_SWAPPER_FB) {
1470 	    xge_debug_device(XGE_ERR, "pif_rd_swapper_fb read "XGE_OS_LLXFMT,
1471 	          (unsigned long long) val64);
1472 	    return XGE_HAL_ERR_SWAPPER_CTRL;
1473 	}
1474 
1475 	xge_debug_device(XGE_TRACE, "%s", "be/le swapper enabled");
1476 
1477 	return XGE_HAL_OK;
1478 }
1479 
1480 /*
1481  * __hal_device_rts_mac_configure - Configure RTS steering based on
1482  * destination mac address.
1483  * @hldev: HAL device handle.
1484  *
1485  */
1486 xge_hal_status_e
__hal_device_rts_mac_configure(xge_hal_device_t * hldev)1487 __hal_device_rts_mac_configure(xge_hal_device_t *hldev)
1488 {
1489 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1490 	u64 val64;
1491 
1492 	if (!hldev->config.rts_mac_en) {
1493 	    return XGE_HAL_OK;
1494 	}
1495 
1496 	/*
1497 	* Set the receive traffic steering mode from default(classic)
1498 	* to enhanced.
1499 	*/
1500 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1501 	                &bar0->rts_ctrl);
1502 	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
1503 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1504 	            val64, &bar0->rts_ctrl);
1505 	return XGE_HAL_OK;
1506 }
1507 
1508 /*
1509  * __hal_device_rts_port_configure - Configure RTS steering based on
1510  * destination or source port number.
1511  * @hldev: HAL device handle.
1512  *
1513  */
1514 xge_hal_status_e
__hal_device_rts_port_configure(xge_hal_device_t * hldev)1515 __hal_device_rts_port_configure(xge_hal_device_t *hldev)
1516 {
1517 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1518 	u64 val64;
1519 	int rnum;
1520 
1521 	if (!hldev->config.rts_port_en) {
1522 	    return XGE_HAL_OK;
1523 	}
1524 
1525 	/*
1526 	 * Set the receive traffic steering mode from default(classic)
1527 	 * to enhanced.
1528 	 */
1529 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1530 	                &bar0->rts_ctrl);
1531 	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
1532 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1533 	            val64, &bar0->rts_ctrl);
1534 
1535 	/*
1536 	 * Initiate port steering according to per-ring configuration
1537 	 */
1538 	for (rnum = 0; rnum < XGE_HAL_MAX_RING_NUM; rnum++) {
1539 	    int pnum;
1540 	    xge_hal_ring_queue_t *queue = &hldev->config.ring.queue[rnum];
1541 
1542 	    if (!queue->configured || queue->rts_port_en)
1543 	        continue;
1544 
1545 	    for (pnum = 0; pnum < XGE_HAL_MAX_STEERABLE_PORTS; pnum++) {
1546 	        xge_hal_rts_port_t *port = &queue->rts_ports[pnum];
1547 
1548 	        /*
1549 	         * Skip and clear empty ports
1550 	         */
1551 	        if (!port->num) {
1552 	            /*
1553 	             * Clear CAM memory
1554 	             */
1555 	            xge_os_pio_mem_write64(hldev->pdev,
1556 	                   hldev->regh0, 0ULL,
1557 	                   &bar0->rts_pn_cam_data);
1558 
1559 	            val64 = BIT(7) | BIT(15);
1560 	        } else {
1561 	            /*
1562 	             * Assign new Port values according
1563 	             * to configuration
1564 	             */
1565 	            val64 = vBIT(port->num,8,16) |
1566 	                vBIT(rnum,37,3) | BIT(63);
1567 	            if (port->src)
1568 	                val64 = BIT(47);
1569 	            if (!port->udp)
1570 	                val64 = BIT(7);
1571 	            xge_os_pio_mem_write64(hldev->pdev,
1572 	                       hldev->regh0, val64,
1573 	                       &bar0->rts_pn_cam_data);
1574 
1575 	            val64 = BIT(7) | BIT(15) | vBIT(pnum,24,8);
1576 	        }
1577 
1578 	        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1579 	                       val64, &bar0->rts_pn_cam_ctrl);
1580 
1581 	        /* poll until done */
1582 	        if (__hal_device_register_poll(hldev,
1583 	               &bar0->rts_pn_cam_ctrl, 0,
1584 	               XGE_HAL_RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED,
1585 	               XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) !=
1586 	                            XGE_HAL_OK) {
1587 	            /* upper layer may require to repeat */
1588 	            return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1589 	        }
1590 	    }
1591 	}
1592 	return XGE_HAL_OK;
1593 }
1594 
1595 /*
1596  * __hal_device_rts_qos_configure - Configure RTS steering based on
1597  * qos.
1598  * @hldev: HAL device handle.
1599  *
1600  */
1601 xge_hal_status_e
__hal_device_rts_qos_configure(xge_hal_device_t * hldev)1602 __hal_device_rts_qos_configure(xge_hal_device_t *hldev)
1603 {
1604 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1605 	u64 val64;
1606 	int j, rx_ring_num;
1607 
1608 	if (!hldev->config.rts_qos_en) {
1609 	    return XGE_HAL_OK;
1610 	}
1611 
1612 	/* First clear the RTS_DS_MEM_DATA */
1613 	val64 = 0;
1614 	for (j = 0; j < 64; j++ )
1615 	{
1616 	    /* First clear the value */
1617 	    val64 = XGE_HAL_RTS_DS_MEM_DATA(0);
1618 
1619 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1620 	                   &bar0->rts_ds_mem_data);
1621 
1622 	    val64 = XGE_HAL_RTS_DS_MEM_CTRL_WE |
1623 	        XGE_HAL_RTS_DS_MEM_CTRL_STROBE_NEW_CMD |
1624 	        XGE_HAL_RTS_DS_MEM_CTRL_OFFSET ( j );
1625 
1626 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1627 	                   &bar0->rts_ds_mem_ctrl);
1628 
1629 
1630 	    /* poll until done */
1631 	    if (__hal_device_register_poll(hldev,
1632 	           &bar0->rts_ds_mem_ctrl, 0,
1633 	           XGE_HAL_RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
1634 	           XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1635 	        /* upper layer may require to repeat */
1636 	        return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1637 	    }
1638 
1639 	}
1640 
1641 	rx_ring_num = 0;
1642 	for (j = 0; j < XGE_HAL_MAX_RING_NUM; j++) {
1643 	    if (hldev->config.ring.queue[j].configured)
1644 	        rx_ring_num++;
1645 	}
1646 
1647 	switch (rx_ring_num) {
1648 	case 1:
1649 	    val64 = 0x0;
1650 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1651 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1652 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1653 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1654 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1655 	    break;
1656 	case 2:
1657 	    val64 = 0x0001000100010001ULL;
1658 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1659 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1660 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1661 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1662 	    val64 = 0x0001000100000000ULL;
1663 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1664 	    break;
1665 	case 3:
1666 	    val64 = 0x0001020001020001ULL;
1667 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1668 	    val64 = 0x0200010200010200ULL;
1669 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1670 	    val64 = 0x0102000102000102ULL;
1671 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1672 	    val64 = 0x0001020001020001ULL;
1673 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1674 	    val64 = 0x0200010200000000ULL;
1675 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1676 	    break;
1677 	case 4:
1678 	    val64 = 0x0001020300010203ULL;
1679 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1680 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1681 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1682 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1683 	    val64 = 0x0001020300000000ULL;
1684 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1685 	    break;
1686 	case 5:
1687 	    val64 = 0x0001020304000102ULL;
1688 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1689 	    val64 = 0x0304000102030400ULL;
1690 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1691 	    val64 = 0x0102030400010203ULL;
1692 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1693 	    val64 = 0x0400010203040001ULL;
1694 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1695 	    val64 = 0x0203040000000000ULL;
1696 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1697 	    break;
1698 	case 6:
1699 	    val64 = 0x0001020304050001ULL;
1700 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1701 	    val64 = 0x0203040500010203ULL;
1702 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1703 	    val64 = 0x0405000102030405ULL;
1704 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1705 	    val64 = 0x0001020304050001ULL;
1706 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1707 	    val64 = 0x0203040500000000ULL;
1708 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1709 	    break;
1710 	case 7:
1711 	    val64 = 0x0001020304050600ULL;
1712 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1713 	    val64 = 0x0102030405060001ULL;
1714 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1715 	    val64 = 0x0203040506000102ULL;
1716 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1717 	    val64 = 0x0304050600010203ULL;
1718 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1719 	    val64 = 0x0405060000000000ULL;
1720 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1721 	    break;
1722 	case 8:
1723 	    val64 = 0x0001020304050607ULL;
1724 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_0);
1725 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_1);
1726 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_2);
1727 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_3);
1728 	    val64 = 0x0001020300000000ULL;
1729 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, &bar0->rx_w_round_robin_4);
1730 	    break;
1731 	}
1732 
1733 	return XGE_HAL_OK;
1734 }
1735 
1736 /*
1737  * xge__hal_device_rts_mac_enable
1738  *
1739  * @devh: HAL device handle.
1740  * @index: index number where the MAC addr will be stored
1741  * @macaddr: MAC address
1742  *
1743  * - Enable RTS steering for the given MAC address. This function has to be
1744  * called with lock acquired.
1745  *
1746  * NOTE:
1747  * 1. ULD has to call this function with the index value which
1748  *    statisfies the following condition:
1749  *  ring_num = (index % 8)
1750  * 2.ULD also needs to make sure that the index is not
1751  *   occupied by any MAC address. If that index has any MAC address
1752  *   it will be overwritten and HAL will not check for it.
1753  *
1754  */
1755 xge_hal_status_e
xge_hal_device_rts_mac_enable(xge_hal_device_h devh,int index,macaddr_t macaddr)1756 xge_hal_device_rts_mac_enable(xge_hal_device_h devh, int index, macaddr_t macaddr)
1757 {
1758 	int max_addr = XGE_HAL_MAX_MAC_ADDRESSES;
1759 	xge_hal_status_e status;
1760 
1761 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
1762 
1763 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
1764 	    max_addr = XGE_HAL_MAX_MAC_ADDRESSES_HERC;
1765 
1766 	if ( index >= max_addr )
1767 	    return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
1768 
1769 	/*
1770 	 * Set the MAC address at the given location marked by index.
1771 	 */
1772 	status = xge_hal_device_macaddr_set(hldev, index, macaddr);
1773 	if (status != XGE_HAL_OK) {
1774 	    xge_debug_device(XGE_ERR, "%s",
1775 	        "Not able to set the mac addr");
1776 	    return status;
1777 	}
1778 
1779 	return xge_hal_device_rts_section_enable(hldev, index);
1780 }
1781 
1782 /*
1783  * xge__hal_device_rts_mac_disable
1784  * @hldev: HAL device handle.
1785  * @index: index number where to disable the MAC addr
1786  *
1787  * Disable RTS Steering based on the MAC address.
1788  * This function should be called with lock acquired.
1789  *
1790  */
1791 xge_hal_status_e
xge_hal_device_rts_mac_disable(xge_hal_device_h devh,int index)1792 xge_hal_device_rts_mac_disable(xge_hal_device_h devh, int index)
1793 {
1794 	xge_hal_status_e status;
1795 	u8 macaddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1796 	int max_addr = XGE_HAL_MAX_MAC_ADDRESSES;
1797 
1798 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
1799 
1800 	xge_debug_ll(XGE_TRACE, "the index value is %d ", index);
1801 
1802 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
1803 	    max_addr = XGE_HAL_MAX_MAC_ADDRESSES_HERC;
1804 
1805 	if ( index >= max_addr )
1806 	    return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
1807 
1808 	/*
1809 	 * Disable MAC address @ given index location
1810 	 */
1811 	status = xge_hal_device_macaddr_set(hldev, index, macaddr);
1812 	if (status != XGE_HAL_OK) {
1813 	    xge_debug_device(XGE_ERR, "%s",
1814 	        "Not able to set the mac addr");
1815 	    return status;
1816 	}
1817 
1818 	return XGE_HAL_OK;
1819 }
1820 
1821 
1822 /*
1823  * __hal_device_rth_configure - Configure RTH for the device
1824  * @hldev: HAL device handle.
1825  *
1826  * Using IT (Indirection Table).
1827  */
1828 xge_hal_status_e
__hal_device_rth_it_configure(xge_hal_device_t * hldev)1829 __hal_device_rth_it_configure(xge_hal_device_t *hldev)
1830 {
1831 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1832 	u64 val64;
1833 	int rings[XGE_HAL_MAX_RING_NUM]={0};
1834 	int rnum;
1835 	int rmax;
1836 	int buckets_num;
1837 	int bucket;
1838 
1839 	if (!hldev->config.rth_en) {
1840 	    return XGE_HAL_OK;
1841 	}
1842 
1843 	/*
1844 	 * Set the receive traffic steering mode from default(classic)
1845 	 * to enhanced.
1846 	 */
1847 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1848 	                  &bar0->rts_ctrl);
1849 	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
1850 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1851 	               val64, &bar0->rts_ctrl);
1852 
1853 	buckets_num = (1 << hldev->config.rth_bucket_size);
1854 
1855 	rmax=0;
1856 	for (rnum = 0; rnum < XGE_HAL_MAX_RING_NUM; rnum++) {
1857 	    if (hldev->config.ring.queue[rnum].configured &&
1858 	            hldev->config.ring.queue[rnum].rth_en)
1859 	            rings[rmax++] = rnum;
1860 	}
1861 
1862 	rnum = 0;
1863 	/* for starters: fill in all the buckets with rings "equally" */
1864 	for (bucket = 0; bucket < buckets_num; bucket++) {
1865 
1866 	    if (rnum == rmax)
1867 	       rnum = 0;
1868 
1869 	    /* write data */
1870 	    val64 = XGE_HAL_RTS_RTH_MAP_MEM_DATA_ENTRY_EN |
1871 	            XGE_HAL_RTS_RTH_MAP_MEM_DATA(rings[rnum]);
1872 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1873 	                 &bar0->rts_rth_map_mem_data);
1874 
1875 	    /* execute */
1876 	    val64 = XGE_HAL_RTS_RTH_MAP_MEM_CTRL_WE |
1877 	        XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE |
1878 	        XGE_HAL_RTS_RTH_MAP_MEM_CTRL_OFFSET(bucket);
1879 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1880 	                 &bar0->rts_rth_map_mem_ctrl);
1881 
1882 	    /* poll until done */
1883 	    if (__hal_device_register_poll(hldev,
1884 	        &bar0->rts_rth_map_mem_ctrl, 0,
1885 	        XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE,
1886 	        XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1887 	        return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1888 	    }
1889 
1890 	    rnum++;
1891 	}
1892 
1893 	val64 = XGE_HAL_RTS_RTH_EN;
1894 	val64 |= XGE_HAL_RTS_RTH_BUCKET_SIZE(hldev->config.rth_bucket_size);
1895 	val64 |= XGE_HAL_RTS_RTH_TCP_IPV4_EN | XGE_HAL_RTS_RTH_UDP_IPV4_EN | XGE_HAL_RTS_RTH_IPV4_EN |
1896 	         XGE_HAL_RTS_RTH_TCP_IPV6_EN |XGE_HAL_RTS_RTH_UDP_IPV6_EN | XGE_HAL_RTS_RTH_IPV6_EN |
1897 	         XGE_HAL_RTS_RTH_TCP_IPV6_EX_EN | XGE_HAL_RTS_RTH_UDP_IPV6_EX_EN | XGE_HAL_RTS_RTH_IPV6_EX_EN;
1898 
1899 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1900 	             &bar0->rts_rth_cfg);
1901 
1902 	xge_debug_device(XGE_TRACE, "RTH configured, bucket_size %d",
1903 	          hldev->config.rth_bucket_size);
1904 
1905 	return XGE_HAL_OK;
1906 }
1907 
1908 
1909 /*
1910  * __hal_spdm_entry_add - Add a new entry to the SPDM table.
1911  *
1912  * Add a new entry to the SPDM table
1913  *
1914  * This function add a new entry to the SPDM table.
1915  *
1916  * Note:
1917  *   This function should be called with spdm_lock.
1918  *
1919  * See also: xge_hal_spdm_entry_add , xge_hal_spdm_entry_remove.
1920  */
1921 static xge_hal_status_e
__hal_spdm_entry_add(xge_hal_device_t * hldev,xge_hal_ipaddr_t * src_ip,xge_hal_ipaddr_t * dst_ip,u16 l4_sp,u16 l4_dp,u8 is_tcp,u8 is_ipv4,u8 tgt_queue,u32 jhash_value,u16 spdm_entry)1922 __hal_spdm_entry_add(xge_hal_device_t *hldev, xge_hal_ipaddr_t *src_ip,
1923 	    xge_hal_ipaddr_t *dst_ip, u16 l4_sp, u16 l4_dp, u8 is_tcp,
1924 	    u8 is_ipv4, u8 tgt_queue, u32 jhash_value, u16 spdm_entry)
1925 {
1926 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
1927 	u64 val64;
1928 	u64 spdm_line_arr[8];
1929 	u8 line_no;
1930 
1931 	/*
1932 	 * Clear the SPDM READY bit
1933 	 */
1934 	val64 = XGE_HAL_RX_PIC_INT_REG_SPDM_READY;
1935 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1936 	               &bar0->rxpic_int_reg);
1937 
1938 	xge_debug_device(XGE_TRACE,
1939 	        "L4 SP %x:DP %x: hash %x tgt_queue %d ",
1940 	        l4_sp, l4_dp, jhash_value, tgt_queue);
1941 
1942 	xge_os_memzero(&spdm_line_arr, sizeof(spdm_line_arr));
1943 
1944 	/*
1945 	 * Construct the SPDM entry.
1946 	 */
1947 	spdm_line_arr[0] = vBIT(l4_sp,0,16) |
1948 	           vBIT(l4_dp,16,32) |
1949 	           vBIT(tgt_queue,53,3) |
1950 	           vBIT(is_tcp,59,1) |
1951 	           vBIT(is_ipv4,63,1);
1952 
1953 
1954 	if (is_ipv4) {
1955 	    spdm_line_arr[1] = vBIT(src_ip->ipv4.addr,0,32) |
1956 	               vBIT(dst_ip->ipv4.addr,32,32);
1957 
1958 	} else {
1959 	    xge_os_memcpy(&spdm_line_arr[1], &src_ip->ipv6.addr[0], 8);
1960 	    xge_os_memcpy(&spdm_line_arr[2], &src_ip->ipv6.addr[1], 8);
1961 	    xge_os_memcpy(&spdm_line_arr[3], &dst_ip->ipv6.addr[0], 8);
1962 	    xge_os_memcpy(&spdm_line_arr[4], &dst_ip->ipv6.addr[1], 8);
1963 	}
1964 
1965 	spdm_line_arr[7] = vBIT(jhash_value,0,32) |
1966 	            BIT(63);  /* entry enable bit */
1967 
1968 	/*
1969 	 * Add the entry to the SPDM table
1970 	 */
1971 	for(line_no = 0; line_no < 8; line_no++) {
1972 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1973 	            spdm_line_arr[line_no],
1974 	            (void *)((char *)hldev->spdm_mem_base +
1975 	                    (spdm_entry * 64) +
1976 	                    (line_no * 8)));
1977 	}
1978 
1979 	/*
1980 	 * Wait for the operation to be completed.
1981 	 */
1982 	if (__hal_device_register_poll(hldev, &bar0->rxpic_int_reg, 1,
1983 	        XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
1984 	        XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
1985 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
1986 	}
1987 
1988 	/*
1989 	 * Add this information to a local SPDM table. The purpose of
1990 	 * maintaining a local SPDM table is to avoid a search in the
1991 	 * adapter SPDM table for spdm entry lookup which is very costly
1992 	 * in terms of time.
1993 	 */
1994 	hldev->spdm_table[spdm_entry]->in_use = 1;
1995 	xge_os_memcpy(&hldev->spdm_table[spdm_entry]->src_ip, src_ip,
1996 	        sizeof(xge_hal_ipaddr_t));
1997 	xge_os_memcpy(&hldev->spdm_table[spdm_entry]->dst_ip, dst_ip,
1998 	        sizeof(xge_hal_ipaddr_t));
1999 	hldev->spdm_table[spdm_entry]->l4_sp = l4_sp;
2000 	hldev->spdm_table[spdm_entry]->l4_dp = l4_dp;
2001 	hldev->spdm_table[spdm_entry]->is_tcp = is_tcp;
2002 	hldev->spdm_table[spdm_entry]->is_ipv4 = is_ipv4;
2003 	hldev->spdm_table[spdm_entry]->tgt_queue = tgt_queue;
2004 	hldev->spdm_table[spdm_entry]->jhash_value = jhash_value;
2005 	hldev->spdm_table[spdm_entry]->spdm_entry = spdm_entry;
2006 
2007 	return XGE_HAL_OK;
2008 }
2009 
2010 /*
2011  * __hal_device_rth_spdm_configure - Configure RTH for the device
2012  * @hldev: HAL device handle.
2013  *
2014  * Using SPDM (Socket-Pair Direct Match).
2015  */
2016 xge_hal_status_e
__hal_device_rth_spdm_configure(xge_hal_device_t * hldev)2017 __hal_device_rth_spdm_configure(xge_hal_device_t *hldev)
2018 {
2019 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
2020 	u64 val64;
2021 	u8 spdm_bar_num;
2022 	u32 spdm_bar_offset;
2023 	int spdm_table_size;
2024 	int i;
2025 
2026 	if (!hldev->config.rth_spdm_en) {
2027 	    return XGE_HAL_OK;
2028 	}
2029 
2030 	/*
2031 	 * Retrieve the base address of SPDM Table.
2032 	 */
2033 	val64 = xge_os_pio_mem_read64(hldev->pdev,
2034 	        hldev->regh0, &bar0->spdm_bir_offset);
2035 
2036 	spdm_bar_num    = XGE_HAL_SPDM_PCI_BAR_NUM(val64);
2037 	spdm_bar_offset = XGE_HAL_SPDM_PCI_BAR_OFFSET(val64);
2038 
2039 
2040 	/*
2041 	 * spdm_bar_num specifies the PCI bar num register used to
2042 	 * address the memory space. spdm_bar_offset specifies the offset
2043 	 * of the SPDM memory with in the bar num memory space.
2044 	 */
2045 	switch (spdm_bar_num) {
2046 	    case 0:
2047 	    {
2048 	        hldev->spdm_mem_base = (char *)bar0 +
2049 	                    (spdm_bar_offset * 8);
2050 	        break;
2051 	    }
2052 	    case 1:
2053 	    {
2054 	        char *bar1 = (char *)hldev->bar1;
2055 	        hldev->spdm_mem_base = bar1 + (spdm_bar_offset * 8);
2056 	        break;
2057 	    }
2058 	    default:
2059 	        xge_assert(((spdm_bar_num != 0) && (spdm_bar_num != 1)));
2060 	}
2061 
2062 	/*
2063 	 * Retrieve the size of SPDM table(number of entries).
2064 	 */
2065 	val64 = xge_os_pio_mem_read64(hldev->pdev,
2066 	        hldev->regh0, &bar0->spdm_structure);
2067 	hldev->spdm_max_entries = XGE_HAL_SPDM_MAX_ENTRIES(val64);
2068 
2069 
2070 	spdm_table_size = hldev->spdm_max_entries *
2071 	                sizeof(xge_hal_spdm_entry_t);
2072 	if (hldev->spdm_table == NULL) {
2073 	    void *mem;
2074 
2075 	    /*
2076 	     * Allocate memory to hold the copy of SPDM table.
2077 	     */
2078 	    if ((hldev->spdm_table = (xge_hal_spdm_entry_t **)
2079 	                xge_os_malloc(
2080 	                 hldev->pdev,
2081 	                 (sizeof(xge_hal_spdm_entry_t *) *
2082 	                 hldev->spdm_max_entries))) == NULL) {
2083 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
2084 	    }
2085 
2086 	    if ((mem = xge_os_malloc(hldev->pdev, spdm_table_size)) == NULL)
2087 	    {
2088 	        xge_os_free(hldev->pdev, hldev->spdm_table,
2089 	              (sizeof(xge_hal_spdm_entry_t *) *
2090 	                 hldev->spdm_max_entries));
2091 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
2092 	    }
2093 
2094 	    xge_os_memzero(mem, spdm_table_size);
2095 	    for (i = 0; i < hldev->spdm_max_entries; i++) {
2096 	        hldev->spdm_table[i] = (xge_hal_spdm_entry_t *)
2097 	                ((char *)mem +
2098 	                 i * sizeof(xge_hal_spdm_entry_t));
2099 	    }
2100 	    xge_os_spin_lock_init(&hldev->spdm_lock, hldev->pdev);
2101 	} else {
2102 	    /*
2103 	     * We are here because the host driver tries to
2104 	     * do a soft reset on the device.
2105 	     * Since the device soft reset clears the SPDM table, copy
2106 	     * the entries from the local SPDM table to the actual one.
2107 	     */
2108 	    xge_os_spin_lock(&hldev->spdm_lock);
2109 	    for (i = 0; i < hldev->spdm_max_entries; i++) {
2110 	        xge_hal_spdm_entry_t *spdm_entry = hldev->spdm_table[i];
2111 
2112 	        if (spdm_entry->in_use) {
2113 	            if (__hal_spdm_entry_add(hldev,
2114 	                         &spdm_entry->src_ip,
2115 	                         &spdm_entry->dst_ip,
2116 	                         spdm_entry->l4_sp,
2117 	                         spdm_entry->l4_dp,
2118 	                         spdm_entry->is_tcp,
2119 	                         spdm_entry->is_ipv4,
2120 	                         spdm_entry->tgt_queue,
2121 	                         spdm_entry->jhash_value,
2122 	                         spdm_entry->spdm_entry)
2123 	                    != XGE_HAL_OK) {
2124 	                /* Log an warning */
2125 	                xge_debug_device(XGE_ERR,
2126 	                    "SPDM table update from local"
2127 	                    " memory failed");
2128 	            }
2129 	        }
2130 	    }
2131 	    xge_os_spin_unlock(&hldev->spdm_lock);
2132 	}
2133 
2134 	/*
2135 	 * Set the receive traffic steering mode from default(classic)
2136 	 * to enhanced.
2137 	 */
2138 	val64 = xge_os_pio_mem_read64(hldev->pdev,
2139 	                hldev->regh0, &bar0->rts_ctrl);
2140 	val64 |=  XGE_HAL_RTS_CTRL_ENHANCED_MODE;
2141 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2142 	             val64, &bar0->rts_ctrl);
2143 
2144 	/*
2145 	 * We may not need to configure rts_rth_jhash_cfg register as the
2146 	 * default values are good enough to calculate the hash.
2147 	 */
2148 
2149 	/*
2150 	 * As of now, set all the rth mask registers to zero. TODO.
2151 	 */
2152 	for(i = 0; i < 5; i++) {
2153 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2154 	                 0, &bar0->rts_rth_hash_mask[i]);
2155 	}
2156 
2157 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2158 	             0, &bar0->rts_rth_hash_mask_5);
2159 
2160 	if (hldev->config.rth_spdm_use_l4) {
2161 	    val64 = XGE_HAL_RTH_STATUS_SPDM_USE_L4;
2162 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2163 	                 val64, &bar0->rts_rth_status);
2164 	}
2165 
2166 	val64 = XGE_HAL_RTS_RTH_EN;
2167 	val64 |= XGE_HAL_RTS_RTH_IPV4_EN | XGE_HAL_RTS_RTH_TCP_IPV4_EN;
2168 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2169 	             &bar0->rts_rth_cfg);
2170 
2171 
2172 	return XGE_HAL_OK;
2173 }
2174 
2175 /*
2176  * __hal_device_pci_init
2177  * @hldev: HAL device handle.
2178  *
2179  * Initialize certain PCI/PCI-X configuration registers
2180  * with recommended values. Save config space for future hw resets.
2181  */
2182 static void
__hal_device_pci_init(xge_hal_device_t * hldev)2183 __hal_device_pci_init(xge_hal_device_t *hldev)
2184 {
2185 	int i, pcisize = 0;
2186 	u16 cmd = 0;
2187 	u8  val;
2188 
2189 	/* Store PCI device ID and revision for future references where in we
2190 	 * decide Xena revision using PCI sub system ID */
2191 	xge_os_pci_read16(hldev->pdev,hldev->cfgh,
2192 	        xge_offsetof(xge_hal_pci_config_le_t, device_id),
2193 	        &hldev->device_id);
2194 	xge_os_pci_read8(hldev->pdev,hldev->cfgh,
2195 	        xge_offsetof(xge_hal_pci_config_le_t, revision),
2196 	        &hldev->revision);
2197 
2198 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
2199 	    pcisize = XGE_HAL_PCISIZE_HERC;
2200 	else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
2201 	    pcisize = XGE_HAL_PCISIZE_XENA;
2202 
2203 	/* save original PCI config space to restore it on device_terminate() */
2204 	for (i = 0; i < pcisize; i++) {
2205 	    xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
2206 	                    (u32*)&hldev->pci_config_space_bios + i);
2207 	}
2208 
2209 	/* Set the PErr Repconse bit and SERR in PCI command register. */
2210 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2211 	        xge_offsetof(xge_hal_pci_config_le_t, command), &cmd);
2212 	cmd |= 0x140;
2213 	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2214 	         xge_offsetof(xge_hal_pci_config_le_t, command), cmd);
2215 
2216 	/* Set user spcecified value for the PCI Latency Timer */
2217 	if (hldev->config.latency_timer &&
2218 	    hldev->config.latency_timer != XGE_HAL_USE_BIOS_DEFAULT_LATENCY) {
2219 	    xge_os_pci_write8(hldev->pdev, hldev->cfgh,
2220 	                 xge_offsetof(xge_hal_pci_config_le_t,
2221 	                 latency_timer),
2222 	         (u8)hldev->config.latency_timer);
2223 	}
2224 	/* Read back latency timer to reflect it into user level */
2225 	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
2226 	    xge_offsetof(xge_hal_pci_config_le_t, latency_timer), &val);
2227 	hldev->config.latency_timer = val;
2228 
2229 	/* Enable Data Parity Error Recovery in PCI-X command register. */
2230 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2231 	    xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
2232 	cmd |= 1;
2233 	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2234 	     xge_offsetof(xge_hal_pci_config_le_t, pcix_command), cmd);
2235 
2236 	/* Set MMRB count in PCI-X command register. */
2237 	if (hldev->config.mmrb_count != XGE_HAL_DEFAULT_BIOS_MMRB_COUNT) {
2238 	    cmd &= 0xFFF3;
2239 	    cmd |= hldev->config.mmrb_count << 2;
2240 	    xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2241 	           xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2242 	           cmd);
2243 	}
2244 	/* Read back MMRB count to reflect it into user level */
2245 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2246 	            xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2247 	            &cmd);
2248 	cmd &= 0x000C;
2249 	hldev->config.mmrb_count = cmd>>2;
2250 
2251 	/*  Setting Maximum outstanding splits based on system type. */
2252 	if (hldev->config.max_splits_trans != XGE_HAL_USE_BIOS_DEFAULT_SPLITS)  {
2253 	    xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2254 	        xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2255 	        &cmd);
2256 	    cmd &= 0xFF8F;
2257 	    cmd |= hldev->config.max_splits_trans << 4;
2258 	    xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2259 	        xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
2260 	        cmd);
2261 	}
2262 
2263 	/* Read back max split trans to reflect it into user level */
2264 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2265 	    xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
2266 	cmd &= 0x0070;
2267 	hldev->config.max_splits_trans = cmd>>4;
2268 
2269 	/* Forcibly disabling relaxed ordering capability of the card. */
2270 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
2271 	    xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
2272 	cmd &= 0xFFFD;
2273 	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
2274 	     xge_offsetof(xge_hal_pci_config_le_t, pcix_command), cmd);
2275 
2276 	/* save PCI config space for future resets */
2277 	for (i = 0; i < pcisize; i++) {
2278 	    xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
2279 	                    (u32*)&hldev->pci_config_space + i);
2280 	}
2281 }
2282 
2283 /*
2284  * __hal_device_pci_info_get - Get PCI bus informations such as width, frequency
2285  *                               and mode.
2286  * @devh: HAL device handle.
2287  * @pci_mode:       pointer to a variable of enumerated type
2288  *          xge_hal_pci_mode_e{}.
2289  * @bus_frequency:  pointer to a variable of enumerated type
2290  *          xge_hal_pci_bus_frequency_e{}.
2291  * @bus_width:      pointer to a variable of enumerated type
2292  *          xge_hal_pci_bus_width_e{}.
2293  *
2294  * Get pci mode, frequency, and PCI bus width.
2295  *
2296  * Returns: one of the xge_hal_status_e{} enumerated types.
2297  * XGE_HAL_OK           - for success.
2298  * XGE_HAL_ERR_INVALID_PCI_INFO - for invalid PCI information from the card.
2299  * XGE_HAL_ERR_BAD_DEVICE_ID    - for invalid card.
2300  *
2301  * See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
2302  */
2303 static xge_hal_status_e
__hal_device_pci_info_get(xge_hal_device_h devh,xge_hal_pci_mode_e * pci_mode,xge_hal_pci_bus_frequency_e * bus_frequency,xge_hal_pci_bus_width_e * bus_width)2304 __hal_device_pci_info_get(xge_hal_device_h devh, xge_hal_pci_mode_e *pci_mode,
2305 	    xge_hal_pci_bus_frequency_e *bus_frequency,
2306 	    xge_hal_pci_bus_width_e *bus_width)
2307 {
2308 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
2309 	xge_hal_status_e rc_status = XGE_HAL_OK;
2310 	xge_hal_card_e card_id     = xge_hal_device_check_id (devh);
2311 
2312 #ifdef XGE_HAL_HERC_EMULATION
2313 	hldev->config.pci_freq_mherz =
2314 	    XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2315 	*bus_frequency  =
2316 	    XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2317 	*pci_mode = XGE_HAL_PCI_66MHZ_MODE;
2318 #else
2319 	if (card_id == XGE_HAL_CARD_HERC) {
2320 	    xge_hal_pci_bar0_t *bar0 =
2321 	    (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2322 	    u64 pci_info = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2323 	                &bar0->pci_info);
2324 	    if (XGE_HAL_PCI_32_BIT & pci_info)
2325 	        *bus_width = XGE_HAL_PCI_BUS_WIDTH_32BIT;
2326 	    else
2327 	        *bus_width = XGE_HAL_PCI_BUS_WIDTH_64BIT;
2328 	    switch((pci_info & XGE_HAL_PCI_INFO)>>60)
2329 	    {
2330 	        case XGE_HAL_PCI_33MHZ_MODE:
2331 	             *bus_frequency =
2332 	                 XGE_HAL_PCI_BUS_FREQUENCY_33MHZ;
2333 	             *pci_mode = XGE_HAL_PCI_33MHZ_MODE;
2334 	             break;
2335 	        case XGE_HAL_PCI_66MHZ_MODE:
2336 	             *bus_frequency =
2337 	                 XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2338 	             *pci_mode = XGE_HAL_PCI_66MHZ_MODE;
2339 	             break;
2340 	        case XGE_HAL_PCIX_M1_66MHZ_MODE:
2341 	             *bus_frequency =
2342 	                 XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
2343 	             *pci_mode = XGE_HAL_PCIX_M1_66MHZ_MODE;
2344 	             break;
2345 	        case XGE_HAL_PCIX_M1_100MHZ_MODE:
2346 	             *bus_frequency =
2347 	                 XGE_HAL_PCI_BUS_FREQUENCY_100MHZ;
2348 	             *pci_mode = XGE_HAL_PCIX_M1_100MHZ_MODE;
2349 	             break;
2350 	        case XGE_HAL_PCIX_M1_133MHZ_MODE:
2351 	             *bus_frequency =
2352 	                 XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
2353 	             *pci_mode = XGE_HAL_PCIX_M1_133MHZ_MODE;
2354 	             break;
2355 	        case XGE_HAL_PCIX_M2_66MHZ_MODE:
2356 	             *bus_frequency =
2357 	                 XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
2358 	             *pci_mode = XGE_HAL_PCIX_M2_66MHZ_MODE;
2359 	             break;
2360 	        case XGE_HAL_PCIX_M2_100MHZ_MODE:
2361 	             *bus_frequency =
2362 	                 XGE_HAL_PCI_BUS_FREQUENCY_200MHZ;
2363 	             *pci_mode = XGE_HAL_PCIX_M2_100MHZ_MODE;
2364 	             break;
2365 	        case XGE_HAL_PCIX_M2_133MHZ_MODE:
2366 	             *bus_frequency =
2367 	                 XGE_HAL_PCI_BUS_FREQUENCY_266MHZ;
2368 	             *pci_mode = XGE_HAL_PCIX_M2_133MHZ_MODE;
2369 	              break;
2370 	        case XGE_HAL_PCIX_M1_RESERVED:
2371 	        case XGE_HAL_PCIX_M1_66MHZ_NS:
2372 	        case XGE_HAL_PCIX_M1_100MHZ_NS:
2373 	        case XGE_HAL_PCIX_M1_133MHZ_NS:
2374 	        case XGE_HAL_PCIX_M2_RESERVED:
2375 	        case XGE_HAL_PCIX_533_RESERVED:
2376 	        default:
2377 	             rc_status = XGE_HAL_ERR_INVALID_PCI_INFO;
2378 	             xge_debug_device(XGE_ERR,
2379 	                  "invalid pci info "XGE_OS_LLXFMT,
2380 	                 (unsigned long long)pci_info);
2381 	             break;
2382 	    }
2383 	    if (rc_status != XGE_HAL_ERR_INVALID_PCI_INFO)
2384 	        xge_debug_device(XGE_TRACE, "PCI info: mode %d width "
2385 	            "%d frequency %d", *pci_mode, *bus_width,
2386 	            *bus_frequency);
2387 	    if (hldev->config.pci_freq_mherz ==
2388 	            XGE_HAL_DEFAULT_USE_HARDCODE) {
2389 	        hldev->config.pci_freq_mherz = *bus_frequency;
2390 	    }
2391 	}
2392 	/* for XENA, we report PCI mode, only. PCI bus frequency, and bus width
2393 	 * are set to unknown */
2394 	else if (card_id == XGE_HAL_CARD_XENA) {
2395 	    u32 pcix_status;
2396 	    u8 dev_num, bus_num;
2397 	    /* initialize defaults for XENA */
2398 	    *bus_frequency  = XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN;
2399 	    *bus_width  = XGE_HAL_PCI_BUS_WIDTH_UNKNOWN;
2400 	    xge_os_pci_read32(hldev->pdev, hldev->cfgh,
2401 	        xge_offsetof(xge_hal_pci_config_le_t, pcix_status),
2402 	        &pcix_status);
2403 	    dev_num = (u8)((pcix_status & 0xF8) >> 3);
2404 	    bus_num = (u8)((pcix_status & 0xFF00) >> 8);
2405 	    if (dev_num == 0 && bus_num == 0)
2406 	        *pci_mode = XGE_HAL_PCI_BASIC_MODE;
2407 	    else
2408 	        *pci_mode = XGE_HAL_PCIX_BASIC_MODE;
2409 	    xge_debug_device(XGE_TRACE, "PCI info: mode %d", *pci_mode);
2410 	    if (hldev->config.pci_freq_mherz ==
2411 	            XGE_HAL_DEFAULT_USE_HARDCODE) {
2412 	        /*
2413 	         * There is no way to detect BUS frequency on Xena,
2414 	         * so, in case of automatic configuration we hopelessly
2415 	         * assume 133MHZ.
2416 	         */
2417 	        hldev->config.pci_freq_mherz =
2418 	            XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
2419 	    }
2420 	} else if (card_id == XGE_HAL_CARD_TITAN) {
2421 	    *bus_width = XGE_HAL_PCI_BUS_WIDTH_64BIT;
2422 	    *bus_frequency  = XGE_HAL_PCI_BUS_FREQUENCY_250MHZ;
2423 	    if (hldev->config.pci_freq_mherz ==
2424 	            XGE_HAL_DEFAULT_USE_HARDCODE) {
2425 	        hldev->config.pci_freq_mherz = *bus_frequency;
2426 	    }
2427 	} else{
2428 	    rc_status =  XGE_HAL_ERR_BAD_DEVICE_ID;
2429 	    xge_debug_device(XGE_ERR, "invalid device id %d", card_id);
2430 	}
2431 #endif
2432 
2433 	return rc_status;
2434 }
2435 
2436 /*
2437  * __hal_device_handle_link_up_ind
2438  * @hldev: HAL device handle.
2439  *
2440  * Link up indication handler. The function is invoked by HAL when
2441  * Xframe indicates that the link is up for programmable amount of time.
2442  */
2443 static int
__hal_device_handle_link_up_ind(xge_hal_device_t * hldev)2444 __hal_device_handle_link_up_ind(xge_hal_device_t *hldev)
2445 {
2446 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2447 	u64 val64;
2448 
2449 	/*
2450 	 * If the previous link state is not down, return.
2451 	 */
2452 	if (hldev->link_state == XGE_HAL_LINK_UP) {
2453 #ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
2454 	    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC){
2455 	        val64 = xge_os_pio_mem_read64(
2456 	            hldev->pdev, hldev->regh0,
2457 	            &bar0->misc_int_mask);
2458 	        val64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
2459 	        val64 &= ~XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
2460 	        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2461 	            val64, &bar0->misc_int_mask);
2462 	    }
2463 #endif
2464 	    xge_debug_device(XGE_TRACE,
2465 	        "link up indication while link is up, ignoring..");
2466 	    return 0;
2467 	}
2468 
2469 	/* Now re-enable it as due to noise, hardware turned it off */
2470 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2471 	                 &bar0->adapter_control);
2472 	val64 |= XGE_HAL_ADAPTER_CNTL_EN;
2473 	val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN); /* ECC enable */
2474 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2475 	             &bar0->adapter_control);
2476 
2477 	/* Turn on the Laser */
2478 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2479 	                &bar0->adapter_control);
2480 	val64 = val64|(XGE_HAL_ADAPTER_EOI_TX_ON |
2481 	        XGE_HAL_ADAPTER_LED_ON);
2482 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2483 	             &bar0->adapter_control);
2484 
2485 #ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
2486 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2487 	        val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2488 	                          &bar0->adapter_status);
2489 	        if (val64 & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
2490 	                 XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) {
2491 	            xge_debug_device(XGE_TRACE, "%s",
2492 	                      "fail to transition link to up...");
2493 	        return 0;
2494 	        }
2495 	        else {
2496 	            /*
2497 	             * Mask the Link Up interrupt and unmask the Link Down
2498 	             * interrupt.
2499 	             */
2500 	            val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2501 	                              &bar0->misc_int_mask);
2502 	            val64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
2503 	            val64 &= ~XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
2504 	            xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2505 	                           &bar0->misc_int_mask);
2506 	            xge_debug_device(XGE_TRACE, "calling link up..");
2507 	            hldev->link_state = XGE_HAL_LINK_UP;
2508 
2509 	            /* notify ULD */
2510 	            if (g_xge_hal_driver->uld_callbacks.link_up) {
2511 	                g_xge_hal_driver->uld_callbacks.link_up(
2512 	                        hldev->upper_layer_info);
2513 	            }
2514 	        return 1;
2515 	        }
2516 	    }
2517 #endif
2518 	xge_os_mdelay(1);
2519 	if (__hal_device_register_poll(hldev, &bar0->adapter_status, 0,
2520 	        (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
2521 	        XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT),
2522 	        XGE_HAL_DEVICE_FAULT_WAIT_MAX_MILLIS) == XGE_HAL_OK) {
2523 
2524 	    /* notify ULD */
2525 	    (void) xge_queue_produce_context(hldev->queueh,
2526 	                     XGE_HAL_EVENT_LINK_IS_UP,
2527 	                     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  */
2544 static int
__hal_device_handle_link_down_ind(xge_hal_device_t * hldev)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,
2621 	                 hldev);
2622 	/* link is down */
2623 	return 1;
2624 }
2625 /*
2626  * __hal_device_handle_link_state_change
2627  * @hldev: HAL device handle.
2628  *
2629  * Link state change handler. The function is invoked by HAL when
2630  * Xframe indicates link state change condition. The code here makes sure to
2631  * 1) ignore redundant state change indications;
2632  * 2) execute link-up sequence, and handle the failure to bring the link up;
2633  * 3) generate XGE_HAL_LINK_UP/DOWN event for the subsequent handling by
2634  *    upper-layer driver (ULD).
2635  */
2636 static int
__hal_device_handle_link_state_change(xge_hal_device_t * hldev)2637 __hal_device_handle_link_state_change(xge_hal_device_t *hldev)
2638 {
2639 	u64 hw_status;
2640 	int hw_link_state;
2641 	int retcode;
2642 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2643 	u64 val64;
2644 	int i = 0;
2645 
2646 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2647 	                &bar0->adapter_control);
2648 
2649 	/* If the adapter is not enabled but the hal thinks we are in the up
2650 	 * state then transition to the down state.
2651 	 */
2652 	if ( !(val64 & XGE_HAL_ADAPTER_CNTL_EN) &&
2653 	     (hldev->link_state == XGE_HAL_LINK_UP) ) {
2654 	    return(__hal_device_handle_link_down_ind(hldev));
2655 	}
2656 
2657 	do {
2658 	    xge_os_mdelay(1);
2659 	    (void) xge_hal_device_status(hldev, &hw_status);
2660 	    hw_link_state = (hw_status &
2661 	        (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
2662 	            XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) ?
2663 	            XGE_HAL_LINK_DOWN : XGE_HAL_LINK_UP;
2664 
2665 	    /* check if the current link state is still considered
2666 	     * to be changed. This way we will make sure that this is
2667 	     * not a noise which needs to be filtered out */
2668 	    if (hldev->link_state == hw_link_state)
2669 	        break;
2670 	} while (i++ < hldev->config.link_valid_cnt);
2671 
2672 	/* If the current link state is same as previous, just return */
2673 	if (hldev->link_state == hw_link_state)
2674 	    retcode = 0;
2675 	/* detected state change */
2676 	else if (hw_link_state == XGE_HAL_LINK_UP)
2677 	    retcode = __hal_device_handle_link_up_ind(hldev);
2678 	else
2679 	    retcode = __hal_device_handle_link_down_ind(hldev);
2680 	return retcode;
2681 }
2682 
2683 /*
2684  *
2685  */
2686 static void
__hal_device_handle_serr(xge_hal_device_t * hldev,char * reg,u64 value)2687 __hal_device_handle_serr(xge_hal_device_t *hldev, char *reg, u64 value)
2688 {
2689 	hldev->stats.sw_dev_err_stats.serr_cnt++;
2690 	if (hldev->config.dump_on_serr) {
2691 #ifdef XGE_HAL_USE_MGMT_AUX
2692 	    (void) xge_hal_aux_device_dump(hldev);
2693 #endif
2694 	}
2695 
2696 	(void) xge_queue_produce(hldev->queueh, XGE_HAL_EVENT_SERR, hldev,
2697 	           1, sizeof(u64), (void *)&value);
2698 
2699 	xge_debug_device(XGE_ERR, "%s: read "XGE_OS_LLXFMT, reg,
2700 	              (unsigned long long) value);
2701 }
2702 
2703 /*
2704  *
2705  */
2706 static void
__hal_device_handle_eccerr(xge_hal_device_t * hldev,char * reg,u64 value)2707 __hal_device_handle_eccerr(xge_hal_device_t *hldev, char *reg, u64 value)
2708 {
2709 	if (hldev->config.dump_on_eccerr) {
2710 #ifdef XGE_HAL_USE_MGMT_AUX
2711 	    (void) xge_hal_aux_device_dump(hldev);
2712 #endif
2713 	}
2714 
2715 	/* Herc smart enough to recover on its own! */
2716 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
2717 	    (void) xge_queue_produce(hldev->queueh,
2718 	        XGE_HAL_EVENT_ECCERR, hldev,
2719 	        1, sizeof(u64), (void *)&value);
2720 	}
2721 
2722 	    xge_debug_device(XGE_ERR, "%s: read "XGE_OS_LLXFMT, reg,
2723 	                              (unsigned long long) value);
2724 }
2725 
2726 /*
2727  *
2728  */
2729 static void
__hal_device_handle_parityerr(xge_hal_device_t * hldev,char * reg,u64 value)2730 __hal_device_handle_parityerr(xge_hal_device_t *hldev, char *reg, u64 value)
2731 {
2732 	if (hldev->config.dump_on_parityerr) {
2733 #ifdef XGE_HAL_USE_MGMT_AUX
2734 	    (void) xge_hal_aux_device_dump(hldev);
2735 #endif
2736 	}
2737 	(void) xge_queue_produce_context(hldev->queueh,
2738 	        XGE_HAL_EVENT_PARITYERR, hldev);
2739 
2740 	    xge_debug_device(XGE_ERR, "%s: read "XGE_OS_LLXFMT, reg,
2741 	                              (unsigned long long) value);
2742 }
2743 
2744 /*
2745  *
2746  */
2747 static void
__hal_device_handle_targetabort(xge_hal_device_t * hldev)2748 __hal_device_handle_targetabort(xge_hal_device_t *hldev)
2749 {
2750 	(void) xge_queue_produce_context(hldev->queueh,
2751 	        XGE_HAL_EVENT_TARGETABORT, hldev);
2752 }
2753 
2754 
2755 /*
2756  * __hal_device_hw_initialize
2757  * @hldev: HAL device handle.
2758  *
2759  * Initialize Xframe hardware.
2760  */
2761 static xge_hal_status_e
__hal_device_hw_initialize(xge_hal_device_t * hldev)2762 __hal_device_hw_initialize(xge_hal_device_t *hldev)
2763 {
2764 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
2765 	xge_hal_status_e status;
2766 	u64 val64;
2767 
2768 	/* Set proper endian settings and verify the same by reading the PIF
2769 	 * Feed-back register. */
2770 	status = __hal_device_set_swapper(hldev);
2771 	if (status != XGE_HAL_OK) {
2772 	    return status;
2773 	}
2774 
2775 	/* update the pci mode, frequency, and width */
2776 	if (__hal_device_pci_info_get(hldev, &hldev->pci_mode,
2777 	    &hldev->bus_frequency, &hldev->bus_width) != XGE_HAL_OK){
2778 	    hldev->pci_mode = XGE_HAL_PCI_INVALID_MODE;
2779 	    hldev->bus_frequency = XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN;
2780 	    hldev->bus_width = XGE_HAL_PCI_BUS_WIDTH_UNKNOWN;
2781 	    /*
2782 	     * FIXME: this cannot happen.
2783 	     * But if it happens we cannot continue just like that
2784 	     */
2785 	    xge_debug_device(XGE_ERR, "unable to get pci info");
2786 	}
2787 
2788 	if ((hldev->pci_mode == XGE_HAL_PCI_33MHZ_MODE) ||
2789 	    (hldev->pci_mode == XGE_HAL_PCI_66MHZ_MODE) ||
2790 	    (hldev->pci_mode == XGE_HAL_PCI_BASIC_MODE)) {
2791 	    /* PCI optimization: set TxReqTimeOut
2792 	     * register (0x800+0x120) to 0x1ff or
2793 	     * something close to this.
2794 	     * Note: not to be used for PCI-X! */
2795 
2796 	    val64 = XGE_HAL_TXREQTO_VAL(0x1FF);
2797 	    val64 |= XGE_HAL_TXREQTO_EN;
2798 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2799 	                 &bar0->txreqtimeout);
2800 
2801 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0ULL,
2802 	                 &bar0->read_retry_delay);
2803 
2804 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0ULL,
2805 	                 &bar0->write_retry_delay);
2806 
2807 	    xge_debug_device(XGE_TRACE, "%s", "optimizing for PCI mode");
2808 	}
2809 
2810 	if (hldev->bus_frequency == XGE_HAL_PCI_BUS_FREQUENCY_266MHZ ||
2811 	    hldev->bus_frequency == XGE_HAL_PCI_BUS_FREQUENCY_250MHZ) {
2812 
2813 	    /* Optimizing for PCI-X 266/250 */
2814 
2815 	    val64 = XGE_HAL_TXREQTO_VAL(0x7F);
2816 	    val64 |= XGE_HAL_TXREQTO_EN;
2817 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2818 	                 &bar0->txreqtimeout);
2819 
2820 	    xge_debug_device(XGE_TRACE, "%s", "optimizing for PCI-X 266/250 modes");
2821 	}
2822 
2823 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2824 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x4000000000000ULL,
2825 	                 &bar0->read_retry_delay);
2826 
2827 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x4000000000000ULL,
2828 	                 &bar0->write_retry_delay);
2829 	}
2830 
2831 	/* added this to set the no of bytes used to update lso_bytes_sent
2832 	   returned TxD0 */
2833 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2834 	                  &bar0->pic_control_2);
2835 	val64 &= ~XGE_HAL_TXD_WRITE_BC(0x2);
2836 	val64 |= XGE_HAL_TXD_WRITE_BC(0x4);
2837 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
2838 	               &bar0->pic_control_2);
2839 	/* added this to clear the EOI_RESET field while leaving XGXS_RESET
2840 	 * in reset, then a 1-second delay */
2841 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2842 	        XGE_HAL_SW_RESET_XGXS, &bar0->sw_reset);
2843 	xge_os_mdelay(1000);
2844 
2845 	/* Clear the XGXS_RESET field of the SW_RESET register in order to
2846 	 * release the XGXS from reset. Its reset value is 0xA5; write 0x00
2847 	 * to activate the XGXS. The core requires a minimum 500 us reset.*/
2848 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0, &bar0->sw_reset);
2849 	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2850 	            &bar0->sw_reset);
2851 	xge_os_mdelay(1);
2852 
2853 	/* read registers in all blocks */
2854 	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2855 	               &bar0->mac_int_mask);
2856 	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2857 	               &bar0->mc_int_mask);
2858 	(void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2859 	               &bar0->xgxs_int_mask);
2860 
2861 	/* set default MTU and steer based on length*/
2862 	__hal_ring_mtu_set(hldev, hldev->config.mtu+22); // Alway set 22 bytes extra for steering to work
2863 
2864 	if (hldev->config.mac.rmac_bcast_en) {
2865 	    xge_hal_device_bcast_enable(hldev);
2866 	} else {
2867 	    xge_hal_device_bcast_disable(hldev);
2868 	}
2869 
2870 #ifndef XGE_HAL_HERC_EMULATION
2871 	__hal_device_xaui_configure(hldev);
2872 #endif
2873 	__hal_device_mac_link_util_set(hldev);
2874 
2875 	__hal_device_mac_link_util_set(hldev);
2876 
2877 	/*
2878 	 * Keep its PCI REQ# line asserted during a write
2879 	 * transaction up to the end of the transaction
2880 	 */
2881 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2882 	            &bar0->misc_control);
2883 
2884 	val64 |= XGE_HAL_MISC_CONTROL_EXT_REQ_EN;
2885 
2886 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2887 	            val64, &bar0->misc_control);
2888 
2889 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2890 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
2891 	                &bar0->misc_control);
2892 
2893 	    val64 |= XGE_HAL_MISC_CONTROL_LINK_FAULT;
2894 
2895 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
2896 	                val64, &bar0->misc_control);
2897 	}
2898 
2899 	/*
2900 	 * bimodal interrupts is when all Rx traffic interrupts
2901 	 * will go to TTI, so we need to adjust RTI settings and
2902 	 * use adaptive TTI timer. We need to make sure RTI is
2903 	 * properly configured to sane value which will not
2904 	 * distrupt bimodal behavior.
2905 	 */
2906 	if (hldev->config.bimodal_interrupts) {
2907 	    int i;
2908 
2909 	    /* force polling_cnt to be "0", otherwise
2910 	     * IRQ workload statistics will be screwed. This could
2911 	     * be worked out in TXPIC handler later. */
2912 	    hldev->config.isr_polling_cnt = 0;
2913 	    hldev->config.sched_timer_us = 10000;
2914 
2915 	    /* disable all TTI < 56 */
2916 	    for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
2917 	        int j;
2918 	        if (!hldev->config.fifo.queue[i].configured)
2919 	            continue;
2920 	        for (j=0; j<XGE_HAL_MAX_FIFO_TTI_NUM; j++) {
2921 	            if (hldev->config.fifo.queue[i].tti[j].enabled)
2922 	            hldev->config.fifo.queue[i].tti[j].enabled = 0;
2923 	        }
2924 	    }
2925 
2926 	    /* now configure bimodal interrupts */
2927 	    __hal_device_bimodal_configure(hldev);
2928 	}
2929 
2930 	status = __hal_device_tti_configure(hldev, 0);
2931 	if (status != XGE_HAL_OK)
2932 	    return status;
2933 
2934 	status = __hal_device_rti_configure(hldev, 0);
2935 	if (status != XGE_HAL_OK)
2936 	    return status;
2937 
2938 	status = __hal_device_rth_it_configure(hldev);
2939 	if (status != XGE_HAL_OK)
2940 	    return status;
2941 
2942 	status = __hal_device_rth_spdm_configure(hldev);
2943 	if (status != XGE_HAL_OK)
2944 	    return status;
2945 
2946 	status = __hal_device_rts_mac_configure(hldev);
2947 	if (status != XGE_HAL_OK) {
2948 	    xge_debug_device(XGE_ERR, "__hal_device_rts_mac_configure Failed ");
2949 	    return status;
2950 	}
2951 
2952 	status = __hal_device_rts_port_configure(hldev);
2953 	if (status != XGE_HAL_OK) {
2954 	    xge_debug_device(XGE_ERR, "__hal_device_rts_port_configure Failed ");
2955 	    return status;
2956 	}
2957 
2958 	status = __hal_device_rts_qos_configure(hldev);
2959 	if (status != XGE_HAL_OK) {
2960 	    xge_debug_device(XGE_ERR, "__hal_device_rts_qos_configure Failed ");
2961 	    return status;
2962 	}
2963 
2964 	__hal_device_pause_frames_configure(hldev);
2965 	__hal_device_rmac_padding_configure(hldev);
2966 	__hal_device_shared_splits_configure(hldev);
2967 
2968 	/* make sure all interrupts going to be disabled at the moment */
2969 	__hal_device_intr_mgmt(hldev, XGE_HAL_ALL_INTRS, 0);
2970 
2971 	/* SXE-008 Transmit DMA arbitration issue */
2972 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA &&
2973 	    hldev->revision < 4) {
2974 	    xge_os_pio_mem_write64(hldev->pdev,hldev->regh0,
2975 	            XGE_HAL_ADAPTER_PCC_ENABLE_FOUR,
2976 	            &bar0->pcc_enable);
2977 	}
2978 #if 0  // Removing temporarily as FreeBSD is seeing lower performance
2979 	   // attributable to this fix.
2980 	/* SXE-2-010 */
2981 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
2982 	    /* Turn off the ECC error reporting for RLDRAM interface */
2983 	    if ((status = xge_hal_fix_rldram_ecc_error(hldev)) != XGE_HAL_OK)
2984 	        return status;
2985 	}
2986 #endif
2987 	__hal_fifo_hw_initialize(hldev);
2988 	__hal_ring_hw_initialize(hldev);
2989 
2990 	if (__hal_device_wait_quiescent(hldev, &val64)) {
2991 	    return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
2992 	}
2993 
2994 	if (__hal_device_register_poll(hldev, &bar0->adapter_status, 1,
2995 	    XGE_HAL_ADAPTER_STATUS_RC_PRC_QUIESCENT,
2996 	     XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
2997 	    xge_debug_device(XGE_TRACE, "%s", "PRC is not QUIESCENT!");
2998 	    return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
2999 	}
3000 
3001 	xge_debug_device(XGE_TRACE, "device 0x"XGE_OS_LLXFMT" is quiescent",
3002 	          (unsigned long long)(ulong_t)hldev);
3003 
3004 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX ||
3005 	    hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSI) {
3006 	    /*
3007 	     * If MSI is enabled, ensure that One Shot for MSI in PCI_CTRL
3008 	     * is disabled.
3009 	     */
3010 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3011 	                    &bar0->pic_control);
3012 	    val64 &= ~(XGE_HAL_PIC_CNTL_ONE_SHOT_TINT);
3013 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
3014 	                    &bar0->pic_control);
3015 	}
3016 
3017 	hldev->hw_is_initialized = 1;
3018 	hldev->terminating = 0;
3019 	return XGE_HAL_OK;
3020 }
3021 
3022 /*
3023  * __hal_device_reset - Reset device only.
3024  * @hldev: HAL device handle.
3025  *
3026  * Reset the device, and subsequently restore
3027  * the previously saved PCI configuration space.
3028  */
3029 #define XGE_HAL_MAX_PCI_CONFIG_SPACE_REINIT 50
3030 static xge_hal_status_e
__hal_device_reset(xge_hal_device_t * hldev)3031 __hal_device_reset(xge_hal_device_t *hldev)
3032 {
3033 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
3034 	int i, j, swap_done, pcisize = 0;
3035 	u64 val64, rawval = 0ULL;
3036 
3037 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
3038 	    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
3039 	        if ( hldev->bar2 ) {
3040 	            u64 *msix_vetor_table = (u64 *)hldev->bar2;
3041 
3042 	            // 2 64bit words for each entry
3043 	            for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2;
3044 	                 i++) {
3045 	                  hldev->msix_vector_table[i] =
3046 	                   xge_os_pio_mem_read64(hldev->pdev,
3047 	                          hldev->regh2, &msix_vetor_table[i]);
3048 	            }
3049 	        }
3050 	    }
3051 	}
3052 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3053 	                            &bar0->pif_rd_swapper_fb);
3054 	swap_done = (val64 == XGE_HAL_IF_RD_SWAPPER_FB);
3055 
3056 	if (swap_done) {
3057 	    __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
3058 	         (u32)(XGE_HAL_SW_RESET_ALL>>32), (char *)&bar0->sw_reset);
3059 	} else {
3060 	    u32 val = (u32)(XGE_HAL_SW_RESET_ALL >> 32);
3061 #if defined(XGE_OS_HOST_LITTLE_ENDIAN) || defined(XGE_OS_PIO_LITTLE_ENDIAN)
3062 	    /* swap it */
3063 	    val = (((val & (u32)0x000000ffUL) << 24) |
3064 	           ((val & (u32)0x0000ff00UL) <<  8) |
3065 	           ((val & (u32)0x00ff0000UL) >>  8) |
3066 	           ((val & (u32)0xff000000UL) >> 24));
3067 #endif
3068 	    xge_os_pio_mem_write32(hldev->pdev, hldev->regh0, val,
3069 	                 &bar0->sw_reset);
3070 	}
3071 
3072 	pcisize = (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)?
3073 	           XGE_HAL_PCISIZE_HERC : XGE_HAL_PCISIZE_XENA;
3074 
3075 	xge_os_mdelay(20); /* Wait for 20 ms after reset */
3076 
3077 	{
3078 	    /* Poll for no more than 1 second */
3079 	    for (i = 0; i < XGE_HAL_MAX_PCI_CONFIG_SPACE_REINIT; i++)
3080 	    {
3081 	        for (j = 0; j < pcisize; j++) {
3082 	            xge_os_pci_write32(hldev->pdev, hldev->cfgh, j * 4,
3083 	                *((u32*)&hldev->pci_config_space + j));
3084 	        }
3085 
3086 	        xge_os_pci_read16(hldev->pdev,hldev->cfgh,
3087 	            xge_offsetof(xge_hal_pci_config_le_t, device_id),
3088 	            &hldev->device_id);
3089 
3090 	        if (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_UNKNOWN)
3091 	            break;
3092 	        xge_os_mdelay(20);
3093 	    }
3094 	}
3095 
3096 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_UNKNOWN)
3097 	{
3098 	    xge_debug_device(XGE_ERR, "device reset failed");
3099 	        return XGE_HAL_ERR_RESET_FAILED;
3100 	}
3101 
3102 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
3103 	    int cnt = 0;
3104 
3105 	    rawval = XGE_HAL_SW_RESET_RAW_VAL_HERC;
3106 	    pcisize = XGE_HAL_PCISIZE_HERC;
3107 	    xge_os_mdelay(1);
3108 	    do {
3109 	        val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3110 	            &bar0->sw_reset);
3111 	        if (val64 != rawval) {
3112 	            break;
3113 	        }
3114 	        cnt++;
3115 	        xge_os_mdelay(1); /* Wait for 1ms before retry */
3116 	    } while(cnt < 20);
3117 	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
3118 	    rawval = XGE_HAL_SW_RESET_RAW_VAL_XENA;
3119 	    pcisize = XGE_HAL_PCISIZE_XENA;
3120 	    xge_os_mdelay(XGE_HAL_DEVICE_RESET_WAIT_MAX_MILLIS);
3121 	}
3122 
3123 	/* Restore MSI-X vector table */
3124 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
3125 	    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
3126 	        if ( hldev->bar2 ) {
3127 	            /*
3128 	             * 94: MSIXTable 00000004  ( BIR:4  Offset:0x0 )
3129 	             * 98: PBATable  00000404  ( BIR:4  Offset:0x400 )
3130 	             */
3131 	             u64 *msix_vetor_table = (u64 *)hldev->bar2;
3132 
3133 	             /* 2 64bit words for each entry */
3134 	             for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2;
3135 	              i++) {
3136 	                 xge_os_pio_mem_write64(hldev->pdev,
3137 	                hldev->regh2,
3138 	                hldev->msix_vector_table[i],
3139 	                &msix_vetor_table[i]);
3140 	             }
3141 	        }
3142 	    }
3143 	}
3144 
3145 	hldev->link_state = XGE_HAL_LINK_DOWN;
3146 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3147 	                                  &bar0->sw_reset);
3148 
3149 	if (val64 != rawval) {
3150 	    xge_debug_device(XGE_ERR, "device has not been reset "
3151 	        "got 0x"XGE_OS_LLXFMT", expected 0x"XGE_OS_LLXFMT,
3152 	        (unsigned long long)val64, (unsigned long long)rawval);
3153 	        return XGE_HAL_ERR_RESET_FAILED;
3154 	}
3155 
3156 	hldev->hw_is_initialized = 0;
3157 	return XGE_HAL_OK;
3158 }
3159 
3160 /*
3161  * __hal_device_poll - General private routine to poll the device.
3162  * @hldev: HAL device handle.
3163  *
3164  * Returns: one of the xge_hal_status_e{} enumerated types.
3165  * XGE_HAL_OK           - for success.
3166  * XGE_HAL_ERR_CRITICAL         - when encounters critical error.
3167  */
3168 static xge_hal_status_e
__hal_device_poll(xge_hal_device_t * hldev)3169 __hal_device_poll(xge_hal_device_t *hldev)
3170 {
3171 	xge_hal_pci_bar0_t *bar0;
3172 	u64 err_reg;
3173 
3174 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
3175 
3176 	/* Handling SERR errors by forcing a H/W reset. */
3177 	err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3178 	                  &bar0->serr_source);
3179 	if (err_reg & XGE_HAL_SERR_SOURCE_ANY) {
3180 	    __hal_device_handle_serr(hldev, "serr_source", err_reg);
3181 	    return XGE_HAL_ERR_CRITICAL;
3182 	}
3183 
3184 	err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3185 	                &bar0->misc_int_reg);
3186 
3187 	if (err_reg & XGE_HAL_MISC_INT_REG_DP_ERR_INT) {
3188 	    hldev->stats.sw_dev_err_stats.parity_err_cnt++;
3189 	    __hal_device_handle_parityerr(hldev, "misc_int_reg", err_reg);
3190 	    return XGE_HAL_ERR_CRITICAL;
3191 	}
3192 
3193 #ifdef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
3194 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
3195 #endif
3196 	{
3197 
3198 	    /* Handling link status change error Intr */
3199 	    err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3200 	                    &bar0->mac_rmac_err_reg);
3201 	    if (__hal_device_handle_link_state_change(hldev))
3202 	        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3203 	                   err_reg, &bar0->mac_rmac_err_reg);
3204 	}
3205 
3206 	if (hldev->inject_serr != 0) {
3207 	    err_reg = hldev->inject_serr;
3208 	    hldev->inject_serr = 0;
3209 	    __hal_device_handle_serr(hldev, "inject_serr", err_reg);
3210 	    return XGE_HAL_ERR_CRITICAL;
3211 	    }
3212 
3213 	    if (hldev->inject_ecc != 0) {
3214 	            err_reg = hldev->inject_ecc;
3215 	            hldev->inject_ecc = 0;
3216 	    hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
3217 	            __hal_device_handle_eccerr(hldev, "inject_ecc", err_reg);
3218 	    return XGE_HAL_ERR_CRITICAL;
3219 	    }
3220 
3221 	if (hldev->inject_bad_tcode != 0) {
3222 	    u8 t_code = hldev->inject_bad_tcode;
3223 	    xge_hal_channel_t channel;
3224 	    xge_hal_fifo_txd_t txd;
3225 	    xge_hal_ring_rxd_1_t rxd;
3226 
3227 	    channel.devh =  hldev;
3228 
3229 	    if (hldev->inject_bad_tcode_for_chan_type ==
3230 	                    XGE_HAL_CHANNEL_TYPE_FIFO) {
3231 	        channel.type = XGE_HAL_CHANNEL_TYPE_FIFO;
3232 
3233 	    } else {
3234 	        channel.type = XGE_HAL_CHANNEL_TYPE_RING;
3235 	    }
3236 
3237 	            hldev->inject_bad_tcode = 0;
3238 
3239 	    if (channel.type == XGE_HAL_CHANNEL_TYPE_FIFO)
3240 	        return xge_hal_device_handle_tcode(&channel, &txd,
3241 	                                           t_code);
3242 	    else
3243 	        return xge_hal_device_handle_tcode(&channel, &rxd,
3244 	                                           t_code);
3245 	    }
3246 
3247 	return XGE_HAL_OK;
3248 }
3249 
3250 /*
3251  * __hal_verify_pcc_idle - Verify All Enbled PCC are IDLE or not
3252  * @hldev: HAL device handle.
3253  * @adp_status: Adapter Status value
3254  * Usage: See xge_hal_device_enable{}.
3255  */
3256 xge_hal_status_e
__hal_verify_pcc_idle(xge_hal_device_t * hldev,u64 adp_status)3257 __hal_verify_pcc_idle(xge_hal_device_t *hldev, u64 adp_status)
3258 {
3259 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA &&
3260 	    hldev->revision < 4) {
3261 	    /*
3262 	     * For Xena 1,2,3 we enable only 4 PCCs Due to
3263 	     * SXE-008 (Transmit DMA arbitration issue)
3264 	     */
3265 	    if ((adp_status & XGE_HAL_ADAPTER_STATUS_RMAC_PCC_4_IDLE)
3266 	        != XGE_HAL_ADAPTER_STATUS_RMAC_PCC_4_IDLE) {
3267 	        xge_debug_device(XGE_TRACE, "%s",
3268 	            "PCC is not IDLE after adapter enabled!");
3269 	        return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
3270 	    }
3271 	} else {
3272 	    if ((adp_status & XGE_HAL_ADAPTER_STATUS_RMAC_PCC_IDLE) !=
3273 	        XGE_HAL_ADAPTER_STATUS_RMAC_PCC_IDLE) {
3274 	        xge_debug_device(XGE_TRACE, "%s",
3275 	        "PCC is not IDLE after adapter enabled!");
3276 	        return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
3277 	    }
3278 	}
3279 	return XGE_HAL_OK;
3280 }
3281 
3282 static void
__hal_update_bimodal(xge_hal_device_t * hldev,int ring_no)3283 __hal_update_bimodal(xge_hal_device_t *hldev, int ring_no)
3284 {
3285 	int tval, d, iwl_avg, len_avg, bytes_avg, bytes_hist, d_hist;
3286 	int iwl_rxcnt, iwl_txcnt, iwl_txavg, len_rxavg, iwl_rxavg, len_txavg;
3287 	int iwl_cnt, i;
3288 
3289 #define _HIST_SIZE  50 /* 0.5 sec history */
3290 #define _HIST_ADJ_TIMER 1
3291 #define _STEP       2
3292 
3293 	static int bytes_avg_history[_HIST_SIZE] = {0};
3294 	static int d_avg_history[_HIST_SIZE] = {0};
3295 	static int history_idx = 0;
3296 	static int pstep = 1;
3297 	static int hist_adj_timer = 0;
3298 
3299 	/*
3300 	 * tval - current value of this bimodal timer
3301 	 */
3302 	tval = hldev->bimodal_tti[ring_no].timer_val_us;
3303 
3304 	/*
3305 	 * d - how many interrupts we were getting since last
3306 	 *     bimodal timer tick.
3307 	 */
3308 	d = hldev->stats.sw_dev_info_stats.tx_traffic_intr_cnt -
3309 	    hldev->bimodal_intr_cnt;
3310 
3311 	/* advance bimodal interrupt counter */
3312 	hldev->bimodal_intr_cnt =
3313 	    hldev->stats.sw_dev_info_stats.tx_traffic_intr_cnt;
3314 
3315 	/*
3316 	 * iwl_cnt - how many interrupts we've got since last
3317 	 *           bimodal timer tick.
3318 	 */
3319 	iwl_rxcnt = (hldev->irq_workload_rxcnt[ring_no] ?
3320 	                 hldev->irq_workload_rxcnt[ring_no] : 1);
3321 	iwl_txcnt = (hldev->irq_workload_txcnt[ring_no] ?
3322 	                 hldev->irq_workload_txcnt[ring_no] : 1);
3323 	iwl_cnt = iwl_rxcnt + iwl_txcnt;
3324 	iwl_cnt = iwl_cnt; /* just to remove the lint warning */
3325 
3326 	/*
3327 	 * we need to take hldev->config.isr_polling_cnt into account
3328 	 * but for some reason this line causing GCC to produce wrong
3329 	 * code on Solaris. As of now, if bimodal_interrupts is configured
3330 	 * hldev->config.isr_polling_cnt is forced to be "0".
3331 	 *
3332 	 * iwl_cnt = iwl_cnt / (hldev->config.isr_polling_cnt + 1); */
3333 
3334 	/*
3335 	 * iwl_avg - how many RXDs on avarage been processed since
3336 	 *           last bimodal timer tick. This indirectly includes
3337 	 *           CPU utilizations.
3338 	 */
3339 	iwl_rxavg = hldev->irq_workload_rxd[ring_no] / iwl_rxcnt;
3340 	iwl_txavg = hldev->irq_workload_txd[ring_no] / iwl_txcnt;
3341 	iwl_avg = iwl_rxavg + iwl_txavg;
3342 	iwl_avg = iwl_avg == 0 ? 1 : iwl_avg;
3343 
3344 	/*
3345 	 * len_avg - how many bytes on avarage been processed since
3346 	 *           last bimodal timer tick. i.e. avarage frame size.
3347 	 */
3348 	len_rxavg = 1 + hldev->irq_workload_rxlen[ring_no] /
3349 	           (hldev->irq_workload_rxd[ring_no] ?
3350 	            hldev->irq_workload_rxd[ring_no] : 1);
3351 	len_txavg = 1 + hldev->irq_workload_txlen[ring_no] /
3352 	           (hldev->irq_workload_txd[ring_no] ?
3353 	            hldev->irq_workload_txd[ring_no] : 1);
3354 	len_avg = len_rxavg + len_txavg;
3355 	if (len_avg < 60)
3356 	    len_avg = 60;
3357 
3358 	/* align on low boundary */
3359 	if ((tval -_STEP) < hldev->config.bimodal_timer_lo_us)
3360 	    tval = hldev->config.bimodal_timer_lo_us;
3361 
3362 	/* reset faster */
3363 	if (iwl_avg == 1) {
3364 	    tval = hldev->config.bimodal_timer_lo_us;
3365 	    /* reset history */
3366 	    for (i = 0; i < _HIST_SIZE; i++)
3367 	        bytes_avg_history[i] = d_avg_history[i] = 0;
3368 	    history_idx = 0;
3369 	    pstep = 1;
3370 	    hist_adj_timer = 0;
3371 	}
3372 
3373 	/* always try to ajust timer to the best throughput value */
3374 	bytes_avg = iwl_avg * len_avg;
3375 	history_idx %= _HIST_SIZE;
3376 	bytes_avg_history[history_idx] = bytes_avg;
3377 	d_avg_history[history_idx] = d;
3378 	history_idx++;
3379 	d_hist = bytes_hist = 0;
3380 	for (i = 0; i < _HIST_SIZE; i++) {
3381 	    /* do not re-configure until history is gathered */
3382 	    if (!bytes_avg_history[i]) {
3383 	        tval = hldev->config.bimodal_timer_lo_us;
3384 	        goto _end;
3385 	    }
3386 	    bytes_hist += bytes_avg_history[i];
3387 	    d_hist += d_avg_history[i];
3388 	}
3389 	bytes_hist /= _HIST_SIZE;
3390 	d_hist /= _HIST_SIZE;
3391 
3392 //  xge_os_printf("d %d iwl_avg %d len_avg %d:%d:%d tval %d avg %d hist %d pstep %d",
3393 //            d, iwl_avg, len_txavg, len_rxavg, len_avg, tval, d*bytes_avg,
3394 //            d_hist*bytes_hist, pstep);
3395 
3396 	/* make an adaptive step */
3397 	if (d * bytes_avg < d_hist * bytes_hist && hist_adj_timer++ > _HIST_ADJ_TIMER) {
3398 	    pstep = !pstep;
3399 	    hist_adj_timer = 0;
3400 	}
3401 
3402 	if (pstep &&
3403 	    (tval + _STEP) <= hldev->config.bimodal_timer_hi_us) {
3404 	    tval += _STEP;
3405 	    hldev->stats.sw_dev_info_stats.bimodal_hi_adjust_cnt++;
3406 	} else if ((tval - _STEP) >= hldev->config.bimodal_timer_lo_us) {
3407 	    tval -= _STEP;
3408 	    hldev->stats.sw_dev_info_stats.bimodal_lo_adjust_cnt++;
3409 	}
3410 
3411 	/* enable TTI range A for better latencies */
3412 	hldev->bimodal_urange_a_en = 0;
3413 	if (tval <= hldev->config.bimodal_timer_lo_us && iwl_avg > 2)
3414 	    hldev->bimodal_urange_a_en = 1;
3415 
3416 _end:
3417 	/* reset workload statistics counters */
3418 	hldev->irq_workload_rxcnt[ring_no] = 0;
3419 	hldev->irq_workload_rxd[ring_no] = 0;
3420 	hldev->irq_workload_rxlen[ring_no] = 0;
3421 	hldev->irq_workload_txcnt[ring_no] = 0;
3422 	hldev->irq_workload_txd[ring_no] = 0;
3423 	hldev->irq_workload_txlen[ring_no] = 0;
3424 
3425 	/* reconfigure TTI56 + ring_no with new timer value */
3426 	hldev->bimodal_timer_val_us = tval;
3427 	(void) __hal_device_rti_configure(hldev, 1);
3428 }
3429 
3430 static void
__hal_update_rxufca(xge_hal_device_t * hldev,int ring_no)3431 __hal_update_rxufca(xge_hal_device_t *hldev, int ring_no)
3432 {
3433 	int ufc, ic, i;
3434 
3435 	ufc = hldev->config.ring.queue[ring_no].rti.ufc_a;
3436 	ic = hldev->stats.sw_dev_info_stats.rx_traffic_intr_cnt;
3437 
3438 	/* urange_a adaptive coalescing */
3439 	if (hldev->rxufca_lbolt > hldev->rxufca_lbolt_time) {
3440 	    if (ic > hldev->rxufca_intr_thres) {
3441 	        if (ufc < hldev->config.rxufca_hi_lim) {
3442 	            ufc += 1;
3443 	            for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
3444 	               hldev->config.ring.queue[i].rti.ufc_a = ufc;
3445 	            (void) __hal_device_rti_configure(hldev, 1);
3446 	            hldev->stats.sw_dev_info_stats.
3447 	                rxufca_hi_adjust_cnt++;
3448 	        }
3449 	        hldev->rxufca_intr_thres = ic +
3450 	            hldev->config.rxufca_intr_thres; /* def: 30 */
3451 	    } else {
3452 	        if (ufc > hldev->config.rxufca_lo_lim) {
3453 	            ufc -= 1;
3454 	            for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
3455 	               hldev->config.ring.queue[i].rti.ufc_a = ufc;
3456 	            (void) __hal_device_rti_configure(hldev, 1);
3457 	            hldev->stats.sw_dev_info_stats.
3458 	                rxufca_lo_adjust_cnt++;
3459 	        }
3460 	    }
3461 	    hldev->rxufca_lbolt_time = hldev->rxufca_lbolt +
3462 	        hldev->config.rxufca_lbolt_period;
3463 	}
3464 	hldev->rxufca_lbolt++;
3465 }
3466 
3467 /*
3468  * __hal_device_handle_mc - Handle MC interrupt reason
3469  * @hldev: HAL device handle.
3470  * @reason: interrupt reason
3471  */
3472 xge_hal_status_e
__hal_device_handle_mc(xge_hal_device_t * hldev,u64 reason)3473 __hal_device_handle_mc(xge_hal_device_t *hldev, u64 reason)
3474 {
3475 	xge_hal_pci_bar0_t *isrbar0 =
3476 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3477 	u64 val64;
3478 
3479 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3480 	            &isrbar0->mc_int_status);
3481 	if (!(val64 & XGE_HAL_MC_INT_STATUS_MC_INT))
3482 	    return XGE_HAL_OK;
3483 
3484 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3485 	            &isrbar0->mc_err_reg);
3486 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3487 	            val64, &isrbar0->mc_err_reg);
3488 
3489 	if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_SG_ERR_L ||
3490 	    val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_SG_ERR_U ||
3491 	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_SG_ERR_0 ||
3492 	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_SG_ERR_1 ||
3493 	    (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_XENA &&
3494 	     (val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_SG_ERR_L ||
3495 	      val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_SG_ERR_U ||
3496 	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_SG_ERR_L ||
3497 	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_SG_ERR_U))) {
3498 	    hldev->stats.sw_dev_err_stats.single_ecc_err_cnt++;
3499 	    hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
3500 	}
3501 
3502 	if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_DB_ERR_L ||
3503 	    val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_DB_ERR_U ||
3504 	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_0 ||
3505 	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_1 ||
3506 	    (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_XENA &&
3507 	     (val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_DB_ERR_L ||
3508 	      val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_DB_ERR_U ||
3509 	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_DB_ERR_L ||
3510 	      val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_DB_ERR_U))) {
3511 	    hldev->stats.sw_dev_err_stats.double_ecc_err_cnt++;
3512 	    hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
3513 	}
3514 
3515 	if (val64 & XGE_HAL_MC_ERR_REG_SM_ERR) {
3516 	    hldev->stats.sw_dev_err_stats.sm_err_cnt++;
3517 	}
3518 
3519 	/* those two should result in device reset */
3520 	if (val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_0 ||
3521 	    val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_1) {
3522 	            __hal_device_handle_eccerr(hldev, "mc_err_reg", val64);
3523 	    return XGE_HAL_ERR_CRITICAL;
3524 	}
3525 
3526 	return XGE_HAL_OK;
3527 }
3528 
3529 /*
3530  * __hal_device_handle_pic - Handle non-traffic PIC interrupt reason
3531  * @hldev: HAL device handle.
3532  * @reason: interrupt reason
3533  */
3534 xge_hal_status_e
__hal_device_handle_pic(xge_hal_device_t * hldev,u64 reason)3535 __hal_device_handle_pic(xge_hal_device_t *hldev, u64 reason)
3536 {
3537 	xge_hal_pci_bar0_t *isrbar0 =
3538 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3539 	u64 val64;
3540 
3541 	if (reason & XGE_HAL_PIC_INT_FLSH) {
3542 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3543 	                &isrbar0->flsh_int_reg);
3544 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3545 	                   val64, &isrbar0->flsh_int_reg);
3546 	    /* FIXME: handle register */
3547 	}
3548 	if (reason & XGE_HAL_PIC_INT_MDIO) {
3549 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3550 	                &isrbar0->mdio_int_reg);
3551 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3552 	                   val64, &isrbar0->mdio_int_reg);
3553 	    /* FIXME: handle register */
3554 	}
3555 	if (reason & XGE_HAL_PIC_INT_IIC) {
3556 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3557 	                &isrbar0->iic_int_reg);
3558 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3559 	                   val64, &isrbar0->iic_int_reg);
3560 	    /* FIXME: handle register */
3561 	}
3562 	if (reason & XGE_HAL_PIC_INT_MISC) {
3563 	    val64 = xge_os_pio_mem_read64(hldev->pdev,
3564 	            hldev->regh0, &isrbar0->misc_int_reg);
3565 #ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
3566 	    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
3567 	        /*  Check for Link interrupts. If both Link Up/Down
3568 	         *  bits are set, clear both and check adapter status
3569 	         */
3570 	        if ((val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) &&
3571 	            (val64 & XGE_HAL_MISC_INT_REG_LINK_DOWN_INT)) {
3572 	            u64 temp64;
3573 
3574 	            xge_debug_device(XGE_TRACE,
3575 	            "both link up and link down detected "XGE_OS_LLXFMT,
3576 	            (unsigned long long)val64);
3577 
3578 	            temp64 = (XGE_HAL_MISC_INT_REG_LINK_DOWN_INT |
3579 	                  XGE_HAL_MISC_INT_REG_LINK_UP_INT);
3580 	            xge_os_pio_mem_write64(hldev->pdev,
3581 	                           hldev->regh0, temp64,
3582 	                           &isrbar0->misc_int_reg);
3583 	        }
3584 	        else if (val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) {
3585 	            xge_debug_device(XGE_TRACE,
3586 	                "link up call request, misc_int "XGE_OS_LLXFMT,
3587 	                (unsigned long long)val64);
3588 	            __hal_device_handle_link_up_ind(hldev);
3589 	        }
3590 	        else if (val64 & XGE_HAL_MISC_INT_REG_LINK_DOWN_INT){
3591 	            xge_debug_device(XGE_TRACE,
3592 	                "link down request, misc_int "XGE_OS_LLXFMT,
3593 	                (unsigned long long)val64);
3594 	            __hal_device_handle_link_down_ind(hldev);
3595 	        }
3596 	    } else
3597 #endif
3598 	    {
3599 	        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3600 	                   val64, &isrbar0->misc_int_reg);
3601 	    }
3602 	}
3603 
3604 	return XGE_HAL_OK;
3605 }
3606 
3607 /*
3608  * __hal_device_handle_txpic - Handle TxPIC interrupt reason
3609  * @hldev: HAL device handle.
3610  * @reason: interrupt reason
3611  */
3612 xge_hal_status_e
__hal_device_handle_txpic(xge_hal_device_t * hldev,u64 reason)3613 __hal_device_handle_txpic(xge_hal_device_t *hldev, u64 reason)
3614 {
3615 	xge_hal_status_e status = XGE_HAL_OK;
3616 	xge_hal_pci_bar0_t *isrbar0 =
3617 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3618 	volatile u64 val64;
3619 
3620 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3621 	            &isrbar0->pic_int_status);
3622 	if ( val64 & (XGE_HAL_PIC_INT_FLSH |
3623 	          XGE_HAL_PIC_INT_MDIO |
3624 	          XGE_HAL_PIC_INT_IIC |
3625 	          XGE_HAL_PIC_INT_MISC) ) {
3626 	    status =  __hal_device_handle_pic(hldev, val64);
3627 	    xge_os_wmb();
3628 	}
3629 
3630 	if (!(val64 & XGE_HAL_PIC_INT_TX))
3631 	    return status;
3632 
3633 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3634 	            &isrbar0->txpic_int_reg);
3635 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3636 	               val64, &isrbar0->txpic_int_reg);
3637 	xge_os_wmb();
3638 
3639 	if (val64 & XGE_HAL_TXPIC_INT_SCHED_INTR) {
3640 	    int i;
3641 
3642 	    if (g_xge_hal_driver->uld_callbacks.sched_timer != NULL)
3643 	        g_xge_hal_driver->uld_callbacks.sched_timer(
3644 	                  hldev, hldev->upper_layer_info);
3645 	    /*
3646 	     * This feature implements adaptive receive interrupt
3647 	     * coalecing. It is disabled by default. To enable it
3648 	     * set hldev->config.rxufca_lo_lim to be not equal to
3649 	     * hldev->config.rxufca_hi_lim.
3650 	     *
3651 	     * We are using HW timer for this feature, so
3652 	     * use needs to configure hldev->config.rxufca_lbolt_period
3653 	     * which is essentially a time slice of timer.
3654 	     *
3655 	     * For those who familiar with Linux, lbolt means jiffies
3656 	     * of this timer. I.e. timer tick.
3657 	     */
3658 	    if (hldev->config.rxufca_lo_lim !=
3659 	            hldev->config.rxufca_hi_lim &&
3660 	        hldev->config.rxufca_lo_lim != 0) {
3661 	        for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
3662 	            if (!hldev->config.ring.queue[i].configured)
3663 	                continue;
3664 	            if (hldev->config.ring.queue[i].rti.urange_a)
3665 	                __hal_update_rxufca(hldev, i);
3666 	        }
3667 	    }
3668 
3669 	    /*
3670 	     * This feature implements adaptive TTI timer re-calculation
3671 	     * based on host utilization, number of interrupt processed,
3672 	     * number of RXD per tick and avarage length of packets per
3673 	     * tick.
3674 	     */
3675 	    if (hldev->config.bimodal_interrupts) {
3676 	        for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
3677 	            if (!hldev->config.ring.queue[i].configured)
3678 	                continue;
3679 	            if (hldev->bimodal_tti[i].enabled)
3680 	                __hal_update_bimodal(hldev, i);
3681 	        }
3682 	    }
3683 	}
3684 
3685 	return XGE_HAL_OK;
3686 }
3687 
3688 /*
3689  * __hal_device_handle_txdma - Handle TxDMA interrupt reason
3690  * @hldev: HAL device handle.
3691  * @reason: interrupt reason
3692  */
3693 xge_hal_status_e
__hal_device_handle_txdma(xge_hal_device_t * hldev,u64 reason)3694 __hal_device_handle_txdma(xge_hal_device_t *hldev, u64 reason)
3695 {
3696 	xge_hal_pci_bar0_t *isrbar0 =
3697 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3698 	u64 val64, temp64, err;
3699 
3700 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3701 	            &isrbar0->txdma_int_status);
3702 	if (val64 & XGE_HAL_TXDMA_PFC_INT) {
3703 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3704 	            &isrbar0->pfc_err_reg);
3705 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3706 	            err, &isrbar0->pfc_err_reg);
3707 	    hldev->stats.sw_dev_info_stats.pfc_err_cnt++;
3708 	    temp64 = XGE_HAL_PFC_ECC_DB_ERR|XGE_HAL_PFC_SM_ERR_ALARM
3709 	        |XGE_HAL_PFC_MISC_0_ERR|XGE_HAL_PFC_MISC_1_ERR
3710 	        |XGE_HAL_PFC_PCIX_ERR;
3711 	    if (val64 & temp64)
3712 	        goto reset;
3713 	}
3714 	if (val64 & XGE_HAL_TXDMA_TDA_INT) {
3715 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3716 	            &isrbar0->tda_err_reg);
3717 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3718 	            err, &isrbar0->tda_err_reg);
3719 	    hldev->stats.sw_dev_info_stats.tda_err_cnt++;
3720 	    temp64 = XGE_HAL_TDA_Fn_ECC_DB_ERR|XGE_HAL_TDA_SM0_ERR_ALARM
3721 	        |XGE_HAL_TDA_SM1_ERR_ALARM;
3722 	    if (val64 & temp64)
3723 	        goto reset;
3724 	}
3725 	if (val64 & XGE_HAL_TXDMA_PCC_INT) {
3726 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3727 	            &isrbar0->pcc_err_reg);
3728 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3729 	            err, &isrbar0->pcc_err_reg);
3730 	    hldev->stats.sw_dev_info_stats.pcc_err_cnt++;
3731 	    temp64 = XGE_HAL_PCC_FB_ECC_DB_ERR|XGE_HAL_PCC_TXB_ECC_DB_ERR
3732 	        |XGE_HAL_PCC_SM_ERR_ALARM|XGE_HAL_PCC_WR_ERR_ALARM
3733 	        |XGE_HAL_PCC_N_SERR|XGE_HAL_PCC_6_COF_OV_ERR
3734 	        |XGE_HAL_PCC_7_COF_OV_ERR|XGE_HAL_PCC_6_LSO_OV_ERR
3735 	        |XGE_HAL_PCC_7_LSO_OV_ERR;
3736 	    if (val64 & temp64)
3737 	        goto reset;
3738 	}
3739 	if (val64 & XGE_HAL_TXDMA_TTI_INT) {
3740 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3741 	            &isrbar0->tti_err_reg);
3742 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3743 	            err, &isrbar0->tti_err_reg);
3744 	    hldev->stats.sw_dev_info_stats.tti_err_cnt++;
3745 	    temp64 = XGE_HAL_TTI_SM_ERR_ALARM;
3746 	    if (val64 & temp64)
3747 	        goto reset;
3748 	}
3749 	if (val64 & XGE_HAL_TXDMA_LSO_INT) {
3750 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3751 	            &isrbar0->lso_err_reg);
3752 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3753 	            err, &isrbar0->lso_err_reg);
3754 	    hldev->stats.sw_dev_info_stats.lso_err_cnt++;
3755 	    temp64 = XGE_HAL_LSO6_ABORT|XGE_HAL_LSO7_ABORT
3756 	        |XGE_HAL_LSO6_SM_ERR_ALARM|XGE_HAL_LSO7_SM_ERR_ALARM;
3757 	    if (val64 & temp64)
3758 	        goto reset;
3759 	}
3760 	if (val64 & XGE_HAL_TXDMA_TPA_INT) {
3761 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3762 	            &isrbar0->tpa_err_reg);
3763 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3764 	            err, &isrbar0->tpa_err_reg);
3765 	    hldev->stats.sw_dev_info_stats.tpa_err_cnt++;
3766 	    temp64 = XGE_HAL_TPA_SM_ERR_ALARM;
3767 	    if (val64 & temp64)
3768 	        goto reset;
3769 	}
3770 	if (val64 & XGE_HAL_TXDMA_SM_INT) {
3771 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3772 	            &isrbar0->sm_err_reg);
3773 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3774 	            err, &isrbar0->sm_err_reg);
3775 	    hldev->stats.sw_dev_info_stats.sm_err_cnt++;
3776 	    temp64 = XGE_HAL_SM_SM_ERR_ALARM;
3777 	    if (val64 & temp64)
3778 	        goto reset;
3779 	}
3780 
3781 	return XGE_HAL_OK;
3782 
3783 reset : xge_hal_device_reset(hldev);
3784 	xge_hal_device_enable(hldev);
3785 	xge_hal_device_intr_enable(hldev);
3786 	return XGE_HAL_OK;
3787 }
3788 
3789 /*
3790  * __hal_device_handle_txmac - Handle TxMAC interrupt reason
3791  * @hldev: HAL device handle.
3792  * @reason: interrupt reason
3793  */
3794 xge_hal_status_e
__hal_device_handle_txmac(xge_hal_device_t * hldev,u64 reason)3795 __hal_device_handle_txmac(xge_hal_device_t *hldev, u64 reason)
3796 {
3797 	xge_hal_pci_bar0_t *isrbar0 =
3798 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3799 	u64 val64, temp64;
3800 
3801 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3802 	            &isrbar0->mac_int_status);
3803 	if (!(val64 & XGE_HAL_MAC_INT_STATUS_TMAC_INT))
3804 	    return XGE_HAL_OK;
3805 
3806 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3807 	            &isrbar0->mac_tmac_err_reg);
3808 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3809 	            val64, &isrbar0->mac_tmac_err_reg);
3810 	hldev->stats.sw_dev_info_stats.mac_tmac_err_cnt++;
3811 	temp64 = XGE_HAL_TMAC_TX_BUF_OVRN|XGE_HAL_TMAC_TX_SM_ERR;
3812 	if (val64 & temp64) {
3813 	    xge_hal_device_reset(hldev);
3814 	    xge_hal_device_enable(hldev);
3815 	    xge_hal_device_intr_enable(hldev);
3816 	}
3817 
3818 	return XGE_HAL_OK;
3819 }
3820 
3821 /*
3822  * __hal_device_handle_txxgxs - Handle TxXGXS interrupt reason
3823  * @hldev: HAL device handle.
3824  * @reason: interrupt reason
3825  */
3826 xge_hal_status_e
__hal_device_handle_txxgxs(xge_hal_device_t * hldev,u64 reason)3827 __hal_device_handle_txxgxs(xge_hal_device_t *hldev, u64 reason)
3828 {
3829 	xge_hal_pci_bar0_t *isrbar0 =
3830 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3831 	u64 val64, temp64;
3832 
3833 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3834 	            &isrbar0->xgxs_int_status);
3835 	if (!(val64 & XGE_HAL_XGXS_INT_STATUS_TXGXS))
3836 	    return XGE_HAL_OK;
3837 
3838 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3839 	            &isrbar0->xgxs_txgxs_err_reg);
3840 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3841 	            val64, &isrbar0->xgxs_txgxs_err_reg);
3842 	hldev->stats.sw_dev_info_stats.xgxs_txgxs_err_cnt++;
3843 	temp64 = XGE_HAL_TXGXS_ESTORE_UFLOW|XGE_HAL_TXGXS_TX_SM_ERR;
3844 	if (val64 & temp64) {
3845 	    xge_hal_device_reset(hldev);
3846 	    xge_hal_device_enable(hldev);
3847 	    xge_hal_device_intr_enable(hldev);
3848 	}
3849 
3850 	return XGE_HAL_OK;
3851 }
3852 
3853 /*
3854  * __hal_device_handle_rxpic - Handle RxPIC interrupt reason
3855  * @hldev: HAL device handle.
3856  * @reason: interrupt reason
3857  */
3858 xge_hal_status_e
__hal_device_handle_rxpic(xge_hal_device_t * hldev,u64 reason)3859 __hal_device_handle_rxpic(xge_hal_device_t *hldev, u64 reason)
3860 {
3861 	/* FIXME: handle register */
3862 
3863 	return XGE_HAL_OK;
3864 }
3865 
3866 /*
3867  * __hal_device_handle_rxdma - Handle RxDMA interrupt reason
3868  * @hldev: HAL device handle.
3869  * @reason: interrupt reason
3870  */
3871 xge_hal_status_e
__hal_device_handle_rxdma(xge_hal_device_t * hldev,u64 reason)3872 __hal_device_handle_rxdma(xge_hal_device_t *hldev, u64 reason)
3873 {
3874 	xge_hal_pci_bar0_t *isrbar0 =
3875 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3876 	u64 val64, err, temp64;
3877 
3878 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3879 	            &isrbar0->rxdma_int_status);
3880 	if (val64 & XGE_HAL_RXDMA_RC_INT) {
3881 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3882 	            &isrbar0->rc_err_reg);
3883 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3884 	            err, &isrbar0->rc_err_reg);
3885 	    hldev->stats.sw_dev_info_stats.rc_err_cnt++;
3886 	    temp64 = XGE_HAL_RC_PRCn_ECC_DB_ERR|XGE_HAL_RC_FTC_ECC_DB_ERR
3887 	        |XGE_HAL_RC_PRCn_SM_ERR_ALARM
3888 	        |XGE_HAL_RC_FTC_SM_ERR_ALARM;
3889 	    if (val64 & temp64)
3890 	        goto reset;
3891 	}
3892 	if (val64 & XGE_HAL_RXDMA_RPA_INT) {
3893 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3894 	            &isrbar0->rpa_err_reg);
3895 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3896 	            err, &isrbar0->rpa_err_reg);
3897 	    hldev->stats.sw_dev_info_stats.rpa_err_cnt++;
3898 	    temp64 = XGE_HAL_RPA_SM_ERR_ALARM|XGE_HAL_RPA_CREDIT_ERR;
3899 	    if (val64 & temp64)
3900 	        goto reset;
3901 	}
3902 	if (val64 & XGE_HAL_RXDMA_RDA_INT) {
3903 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3904 	            &isrbar0->rda_err_reg);
3905 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3906 	            err, &isrbar0->rda_err_reg);
3907 	    hldev->stats.sw_dev_info_stats.rda_err_cnt++;
3908 	    temp64 = XGE_HAL_RDA_RXDn_ECC_DB_ERR
3909 	        |XGE_HAL_RDA_FRM_ECC_DB_N_AERR
3910 	        |XGE_HAL_RDA_SM1_ERR_ALARM|XGE_HAL_RDA_SM0_ERR_ALARM
3911 	        |XGE_HAL_RDA_RXD_ECC_DB_SERR;
3912 	    if (val64 & temp64)
3913 	        goto reset;
3914 	}
3915 	if (val64 & XGE_HAL_RXDMA_RTI_INT) {
3916 	    err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3917 	            &isrbar0->rti_err_reg);
3918 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3919 	            err, &isrbar0->rti_err_reg);
3920 	    hldev->stats.sw_dev_info_stats.rti_err_cnt++;
3921 	    temp64 = XGE_HAL_RTI_SM_ERR_ALARM;
3922 	    if (val64 & temp64)
3923 	        goto reset;
3924 	}
3925 
3926 	return XGE_HAL_OK;
3927 
3928 reset : xge_hal_device_reset(hldev);
3929 	xge_hal_device_enable(hldev);
3930 	xge_hal_device_intr_enable(hldev);
3931 	return XGE_HAL_OK;
3932 }
3933 
3934 /*
3935  * __hal_device_handle_rxmac - Handle RxMAC interrupt reason
3936  * @hldev: HAL device handle.
3937  * @reason: interrupt reason
3938  */
3939 xge_hal_status_e
__hal_device_handle_rxmac(xge_hal_device_t * hldev,u64 reason)3940 __hal_device_handle_rxmac(xge_hal_device_t *hldev, u64 reason)
3941 {
3942 	xge_hal_pci_bar0_t *isrbar0 =
3943 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3944 	u64 val64, temp64;
3945 
3946 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3947 	            &isrbar0->mac_int_status);
3948 	if (!(val64 & XGE_HAL_MAC_INT_STATUS_RMAC_INT))
3949 	    return XGE_HAL_OK;
3950 
3951 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3952 	            &isrbar0->mac_rmac_err_reg);
3953 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3954 	            val64, &isrbar0->mac_rmac_err_reg);
3955 	hldev->stats.sw_dev_info_stats.mac_rmac_err_cnt++;
3956 	temp64 = XGE_HAL_RMAC_RX_BUFF_OVRN|XGE_HAL_RMAC_RX_SM_ERR;
3957 	if (val64 & temp64) {
3958 	    xge_hal_device_reset(hldev);
3959 	    xge_hal_device_enable(hldev);
3960 	    xge_hal_device_intr_enable(hldev);
3961 	}
3962 
3963 	return XGE_HAL_OK;
3964 }
3965 
3966 /*
3967  * __hal_device_handle_rxxgxs - Handle RxXGXS interrupt reason
3968  * @hldev: HAL device handle.
3969  * @reason: interrupt reason
3970  */
3971 xge_hal_status_e
__hal_device_handle_rxxgxs(xge_hal_device_t * hldev,u64 reason)3972 __hal_device_handle_rxxgxs(xge_hal_device_t *hldev, u64 reason)
3973 {
3974 	xge_hal_pci_bar0_t *isrbar0 =
3975 	        (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
3976 	u64 val64, temp64;
3977 
3978 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3979 	            &isrbar0->xgxs_int_status);
3980 	if (!(val64 & XGE_HAL_XGXS_INT_STATUS_RXGXS))
3981 	    return XGE_HAL_OK;
3982 
3983 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
3984 	            &isrbar0->xgxs_rxgxs_err_reg);
3985 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
3986 	            val64, &isrbar0->xgxs_rxgxs_err_reg);
3987 	hldev->stats.sw_dev_info_stats.xgxs_rxgxs_err_cnt++;
3988 	temp64 = XGE_HAL_RXGXS_ESTORE_OFLOW|XGE_HAL_RXGXS_RX_SM_ERR;
3989 	if (val64 & temp64) {
3990 	    xge_hal_device_reset(hldev);
3991 	    xge_hal_device_enable(hldev);
3992 	    xge_hal_device_intr_enable(hldev);
3993 	}
3994 
3995 	return XGE_HAL_OK;
3996 }
3997 
3998 /**
3999  * xge_hal_device_enable - Enable device.
4000  * @hldev: HAL device handle.
4001  *
4002  * Enable the specified device: bring up the link/interface.
4003  * Returns:  XGE_HAL_OK - success.
4004  * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device
4005  * to a "quiescent" state.
4006  *
4007  * See also: xge_hal_status_e{}.
4008  *
4009  * Usage: See ex_open{}.
4010  */
4011 xge_hal_status_e
xge_hal_device_enable(xge_hal_device_t * hldev)4012 xge_hal_device_enable(xge_hal_device_t *hldev)
4013 {
4014 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4015 	u64 val64;
4016 	u64 adp_status;
4017 	int i, j;
4018 
4019 	if (!hldev->hw_is_initialized) {
4020 	    xge_hal_status_e status;
4021 
4022 	    status = __hal_device_hw_initialize(hldev);
4023 	    if (status != XGE_HAL_OK) {
4024 	        return status;
4025 	    }
4026 	}
4027 
4028 	/*
4029 	 * Not needed in most cases, i.e.
4030 	 * when device_disable() is followed by reset -
4031 	 * the latter copies back PCI config space, along with
4032 	 * the bus mastership - see __hal_device_reset().
4033 	 * However, there are/may-in-future be other cases, and
4034 	 * does not hurt.
4035 	 */
4036 	__hal_device_bus_master_enable(hldev);
4037 
4038 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
4039 	    /*
4040 	     * Configure the link stability period.
4041 	     */
4042 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4043 	                      &bar0->misc_control);
4044 	    if (hldev->config.link_stability_period !=
4045 	            XGE_HAL_DEFAULT_USE_HARDCODE) {
4046 
4047 	        val64 |= XGE_HAL_MISC_CONTROL_LINK_STABILITY_PERIOD(
4048 	                hldev->config.link_stability_period);
4049 	    } else {
4050 	        /*
4051 	         * Use the link stability period 1 ms as default
4052 	         */
4053 	        val64 |= XGE_HAL_MISC_CONTROL_LINK_STABILITY_PERIOD(
4054 	                XGE_HAL_DEFAULT_LINK_STABILITY_PERIOD);
4055 	    }
4056 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4057 	                   val64, &bar0->misc_control);
4058 
4059 	    /*
4060 	     * Clearing any possible Link up/down interrupts that
4061 	     * could have popped up just before Enabling the card.
4062 	     */
4063 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4064 	                      &bar0->misc_int_reg);
4065 	    if (val64) {
4066 	        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4067 	                       val64, &bar0->misc_int_reg);
4068 	        xge_debug_device(XGE_TRACE, "%s","link state cleared");
4069 	    }
4070 	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
4071 	    /*
4072 	     * Clearing any possible Link state change interrupts that
4073 	     * could have popped up just before Enabling the card.
4074 	     */
4075 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4076 	        &bar0->mac_rmac_err_reg);
4077 	    if (val64) {
4078 	        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4079 	                       val64, &bar0->mac_rmac_err_reg);
4080 	        xge_debug_device(XGE_TRACE, "%s", "link state cleared");
4081 	    }
4082 	}
4083 
4084 	if (__hal_device_wait_quiescent(hldev, &val64)) {
4085 	    return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4086 	}
4087 
4088 	/* Enabling Laser. */
4089 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4090 	                &bar0->adapter_control);
4091 	val64 |= XGE_HAL_ADAPTER_EOI_TX_ON;
4092 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4093 	                     &bar0->adapter_control);
4094 
4095 	/* let link establish */
4096 	xge_os_mdelay(1);
4097 
4098 	/* set link down untill poll() routine will set it up (maybe) */
4099 	hldev->link_state = XGE_HAL_LINK_DOWN;
4100 
4101 	/* If link is UP (adpter is connected) then enable the adapter */
4102 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4103 	                            &bar0->adapter_status);
4104 	if( val64 & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
4105 	         XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT) ) {
4106 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4107 	                            &bar0->adapter_control);
4108 	    val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
4109 	} else {
4110 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4111 	                               &bar0->adapter_control);
4112 	    val64 = val64 | ( XGE_HAL_ADAPTER_EOI_TX_ON |
4113 	              XGE_HAL_ADAPTER_LED_ON );
4114 	}
4115 
4116 	val64 = val64 | XGE_HAL_ADAPTER_CNTL_EN;   /* adapter enable */
4117 	val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN); /* ECC enable */
4118 	xge_os_pio_mem_write64 (hldev->pdev, hldev->regh0, val64,
4119 	              &bar0->adapter_control);
4120 
4121 	/* We spin here waiting for the Link to come up.
4122 	 * This is the fix for the Link being unstable after the reset. */
4123 	i = 0;
4124 	j = 0;
4125 	do
4126 	{
4127 	    adp_status = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4128 	                                    &bar0->adapter_status);
4129 
4130 	    /* Read the adapter control register for Adapter_enable bit */
4131 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4132 	                               &bar0->adapter_control);
4133 	    if (!(adp_status & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
4134 	                XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) &&
4135 	        (val64 & XGE_HAL_ADAPTER_CNTL_EN)) {
4136 	        j++;
4137 	        if (j >= hldev->config.link_valid_cnt) {
4138 	            if (xge_hal_device_status(hldev, &adp_status) ==
4139 	                        XGE_HAL_OK) {
4140 	                if (__hal_verify_pcc_idle(hldev,
4141 	                      adp_status) != XGE_HAL_OK) {
4142 	                   return
4143 	                    XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4144 	                }
4145 	                xge_debug_device(XGE_TRACE,
4146 	                      "adp_status: "XGE_OS_LLXFMT
4147 	                      ", link is up on "
4148 	                      "adapter enable!",
4149 	                      (unsigned long long)adp_status);
4150 	                val64 = xge_os_pio_mem_read64(
4151 	                        hldev->pdev,
4152 	                        hldev->regh0,
4153 	                        &bar0->adapter_control);
4154 	                val64 = val64|
4155 	                    (XGE_HAL_ADAPTER_EOI_TX_ON |
4156 	                     XGE_HAL_ADAPTER_LED_ON );
4157 	                xge_os_pio_mem_write64(hldev->pdev,
4158 	                                hldev->regh0, val64,
4159 	                                &bar0->adapter_control);
4160 	                xge_os_mdelay(1);
4161 
4162 	                val64 = xge_os_pio_mem_read64(
4163 	                        hldev->pdev,
4164 	                        hldev->regh0,
4165 	                        &bar0->adapter_control);
4166 	                break;    /* out of for loop */
4167 	            } else {
4168 	                   return
4169 	                   XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4170 	            }
4171 	        }
4172 	    } else {
4173 	        j = 0;  /* Reset the count */
4174 	        /* Turn on the Laser */
4175 	        val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4176 	                        &bar0->adapter_control);
4177 	        val64 = val64 | XGE_HAL_ADAPTER_EOI_TX_ON;
4178 	        xge_os_pio_mem_write64 (hldev->pdev, hldev->regh0,
4179 	                    val64, &bar0->adapter_control);
4180 
4181 	        xge_os_mdelay(1);
4182 
4183 	        /* Now re-enable it as due to noise, hardware
4184 	         * turned it off */
4185 	        val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4186 	                                    &bar0->adapter_control);
4187 	        val64 |= XGE_HAL_ADAPTER_CNTL_EN;
4188 	        val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN);/*ECC enable*/
4189 	        xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4190 	                            &bar0->adapter_control);
4191 	    }
4192 	    xge_os_mdelay(1); /* Sleep for 1 msec */
4193 	    i++;
4194 	} while (i < hldev->config.link_retry_cnt);
4195 
4196 	__hal_device_led_actifity_fix(hldev);
4197 
4198 #ifndef  XGE_HAL_PROCESS_LINK_INT_IN_ISR
4199 	/* Here we are performing soft reset on XGXS to force link down.
4200 	 * Since link is already up, we will get link state change
4201 	 * poll notificatoin after adapter is enabled */
4202 
4203 	__hal_serial_mem_write64(hldev, 0x80010515001E0000ULL,
4204 	             &bar0->dtx_control);
4205 	(void) __hal_serial_mem_read64(hldev, &bar0->dtx_control);
4206 
4207 	__hal_serial_mem_write64(hldev, 0x80010515001E00E0ULL,
4208 	             &bar0->dtx_control);
4209 	(void) __hal_serial_mem_read64(hldev, &bar0->dtx_control);
4210 
4211 	__hal_serial_mem_write64(hldev, 0x80070515001F00E4ULL,
4212 	             &bar0->dtx_control);
4213 	(void) __hal_serial_mem_read64(hldev, &bar0->dtx_control);
4214 
4215 	xge_os_mdelay(100); /* Sleep for 500 msec */
4216 #else
4217 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
4218 #endif
4219 	{
4220 	    /*
4221 	     * With some switches the link state change interrupt does not
4222 	     * occur even though the xgxs reset is done as per SPN-006. So,
4223 	     * poll the adapter status register and check if the link state
4224 	     * is ok.
4225 	     */
4226 	    adp_status = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4227 	                       &bar0->adapter_status);
4228 	    if (!(adp_status & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
4229 	          XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
4230 	    {
4231 	        xge_debug_device(XGE_TRACE, "%s",
4232 	             "enable device causing link state change ind..");
4233 	        (void) __hal_device_handle_link_state_change(hldev);
4234 	    }
4235 	}
4236 
4237 	if (hldev->config.stats_refresh_time_sec !=
4238 	    XGE_HAL_STATS_REFRESH_DISABLE)
4239 	        __hal_stats_enable(&hldev->stats);
4240 
4241 	return XGE_HAL_OK;
4242 }
4243 
4244 /**
4245  * xge_hal_device_disable - Disable Xframe adapter.
4246  * @hldev: Device handle.
4247  *
4248  * Disable this device. To gracefully reset the adapter, the host should:
4249  *
4250  *  - call xge_hal_device_disable();
4251  *
4252  *  - call xge_hal_device_intr_disable();
4253  *
4254  *  - close all opened channels and clean up outstanding resources;
4255  *
4256  *  - do some work (error recovery, change mtu, reset, etc);
4257  *
4258  *  - call xge_hal_device_enable();
4259  *
4260  *  - open channels, replenish RxDs, etc.
4261  *
4262  *  - call xge_hal_device_intr_enable().
4263  *
4264  * Note: Disabling the device does _not_ include disabling of interrupts.
4265  * After disabling the device stops receiving new frames but those frames
4266  * that were already in the pipe will keep coming for some few milliseconds.
4267  *
4268  * Returns:  XGE_HAL_OK - success.
4269  * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
4270  * a "quiescent" state.
4271  *
4272  * See also: xge_hal_status_e{}.
4273  */
4274 xge_hal_status_e
xge_hal_device_disable(xge_hal_device_t * hldev)4275 xge_hal_device_disable(xge_hal_device_t *hldev)
4276 {
4277 	xge_hal_status_e status = XGE_HAL_OK;
4278 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4279 	u64 val64;
4280 
4281 	xge_debug_device(XGE_TRACE, "%s", "turn off laser, cleanup hardware");
4282 
4283 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4284 	                            &bar0->adapter_control);
4285 	val64 = val64 & (~XGE_HAL_ADAPTER_CNTL_EN);
4286 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4287 	                     &bar0->adapter_control);
4288 
4289 	if (__hal_device_wait_quiescent(hldev, &val64) != XGE_HAL_OK) {
4290 	    status = XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4291 	}
4292 
4293 	if (__hal_device_register_poll(hldev, &bar0->adapter_status, 1,
4294 	     XGE_HAL_ADAPTER_STATUS_RC_PRC_QUIESCENT,
4295 	     XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4296 	    xge_debug_device(XGE_TRACE, "%s", "PRC is not QUIESCENT!");
4297 	    status = XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
4298 	}
4299 
4300 	if (hldev->config.stats_refresh_time_sec !=
4301 	    XGE_HAL_STATS_REFRESH_DISABLE)
4302 	            __hal_stats_disable(&hldev->stats);
4303 #ifdef XGE_DEBUG_ASSERT
4304 	    else
4305 	        xge_assert(!hldev->stats.is_enabled);
4306 #endif
4307 
4308 #ifndef XGE_HAL_DONT_DISABLE_BUS_MASTER_ON_STOP
4309 	__hal_device_bus_master_disable(hldev);
4310 #endif
4311 
4312 	return status;
4313 }
4314 
4315 /**
4316  * xge_hal_device_reset - Reset device.
4317  * @hldev: HAL device handle.
4318  *
4319  * Soft-reset the device, reset the device stats except reset_cnt.
4320  *
4321  * After reset is done, will try to re-initialize HW.
4322  *
4323  * Returns:  XGE_HAL_OK - success.
4324  * XGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
4325  * XGE_HAL_ERR_RESET_FAILED - Reset failed.
4326  *
4327  * See also: xge_hal_status_e{}.
4328  */
4329 xge_hal_status_e
xge_hal_device_reset(xge_hal_device_t * hldev)4330 xge_hal_device_reset(xge_hal_device_t *hldev)
4331 {
4332 	xge_hal_status_e status;
4333 
4334 	/* increment the soft reset counter */
4335 	u32 reset_cnt = hldev->stats.sw_dev_info_stats.soft_reset_cnt;
4336 
4337 	xge_debug_device(XGE_TRACE, "%s (%d)", "resetting the device", reset_cnt);
4338 
4339 	if (!hldev->is_initialized)
4340 	    return XGE_HAL_ERR_DEVICE_NOT_INITIALIZED;
4341 
4342 	/* actual "soft" reset of the adapter */
4343 	status = __hal_device_reset(hldev);
4344 
4345 	/* reset all stats including saved */
4346 	__hal_stats_soft_reset(hldev, 1);
4347 
4348 	/* increment reset counter */
4349 	hldev->stats.sw_dev_info_stats.soft_reset_cnt = reset_cnt + 1;
4350 
4351 	/* re-initialize rxufca_intr_thres */
4352 	hldev->rxufca_intr_thres = hldev->config.rxufca_intr_thres;
4353 
4354 	    hldev->reset_needed_after_close = 0;
4355 
4356 	return status;
4357 }
4358 
4359 /**
4360  * xge_hal_device_status - Check whether Xframe hardware is ready for
4361  * operation.
4362  * @hldev: HAL device handle.
4363  * @hw_status: Xframe status register. Returned by HAL.
4364  *
4365  * Check whether Xframe hardware is ready for operation.
4366  * The checking includes TDMA, RDMA, PFC, PIC, MC_DRAM, and the rest
4367  * hardware functional blocks.
4368  *
4369  * Returns: XGE_HAL_OK if the device is ready for operation. Otherwise
4370  * returns XGE_HAL_FAIL. Also, fills in  adapter status (in @hw_status).
4371  *
4372  * See also: xge_hal_status_e{}.
4373  * Usage: See ex_open{}.
4374  */
4375 xge_hal_status_e
xge_hal_device_status(xge_hal_device_t * hldev,u64 * hw_status)4376 xge_hal_device_status(xge_hal_device_t *hldev, u64 *hw_status)
4377 {
4378 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4379 	u64 tmp64;
4380 
4381 	tmp64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4382 	                            &bar0->adapter_status);
4383 
4384 	*hw_status = tmp64;
4385 
4386 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TDMA_READY)) {
4387 	    xge_debug_device(XGE_TRACE, "%s", "TDMA is not ready!");
4388 	    return XGE_HAL_FAIL;
4389 	}
4390 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_RDMA_READY)) {
4391 	    xge_debug_device(XGE_TRACE, "%s", "RDMA is not ready!");
4392 	    return XGE_HAL_FAIL;
4393 	}
4394 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PFC_READY)) {
4395 	    xge_debug_device(XGE_TRACE, "%s", "PFC is not ready!");
4396 	    return XGE_HAL_FAIL;
4397 	}
4398 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY)) {
4399 	    xge_debug_device(XGE_TRACE, "%s", "TMAC BUF is not empty!");
4400 	    return XGE_HAL_FAIL;
4401 	}
4402 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT)) {
4403 	    xge_debug_device(XGE_TRACE, "%s", "PIC is not QUIESCENT!");
4404 	    return XGE_HAL_FAIL;
4405 	}
4406 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY)) {
4407 	    xge_debug_device(XGE_TRACE, "%s", "MC_DRAM is not ready!");
4408 	    return XGE_HAL_FAIL;
4409 	}
4410 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY)) {
4411 	    xge_debug_device(XGE_TRACE, "%s", "MC_QUEUES is not ready!");
4412 	    return XGE_HAL_FAIL;
4413 	}
4414 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK)) {
4415 	    xge_debug_device(XGE_TRACE, "%s", "M_PLL is not locked!");
4416 	    return XGE_HAL_FAIL;
4417 	}
4418 #ifndef XGE_HAL_HERC_EMULATION
4419 	/*
4420 	 * Andrew: in PCI 33 mode, the P_PLL is not used, and therefore,
4421 	 * the P_PLL_LOCK bit in the adapter_status register will
4422 	 * not be asserted.
4423 	 */
4424 	if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_P_PLL_LOCK) &&
4425 	     xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC &&
4426 	     hldev->pci_mode != XGE_HAL_PCI_33MHZ_MODE) {
4427 	    xge_debug_device(XGE_TRACE, "%s", "P_PLL is not locked!");
4428 	    return XGE_HAL_FAIL;
4429 	}
4430 #endif
4431 
4432 	return XGE_HAL_OK;
4433 }
4434 
4435 void
__hal_device_msi_intr_endis(xge_hal_device_t * hldev,int flag)4436 __hal_device_msi_intr_endis(xge_hal_device_t *hldev, int flag)
4437 {
4438 	u16 msi_control_reg;
4439 
4440 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
4441 	     xge_offsetof(xge_hal_pci_config_le_t,
4442 	          msi_control), &msi_control_reg);
4443 
4444 	if (flag)
4445 	    msi_control_reg |= 0x1;
4446 	else
4447 	    msi_control_reg &= ~0x1;
4448 
4449 	xge_os_pci_write16(hldev->pdev, hldev->cfgh,
4450 	     xge_offsetof(xge_hal_pci_config_le_t,
4451 	             msi_control), msi_control_reg);
4452 }
4453 
4454 void
__hal_device_msix_intr_endis(xge_hal_device_t * hldev,xge_hal_channel_t * channel,int flag)4455 __hal_device_msix_intr_endis(xge_hal_device_t *hldev,
4456 	              xge_hal_channel_t *channel, int flag)
4457 {
4458 	u64 val64;
4459 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
4460 
4461 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4462 	    &bar0->xmsi_mask_reg);
4463 
4464 	if (flag)
4465 	    val64 &= ~(1LL << ( 63 - channel->msix_idx ));
4466 	else
4467 	    val64 |= (1LL << ( 63 - channel->msix_idx ));
4468 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4469 	    &bar0->xmsi_mask_reg);
4470 }
4471 
4472 /**
4473  * xge_hal_device_intr_enable - Enable Xframe interrupts.
4474  * @hldev: HAL device handle.
4475  * @op: One of the xge_hal_device_intr_e enumerated values specifying
4476  *      the type(s) of interrupts to enable.
4477  *
4478  * Enable Xframe interrupts. The function is to be executed the last in
4479  * Xframe initialization sequence.
4480  *
4481  * See also: xge_hal_device_intr_disable()
4482  */
4483 void
xge_hal_device_intr_enable(xge_hal_device_t * hldev)4484 xge_hal_device_intr_enable(xge_hal_device_t *hldev)
4485 {
4486 	xge_list_t *item;
4487 	u64 val64;
4488 
4489 	/* PRC initialization and configuration */
4490 	xge_list_for_each(item, &hldev->ring_channels) {
4491 	    xge_hal_channel_h channel;
4492 	    channel = xge_container_of(item, xge_hal_channel_t, item);
4493 	    __hal_ring_prc_enable(channel);
4494 	}
4495 
4496 	/* enable traffic only interrupts */
4497 	if (hldev->config.intr_mode != XGE_HAL_INTR_MODE_IRQLINE) {
4498 	    /*
4499 	     * make sure all interrupts going to be disabled if MSI
4500 	     * is enabled.
4501 	     */
4502 	    __hal_device_intr_mgmt(hldev, XGE_HAL_ALL_INTRS, 0);
4503 	} else {
4504 	    /*
4505 	     * Enable the Tx traffic interrupts only if the TTI feature is
4506 	     * enabled.
4507 	     */
4508 	    val64 = 0;
4509 	    if (hldev->tti_enabled)
4510 	        val64 = XGE_HAL_TX_TRAFFIC_INTR;
4511 
4512 	    if (!hldev->config.bimodal_interrupts)
4513 	        val64 |= XGE_HAL_RX_TRAFFIC_INTR;
4514 
4515 	    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
4516 	        val64 |= XGE_HAL_RX_TRAFFIC_INTR;
4517 
4518 	    val64 |=XGE_HAL_TX_PIC_INTR |
4519 	        XGE_HAL_MC_INTR |
4520 	        XGE_HAL_TX_DMA_INTR |
4521 	        (hldev->config.sched_timer_us !=
4522 	         XGE_HAL_SCHED_TIMER_DISABLED ? XGE_HAL_SCHED_INTR : 0);
4523 	    __hal_device_intr_mgmt(hldev, val64, 1);
4524 	}
4525 
4526 	/*
4527 	 * Enable MSI-X interrupts
4528 	 */
4529 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
4530 
4531 	    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
4532 	        /*
4533 	         * To enable MSI-X, MSI also needs to be enabled,
4534 	         * due to a bug in the herc NIC.
4535 	         */
4536 	        __hal_device_msi_intr_endis(hldev, 1);
4537 	    }
4538 
4539 
4540 	    /* Enable the MSI-X interrupt for each configured channel */
4541 	    xge_list_for_each(item, &hldev->fifo_channels) {
4542 	        xge_hal_channel_t *channel;
4543 
4544 	        channel = xge_container_of(item,
4545 	                   xge_hal_channel_t, item);
4546 
4547 	        /* 0 vector is reserved for alarms */
4548 	        if (!channel->msix_idx)
4549 	            continue;
4550 
4551 	        __hal_device_msix_intr_endis(hldev, channel, 1);
4552 	    }
4553 
4554 	    xge_list_for_each(item, &hldev->ring_channels) {
4555 	        xge_hal_channel_t *channel;
4556 
4557 	        channel = xge_container_of(item,
4558 	                   xge_hal_channel_t, item);
4559 
4560 	        /* 0 vector is reserved for alarms */
4561 	        if (!channel->msix_idx)
4562 	            continue;
4563 
4564 	        __hal_device_msix_intr_endis(hldev, channel, 1);
4565 	    }
4566 	}
4567 
4568 	xge_debug_device(XGE_TRACE, "%s", "interrupts are enabled");
4569 }
4570 
4571 
4572 /**
4573  * xge_hal_device_intr_disable - Disable Xframe interrupts.
4574  * @hldev: HAL device handle.
4575  * @op: One of the xge_hal_device_intr_e enumerated values specifying
4576  *      the type(s) of interrupts to disable.
4577  *
4578  * Disable Xframe interrupts.
4579  *
4580  * See also: xge_hal_device_intr_enable()
4581  */
4582 void
xge_hal_device_intr_disable(xge_hal_device_t * hldev)4583 xge_hal_device_intr_disable(xge_hal_device_t *hldev)
4584 {
4585 	xge_list_t *item;
4586 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4587 	u64 val64;
4588 
4589 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
4590 
4591 	    if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
4592 	        /*
4593 	         * To disable MSI-X, MSI also needs to be disabled,
4594 	         * due to a bug in the herc NIC.
4595 	         */
4596 	        __hal_device_msi_intr_endis(hldev, 0);
4597 	    }
4598 
4599 	    /* Disable the MSI-X interrupt for each configured channel */
4600 	    xge_list_for_each(item, &hldev->fifo_channels) {
4601 	        xge_hal_channel_t *channel;
4602 
4603 	        channel = xge_container_of(item,
4604 	                   xge_hal_channel_t, item);
4605 
4606 	        /* 0 vector is reserved for alarms */
4607 	        if (!channel->msix_idx)
4608 	            continue;
4609 
4610 	        __hal_device_msix_intr_endis(hldev, channel, 0);
4611 
4612 	    }
4613 
4614 	    xge_os_pio_mem_write64(hldev->pdev,
4615 	        hldev->regh0, 0xFFFFFFFFFFFFFFFFULL,
4616 	        &bar0->tx_traffic_mask);
4617 
4618 	    xge_list_for_each(item, &hldev->ring_channels) {
4619 	        xge_hal_channel_t *channel;
4620 
4621 	        channel = xge_container_of(item,
4622 	                   xge_hal_channel_t, item);
4623 
4624 	        /* 0 vector is reserved for alarms */
4625 	        if (!channel->msix_idx)
4626 	            continue;
4627 
4628 	        __hal_device_msix_intr_endis(hldev, channel, 0);
4629 	    }
4630 
4631 	    xge_os_pio_mem_write64(hldev->pdev,
4632 	        hldev->regh0, 0xFFFFFFFFFFFFFFFFULL,
4633 	        &bar0->rx_traffic_mask);
4634 	}
4635 
4636 	/*
4637 	 * Disable traffic only interrupts.
4638 	 * Tx traffic interrupts are used only if the TTI feature is
4639 	 * enabled.
4640 	 */
4641 	val64 = 0;
4642 	if (hldev->tti_enabled)
4643 	    val64 = XGE_HAL_TX_TRAFFIC_INTR;
4644 
4645 	val64 |= XGE_HAL_RX_TRAFFIC_INTR |
4646 	     XGE_HAL_TX_PIC_INTR |
4647 	     XGE_HAL_MC_INTR |
4648 	     (hldev->config.sched_timer_us != XGE_HAL_SCHED_TIMER_DISABLED ?
4649 	                    XGE_HAL_SCHED_INTR : 0);
4650 	__hal_device_intr_mgmt(hldev, val64, 0);
4651 
4652 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4653 	                     0xFFFFFFFFFFFFFFFFULL,
4654 	             &bar0->general_int_mask);
4655 
4656 
4657 	/* disable all configured PRCs */
4658 	xge_list_for_each(item, &hldev->ring_channels) {
4659 	    xge_hal_channel_h channel;
4660 	    channel = xge_container_of(item, xge_hal_channel_t, item);
4661 	    __hal_ring_prc_disable(channel);
4662 	}
4663 
4664 	xge_debug_device(XGE_TRACE, "%s", "interrupts are disabled");
4665 }
4666 
4667 
4668 /**
4669  * xge_hal_device_mcast_enable - Enable Xframe multicast addresses.
4670  * @hldev: HAL device handle.
4671  *
4672  * Enable Xframe multicast addresses.
4673  * Returns: XGE_HAL_OK on success.
4674  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to enable mcast
4675  * feature within the time(timeout).
4676  *
4677  * See also: xge_hal_device_mcast_disable(), xge_hal_status_e{}.
4678  */
4679 xge_hal_status_e
xge_hal_device_mcast_enable(xge_hal_device_t * hldev)4680 xge_hal_device_mcast_enable(xge_hal_device_t *hldev)
4681 {
4682 	u64 val64;
4683 	xge_hal_pci_bar0_t *bar0;
4684 	int mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET;
4685 
4686 	if (hldev == NULL)
4687 	    return XGE_HAL_ERR_INVALID_DEVICE;
4688 
4689 	if (hldev->mcast_refcnt)
4690 	    return XGE_HAL_OK;
4691 
4692 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
4693 	    mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET_HERC;
4694 
4695 	hldev->mcast_refcnt = 1;
4696 
4697 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4698 
4699 	/*  Enable all Multicast addresses */
4700 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4701 	      XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0x010203040506ULL),
4702 	      &bar0->rmac_addr_data0_mem);
4703 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4704 	      XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0xfeffffffffffULL),
4705 	      &bar0->rmac_addr_data1_mem);
4706 	val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
4707 	    XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4708 	    XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET(mc_offset);
4709 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4710 	                &bar0->rmac_addr_cmd_mem);
4711 
4712 	if (__hal_device_register_poll(hldev,
4713 	    &bar0->rmac_addr_cmd_mem, 0,
4714 	    XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4715 	    XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4716 	    /* upper layer may require to repeat */
4717 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
4718 	}
4719 
4720 	return XGE_HAL_OK;
4721 }
4722 
4723 /**
4724  * xge_hal_device_mcast_disable - Disable Xframe multicast addresses.
4725  * @hldev: HAL device handle.
4726  *
4727  * Disable Xframe multicast addresses.
4728  * Returns: XGE_HAL_OK - success.
4729  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to disable mcast
4730  * feature within the time(timeout).
4731  *
4732  * See also: xge_hal_device_mcast_enable(), xge_hal_status_e{}.
4733  */
4734 xge_hal_status_e
xge_hal_device_mcast_disable(xge_hal_device_t * hldev)4735 xge_hal_device_mcast_disable(xge_hal_device_t *hldev)
4736 {
4737 	u64 val64;
4738 	xge_hal_pci_bar0_t *bar0;
4739 	int mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET;
4740 
4741 	if (hldev == NULL)
4742 	    return XGE_HAL_ERR_INVALID_DEVICE;
4743 
4744 	if (hldev->mcast_refcnt == 0)
4745 	    return XGE_HAL_OK;
4746 
4747 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
4748 	    mc_offset = XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET_HERC;
4749 
4750 	hldev->mcast_refcnt = 0;
4751 
4752 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4753 
4754 	/*  Disable all Multicast addresses */
4755 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4756 	       XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0xffffffffffffULL),
4757 	           &bar0->rmac_addr_data0_mem);
4758 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4759 	       XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0),
4760 	           &bar0->rmac_addr_data1_mem);
4761 
4762 	val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
4763 	    XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4764 	    XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET(mc_offset);
4765 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4766 	                &bar0->rmac_addr_cmd_mem);
4767 
4768 	if (__hal_device_register_poll(hldev,
4769 	    &bar0->rmac_addr_cmd_mem, 0,
4770 	    XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4771 	    XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4772 	    /* upper layer may require to repeat */
4773 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
4774 	}
4775 
4776 	return XGE_HAL_OK;
4777 }
4778 
4779 /**
4780  * xge_hal_device_promisc_enable - Enable promiscuous mode.
4781  * @hldev: HAL device handle.
4782  *
4783  * Enable promiscuous mode of Xframe operation.
4784  *
4785  * See also: xge_hal_device_promisc_disable().
4786  */
4787 void
xge_hal_device_promisc_enable(xge_hal_device_t * hldev)4788 xge_hal_device_promisc_enable(xge_hal_device_t *hldev)
4789 {
4790 	u64 val64;
4791 	xge_hal_pci_bar0_t *bar0;
4792 
4793 	xge_assert(hldev);
4794 
4795 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4796 
4797 	if (!hldev->is_promisc) {
4798 	    /*  Put the NIC into promiscuous mode */
4799 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4800 	                                &bar0->mac_cfg);
4801 	    val64 |= XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE;
4802 
4803 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4804 	               XGE_HAL_RMAC_CFG_KEY(0x4C0D),
4805 	               &bar0->rmac_cfg_key);
4806 
4807 	    __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
4808 	                  (u32)(val64 >> 32),
4809 	                  &bar0->mac_cfg);
4810 
4811 	    hldev->is_promisc = 1;
4812 	    xge_debug_device(XGE_TRACE,
4813 	        "mac_cfg 0x"XGE_OS_LLXFMT": promisc enabled",
4814 	        (unsigned long long)val64);
4815 	}
4816 }
4817 
4818 /**
4819  * xge_hal_device_promisc_disable - Disable promiscuous mode.
4820  * @hldev: HAL device handle.
4821  *
4822  * Disable promiscuous mode of Xframe operation.
4823  *
4824  * See also: xge_hal_device_promisc_enable().
4825  */
4826 void
xge_hal_device_promisc_disable(xge_hal_device_t * hldev)4827 xge_hal_device_promisc_disable(xge_hal_device_t *hldev)
4828 {
4829 	u64 val64;
4830 	xge_hal_pci_bar0_t *bar0;
4831 
4832 	xge_assert(hldev);
4833 
4834 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4835 
4836 	if (hldev->is_promisc) {
4837 	    /*  Remove the NIC from promiscuous mode */
4838 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4839 	                    &bar0->mac_cfg);
4840 	    val64 &= ~XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE;
4841 
4842 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4843 	               XGE_HAL_RMAC_CFG_KEY(0x4C0D),
4844 	               &bar0->rmac_cfg_key);
4845 
4846 	    __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
4847 	                  (u32)(val64 >> 32),
4848 	                  &bar0->mac_cfg);
4849 
4850 	    hldev->is_promisc = 0;
4851 	    xge_debug_device(XGE_TRACE,
4852 	        "mac_cfg 0x"XGE_OS_LLXFMT": promisc disabled",
4853 	        (unsigned long long)val64);
4854 	}
4855 }
4856 
4857 /**
4858  * xge_hal_device_macaddr_get - Get MAC addresses.
4859  * @hldev: HAL device handle.
4860  * @index: MAC address index, in the range from 0 to
4861  * XGE_HAL_MAX_MAC_ADDRESSES.
4862  * @macaddr: MAC address. Returned by HAL.
4863  *
4864  * Retrieve one of the stored MAC addresses by reading non-volatile
4865  * memory on the chip.
4866  *
4867  * Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
4868  *
4869  * Returns: XGE_HAL_OK - success.
4870  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
4871  * address within the time(timeout).
4872  * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
4873  *
4874  * See also: xge_hal_device_macaddr_set(), xge_hal_status_e{}.
4875  */
4876 xge_hal_status_e
xge_hal_device_macaddr_get(xge_hal_device_t * hldev,int index,macaddr_t * macaddr)4877 xge_hal_device_macaddr_get(xge_hal_device_t *hldev, int index,
4878 	        macaddr_t *macaddr)
4879 {
4880 	xge_hal_pci_bar0_t *bar0;
4881 	u64 val64;
4882 	int i;
4883 
4884 	if (hldev == NULL) {
4885 	    return XGE_HAL_ERR_INVALID_DEVICE;
4886 	}
4887 
4888 	bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4889 
4890 	if ( index >= XGE_HAL_MAX_MAC_ADDRESSES ) {
4891 	    return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
4892 	}
4893 
4894 #ifdef XGE_HAL_HERC_EMULATION
4895 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,0x0000010000000000,
4896 	                            &bar0->rmac_addr_data0_mem);
4897 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,0x0000000000000000,
4898 	                            &bar0->rmac_addr_data1_mem);
4899 	val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_RD |
4900 	             XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4901 	             XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index));
4902 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4903 	                     &bar0->rmac_addr_cmd_mem);
4904 
4905 	    /* poll until done */
4906 	__hal_device_register_poll(hldev,
4907 	           &bar0->rmac_addr_cmd_mem, 0,
4908 	           XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD,
4909 	           XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS);
4910 
4911 #endif
4912 
4913 	val64 = ( XGE_HAL_RMAC_ADDR_CMD_MEM_RD |
4914 	      XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4915 	      XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index)) );
4916 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4917 	                     &bar0->rmac_addr_cmd_mem);
4918 
4919 	if (__hal_device_register_poll(hldev, &bar0->rmac_addr_cmd_mem, 0,
4920 	       XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4921 	       XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4922 	    /* upper layer may require to repeat */
4923 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
4924 	}
4925 
4926 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
4927 	                            &bar0->rmac_addr_data0_mem);
4928 	for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
4929 	    (*macaddr)[i] = (u8)(val64 >> ((64 - 8) - (i * 8)));
4930 	}
4931 
4932 #ifdef XGE_HAL_HERC_EMULATION
4933 	for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
4934 	    (*macaddr)[i] = (u8)0;
4935 	}
4936 	(*macaddr)[1] = (u8)1;
4937 
4938 #endif
4939 
4940 	return XGE_HAL_OK;
4941 }
4942 
4943 /**
4944  * xge_hal_device_macaddr_set - Set MAC address.
4945  * @hldev: HAL device handle.
4946  * @index: MAC address index, in the range from 0 to
4947  * XGE_HAL_MAX_MAC_ADDRESSES.
4948  * @macaddr: New MAC address to configure.
4949  *
4950  * Configure one of the available MAC address "slots".
4951  *
4952  * Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
4953  *
4954  * Returns: XGE_HAL_OK - success.
4955  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to set the new mac
4956  * address within the time(timeout).
4957  * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
4958  *
4959  * See also: xge_hal_device_macaddr_get(), xge_hal_status_e{}.
4960  */
4961 xge_hal_status_e
xge_hal_device_macaddr_set(xge_hal_device_t * hldev,int index,macaddr_t macaddr)4962 xge_hal_device_macaddr_set(xge_hal_device_t *hldev, int index,
4963 	        macaddr_t macaddr)
4964 {
4965 	xge_hal_pci_bar0_t *bar0 =
4966 	    (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
4967 	u64 val64, temp64;
4968 	int i;
4969 
4970 	if ( index >= XGE_HAL_MAX_MAC_ADDRESSES )
4971 	    return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
4972 
4973 	temp64 = 0;
4974 	for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
4975 	    temp64 |= macaddr[i];
4976 	    temp64 <<= 8;
4977 	}
4978 	temp64 >>= 8;
4979 
4980 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4981 	                XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(temp64),
4982 	            &bar0->rmac_addr_data0_mem);
4983 
4984 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
4985 	                XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0ULL),
4986 	            &bar0->rmac_addr_data1_mem);
4987 
4988 	val64 = ( XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
4989 	      XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
4990 	      XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index)) );
4991 
4992 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
4993 	                     &bar0->rmac_addr_cmd_mem);
4994 
4995 	if (__hal_device_register_poll(hldev, &bar0->rmac_addr_cmd_mem, 0,
4996 	       XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
4997 	       XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
4998 	    /* upper layer may require to repeat */
4999 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
5000 	}
5001 
5002 	return XGE_HAL_OK;
5003 }
5004 
5005 /**
5006  * xge_hal_device_macaddr_clear - Set MAC address.
5007  * @hldev: HAL device handle.
5008  * @index: MAC address index, in the range from 0 to
5009  * XGE_HAL_MAX_MAC_ADDRESSES.
5010  *
5011  * Clear one of the available MAC address "slots".
5012  *
5013  * Returns: XGE_HAL_OK - success.
5014  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to set the new mac
5015  * address within the time(timeout).
5016  * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
5017  *
5018  * See also: xge_hal_device_macaddr_set(), xge_hal_status_e{}.
5019  */
5020 xge_hal_status_e
xge_hal_device_macaddr_clear(xge_hal_device_t * hldev,int index)5021 xge_hal_device_macaddr_clear(xge_hal_device_t *hldev, int index)
5022 {
5023 	xge_hal_status_e status;
5024 	u8 macaddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
5025 
5026 	status = xge_hal_device_macaddr_set(hldev, index, macaddr);
5027 	if (status != XGE_HAL_OK) {
5028 	    xge_debug_device(XGE_ERR, "%s",
5029 	        "Not able to set the mac addr");
5030 	    return status;
5031 	}
5032 
5033 	return XGE_HAL_OK;
5034 }
5035 
5036 /**
5037  * xge_hal_device_macaddr_find - Finds index in the rmac table.
5038  * @hldev: HAL device handle.
5039  * @wanted: Wanted MAC address.
5040  *
5041  * See also: xge_hal_device_macaddr_set().
5042  */
5043 int
xge_hal_device_macaddr_find(xge_hal_device_t * hldev,macaddr_t wanted)5044 xge_hal_device_macaddr_find(xge_hal_device_t *hldev, macaddr_t wanted)
5045 {
5046 	int i;
5047 
5048 	if (hldev == NULL) {
5049 	    return XGE_HAL_ERR_INVALID_DEVICE;
5050 	}
5051 
5052 	for (i=1; i<XGE_HAL_MAX_MAC_ADDRESSES; i++) {
5053 	    macaddr_t macaddr;
5054 	    (void) xge_hal_device_macaddr_get(hldev, i, &macaddr);
5055 	    if (!xge_os_memcmp(macaddr, wanted, sizeof(macaddr_t))) {
5056 	        return i;
5057 	    }
5058 	}
5059 
5060 	return -1;
5061 }
5062 
5063 /**
5064  * xge_hal_device_mtu_set - Set MTU.
5065  * @hldev: HAL device handle.
5066  * @new_mtu: New MTU size to configure.
5067  *
5068  * Set new MTU value. Example, to use jumbo frames:
5069  * xge_hal_device_mtu_set(my_device, my_channel, 9600);
5070  *
5071  * Returns: XGE_HAL_OK on success.
5072  * XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control
5073  * register.
5074  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to initialize TTI/RTI
5075  * schemes.
5076  * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
5077  * a "quiescent" state.
5078  */
5079 xge_hal_status_e
xge_hal_device_mtu_set(xge_hal_device_t * hldev,int new_mtu)5080 xge_hal_device_mtu_set(xge_hal_device_t *hldev, int new_mtu)
5081 {
5082 	xge_hal_status_e status;
5083 
5084 	/*
5085 	 * reset needed if 1) new MTU differs, and
5086 	 * 2a) device was closed or
5087 	 * 2b) device is being upped for first time.
5088 	 */
5089 	if (hldev->config.mtu != new_mtu) {
5090 	    if (hldev->reset_needed_after_close ||
5091 	        !hldev->mtu_first_time_set) {
5092 	        status = xge_hal_device_reset(hldev);
5093 	        if (status != XGE_HAL_OK) {
5094 	            xge_debug_device(XGE_TRACE, "%s",
5095 	                  "fatal: can not reset the device");
5096 	            return status;
5097 	        }
5098 	    }
5099 	    /* store the new MTU in device, reset will use it */
5100 	    hldev->config.mtu = new_mtu;
5101 	    xge_debug_device(XGE_TRACE, "new MTU %d applied",
5102 	             new_mtu);
5103 	}
5104 
5105 	if (!hldev->mtu_first_time_set)
5106 	    hldev->mtu_first_time_set = 1;
5107 
5108 	return XGE_HAL_OK;
5109 }
5110 
5111 /**
5112  * xge_hal_device_initialize - Initialize Xframe device.
5113  * @hldev: HAL device handle.
5114  * @attr: pointer to xge_hal_device_attr_t structure
5115  * @device_config: Configuration to be _applied_ to the device,
5116  *                 For the Xframe configuration "knobs" please
5117  *                 refer to xge_hal_device_config_t and Xframe
5118  *                 User Guide.
5119  *
5120  * Initialize Xframe device. Note that all the arguments of this public API
5121  * are 'IN', including @hldev. Upper-layer driver (ULD) cooperates with
5122  * OS to find new Xframe device, locate its PCI and memory spaces.
5123  *
5124  * When done, the ULD allocates sizeof(xge_hal_device_t) bytes for HAL
5125  * to enable the latter to perform Xframe hardware initialization.
5126  *
5127  * Returns: XGE_HAL_OK - success.
5128  * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - Driver is not initialized.
5129  * XGE_HAL_ERR_BAD_DEVICE_CONFIG - Device configuration params are not
5130  * valid.
5131  * XGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed.
5132  * XGE_HAL_ERR_BAD_SUBSYSTEM_ID - Device subsystem id is invalid.
5133  * XGE_HAL_ERR_INVALID_MAC_ADDRESS - Device mac address in not valid.
5134  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
5135  * address within the time(timeout) or TTI/RTI initialization failed.
5136  * XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control.
5137  * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT -Device is not queiscent.
5138  *
5139  * See also: xge_hal_device_terminate(), xge_hal_status_e{}
5140  * xge_hal_device_attr_t{}.
5141  */
5142 xge_hal_status_e
xge_hal_device_initialize(xge_hal_device_t * hldev,xge_hal_device_attr_t * attr,xge_hal_device_config_t * device_config)5143 xge_hal_device_initialize(xge_hal_device_t *hldev, xge_hal_device_attr_t *attr,
5144 	    xge_hal_device_config_t *device_config)
5145 {
5146 	int i;
5147 	xge_hal_status_e status;
5148 	xge_hal_channel_t *channel;
5149 	u16 subsys_device;
5150 	u16 subsys_vendor;
5151 	int total_dram_size, ring_auto_dram_cfg, left_dram_size;
5152 	int total_dram_size_max = 0;
5153 
5154 	xge_debug_device(XGE_TRACE, "device 0x"XGE_OS_LLXFMT" is initializing",
5155 	         (unsigned long long)(ulong_t)hldev);
5156 
5157 	/* sanity check */
5158 	if (g_xge_hal_driver == NULL ||
5159 	    !g_xge_hal_driver->is_initialized) {
5160 	    return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
5161 	}
5162 
5163 	xge_os_memzero(hldev, sizeof(xge_hal_device_t));
5164 
5165 	/*
5166 	 * validate a common part of Xframe-I/II configuration
5167 	 * (and run check_card() later, once PCI inited - see below)
5168 	 */
5169 	status = __hal_device_config_check_common(device_config);
5170 	if (status != XGE_HAL_OK)
5171 	    return status;
5172 
5173 	/* apply config */
5174 	xge_os_memcpy(&hldev->config, device_config,
5175 	                  sizeof(xge_hal_device_config_t));
5176 
5177 	/* save original attr */
5178 	xge_os_memcpy(&hldev->orig_attr, attr,
5179 	                  sizeof(xge_hal_device_attr_t));
5180 
5181 	/* initialize rxufca_intr_thres */
5182 	hldev->rxufca_intr_thres = hldev->config.rxufca_intr_thres;
5183 
5184 	hldev->regh0 = attr->regh0;
5185 	hldev->regh1 = attr->regh1;
5186 	hldev->regh2 = attr->regh2;
5187 	hldev->isrbar0 = hldev->bar0 = attr->bar0;
5188 	hldev->bar1 = attr->bar1;
5189 	hldev->bar2 = attr->bar2;
5190 	hldev->pdev = attr->pdev;
5191 	hldev->irqh = attr->irqh;
5192 	hldev->cfgh = attr->cfgh;
5193 
5194 	/* set initial bimodal timer for bimodal adaptive schema */
5195 	hldev->bimodal_timer_val_us = hldev->config.bimodal_timer_lo_us;
5196 
5197 	hldev->queueh = xge_queue_create(hldev->pdev, hldev->irqh,
5198 	              g_xge_hal_driver->config.queue_size_initial,
5199 	              g_xge_hal_driver->config.queue_size_max,
5200 	              __hal_device_event_queued, hldev);
5201 	if (hldev->queueh == NULL)
5202 	    return XGE_HAL_ERR_OUT_OF_MEMORY;
5203 
5204 	hldev->magic = XGE_HAL_MAGIC;
5205 
5206 	xge_assert(hldev->regh0);
5207 	xge_assert(hldev->regh1);
5208 	xge_assert(hldev->bar0);
5209 	xge_assert(hldev->bar1);
5210 	xge_assert(hldev->pdev);
5211 	xge_assert(hldev->irqh);
5212 	xge_assert(hldev->cfgh);
5213 
5214 	/* initialize some PCI/PCI-X fields of this PCI device. */
5215 	__hal_device_pci_init(hldev);
5216 
5217 	/*
5218 	 * initlialize lists to properly handling a potential
5219 	 * terminate request
5220 	 */
5221 	xge_list_init(&hldev->free_channels);
5222 	xge_list_init(&hldev->fifo_channels);
5223 	xge_list_init(&hldev->ring_channels);
5224 
5225 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
5226 	    /* fixups for xena */
5227 	    hldev->config.rth_en = 0;
5228 	    hldev->config.rth_spdm_en = 0;
5229 	    hldev->config.rts_mac_en = 0;
5230 	    total_dram_size_max = XGE_HAL_MAX_RING_QUEUE_SIZE_XENA;
5231 
5232 	    status = __hal_device_config_check_xena(device_config);
5233 	    if (status != XGE_HAL_OK) {
5234 	        xge_hal_device_terminate(hldev);
5235 	        return status;
5236 	    }
5237 	    if (hldev->config.bimodal_interrupts == 1) {
5238 	        xge_hal_device_terminate(hldev);
5239 	        return XGE_HAL_BADCFG_BIMODAL_XENA_NOT_ALLOWED;
5240 	    } else if (hldev->config.bimodal_interrupts ==
5241 	        XGE_HAL_DEFAULT_USE_HARDCODE)
5242 	        hldev->config.bimodal_interrupts = 0;
5243 	} else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
5244 	    /* fixups for herc */
5245 	    total_dram_size_max = XGE_HAL_MAX_RING_QUEUE_SIZE_HERC;
5246 	    status = __hal_device_config_check_herc(device_config);
5247 	    if (status != XGE_HAL_OK) {
5248 	        xge_hal_device_terminate(hldev);
5249 	        return status;
5250 	    }
5251 	    if (hldev->config.bimodal_interrupts ==
5252 	        XGE_HAL_DEFAULT_USE_HARDCODE)
5253 	        hldev->config.bimodal_interrupts = 1;
5254 	} else {
5255 	    xge_debug_device(XGE_ERR,
5256 	          "detected unknown device_id 0x%x", hldev->device_id);
5257 	    xge_hal_device_terminate(hldev);
5258 	    return XGE_HAL_ERR_BAD_DEVICE_ID;
5259 	}
5260 
5261 	/* allocate and initialize FIFO types of channels according to
5262 	 * configuration */
5263 	for (i = 0; i < XGE_HAL_MAX_FIFO_NUM; i++) {
5264 	    if (!device_config->fifo.queue[i].configured)
5265 	        continue;
5266 
5267 	    channel = __hal_channel_allocate(hldev, i,
5268 	                     XGE_HAL_CHANNEL_TYPE_FIFO);
5269 	    if (channel == NULL) {
5270 	        xge_debug_device(XGE_ERR,
5271 	            "fifo: __hal_channel_allocate failed");
5272 	        xge_hal_device_terminate(hldev);
5273 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
5274 	    }
5275 	    /* add new channel to the device */
5276 	    xge_list_insert(&channel->item, &hldev->free_channels);
5277 	}
5278 
5279 	/*
5280 	 * automatic DRAM adjustment
5281 	 */
5282 	total_dram_size = 0;
5283 	ring_auto_dram_cfg = 0;
5284 	for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
5285 	    if (!device_config->ring.queue[i].configured)
5286 	        continue;
5287 	    if (device_config->ring.queue[i].dram_size_mb ==
5288 	        XGE_HAL_DEFAULT_USE_HARDCODE) {
5289 	        ring_auto_dram_cfg++;
5290 	        continue;
5291 	    }
5292 	    total_dram_size += device_config->ring.queue[i].dram_size_mb;
5293 	}
5294 	left_dram_size = total_dram_size_max - total_dram_size;
5295 	if (left_dram_size < 0 ||
5296 	    (ring_auto_dram_cfg && left_dram_size / ring_auto_dram_cfg == 0))  {
5297 	    xge_debug_device(XGE_ERR,
5298 	         "ring config: exceeded DRAM size %d MB",
5299 	         total_dram_size_max);
5300 	    xge_hal_device_terminate(hldev);
5301 	            return XGE_HAL_BADCFG_RING_QUEUE_SIZE;
5302 	    }
5303 
5304 	/*
5305 	 * allocate and initialize RING types of channels according to
5306 	 * configuration
5307 	 */
5308 	for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
5309 	    if (!device_config->ring.queue[i].configured)
5310 	        continue;
5311 
5312 	    if (device_config->ring.queue[i].dram_size_mb ==
5313 	        XGE_HAL_DEFAULT_USE_HARDCODE) {
5314 	        hldev->config.ring.queue[i].dram_size_mb =
5315 	            device_config->ring.queue[i].dram_size_mb =
5316 	                left_dram_size / ring_auto_dram_cfg;
5317 	    }
5318 
5319 	    channel = __hal_channel_allocate(hldev, i,
5320 	                     XGE_HAL_CHANNEL_TYPE_RING);
5321 	    if (channel == NULL) {
5322 	        xge_debug_device(XGE_ERR,
5323 	            "ring: __hal_channel_allocate failed");
5324 	        xge_hal_device_terminate(hldev);
5325 	        return XGE_HAL_ERR_OUT_OF_MEMORY;
5326 	    }
5327 	    /* add new channel to the device */
5328 	    xge_list_insert(&channel->item, &hldev->free_channels);
5329 	}
5330 
5331 	/* get subsystem IDs */
5332 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
5333 	    xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
5334 	    &subsys_device);
5335 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
5336 	    xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
5337 	    &subsys_vendor);
5338 	xge_debug_device(XGE_TRACE,
5339 	                     "subsystem_id %04x:%04x",
5340 	                     subsys_vendor, subsys_device);
5341 
5342 	/* reset device initially */
5343 	(void) __hal_device_reset(hldev);
5344 
5345 	/* set host endian before, to assure proper action */
5346 	status = __hal_device_set_swapper(hldev);
5347 	if (status != XGE_HAL_OK) {
5348 	    xge_debug_device(XGE_ERR,
5349 	        "__hal_device_set_swapper failed");
5350 	    xge_hal_device_terminate(hldev);
5351 	    (void) __hal_device_reset(hldev);
5352 	    return status;
5353 	}
5354 
5355 #ifndef XGE_HAL_HERC_EMULATION
5356 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
5357 	    __hal_device_xena_fix_mac(hldev);
5358 #endif
5359 
5360 	/*  MAC address initialization.
5361 	 *  For now only one mac address will be read and used.  */
5362 	status = xge_hal_device_macaddr_get(hldev, 0, &hldev->macaddr[0]);
5363 	if (status != XGE_HAL_OK) {
5364 	    xge_debug_device(XGE_ERR,
5365 	        "xge_hal_device_macaddr_get failed");
5366 	    xge_hal_device_terminate(hldev);
5367 	    return status;
5368 	}
5369 
5370 	if (hldev->macaddr[0][0] == 0xFF &&
5371 	    hldev->macaddr[0][1] == 0xFF &&
5372 	    hldev->macaddr[0][2] == 0xFF &&
5373 	    hldev->macaddr[0][3] == 0xFF &&
5374 	    hldev->macaddr[0][4] == 0xFF &&
5375 	    hldev->macaddr[0][5] == 0xFF) {
5376 	    xge_debug_device(XGE_ERR,
5377 	        "xge_hal_device_macaddr_get returns all FFs");
5378 	    xge_hal_device_terminate(hldev);
5379 	    return XGE_HAL_ERR_INVALID_MAC_ADDRESS;
5380 	}
5381 
5382 	xge_debug_device(XGE_TRACE,
5383 	          "default macaddr: 0x%02x-%02x-%02x-%02x-%02x-%02x",
5384 	          hldev->macaddr[0][0], hldev->macaddr[0][1],
5385 	          hldev->macaddr[0][2], hldev->macaddr[0][3],
5386 	          hldev->macaddr[0][4], hldev->macaddr[0][5]);
5387 
5388 	status = __hal_stats_initialize(&hldev->stats, hldev);
5389 	if (status != XGE_HAL_OK) {
5390 	    xge_debug_device(XGE_ERR,
5391 	        "__hal_stats_initialize failed");
5392 	    xge_hal_device_terminate(hldev);
5393 	    return status;
5394 	}
5395 
5396 	status = __hal_device_hw_initialize(hldev);
5397 	if (status != XGE_HAL_OK) {
5398 	    xge_debug_device(XGE_ERR,
5399 	        "__hal_device_hw_initialize failed");
5400 	    xge_hal_device_terminate(hldev);
5401 	    return status;
5402 	}
5403 	hldev->dump_buf=(char*)xge_os_malloc(hldev->pdev, XGE_HAL_DUMP_BUF_SIZE);
5404 	if (hldev->dump_buf == NULL)  {
5405 	    xge_debug_device(XGE_ERR,
5406 	        "__hal_device_hw_initialize failed");
5407 	    xge_hal_device_terminate(hldev);
5408 	            return XGE_HAL_ERR_OUT_OF_MEMORY;
5409 	}
5410 
5411 
5412 	/* Xena-only: need to serialize fifo posts across all device fifos */
5413 #if defined(XGE_HAL_TX_MULTI_POST)
5414 	xge_os_spin_lock_init(&hldev->xena_post_lock, hldev->pdev);
5415 #elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
5416 	xge_os_spin_lock_init_irq(&hldev->xena_post_lock, hldev->irqh);
5417 #endif
5418 	 /* Getting VPD data */
5419 	    __hal_device_get_vpd_data(hldev);
5420 
5421 	hldev->is_initialized = 1;
5422 
5423 	return XGE_HAL_OK;
5424 }
5425 
5426 /**
5427  * xge_hal_device_terminating - Mark the device as 'terminating'.
5428  * @devh: HAL device handle.
5429  *
5430  * Mark the device as 'terminating', going to terminate. Can be used
5431  * to serialize termination with other running processes/contexts.
5432  *
5433  * See also: xge_hal_device_terminate().
5434  */
5435 void
xge_hal_device_terminating(xge_hal_device_h devh)5436 xge_hal_device_terminating(xge_hal_device_h devh)
5437 {
5438 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
5439 	xge_list_t *item;
5440 	xge_hal_channel_t *channel;
5441 #if defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
5442 	unsigned long flags=0;
5443 #endif
5444 
5445 	/*
5446 	 * go through each opened tx channel and aquire
5447 	 * lock, so it will serialize with HAL termination flag
5448 	 */
5449 	xge_list_for_each(item, &hldev->fifo_channels) {
5450 	    channel = xge_container_of(item, xge_hal_channel_t, item);
5451 #if defined(XGE_HAL_TX_MULTI_RESERVE)
5452 	    xge_os_spin_lock(&channel->reserve_lock);
5453 #elif defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
5454 	    xge_os_spin_lock_irq(&channel->reserve_lock, flags);
5455 #endif
5456 
5457 	    channel->terminating = 1;
5458 
5459 #if defined(XGE_HAL_TX_MULTI_RESERVE)
5460 	    xge_os_spin_unlock(&channel->reserve_lock);
5461 #elif defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
5462 	    xge_os_spin_unlock_irq(&channel->reserve_lock, flags);
5463 #endif
5464 	}
5465 
5466 	hldev->terminating = 1;
5467 }
5468 
5469 /**
5470  * xge_hal_device_terminate - Terminate Xframe device.
5471  * @hldev: HAL device handle.
5472  *
5473  * Terminate HAL device.
5474  *
5475  * See also: xge_hal_device_initialize().
5476  */
5477 void
xge_hal_device_terminate(xge_hal_device_t * hldev)5478 xge_hal_device_terminate(xge_hal_device_t *hldev)
5479 {
5480 	xge_assert(g_xge_hal_driver != NULL);
5481 	xge_assert(hldev != NULL);
5482 	xge_assert(hldev->magic == XGE_HAL_MAGIC);
5483 
5484 	xge_queue_flush(hldev->queueh);
5485 
5486 	hldev->terminating = 1;
5487 	hldev->is_initialized = 0;
5488 	    hldev->in_poll = 0;
5489 	hldev->magic = XGE_HAL_DEAD;
5490 
5491 #if defined(XGE_HAL_TX_MULTI_POST)
5492 	xge_os_spin_lock_destroy(&hldev->xena_post_lock, hldev->pdev);
5493 #elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
5494 	xge_os_spin_lock_destroy_irq(&hldev->xena_post_lock, hldev->pdev);
5495 #endif
5496 
5497 	xge_debug_device(XGE_TRACE, "device "XGE_OS_LLXFMT" is terminating",
5498 	            (unsigned long long)(ulong_t)hldev);
5499 
5500 	xge_assert(xge_list_is_empty(&hldev->fifo_channels));
5501 	xge_assert(xge_list_is_empty(&hldev->ring_channels));
5502 
5503 	if (hldev->stats.is_initialized) {
5504 	    __hal_stats_terminate(&hldev->stats);
5505 	}
5506 
5507 	/* close if open and free all channels */
5508 	while (!xge_list_is_empty(&hldev->free_channels)) {
5509 	    xge_hal_channel_t *channel = (xge_hal_channel_t*)
5510 	                hldev->free_channels.next;
5511 
5512 	    xge_assert(!channel->is_open);
5513 	    xge_list_remove(&channel->item);
5514 	    __hal_channel_free(channel);
5515 	}
5516 
5517 	if (hldev->queueh) {
5518 	    xge_queue_destroy(hldev->queueh);
5519 	}
5520 
5521 	if (hldev->spdm_table) {
5522 	    xge_os_free(hldev->pdev,
5523 	          hldev->spdm_table[0],
5524 	          (sizeof(xge_hal_spdm_entry_t) *
5525 	            hldev->spdm_max_entries));
5526 	    xge_os_free(hldev->pdev,
5527 	          hldev->spdm_table,
5528 	          (sizeof(xge_hal_spdm_entry_t *) *
5529 	            hldev->spdm_max_entries));
5530 	    xge_os_spin_lock_destroy(&hldev->spdm_lock, hldev->pdev);
5531 	    hldev->spdm_table = NULL;
5532 	}
5533 
5534 	if (hldev->dump_buf)  {
5535 	        xge_os_free(hldev->pdev, hldev->dump_buf,
5536 	            XGE_HAL_DUMP_BUF_SIZE);
5537 	    hldev->dump_buf = NULL;
5538 	}
5539 
5540 	if (hldev->device_id != 0) {
5541 	    int j, pcisize;
5542 
5543 	    pcisize = (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)?
5544 	               XGE_HAL_PCISIZE_HERC : XGE_HAL_PCISIZE_XENA;
5545 	    for (j = 0; j < pcisize; j++) {
5546 	        xge_os_pci_write32(hldev->pdev, hldev->cfgh, j * 4,
5547 	            *((u32*)&hldev->pci_config_space_bios + j));
5548 	    }
5549 	}
5550 }
5551 /**
5552  * __hal_device_get_vpd_data - Getting vpd_data.
5553  *
5554  *   @hldev: HAL device handle.
5555  *
5556  *   Getting  product name and serial number from vpd capabilites structure
5557  *
5558  */
5559 void
__hal_device_get_vpd_data(xge_hal_device_t * hldev)5560 __hal_device_get_vpd_data(xge_hal_device_t *hldev)
5561 {
5562 	u8 * vpd_data;
5563 	u8   data;
5564 	int  index = 0, count, fail = 0;
5565 	u8   vpd_addr = XGE_HAL_CARD_XENA_VPD_ADDR;
5566 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
5567 	    vpd_addr = XGE_HAL_CARD_HERC_VPD_ADDR;
5568 
5569 	xge_os_strcpy((char *) hldev->vpd_data.product_name,
5570 	            "10 Gigabit Ethernet Adapter");
5571 	xge_os_strcpy((char *) hldev->vpd_data.serial_num, "not available");
5572 
5573 	vpd_data = ( u8*) xge_os_malloc(hldev->pdev, XGE_HAL_VPD_BUFFER_SIZE + 16);
5574 	if ( vpd_data == 0 )
5575 	    return;
5576 
5577 	for (index = 0; index < XGE_HAL_VPD_BUFFER_SIZE; index +=4 ) {
5578 	    xge_os_pci_write8(hldev->pdev, hldev->cfgh, (vpd_addr + 2), (u8)index);
5579 	    xge_os_pci_read8(hldev->pdev, hldev->cfgh,(vpd_addr + 2), &data);
5580 	    xge_os_pci_write8(hldev->pdev, hldev->cfgh, (vpd_addr + 3), 0);
5581 	    for (count = 0; count < 5; count++ ) {
5582 	        xge_os_mdelay(2);
5583 	        xge_os_pci_read8(hldev->pdev, hldev->cfgh,(vpd_addr + 3), &data);
5584 	        if (data == XGE_HAL_VPD_READ_COMPLETE)
5585 	            break;
5586 	    }
5587 
5588 	    if (count >= 5) {
5589 	        xge_os_printf("ERR, Reading VPD data failed");
5590 	        fail = 1;
5591 	        break;
5592 	    }
5593 
5594 	    xge_os_pci_read32(hldev->pdev, hldev->cfgh,(vpd_addr + 4),
5595 	            (u32 *)&vpd_data[index]);
5596 	}
5597 
5598 	if(!fail) {
5599 
5600 	    /* read serial number of adapter */
5601 	    for (count = 0; count < XGE_HAL_VPD_BUFFER_SIZE; count++) {
5602 	        if ((vpd_data[count] == 'S')     &&
5603 	            (vpd_data[count + 1] == 'N') &&
5604 	            (vpd_data[count + 2] < XGE_HAL_VPD_LENGTH)) {
5605 	                memset(hldev->vpd_data.serial_num, 0, XGE_HAL_VPD_LENGTH);
5606 	                memcpy(hldev->vpd_data.serial_num, &vpd_data[count + 3],
5607 	                    vpd_data[count + 2]);
5608 	                break;
5609 	        }
5610 	    }
5611 
5612 	    if (vpd_data[1] < XGE_HAL_VPD_LENGTH) {
5613 	        memset(hldev->vpd_data.product_name, 0, vpd_data[1]);
5614 	        memcpy(hldev->vpd_data.product_name, &vpd_data[3], vpd_data[1]);
5615 	    }
5616 
5617 	}
5618 
5619 	xge_os_free(hldev->pdev, vpd_data, XGE_HAL_VPD_BUFFER_SIZE + 16);
5620 }
5621 
5622 
5623 /**
5624  * xge_hal_device_handle_tcode - Handle transfer code.
5625  * @channelh: Channel handle.
5626  * @dtrh: Descriptor handle.
5627  * @t_code: One of the enumerated (and documented in the Xframe user guide)
5628  *          "transfer codes".
5629  *
5630  * Handle descriptor's transfer code. The latter comes with each completed
5631  * descriptor, see xge_hal_fifo_dtr_next_completed() and
5632  * xge_hal_ring_dtr_next_completed().
5633  * Transfer codes are enumerated in xgehal-fifo.h and xgehal-ring.h.
5634  *
5635  * Returns: one of the xge_hal_status_e{} enumerated types.
5636  * XGE_HAL_OK           - for success.
5637  * XGE_HAL_ERR_CRITICAL         - when encounters critical error.
5638  */
5639 xge_hal_status_e
xge_hal_device_handle_tcode(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh,u8 t_code)5640 xge_hal_device_handle_tcode (xge_hal_channel_h channelh,
5641 	             xge_hal_dtr_h dtrh, u8 t_code)
5642 {
5643 	xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
5644 	xge_hal_device_t *hldev = (xge_hal_device_t *)channel->devh;
5645 
5646 	if (t_code > 15) {
5647 	    xge_os_printf("invalid t_code %d", t_code);
5648 	    return XGE_HAL_OK;
5649 	}
5650 
5651 	if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
5652 	        hldev->stats.sw_dev_err_stats.txd_t_code_err_cnt[t_code]++;
5653 
5654 #if defined(XGE_HAL_DEBUG_BAD_TCODE)
5655 	    xge_hal_fifo_txd_t *txdp = (xge_hal_fifo_txd_t *)dtrh;
5656 	    xge_os_printf(""XGE_OS_LLXFMT":"XGE_OS_LLXFMT":"
5657 	    XGE_OS_LLXFMT":"XGE_OS_LLXFMT,
5658 	    txdp->control_1, txdp->control_2, txdp->buffer_pointer,
5659 	    txdp->host_control);
5660 #endif
5661 
5662 	    /* handle link "down" immediately without going through
5663 	     * xge_hal_device_poll() routine. */
5664 	    if (t_code == XGE_HAL_TXD_T_CODE_LOSS_OF_LINK) {
5665 	        /* link is down */
5666 	        if (hldev->link_state != XGE_HAL_LINK_DOWN) {
5667 	            xge_hal_pci_bar0_t *bar0 =
5668 	            (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
5669 	            u64 val64;
5670 
5671 	            hldev->link_state = XGE_HAL_LINK_DOWN;
5672 
5673 	            val64 = xge_os_pio_mem_read64(hldev->pdev,
5674 	                hldev->regh0, &bar0->adapter_control);
5675 
5676 	            /* turn off LED */
5677 	            val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
5678 	            xge_os_pio_mem_write64(hldev->pdev,
5679 	                    hldev->regh0, val64,
5680 	                    &bar0->adapter_control);
5681 
5682 	            g_xge_hal_driver->uld_callbacks.link_down(
5683 	                    hldev->upper_layer_info);
5684 	        }
5685 	    } else if (t_code == XGE_HAL_TXD_T_CODE_ABORT_BUFFER ||
5686 	               t_code == XGE_HAL_TXD_T_CODE_ABORT_DTOR) {
5687 	                    __hal_device_handle_targetabort(hldev);
5688 	        return XGE_HAL_ERR_CRITICAL;
5689 	    }
5690 	    return XGE_HAL_ERR_PKT_DROP;
5691 	} else if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
5692 	        hldev->stats.sw_dev_err_stats.rxd_t_code_err_cnt[t_code]++;
5693 
5694 #if defined(XGE_HAL_DEBUG_BAD_TCODE)
5695 	    xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
5696 	    xge_os_printf(""XGE_OS_LLXFMT":"XGE_OS_LLXFMT":"XGE_OS_LLXFMT
5697 	        ":"XGE_OS_LLXFMT, rxdp->control_1,
5698 	        rxdp->control_2, rxdp->buffer0_ptr,
5699 	        rxdp->host_control);
5700 #endif
5701 	    if (t_code == XGE_HAL_RXD_T_CODE_BAD_ECC) {
5702 	        hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
5703 	        __hal_device_handle_eccerr(hldev, "rxd_t_code",
5704 	                       (u64)t_code);
5705 	        return XGE_HAL_ERR_CRITICAL;
5706 	    } else if (t_code == XGE_HAL_RXD_T_CODE_PARITY ||
5707 	           t_code == XGE_HAL_RXD_T_CODE_PARITY_ABORT) {
5708 	        hldev->stats.sw_dev_err_stats.parity_err_cnt++;
5709 	        __hal_device_handle_parityerr(hldev, "rxd_t_code",
5710 	                          (u64)t_code);
5711 	        return XGE_HAL_ERR_CRITICAL;
5712 	    /* do not drop if detected unknown IPv6 extension */
5713 	    } else if (t_code != XGE_HAL_RXD_T_CODE_UNKNOWN_PROTO) {
5714 	        return XGE_HAL_ERR_PKT_DROP;
5715 	    }
5716 	}
5717 	return XGE_HAL_OK;
5718 }
5719 
5720 /**
5721  * xge_hal_device_link_state - Get link state.
5722  * @devh: HAL device handle.
5723  * @ls: Link state, see xge_hal_device_link_state_e{}.
5724  *
5725  * Get link state.
5726  * Returns: XGE_HAL_OK.
5727  * See also: xge_hal_device_link_state_e{}.
5728  */
xge_hal_device_link_state(xge_hal_device_h devh,xge_hal_device_link_state_e * ls)5729 xge_hal_status_e xge_hal_device_link_state(xge_hal_device_h devh,
5730 	        xge_hal_device_link_state_e *ls)
5731 {
5732 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5733 
5734 	xge_assert(ls != NULL);
5735 	*ls = hldev->link_state;
5736 	return XGE_HAL_OK;
5737 }
5738 
5739 /**
5740  * xge_hal_device_sched_timer - Configure scheduled device interrupt.
5741  * @devh: HAL device handle.
5742  * @interval_us: Time interval, in miscoseconds.
5743  *            Unlike transmit and receive interrupts,
5744  *            the scheduled interrupt is generated independently of
5745  *            traffic, but purely based on time.
5746  * @one_shot: 1 - generate scheduled interrupt only once.
5747  *            0 - generate scheduled interrupt periodically at the specified
5748  *            @interval_us interval.
5749  *
5750  * (Re-)configure scheduled interrupt. Can be called at runtime to change
5751  * the setting, generate one-shot interrupts based on the resource and/or
5752  * traffic conditions, other purposes.
5753  * See also: xge_hal_device_config_t{}.
5754  */
xge_hal_device_sched_timer(xge_hal_device_h devh,int interval_us,int one_shot)5755 void xge_hal_device_sched_timer(xge_hal_device_h devh, int interval_us,
5756 	        int one_shot)
5757 {
5758 	u64 val64;
5759 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5760 	xge_hal_pci_bar0_t *bar0 =
5761 	    (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
5762 	unsigned int interval = hldev->config.pci_freq_mherz * interval_us;
5763 
5764 	interval = __hal_fix_time_ival_herc(hldev, interval);
5765 
5766 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
5767 	                &bar0->scheduled_int_ctrl);
5768 	if (interval) {
5769 	    val64 &= XGE_HAL_SCHED_INT_PERIOD_MASK;
5770 	    val64 |= XGE_HAL_SCHED_INT_PERIOD(interval);
5771 	    if (one_shot) {
5772 	        val64 |= XGE_HAL_SCHED_INT_CTRL_ONE_SHOT;
5773 	    }
5774 	    val64 |= XGE_HAL_SCHED_INT_CTRL_TIMER_EN;
5775 	} else {
5776 	    val64 &= ~XGE_HAL_SCHED_INT_CTRL_TIMER_EN;
5777 	}
5778 
5779 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
5780 	             val64, &bar0->scheduled_int_ctrl);
5781 
5782 	xge_debug_device(XGE_TRACE, "sched_timer 0x"XGE_OS_LLXFMT": %s",
5783 	          (unsigned long long)val64,
5784 	          interval ? "enabled" : "disabled");
5785 }
5786 
5787 /**
5788  * xge_hal_device_check_id - Verify device ID.
5789  * @devh: HAL device handle.
5790  *
5791  * Verify device ID.
5792  * Returns: one of the xge_hal_card_e{} enumerated types.
5793  * See also: xge_hal_card_e{}.
5794  */
5795 xge_hal_card_e
xge_hal_device_check_id(xge_hal_device_h devh)5796 xge_hal_device_check_id(xge_hal_device_h devh)
5797 {
5798 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5799 	switch (hldev->device_id) {
5800 	case XGE_PCI_DEVICE_ID_XENA_1:
5801 	case XGE_PCI_DEVICE_ID_XENA_2:
5802 	    return XGE_HAL_CARD_XENA;
5803 	case XGE_PCI_DEVICE_ID_HERC_1:
5804 	case XGE_PCI_DEVICE_ID_HERC_2:
5805 	    return XGE_HAL_CARD_HERC;
5806 	case XGE_PCI_DEVICE_ID_TITAN_1:
5807 	case XGE_PCI_DEVICE_ID_TITAN_2:
5808 	    return XGE_HAL_CARD_TITAN;
5809 	default:
5810 	    return XGE_HAL_CARD_UNKNOWN;
5811 	}
5812 }
5813 
5814 /**
5815  * xge_hal_device_pci_info_get - Get PCI bus informations such as width,
5816  *           frequency, and mode from previously stored values.
5817  * @devh:       HAL device handle.
5818  * @pci_mode:       pointer to a variable of enumerated type
5819  *          xge_hal_pci_mode_e{}.
5820  * @bus_frequency:  pointer to a variable of enumerated type
5821  *          xge_hal_pci_bus_frequency_e{}.
5822  * @bus_width:      pointer to a variable of enumerated type
5823  *          xge_hal_pci_bus_width_e{}.
5824  *
5825  * Get pci mode, frequency, and PCI bus width.
5826  * Returns: one of the xge_hal_status_e{} enumerated types.
5827  * XGE_HAL_OK           - for success.
5828  * XGE_HAL_ERR_INVALID_DEVICE   - for invalid device handle.
5829  * See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
5830  */
5831 xge_hal_status_e
xge_hal_device_pci_info_get(xge_hal_device_h devh,xge_hal_pci_mode_e * pci_mode,xge_hal_pci_bus_frequency_e * bus_frequency,xge_hal_pci_bus_width_e * bus_width)5832 xge_hal_device_pci_info_get(xge_hal_device_h devh, xge_hal_pci_mode_e *pci_mode,
5833 	    xge_hal_pci_bus_frequency_e *bus_frequency,
5834 	    xge_hal_pci_bus_width_e *bus_width)
5835 {
5836 	xge_hal_status_e rc_status;
5837 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
5838 
5839 	if (!hldev || !hldev->is_initialized || hldev->magic != XGE_HAL_MAGIC) {
5840 	    rc_status =  XGE_HAL_ERR_INVALID_DEVICE;
5841 	    xge_debug_device(XGE_ERR,
5842 	            "xge_hal_device_pci_info_get error, rc %d for device %p",
5843 	        rc_status, hldev);
5844 
5845 	    return rc_status;
5846 	}
5847 
5848 	*pci_mode   = hldev->pci_mode;
5849 	*bus_frequency  = hldev->bus_frequency;
5850 	*bus_width  = hldev->bus_width;
5851 	rc_status   = XGE_HAL_OK;
5852 	return rc_status;
5853 }
5854 
5855 /**
5856  * xge_hal_reinitialize_hw
5857  * @hldev: private member of the device structure.
5858  *
5859  * This function will soft reset the NIC and re-initalize all the
5860  * I/O registers to the values they had after it's inital initialization
5861  * through the probe function.
5862  */
xge_hal_reinitialize_hw(xge_hal_device_t * hldev)5863 int xge_hal_reinitialize_hw(xge_hal_device_t * hldev)
5864 {
5865 	(void) xge_hal_device_reset(hldev);
5866 	if (__hal_device_hw_initialize(hldev) != XGE_HAL_OK) {
5867 	    xge_hal_device_terminate(hldev);
5868 	    (void) __hal_device_reset(hldev);
5869 	    return 1;
5870 	}
5871 	return 0;
5872 }
5873 
5874 
5875 /*
5876  * __hal_read_spdm_entry_line
5877  * @hldev: pointer to xge_hal_device_t structure
5878  * @spdm_line: spdm line in the spdm entry to be read.
5879  * @spdm_entry: spdm entry of the spdm_line in the SPDM table.
5880  * @spdm_line_val: Contains the value stored in the spdm line.
5881  *
5882  * SPDM table contains upto a maximum of 256 spdm entries.
5883  * Each spdm entry contains 8 lines and each line stores 8 bytes.
5884  * This function reads the spdm line(addressed by @spdm_line)
5885  * of the spdm entry(addressed by @spdm_entry) in
5886  * the SPDM table.
5887  */
5888 xge_hal_status_e
__hal_read_spdm_entry_line(xge_hal_device_t * hldev,u8 spdm_line,u16 spdm_entry,u64 * spdm_line_val)5889 __hal_read_spdm_entry_line(xge_hal_device_t *hldev, u8 spdm_line,
5890 	        u16 spdm_entry, u64 *spdm_line_val)
5891 {
5892 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
5893 	u64 val64;
5894 
5895 	val64 = XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_STROBE |
5896 	    XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_LINE_SEL(spdm_line) |
5897 	    XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_OFFSET(spdm_entry);
5898 
5899 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
5900 	        &bar0->rts_rth_spdm_mem_ctrl);
5901 
5902 	/* poll until done */
5903 	if (__hal_device_register_poll(hldev,
5904 	    &bar0->rts_rth_spdm_mem_ctrl, 0,
5905 	    XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_STROBE,
5906 	    XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
5907 
5908 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
5909 	}
5910 
5911 	*spdm_line_val = xge_os_pio_mem_read64(hldev->pdev,
5912 	            hldev->regh0, &bar0->rts_rth_spdm_mem_data);
5913 	return XGE_HAL_OK;
5914 }
5915 
5916 
5917 /*
5918  * __hal_get_free_spdm_entry
5919  * @hldev: pointer to xge_hal_device_t structure
5920  * @spdm_entry: Contains an index to the unused spdm entry in the SPDM table.
5921  *
5922  * This function returns an index of unused spdm entry in the SPDM
5923  * table.
5924  */
5925 static xge_hal_status_e
__hal_get_free_spdm_entry(xge_hal_device_t * hldev,u16 * spdm_entry)5926 __hal_get_free_spdm_entry(xge_hal_device_t *hldev, u16 *spdm_entry)
5927 {
5928 	xge_hal_status_e status;
5929 	u64 spdm_line_val=0;
5930 
5931 	/*
5932 	 * Search in the local SPDM table for a free slot.
5933 	 */
5934 	*spdm_entry = 0;
5935 	for(; *spdm_entry < hldev->spdm_max_entries; (*spdm_entry)++) {
5936 	    if (hldev->spdm_table[*spdm_entry]->in_use) {
5937 	        break;
5938 	    }
5939 	}
5940 
5941 	if (*spdm_entry >= hldev->spdm_max_entries) {
5942 	    return XGE_HAL_ERR_SPDM_TABLE_FULL;
5943 	}
5944 
5945 	/*
5946 	 * Make sure that the corresponding spdm entry in the SPDM
5947 	 * table is free.
5948 	 * Seventh line of the spdm entry contains information about
5949 	 * whether the entry is free or not.
5950 	 */
5951 	if ((status = __hal_read_spdm_entry_line(hldev, 7, *spdm_entry,
5952 	                &spdm_line_val)) != XGE_HAL_OK) {
5953 	    return status;
5954 	}
5955 
5956 	/* BIT(63) in spdm_line 7 corresponds to entry_enable bit */
5957 	if ((spdm_line_val & BIT(63))) {
5958 	    /*
5959 	     * Log a warning
5960 	     */
5961 	    xge_debug_device(XGE_ERR, "Local SPDM table is not "
5962 	          "consistent with the actual one for the spdm "
5963 	          "entry %d", *spdm_entry);
5964 	    return XGE_HAL_ERR_SPDM_TABLE_DATA_INCONSISTENT;
5965 	}
5966 
5967 	return XGE_HAL_OK;
5968 }
5969 
5970 
5971 /*
5972  * __hal_calc_jhash - Calculate Jenkins hash.
5973  * @msg: Jenkins hash algorithm key.
5974  * @length: Length of the key.
5975  * @golden_ratio: Jenkins hash golden ratio.
5976  * @init_value: Jenkins hash initial value.
5977  *
5978  * This function implements the Jenkins based algorithm used for the
5979  * calculation of the RTH hash.
5980  * Returns:  Jenkins hash value.
5981  *
5982  */
5983 static u32
__hal_calc_jhash(u8 * msg,u32 length,u32 golden_ratio,u32 init_value)5984 __hal_calc_jhash(u8 *msg, u32 length, u32 golden_ratio, u32 init_value)
5985 {
5986 
5987 	register u32 a,b,c,len;
5988 
5989 	/*
5990 	 * Set up the internal state
5991 	 */
5992 	len = length;
5993 	a = b = golden_ratio;  /* the golden ratio; an arbitrary value */
5994 	c = init_value;         /* the previous hash value */
5995 
5996 	/*  handle most of the key */
5997 	while (len >= 12)
5998 	{
5999 	    a += (msg[0] + ((u32)msg[1]<<8) + ((u32)msg[2]<<16)
6000 	                     + ((u32)msg[3]<<24));
6001 	    b += (msg[4] + ((u32)msg[5]<<8) + ((u32)msg[6]<<16)
6002 	                     + ((u32)msg[7]<<24));
6003 	    c += (msg[8] + ((u32)msg[9]<<8) + ((u32)msg[10]<<16)
6004 	                     + ((u32)msg[11]<<24));
6005 	    mix(a,b,c);
6006 	    msg += 12; len -= 12;
6007 	}
6008 
6009 	/*  handle the last 11 bytes */
6010 	c += length;
6011 	switch(len)  /* all the case statements fall through */
6012 	{
6013 	    case 11: c+= ((u32)msg[10]<<24);
6014 	         break;
6015 	    case 10: c+= ((u32)msg[9]<<16);
6016 	         break;
6017 	    case 9 : c+= ((u32)msg[8]<<8);
6018 	         break;
6019 	    /* the first byte of c is reserved for the length */
6020 	    case 8 : b+= ((u32)msg[7]<<24);
6021 	         break;
6022 	    case 7 : b+= ((u32)msg[6]<<16);
6023 	         break;
6024 	    case 6 : b+= ((u32)msg[5]<<8);
6025 	         break;
6026 	    case 5 : b+= msg[4];
6027 	         break;
6028 	    case 4 : a+= ((u32)msg[3]<<24);
6029 	         break;
6030 	    case 3 : a+= ((u32)msg[2]<<16);
6031 	         break;
6032 	    case 2 : a+= ((u32)msg[1]<<8);
6033 	         break;
6034 	    case 1 : a+= msg[0];
6035 	         break;
6036 	    /* case 0: nothing left to add */
6037 	}
6038 
6039 	mix(a,b,c);
6040 
6041 	/* report the result */
6042 	return c;
6043 }
6044 
6045 
6046 /**
6047  * xge_hal_spdm_entry_add - Add a new entry to the SPDM table.
6048  * @devh: HAL device handle.
6049  * @src_ip: Source ip address(IPv4/IPv6).
6050  * @dst_ip: Destination ip address(IPv4/IPv6).
6051  * @l4_sp: L4 source port.
6052  * @l4_dp: L4 destination port.
6053  * @is_tcp: Set to 1, if the protocol is TCP.
6054  *         0, if the protocol is UDP.
6055  * @is_ipv4: Set to 1, if the protocol is IPv4.
6056  *         0, if the protocol is IPv6.
6057  * @tgt_queue: Target queue to route the receive packet.
6058  *
6059  * This function add a new entry to the SPDM table.
6060  *
6061  * Returns:  XGE_HAL_OK - success.
6062  * XGE_HAL_ERR_SPDM_NOT_ENABLED -  SPDM support is not enabled.
6063  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to add a new entry with in
6064  *                  the time(timeout).
6065  * XGE_HAL_ERR_SPDM_TABLE_FULL - SPDM table is full.
6066  * XGE_HAL_ERR_SPDM_INVALID_ENTRY - Invalid SPDM entry.
6067  *
6068  * See also: xge_hal_spdm_entry_remove{}.
6069  */
6070 xge_hal_status_e
xge_hal_spdm_entry_add(xge_hal_device_h devh,xge_hal_ipaddr_t * src_ip,xge_hal_ipaddr_t * dst_ip,u16 l4_sp,u16 l4_dp,u8 is_tcp,u8 is_ipv4,u8 tgt_queue)6071 xge_hal_spdm_entry_add(xge_hal_device_h devh, xge_hal_ipaddr_t *src_ip,
6072 	    xge_hal_ipaddr_t *dst_ip, u16 l4_sp, u16 l4_dp,
6073 	    u8 is_tcp, u8 is_ipv4, u8 tgt_queue)
6074 {
6075 
6076 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
6077 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
6078 	u32 jhash_value;
6079 	u32 jhash_init_val;
6080 	u32 jhash_golden_ratio;
6081 	u64 val64;
6082 	int off;
6083 	u16 spdm_entry;
6084 	u8  msg[XGE_HAL_JHASH_MSG_LEN];
6085 	int ipaddr_len;
6086 	xge_hal_status_e status;
6087 
6088 
6089 	if (!hldev->config.rth_spdm_en) {
6090 	    return XGE_HAL_ERR_SPDM_NOT_ENABLED;
6091 	}
6092 
6093 	if ((tgt_queue <  XGE_HAL_MIN_RING_NUM) ||
6094 	    (tgt_queue  >  XGE_HAL_MAX_RING_NUM)) {
6095 	    return XGE_HAL_ERR_SPDM_INVALID_ENTRY;
6096 	}
6097 
6098 
6099 	/*
6100 	 * Calculate the jenkins hash.
6101 	 */
6102 	/*
6103 	 * Create the Jenkins hash algorithm key.
6104 	 * key = {L3SA, L3DA, L4SP, L4DP}, if SPDM is configured to
6105 	 * use L4 information. Otherwize key = {L3SA, L3DA}.
6106 	 */
6107 
6108 	if (is_ipv4) {
6109 	    ipaddr_len = 4;   // In bytes
6110 	} else {
6111 	    ipaddr_len = 16;
6112 	}
6113 
6114 	/*
6115 	 * Jenkins hash algorithm expects the key in the big endian
6116 	 * format. Since key is the byte array, memcpy won't work in the
6117 	 * case of little endian. So, the current code extracts each
6118 	 * byte starting from MSB and store it in the key.
6119 	 */
6120 	if (is_ipv4) {
6121 	    for (off = 0; off < ipaddr_len; off++) {
6122 	        u32 mask = vBIT32(0xff,(off*8),8);
6123 	        int shift = 32-(off+1)*8;
6124 	        msg[off] = (u8)((src_ip->ipv4.addr & mask) >> shift);
6125 	        msg[off+ipaddr_len] =
6126 	            (u8)((dst_ip->ipv4.addr & mask) >> shift);
6127 	    }
6128 	} else {
6129 	    for (off = 0; off < ipaddr_len; off++) {
6130 	        int loc = off % 8;
6131 	        u64 mask = vBIT(0xff,(loc*8),8);
6132 	        int shift = 64-(loc+1)*8;
6133 
6134 	        msg[off] = (u8)((src_ip->ipv6.addr[off/8] & mask)
6135 	                    >> shift);
6136 	        msg[off+ipaddr_len] = (u8)((dst_ip->ipv6.addr[off/8]
6137 	                        & mask) >> shift);
6138 	    }
6139 	}
6140 
6141 	off = (2*ipaddr_len);
6142 
6143 	if (hldev->config.rth_spdm_use_l4) {
6144 	    msg[off] = (u8)((l4_sp & 0xff00) >> 8);
6145 	    msg[off + 1] = (u8)(l4_sp & 0xff);
6146 	    msg[off + 2] = (u8)((l4_dp & 0xff00) >> 8);
6147 	    msg[off + 3] = (u8)(l4_dp & 0xff);
6148 	    off += 4;
6149 	}
6150 
6151 	/*
6152 	 * Calculate jenkins hash for this configuration
6153 	 */
6154 	val64 = xge_os_pio_mem_read64(hldev->pdev,
6155 	                hldev->regh0,
6156 	                &bar0->rts_rth_jhash_cfg);
6157 	jhash_golden_ratio = (u32)(val64 >> 32);
6158 	jhash_init_val = (u32)(val64 & 0xffffffff);
6159 
6160 	jhash_value = __hal_calc_jhash(msg, off,
6161 	                   jhash_golden_ratio,
6162 	                   jhash_init_val);
6163 
6164 	xge_os_spin_lock(&hldev->spdm_lock);
6165 
6166 	/*
6167 	 * Locate a free slot in the SPDM table. To avoid a seach in the
6168 	 * actual SPDM table, which is very expensive in terms of time,
6169 	 * we are maintaining a local copy of  the table and the search for
6170 	 * the free entry is performed in the local table.
6171 	 */
6172 	if ((status = __hal_get_free_spdm_entry(hldev,&spdm_entry))
6173 	        != XGE_HAL_OK) {
6174 	    xge_os_spin_unlock(&hldev->spdm_lock);
6175 	    return status;
6176 	}
6177 
6178 	/*
6179 	 * Add this entry to the SPDM table
6180 	 */
6181 	status =  __hal_spdm_entry_add(hldev, src_ip, dst_ip, l4_sp, l4_dp,
6182 	                 is_tcp, is_ipv4, tgt_queue,
6183 	                 jhash_value, /* calculated jhash */
6184 	                 spdm_entry);
6185 
6186 	xge_os_spin_unlock(&hldev->spdm_lock);
6187 
6188 	return status;
6189 }
6190 
6191 /**
6192  * xge_hal_spdm_entry_remove - Remove an entry from the SPDM table.
6193  * @devh: HAL device handle.
6194  * @src_ip: Source ip address(IPv4/IPv6).
6195  * @dst_ip: Destination ip address(IPv4/IPv6).
6196  * @l4_sp: L4 source port.
6197  * @l4_dp: L4 destination port.
6198  * @is_tcp: Set to 1, if the protocol is TCP.
6199  *         0, if the protocol os UDP.
6200  * @is_ipv4: Set to 1, if the protocol is IPv4.
6201  *         0, if the protocol is IPv6.
6202  *
6203  * This function remove an entry from the SPDM table.
6204  *
6205  * Returns:  XGE_HAL_OK - success.
6206  * XGE_HAL_ERR_SPDM_NOT_ENABLED -  SPDM support is not enabled.
6207  * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to remove an entry with in
6208  *                  the time(timeout).
6209  * XGE_HAL_ERR_SPDM_ENTRY_NOT_FOUND - Unable to locate the entry in the SPDM
6210  *                  table.
6211  *
6212  * See also: xge_hal_spdm_entry_add{}.
6213  */
6214 xge_hal_status_e
xge_hal_spdm_entry_remove(xge_hal_device_h devh,xge_hal_ipaddr_t * src_ip,xge_hal_ipaddr_t * dst_ip,u16 l4_sp,u16 l4_dp,u8 is_tcp,u8 is_ipv4)6215 xge_hal_spdm_entry_remove(xge_hal_device_h devh, xge_hal_ipaddr_t *src_ip,
6216 	    xge_hal_ipaddr_t *dst_ip, u16 l4_sp, u16 l4_dp,
6217 	    u8 is_tcp, u8 is_ipv4)
6218 {
6219 
6220 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
6221 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
6222 	u64 val64;
6223 	u16 spdm_entry;
6224 	xge_hal_status_e status;
6225 	u64 spdm_line_arr[8];
6226 	u8 line_no;
6227 	u8 spdm_is_tcp;
6228 	u8 spdm_is_ipv4;
6229 	u16 spdm_l4_sp;
6230 	u16 spdm_l4_dp;
6231 
6232 	if (!hldev->config.rth_spdm_en) {
6233 	    return XGE_HAL_ERR_SPDM_NOT_ENABLED;
6234 	}
6235 
6236 	xge_os_spin_lock(&hldev->spdm_lock);
6237 
6238 	/*
6239 	 * Poll the rxpic_int_reg register until spdm ready bit is set or
6240 	 * timeout happens.
6241 	 */
6242 	if (__hal_device_register_poll(hldev, &bar0->rxpic_int_reg, 1,
6243 	        XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
6244 	        XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
6245 
6246 	    /* upper layer may require to repeat */
6247 	    xge_os_spin_unlock(&hldev->spdm_lock);
6248 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
6249 	}
6250 
6251 	/*
6252 	 * Clear the SPDM READY bit.
6253 	 */
6254 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6255 	                           &bar0->rxpic_int_reg);
6256 	val64 &= ~XGE_HAL_RX_PIC_INT_REG_SPDM_READY;
6257 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6258 	                  &bar0->rxpic_int_reg);
6259 
6260 	/*
6261 	 * Search in the local SPDM table to get the index of the
6262 	 * corresponding entry in the SPDM table.
6263 	 */
6264 	spdm_entry = 0;
6265 	for (;spdm_entry < hldev->spdm_max_entries; spdm_entry++) {
6266 	    if ((!hldev->spdm_table[spdm_entry]->in_use) ||
6267 	        (hldev->spdm_table[spdm_entry]->is_tcp != is_tcp) ||
6268 	        (hldev->spdm_table[spdm_entry]->l4_sp != l4_sp) ||
6269 	        (hldev->spdm_table[spdm_entry]->l4_dp != l4_dp) ||
6270 	        (hldev->spdm_table[spdm_entry]->is_ipv4 != is_ipv4)) {
6271 	        continue;
6272 	    }
6273 
6274 	    /*
6275 	     * Compare the src/dst IP addresses of source and target
6276 	     */
6277 	    if (is_ipv4) {
6278 	        if ((hldev->spdm_table[spdm_entry]->src_ip.ipv4.addr
6279 	             != src_ip->ipv4.addr) ||
6280 	            (hldev->spdm_table[spdm_entry]->dst_ip.ipv4.addr
6281 	             != dst_ip->ipv4.addr)) {
6282 	            continue;
6283 	        }
6284 	    } else {
6285 	        if ((hldev->spdm_table[spdm_entry]->src_ip.ipv6.addr[0]
6286 	             != src_ip->ipv6.addr[0]) ||
6287 	            (hldev->spdm_table[spdm_entry]->src_ip.ipv6.addr[1]
6288 	             != src_ip->ipv6.addr[1]) ||
6289 	            (hldev->spdm_table[spdm_entry]->dst_ip.ipv6.addr[0]
6290 	             != dst_ip->ipv6.addr[0]) ||
6291 	            (hldev->spdm_table[spdm_entry]->dst_ip.ipv6.addr[1]
6292 	             != dst_ip->ipv6.addr[1])) {
6293 	            continue;
6294 	        }
6295 	    }
6296 	    break;
6297 	}
6298 
6299 	if (spdm_entry >= hldev->spdm_max_entries) {
6300 	    xge_os_spin_unlock(&hldev->spdm_lock);
6301 	    return XGE_HAL_ERR_SPDM_ENTRY_NOT_FOUND;
6302 	}
6303 
6304 	/*
6305 	 * Retrieve the corresponding entry from the SPDM table and
6306 	 * make sure that the data is consistent.
6307 	 */
6308 	for(line_no = 0; line_no < 8; line_no++) {
6309 
6310 	    /*
6311 	     *  SPDM line 2,3,4 are valid only for IPv6 entry.
6312 	     *  SPDM line 5 & 6 are reserved. We don't have to
6313 	     *  read these entries in the above cases.
6314 	     */
6315 	    if (((is_ipv4) &&
6316 	        ((line_no == 2)||(line_no == 3)||(line_no == 4))) ||
6317 	         (line_no == 5) ||
6318 	         (line_no == 6)) {
6319 	        continue;
6320 	    }
6321 
6322 	    if ((status = __hal_read_spdm_entry_line(
6323 	                hldev,
6324 	                line_no,
6325 	                spdm_entry,
6326 	                &spdm_line_arr[line_no]))
6327 	                        != XGE_HAL_OK) {
6328 	        xge_os_spin_unlock(&hldev->spdm_lock);
6329 	        return status;
6330 	    }
6331 	}
6332 
6333 	/*
6334 	 * Seventh line of the spdm entry contains the entry_enable
6335 	 * bit. Make sure that the entry_enable bit of this spdm entry
6336 	 * is set.
6337 	 * To remove an entry from the SPDM table, reset this
6338 	 * bit.
6339 	 */
6340 	if (!(spdm_line_arr[7] & BIT(63))) {
6341 	    /*
6342 	     * Log a warning
6343 	     */
6344 	    xge_debug_device(XGE_ERR, "Local SPDM table is not "
6345 	        "consistent with the actual one for the spdm "
6346 	        "entry %d ", spdm_entry);
6347 	    goto err_exit;
6348 	}
6349 
6350 	/*
6351 	 *  Retreive the L4 SP/DP, src/dst ip addresses from the SPDM
6352 	 *  table and do a comparision.
6353 	 */
6354 	spdm_is_tcp = (u8)((spdm_line_arr[0] & BIT(59)) >> 4);
6355 	spdm_is_ipv4 = (u8)(spdm_line_arr[0] & BIT(63));
6356 	spdm_l4_sp = (u16)(spdm_line_arr[0] >> 48);
6357 	spdm_l4_dp = (u16)((spdm_line_arr[0] >> 32) & 0xffff);
6358 
6359 
6360 	if ((spdm_is_tcp != is_tcp) ||
6361 	    (spdm_is_ipv4 != is_ipv4) ||
6362 	    (spdm_l4_sp != l4_sp) ||
6363 	    (spdm_l4_dp != l4_dp)) {
6364 	    /*
6365 	     * Log a warning
6366 	     */
6367 	    xge_debug_device(XGE_ERR, "Local SPDM table is not "
6368 	        "consistent with the actual one for the spdm "
6369 	        "entry %d ", spdm_entry);
6370 	    goto err_exit;
6371 	}
6372 
6373 	if (is_ipv4) {
6374 	    /* Upper 32 bits of spdm_line(64 bit) contains the
6375 	     * src IPv4 address. Lower 32 bits of spdm_line
6376 	     * contains the destination IPv4 address.
6377 	     */
6378 	    u32 temp_src_ip = (u32)(spdm_line_arr[1] >> 32);
6379 	    u32 temp_dst_ip = (u32)(spdm_line_arr[1] & 0xffffffff);
6380 
6381 	    if ((temp_src_ip != src_ip->ipv4.addr) ||
6382 	        (temp_dst_ip != dst_ip->ipv4.addr)) {
6383 	        xge_debug_device(XGE_ERR, "Local SPDM table is not "
6384 	            "consistent with the actual one for the spdm "
6385 	            "entry %d ", spdm_entry);
6386 	        goto err_exit;
6387 	    }
6388 
6389 	} else {
6390 	    /*
6391 	     * SPDM line 1 & 2 contains the src IPv6 address.
6392 	     * SPDM line 3 & 4 contains the dst IPv6 address.
6393 	     */
6394 	    if ((spdm_line_arr[1] != src_ip->ipv6.addr[0]) ||
6395 	        (spdm_line_arr[2] != src_ip->ipv6.addr[1]) ||
6396 	        (spdm_line_arr[3] != dst_ip->ipv6.addr[0]) ||
6397 	        (spdm_line_arr[4] != dst_ip->ipv6.addr[1])) {
6398 
6399 	        /*
6400 	         * Log a warning
6401 	         */
6402 	        xge_debug_device(XGE_ERR, "Local SPDM table is not "
6403 	            "consistent with the actual one for the spdm "
6404 	            "entry %d ", spdm_entry);
6405 	        goto err_exit;
6406 	    }
6407 	}
6408 
6409 	/*
6410 	 * Reset the entry_enable bit to zero
6411 	 */
6412 	spdm_line_arr[7] &= ~BIT(63);
6413 
6414 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
6415 	    spdm_line_arr[7],
6416 	    (void *)((char *)hldev->spdm_mem_base +
6417 	    (spdm_entry * 64) + (7 * 8)));
6418 
6419 	/*
6420 	 * Wait for the operation to be completed.
6421 	 */
6422 	if (__hal_device_register_poll(hldev,
6423 	    &bar0->rxpic_int_reg, 1,
6424 	    XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
6425 	    XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
6426 	    xge_os_spin_unlock(&hldev->spdm_lock);
6427 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
6428 	}
6429 
6430 	/*
6431 	 * Make the corresponding spdm entry in the local SPDM table
6432 	 * available for future use.
6433 	 */
6434 	hldev->spdm_table[spdm_entry]->in_use = 0;
6435 	xge_os_spin_unlock(&hldev->spdm_lock);
6436 
6437 	return XGE_HAL_OK;
6438 
6439 err_exit:
6440 	xge_os_spin_unlock(&hldev->spdm_lock);
6441 	return XGE_HAL_ERR_SPDM_TABLE_DATA_INCONSISTENT;
6442 }
6443 
6444 /*
6445  * __hal_device_rti_set
6446  * @ring: The post_qid of the ring.
6447  * @channel: HAL channel of the ring.
6448  *
6449  * This function stores the RTI value associated for the MSI and
6450  * also unmasks this particular RTI in the rti_mask register.
6451  */
__hal_device_rti_set(int ring_qid,xge_hal_channel_t * channel)6452 static void __hal_device_rti_set(int ring_qid, xge_hal_channel_t *channel)
6453 {
6454 	xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
6455 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
6456 	u64 val64;
6457 
6458 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSI ||
6459 	    hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX)
6460 	    channel->rti = (u8)ring_qid;
6461 
6462 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6463 	            &bar0->rx_traffic_mask);
6464 	val64 &= ~BIT(ring_qid);
6465 	xge_os_pio_mem_write64(hldev->pdev,
6466 	            hldev->regh0, val64,
6467 	            &bar0->rx_traffic_mask);
6468 }
6469 
6470 /*
6471  * __hal_device_tti_set
6472  * @ring: The post_qid of the FIFO.
6473  * @channel: HAL channel the FIFO.
6474  *
6475  * This function stores the TTI value associated for the MSI and
6476  * also unmasks this particular TTI in the tti_mask register.
6477  */
__hal_device_tti_set(int fifo_qid,xge_hal_channel_t * channel)6478 static void __hal_device_tti_set(int fifo_qid, xge_hal_channel_t *channel)
6479 {
6480 	xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
6481 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
6482 	u64 val64;
6483 
6484 	if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSI ||
6485 	    hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX)
6486 	    channel->tti = (u8)fifo_qid;
6487 
6488 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6489 	            &bar0->tx_traffic_mask);
6490 	val64 &= ~BIT(fifo_qid);
6491 	xge_os_pio_mem_write64(hldev->pdev,
6492 	            hldev->regh0, val64,
6493 	            &bar0->tx_traffic_mask);
6494 }
6495 
6496 /**
6497  * xge_hal_channel_msi_set - Associate a RTI with a ring or TTI with a
6498  * FIFO for a given MSI.
6499  * @channelh: HAL channel handle.
6500  * @msi: MSI Number associated with the channel.
6501  * @msi_msg: The MSI message associated with the MSI number above.
6502  *
6503  * This API will associate a given channel (either Ring or FIFO) with the
6504  * given MSI number. It will alo program the Tx_Mat/Rx_Mat tables in the
6505  * hardware to indicate this association to the hardware.
6506  */
6507 xge_hal_status_e
xge_hal_channel_msi_set(xge_hal_channel_h channelh,int msi,u32 msi_msg)6508 xge_hal_channel_msi_set(xge_hal_channel_h channelh, int msi, u32 msi_msg)
6509 {
6510 	xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
6511 	xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
6512 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
6513 	u64 val64;
6514 
6515 	channel->msi_msg = msi_msg;
6516 	if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
6517 	    int ring = channel->post_qid;
6518 	    xge_debug_osdep(XGE_TRACE, "MSI Data: 0x%4x, Ring: %d,"
6519 	            " MSI: %d", channel->msi_msg, ring, msi);
6520 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6521 	        &bar0->rx_mat);
6522 	    val64 |= XGE_HAL_SET_RX_MAT(ring, msi);
6523 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6524 	        &bar0->rx_mat);
6525 	    __hal_device_rti_set(ring, channel);
6526 	} else {
6527 	    int fifo = channel->post_qid;
6528 	    xge_debug_osdep(XGE_TRACE, "MSI Data: 0x%4x, Fifo: %d,"
6529 	            " MSI: %d", channel->msi_msg, fifo, msi);
6530 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6531 	        &bar0->tx_mat[0]);
6532 	    val64 |= XGE_HAL_SET_TX_MAT(fifo, msi);
6533 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6534 	        &bar0->tx_mat[0]);
6535 	    __hal_device_tti_set(fifo, channel);
6536 	}
6537 
6538 	 return XGE_HAL_OK;
6539 }
6540 
6541 /**
6542  * xge_hal_mask_msix - Begin IRQ processing.
6543  * @hldev: HAL device handle.
6544  * @msi_id:  MSI ID
6545  *
6546  * The function masks the msix interrupt for the given msi_id
6547  *
6548  * Note:
6549  *
6550  * Returns: 0,
6551  * Otherwise, XGE_HAL_ERR_WRONG_IRQ if the msix index is out of range
6552  * status.
6553  * See also:
6554  */
6555 xge_hal_status_e
xge_hal_mask_msix(xge_hal_device_h devh,int msi_id)6556 xge_hal_mask_msix(xge_hal_device_h devh, int msi_id)
6557 {
6558 	xge_hal_status_e  status = XGE_HAL_OK;
6559 	xge_hal_device_t *hldev  = (xge_hal_device_t *)devh;
6560 	u32              *bar2   = (u32 *)hldev->bar2;
6561 	u32               val32;
6562 
6563 	xge_assert(msi_id < XGE_HAL_MAX_MSIX_MESSAGES);
6564 
6565 	val32 = xge_os_pio_mem_read32(hldev->pdev, hldev->regh2, &bar2[msi_id*4+3]);
6566 	val32 |= 1;
6567 	xge_os_pio_mem_write32(hldev->pdev, hldev->regh2, val32, &bar2[msi_id*4+3]);
6568 	return status;
6569 }
6570 
6571 /**
6572  * xge_hal_mask_msix - Begin IRQ processing.
6573  * @hldev: HAL device handle.
6574  * @msi_id:  MSI ID
6575  *
6576  * The function masks the msix interrupt for the given msi_id
6577  *
6578  * Note:
6579  *
6580  * Returns: 0,
6581  * Otherwise, XGE_HAL_ERR_WRONG_IRQ if the msix index is out of range
6582  * status.
6583  * See also:
6584  */
6585 xge_hal_status_e
xge_hal_unmask_msix(xge_hal_device_h devh,int msi_id)6586 xge_hal_unmask_msix(xge_hal_device_h devh, int msi_id)
6587 {
6588 	xge_hal_status_e  status = XGE_HAL_OK;
6589 	xge_hal_device_t *hldev  = (xge_hal_device_t *)devh;
6590 	u32              *bar2   = (u32 *)hldev->bar2;
6591 	u32               val32;
6592 
6593 	xge_assert(msi_id < XGE_HAL_MAX_MSIX_MESSAGES);
6594 
6595 	val32 = xge_os_pio_mem_read32(hldev->pdev, hldev->regh2, &bar2[msi_id*4+3]);
6596 	val32 &= ~1;
6597 	xge_os_pio_mem_write32(hldev->pdev, hldev->regh2, val32, &bar2[msi_id*4+3]);
6598 	return status;
6599 }
6600 
6601 /*
6602  * __hal_set_msix_vals
6603  * @devh: HAL device handle.
6604  * @msix_value: 32bit MSI-X value transferred across PCI to @msix_address.
6605  *              Filled in by this function.
6606  * @msix_address: 32bit MSI-X DMA address.
6607  *              Filled in by this function.
6608  * @msix_idx: index that corresponds to the (@msix_value, @msix_address)
6609  *            entry in the table of MSI-X (value, address) pairs.
6610  *
6611  * This function will program the hardware associating the given
6612  * address/value cobination to the specified msi number.
6613  */
__hal_set_msix_vals(xge_hal_device_h devh,u32 * msix_value,u64 * msix_addr,int msix_idx)6614 static void __hal_set_msix_vals (xge_hal_device_h devh,
6615 	             u32 *msix_value,
6616 	             u64 *msix_addr,
6617 	             int msix_idx)
6618 {
6619 	int cnt = 0;
6620 
6621 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
6622 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
6623 	u64 val64;
6624 
6625 	val64 = XGE_HAL_XMSI_NO(msix_idx) | XGE_HAL_XMSI_STROBE;
6626 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
6627 	        (u32)(val64 >> 32), &bar0->xmsi_access);
6628 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
6629 	               (u32)(val64), &bar0->xmsi_access);
6630 	do {
6631 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6632 	                    &bar0->xmsi_access);
6633 	    if (val64 & XGE_HAL_XMSI_STROBE)
6634 	        break;
6635 	    cnt++;
6636 	    xge_os_mdelay(20);
6637 	} while(cnt < 5);
6638 	*msix_value = (u32)(xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6639 	             &bar0->xmsi_data));
6640 	*msix_addr = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6641 	             &bar0->xmsi_address);
6642 }
6643 
6644 /**
6645  * xge_hal_channel_msix_set - Associate MSI-X with a channel.
6646  * @channelh: HAL channel handle.
6647  * @msix_idx: index that corresponds to a particular (@msix_value,
6648  *            @msix_address) entry in the MSI-X table.
6649  *
6650  * This API associates a given channel (either Ring or FIFO) with the
6651  * given MSI-X number. It programs the Xframe's Tx_Mat/Rx_Mat tables
6652  * to indicate this association.
6653  */
6654 xge_hal_status_e
xge_hal_channel_msix_set(xge_hal_channel_h channelh,int msix_idx)6655 xge_hal_channel_msix_set(xge_hal_channel_h channelh, int msix_idx)
6656 {
6657 	xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
6658 	xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
6659 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
6660 	u64 val64;
6661 
6662 	 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
6663 	     /* Currently Ring and RTI is one on one. */
6664 	    int ring = channel->post_qid;
6665 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6666 	        &bar0->rx_mat);
6667 	    val64 |= XGE_HAL_SET_RX_MAT(ring, msix_idx);
6668 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6669 	        &bar0->rx_mat);
6670 	    __hal_device_rti_set(ring, channel);
6671 	    hldev->config.fifo.queue[channel->post_qid].intr_vector =
6672 	                            msix_idx;
6673 	 } else if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
6674 	    int fifo = channel->post_qid;
6675 	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6676 	        &bar0->tx_mat[0]);
6677 	    val64 |= XGE_HAL_SET_TX_MAT(fifo, msix_idx);
6678 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6679 	        &bar0->tx_mat[0]);
6680 	    __hal_device_tti_set(fifo, channel);
6681 	    hldev->config.ring.queue[channel->post_qid].intr_vector =
6682 	                            msix_idx;
6683 	}
6684 	 channel->msix_idx = msix_idx;
6685 	__hal_set_msix_vals(hldev, &channel->msix_data,
6686 	            &channel->msix_address,
6687 	            channel->msix_idx);
6688 
6689 	 return XGE_HAL_OK;
6690 }
6691 
6692 #if defined(XGE_HAL_CONFIG_LRO)
6693 /**
6694  * xge_hal_lro_terminate - Terminate lro resources.
6695  * @lro_scale: Amount of  lro memory.
6696  * @hldev: Hal device structure.
6697  *
6698  */
6699 void
xge_hal_lro_terminate(u32 lro_scale,xge_hal_device_t * hldev)6700 xge_hal_lro_terminate(u32 lro_scale,
6701 	            xge_hal_device_t *hldev)
6702 {
6703 }
6704 
6705 /**
6706  * xge_hal_lro_init - Initiate lro resources.
6707  * @lro_scale: Amount of  lro memory.
6708  * @hldev: Hal device structure.
6709  * Note: For time being I am using only one LRO per device. Later on size
6710  * will be increased.
6711  */
6712 
6713 xge_hal_status_e
xge_hal_lro_init(u32 lro_scale,xge_hal_device_t * hldev)6714 xge_hal_lro_init(u32 lro_scale,
6715 	       xge_hal_device_t *hldev)
6716 {
6717 	int i;
6718 
6719 	if (hldev->config.lro_sg_size == XGE_HAL_DEFAULT_USE_HARDCODE)
6720 	    hldev->config.lro_sg_size = XGE_HAL_LRO_DEFAULT_SG_SIZE;
6721 
6722 	if (hldev->config.lro_frm_len == XGE_HAL_DEFAULT_USE_HARDCODE)
6723 	    hldev->config.lro_frm_len = XGE_HAL_LRO_DEFAULT_FRM_LEN;
6724 
6725 	for (i=0; i < XGE_HAL_MAX_RING_NUM; i++)
6726 	{
6727 	    xge_os_memzero(hldev->lro_desc[i].lro_pool,
6728 	               sizeof(lro_t) * XGE_HAL_LRO_MAX_BUCKETS);
6729 
6730 	    hldev->lro_desc[i].lro_next_idx = 0;
6731 	    hldev->lro_desc[i].lro_recent = NULL;
6732 	}
6733 
6734 	return XGE_HAL_OK;
6735 }
6736 #endif
6737 
6738 
6739 /**
6740  * xge_hal_device_poll - HAL device "polling" entry point.
6741  * @devh: HAL device.
6742  *
6743  * HAL "polling" entry point. Note that this is part of HAL public API.
6744  * Upper-Layer driver _must_ periodically poll HAL via
6745  * xge_hal_device_poll().
6746  *
6747  * HAL uses caller's execution context to serially process accumulated
6748  * slow-path events, such as link state changes and hardware error
6749  * indications.
6750  *
6751  * The rate of polling could be somewhere between 500us to 10ms,
6752  * depending on requirements (e.g., the requirement to support fail-over
6753  * could mean that 500us or even 100us polling interval need to be used).
6754  *
6755  * The need and motivation for external polling includes
6756  *
6757  *   - remove the error-checking "burden" from the HAL interrupt handler
6758  *     (see xge_hal_device_handle_irq());
6759  *
6760  *   - remove the potential source of portability issues by _not_
6761  *     implementing separate polling thread within HAL itself.
6762  *
6763  * See also: xge_hal_event_e{}, xge_hal_driver_config_t{}.
6764  * Usage: See ex_slow_path{}.
6765  */
6766 void
xge_hal_device_poll(xge_hal_device_h devh)6767 xge_hal_device_poll(xge_hal_device_h devh)
6768 {
6769 	unsigned char item_buf[sizeof(xge_queue_item_t) +
6770 	            XGE_DEFAULT_EVENT_MAX_DATA_SIZE];
6771 	xge_queue_item_t *item = (xge_queue_item_t *)(void *)item_buf;
6772 	xge_queue_status_e qstatus;
6773 	xge_hal_status_e hstatus;
6774 	int i = 0;
6775 	int queue_has_critical_event = 0;
6776 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
6777 
6778   xge_os_memzero(item_buf, (sizeof(xge_queue_item_t) +
6779 	                         XGE_DEFAULT_EVENT_MAX_DATA_SIZE));
6780 
6781 _again:
6782 	if (!hldev->is_initialized ||
6783 	    hldev->terminating ||
6784 	    hldev->magic != XGE_HAL_MAGIC)
6785 	    return;
6786 
6787 	if(hldev->stats.sw_dev_err_stats.xpak_counter.tick_period < 72000)
6788 	{
6789 	    /*
6790 	     * Wait for an Hour
6791 	     */
6792 	    hldev->stats.sw_dev_err_stats.xpak_counter.tick_period++;
6793 	} else {
6794 	    /*
6795 	     * Logging Error messages in the excess temperature,
6796 	     * Bias current, laser ouput for three cycle
6797 	     */
6798 	    __hal_updt_stats_xpak(hldev);
6799 	    hldev->stats.sw_dev_err_stats.xpak_counter.tick_period = 0;
6800 	}
6801 
6802 	if (!queue_has_critical_event)
6803 	        queue_has_critical_event =
6804 	        __queue_get_reset_critical(hldev->queueh);
6805 
6806 	hldev->in_poll = 1;
6807 	while (i++ < XGE_HAL_DRIVER_QUEUE_CONSUME_MAX || queue_has_critical_event) {
6808 
6809 	    qstatus = xge_queue_consume(hldev->queueh,
6810 	                XGE_DEFAULT_EVENT_MAX_DATA_SIZE,
6811 	                item);
6812 	    if (qstatus == XGE_QUEUE_IS_EMPTY)
6813 	        break;
6814 
6815 	    xge_debug_queue(XGE_TRACE,
6816 	         "queueh 0x"XGE_OS_LLXFMT" consumed event: %d ctxt 0x"
6817 	         XGE_OS_LLXFMT, (u64)(ulong_t)hldev->queueh, item->event_type,
6818 	         (u64)(ulong_t)item->context);
6819 
6820 	    if (!hldev->is_initialized ||
6821 	        hldev->magic != XGE_HAL_MAGIC) {
6822 	        hldev->in_poll = 0;
6823 	        return;
6824 	    }
6825 
6826 	    switch (item->event_type) {
6827 	    case XGE_HAL_EVENT_LINK_IS_UP: {
6828 	        if (!queue_has_critical_event &&
6829 	            g_xge_hal_driver->uld_callbacks.link_up) {
6830 	            g_xge_hal_driver->uld_callbacks.link_up(
6831 	                hldev->upper_layer_info);
6832 	            hldev->link_state = XGE_HAL_LINK_UP;
6833 	        }
6834 	    } break;
6835 	    case XGE_HAL_EVENT_LINK_IS_DOWN: {
6836 	        if (!queue_has_critical_event &&
6837 	            g_xge_hal_driver->uld_callbacks.link_down) {
6838 	            g_xge_hal_driver->uld_callbacks.link_down(
6839 	                hldev->upper_layer_info);
6840 	            hldev->link_state = XGE_HAL_LINK_DOWN;
6841 	        }
6842 	    } break;
6843 	    case XGE_HAL_EVENT_SERR:
6844 	    case XGE_HAL_EVENT_ECCERR:
6845 	    case XGE_HAL_EVENT_PARITYERR:
6846 	    case XGE_HAL_EVENT_TARGETABORT:
6847 	    case XGE_HAL_EVENT_SLOT_FREEZE: {
6848 	        void *item_data = xge_queue_item_data(item);
6849 	        xge_hal_event_e event_type = item->event_type;
6850 	        u64 val64 = *((u64*)item_data);
6851 
6852 	        if (event_type != XGE_HAL_EVENT_SLOT_FREEZE)
6853 	            if (xge_hal_device_is_slot_freeze(hldev))
6854 	                event_type = XGE_HAL_EVENT_SLOT_FREEZE;
6855 	        if (g_xge_hal_driver->uld_callbacks.crit_err) {
6856 	            g_xge_hal_driver->uld_callbacks.crit_err(
6857 	                hldev->upper_layer_info,
6858 	                event_type,
6859 	                val64);
6860 	            /* handle one critical event per poll cycle */
6861 	            hldev->in_poll = 0;
6862 	            return;
6863 	        }
6864 	    } break;
6865 	    default: {
6866 	        xge_debug_queue(XGE_TRACE,
6867 	            "got non-HAL event %d",
6868 	            item->event_type);
6869 	    } break;
6870 	    }
6871 
6872 	    /* broadcast this event */
6873 	    if (g_xge_hal_driver->uld_callbacks.event)
6874 	        g_xge_hal_driver->uld_callbacks.event(item);
6875 	}
6876 
6877 	if (g_xge_hal_driver->uld_callbacks.before_device_poll) {
6878 	    if (g_xge_hal_driver->uld_callbacks.before_device_poll(
6879 	                     hldev) != 0) {
6880 	        hldev->in_poll = 0;
6881 	        return;
6882 	    }
6883 	}
6884 
6885 	hstatus = __hal_device_poll(hldev);
6886 	if (g_xge_hal_driver->uld_callbacks.after_device_poll)
6887 	    g_xge_hal_driver->uld_callbacks.after_device_poll(hldev);
6888 
6889 	/*
6890 	 * handle critical error right away:
6891 	 * - walk the device queue again
6892 	 * - drop non-critical events, if any
6893 	 * - look for the 1st critical
6894 	 */
6895 	if (hstatus == XGE_HAL_ERR_CRITICAL) {
6896 	        queue_has_critical_event = 1;
6897 	    goto _again;
6898 	}
6899 
6900 	hldev->in_poll = 0;
6901 }
6902 
6903 /**
6904  * xge_hal_rts_rth_init - Set enhanced mode for  RTS hashing.
6905  * @hldev: HAL device handle.
6906  *
6907  * This function is used to set the adapter to enhanced mode.
6908  *
6909  * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
6910  */
6911 void
xge_hal_rts_rth_init(xge_hal_device_t * hldev)6912 xge_hal_rts_rth_init(xge_hal_device_t *hldev)
6913 {
6914 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
6915 	u64 val64;
6916 
6917 	/*
6918 	 * Set the receive traffic steering mode from default(classic)
6919 	 * to enhanced.
6920 	 */
6921 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6922 	                  &bar0->rts_ctrl);
6923 	val64 |= XGE_HAL_RTS_CTRL_ENHANCED_MODE;
6924 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
6925 	               val64, &bar0->rts_ctrl);
6926 }
6927 
6928 /**
6929  * xge_hal_rts_rth_clr - Clear RTS hashing.
6930  * @hldev: HAL device handle.
6931  *
6932  * This function is used to clear all RTS hashing related stuff.
6933  * It brings the adapter out from enhanced mode to classic mode.
6934  * It also clears RTS_RTH_CFG register i.e clears hash type, function etc.
6935  *
6936  * See also: xge_hal_rts_rth_set(), xge_hal_rts_rth_itable_set().
6937  */
6938 void
xge_hal_rts_rth_clr(xge_hal_device_t * hldev)6939 xge_hal_rts_rth_clr(xge_hal_device_t *hldev)
6940 {
6941 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
6942 	u64 val64;
6943 
6944 	/*
6945 	 * Set the receive traffic steering mode from default(classic)
6946 	 * to enhanced.
6947 	 */
6948 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
6949 	                  &bar0->rts_ctrl);
6950 	val64 &=  ~XGE_HAL_RTS_CTRL_ENHANCED_MODE;
6951 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
6952 	               val64, &bar0->rts_ctrl);
6953 	val64 = 0;
6954 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6955 	               &bar0->rts_rth_cfg);
6956 }
6957 
6958 /**
6959  * xge_hal_rts_rth_set - Set/configure RTS hashing.
6960  * @hldev: HAL device handle.
6961  * @def_q: default queue
6962  * @hash_type: hash type i.e TcpIpV4, TcpIpV6 etc.
6963  * @bucket_size: no of least significant bits to be used for hashing.
6964  *
6965  * Used to set/configure all RTS hashing related stuff.
6966  * - set the steering mode to enhanced.
6967  * - set hash function i.e algo selection.
6968  * - set the default queue.
6969  *
6970  * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set().
6971  */
6972 void
xge_hal_rts_rth_set(xge_hal_device_t * hldev,u8 def_q,u64 hash_type,u16 bucket_size)6973 xge_hal_rts_rth_set(xge_hal_device_t *hldev, u8 def_q, u64 hash_type,
6974 	        u16 bucket_size)
6975 {
6976 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
6977 	u64 val64;
6978 
6979 	val64 = XGE_HAL_RTS_DEFAULT_Q(def_q);
6980 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6981 	               &bar0->rts_default_q);
6982 
6983 	val64 = hash_type;
6984 	val64 |= XGE_HAL_RTS_RTH_EN;
6985 	val64 |= XGE_HAL_RTS_RTH_BUCKET_SIZE(bucket_size);
6986 	val64 |= XGE_HAL_RTS_RTH_ALG_SEL_MS;
6987 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
6988 	               &bar0->rts_rth_cfg);
6989 }
6990 
6991 /**
6992  * xge_hal_rts_rth_start - Start RTS hashing.
6993  * @hldev: HAL device handle.
6994  *
6995  * Used to Start RTS hashing .
6996  *
6997  * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set(), xge_hal_rts_rth_start.
6998  */
6999 void
xge_hal_rts_rth_start(xge_hal_device_t * hldev)7000 xge_hal_rts_rth_start(xge_hal_device_t *hldev)
7001 {
7002 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
7003 	u64 val64;
7004 
7005 
7006 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
7007 	                  &bar0->rts_rth_cfg);
7008 	val64 |= XGE_HAL_RTS_RTH_EN;
7009 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7010 	               &bar0->rts_rth_cfg);
7011 }
7012 
7013 /**
7014  * xge_hal_rts_rth_stop - Stop the RTS hashing.
7015  * @hldev: HAL device handle.
7016  *
7017  * Used to Staop RTS hashing .
7018  *
7019  * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set(), xge_hal_rts_rth_start.
7020  */
7021 void
xge_hal_rts_rth_stop(xge_hal_device_t * hldev)7022 xge_hal_rts_rth_stop(xge_hal_device_t *hldev)
7023 {
7024 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
7025 	u64 val64;
7026 
7027 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
7028 	                  &bar0->rts_rth_cfg);
7029 	val64 &=  ~XGE_HAL_RTS_RTH_EN;
7030 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7031 	               &bar0->rts_rth_cfg);
7032 }
7033 
7034 /**
7035  * xge_hal_rts_rth_itable_set - Set/configure indirection table (IT).
7036  * @hldev: HAL device handle.
7037  * @itable: Pointer to the indirection table
7038  * @itable_size: no of least significant bits to be used for hashing
7039  *
7040  * Used to set/configure indirection table.
7041  * It enables the required no of entries in the IT.
7042  * It adds entries to the IT.
7043  *
7044  * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
7045  */
7046 xge_hal_status_e
xge_hal_rts_rth_itable_set(xge_hal_device_t * hldev,u8 * itable,u32 itable_size)7047 xge_hal_rts_rth_itable_set(xge_hal_device_t *hldev, u8 *itable, u32 itable_size)
7048 {
7049 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void  *)hldev->bar0;
7050 	u64 val64;
7051 	u32 idx;
7052 
7053 	for (idx = 0; idx < itable_size; idx++) {
7054 	    val64 = XGE_HAL_RTS_RTH_MAP_MEM_DATA_ENTRY_EN |
7055 	        XGE_HAL_RTS_RTH_MAP_MEM_DATA(itable[idx]);
7056 
7057 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7058 	                   &bar0->rts_rth_map_mem_data);
7059 
7060 	    /* execute */
7061 	    val64 = (XGE_HAL_RTS_RTH_MAP_MEM_CTRL_WE |
7062 	         XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE |
7063 	         XGE_HAL_RTS_RTH_MAP_MEM_CTRL_OFFSET(idx));
7064 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7065 	                   &bar0->rts_rth_map_mem_ctrl);
7066 
7067 	    /* poll until done */
7068 	    if (__hal_device_register_poll(hldev,
7069 	           &bar0->rts_rth_map_mem_ctrl, 0,
7070 	           XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE,
7071 	           XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
7072 	        /* upper layer may require to repeat */
7073 	        return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
7074 	    }
7075 	}
7076 
7077 	return XGE_HAL_OK;
7078 }
7079 
7080 
7081 /**
7082  * xge_hal_device_rts_rth_key_set - Configure 40byte secret for hash calc.
7083  *
7084  * @hldev: HAL device handle.
7085  * @KeySize: Number of 64-bit words
7086  * @Key: upto 40-byte array of 8-bit values
7087  * This function configures the 40-byte secret which is used for hash
7088  * calculation.
7089  *
7090  * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
7091  */
7092 void
xge_hal_device_rts_rth_key_set(xge_hal_device_t * hldev,u8 KeySize,u8 * Key)7093 xge_hal_device_rts_rth_key_set(xge_hal_device_t *hldev, u8 KeySize, u8 *Key)
7094 {
7095 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *) hldev->bar0;
7096 	u64 val64;
7097 	u32 entry, nreg, i;
7098 
7099 	entry = 0;
7100 	nreg = 0;
7101 
7102 	while( KeySize ) {
7103 	    val64 = 0;
7104 	    for ( i = 0; i < 8 ; i++) {
7105 	        /* Prepare 64-bit word for 'nreg' containing 8 keys. */
7106 	        if (i)
7107 	            val64 <<= 8;
7108 	        val64 |= Key[entry++];
7109 	    }
7110 
7111 	    KeySize--;
7112 
7113 	    /* temp64 = XGE_HAL_RTH_HASH_MASK_n(val64, (n<<3), (n<<3)+7);*/
7114 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7115 	                   &bar0->rts_rth_hash_mask[nreg++]);
7116 	}
7117 
7118 	while( nreg < 5 ) {
7119 	    /* Clear the rest if key is less than 40 bytes */
7120 	    val64 = 0;
7121 	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7122 	                   &bar0->rts_rth_hash_mask[nreg++]);
7123 	}
7124 }
7125 
7126 
7127 /**
7128  * xge_hal_device_is_closed - Device is closed
7129  *
7130  * @devh: HAL device handle.
7131  */
7132 int
xge_hal_device_is_closed(xge_hal_device_h devh)7133 xge_hal_device_is_closed(xge_hal_device_h devh)
7134 {
7135 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
7136 
7137 	if (xge_list_is_empty(&hldev->fifo_channels) &&
7138 	    xge_list_is_empty(&hldev->ring_channels))
7139 	    return 1;
7140 
7141 	return 0;
7142 }
7143 
7144 xge_hal_status_e
xge_hal_device_rts_section_enable(xge_hal_device_h devh,int index)7145 xge_hal_device_rts_section_enable(xge_hal_device_h devh, int index)
7146 {
7147 	u64 val64;
7148 	int section;
7149 	int max_addr = XGE_HAL_MAX_MAC_ADDRESSES;
7150 
7151 	xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
7152 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
7153 
7154 	if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
7155 	    max_addr = XGE_HAL_MAX_MAC_ADDRESSES_HERC;
7156 
7157 	if ( index >= max_addr )
7158 	    return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
7159 
7160 	/*
7161 	 * Calculate the section value
7162 	 */
7163 	section = index / 32;
7164 
7165 	    xge_debug_device(XGE_TRACE, "the Section value is %d ", section);
7166 
7167 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
7168 	            &bar0->rts_mac_cfg);
7169 	switch(section)
7170 	{
7171 	    case 0:
7172 	        val64 |=  XGE_HAL_RTS_MAC_SECT0_EN;
7173 	        break;
7174 	    case 1:
7175 	        val64 |=  XGE_HAL_RTS_MAC_SECT1_EN;
7176 	        break;
7177 	    case 2:
7178 	        val64 |=  XGE_HAL_RTS_MAC_SECT2_EN;
7179 	        break;
7180 	    case 3:
7181 	        val64 |=  XGE_HAL_RTS_MAC_SECT3_EN;
7182 	        break;
7183 	    case 4:
7184 	        val64 |=  XGE_HAL_RTS_MAC_SECT4_EN;
7185 	        break;
7186 	    case 5:
7187 	        val64 |=  XGE_HAL_RTS_MAC_SECT5_EN;
7188 	        break;
7189 	    case 6:
7190 	        val64 |=  XGE_HAL_RTS_MAC_SECT6_EN;
7191 	        break;
7192 	    case 7:
7193 	        val64 |=  XGE_HAL_RTS_MAC_SECT7_EN;
7194 	        break;
7195 	    default:
7196 	        xge_debug_device(XGE_ERR, "Invalid Section value %d "
7197 	                , section);
7198 	    }
7199 
7200 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
7201 	            val64, &bar0->rts_mac_cfg);
7202 	return XGE_HAL_OK;
7203 }
7204 
7205 
7206 /**
7207  * xge_hal_fix_rldram_ecc_error
7208  * @hldev: private member of the device structure.
7209  *
7210  * SXE-02-010. This function will turn OFF the ECC error reporting for the
7211  * interface bet'n external Micron RLDRAM II device and memory controller.
7212  * The error would have been reported in RLD_ECC_DB_ERR_L and RLD_ECC_DB_ERR_U
7213  * fields of MC_ERR_REG register. Issue reported by HP-Unix folks during the
7214  * qualification of Herc.
7215  */
7216 xge_hal_status_e
xge_hal_fix_rldram_ecc_error(xge_hal_device_t * hldev)7217 xge_hal_fix_rldram_ecc_error(xge_hal_device_t * hldev)
7218 {
7219 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
7220 	u64 val64;
7221 
7222 	// Enter Test Mode.
7223 	val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
7224 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7225 	                       &bar0->mc_rldram_test_ctrl);
7226 
7227 	// Enable fg/bg tests.
7228 	val64 = 0x0100000000000000ULL;
7229 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7230 	                       &bar0->mc_driver);
7231 
7232 	// Enable RLDRAM configuration.
7233 	val64 = 0x0000000000017B00ULL;
7234 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7235 	                       &bar0->mc_rldram_mrs);
7236 
7237 	// Enable RLDRAM queues.
7238 	val64 = 0x0000000001017B00ULL;
7239 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7240 	                       &bar0->mc_rldram_mrs);
7241 
7242 	// Setup test ranges
7243 	val64 = 0x00000000001E0100ULL;
7244 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7245 	                       &bar0->mc_rldram_test_add);
7246 
7247 	val64 = 0x00000100001F0100ULL;
7248 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7249 	                       &bar0->mc_rldram_test_add_bkg);
7250 	// Start Reads.
7251 	val64 = 0x0001000000010000ULL;
7252 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7253 	                       &bar0->mc_rldram_test_ctrl);
7254 
7255 	if (__hal_device_register_poll(hldev, &bar0->mc_rldram_test_ctrl, 1,
7256 	                           XGE_HAL_MC_RLDRAM_TEST_DONE,
7257 	                           XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK){
7258 	    return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
7259 	}
7260 
7261 	// Exit test mode
7262 	val64 = 0x0000000000000000ULL;
7263 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
7264 	                       &bar0->mc_rldram_test_ctrl);
7265 
7266 	return XGE_HAL_OK;
7267 }
7268