xref: /freebsd/sys/dev/oce/oce_mbox.c (revision e991acd5d0f60fe3c57acb452003c551194a758b)
12f345d8eSLuigi Rizzo /*-
27282444bSPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
37282444bSPedro F. Giffuni  *
4291a1934SXin LI  * Copyright (C) 2013 Emulex
52f345d8eSLuigi Rizzo  * All rights reserved.
62f345d8eSLuigi Rizzo  *
72f345d8eSLuigi Rizzo  * Redistribution and use in source and binary forms, with or without
82f345d8eSLuigi Rizzo  * modification, are permitted provided that the following conditions are met:
92f345d8eSLuigi Rizzo  *
102f345d8eSLuigi Rizzo  * 1. Redistributions of source code must retain the above copyright notice,
112f345d8eSLuigi Rizzo  *    this list of conditions and the following disclaimer.
122f345d8eSLuigi Rizzo  *
132f345d8eSLuigi Rizzo  * 2. Redistributions in binary form must reproduce the above copyright
142f345d8eSLuigi Rizzo  *    notice, this list of conditions and the following disclaimer in the
152f345d8eSLuigi Rizzo  *    documentation and/or other materials provided with the distribution.
162f345d8eSLuigi Rizzo  *
172f345d8eSLuigi Rizzo  * 3. Neither the name of the Emulex Corporation nor the names of its
182f345d8eSLuigi Rizzo  *    contributors may be used to endorse or promote products derived from
192f345d8eSLuigi Rizzo  *    this software without specific prior written permission.
202f345d8eSLuigi Rizzo  *
212f345d8eSLuigi Rizzo  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
222f345d8eSLuigi Rizzo  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
232f345d8eSLuigi Rizzo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
242f345d8eSLuigi Rizzo  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
252f345d8eSLuigi Rizzo  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
262f345d8eSLuigi Rizzo  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
272f345d8eSLuigi Rizzo  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
282f345d8eSLuigi Rizzo  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
292f345d8eSLuigi Rizzo  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
302f345d8eSLuigi Rizzo  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
312f345d8eSLuigi Rizzo  * POSSIBILITY OF SUCH DAMAGE.
322f345d8eSLuigi Rizzo  *
332f345d8eSLuigi Rizzo  * Contact Information:
342f345d8eSLuigi Rizzo  * freebsd-drivers@emulex.com
352f345d8eSLuigi Rizzo  *
362f345d8eSLuigi Rizzo  * Emulex
372f345d8eSLuigi Rizzo  * 3333 Susan Street
382f345d8eSLuigi Rizzo  * Costa Mesa, CA 92626
392f345d8eSLuigi Rizzo  */
402f345d8eSLuigi Rizzo 
412f345d8eSLuigi Rizzo 
42cdaba892SXin LI #include "oce_if.h"
432f345d8eSLuigi Rizzo 
44dced0d18SJosh Paetzel int
45dced0d18SJosh Paetzel oce_wait_ready(POCE_SOFTC sc)
46dced0d18SJosh Paetzel {
47dced0d18SJosh Paetzel #define SLIPORT_READY_TIMEOUT 30000
48dced0d18SJosh Paetzel 	uint32_t sliport_status, i;
49dced0d18SJosh Paetzel 
50dced0d18SJosh Paetzel 	if (!IS_XE201(sc))
51dced0d18SJosh Paetzel 		return (-1);
52dced0d18SJosh Paetzel 
53dced0d18SJosh Paetzel 	for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
54dced0d18SJosh Paetzel 		sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET);
55dced0d18SJosh Paetzel 		if (sliport_status & SLIPORT_STATUS_RDY_MASK)
56dced0d18SJosh Paetzel 			return 0;
57dced0d18SJosh Paetzel 
58dced0d18SJosh Paetzel 		if (sliport_status & SLIPORT_STATUS_ERR_MASK &&
59dced0d18SJosh Paetzel 			!(sliport_status & SLIPORT_STATUS_RN_MASK)) {
60dced0d18SJosh Paetzel 			device_printf(sc->dev, "Error detected in the card\n");
61dced0d18SJosh Paetzel 			return EIO;
62dced0d18SJosh Paetzel 		}
63dced0d18SJosh Paetzel 
64dced0d18SJosh Paetzel 		DELAY(1000);
65dced0d18SJosh Paetzel 	}
66dced0d18SJosh Paetzel 
67dced0d18SJosh Paetzel 	device_printf(sc->dev, "Firmware wait timed out\n");
68dced0d18SJosh Paetzel 
69dced0d18SJosh Paetzel 	return (-1);
70dced0d18SJosh Paetzel }
71dced0d18SJosh Paetzel 
722f345d8eSLuigi Rizzo /**
732f345d8eSLuigi Rizzo  * @brief Reset (firmware) common function
742f345d8eSLuigi Rizzo  * @param sc		software handle to the device
752f345d8eSLuigi Rizzo  * @returns		0 on success, ETIMEDOUT on failure
762f345d8eSLuigi Rizzo  */
772f345d8eSLuigi Rizzo int
782f345d8eSLuigi Rizzo oce_reset_fun(POCE_SOFTC sc)
792f345d8eSLuigi Rizzo {
802f345d8eSLuigi Rizzo 	struct oce_mbx *mbx;
812f345d8eSLuigi Rizzo 	struct oce_bmbx *mb;
822f345d8eSLuigi Rizzo 	struct ioctl_common_function_reset *fwcmd;
832f345d8eSLuigi Rizzo 	int rc = 0;
842f345d8eSLuigi Rizzo 
85dced0d18SJosh Paetzel 	if (IS_XE201(sc)) {
86dced0d18SJosh Paetzel 		OCE_WRITE_REG32(sc, db, SLIPORT_CONTROL_OFFSET,
87dced0d18SJosh Paetzel 					SLI_PORT_CONTROL_IP_MASK);
88dced0d18SJosh Paetzel 
89dced0d18SJosh Paetzel 		rc = oce_wait_ready(sc);
90dced0d18SJosh Paetzel 		if (rc) {
91dced0d18SJosh Paetzel 			device_printf(sc->dev, "Firmware reset Failed\n");
92dced0d18SJosh Paetzel 		}
93dced0d18SJosh Paetzel 
94dced0d18SJosh Paetzel 		return rc;
95dced0d18SJosh Paetzel 	}
96dced0d18SJosh Paetzel 
972f345d8eSLuigi Rizzo 	mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
982f345d8eSLuigi Rizzo 	mbx = &mb->mbx;
992f345d8eSLuigi Rizzo 	bzero(mbx, sizeof(struct oce_mbx));
1002f345d8eSLuigi Rizzo 
1012f345d8eSLuigi Rizzo 	fwcmd = (struct ioctl_common_function_reset *)&mbx->payload;
1022f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1032f345d8eSLuigi Rizzo 			MBX_SUBSYSTEM_COMMON,
1042f345d8eSLuigi Rizzo 			OPCODE_COMMON_FUNCTION_RESET,
1052f345d8eSLuigi Rizzo 			10,	/* MBX_TIMEOUT_SEC */
1062f345d8eSLuigi Rizzo 			sizeof(struct
1072f345d8eSLuigi Rizzo 				ioctl_common_function_reset),
1082f345d8eSLuigi Rizzo 			OCE_MBX_VER_V0);
1092f345d8eSLuigi Rizzo 
1102f345d8eSLuigi Rizzo 	mbx->u0.s.embedded = 1;
1112f345d8eSLuigi Rizzo 	mbx->payload_length =
1122f345d8eSLuigi Rizzo 		sizeof(struct ioctl_common_function_reset);
1132f345d8eSLuigi Rizzo 
1142f345d8eSLuigi Rizzo 	rc = oce_mbox_dispatch(sc, 2);
1152f345d8eSLuigi Rizzo 
1162f345d8eSLuigi Rizzo 	return rc;
1172f345d8eSLuigi Rizzo }
1182f345d8eSLuigi Rizzo 
1192f345d8eSLuigi Rizzo /**
1205bdf58e1SGordon Bergling  * @brief  		This functions tells firmware we are
1212f345d8eSLuigi Rizzo  *			done with commands.
1222f345d8eSLuigi Rizzo  * @param sc            software handle to the device
1232f345d8eSLuigi Rizzo  * @returns             0 on success, ETIMEDOUT on failure
1242f345d8eSLuigi Rizzo  */
1252f345d8eSLuigi Rizzo int
1262f345d8eSLuigi Rizzo oce_fw_clean(POCE_SOFTC sc)
1272f345d8eSLuigi Rizzo {
1282f345d8eSLuigi Rizzo 	struct oce_bmbx *mbx;
1292f345d8eSLuigi Rizzo 	uint8_t *ptr;
1302f345d8eSLuigi Rizzo 	int ret = 0;
1312f345d8eSLuigi Rizzo 
1322f345d8eSLuigi Rizzo 	mbx = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
1332f345d8eSLuigi Rizzo 	ptr = (uint8_t *) &mbx->mbx;
1342f345d8eSLuigi Rizzo 
1352f345d8eSLuigi Rizzo 	/* Endian Signature */
1362f345d8eSLuigi Rizzo 	*ptr++ = 0xff;
1372f345d8eSLuigi Rizzo 	*ptr++ = 0xaa;
1382f345d8eSLuigi Rizzo 	*ptr++ = 0xbb;
1392f345d8eSLuigi Rizzo 	*ptr++ = 0xff;
1402f345d8eSLuigi Rizzo 	*ptr++ = 0xff;
1412f345d8eSLuigi Rizzo 	*ptr++ = 0xcc;
1422f345d8eSLuigi Rizzo 	*ptr++ = 0xdd;
1432f345d8eSLuigi Rizzo 	*ptr = 0xff;
1442f345d8eSLuigi Rizzo 
1452f345d8eSLuigi Rizzo 	ret = oce_mbox_dispatch(sc, 2);
1462f345d8eSLuigi Rizzo 
1472f345d8eSLuigi Rizzo 	return ret;
1482f345d8eSLuigi Rizzo }
1492f345d8eSLuigi Rizzo 
1502f345d8eSLuigi Rizzo /**
1512f345d8eSLuigi Rizzo  * @brief Mailbox wait
1522f345d8eSLuigi Rizzo  * @param sc		software handle to the device
1532f345d8eSLuigi Rizzo  * @param tmo_sec	timeout in seconds
1542f345d8eSLuigi Rizzo  */
1552f345d8eSLuigi Rizzo static int
1562f345d8eSLuigi Rizzo oce_mbox_wait(POCE_SOFTC sc, uint32_t tmo_sec)
1572f345d8eSLuigi Rizzo {
1582f345d8eSLuigi Rizzo 	tmo_sec *= 10000;
1592f345d8eSLuigi Rizzo 	pd_mpu_mbox_db_t mbox_db;
1602f345d8eSLuigi Rizzo 
1612f345d8eSLuigi Rizzo 	for (;;) {
1622f345d8eSLuigi Rizzo 		if (tmo_sec != 0) {
1632f345d8eSLuigi Rizzo 			if (--tmo_sec == 0)
1642f345d8eSLuigi Rizzo 				break;
1652f345d8eSLuigi Rizzo 		}
1662f345d8eSLuigi Rizzo 
1672f345d8eSLuigi Rizzo 		mbox_db.dw0 = OCE_READ_REG32(sc, db, PD_MPU_MBOX_DB);
1682f345d8eSLuigi Rizzo 
1692f345d8eSLuigi Rizzo 		if (mbox_db.bits.ready)
1702f345d8eSLuigi Rizzo 			return 0;
1712f345d8eSLuigi Rizzo 
1722f345d8eSLuigi Rizzo 		DELAY(100);
1732f345d8eSLuigi Rizzo 	}
1742f345d8eSLuigi Rizzo 
1752f345d8eSLuigi Rizzo 	device_printf(sc->dev, "Mailbox timed out\n");
1762f345d8eSLuigi Rizzo 
1772f345d8eSLuigi Rizzo 	return ETIMEDOUT;
1782f345d8eSLuigi Rizzo }
1792f345d8eSLuigi Rizzo 
1802f345d8eSLuigi Rizzo /**
1812f345d8eSLuigi Rizzo  * @brief Mailbox dispatch
1822f345d8eSLuigi Rizzo  * @param sc		software handle to the device
1832f345d8eSLuigi Rizzo  * @param tmo_sec	timeout in seconds
1842f345d8eSLuigi Rizzo  */
1852f345d8eSLuigi Rizzo int
1862f345d8eSLuigi Rizzo oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec)
1872f345d8eSLuigi Rizzo {
1882f345d8eSLuigi Rizzo 	pd_mpu_mbox_db_t mbox_db;
1892f345d8eSLuigi Rizzo 	uint32_t pa;
1902f345d8eSLuigi Rizzo 	int rc;
1912f345d8eSLuigi Rizzo 
1922f345d8eSLuigi Rizzo 	oce_dma_sync(&sc->bsmbx, BUS_DMASYNC_PREWRITE);
1932f345d8eSLuigi Rizzo 	pa = (uint32_t) ((uint64_t) sc->bsmbx.paddr >> 34);
1942f345d8eSLuigi Rizzo 	bzero(&mbox_db, sizeof(pd_mpu_mbox_db_t));
1952f345d8eSLuigi Rizzo 	mbox_db.bits.ready = 0;
1962f345d8eSLuigi Rizzo 	mbox_db.bits.hi = 1;
1972f345d8eSLuigi Rizzo 	mbox_db.bits.address = pa;
1982f345d8eSLuigi Rizzo 
1992f345d8eSLuigi Rizzo 	rc = oce_mbox_wait(sc, tmo_sec);
2002f345d8eSLuigi Rizzo 	if (rc == 0) {
2012f345d8eSLuigi Rizzo 		OCE_WRITE_REG32(sc, db, PD_MPU_MBOX_DB, mbox_db.dw0);
2022f345d8eSLuigi Rizzo 
2032f345d8eSLuigi Rizzo 		pa = (uint32_t) ((uint64_t) sc->bsmbx.paddr >> 4) & 0x3fffffff;
2042f345d8eSLuigi Rizzo 		mbox_db.bits.ready = 0;
2052f345d8eSLuigi Rizzo 		mbox_db.bits.hi = 0;
2062f345d8eSLuigi Rizzo 		mbox_db.bits.address = pa;
2072f345d8eSLuigi Rizzo 
2082f345d8eSLuigi Rizzo 		rc = oce_mbox_wait(sc, tmo_sec);
2092f345d8eSLuigi Rizzo 
2102f345d8eSLuigi Rizzo 		if (rc == 0) {
2112f345d8eSLuigi Rizzo 			OCE_WRITE_REG32(sc, db, PD_MPU_MBOX_DB, mbox_db.dw0);
2122f345d8eSLuigi Rizzo 
2132f345d8eSLuigi Rizzo 			rc = oce_mbox_wait(sc, tmo_sec);
2142f345d8eSLuigi Rizzo 
2152f345d8eSLuigi Rizzo 			oce_dma_sync(&sc->bsmbx, BUS_DMASYNC_POSTWRITE);
2162f345d8eSLuigi Rizzo 		}
2172f345d8eSLuigi Rizzo 	}
2182f345d8eSLuigi Rizzo 
2192f345d8eSLuigi Rizzo 	return rc;
2202f345d8eSLuigi Rizzo }
2212f345d8eSLuigi Rizzo 
2222f345d8eSLuigi Rizzo /**
2232f345d8eSLuigi Rizzo  * @brief 		Mailbox common request header initialization
2242f345d8eSLuigi Rizzo  * @param hdr		mailbox header
2252f345d8eSLuigi Rizzo  * @param dom		domain
2262f345d8eSLuigi Rizzo  * @param port		port
2272f345d8eSLuigi Rizzo  * @param subsys	subsystem
2282f345d8eSLuigi Rizzo  * @param opcode	opcode
2292f345d8eSLuigi Rizzo  * @param timeout	timeout
2302f345d8eSLuigi Rizzo  * @param pyld_len	payload length
2312f345d8eSLuigi Rizzo  */
2322f345d8eSLuigi Rizzo void
2332f345d8eSLuigi Rizzo mbx_common_req_hdr_init(struct mbx_hdr *hdr,
2342f345d8eSLuigi Rizzo 			uint8_t dom, uint8_t port,
2352f345d8eSLuigi Rizzo 			uint8_t subsys, uint8_t opcode,
2362f345d8eSLuigi Rizzo 			uint32_t timeout, uint32_t pyld_len,
2372f345d8eSLuigi Rizzo 			uint8_t version)
2382f345d8eSLuigi Rizzo {
2392f345d8eSLuigi Rizzo 	hdr->u0.req.opcode = opcode;
2402f345d8eSLuigi Rizzo 	hdr->u0.req.subsystem = subsys;
2412f345d8eSLuigi Rizzo 	hdr->u0.req.port_number = port;
2422f345d8eSLuigi Rizzo 	hdr->u0.req.domain = dom;
2432f345d8eSLuigi Rizzo 
2442f345d8eSLuigi Rizzo 	hdr->u0.req.timeout = timeout;
2452f345d8eSLuigi Rizzo 	hdr->u0.req.request_length = pyld_len - sizeof(struct mbx_hdr);
2462f345d8eSLuigi Rizzo 	hdr->u0.req.version = version;
2472f345d8eSLuigi Rizzo }
2482f345d8eSLuigi Rizzo 
2492f345d8eSLuigi Rizzo /**
2502f345d8eSLuigi Rizzo  * @brief Function to initialize the hw with host endian information
2512f345d8eSLuigi Rizzo  * @param sc		software handle to the device
2522f345d8eSLuigi Rizzo  * @returns		0 on success, ETIMEDOUT on failure
2532f345d8eSLuigi Rizzo  */
2542f345d8eSLuigi Rizzo int
2552f345d8eSLuigi Rizzo oce_mbox_init(POCE_SOFTC sc)
2562f345d8eSLuigi Rizzo {
2572f345d8eSLuigi Rizzo 	struct oce_bmbx *mbx;
2582f345d8eSLuigi Rizzo 	uint8_t *ptr;
2592f345d8eSLuigi Rizzo 	int ret = 0;
2602f345d8eSLuigi Rizzo 
2612f345d8eSLuigi Rizzo 	if (sc->flags & OCE_FLAGS_MBOX_ENDIAN_RQD) {
2622f345d8eSLuigi Rizzo 		mbx = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
2632f345d8eSLuigi Rizzo 		ptr = (uint8_t *) &mbx->mbx;
2642f345d8eSLuigi Rizzo 
2652f345d8eSLuigi Rizzo 		/* Endian Signature */
2662f345d8eSLuigi Rizzo 		*ptr++ = 0xff;
2672f345d8eSLuigi Rizzo 		*ptr++ = 0x12;
2682f345d8eSLuigi Rizzo 		*ptr++ = 0x34;
2692f345d8eSLuigi Rizzo 		*ptr++ = 0xff;
2702f345d8eSLuigi Rizzo 		*ptr++ = 0xff;
2712f345d8eSLuigi Rizzo 		*ptr++ = 0x56;
2722f345d8eSLuigi Rizzo 		*ptr++ = 0x78;
2732f345d8eSLuigi Rizzo 		*ptr = 0xff;
2742f345d8eSLuigi Rizzo 
2752f345d8eSLuigi Rizzo 		ret = oce_mbox_dispatch(sc, 0);
2762f345d8eSLuigi Rizzo 	}
2772f345d8eSLuigi Rizzo 
2782f345d8eSLuigi Rizzo 	return ret;
2792f345d8eSLuigi Rizzo }
2802f345d8eSLuigi Rizzo 
2812f345d8eSLuigi Rizzo /**
2822f345d8eSLuigi Rizzo  * @brief 		Function to get the firmware version
2832f345d8eSLuigi Rizzo  * @param sc		software handle to the device
2842f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
2852f345d8eSLuigi Rizzo  */
2862f345d8eSLuigi Rizzo int
2872f345d8eSLuigi Rizzo oce_get_fw_version(POCE_SOFTC sc)
2882f345d8eSLuigi Rizzo {
2892f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
2902f345d8eSLuigi Rizzo 	struct mbx_get_common_fw_version *fwcmd;
2912f345d8eSLuigi Rizzo 	int ret = 0;
2922f345d8eSLuigi Rizzo 
2932f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
2942f345d8eSLuigi Rizzo 
2952f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_get_common_fw_version *)&mbx.payload;
2962f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
2972f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
2982f345d8eSLuigi Rizzo 				OPCODE_COMMON_GET_FW_VERSION,
2992f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
3002f345d8eSLuigi Rizzo 				sizeof(struct mbx_get_common_fw_version),
3012f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
3022f345d8eSLuigi Rizzo 
3032f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
3042f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_get_common_fw_version);
3052f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
3062f345d8eSLuigi Rizzo 
3072f345d8eSLuigi Rizzo 	ret = oce_mbox_post(sc, &mbx, NULL);
308cdaba892SXin LI 	if (!ret)
309cdaba892SXin LI                 ret = fwcmd->hdr.u0.rsp.status;
310cdaba892SXin LI 	if (ret) {
3115fbb6830SXin LI 		device_printf(sc->dev,
3125fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
3135fbb6830SXin LI 			      __FUNCTION__, ret,
3145fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
315cdaba892SXin LI 		goto error;
316cdaba892SXin LI 	}
3172f345d8eSLuigi Rizzo 
3182f345d8eSLuigi Rizzo 	bcopy(fwcmd->params.rsp.fw_ver_str, sc->fw_version, 32);
319cdaba892SXin LI error:
320cdaba892SXin LI 	return ret;
3212f345d8eSLuigi Rizzo }
3222f345d8eSLuigi Rizzo 
3232f345d8eSLuigi Rizzo /**
3249bd3250aSLuigi Rizzo  * @brief	Firmware will send gracious notifications during
3259bd3250aSLuigi Rizzo  *		attach only after sending first mcc commnad. We
3269bd3250aSLuigi Rizzo  *		use MCC queue only for getting async and mailbox
3279bd3250aSLuigi Rizzo  *		for sending cmds. So to get gracious notifications
3289bd3250aSLuigi Rizzo  *		atleast send one dummy command on mcc.
3299bd3250aSLuigi Rizzo  */
3309bd3250aSLuigi Rizzo int
3319bd3250aSLuigi Rizzo oce_first_mcc_cmd(POCE_SOFTC sc)
3329bd3250aSLuigi Rizzo {
3339bd3250aSLuigi Rizzo 	struct oce_mbx *mbx;
3349bd3250aSLuigi Rizzo 	struct oce_mq *mq = sc->mq;
3359bd3250aSLuigi Rizzo 	struct mbx_get_common_fw_version *fwcmd;
3369bd3250aSLuigi Rizzo 	uint32_t reg_value;
3379bd3250aSLuigi Rizzo 
3389bd3250aSLuigi Rizzo 	mbx = RING_GET_PRODUCER_ITEM_VA(mq->ring, struct oce_mbx);
3399bd3250aSLuigi Rizzo 	bzero(mbx, sizeof(struct oce_mbx));
3409bd3250aSLuigi Rizzo 
3419bd3250aSLuigi Rizzo 	fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
3429bd3250aSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
3439bd3250aSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
3449bd3250aSLuigi Rizzo 				OPCODE_COMMON_GET_FW_VERSION,
3459bd3250aSLuigi Rizzo 				MBX_TIMEOUT_SEC,
3469bd3250aSLuigi Rizzo 				sizeof(struct mbx_get_common_fw_version),
3479bd3250aSLuigi Rizzo 				OCE_MBX_VER_V0);
3489bd3250aSLuigi Rizzo 	mbx->u0.s.embedded = 1;
3499bd3250aSLuigi Rizzo 	mbx->payload_length = sizeof(struct mbx_get_common_fw_version);
3509bd3250aSLuigi Rizzo 	bus_dmamap_sync(mq->ring->dma.tag, mq->ring->dma.map,
3519bd3250aSLuigi Rizzo 				BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3529bd3250aSLuigi Rizzo 	RING_PUT(mq->ring, 1);
3539bd3250aSLuigi Rizzo 	reg_value = (1 << 16) | mq->mq_id;
3549bd3250aSLuigi Rizzo 	OCE_WRITE_REG32(sc, db, PD_MQ_DB, reg_value);
3559bd3250aSLuigi Rizzo 
3569bd3250aSLuigi Rizzo 	return 0;
3579bd3250aSLuigi Rizzo }
3589bd3250aSLuigi Rizzo 
3599bd3250aSLuigi Rizzo /**
3602f345d8eSLuigi Rizzo  * @brief		Function to post a MBX to the mbox
3612f345d8eSLuigi Rizzo  * @param sc		software handle to the device
3622f345d8eSLuigi Rizzo  * @param mbx 		pointer to the MBX to send
3632f345d8eSLuigi Rizzo  * @param mbxctx	pointer to the mbx context structure
3642f345d8eSLuigi Rizzo  * @returns		0 on success, error on failure
3652f345d8eSLuigi Rizzo  */
3662f345d8eSLuigi Rizzo int
3672f345d8eSLuigi Rizzo oce_mbox_post(POCE_SOFTC sc, struct oce_mbx *mbx, struct oce_mbx_ctx *mbxctx)
3682f345d8eSLuigi Rizzo {
3692f345d8eSLuigi Rizzo 	struct oce_mbx *mb_mbx = NULL;
3702f345d8eSLuigi Rizzo 	struct oce_mq_cqe *mb_cqe = NULL;
3712f345d8eSLuigi Rizzo 	struct oce_bmbx *mb = NULL;
3722f345d8eSLuigi Rizzo 	int rc = 0;
3732f345d8eSLuigi Rizzo 	uint32_t tmo = 0;
3742f345d8eSLuigi Rizzo 	uint32_t cstatus = 0;
3752f345d8eSLuigi Rizzo 
3762f345d8eSLuigi Rizzo 	LOCK(&sc->bmbx_lock);
3772f345d8eSLuigi Rizzo 
3782f345d8eSLuigi Rizzo 	mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
3792f345d8eSLuigi Rizzo 	mb_mbx = &mb->mbx;
3802f345d8eSLuigi Rizzo 
3812f345d8eSLuigi Rizzo 	/* get the tmo */
3822f345d8eSLuigi Rizzo 	tmo = mbx->tag[0];
3832f345d8eSLuigi Rizzo 	mbx->tag[0] = 0;
3842f345d8eSLuigi Rizzo 
3852f345d8eSLuigi Rizzo 	/* copy mbx into mbox */
3862f345d8eSLuigi Rizzo 	bcopy(mbx, mb_mbx, sizeof(struct oce_mbx));
3872f345d8eSLuigi Rizzo 
3882f345d8eSLuigi Rizzo 	/* now dispatch */
3892f345d8eSLuigi Rizzo 	rc = oce_mbox_dispatch(sc, tmo);
3902f345d8eSLuigi Rizzo 	if (rc == 0) {
3912f345d8eSLuigi Rizzo 		/*
3922f345d8eSLuigi Rizzo 		 * the command completed successfully. Now get the
3932f345d8eSLuigi Rizzo 		 * completion queue entry
3942f345d8eSLuigi Rizzo 		 */
3952f345d8eSLuigi Rizzo 		mb_cqe = &mb->cqe;
3962f345d8eSLuigi Rizzo 		DW_SWAP(u32ptr(&mb_cqe->u0.dw[0]), sizeof(struct oce_mq_cqe));
3972f345d8eSLuigi Rizzo 
3982f345d8eSLuigi Rizzo 		/* copy mbox mbx back */
3992f345d8eSLuigi Rizzo 		bcopy(mb_mbx, mbx, sizeof(struct oce_mbx));
4002f345d8eSLuigi Rizzo 
4012f345d8eSLuigi Rizzo 		/* pick up the mailbox status */
4022f345d8eSLuigi Rizzo 		cstatus = mb_cqe->u0.s.completion_status;
4032f345d8eSLuigi Rizzo 
4042f345d8eSLuigi Rizzo 		/*
4052f345d8eSLuigi Rizzo 		 * store the mbx context in the cqe tag section so that
4062f345d8eSLuigi Rizzo 		 * the upper layer handling the cqe can associate the mbx
4072f345d8eSLuigi Rizzo 		 * with the response
4082f345d8eSLuigi Rizzo 		 */
4092f345d8eSLuigi Rizzo 		if (cstatus == 0 && mbxctx) {
4102f345d8eSLuigi Rizzo 			/* save context */
4112f345d8eSLuigi Rizzo 			mbxctx->mbx = mb_mbx;
4122f345d8eSLuigi Rizzo 			bcopy(&mbxctx, mb_cqe->u0.s.mq_tag,
4132f345d8eSLuigi Rizzo 				sizeof(struct oce_mbx_ctx *));
4142f345d8eSLuigi Rizzo 		}
4152f345d8eSLuigi Rizzo 	}
4162f345d8eSLuigi Rizzo 
4172f345d8eSLuigi Rizzo 	UNLOCK(&sc->bmbx_lock);
4182f345d8eSLuigi Rizzo 
4192f345d8eSLuigi Rizzo 	return rc;
4202f345d8eSLuigi Rizzo }
4212f345d8eSLuigi Rizzo 
4222f345d8eSLuigi Rizzo /**
4232f345d8eSLuigi Rizzo  * @brief Function to read the mac address associated with an interface
4242f345d8eSLuigi Rizzo  * @param sc		software handle to the device
4252f345d8eSLuigi Rizzo  * @param if_id 	interface id to read the address from
4262f345d8eSLuigi Rizzo  * @param perm 		set to 1 if reading the factory mac address.
4272f345d8eSLuigi Rizzo  *			In this case if_id is ignored
4282f345d8eSLuigi Rizzo  * @param type 		type of the mac address, whether network or storage
4292f345d8eSLuigi Rizzo  * @param[out] mac 	[OUTPUT] pointer to a buffer containing the
4302f345d8eSLuigi Rizzo  *			mac address when the command succeeds.
4312f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
4322f345d8eSLuigi Rizzo  */
4332f345d8eSLuigi Rizzo int
4342f345d8eSLuigi Rizzo oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id,
4352f345d8eSLuigi Rizzo 		uint8_t perm, uint8_t type, struct mac_address_format *mac)
4362f345d8eSLuigi Rizzo {
4372f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
4382f345d8eSLuigi Rizzo 	struct mbx_query_common_iface_mac *fwcmd;
4392f345d8eSLuigi Rizzo 	int ret = 0;
4402f345d8eSLuigi Rizzo 
4412f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
4422f345d8eSLuigi Rizzo 
4432f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_query_common_iface_mac *)&mbx.payload;
4442f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4452f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
4462f345d8eSLuigi Rizzo 				OPCODE_COMMON_QUERY_IFACE_MAC,
4472f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
4482f345d8eSLuigi Rizzo 				sizeof(struct mbx_query_common_iface_mac),
4492f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
4502f345d8eSLuigi Rizzo 
4512f345d8eSLuigi Rizzo 	fwcmd->params.req.permanent = perm;
4522f345d8eSLuigi Rizzo 	if (!perm)
4532f345d8eSLuigi Rizzo 		fwcmd->params.req.if_id = (uint16_t) if_id;
4542f345d8eSLuigi Rizzo 	else
4552f345d8eSLuigi Rizzo 		fwcmd->params.req.if_id = 0;
4562f345d8eSLuigi Rizzo 
4572f345d8eSLuigi Rizzo 	fwcmd->params.req.type = type;
4582f345d8eSLuigi Rizzo 
4592f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
4602f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_query_common_iface_mac);
4612f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
4622f345d8eSLuigi Rizzo 
4632f345d8eSLuigi Rizzo 	ret = oce_mbox_post(sc, &mbx, NULL);
464cdaba892SXin LI 	if (!ret)
465cdaba892SXin LI                 ret = fwcmd->hdr.u0.rsp.status;
466cdaba892SXin LI 	if (ret) {
4675fbb6830SXin LI 		device_printf(sc->dev,
4685fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
4695fbb6830SXin LI 			      __FUNCTION__, ret,
4705fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
471cdaba892SXin LI 		goto error;
472cdaba892SXin LI 	}
4732f345d8eSLuigi Rizzo 
474*e991acd5SGordon Bergling 	/* copy the mac address in the output parameter */
4752f345d8eSLuigi Rizzo 	mac->size_of_struct = fwcmd->params.rsp.mac.size_of_struct;
4762f345d8eSLuigi Rizzo 	bcopy(&fwcmd->params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
4772f345d8eSLuigi Rizzo 		mac->size_of_struct);
478cdaba892SXin LI error:
479cdaba892SXin LI 	return ret;
4802f345d8eSLuigi Rizzo }
4812f345d8eSLuigi Rizzo 
4822f345d8eSLuigi Rizzo /**
4832f345d8eSLuigi Rizzo  * @brief Function to query the fw attributes from the hw
4842f345d8eSLuigi Rizzo  * @param sc		software handle to the device
4852f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
4862f345d8eSLuigi Rizzo  */
4872f345d8eSLuigi Rizzo int
4882f345d8eSLuigi Rizzo oce_get_fw_config(POCE_SOFTC sc)
4892f345d8eSLuigi Rizzo {
4902f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
4912f345d8eSLuigi Rizzo 	struct mbx_common_query_fw_config *fwcmd;
4922f345d8eSLuigi Rizzo 	int ret = 0;
4932f345d8eSLuigi Rizzo 
4942f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
4952f345d8eSLuigi Rizzo 
4962f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_common_query_fw_config *)&mbx.payload;
4972f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
4982f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
4992f345d8eSLuigi Rizzo 				OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
5002f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
5012f345d8eSLuigi Rizzo 				sizeof(struct mbx_common_query_fw_config),
5022f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
5032f345d8eSLuigi Rizzo 
5042f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
5052f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_common_query_fw_config);
5062f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
5072f345d8eSLuigi Rizzo 
5082f345d8eSLuigi Rizzo 	ret = oce_mbox_post(sc, &mbx, NULL);
509cdaba892SXin LI 	if (!ret)
510cdaba892SXin LI                 ret = fwcmd->hdr.u0.rsp.status;
511cdaba892SXin LI 	if (ret) {
5125fbb6830SXin LI 		device_printf(sc->dev,
5135fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
5145fbb6830SXin LI 			      __FUNCTION__, ret,
5155fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
516cdaba892SXin LI 		goto error;
517cdaba892SXin LI 	}
5182f345d8eSLuigi Rizzo 
5192f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config));
5202f345d8eSLuigi Rizzo 
5215fbb6830SXin LI 	sc->config_number = HOST_32(fwcmd->params.rsp.config_number);
5225fbb6830SXin LI 	sc->asic_revision = HOST_32(fwcmd->params.rsp.asic_revision);
5235fbb6830SXin LI 	sc->port_id	  = HOST_32(fwcmd->params.rsp.port_id);
5245fbb6830SXin LI 	sc->function_mode = HOST_32(fwcmd->params.rsp.function_mode);
525c2625e6eSJosh Paetzel 	if ((sc->function_mode & (ULP_NIC_MODE | ULP_RDMA_MODE)) ==
526c2625e6eSJosh Paetzel 	    (ULP_NIC_MODE | ULP_RDMA_MODE)) {
527c2625e6eSJosh Paetzel 	  sc->rdma_flags = OCE_RDMA_FLAG_SUPPORTED;
528c2625e6eSJosh Paetzel 	}
5295fbb6830SXin LI 	sc->function_caps = HOST_32(fwcmd->params.rsp.function_caps);
5302f345d8eSLuigi Rizzo 
5312f345d8eSLuigi Rizzo 	if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) {
5325fbb6830SXin LI 		sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[0].nic_wq_tot);
5335fbb6830SXin LI 		sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[0].lro_rqid_tot);
5342f345d8eSLuigi Rizzo 	} else {
5355fbb6830SXin LI 		sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[1].nic_wq_tot);
5365fbb6830SXin LI 		sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[1].lro_rqid_tot);
5372f345d8eSLuigi Rizzo 	}
5382f345d8eSLuigi Rizzo 
539cdaba892SXin LI error:
540cdaba892SXin LI 	return ret;
5412f345d8eSLuigi Rizzo 
5422f345d8eSLuigi Rizzo }
5432f345d8eSLuigi Rizzo 
5442f345d8eSLuigi Rizzo /**
5452f345d8eSLuigi Rizzo  *
5462f345d8eSLuigi Rizzo  * @brief function to create a device interface
5472f345d8eSLuigi Rizzo  * @param sc		software handle to the device
5482f345d8eSLuigi Rizzo  * @param cap_flags	capability flags
5492f345d8eSLuigi Rizzo  * @param en_flags	enable capability flags
5502f345d8eSLuigi Rizzo  * @param vlan_tag	optional vlan tag to associate with the if
5512f345d8eSLuigi Rizzo  * @param mac_addr	pointer to a buffer containing the mac address
5522f345d8eSLuigi Rizzo  * @param[out] if_id	[OUTPUT] pointer to an integer to hold the ID of the
5532f345d8eSLuigi Rizzo  interface created
5542f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
5552f345d8eSLuigi Rizzo  */
5562f345d8eSLuigi Rizzo int
5572f345d8eSLuigi Rizzo oce_if_create(POCE_SOFTC sc,
5582f345d8eSLuigi Rizzo 		uint32_t cap_flags,
5592f345d8eSLuigi Rizzo 		uint32_t en_flags,
5602f345d8eSLuigi Rizzo 		uint16_t vlan_tag,
5612f345d8eSLuigi Rizzo 		uint8_t *mac_addr,
5622f345d8eSLuigi Rizzo 		uint32_t *if_id)
5632f345d8eSLuigi Rizzo {
5642f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
5652f345d8eSLuigi Rizzo 	struct mbx_create_common_iface *fwcmd;
5662f345d8eSLuigi Rizzo 	int rc = 0;
5672f345d8eSLuigi Rizzo 
5682f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
5692f345d8eSLuigi Rizzo 
5702f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_create_common_iface *)&mbx.payload;
5712f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
5722f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
5732f345d8eSLuigi Rizzo 				OPCODE_COMMON_CREATE_IFACE,
5742f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
5752f345d8eSLuigi Rizzo 				sizeof(struct mbx_create_common_iface),
5762f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
5772f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&fwcmd->hdr), sizeof(struct mbx_hdr));
5782f345d8eSLuigi Rizzo 
5792f345d8eSLuigi Rizzo 	fwcmd->params.req.version = 0;
5802f345d8eSLuigi Rizzo 	fwcmd->params.req.cap_flags = LE_32(cap_flags);
5812f345d8eSLuigi Rizzo 	fwcmd->params.req.enable_flags = LE_32(en_flags);
5822f345d8eSLuigi Rizzo 	if (mac_addr != NULL) {
5832f345d8eSLuigi Rizzo 		bcopy(mac_addr, &fwcmd->params.req.mac_addr[0], 6);
5842f345d8eSLuigi Rizzo 		fwcmd->params.req.vlan_tag.u0.normal.vtag = LE_16(vlan_tag);
5852f345d8eSLuigi Rizzo 		fwcmd->params.req.mac_invalid = 0;
5862f345d8eSLuigi Rizzo 	} else {
5872f345d8eSLuigi Rizzo 		fwcmd->params.req.mac_invalid = 1;
5882f345d8eSLuigi Rizzo 	}
5892f345d8eSLuigi Rizzo 
5902f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
5912f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_create_common_iface);
5922f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
5932f345d8eSLuigi Rizzo 
5942f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
595cdaba892SXin LI 	if (!rc)
596cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
597cdaba892SXin LI 	if (rc) {
5985fbb6830SXin LI 		device_printf(sc->dev,
5995fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
6005fbb6830SXin LI 			      __FUNCTION__, rc,
6015fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
602cdaba892SXin LI 		goto error;
603cdaba892SXin LI 	}
6042f345d8eSLuigi Rizzo 
6055fbb6830SXin LI 	*if_id = HOST_32(fwcmd->params.rsp.if_id);
6062f345d8eSLuigi Rizzo 
6072f345d8eSLuigi Rizzo 	if (mac_addr != NULL)
6085fbb6830SXin LI 		sc->pmac_id = HOST_32(fwcmd->params.rsp.pmac_id);
609cdaba892SXin LI error:
610cdaba892SXin LI 	return rc;
6112f345d8eSLuigi Rizzo }
6122f345d8eSLuigi Rizzo 
6132f345d8eSLuigi Rizzo /**
6142f345d8eSLuigi Rizzo  * @brief		Function to delete an interface
6152f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
6162f345d8eSLuigi Rizzo  * @param if_id		ID of the interface to delete
6172f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
6182f345d8eSLuigi Rizzo  */
6192f345d8eSLuigi Rizzo int
6202f345d8eSLuigi Rizzo oce_if_del(POCE_SOFTC sc, uint32_t if_id)
6212f345d8eSLuigi Rizzo {
6222f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
6232f345d8eSLuigi Rizzo 	struct mbx_destroy_common_iface *fwcmd;
6242f345d8eSLuigi Rizzo 	int rc = 0;
6252f345d8eSLuigi Rizzo 
6262f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
6272f345d8eSLuigi Rizzo 
6282f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_destroy_common_iface *)&mbx.payload;
6292f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
6302f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
6312f345d8eSLuigi Rizzo 				OPCODE_COMMON_DESTROY_IFACE,
6322f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
6332f345d8eSLuigi Rizzo 				sizeof(struct mbx_destroy_common_iface),
6342f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
6352f345d8eSLuigi Rizzo 
6362f345d8eSLuigi Rizzo 	fwcmd->params.req.if_id = if_id;
6372f345d8eSLuigi Rizzo 
6382f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
6392f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_destroy_common_iface);
6402f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
6412f345d8eSLuigi Rizzo 
6422f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
643cdaba892SXin LI 	if (!rc)
644cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
645cdaba892SXin LI 	if (rc)
6465fbb6830SXin LI 		device_printf(sc->dev,
6475fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
6485fbb6830SXin LI 			      __FUNCTION__, rc,
6495fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
6502f345d8eSLuigi Rizzo 	return rc;
6512f345d8eSLuigi Rizzo }
6522f345d8eSLuigi Rizzo 
6532f345d8eSLuigi Rizzo /**
6542f345d8eSLuigi Rizzo  * @brief Function to send the mbx command to configure vlan
6552f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
6562f345d8eSLuigi Rizzo  * @param if_id 	interface identifier index
6572f345d8eSLuigi Rizzo  * @param vtag_arr	array of vlan tags
6582f345d8eSLuigi Rizzo  * @param vtag_cnt	number of elements in array
6592f345d8eSLuigi Rizzo  * @param untagged	boolean TRUE/FLASE
6602f345d8eSLuigi Rizzo  * @param enable_promisc flag to enable/disable VLAN promiscuous mode
6612f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
6622f345d8eSLuigi Rizzo  */
6632f345d8eSLuigi Rizzo int
6642f345d8eSLuigi Rizzo oce_config_vlan(POCE_SOFTC sc,
6652f345d8eSLuigi Rizzo 		uint32_t if_id,
6662f345d8eSLuigi Rizzo 		struct normal_vlan *vtag_arr,
6672f345d8eSLuigi Rizzo 		uint8_t vtag_cnt, uint32_t untagged, uint32_t enable_promisc)
6682f345d8eSLuigi Rizzo {
6692f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
6702f345d8eSLuigi Rizzo 	struct mbx_common_config_vlan *fwcmd;
6715fbb6830SXin LI 	int rc = 0;
6725fbb6830SXin LI 
6735fbb6830SXin LI 	if (sc->vlans_added > sc->max_vlans)
6745fbb6830SXin LI 		goto vlan_promisc;
6752f345d8eSLuigi Rizzo 
6762f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
6772f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_common_config_vlan *)&mbx.payload;
6782f345d8eSLuigi Rizzo 
6792f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
6802f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
6812f345d8eSLuigi Rizzo 				OPCODE_COMMON_CONFIG_IFACE_VLAN,
6822f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
6832f345d8eSLuigi Rizzo 				sizeof(struct mbx_common_config_vlan),
6842f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
6852f345d8eSLuigi Rizzo 
6862f345d8eSLuigi Rizzo 	fwcmd->params.req.if_id = (uint8_t) if_id;
6872f345d8eSLuigi Rizzo 	fwcmd->params.req.promisc = (uint8_t) enable_promisc;
6882f345d8eSLuigi Rizzo 	fwcmd->params.req.untagged = (uint8_t) untagged;
6892f345d8eSLuigi Rizzo 	fwcmd->params.req.num_vlans = vtag_cnt;
6902f345d8eSLuigi Rizzo 
6912f345d8eSLuigi Rizzo 	if (!enable_promisc) {
6922f345d8eSLuigi Rizzo 		bcopy(vtag_arr, fwcmd->params.req.tags.normal_vlans,
6932f345d8eSLuigi Rizzo 			vtag_cnt * sizeof(struct normal_vlan));
6942f345d8eSLuigi Rizzo 	}
6952f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
6962f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_common_config_vlan);
6972f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
6982f345d8eSLuigi Rizzo 
6992f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
700cdaba892SXin LI 	if (!rc)
701cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
702cdaba892SXin LI 	if (rc)
7035fbb6830SXin LI 		device_printf(sc->dev,
7045fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
7055fbb6830SXin LI 			      __FUNCTION__, rc,
7065fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
7075fbb6830SXin LI 
7085fbb6830SXin LI 	goto done;
7095fbb6830SXin LI 
7105fbb6830SXin LI vlan_promisc:
7115fbb6830SXin LI 	/* Enable Vlan Promis */
7125fbb6830SXin LI 	oce_rxf_set_promiscuous(sc, (1 << 1));
7135fbb6830SXin LI 	device_printf(sc->dev,"Enabling Vlan Promisc Mode\n");
7145fbb6830SXin LI done:
7155fbb6830SXin LI 	return rc;
7162f345d8eSLuigi Rizzo 
7172f345d8eSLuigi Rizzo }
7182f345d8eSLuigi Rizzo 
7192f345d8eSLuigi Rizzo /**
7202f345d8eSLuigi Rizzo  * @brief Function to set flow control capability in the hardware
7212f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
7222f345d8eSLuigi Rizzo  * @param flow_control	flow control flags to set
7232f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
7242f345d8eSLuigi Rizzo  */
7252f345d8eSLuigi Rizzo int
7262f345d8eSLuigi Rizzo oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control)
7272f345d8eSLuigi Rizzo {
7282f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
7292f345d8eSLuigi Rizzo 	struct mbx_common_get_set_flow_control *fwcmd =
7302f345d8eSLuigi Rizzo 		(struct mbx_common_get_set_flow_control *)&mbx.payload;
7312f345d8eSLuigi Rizzo 	int rc;
7322f345d8eSLuigi Rizzo 
7332f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
7342f345d8eSLuigi Rizzo 
7352f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
7362f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
7372f345d8eSLuigi Rizzo 				OPCODE_COMMON_SET_FLOW_CONTROL,
7382f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
7392f345d8eSLuigi Rizzo 				sizeof(struct mbx_common_get_set_flow_control),
7402f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
7412f345d8eSLuigi Rizzo 
7422f345d8eSLuigi Rizzo 	if (flow_control & OCE_FC_TX)
7432f345d8eSLuigi Rizzo 		fwcmd->tx_flow_control = 1;
7442f345d8eSLuigi Rizzo 
7452f345d8eSLuigi Rizzo 	if (flow_control & OCE_FC_RX)
7462f345d8eSLuigi Rizzo 		fwcmd->rx_flow_control = 1;
7472f345d8eSLuigi Rizzo 
7482f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
7492f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_common_get_set_flow_control);
7502f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
7512f345d8eSLuigi Rizzo 
7522f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
753cdaba892SXin LI 	if (!rc)
754cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
755cdaba892SXin LI 	if (rc)
7565fbb6830SXin LI 		device_printf(sc->dev,
7575fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
7585fbb6830SXin LI 			      __FUNCTION__, rc,
7595fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
7602f345d8eSLuigi Rizzo 	return rc;
7612f345d8eSLuigi Rizzo }
7622f345d8eSLuigi Rizzo 
7632f345d8eSLuigi Rizzo /**
7642f345d8eSLuigi Rizzo  * @brief Initialize the RSS CPU indirection table
7652f345d8eSLuigi Rizzo  *
7662f345d8eSLuigi Rizzo  * The table is used to choose the queue to place the incomming packets.
7672f345d8eSLuigi Rizzo  * Incomming packets are hashed.  The lowest bits in the hash result
7682f345d8eSLuigi Rizzo  * are used as the index into the CPU indirection table.
7692f345d8eSLuigi Rizzo  * Each entry in the table contains the RSS CPU-ID returned by the NIC
7702f345d8eSLuigi Rizzo  * create.  Based on the CPU ID, the receive completion is routed to
7712f345d8eSLuigi Rizzo  * the corresponding RSS CQs.  (Non-RSS packets are always completed
7722f345d8eSLuigi Rizzo  * on the default (0) CQ).
7732f345d8eSLuigi Rizzo  *
7742f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
7752f345d8eSLuigi Rizzo  * @param *fwcmd	pointer to the rss mbox command
7762f345d8eSLuigi Rizzo  * @returns		none
7772f345d8eSLuigi Rizzo  */
7782f345d8eSLuigi Rizzo static int
7792f345d8eSLuigi Rizzo oce_rss_itbl_init(POCE_SOFTC sc, struct mbx_config_nic_rss *fwcmd)
7802f345d8eSLuigi Rizzo {
7812f345d8eSLuigi Rizzo 	int i = 0, j = 0, rc = 0;
7822f345d8eSLuigi Rizzo 	uint8_t *tbl = fwcmd->params.req.cputable;
783291a1934SXin LI 	struct oce_rq *rq = NULL;
7842f345d8eSLuigi Rizzo 
785291a1934SXin LI 	for (j = 0; j < INDIRECTION_TABLE_ENTRIES ; j += (sc->nrqs - 1)) {
786291a1934SXin LI 		for_all_rss_queues(sc, rq, i) {
787291a1934SXin LI 			if ((j + i) >= INDIRECTION_TABLE_ENTRIES)
788291a1934SXin LI 				break;
789291a1934SXin LI 			tbl[j + i] = rq->rss_cpuid;
7902f345d8eSLuigi Rizzo 		}
7912f345d8eSLuigi Rizzo 	}
7922f345d8eSLuigi Rizzo 	if (i == 0) {
7932f345d8eSLuigi Rizzo 		device_printf(sc->dev, "error: Invalid number of RSS RQ's\n");
7942f345d8eSLuigi Rizzo 		rc = ENXIO;
7952f345d8eSLuigi Rizzo 
7962f345d8eSLuigi Rizzo 	}
7972f345d8eSLuigi Rizzo 
7982f345d8eSLuigi Rizzo 	/* fill log2 value indicating the size of the CPU table */
7992f345d8eSLuigi Rizzo 	if (rc == 0)
800c2625e6eSJosh Paetzel 		fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(INDIRECTION_TABLE_ENTRIES));
8012f345d8eSLuigi Rizzo 
8022f345d8eSLuigi Rizzo 	return rc;
8032f345d8eSLuigi Rizzo }
8042f345d8eSLuigi Rizzo 
8052f345d8eSLuigi Rizzo /**
8062f345d8eSLuigi Rizzo  * @brief Function to set flow control capability in the hardware
8072f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
8082f345d8eSLuigi Rizzo  * @param if_id 	interface id to read the address from
8092f345d8eSLuigi Rizzo  * @param enable_rss	0=disable, RSS_ENABLE_xxx flags otherwise
8102f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
8112f345d8eSLuigi Rizzo  */
8122f345d8eSLuigi Rizzo int
8132f345d8eSLuigi Rizzo oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
8142f345d8eSLuigi Rizzo {
8152f345d8eSLuigi Rizzo 	int rc;
8162f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
8172f345d8eSLuigi Rizzo 	struct mbx_config_nic_rss *fwcmd =
8182f345d8eSLuigi Rizzo 				(struct mbx_config_nic_rss *)&mbx.payload;
819cdaba892SXin LI 	int version;
8202f345d8eSLuigi Rizzo 
8212f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
8222f345d8eSLuigi Rizzo 
823291a1934SXin LI 	if (IS_XE201(sc) || IS_SH(sc)) {
824cdaba892SXin LI 		version = OCE_MBX_VER_V1;
825cdaba892SXin LI 		fwcmd->params.req.enable_rss = RSS_ENABLE_UDP_IPV4 |
826cdaba892SXin LI 					       RSS_ENABLE_UDP_IPV6;
827cdaba892SXin LI 	} else
828cdaba892SXin LI 		version = OCE_MBX_VER_V0;
829cdaba892SXin LI 
8302f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
8312f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_NIC,
8322f345d8eSLuigi Rizzo 				NIC_CONFIG_RSS,
8332f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
8342f345d8eSLuigi Rizzo 				sizeof(struct mbx_config_nic_rss),
835cdaba892SXin LI 				version);
8362f345d8eSLuigi Rizzo 	if (enable_rss)
837cdaba892SXin LI 		fwcmd->params.req.enable_rss |= (RSS_ENABLE_IPV4 |
8382f345d8eSLuigi Rizzo 					         RSS_ENABLE_TCP_IPV4 |
8392f345d8eSLuigi Rizzo 						 RSS_ENABLE_IPV6 |
8402f345d8eSLuigi Rizzo 						 RSS_ENABLE_TCP_IPV6);
841c2625e6eSJosh Paetzel 
842c2625e6eSJosh Paetzel 	if(!sc->enable_hwlro)
8432f345d8eSLuigi Rizzo 		fwcmd->params.req.flush = OCE_FLUSH;
844c2625e6eSJosh Paetzel 	else
845c2625e6eSJosh Paetzel 		fwcmd->params.req.flush = 0;
846c2625e6eSJosh Paetzel 
8472f345d8eSLuigi Rizzo 	fwcmd->params.req.if_id = LE_32(if_id);
8482f345d8eSLuigi Rizzo 
8492f345d8eSLuigi Rizzo 	read_random(fwcmd->params.req.hash, sizeof(fwcmd->params.req.hash));
8502f345d8eSLuigi Rizzo 
8512f345d8eSLuigi Rizzo 	rc = oce_rss_itbl_init(sc, fwcmd);
8522f345d8eSLuigi Rizzo 	if (rc == 0) {
8532f345d8eSLuigi Rizzo 		mbx.u0.s.embedded = 1;
8542f345d8eSLuigi Rizzo 		mbx.payload_length = sizeof(struct mbx_config_nic_rss);
8552f345d8eSLuigi Rizzo 		DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
8562f345d8eSLuigi Rizzo 
8572f345d8eSLuigi Rizzo 		rc = oce_mbox_post(sc, &mbx, NULL);
858cdaba892SXin LI 		if (!rc)
859cdaba892SXin LI                 	rc = fwcmd->hdr.u0.rsp.status;
860cdaba892SXin LI 		if (rc)
8615fbb6830SXin LI 		device_printf(sc->dev,
8625fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
8635fbb6830SXin LI 			      __FUNCTION__, rc,
8645fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
8652f345d8eSLuigi Rizzo 	}
8662f345d8eSLuigi Rizzo 	return rc;
8672f345d8eSLuigi Rizzo }
8682f345d8eSLuigi Rizzo 
8692f345d8eSLuigi Rizzo /**
8702f345d8eSLuigi Rizzo  * @brief 		RXF function to enable/disable device promiscuous mode
8712f345d8eSLuigi Rizzo  * @param sc		software handle to the device
8722f345d8eSLuigi Rizzo  * @param enable	enable/disable flag
8732f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
8742f345d8eSLuigi Rizzo  * @note
8752f345d8eSLuigi Rizzo  *	The NIC_CONFIG_PROMISCUOUS command deprecated for Lancer.
8762f345d8eSLuigi Rizzo  *	This function uses the COMMON_SET_IFACE_RX_FILTER command instead.
8772f345d8eSLuigi Rizzo  */
8782f345d8eSLuigi Rizzo int
8795fbb6830SXin LI oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable)
8802f345d8eSLuigi Rizzo {
8812f345d8eSLuigi Rizzo 	struct mbx_set_common_iface_rx_filter *fwcmd;
8822f345d8eSLuigi Rizzo 	int sz = sizeof(struct mbx_set_common_iface_rx_filter);
8832f345d8eSLuigi Rizzo 	iface_rx_filter_ctx_t *req;
8842f345d8eSLuigi Rizzo 	OCE_DMA_MEM sgl;
8852f345d8eSLuigi Rizzo 	int rc;
8862f345d8eSLuigi Rizzo 
8872f345d8eSLuigi Rizzo 	/* allocate mbx payload's dma scatter/gather memory */
8882f345d8eSLuigi Rizzo 	rc = oce_dma_alloc(sc, sz, &sgl, 0);
8892f345d8eSLuigi Rizzo 	if (rc)
8902f345d8eSLuigi Rizzo 		return rc;
8912f345d8eSLuigi Rizzo 
8922f345d8eSLuigi Rizzo 	fwcmd = OCE_DMAPTR(&sgl, struct mbx_set_common_iface_rx_filter);
8932f345d8eSLuigi Rizzo 
8942f345d8eSLuigi Rizzo 	req =  &fwcmd->params.req;
8952f345d8eSLuigi Rizzo 	req->iface_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
8962f345d8eSLuigi Rizzo 				MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
8975fbb6830SXin LI 	/* Bit 0 Mac promisc, Bit 1 Vlan promisc */
8985fbb6830SXin LI 	if (enable & 0x01)
8995fbb6830SXin LI 		req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
9005fbb6830SXin LI 
9015fbb6830SXin LI 	if (enable & 0x02)
902c2625e6eSJosh Paetzel 		req->iface_flags |= MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
9035fbb6830SXin LI 
9042f345d8eSLuigi Rizzo 	req->if_id = sc->if_id;
9052f345d8eSLuigi Rizzo 
9062f345d8eSLuigi Rizzo 	rc = oce_set_common_iface_rx_filter(sc, &sgl);
9072f345d8eSLuigi Rizzo 	oce_dma_free(sc, &sgl);
9082f345d8eSLuigi Rizzo 
9092f345d8eSLuigi Rizzo 	return rc;
9102f345d8eSLuigi Rizzo }
9112f345d8eSLuigi Rizzo 
9122f345d8eSLuigi Rizzo /**
9132f345d8eSLuigi Rizzo  * @brief 			Function modify and select rx filter options
9142f345d8eSLuigi Rizzo  * @param sc			software handle to the device
9152f345d8eSLuigi Rizzo  * @param sgl			scatter/gather request/response
9162f345d8eSLuigi Rizzo  * @returns			0 on success, error code on failure
9172f345d8eSLuigi Rizzo  */
9182f345d8eSLuigi Rizzo int
9192f345d8eSLuigi Rizzo oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl)
9202f345d8eSLuigi Rizzo {
9212f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
9222f345d8eSLuigi Rizzo 	int mbx_sz = sizeof(struct mbx_set_common_iface_rx_filter);
9232f345d8eSLuigi Rizzo 	struct mbx_set_common_iface_rx_filter *fwcmd;
9242f345d8eSLuigi Rizzo 	int rc;
9252f345d8eSLuigi Rizzo 
9262f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
9272f345d8eSLuigi Rizzo 	fwcmd = OCE_DMAPTR(sgl, struct mbx_set_common_iface_rx_filter);
9282f345d8eSLuigi Rizzo 
9292f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
9302f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
9312f345d8eSLuigi Rizzo 				OPCODE_COMMON_SET_IFACE_RX_FILTER,
9322f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
9332f345d8eSLuigi Rizzo 				mbx_sz,
9342f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
9352f345d8eSLuigi Rizzo 
9362f345d8eSLuigi Rizzo 	oce_dma_sync(sgl, BUS_DMASYNC_PREWRITE);
9372f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 0;
9382f345d8eSLuigi Rizzo 	mbx.u0.s.sge_count = 1;
9392f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(sgl->paddr);
9402f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(sgl->paddr);
9412f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].length = mbx_sz;
9422f345d8eSLuigi Rizzo 	mbx.payload_length = mbx_sz;
9432f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
9442f345d8eSLuigi Rizzo 
9452f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
946cdaba892SXin LI 	if (!rc)
947cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
948cdaba892SXin LI 	if (rc)
9495fbb6830SXin LI 		device_printf(sc->dev,
9505fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
9515fbb6830SXin LI 			      __FUNCTION__, rc,
9525fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
9535fbb6830SXin LI 	return rc;
9542f345d8eSLuigi Rizzo }
9552f345d8eSLuigi Rizzo 
9562f345d8eSLuigi Rizzo /**
9572f345d8eSLuigi Rizzo  * @brief Function to query the link status from the hardware
9582f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
9592f345d8eSLuigi Rizzo  * @param[out] link	pointer to the structure returning link attributes
9602f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
9612f345d8eSLuigi Rizzo  */
9622f345d8eSLuigi Rizzo int
9632f345d8eSLuigi Rizzo oce_get_link_status(POCE_SOFTC sc, struct link_status *link)
9642f345d8eSLuigi Rizzo {
9652f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
9662f345d8eSLuigi Rizzo 	struct mbx_query_common_link_config *fwcmd;
967cdaba892SXin LI 	int rc = 0, version;
9682f345d8eSLuigi Rizzo 
9692f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
9702f345d8eSLuigi Rizzo 
971b41206d8SXin LI 	IS_BE2(sc) ? (version = OCE_MBX_VER_V0) : (version = OCE_MBX_VER_V1);
972cdaba892SXin LI 
9732f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_query_common_link_config *)&mbx.payload;
9742f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
9752f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
9762f345d8eSLuigi Rizzo 				OPCODE_COMMON_QUERY_LINK_CONFIG,
9772f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
9782f345d8eSLuigi Rizzo 				sizeof(struct mbx_query_common_link_config),
979cdaba892SXin LI 				version);
9802f345d8eSLuigi Rizzo 
9812f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
9822f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_query_common_link_config);
9832f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
9842f345d8eSLuigi Rizzo 
9852f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
9862f345d8eSLuigi Rizzo 
987cdaba892SXin LI 	if (!rc)
988cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
9892f345d8eSLuigi Rizzo 	if (rc) {
9905fbb6830SXin LI 		device_printf(sc->dev,
9915fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
9925fbb6830SXin LI 			      __FUNCTION__, rc,
9935fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
994cdaba892SXin LI 		goto error;
995cdaba892SXin LI 	}
9962f345d8eSLuigi Rizzo 	/* interpret response */
997a4f734b4SXin LI 	link->qos_link_speed = HOST_16(fwcmd->params.rsp.qos_link_speed);
998a4f734b4SXin LI 	link->phys_port_speed = fwcmd->params.rsp.physical_port_speed;
999a4f734b4SXin LI 	link->logical_link_status = fwcmd->params.rsp.logical_link_status;
1000cdaba892SXin LI error:
10012f345d8eSLuigi Rizzo 	return rc;
10022f345d8eSLuigi Rizzo }
10032f345d8eSLuigi Rizzo 
10042f345d8eSLuigi Rizzo /**
10052f345d8eSLuigi Rizzo  * @brief Function to get NIC statistics
10062f345d8eSLuigi Rizzo  * @param sc            software handle to the device
10072f345d8eSLuigi Rizzo  * @param *stats        pointer to where to store statistics
10082f345d8eSLuigi Rizzo  * @param reset_stats   resets statistics of set
10092f345d8eSLuigi Rizzo  * @returns             0 on success, EIO on failure
10102f345d8eSLuigi Rizzo  * @note                command depricated in Lancer
10112f345d8eSLuigi Rizzo  */
1012c2625e6eSJosh Paetzel #define OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, version) 				\
1013c2625e6eSJosh Paetzel int 											\
1014c2625e6eSJosh Paetzel oce_mbox_get_nic_stats_v##version(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem) 		\
1015c2625e6eSJosh Paetzel { 											\
1016c2625e6eSJosh Paetzel         struct oce_mbx mbx; 								\
1017c2625e6eSJosh Paetzel         struct mbx_get_nic_stats_v##version *fwcmd; 					\
1018c2625e6eSJosh Paetzel         int rc = 0; 									\
1019c2625e6eSJosh Paetzel 											\
1020c2625e6eSJosh Paetzel         bzero(&mbx, sizeof(struct oce_mbx)); 						\
1021c2625e6eSJosh Paetzel         fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats_v##version); 	\
1022c2625e6eSJosh Paetzel         bzero(fwcmd, sizeof(*fwcmd)); 							\
1023c2625e6eSJosh Paetzel 											\
1024c2625e6eSJosh Paetzel         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 					\
1025c2625e6eSJosh Paetzel                                 MBX_SUBSYSTEM_NIC, 					\
1026c2625e6eSJosh Paetzel                                 NIC_GET_STATS, 						\
1027c2625e6eSJosh Paetzel                                 MBX_TIMEOUT_SEC, 					\
1028c2625e6eSJosh Paetzel                                 sizeof(*fwcmd), 					\
1029c2625e6eSJosh Paetzel                                 OCE_MBX_VER_V##version); 				\
1030c2625e6eSJosh Paetzel 											\
1031c2625e6eSJosh Paetzel         mbx.u0.s.embedded = 0;  /* stats too large for embedded mbx rsp */ 		\
1032c2625e6eSJosh Paetzel         mbx.u0.s.sge_count = 1; /* using scatter gather instead */ 			\
1033c2625e6eSJosh Paetzel 											\
1034c2625e6eSJosh Paetzel         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE); 				\
1035c2625e6eSJosh Paetzel         mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);		\
1036c2625e6eSJosh Paetzel         mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr); 		\
1037c2625e6eSJosh Paetzel         mbx.payload.u0.u1.sgl[0].length = sizeof(*fwcmd); 				\
1038c2625e6eSJosh Paetzel         mbx.payload_length = sizeof(*fwcmd); 						\
1039c2625e6eSJosh Paetzel         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 			\
1040c2625e6eSJosh Paetzel 											\
1041c2625e6eSJosh Paetzel         rc = oce_mbox_post(sc, &mbx, NULL); 						\
1042c2625e6eSJosh Paetzel         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE); 				\
1043c2625e6eSJosh Paetzel         if (!rc) 									\
1044c2625e6eSJosh Paetzel                 rc = fwcmd->hdr.u0.rsp.status; 						\
1045c2625e6eSJosh Paetzel         if (rc) 									\
1046c2625e6eSJosh Paetzel                 device_printf(sc->dev, 							\
1047c2625e6eSJosh Paetzel                               "%s failed - cmd status: %d addi status: %d\n", 		\
1048c2625e6eSJosh Paetzel                               __FUNCTION__, rc, 					\
1049c2625e6eSJosh Paetzel                               fwcmd->hdr.u0.rsp.additional_status); 			\
1050c2625e6eSJosh Paetzel         return rc; 									\
105114410265SConrad Meyer }
1052764c812dSJosh Paetzel 
1053c2625e6eSJosh Paetzel OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 0);
1054c2625e6eSJosh Paetzel OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 1);
1055c2625e6eSJosh Paetzel OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 2);
1056c2625e6eSJosh Paetzel 
10572f345d8eSLuigi Rizzo /**
10582f345d8eSLuigi Rizzo  * @brief Function to get pport (physical port) statistics
10592f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
10602f345d8eSLuigi Rizzo  * @param *stats	pointer to where to store statistics
10612f345d8eSLuigi Rizzo  * @param reset_stats	resets statistics of set
10622f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
10632f345d8eSLuigi Rizzo  */
10642f345d8eSLuigi Rizzo int
10652f345d8eSLuigi Rizzo oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
10662f345d8eSLuigi Rizzo 				uint32_t reset_stats)
10672f345d8eSLuigi Rizzo {
10682f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
10692f345d8eSLuigi Rizzo 	struct mbx_get_pport_stats *fwcmd;
10702f345d8eSLuigi Rizzo 	int rc = 0;
10712f345d8eSLuigi Rizzo 
10722f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
10732f345d8eSLuigi Rizzo 	fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_pport_stats);
10742f345d8eSLuigi Rizzo 	bzero(fwcmd, sizeof(struct mbx_get_pport_stats));
10752f345d8eSLuigi Rizzo 
10762f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
10772f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_NIC,
10782f345d8eSLuigi Rizzo 				NIC_GET_PPORT_STATS,
10792f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
10802f345d8eSLuigi Rizzo 				sizeof(struct mbx_get_pport_stats),
10812f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
10822f345d8eSLuigi Rizzo 
10832f345d8eSLuigi Rizzo 	fwcmd->params.req.reset_stats = reset_stats;
1084cdaba892SXin LI 	fwcmd->params.req.port_number = sc->port_id;
10852f345d8eSLuigi Rizzo 
10862f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 0;	/* stats too large for embedded mbx rsp */
10872f345d8eSLuigi Rizzo 	mbx.u0.s.sge_count = 1; /* using scatter gather instead */
10882f345d8eSLuigi Rizzo 
10892f345d8eSLuigi Rizzo 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
10902f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
10912f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
10922f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_pport_stats);
10932f345d8eSLuigi Rizzo 
10942f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_get_pport_stats);
10952f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
10962f345d8eSLuigi Rizzo 
10972f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
10982f345d8eSLuigi Rizzo 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
10992f345d8eSLuigi Rizzo 
1100cdaba892SXin LI 	if (!rc)
1101cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1102cdaba892SXin LI 	if (rc)
11035fbb6830SXin LI 		device_printf(sc->dev,
11045fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
11055fbb6830SXin LI 			      __FUNCTION__, rc,
11065fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
11072f345d8eSLuigi Rizzo 	return rc;
11082f345d8eSLuigi Rizzo }
11092f345d8eSLuigi Rizzo 
11102f345d8eSLuigi Rizzo /**
11112f345d8eSLuigi Rizzo  * @brief Function to get vport (virtual port) statistics
11122f345d8eSLuigi Rizzo  * @param sc 		software handle to the device
11132f345d8eSLuigi Rizzo  * @param *stats	pointer to where to store statistics
11142f345d8eSLuigi Rizzo  * @param reset_stats	resets statistics of set
11152f345d8eSLuigi Rizzo  * @returns		0 on success, EIO on failure
11162f345d8eSLuigi Rizzo  */
11172f345d8eSLuigi Rizzo int
11182f345d8eSLuigi Rizzo oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
11192f345d8eSLuigi Rizzo 				uint32_t req_size, uint32_t reset_stats)
11202f345d8eSLuigi Rizzo {
11212f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
11222f345d8eSLuigi Rizzo 	struct mbx_get_vport_stats *fwcmd;
11232f345d8eSLuigi Rizzo 	int rc = 0;
11242f345d8eSLuigi Rizzo 
11252f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
11262f345d8eSLuigi Rizzo 
11272f345d8eSLuigi Rizzo 	fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_vport_stats);
11282f345d8eSLuigi Rizzo 	bzero(fwcmd, sizeof(struct mbx_get_vport_stats));
11292f345d8eSLuigi Rizzo 
11302f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
11312f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_NIC,
11322f345d8eSLuigi Rizzo 				NIC_GET_VPORT_STATS,
11332f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
11342f345d8eSLuigi Rizzo 				sizeof(struct mbx_get_vport_stats),
11352f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
11362f345d8eSLuigi Rizzo 
11372f345d8eSLuigi Rizzo 	fwcmd->params.req.reset_stats = reset_stats;
11382f345d8eSLuigi Rizzo 	fwcmd->params.req.vport_number = sc->if_id;
11392f345d8eSLuigi Rizzo 
11402f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 0;	/* stats too large for embedded mbx rsp */
11412f345d8eSLuigi Rizzo 	mbx.u0.s.sge_count = 1; /* using scatter gather instead */
11422f345d8eSLuigi Rizzo 
11432f345d8eSLuigi Rizzo 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
11442f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
11452f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
11462f345d8eSLuigi Rizzo 	mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_vport_stats);
11472f345d8eSLuigi Rizzo 
11482f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_get_vport_stats);
11492f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
11502f345d8eSLuigi Rizzo 
11512f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
11522f345d8eSLuigi Rizzo 	oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
11532f345d8eSLuigi Rizzo 
1154cdaba892SXin LI 	if (!rc)
1155cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1156cdaba892SXin LI 	if (rc)
11575fbb6830SXin LI 		device_printf(sc->dev,
11585fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
11595fbb6830SXin LI 			      __FUNCTION__, rc,
11605fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
11612f345d8eSLuigi Rizzo 	return rc;
11622f345d8eSLuigi Rizzo }
11632f345d8eSLuigi Rizzo 
11642f345d8eSLuigi Rizzo /**
11652f345d8eSLuigi Rizzo  * @brief               Function to update the muticast filter with
11662f345d8eSLuigi Rizzo  *                      values in dma_mem
11672f345d8eSLuigi Rizzo  * @param sc            software handle to the device
11682f345d8eSLuigi Rizzo  * @param dma_mem       pointer to dma memory region
11692f345d8eSLuigi Rizzo  * @returns             0 on success, EIO on failure
11702f345d8eSLuigi Rizzo  */
11712f345d8eSLuigi Rizzo int
11722f345d8eSLuigi Rizzo oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem)
11732f345d8eSLuigi Rizzo {
11742f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
11752f345d8eSLuigi Rizzo 	struct oce_mq_sge *sgl;
11762f345d8eSLuigi Rizzo 	struct mbx_set_common_iface_multicast *req = NULL;
11772f345d8eSLuigi Rizzo 	int rc = 0;
11782f345d8eSLuigi Rizzo 
11792f345d8eSLuigi Rizzo 	req = OCE_DMAPTR(pdma_mem, struct mbx_set_common_iface_multicast);
11802f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&req->hdr, 0, 0,
11812f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
11822f345d8eSLuigi Rizzo 				OPCODE_COMMON_SET_IFACE_MULTICAST,
11832f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
11842f345d8eSLuigi Rizzo 				sizeof(struct mbx_set_common_iface_multicast),
11852f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
11862f345d8eSLuigi Rizzo 
11872f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
11882f345d8eSLuigi Rizzo 
11892f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 0; /*Non embeded*/
11902f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_set_common_iface_multicast);
11912f345d8eSLuigi Rizzo 	mbx.u0.s.sge_count = 1;
11922f345d8eSLuigi Rizzo 	sgl = &mbx.payload.u0.u1.sgl[0];
11932f345d8eSLuigi Rizzo 	sgl->pa_hi = htole32(upper_32_bits(pdma_mem->paddr));
11942f345d8eSLuigi Rizzo 	sgl->pa_lo = htole32((pdma_mem->paddr) & 0xFFFFFFFF);
11952f345d8eSLuigi Rizzo 	sgl->length = htole32(mbx.payload_length);
11962f345d8eSLuigi Rizzo 
11972f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
11982f345d8eSLuigi Rizzo 
11992f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1200cdaba892SXin LI 	if (!rc)
1201cdaba892SXin LI                 rc = req->hdr.u0.rsp.status;
1202cdaba892SXin LI 	if (rc)
12035fbb6830SXin LI 		device_printf(sc->dev,
12045fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
12055fbb6830SXin LI 			      __FUNCTION__, rc,
12065fbb6830SXin LI 			      req->hdr.u0.rsp.additional_status);
12072f345d8eSLuigi Rizzo 	return rc;
12082f345d8eSLuigi Rizzo }
12092f345d8eSLuigi Rizzo 
12102f345d8eSLuigi Rizzo /**
12112f345d8eSLuigi Rizzo  * @brief               Function to send passthrough Ioctls
12122f345d8eSLuigi Rizzo  * @param sc            software handle to the device
12132f345d8eSLuigi Rizzo  * @param dma_mem       pointer to dma memory region
12142f345d8eSLuigi Rizzo  * @param req_size      size of dma_mem
12152f345d8eSLuigi Rizzo  * @returns             0 on success, EIO on failure
12162f345d8eSLuigi Rizzo  */
12172f345d8eSLuigi Rizzo int
12182f345d8eSLuigi Rizzo oce_pass_through_mbox(POCE_SOFTC sc, POCE_DMA_MEM dma_mem, uint32_t req_size)
12192f345d8eSLuigi Rizzo {
12202f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
12212f345d8eSLuigi Rizzo 	struct oce_mq_sge *sgl;
12222f345d8eSLuigi Rizzo 	int rc = 0;
12232f345d8eSLuigi Rizzo 
12242f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
12252f345d8eSLuigi Rizzo 
12262f345d8eSLuigi Rizzo 	mbx.u0.s.embedded  = 0; /*Non embeded*/
12272f345d8eSLuigi Rizzo 	mbx.payload_length = req_size;
12282f345d8eSLuigi Rizzo 	mbx.u0.s.sge_count = 1;
12292f345d8eSLuigi Rizzo 	sgl = &mbx.payload.u0.u1.sgl[0];
12302f345d8eSLuigi Rizzo 	sgl->pa_hi = htole32(upper_32_bits(dma_mem->paddr));
12312f345d8eSLuigi Rizzo 	sgl->pa_lo = htole32((dma_mem->paddr) & 0xFFFFFFFF);
12322f345d8eSLuigi Rizzo 	sgl->length = htole32(req_size);
12332f345d8eSLuigi Rizzo 
12342f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
12352f345d8eSLuigi Rizzo 
12362f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
12372f345d8eSLuigi Rizzo 	return rc;
12382f345d8eSLuigi Rizzo }
12392f345d8eSLuigi Rizzo 
12402f345d8eSLuigi Rizzo int
12412f345d8eSLuigi Rizzo oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
12422f345d8eSLuigi Rizzo 		 uint32_t if_id, uint32_t *pmac_id)
12432f345d8eSLuigi Rizzo {
12442f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
12452f345d8eSLuigi Rizzo 	struct mbx_add_common_iface_mac *fwcmd;
12462f345d8eSLuigi Rizzo 	int rc = 0;
12472f345d8eSLuigi Rizzo 
12482f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
12492f345d8eSLuigi Rizzo 
12502f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_add_common_iface_mac *)&mbx.payload;
12512f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
12522f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
12532f345d8eSLuigi Rizzo 				OPCODE_COMMON_ADD_IFACE_MAC,
12542f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
12552f345d8eSLuigi Rizzo 				sizeof(struct mbx_add_common_iface_mac),
12562f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
12572f345d8eSLuigi Rizzo 
12582f345d8eSLuigi Rizzo 	fwcmd->params.req.if_id = (uint16_t) if_id;
12592f345d8eSLuigi Rizzo 	bcopy(mac_addr, fwcmd->params.req.mac_address, 6);
12602f345d8eSLuigi Rizzo 
12612f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
12622f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct  mbx_add_common_iface_mac);
12632f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
12642f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1265cdaba892SXin LI 	if (!rc)
1266cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1267cdaba892SXin LI 	if (rc) {
12685fbb6830SXin LI 		device_printf(sc->dev,
12695fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
12705fbb6830SXin LI 			      __FUNCTION__, rc,
12715fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
1272cdaba892SXin LI 		goto error;
1273cdaba892SXin LI 	}
12742f345d8eSLuigi Rizzo 	*pmac_id = fwcmd->params.rsp.pmac_id;
1275cdaba892SXin LI error:
12762f345d8eSLuigi Rizzo 	return rc;
12772f345d8eSLuigi Rizzo }
12782f345d8eSLuigi Rizzo 
12792f345d8eSLuigi Rizzo int
12802f345d8eSLuigi Rizzo oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id)
12812f345d8eSLuigi Rizzo {
12822f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
12832f345d8eSLuigi Rizzo 	struct mbx_del_common_iface_mac *fwcmd;
12842f345d8eSLuigi Rizzo 	int rc = 0;
12852f345d8eSLuigi Rizzo 
12862f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
12872f345d8eSLuigi Rizzo 
12882f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_del_common_iface_mac *)&mbx.payload;
12892f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
12902f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
12912f345d8eSLuigi Rizzo 				OPCODE_COMMON_DEL_IFACE_MAC,
12922f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
12932f345d8eSLuigi Rizzo 				sizeof(struct mbx_del_common_iface_mac),
12942f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
12952f345d8eSLuigi Rizzo 
12962f345d8eSLuigi Rizzo 	fwcmd->params.req.if_id = (uint16_t)if_id;
12972f345d8eSLuigi Rizzo 	fwcmd->params.req.pmac_id = pmac_id;
12982f345d8eSLuigi Rizzo 
12992f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
13002f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct  mbx_del_common_iface_mac);
13012f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
13022f345d8eSLuigi Rizzo 
13032f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1304cdaba892SXin LI 	if (!rc)
1305cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1306cdaba892SXin LI 	if (rc)
13075fbb6830SXin LI 		device_printf(sc->dev,
13085fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
13095fbb6830SXin LI 			      __FUNCTION__, rc,
13105fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
13112f345d8eSLuigi Rizzo 	return rc;
13122f345d8eSLuigi Rizzo }
13132f345d8eSLuigi Rizzo 
13142f345d8eSLuigi Rizzo int
13152f345d8eSLuigi Rizzo oce_mbox_check_native_mode(POCE_SOFTC sc)
13162f345d8eSLuigi Rizzo {
13172f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
13182f345d8eSLuigi Rizzo 	struct mbx_common_set_function_cap *fwcmd;
13192f345d8eSLuigi Rizzo 	int rc = 0;
13202f345d8eSLuigi Rizzo 
13212f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
13222f345d8eSLuigi Rizzo 
13232f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_common_set_function_cap *)&mbx.payload;
13242f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
13252f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
13262f345d8eSLuigi Rizzo 				OPCODE_COMMON_SET_FUNCTIONAL_CAPS,
13272f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
13282f345d8eSLuigi Rizzo 				sizeof(struct mbx_common_set_function_cap),
13292f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
13302f345d8eSLuigi Rizzo 
13312f345d8eSLuigi Rizzo 	fwcmd->params.req.valid_capability_flags = CAP_SW_TIMESTAMPS |
13322f345d8eSLuigi Rizzo 							CAP_BE3_NATIVE_ERX_API;
13332f345d8eSLuigi Rizzo 
13342f345d8eSLuigi Rizzo 	fwcmd->params.req.capability_flags = CAP_BE3_NATIVE_ERX_API;
13352f345d8eSLuigi Rizzo 
13362f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
13372f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_common_set_function_cap);
13382f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
13392f345d8eSLuigi Rizzo 
13402f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1341cdaba892SXin LI 	if (!rc)
1342cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1343cdaba892SXin LI 	if (rc) {
13445fbb6830SXin LI 		device_printf(sc->dev,
13455fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
13465fbb6830SXin LI 			      __FUNCTION__, rc,
13475fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
1348cdaba892SXin LI 		goto error;
1349cdaba892SXin LI 	}
13505fbb6830SXin LI 	sc->be3_native = HOST_32(fwcmd->params.rsp.capability_flags)
13512f345d8eSLuigi Rizzo 			& CAP_BE3_NATIVE_ERX_API;
13522f345d8eSLuigi Rizzo 
1353cdaba892SXin LI error:
13542f345d8eSLuigi Rizzo 	return 0;
13552f345d8eSLuigi Rizzo }
13562f345d8eSLuigi Rizzo 
13572f345d8eSLuigi Rizzo int
13582f345d8eSLuigi Rizzo oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
13592f345d8eSLuigi Rizzo 		uint8_t loopback_type, uint8_t enable)
13602f345d8eSLuigi Rizzo {
13612f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
13622f345d8eSLuigi Rizzo 	struct mbx_lowlevel_set_loopback_mode *fwcmd;
13632f345d8eSLuigi Rizzo 	int rc = 0;
13642f345d8eSLuigi Rizzo 
13652f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
13662f345d8eSLuigi Rizzo 
13672f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_lowlevel_set_loopback_mode *)&mbx.payload;
13682f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
13692f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_LOWLEVEL,
13702f345d8eSLuigi Rizzo 				OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
13712f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
13722f345d8eSLuigi Rizzo 				sizeof(struct mbx_lowlevel_set_loopback_mode),
13732f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
13742f345d8eSLuigi Rizzo 
13752f345d8eSLuigi Rizzo 	fwcmd->params.req.src_port = port_num;
13762f345d8eSLuigi Rizzo 	fwcmd->params.req.dest_port = port_num;
13772f345d8eSLuigi Rizzo 	fwcmd->params.req.loopback_type = loopback_type;
13782f345d8eSLuigi Rizzo 	fwcmd->params.req.loopback_state = enable;
13792f345d8eSLuigi Rizzo 
13802f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
13812f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct  mbx_lowlevel_set_loopback_mode);
13822f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
13832f345d8eSLuigi Rizzo 
13842f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1385cdaba892SXin LI 	if (!rc)
1386cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1387cdaba892SXin LI 	if (rc)
13885fbb6830SXin LI 		device_printf(sc->dev,
13895fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
13905fbb6830SXin LI 			      __FUNCTION__, rc,
13915fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
13922f345d8eSLuigi Rizzo 
13932f345d8eSLuigi Rizzo 	return rc;
13942f345d8eSLuigi Rizzo 
13952f345d8eSLuigi Rizzo }
13962f345d8eSLuigi Rizzo 
13972f345d8eSLuigi Rizzo int
13982f345d8eSLuigi Rizzo oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
13992f345d8eSLuigi Rizzo 	uint32_t loopback_type, uint32_t pkt_size, uint32_t num_pkts,
14002f345d8eSLuigi Rizzo 	uint64_t pattern)
14012f345d8eSLuigi Rizzo {
14022f345d8eSLuigi Rizzo 
14032f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
14042f345d8eSLuigi Rizzo 	struct mbx_lowlevel_test_loopback_mode *fwcmd;
14052f345d8eSLuigi Rizzo 	int rc = 0;
14062f345d8eSLuigi Rizzo 
14072f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
14082f345d8eSLuigi Rizzo 
14092f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_lowlevel_test_loopback_mode *)&mbx.payload;
14102f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
14112f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_LOWLEVEL,
14122f345d8eSLuigi Rizzo 				OPCODE_LOWLEVEL_TEST_LOOPBACK,
14132f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
14142f345d8eSLuigi Rizzo 				sizeof(struct mbx_lowlevel_test_loopback_mode),
14152f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
14162f345d8eSLuigi Rizzo 
14172f345d8eSLuigi Rizzo 	fwcmd->params.req.pattern = pattern;
14182f345d8eSLuigi Rizzo 	fwcmd->params.req.src_port = port_num;
14192f345d8eSLuigi Rizzo 	fwcmd->params.req.dest_port = port_num;
14202f345d8eSLuigi Rizzo 	fwcmd->params.req.pkt_size = pkt_size;
14212f345d8eSLuigi Rizzo 	fwcmd->params.req.num_pkts = num_pkts;
14222f345d8eSLuigi Rizzo 	fwcmd->params.req.loopback_type = loopback_type;
14232f345d8eSLuigi Rizzo 
14242f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
14252f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct  mbx_lowlevel_test_loopback_mode);
14262f345d8eSLuigi Rizzo 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
14272f345d8eSLuigi Rizzo 
14282f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1429cdaba892SXin LI 	if (!rc)
1430cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
14312f345d8eSLuigi Rizzo 	if (rc)
14325fbb6830SXin LI 		device_printf(sc->dev,
14335fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
14345fbb6830SXin LI 			      __FUNCTION__, rc,
14355fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
14362f345d8eSLuigi Rizzo 
1437cdaba892SXin LI 	return rc;
14382f345d8eSLuigi Rizzo }
14392f345d8eSLuigi Rizzo 
14402f345d8eSLuigi Rizzo int
14412f345d8eSLuigi Rizzo oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
14422f345d8eSLuigi Rizzo 				POCE_DMA_MEM pdma_mem, uint32_t num_bytes)
14432f345d8eSLuigi Rizzo {
14442f345d8eSLuigi Rizzo 
14452f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
14462f345d8eSLuigi Rizzo 	struct oce_mq_sge *sgl = NULL;
14472f345d8eSLuigi Rizzo 	struct mbx_common_read_write_flashrom *fwcmd = NULL;
14482f345d8eSLuigi Rizzo 	int rc = 0, payload_len = 0;
14492f345d8eSLuigi Rizzo 
14502f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
14512f345d8eSLuigi Rizzo 	fwcmd = OCE_DMAPTR(pdma_mem, struct mbx_common_read_write_flashrom);
14522f345d8eSLuigi Rizzo 	payload_len = sizeof(struct mbx_common_read_write_flashrom) + 32*1024;
14532f345d8eSLuigi Rizzo 
14542f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
14552f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
14562f345d8eSLuigi Rizzo 				OPCODE_COMMON_WRITE_FLASHROM,
14572f345d8eSLuigi Rizzo 				LONG_TIMEOUT,
14582f345d8eSLuigi Rizzo 				payload_len,
14592f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
14602f345d8eSLuigi Rizzo 
14615fbb6830SXin LI 	fwcmd->flash_op_type = LE_32(optype);
14625fbb6830SXin LI 	fwcmd->flash_op_code = LE_32(opcode);
14635fbb6830SXin LI 	fwcmd->data_buffer_size = LE_32(num_bytes);
14642f345d8eSLuigi Rizzo 
14652f345d8eSLuigi Rizzo 	mbx.u0.s.embedded  = 0; /*Non embeded*/
14662f345d8eSLuigi Rizzo 	mbx.payload_length = payload_len;
14672f345d8eSLuigi Rizzo 	mbx.u0.s.sge_count = 1;
14682f345d8eSLuigi Rizzo 
14692f345d8eSLuigi Rizzo 	sgl = &mbx.payload.u0.u1.sgl[0];
14702f345d8eSLuigi Rizzo 	sgl->pa_hi = upper_32_bits(pdma_mem->paddr);
14712f345d8eSLuigi Rizzo 	sgl->pa_lo = pdma_mem->paddr & 0xFFFFFFFF;
14722f345d8eSLuigi Rizzo 	sgl->length = payload_len;
14732f345d8eSLuigi Rizzo 
14742f345d8eSLuigi Rizzo 	/* post the command */
14759bd3250aSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1476cdaba892SXin LI 	if (!rc)
14772f345d8eSLuigi Rizzo                 rc = fwcmd->hdr.u0.rsp.status;
1478cdaba892SXin LI 	if (rc)
14795fbb6830SXin LI 		device_printf(sc->dev,
14805fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
14815fbb6830SXin LI 			      __FUNCTION__, rc,
14825fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
14832f345d8eSLuigi Rizzo 
14842f345d8eSLuigi Rizzo 	return rc;
14852f345d8eSLuigi Rizzo 
14862f345d8eSLuigi Rizzo }
14872f345d8eSLuigi Rizzo 
14882f345d8eSLuigi Rizzo int
14892f345d8eSLuigi Rizzo oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
14902f345d8eSLuigi Rizzo 				uint32_t offset, uint32_t optype)
14912f345d8eSLuigi Rizzo {
14922f345d8eSLuigi Rizzo 
14932f345d8eSLuigi Rizzo 	int rc = 0, payload_len = 0;
14942f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
14952f345d8eSLuigi Rizzo 	struct mbx_common_read_write_flashrom *fwcmd;
14962f345d8eSLuigi Rizzo 
14972f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
14982f345d8eSLuigi Rizzo 
14992f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_common_read_write_flashrom *)&mbx.payload;
15002f345d8eSLuigi Rizzo 
15012f345d8eSLuigi Rizzo 	/* Firmware requires extra 4 bytes with this ioctl. Since there
15022f345d8eSLuigi Rizzo 	   is enough room in the mbx payload it should be good enough
15032f345d8eSLuigi Rizzo 	   Reference: Bug 14853
15042f345d8eSLuigi Rizzo 	*/
15052f345d8eSLuigi Rizzo 	payload_len = sizeof(struct mbx_common_read_write_flashrom) + 4;
15062f345d8eSLuigi Rizzo 
15072f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
15082f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
15092f345d8eSLuigi Rizzo 				OPCODE_COMMON_READ_FLASHROM,
15102f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
15112f345d8eSLuigi Rizzo 				payload_len,
15122f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
15132f345d8eSLuigi Rizzo 
15142f345d8eSLuigi Rizzo 	fwcmd->flash_op_type = optype;
15152f345d8eSLuigi Rizzo 	fwcmd->flash_op_code = FLASHROM_OPER_REPORT;
15162f345d8eSLuigi Rizzo 	fwcmd->data_offset = offset;
15172f345d8eSLuigi Rizzo 	fwcmd->data_buffer_size = 0x4;
15182f345d8eSLuigi Rizzo 
15192f345d8eSLuigi Rizzo 	mbx.u0.s.embedded  = 1;
15202f345d8eSLuigi Rizzo 	mbx.payload_length = payload_len;
15212f345d8eSLuigi Rizzo 
15222f345d8eSLuigi Rizzo 	/* post the command */
15232f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1524cdaba892SXin LI 	if (!rc)
15252f345d8eSLuigi Rizzo                 rc = fwcmd->hdr.u0.rsp.status;
1526cdaba892SXin LI 	if (rc) {
15275fbb6830SXin LI 		device_printf(sc->dev,
15285fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
15295fbb6830SXin LI 			      __FUNCTION__, rc,
15305fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
1531cdaba892SXin LI 		goto error;
15322f345d8eSLuigi Rizzo 	}
1533cdaba892SXin LI 	bcopy(fwcmd->data_buffer, flash_crc, 4);
1534cdaba892SXin LI error:
15352f345d8eSLuigi Rizzo 	return rc;
15362f345d8eSLuigi Rizzo }
15372f345d8eSLuigi Rizzo 
15382f345d8eSLuigi Rizzo int
15392f345d8eSLuigi Rizzo oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info)
15402f345d8eSLuigi Rizzo {
15412f345d8eSLuigi Rizzo 
15422f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
15432f345d8eSLuigi Rizzo 	struct mbx_common_phy_info *fwcmd;
15442f345d8eSLuigi Rizzo 	int rc = 0;
15452f345d8eSLuigi Rizzo 
15462f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
15472f345d8eSLuigi Rizzo 
15482f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_common_phy_info *)&mbx.payload;
15492f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
15502f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
15512f345d8eSLuigi Rizzo 				OPCODE_COMMON_GET_PHY_CONFIG,
15522f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
15532f345d8eSLuigi Rizzo 				sizeof(struct mbx_common_phy_info),
15542f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
15552f345d8eSLuigi Rizzo 
15562f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
15572f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct  mbx_common_phy_info);
15582f345d8eSLuigi Rizzo 
15592f345d8eSLuigi Rizzo 	/* now post the command */
15602f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1561cdaba892SXin LI 	if (!rc)
15622f345d8eSLuigi Rizzo                 rc = fwcmd->hdr.u0.rsp.status;
1563cdaba892SXin LI 	if (rc) {
15645fbb6830SXin LI 		device_printf(sc->dev,
15655fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
15665fbb6830SXin LI 			      __FUNCTION__, rc,
15675fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
1568cdaba892SXin LI 		goto error;
1569cdaba892SXin LI 	}
15705fbb6830SXin LI 	phy_info->phy_type = HOST_16(fwcmd->params.rsp.phy_info.phy_type);
15712f345d8eSLuigi Rizzo 	phy_info->interface_type =
15725fbb6830SXin LI 			HOST_16(fwcmd->params.rsp.phy_info.interface_type);
15732f345d8eSLuigi Rizzo 	phy_info->auto_speeds_supported =
15745fbb6830SXin LI 		HOST_16(fwcmd->params.rsp.phy_info.auto_speeds_supported);
15752f345d8eSLuigi Rizzo 	phy_info->fixed_speeds_supported =
15765fbb6830SXin LI 		HOST_16(fwcmd->params.rsp.phy_info.fixed_speeds_supported);
15775fbb6830SXin LI 	phy_info->misc_params = HOST_32(fwcmd->params.rsp.phy_info.misc_params);
1578cdaba892SXin LI error:
15792f345d8eSLuigi Rizzo 	return rc;
15802f345d8eSLuigi Rizzo 
15812f345d8eSLuigi Rizzo }
15822f345d8eSLuigi Rizzo 
15832f345d8eSLuigi Rizzo int
15842f345d8eSLuigi Rizzo oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
15852f345d8eSLuigi Rizzo 			uint32_t data_offset, POCE_DMA_MEM pdma_mem,
15862f345d8eSLuigi Rizzo 			uint32_t *written_data, uint32_t *additional_status)
15872f345d8eSLuigi Rizzo {
15882f345d8eSLuigi Rizzo 
15892f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
15902f345d8eSLuigi Rizzo 	struct mbx_lancer_common_write_object *fwcmd = NULL;
15912f345d8eSLuigi Rizzo 	int rc = 0, payload_len = 0;
15922f345d8eSLuigi Rizzo 
15932f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
15942f345d8eSLuigi Rizzo 	payload_len = sizeof(struct mbx_lancer_common_write_object);
15952f345d8eSLuigi Rizzo 
15962f345d8eSLuigi Rizzo 	mbx.u0.s.embedded  = 1;/* Embedded */
15972f345d8eSLuigi Rizzo 	mbx.payload_length = payload_len;
15982f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_lancer_common_write_object *)&mbx.payload;
15992f345d8eSLuigi Rizzo 
16002f345d8eSLuigi Rizzo 	/* initialize the ioctl header */
16012f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->params.req.hdr, 0, 0,
16022f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
16032f345d8eSLuigi Rizzo 				OPCODE_COMMON_WRITE_OBJECT,
16042f345d8eSLuigi Rizzo 				LONG_TIMEOUT,
16052f345d8eSLuigi Rizzo 				payload_len,
16062f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
16072f345d8eSLuigi Rizzo 
16082f345d8eSLuigi Rizzo 	fwcmd->params.req.write_length = data_size;
16092f345d8eSLuigi Rizzo 	if (data_size == 0)
16102f345d8eSLuigi Rizzo 		fwcmd->params.req.eof = 1;
16112f345d8eSLuigi Rizzo 	else
16122f345d8eSLuigi Rizzo 		fwcmd->params.req.eof = 0;
16132f345d8eSLuigi Rizzo 
16142f345d8eSLuigi Rizzo 	strcpy(fwcmd->params.req.object_name, "/prg");
16152f345d8eSLuigi Rizzo 	fwcmd->params.req.descriptor_count = 1;
16162f345d8eSLuigi Rizzo 	fwcmd->params.req.write_offset = data_offset;
16172f345d8eSLuigi Rizzo 	fwcmd->params.req.buffer_length = data_size;
16182f345d8eSLuigi Rizzo 	fwcmd->params.req.address_lower = pdma_mem->paddr & 0xFFFFFFFF;
16192f345d8eSLuigi Rizzo 	fwcmd->params.req.address_upper = upper_32_bits(pdma_mem->paddr);
16202f345d8eSLuigi Rizzo 
16212f345d8eSLuigi Rizzo 	/* post the command */
16222f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1623cdaba892SXin LI 	if (!rc)
1624cdaba892SXin LI                 rc = fwcmd->params.rsp.status;
16252f345d8eSLuigi Rizzo 	if (rc) {
16265fbb6830SXin LI 		device_printf(sc->dev,
16275fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
16285fbb6830SXin LI 			      __FUNCTION__, rc,
16295fbb6830SXin LI 			      fwcmd->params.rsp.additional_status);
1630cdaba892SXin LI 		goto error;
1631cdaba892SXin LI 	}
16325fbb6830SXin LI 	*written_data = HOST_32(fwcmd->params.rsp.actual_write_length);
16332f345d8eSLuigi Rizzo 	*additional_status = fwcmd->params.rsp.additional_status;
1634cdaba892SXin LI error:
16352f345d8eSLuigi Rizzo 	return rc;
16362f345d8eSLuigi Rizzo 
16372f345d8eSLuigi Rizzo }
16382f345d8eSLuigi Rizzo 
16392f345d8eSLuigi Rizzo int
16402f345d8eSLuigi Rizzo oce_mbox_create_rq(struct oce_rq *rq)
16412f345d8eSLuigi Rizzo {
16422f345d8eSLuigi Rizzo 
16432f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
16442f345d8eSLuigi Rizzo 	struct mbx_create_nic_rq *fwcmd;
16452f345d8eSLuigi Rizzo 	POCE_SOFTC sc = rq->parent;
16462f345d8eSLuigi Rizzo 	int rc, num_pages = 0;
16472f345d8eSLuigi Rizzo 
16482f345d8eSLuigi Rizzo 	if (rq->qstate == QCREATED)
16492f345d8eSLuigi Rizzo 		return 0;
16502f345d8eSLuigi Rizzo 
16512f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
16522f345d8eSLuigi Rizzo 
16532f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_create_nic_rq *)&mbx.payload;
16542f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
16552f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_NIC,
16562f345d8eSLuigi Rizzo 				NIC_CREATE_RQ, MBX_TIMEOUT_SEC,
16572f345d8eSLuigi Rizzo 				sizeof(struct mbx_create_nic_rq),
16582f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
16592f345d8eSLuigi Rizzo 
16602f345d8eSLuigi Rizzo 	/* oce_page_list will also prepare pages */
16612f345d8eSLuigi Rizzo 	num_pages = oce_page_list(rq->ring, &fwcmd->params.req.pages[0]);
16622f345d8eSLuigi Rizzo 
16632f345d8eSLuigi Rizzo 	if (IS_XE201(sc)) {
16642f345d8eSLuigi Rizzo 		fwcmd->params.req.frag_size = rq->cfg.frag_size/2048;
16652f345d8eSLuigi Rizzo 		fwcmd->params.req.page_size = 1;
16662f345d8eSLuigi Rizzo 		fwcmd->hdr.u0.req.version = OCE_MBX_VER_V1;
16672f345d8eSLuigi Rizzo 	} else
16682f345d8eSLuigi Rizzo 		fwcmd->params.req.frag_size = OCE_LOG2(rq->cfg.frag_size);
16692f345d8eSLuigi Rizzo 	fwcmd->params.req.num_pages = num_pages;
16702f345d8eSLuigi Rizzo 	fwcmd->params.req.cq_id = rq->cq->cq_id;
16712f345d8eSLuigi Rizzo 	fwcmd->params.req.if_id = sc->if_id;
16722f345d8eSLuigi Rizzo 	fwcmd->params.req.max_frame_size = rq->cfg.mtu;
16732f345d8eSLuigi Rizzo 	fwcmd->params.req.is_rss_queue = rq->cfg.is_rss_queue;
16742f345d8eSLuigi Rizzo 
16752f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
16762f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_create_nic_rq);
16772f345d8eSLuigi Rizzo 
16782f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1679cdaba892SXin LI 	if (!rc)
1680cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1681cdaba892SXin LI 	if (rc) {
16825fbb6830SXin LI 		device_printf(sc->dev,
16835fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
16845fbb6830SXin LI 			      __FUNCTION__, rc,
16855fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
16862f345d8eSLuigi Rizzo 		goto error;
1687cdaba892SXin LI 	}
16885fbb6830SXin LI 	rq->rq_id = HOST_16(fwcmd->params.rsp.rq_id);
16892f345d8eSLuigi Rizzo 	rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
16902f345d8eSLuigi Rizzo error:
16912f345d8eSLuigi Rizzo 	return rc;
16922f345d8eSLuigi Rizzo 
16932f345d8eSLuigi Rizzo }
16942f345d8eSLuigi Rizzo 
16952f345d8eSLuigi Rizzo int
16962f345d8eSLuigi Rizzo oce_mbox_create_wq(struct oce_wq *wq)
16972f345d8eSLuigi Rizzo {
16982f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
16992f345d8eSLuigi Rizzo 	struct mbx_create_nic_wq *fwcmd;
17002f345d8eSLuigi Rizzo 	POCE_SOFTC sc = wq->parent;
17012f345d8eSLuigi Rizzo 	int rc = 0, version, num_pages;
17022f345d8eSLuigi Rizzo 
17032f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
17042f345d8eSLuigi Rizzo 
17052f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_create_nic_wq *)&mbx.payload;
17065fbb6830SXin LI 	if (IS_XE201(sc))
17072f345d8eSLuigi Rizzo 		version = OCE_MBX_VER_V1;
17085fbb6830SXin LI 	else if(IS_BE(sc))
1709291a1934SXin LI 		IS_PROFILE_SUPER_NIC(sc) ? (version = OCE_MBX_VER_V2)
1710291a1934SXin LI 					 : (version = OCE_MBX_VER_V0);
1711291a1934SXin LI 	else
1712291a1934SXin LI 		version = OCE_MBX_VER_V2;
17132f345d8eSLuigi Rizzo 
17145fbb6830SXin LI 	if (version > OCE_MBX_VER_V0)
17155fbb6830SXin LI 		fwcmd->params.req.if_id = sc->if_id;
17165fbb6830SXin LI 
17172f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
17182f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_NIC,
17192f345d8eSLuigi Rizzo 				NIC_CREATE_WQ, MBX_TIMEOUT_SEC,
17202f345d8eSLuigi Rizzo 				sizeof(struct mbx_create_nic_wq),
17212f345d8eSLuigi Rizzo 				version);
17222f345d8eSLuigi Rizzo 
17232f345d8eSLuigi Rizzo 	num_pages = oce_page_list(wq->ring, &fwcmd->params.req.pages[0]);
17242f345d8eSLuigi Rizzo 
17252f345d8eSLuigi Rizzo 	fwcmd->params.req.nic_wq_type = wq->cfg.wq_type;
17262f345d8eSLuigi Rizzo 	fwcmd->params.req.num_pages = num_pages;
17272f345d8eSLuigi Rizzo 	fwcmd->params.req.wq_size = OCE_LOG2(wq->cfg.q_len) + 1;
17282f345d8eSLuigi Rizzo 	fwcmd->params.req.cq_id = wq->cq->cq_id;
17292f345d8eSLuigi Rizzo 	fwcmd->params.req.ulp_num = 1;
17302f345d8eSLuigi Rizzo 
17312f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
17322f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_create_nic_wq);
17332f345d8eSLuigi Rizzo 
17342f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1735cdaba892SXin LI 	if (!rc)
1736cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1737cdaba892SXin LI 	if (rc) {
17385fbb6830SXin LI 		device_printf(sc->dev,
17395fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
17405fbb6830SXin LI 			      __FUNCTION__, rc,
17415fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
17422f345d8eSLuigi Rizzo 		goto error;
1743cdaba892SXin LI 	}
17445fbb6830SXin LI 	wq->wq_id = HOST_16(fwcmd->params.rsp.wq_id);
1745291a1934SXin LI 	if (version == OCE_MBX_VER_V2)
17465fbb6830SXin LI 		wq->db_offset = HOST_32(fwcmd->params.rsp.db_offset);
1747291a1934SXin LI 	else
1748291a1934SXin LI 		wq->db_offset = PD_TXULP_DB;
17492f345d8eSLuigi Rizzo error:
17502f345d8eSLuigi Rizzo 	return rc;
17512f345d8eSLuigi Rizzo 
17522f345d8eSLuigi Rizzo }
17532f345d8eSLuigi Rizzo 
17542f345d8eSLuigi Rizzo int
17552f345d8eSLuigi Rizzo oce_mbox_create_eq(struct oce_eq *eq)
17562f345d8eSLuigi Rizzo {
17572f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
17582f345d8eSLuigi Rizzo 	struct mbx_create_common_eq *fwcmd;
17592f345d8eSLuigi Rizzo 	POCE_SOFTC sc = eq->parent;
17602f345d8eSLuigi Rizzo 	int rc = 0;
17612f345d8eSLuigi Rizzo 	uint32_t num_pages;
17622f345d8eSLuigi Rizzo 
17632f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
17642f345d8eSLuigi Rizzo 
17652f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_create_common_eq *)&mbx.payload;
17662f345d8eSLuigi Rizzo 
17672f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
17682f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
17692f345d8eSLuigi Rizzo 				OPCODE_COMMON_CREATE_EQ, MBX_TIMEOUT_SEC,
17702f345d8eSLuigi Rizzo 				sizeof(struct mbx_create_common_eq),
17712f345d8eSLuigi Rizzo 				OCE_MBX_VER_V0);
17722f345d8eSLuigi Rizzo 
17732f345d8eSLuigi Rizzo 	num_pages = oce_page_list(eq->ring, &fwcmd->params.req.pages[0]);
17742f345d8eSLuigi Rizzo 	fwcmd->params.req.ctx.num_pages = num_pages;
17752f345d8eSLuigi Rizzo 	fwcmd->params.req.ctx.valid = 1;
17762f345d8eSLuigi Rizzo 	fwcmd->params.req.ctx.size = (eq->eq_cfg.item_size == 4) ? 0 : 1;
17772f345d8eSLuigi Rizzo 	fwcmd->params.req.ctx.count = OCE_LOG2(eq->eq_cfg.q_len / 256);
17782f345d8eSLuigi Rizzo 	fwcmd->params.req.ctx.armed = 0;
17792f345d8eSLuigi Rizzo 	fwcmd->params.req.ctx.delay_mult = eq->eq_cfg.cur_eqd;
17802f345d8eSLuigi Rizzo 
17812f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
17822f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_create_common_eq);
17832f345d8eSLuigi Rizzo 
17842f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1785cdaba892SXin LI 	if (!rc)
1786cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1787cdaba892SXin LI 	if (rc) {
17885fbb6830SXin LI 		device_printf(sc->dev,
17895fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
17905fbb6830SXin LI 			      __FUNCTION__, rc,
17915fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
17922f345d8eSLuigi Rizzo 		goto error;
1793cdaba892SXin LI 	}
17945fbb6830SXin LI 	eq->eq_id = HOST_16(fwcmd->params.rsp.eq_id);
17952f345d8eSLuigi Rizzo error:
17962f345d8eSLuigi Rizzo 	return rc;
17972f345d8eSLuigi Rizzo }
17982f345d8eSLuigi Rizzo 
17992f345d8eSLuigi Rizzo int
18002f345d8eSLuigi Rizzo oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable)
18012f345d8eSLuigi Rizzo {
18022f345d8eSLuigi Rizzo 	struct oce_mbx mbx;
18032f345d8eSLuigi Rizzo 	struct mbx_create_common_cq *fwcmd;
18042f345d8eSLuigi Rizzo 	POCE_SOFTC sc = cq->parent;
18052f345d8eSLuigi Rizzo 	uint8_t version;
18062f345d8eSLuigi Rizzo 	oce_cq_ctx_t *ctx;
18072f345d8eSLuigi Rizzo 	uint32_t num_pages, page_size;
18082f345d8eSLuigi Rizzo 	int rc = 0;
18092f345d8eSLuigi Rizzo 
18102f345d8eSLuigi Rizzo 	bzero(&mbx, sizeof(struct oce_mbx));
18112f345d8eSLuigi Rizzo 
18122f345d8eSLuigi Rizzo 	fwcmd = (struct mbx_create_common_cq *)&mbx.payload;
18132f345d8eSLuigi Rizzo 
18142f345d8eSLuigi Rizzo 	if (IS_XE201(sc))
18152f345d8eSLuigi Rizzo 		version = OCE_MBX_VER_V2;
18162f345d8eSLuigi Rizzo 	else
18172f345d8eSLuigi Rizzo 		version = OCE_MBX_VER_V0;
18182f345d8eSLuigi Rizzo 
18192f345d8eSLuigi Rizzo 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
18202f345d8eSLuigi Rizzo 				MBX_SUBSYSTEM_COMMON,
18212f345d8eSLuigi Rizzo 				OPCODE_COMMON_CREATE_CQ,
18222f345d8eSLuigi Rizzo 				MBX_TIMEOUT_SEC,
18232f345d8eSLuigi Rizzo 				sizeof(struct mbx_create_common_cq),
18242f345d8eSLuigi Rizzo 				version);
18252f345d8eSLuigi Rizzo 
18262f345d8eSLuigi Rizzo 	ctx = &fwcmd->params.req.cq_ctx;
18272f345d8eSLuigi Rizzo 
18282f345d8eSLuigi Rizzo 	num_pages = oce_page_list(cq->ring, &fwcmd->params.req.pages[0]);
18292f345d8eSLuigi Rizzo 	page_size =  1;  /* 1 for 4K */
18302f345d8eSLuigi Rizzo 
18312f345d8eSLuigi Rizzo 	if (version == OCE_MBX_VER_V2) {
18322f345d8eSLuigi Rizzo 		ctx->v2.num_pages = LE_16(num_pages);
18332f345d8eSLuigi Rizzo 		ctx->v2.page_size = page_size;
18342f345d8eSLuigi Rizzo 		ctx->v2.eventable = is_eventable;
18352f345d8eSLuigi Rizzo 		ctx->v2.valid = 1;
18362f345d8eSLuigi Rizzo 		ctx->v2.count = OCE_LOG2(cq->cq_cfg.q_len / 256);
18372f345d8eSLuigi Rizzo 		ctx->v2.nodelay = cq->cq_cfg.nodelay;
18382f345d8eSLuigi Rizzo 		ctx->v2.coalesce_wm = ncoalesce;
18392f345d8eSLuigi Rizzo 		ctx->v2.armed = 0;
18402f345d8eSLuigi Rizzo 		ctx->v2.eq_id = cq->eq->eq_id;
18412f345d8eSLuigi Rizzo 		if (ctx->v2.count == 3) {
1842c236d647SWarner Losh 			if ((u_int)cq->cq_cfg.q_len > (4*1024)-1)
18432f345d8eSLuigi Rizzo 				ctx->v2.cqe_count = (4*1024)-1;
18442f345d8eSLuigi Rizzo 			else
18452f345d8eSLuigi Rizzo 				ctx->v2.cqe_count = cq->cq_cfg.q_len;
18462f345d8eSLuigi Rizzo 		}
18472f345d8eSLuigi Rizzo 	} else {
18482f345d8eSLuigi Rizzo 		ctx->v0.num_pages = LE_16(num_pages);
18492f345d8eSLuigi Rizzo 		ctx->v0.eventable = is_eventable;
18502f345d8eSLuigi Rizzo 		ctx->v0.valid = 1;
18512f345d8eSLuigi Rizzo 		ctx->v0.count = OCE_LOG2(cq->cq_cfg.q_len / 256);
18522f345d8eSLuigi Rizzo 		ctx->v0.nodelay = cq->cq_cfg.nodelay;
18532f345d8eSLuigi Rizzo 		ctx->v0.coalesce_wm = ncoalesce;
18542f345d8eSLuigi Rizzo 		ctx->v0.armed = 0;
18552f345d8eSLuigi Rizzo 		ctx->v0.eq_id = cq->eq->eq_id;
18562f345d8eSLuigi Rizzo 	}
18572f345d8eSLuigi Rizzo 
18582f345d8eSLuigi Rizzo 	mbx.u0.s.embedded = 1;
18592f345d8eSLuigi Rizzo 	mbx.payload_length = sizeof(struct mbx_create_common_cq);
18602f345d8eSLuigi Rizzo 
18612f345d8eSLuigi Rizzo 	rc = oce_mbox_post(sc, &mbx, NULL);
1862cdaba892SXin LI 	if (!rc)
1863cdaba892SXin LI                 rc = fwcmd->hdr.u0.rsp.status;
1864cdaba892SXin LI 	if (rc) {
18655fbb6830SXin LI 		device_printf(sc->dev,
18665fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
18675fbb6830SXin LI 			      __FUNCTION__, rc,
18685fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
18692f345d8eSLuigi Rizzo 		goto error;
1870cdaba892SXin LI 	}
18715fbb6830SXin LI 	cq->cq_id = HOST_16(fwcmd->params.rsp.cq_id);
18722f345d8eSLuigi Rizzo error:
18732f345d8eSLuigi Rizzo 	return rc;
18742f345d8eSLuigi Rizzo 
18752f345d8eSLuigi Rizzo }
1876cdaba892SXin LI 
1877cdaba892SXin LI int
1878cdaba892SXin LI oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
1879cdaba892SXin LI {
1880cdaba892SXin LI 	int rc = 0;
1881cdaba892SXin LI 	struct oce_mbx mbx;
1882cdaba892SXin LI 	struct mbx_read_common_transrecv_data *fwcmd;
1883cdaba892SXin LI 	struct oce_mq_sge *sgl;
1884cdaba892SXin LI 	OCE_DMA_MEM dma;
1885cdaba892SXin LI 
1886cdaba892SXin LI 	/* Allocate DMA mem*/
1887cdaba892SXin LI 	if (oce_dma_alloc(sc, sizeof(struct mbx_read_common_transrecv_data),
1888cdaba892SXin LI 				&dma, 0))
1889cdaba892SXin LI 		return ENOMEM;
1890cdaba892SXin LI 
1891cdaba892SXin LI 	fwcmd = OCE_DMAPTR(&dma, struct mbx_read_common_transrecv_data);
1892cdaba892SXin LI 	bzero(fwcmd, sizeof(struct mbx_read_common_transrecv_data));
1893cdaba892SXin LI 
1894cdaba892SXin LI 	bzero(&mbx, sizeof(struct oce_mbx));
1895cdaba892SXin LI 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1896cdaba892SXin LI 			MBX_SUBSYSTEM_COMMON,
1897cdaba892SXin LI 			OPCODE_COMMON_READ_TRANSRECEIVER_DATA,
1898cdaba892SXin LI 			MBX_TIMEOUT_SEC,
1899cdaba892SXin LI 			sizeof(struct mbx_read_common_transrecv_data),
1900cdaba892SXin LI 			OCE_MBX_VER_V0);
1901cdaba892SXin LI 
1902cdaba892SXin LI 	/* fill rest of mbx */
1903cdaba892SXin LI 	mbx.u0.s.embedded = 0;
1904cdaba892SXin LI 	mbx.payload_length = sizeof(struct mbx_read_common_transrecv_data);
1905cdaba892SXin LI 	mbx.u0.s.sge_count = 1;
1906cdaba892SXin LI 	sgl = &mbx.payload.u0.u1.sgl[0];
1907cdaba892SXin LI 	sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
1908cdaba892SXin LI 	sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
1909cdaba892SXin LI 	sgl->length = htole32(mbx.payload_length);
1910cdaba892SXin LI 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
1911cdaba892SXin LI 
1912cdaba892SXin LI 	fwcmd->params.req.port = LE_32(sc->port_id);
1913cdaba892SXin LI 	fwcmd->params.req.page_num = LE_32(page_num);
1914cdaba892SXin LI 
1915cdaba892SXin LI 	/* command post */
1916cdaba892SXin LI 	rc = oce_mbox_post(sc, &mbx, NULL);
1917cdaba892SXin LI 	if (!rc)
1918cdaba892SXin LI 		rc = fwcmd->hdr.u0.rsp.status;
1919cdaba892SXin LI 	if (rc) {
19205fbb6830SXin LI 		device_printf(sc->dev,
19215fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
19225fbb6830SXin LI 			      __FUNCTION__, rc,
19235fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
1924cdaba892SXin LI 		goto error;
1925cdaba892SXin LI 	}
1926cdaba892SXin LI 	if(fwcmd->params.rsp.page_num == PAGE_NUM_A0)
1927cdaba892SXin LI 	{
1928cdaba892SXin LI 		bcopy((char *)fwcmd->params.rsp.page_data,
1929e0dd0fe3SXin LI 		      &sfp_vpd_dump_buffer[0],
1930cdaba892SXin LI 		      TRANSCEIVER_A0_SIZE);
1931cdaba892SXin LI 	}
1932cdaba892SXin LI 
1933cdaba892SXin LI 	if(fwcmd->params.rsp.page_num == PAGE_NUM_A2)
1934cdaba892SXin LI 	{
1935cdaba892SXin LI 		bcopy((char *)fwcmd->params.rsp.page_data,
1936e0dd0fe3SXin LI 		      &sfp_vpd_dump_buffer[TRANSCEIVER_A0_SIZE],
1937cdaba892SXin LI 		      TRANSCEIVER_A2_SIZE);
1938cdaba892SXin LI 	}
1939cdaba892SXin LI error:
1940291a1934SXin LI 	oce_dma_free(sc, &dma);
1941cdaba892SXin LI 	return rc;
1942cdaba892SXin LI }
1943cdaba892SXin LI 
1944cdaba892SXin LI void
1945cdaba892SXin LI oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
1946cdaba892SXin LI 				int num)
1947cdaba892SXin LI {
1948cdaba892SXin LI 	struct oce_mbx mbx;
1949cdaba892SXin LI 	struct mbx_modify_common_eq_delay *fwcmd;
1950cdaba892SXin LI 	int rc = 0;
1951cdaba892SXin LI 	int i = 0;
1952cdaba892SXin LI 
1953cdaba892SXin LI 	bzero(&mbx, sizeof(struct oce_mbx));
1954cdaba892SXin LI 
1955cdaba892SXin LI 	/* Initialize MODIFY_EQ_DELAY ioctl header */
1956cdaba892SXin LI 	fwcmd = (struct mbx_modify_common_eq_delay *)&mbx.payload;
1957cdaba892SXin LI 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1958cdaba892SXin LI 				MBX_SUBSYSTEM_COMMON,
1959cdaba892SXin LI 				OPCODE_COMMON_MODIFY_EQ_DELAY,
1960cdaba892SXin LI 				MBX_TIMEOUT_SEC,
1961cdaba892SXin LI 				sizeof(struct mbx_modify_common_eq_delay),
1962cdaba892SXin LI 				OCE_MBX_VER_V0);
1963cdaba892SXin LI 	/* fill rest of mbx */
1964cdaba892SXin LI 	mbx.u0.s.embedded = 1;
1965cdaba892SXin LI 	mbx.payload_length = sizeof(struct mbx_modify_common_eq_delay);
1966cdaba892SXin LI 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
1967cdaba892SXin LI 
1968cdaba892SXin LI 	fwcmd->params.req.num_eq = num;
1969cdaba892SXin LI 	for (i = 0; i < num; i++) {
1970cdaba892SXin LI 		fwcmd->params.req.delay[i].eq_id =
1971cdaba892SXin LI 					htole32(set_eqd[i].eq_id);
1972cdaba892SXin LI 		fwcmd->params.req.delay[i].phase = 0;
1973cdaba892SXin LI 		fwcmd->params.req.delay[i].dm =
1974cdaba892SXin LI 		htole32(set_eqd[i].delay_multiplier);
1975cdaba892SXin LI 	}
1976cdaba892SXin LI 
1977cdaba892SXin LI 	/* command post */
1978cdaba892SXin LI 	rc = oce_mbox_post(sc, &mbx, NULL);
1979cdaba892SXin LI 
1980cdaba892SXin LI 	if (!rc)
1981cdaba892SXin LI 		rc = fwcmd->hdr.u0.rsp.status;
1982cdaba892SXin LI 	if (rc)
19835fbb6830SXin LI 		device_printf(sc->dev,
19845fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
19855fbb6830SXin LI 			      __FUNCTION__, rc,
19865fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
1987cdaba892SXin LI }
1988cdaba892SXin LI 
1989291a1934SXin LI int
1990b41206d8SXin LI oce_get_profile_config(POCE_SOFTC sc, uint32_t max_rss)
1991291a1934SXin LI {
1992291a1934SXin LI 	struct oce_mbx mbx;
1993291a1934SXin LI 	struct mbx_common_get_profile_config *fwcmd;
1994291a1934SXin LI 	int rc = 0;
1995291a1934SXin LI 	int version = 0;
1996291a1934SXin LI 	struct oce_mq_sge *sgl;
1997291a1934SXin LI 	OCE_DMA_MEM dma;
1998291a1934SXin LI 	uint32_t desc_count = 0;
1999291a1934SXin LI 	struct oce_nic_resc_desc *nic_desc = NULL;
2000291a1934SXin LI 	int i;
2001291a1934SXin LI 	boolean_t nic_desc_valid = FALSE;
2002cdaba892SXin LI 
2003291a1934SXin LI 	if (IS_BE2(sc))
2004291a1934SXin LI 		return -1;
2005291a1934SXin LI 
2006291a1934SXin LI 	/* Allocate DMA mem*/
2007291a1934SXin LI 	if (oce_dma_alloc(sc, sizeof(struct mbx_common_get_profile_config),
2008291a1934SXin LI 			  &dma, 0))
2009291a1934SXin LI 		return ENOMEM;
2010291a1934SXin LI 
2011291a1934SXin LI 	/* Initialize MODIFY_EQ_DELAY ioctl header */
2012291a1934SXin LI 	fwcmd = OCE_DMAPTR(&dma, struct mbx_common_get_profile_config);
2013291a1934SXin LI 	bzero(fwcmd, sizeof(struct mbx_common_get_profile_config));
2014291a1934SXin LI 
2015b41206d8SXin LI 	if (!IS_XE201(sc))
2016291a1934SXin LI 		version = OCE_MBX_VER_V1;
2017291a1934SXin LI 	else
2018291a1934SXin LI 		version = OCE_MBX_VER_V0;
2019291a1934SXin LI 
2020291a1934SXin LI 	bzero(&mbx, sizeof(struct oce_mbx));
2021291a1934SXin LI 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
2022291a1934SXin LI 				MBX_SUBSYSTEM_COMMON,
2023291a1934SXin LI 				OPCODE_COMMON_GET_PROFILE_CONFIG,
2024291a1934SXin LI 				MBX_TIMEOUT_SEC,
2025291a1934SXin LI 				sizeof(struct mbx_common_get_profile_config),
2026291a1934SXin LI 				version);
2027291a1934SXin LI 	/* fill rest of mbx */
2028291a1934SXin LI 	mbx.u0.s.embedded = 0;
2029291a1934SXin LI 	mbx.payload_length = sizeof(struct mbx_common_get_profile_config);
2030291a1934SXin LI 	mbx.u0.s.sge_count = 1;
2031291a1934SXin LI 	sgl = &mbx.payload.u0.u1.sgl[0];
2032291a1934SXin LI 	sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
2033291a1934SXin LI 	sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
2034291a1934SXin LI 	sgl->length = htole32(mbx.payload_length);
2035291a1934SXin LI 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
2036291a1934SXin LI 
2037291a1934SXin LI 	fwcmd->params.req.type = ACTIVE_PROFILE;
2038291a1934SXin LI 
2039291a1934SXin LI 	/* command post */
2040291a1934SXin LI 	rc = oce_mbox_post(sc, &mbx, NULL);
2041291a1934SXin LI 	if (!rc)
2042291a1934SXin LI 		rc = fwcmd->hdr.u0.rsp.status;
2043291a1934SXin LI 	if (rc) {
20445fbb6830SXin LI 		device_printf(sc->dev,
20455fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
20465fbb6830SXin LI 			      __FUNCTION__, rc,
20475fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
2048291a1934SXin LI 		goto error;
2049291a1934SXin LI 	}
2050291a1934SXin LI 
2051291a1934SXin LI 	nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
2052291a1934SXin LI 	desc_count = HOST_32(fwcmd->params.rsp.desc_count);
2053291a1934SXin LI 	for (i = 0; i < desc_count; i++) {
2054291a1934SXin LI 		if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
2055291a1934SXin LI 		    (nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
2056291a1934SXin LI 			nic_desc_valid = TRUE;
2057291a1934SXin LI 			break;
2058291a1934SXin LI 		}
2059291a1934SXin LI 		nic_desc = (struct oce_nic_resc_desc *) \
2060291a1934SXin LI 				((char *)nic_desc + nic_desc->desc_len);
2061291a1934SXin LI 	}
2062291a1934SXin LI 	if (!nic_desc_valid) {
2063291a1934SXin LI 		rc = -1;
2064291a1934SXin LI 		goto error;
2065291a1934SXin LI 	}
2066291a1934SXin LI 	else {
2067b41206d8SXin LI 		sc->max_vlans = HOST_16(nic_desc->vlan_count);
2068b41206d8SXin LI 		sc->nwqs = HOST_16(nic_desc->txq_count);
2069291a1934SXin LI 		if (sc->nwqs)
2070291a1934SXin LI 			sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
2071291a1934SXin LI 		else
2072291a1934SXin LI 			sc->nwqs = OCE_MAX_WQ;
2073291a1934SXin LI 
2074b41206d8SXin LI 		sc->nrssqs = HOST_16(nic_desc->rssq_count);
2075b41206d8SXin LI 		if (sc->nrssqs)
2076b41206d8SXin LI 			sc->nrssqs = MIN(sc->nrssqs, max_rss);
2077b41206d8SXin LI 		else
2078b41206d8SXin LI 			sc->nrssqs = max_rss;
207974b8d63dSPedro F. Giffuni 		sc->nrqs =  sc->nrssqs + 1; /* 1 for def RX */
2080291a1934SXin LI 	}
2081291a1934SXin LI error:
2082291a1934SXin LI 	oce_dma_free(sc, &dma);
2083291a1934SXin LI 	return rc;
2084291a1934SXin LI 
2085291a1934SXin LI }
2086291a1934SXin LI 
2087291a1934SXin LI int
2088291a1934SXin LI oce_get_func_config(POCE_SOFTC sc)
2089291a1934SXin LI {
2090291a1934SXin LI 	struct oce_mbx mbx;
2091291a1934SXin LI 	struct mbx_common_get_func_config *fwcmd;
2092291a1934SXin LI 	int rc = 0;
2093291a1934SXin LI 	int version = 0;
2094291a1934SXin LI 	struct oce_mq_sge *sgl;
2095291a1934SXin LI 	OCE_DMA_MEM dma;
2096291a1934SXin LI 	uint32_t desc_count = 0;
2097291a1934SXin LI 	struct oce_nic_resc_desc *nic_desc = NULL;
2098291a1934SXin LI 	int i;
2099291a1934SXin LI 	boolean_t nic_desc_valid = FALSE;
2100291a1934SXin LI 	uint32_t max_rss = 0;
2101291a1934SXin LI 
2102291a1934SXin LI 	if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
2103291a1934SXin LI 		max_rss = OCE_LEGACY_MODE_RSS;
2104291a1934SXin LI 	else
2105291a1934SXin LI 		max_rss = OCE_MAX_RSS;
2106291a1934SXin LI 
2107291a1934SXin LI 	/* Allocate DMA mem*/
2108291a1934SXin LI 	if (oce_dma_alloc(sc, sizeof(struct mbx_common_get_func_config),
2109291a1934SXin LI 			  &dma, 0))
2110291a1934SXin LI 		return ENOMEM;
2111291a1934SXin LI 
2112291a1934SXin LI 	/* Initialize MODIFY_EQ_DELAY ioctl header */
2113291a1934SXin LI 	fwcmd = OCE_DMAPTR(&dma, struct mbx_common_get_func_config);
2114291a1934SXin LI 	bzero(fwcmd, sizeof(struct mbx_common_get_func_config));
2115291a1934SXin LI 
2116291a1934SXin LI 	if (IS_SH(sc))
2117291a1934SXin LI 		version = OCE_MBX_VER_V1;
2118291a1934SXin LI 	else
2119291a1934SXin LI 		version = OCE_MBX_VER_V0;
2120291a1934SXin LI 
2121291a1934SXin LI 	bzero(&mbx, sizeof(struct oce_mbx));
2122291a1934SXin LI 	mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
2123291a1934SXin LI 				MBX_SUBSYSTEM_COMMON,
2124291a1934SXin LI 				OPCODE_COMMON_GET_FUNCTION_CONFIG,
2125291a1934SXin LI 				MBX_TIMEOUT_SEC,
2126291a1934SXin LI 				sizeof(struct mbx_common_get_func_config),
2127291a1934SXin LI 				version);
2128291a1934SXin LI 	/* fill rest of mbx */
2129291a1934SXin LI 	mbx.u0.s.embedded = 0;
2130291a1934SXin LI 	mbx.payload_length = sizeof(struct mbx_common_get_func_config);
2131291a1934SXin LI 	mbx.u0.s.sge_count = 1;
2132291a1934SXin LI 	sgl = &mbx.payload.u0.u1.sgl[0];
2133291a1934SXin LI 	sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
2134291a1934SXin LI 	sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
2135291a1934SXin LI 	sgl->length = htole32(mbx.payload_length);
2136291a1934SXin LI 	DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
2137291a1934SXin LI 
2138291a1934SXin LI 	/* command post */
2139291a1934SXin LI 	rc = oce_mbox_post(sc, &mbx, NULL);
2140291a1934SXin LI 	if (!rc)
2141291a1934SXin LI 		rc = fwcmd->hdr.u0.rsp.status;
2142291a1934SXin LI 	if (rc) {
21435fbb6830SXin LI 		device_printf(sc->dev,
21445fbb6830SXin LI 			      "%s failed - cmd status: %d addi status: %d\n",
21455fbb6830SXin LI 			      __FUNCTION__, rc,
21465fbb6830SXin LI 			      fwcmd->hdr.u0.rsp.additional_status);
2147291a1934SXin LI 		goto error;
2148291a1934SXin LI 	}
2149291a1934SXin LI 
2150291a1934SXin LI 	nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
2151291a1934SXin LI 	desc_count = HOST_32(fwcmd->params.rsp.desc_count);
2152291a1934SXin LI 	for (i = 0; i < desc_count; i++) {
2153291a1934SXin LI 		if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
2154291a1934SXin LI 		    (nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
2155291a1934SXin LI 			nic_desc_valid = TRUE;
2156291a1934SXin LI 			break;
2157291a1934SXin LI 		}
2158291a1934SXin LI 		nic_desc = (struct oce_nic_resc_desc *) \
2159291a1934SXin LI 				((char *)nic_desc + nic_desc->desc_len);
2160291a1934SXin LI 	}
2161291a1934SXin LI 	if (!nic_desc_valid) {
2162291a1934SXin LI 		rc = -1;
2163291a1934SXin LI 		goto error;
2164291a1934SXin LI 	}
2165291a1934SXin LI 	else {
21665fbb6830SXin LI 		sc->max_vlans = nic_desc->vlan_count;
2167291a1934SXin LI 		sc->nwqs = HOST_32(nic_desc->txq_count);
2168291a1934SXin LI                 if (sc->nwqs)
2169291a1934SXin LI                         sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
2170291a1934SXin LI                 else
2171291a1934SXin LI                         sc->nwqs = OCE_MAX_WQ;
2172291a1934SXin LI 
2173291a1934SXin LI 		sc->nrssqs = HOST_32(nic_desc->rssq_count);
2174291a1934SXin LI 		if (sc->nrssqs)
2175291a1934SXin LI 			sc->nrssqs = MIN(sc->nrssqs, max_rss);
2176291a1934SXin LI 		else
2177291a1934SXin LI 			sc->nrssqs = max_rss;
217874b8d63dSPedro F. Giffuni 		sc->nrqs =  sc->nrssqs + 1; /* 1 for def RX */
2179291a1934SXin LI 	}
2180291a1934SXin LI error:
2181291a1934SXin LI 	oce_dma_free(sc, &dma);
2182291a1934SXin LI 	return rc;
2183291a1934SXin LI 
2184291a1934SXin LI }
2185c2625e6eSJosh Paetzel 
2186c2625e6eSJosh Paetzel /* hw lro functions */
2187c2625e6eSJosh Paetzel 
2188c2625e6eSJosh Paetzel int
2189c2625e6eSJosh Paetzel oce_mbox_nic_query_lro_capabilities(POCE_SOFTC sc, uint32_t *lro_rq_cnt, uint32_t *lro_flags)
2190c2625e6eSJosh Paetzel {
2191c2625e6eSJosh Paetzel         struct oce_mbx mbx;
2192c2625e6eSJosh Paetzel         struct mbx_nic_query_lro_capabilities *fwcmd;
2193c2625e6eSJosh Paetzel         int rc = 0;
2194c2625e6eSJosh Paetzel 
2195c2625e6eSJosh Paetzel         bzero(&mbx, sizeof(struct oce_mbx));
2196c2625e6eSJosh Paetzel 
2197c2625e6eSJosh Paetzel         fwcmd = (struct mbx_nic_query_lro_capabilities *)&mbx.payload;
2198c2625e6eSJosh Paetzel         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
2199c2625e6eSJosh Paetzel                                 MBX_SUBSYSTEM_NIC,
2200c2625e6eSJosh Paetzel                                 0x20,MBX_TIMEOUT_SEC,
2201c2625e6eSJosh Paetzel                                 sizeof(struct mbx_nic_query_lro_capabilities),
2202c2625e6eSJosh Paetzel                                 OCE_MBX_VER_V0);
2203c2625e6eSJosh Paetzel 
2204c2625e6eSJosh Paetzel         mbx.u0.s.embedded = 1;
2205c2625e6eSJosh Paetzel         mbx.payload_length = sizeof(struct mbx_nic_query_lro_capabilities);
2206c2625e6eSJosh Paetzel 
2207c2625e6eSJosh Paetzel         rc = oce_mbox_post(sc, &mbx, NULL);
2208c2625e6eSJosh Paetzel         if (!rc)
2209c2625e6eSJosh Paetzel                 rc = fwcmd->hdr.u0.rsp.status;
2210c2625e6eSJosh Paetzel         if (rc) {
2211c2625e6eSJosh Paetzel                 device_printf(sc->dev,
2212c2625e6eSJosh Paetzel                               "%s failed - cmd status: %d addi status: %d\n",
2213c2625e6eSJosh Paetzel                               __FUNCTION__, rc,
2214c2625e6eSJosh Paetzel                               fwcmd->hdr.u0.rsp.additional_status);
2215c2625e6eSJosh Paetzel 
2216c2625e6eSJosh Paetzel                 return rc;
2217c2625e6eSJosh Paetzel         }
2218c2625e6eSJosh Paetzel         if(lro_flags)
2219c2625e6eSJosh Paetzel                 *lro_flags = HOST_32(fwcmd->params.rsp.lro_flags);
2220c2625e6eSJosh Paetzel 
2221c2625e6eSJosh Paetzel         if(lro_rq_cnt)
2222c2625e6eSJosh Paetzel                 *lro_rq_cnt = HOST_16(fwcmd->params.rsp.lro_rq_cnt);
2223c2625e6eSJosh Paetzel 
2224c2625e6eSJosh Paetzel         return rc;
2225c2625e6eSJosh Paetzel }
2226c2625e6eSJosh Paetzel 
2227c2625e6eSJosh Paetzel int
2228c2625e6eSJosh Paetzel oce_mbox_nic_set_iface_lro_config(POCE_SOFTC sc, int enable)
2229c2625e6eSJosh Paetzel {
2230c2625e6eSJosh Paetzel         struct oce_mbx mbx;
2231c2625e6eSJosh Paetzel         struct mbx_nic_set_iface_lro_config *fwcmd;
2232c2625e6eSJosh Paetzel         int rc = 0;
2233c2625e6eSJosh Paetzel 
2234c2625e6eSJosh Paetzel         bzero(&mbx, sizeof(struct oce_mbx));
2235c2625e6eSJosh Paetzel 
2236c2625e6eSJosh Paetzel         fwcmd = (struct mbx_nic_set_iface_lro_config *)&mbx.payload;
2237c2625e6eSJosh Paetzel         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
2238c2625e6eSJosh Paetzel                                 MBX_SUBSYSTEM_NIC,
2239c2625e6eSJosh Paetzel                                 0x26,MBX_TIMEOUT_SEC,
2240c2625e6eSJosh Paetzel                                 sizeof(struct mbx_nic_set_iface_lro_config),
2241c2625e6eSJosh Paetzel                                 OCE_MBX_VER_V0);
2242c2625e6eSJosh Paetzel 
2243c2625e6eSJosh Paetzel         mbx.u0.s.embedded = 1;
2244c2625e6eSJosh Paetzel         mbx.payload_length = sizeof(struct mbx_nic_set_iface_lro_config);
2245c2625e6eSJosh Paetzel 
2246c2625e6eSJosh Paetzel         fwcmd->params.req.iface_id = sc->if_id;
2247c2625e6eSJosh Paetzel         fwcmd->params.req.lro_flags = 0;
2248c2625e6eSJosh Paetzel 
2249c2625e6eSJosh Paetzel         if(enable) {
2250c2625e6eSJosh Paetzel                 fwcmd->params.req.lro_flags = LRO_FLAGS_HASH_MODE | LRO_FLAGS_RSS_MODE;
2251c2625e6eSJosh Paetzel                 fwcmd->params.req.lro_flags |= LRO_FLAGS_CLSC_IPV4 | LRO_FLAGS_CLSC_IPV6;
2252c2625e6eSJosh Paetzel 
2253c2625e6eSJosh Paetzel                 fwcmd->params.req.max_clsc_byte_cnt = 64*1024; /* min = 2974, max = 0xfa59 */
2254c2625e6eSJosh Paetzel                 fwcmd->params.req.max_clsc_seg_cnt = 43; /* min = 2, max = 64 */
2255c2625e6eSJosh Paetzel                 fwcmd->params.req.max_clsc_usec_delay = 18; /* min = 1, max = 256 */
2256c2625e6eSJosh Paetzel                 fwcmd->params.req.min_clsc_frame_byte_cnt = 0; /* min = 1, max = 9014 */
2257c2625e6eSJosh Paetzel         }
2258c2625e6eSJosh Paetzel 
2259c2625e6eSJosh Paetzel         rc = oce_mbox_post(sc, &mbx, NULL);
2260c2625e6eSJosh Paetzel         if (!rc)
2261c2625e6eSJosh Paetzel                 rc = fwcmd->hdr.u0.rsp.status;
2262c2625e6eSJosh Paetzel         if (rc) {
2263c2625e6eSJosh Paetzel                 device_printf(sc->dev,
2264c2625e6eSJosh Paetzel                               "%s failed - cmd status: %d addi status: %d\n",
2265c2625e6eSJosh Paetzel                               __FUNCTION__, rc,
2266c2625e6eSJosh Paetzel                               fwcmd->hdr.u0.rsp.additional_status);
2267c2625e6eSJosh Paetzel 
2268c2625e6eSJosh Paetzel                 return rc;
2269c2625e6eSJosh Paetzel         }
2270c2625e6eSJosh Paetzel         return rc;
2271c2625e6eSJosh Paetzel }
2272c2625e6eSJosh Paetzel 
2273c2625e6eSJosh Paetzel int
2274c2625e6eSJosh Paetzel oce_mbox_create_rq_v2(struct oce_rq *rq)
2275c2625e6eSJosh Paetzel {
2276c2625e6eSJosh Paetzel         struct oce_mbx mbx;
2277c2625e6eSJosh Paetzel         struct mbx_create_nic_rq_v2 *fwcmd;
2278c2625e6eSJosh Paetzel         POCE_SOFTC sc = rq->parent;
2279c2625e6eSJosh Paetzel         int rc = 0, num_pages = 0;
2280c2625e6eSJosh Paetzel 
2281c2625e6eSJosh Paetzel         if (rq->qstate == QCREATED)
2282c2625e6eSJosh Paetzel                 return 0;
2283c2625e6eSJosh Paetzel 
2284c2625e6eSJosh Paetzel         bzero(&mbx, sizeof(struct oce_mbx));
2285c2625e6eSJosh Paetzel 
2286c2625e6eSJosh Paetzel         fwcmd = (struct mbx_create_nic_rq_v2 *)&mbx.payload;
2287c2625e6eSJosh Paetzel         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
2288c2625e6eSJosh Paetzel                                 MBX_SUBSYSTEM_NIC,
2289c2625e6eSJosh Paetzel                                 0x08, MBX_TIMEOUT_SEC,
2290c2625e6eSJosh Paetzel                                 sizeof(struct mbx_create_nic_rq_v2),
2291c2625e6eSJosh Paetzel                                 OCE_MBX_VER_V2);
2292c2625e6eSJosh Paetzel 
2293c2625e6eSJosh Paetzel         /* oce_page_list will also prepare pages */
2294c2625e6eSJosh Paetzel         num_pages = oce_page_list(rq->ring, &fwcmd->params.req.pages[0]);
2295c2625e6eSJosh Paetzel 
2296c2625e6eSJosh Paetzel         fwcmd->params.req.cq_id = rq->cq->cq_id;
2297c2625e6eSJosh Paetzel         fwcmd->params.req.frag_size = rq->cfg.frag_size/2048;
2298c2625e6eSJosh Paetzel         fwcmd->params.req.num_pages = num_pages;
2299c2625e6eSJosh Paetzel 
2300c2625e6eSJosh Paetzel         fwcmd->params.req.if_id = sc->if_id;
2301c2625e6eSJosh Paetzel 
2302c2625e6eSJosh Paetzel         fwcmd->params.req.max_frame_size = rq->cfg.mtu;
2303c2625e6eSJosh Paetzel         fwcmd->params.req.page_size = 1;
2304c2625e6eSJosh Paetzel         if(rq->cfg.is_rss_queue) {
2305c2625e6eSJosh Paetzel                 fwcmd->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO);
2306c2625e6eSJosh Paetzel         }else {
2307c2625e6eSJosh Paetzel                 device_printf(sc->dev,
2308c2625e6eSJosh Paetzel                         "non rss lro queue should not be created \n");
2309c2625e6eSJosh Paetzel                 goto error;
2310c2625e6eSJosh Paetzel         }
2311c2625e6eSJosh Paetzel         mbx.u0.s.embedded = 1;
2312c2625e6eSJosh Paetzel         mbx.payload_length = sizeof(struct mbx_create_nic_rq_v2);
2313c2625e6eSJosh Paetzel 
2314c2625e6eSJosh Paetzel         rc = oce_mbox_post(sc, &mbx, NULL);
2315c2625e6eSJosh Paetzel         if (!rc)
2316c2625e6eSJosh Paetzel                 rc = fwcmd->hdr.u0.rsp.status;
2317c2625e6eSJosh Paetzel         if (rc) {
2318c2625e6eSJosh Paetzel                 device_printf(sc->dev,
2319c2625e6eSJosh Paetzel                               "%s failed - cmd status: %d addi status: %d\n",
2320c2625e6eSJosh Paetzel                               __FUNCTION__, rc,
2321c2625e6eSJosh Paetzel                               fwcmd->hdr.u0.rsp.additional_status);
2322c2625e6eSJosh Paetzel                 goto error;
2323c2625e6eSJosh Paetzel         }
2324c2625e6eSJosh Paetzel         rq->rq_id = HOST_16(fwcmd->params.rsp.rq_id);
2325c2625e6eSJosh Paetzel         rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
2326c2625e6eSJosh Paetzel 
2327c2625e6eSJosh Paetzel error:
2328c2625e6eSJosh Paetzel         return rc;
2329c2625e6eSJosh Paetzel }
2330