cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qlcnic_ctx.c (39622B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * QLogic qlcnic NIC Driver
      4 * Copyright (c) 2009-2013 QLogic Corporation
      5 */
      6
      7#include "qlcnic.h"
      8
      9static const struct qlcnic_mailbox_metadata qlcnic_mbx_tbl[] = {
     10	{QLCNIC_CMD_CREATE_RX_CTX, 4, 1},
     11	{QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
     12	{QLCNIC_CMD_CREATE_TX_CTX, 4, 1},
     13	{QLCNIC_CMD_DESTROY_TX_CTX, 3, 1},
     14	{QLCNIC_CMD_INTRPT_TEST, 4, 1},
     15	{QLCNIC_CMD_SET_MTU, 4, 1},
     16	{QLCNIC_CMD_READ_PHY, 4, 2},
     17	{QLCNIC_CMD_WRITE_PHY, 5, 1},
     18	{QLCNIC_CMD_READ_HW_REG, 4, 1},
     19	{QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
     20	{QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
     21	{QLCNIC_CMD_READ_MAX_MTU, 4, 2},
     22	{QLCNIC_CMD_READ_MAX_LRO, 4, 2},
     23	{QLCNIC_CMD_MAC_ADDRESS, 4, 3},
     24	{QLCNIC_CMD_GET_PCI_INFO, 4, 1},
     25	{QLCNIC_CMD_GET_NIC_INFO, 4, 1},
     26	{QLCNIC_CMD_SET_NIC_INFO, 4, 1},
     27	{QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
     28	{QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
     29	{QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
     30	{QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
     31	{QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
     32	{QLCNIC_CMD_GET_MAC_STATS, 4, 1},
     33	{QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
     34	{QLCNIC_CMD_GET_ESWITCH_STATS, 4, 1},
     35	{QLCNIC_CMD_CONFIG_PORT, 4, 1},
     36	{QLCNIC_CMD_TEMP_SIZE, 4, 4},
     37	{QLCNIC_CMD_GET_TEMP_HDR, 4, 1},
     38	{QLCNIC_CMD_82XX_SET_DRV_VER, 4, 1},
     39	{QLCNIC_CMD_GET_LED_STATUS, 4, 2},
     40	{QLCNIC_CMD_MQ_TX_CONFIG_INTR, 2, 3},
     41	{QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
     42	{QLCNIC_CMD_DCB_QUERY_PARAM, 4, 1},
     43};
     44
     45static inline u32 qlcnic_get_cmd_signature(struct qlcnic_hardware_context *ahw)
     46{
     47	return (ahw->pci_func & 0xff) | ((ahw->fw_hal_version & 0xff) << 8) |
     48	       (0xcafe << 16);
     49}
     50
     51/* Allocate mailbox registers */
     52int qlcnic_82xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
     53			       struct qlcnic_adapter *adapter, u32 type)
     54{
     55	int i, size;
     56	const struct qlcnic_mailbox_metadata *mbx_tbl;
     57
     58	mbx_tbl = qlcnic_mbx_tbl;
     59	size = ARRAY_SIZE(qlcnic_mbx_tbl);
     60	for (i = 0; i < size; i++) {
     61		if (type == mbx_tbl[i].cmd) {
     62			mbx->req.num = mbx_tbl[i].in_args;
     63			mbx->rsp.num = mbx_tbl[i].out_args;
     64			mbx->req.arg = kcalloc(mbx->req.num,
     65					       sizeof(u32), GFP_ATOMIC);
     66			if (!mbx->req.arg)
     67				return -ENOMEM;
     68			mbx->rsp.arg = kcalloc(mbx->rsp.num,
     69					       sizeof(u32), GFP_ATOMIC);
     70			if (!mbx->rsp.arg) {
     71				kfree(mbx->req.arg);
     72				mbx->req.arg = NULL;
     73				return -ENOMEM;
     74			}
     75			mbx->req.arg[0] = type;
     76			break;
     77		}
     78	}
     79	return 0;
     80}
     81
     82/* Free up mailbox registers */
     83void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd)
     84{
     85	kfree(cmd->req.arg);
     86	cmd->req.arg = NULL;
     87	kfree(cmd->rsp.arg);
     88	cmd->rsp.arg = NULL;
     89}
     90
     91static u32
     92qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
     93{
     94	u32 rsp;
     95	int timeout = 0, err = 0;
     96
     97	do {
     98		/* give atleast 1ms for firmware to respond */
     99		mdelay(1);
    100
    101		if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
    102			return QLCNIC_CDRP_RSP_TIMEOUT;
    103
    104		rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET, &err);
    105	} while (!QLCNIC_CDRP_IS_RSP(rsp));
    106
    107	return rsp;
    108}
    109
    110int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter,
    111			  struct qlcnic_cmd_args *cmd)
    112{
    113	int i, err = 0;
    114	u32 rsp;
    115	u32 signature;
    116	struct pci_dev *pdev = adapter->pdev;
    117	struct qlcnic_hardware_context *ahw = adapter->ahw;
    118	const char *fmt;
    119
    120	signature = qlcnic_get_cmd_signature(ahw);
    121
    122	/* Acquire semaphore before accessing CRB */
    123	if (qlcnic_api_lock(adapter)) {
    124		cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
    125		return cmd->rsp.arg[0];
    126	}
    127
    128	QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature);
    129	for (i = 1; i < cmd->req.num; i++)
    130		QLCWR32(adapter, QLCNIC_CDRP_ARG(i), cmd->req.arg[i]);
    131	QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET,
    132		QLCNIC_CDRP_FORM_CMD(cmd->req.arg[0]));
    133	rsp = qlcnic_poll_rsp(adapter);
    134
    135	if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
    136		dev_err(&pdev->dev, "command timeout, response = 0x%x\n", rsp);
    137		cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
    138	} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
    139		cmd->rsp.arg[0] = QLCRD32(adapter, QLCNIC_CDRP_ARG(1), &err);
    140		switch (cmd->rsp.arg[0]) {
    141		case QLCNIC_RCODE_INVALID_ARGS:
    142			fmt = "CDRP invalid args: [%d]\n";
    143			break;
    144		case QLCNIC_RCODE_NOT_SUPPORTED:
    145		case QLCNIC_RCODE_NOT_IMPL:
    146			fmt = "CDRP command not supported: [%d]\n";
    147			break;
    148		case QLCNIC_RCODE_NOT_PERMITTED:
    149			fmt = "CDRP requested action not permitted: [%d]\n";
    150			break;
    151		case QLCNIC_RCODE_INVALID:
    152			fmt = "CDRP invalid or unknown cmd received: [%d]\n";
    153			break;
    154		case QLCNIC_RCODE_TIMEOUT:
    155			fmt = "CDRP command timeout: [%d]\n";
    156			break;
    157		default:
    158			fmt = "CDRP command failed: [%d]\n";
    159			break;
    160		}
    161		dev_err(&pdev->dev, fmt, cmd->rsp.arg[0]);
    162		qlcnic_dump_mbx(adapter, cmd);
    163	} else if (rsp == QLCNIC_CDRP_RSP_OK)
    164		cmd->rsp.arg[0] = QLCNIC_RCODE_SUCCESS;
    165
    166	for (i = 1; i < cmd->rsp.num; i++)
    167		cmd->rsp.arg[i] = QLCRD32(adapter, QLCNIC_CDRP_ARG(i), &err);
    168
    169	/* Release semaphore */
    170	qlcnic_api_unlock(adapter);
    171	return cmd->rsp.arg[0];
    172}
    173
    174int qlcnic_fw_cmd_set_drv_version(struct qlcnic_adapter *adapter, u32 fw_cmd)
    175{
    176	struct qlcnic_cmd_args cmd;
    177	u32 arg1, arg2, arg3;
    178	char drv_string[12];
    179	int err = 0;
    180
    181	memset(drv_string, 0, sizeof(drv_string));
    182	snprintf(drv_string, sizeof(drv_string), "%d"".""%d"".""%d",
    183		 _QLCNIC_LINUX_MAJOR, _QLCNIC_LINUX_MINOR,
    184		 _QLCNIC_LINUX_SUBVERSION);
    185
    186	err = qlcnic_alloc_mbx_args(&cmd, adapter, fw_cmd);
    187	if (err)
    188		return err;
    189
    190	memcpy(&arg1, drv_string, sizeof(u32));
    191	memcpy(&arg2, drv_string + 4, sizeof(u32));
    192	memcpy(&arg3, drv_string + 8, sizeof(u32));
    193
    194	cmd.req.arg[1] = arg1;
    195	cmd.req.arg[2] = arg2;
    196	cmd.req.arg[3] = arg3;
    197
    198	err = qlcnic_issue_cmd(adapter, &cmd);
    199	if (err) {
    200		dev_info(&adapter->pdev->dev,
    201			 "Failed to set driver version in firmware\n");
    202		err = -EIO;
    203	}
    204	qlcnic_free_mbx_args(&cmd);
    205	return err;
    206}
    207
    208int
    209qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)
    210{
    211	int err = 0;
    212	struct qlcnic_cmd_args cmd;
    213	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
    214
    215	if (recv_ctx->state != QLCNIC_HOST_CTX_STATE_ACTIVE)
    216		return err;
    217	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_MTU);
    218	if (err)
    219		return err;
    220
    221	cmd.req.arg[1] = recv_ctx->context_id;
    222	cmd.req.arg[2] = mtu;
    223
    224	err = qlcnic_issue_cmd(adapter, &cmd);
    225	if (err) {
    226		dev_err(&adapter->pdev->dev, "Failed to set mtu\n");
    227		err = -EIO;
    228	}
    229	qlcnic_free_mbx_args(&cmd);
    230	return err;
    231}
    232
    233int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
    234{
    235	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
    236	struct qlcnic_hardware_context *ahw = adapter->ahw;
    237	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
    238	struct net_device *netdev = adapter->netdev;
    239	u32 temp_intr_crb_mode, temp_rds_crb_mode;
    240	struct qlcnic_cardrsp_rds_ring *prsp_rds;
    241	struct qlcnic_cardrsp_sds_ring *prsp_sds;
    242	struct qlcnic_hostrq_rds_ring *prq_rds;
    243	struct qlcnic_hostrq_sds_ring *prq_sds;
    244	struct qlcnic_host_rds_ring *rds_ring;
    245	struct qlcnic_host_sds_ring *sds_ring;
    246	struct qlcnic_cardrsp_rx_ctx *prsp;
    247	struct qlcnic_hostrq_rx_ctx *prq;
    248	u8 i, nrds_rings, nsds_rings;
    249	struct qlcnic_cmd_args cmd;
    250	size_t rq_size, rsp_size;
    251	u32 cap, reg, val, reg2;
    252	u64 phys_addr;
    253	u16 temp_u16;
    254	void *addr;
    255	int err;
    256
    257	nrds_rings = adapter->max_rds_rings;
    258	nsds_rings = adapter->drv_sds_rings;
    259
    260	rq_size = SIZEOF_HOSTRQ_RX(struct qlcnic_hostrq_rx_ctx, nrds_rings,
    261				   nsds_rings);
    262	rsp_size = SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
    263				     nsds_rings);
    264
    265	addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size,
    266				  &hostrq_phys_addr, GFP_KERNEL);
    267	if (addr == NULL)
    268		return -ENOMEM;
    269	prq = addr;
    270
    271	addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size,
    272			&cardrsp_phys_addr, GFP_KERNEL);
    273	if (addr == NULL) {
    274		err = -ENOMEM;
    275		goto out_free_rq;
    276	}
    277	prsp = addr;
    278
    279	prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
    280
    281	cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN
    282						| QLCNIC_CAP0_VALIDOFF);
    283	cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
    284
    285	if (qlcnic_check_multi_tx(adapter) &&
    286	    !adapter->ahw->diag_test) {
    287		cap |= QLCNIC_CAP0_TX_MULTI;
    288	} else {
    289		temp_u16 = offsetof(struct qlcnic_hostrq_rx_ctx, msix_handler);
    290		prq->valid_field_offset = cpu_to_le16(temp_u16);
    291		prq->txrx_sds_binding = nsds_rings - 1;
    292		temp_intr_crb_mode = QLCNIC_HOST_INT_CRB_MODE_SHARED;
    293		prq->host_int_crb_mode = cpu_to_le32(temp_intr_crb_mode);
    294		temp_rds_crb_mode = QLCNIC_HOST_RDS_CRB_MODE_UNIQUE;
    295		prq->host_rds_crb_mode = cpu_to_le32(temp_rds_crb_mode);
    296	}
    297
    298	prq->capabilities[0] = cpu_to_le32(cap);
    299
    300	prq->num_rds_rings = cpu_to_le16(nrds_rings);
    301	prq->num_sds_rings = cpu_to_le16(nsds_rings);
    302	prq->rds_ring_offset = 0;
    303
    304	val = le32_to_cpu(prq->rds_ring_offset) +
    305		(sizeof(struct qlcnic_hostrq_rds_ring) * nrds_rings);
    306	prq->sds_ring_offset = cpu_to_le32(val);
    307
    308	prq_rds = (struct qlcnic_hostrq_rds_ring *)(prq->data +
    309			le32_to_cpu(prq->rds_ring_offset));
    310
    311	for (i = 0; i < nrds_rings; i++) {
    312		rds_ring = &recv_ctx->rds_rings[i];
    313		rds_ring->producer = 0;
    314		prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
    315		prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
    316		prq_rds[i].ring_kind = cpu_to_le32(i);
    317		prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
    318	}
    319
    320	prq_sds = (struct qlcnic_hostrq_sds_ring *)(prq->data +
    321			le32_to_cpu(prq->sds_ring_offset));
    322
    323	for (i = 0; i < nsds_rings; i++) {
    324		sds_ring = &recv_ctx->sds_rings[i];
    325		sds_ring->consumer = 0;
    326		memset(sds_ring->desc_head, 0, STATUS_DESC_RINGSIZE(sds_ring));
    327		prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
    328		prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
    329		if (qlcnic_check_multi_tx(adapter) &&
    330		    !adapter->ahw->diag_test)
    331			prq_sds[i].msi_index = cpu_to_le16(ahw->intr_tbl[i].id);
    332		else
    333			prq_sds[i].msi_index = cpu_to_le16(i);
    334	}
    335
    336	phys_addr = hostrq_phys_addr;
    337	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_RX_CTX);
    338	if (err)
    339		goto out_free_rsp;
    340
    341	cmd.req.arg[1] = MSD(phys_addr);
    342	cmd.req.arg[2] = LSD(phys_addr);
    343	cmd.req.arg[3] = rq_size;
    344	err = qlcnic_issue_cmd(adapter, &cmd);
    345	if (err) {
    346		dev_err(&adapter->pdev->dev,
    347			"Failed to create rx ctx in firmware%d\n", err);
    348		goto out_free_rsp;
    349	}
    350
    351	prsp_rds = ((struct qlcnic_cardrsp_rds_ring *)
    352			 &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]);
    353
    354	for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) {
    355		rds_ring = &recv_ctx->rds_rings[i];
    356		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
    357		rds_ring->crb_rcv_producer = ahw->pci_base0 + reg;
    358	}
    359
    360	prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
    361			&prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
    362
    363	for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
    364		sds_ring = &recv_ctx->sds_rings[i];
    365		reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
    366		if (qlcnic_check_multi_tx(adapter) && !adapter->ahw->diag_test)
    367			reg2 = ahw->intr_tbl[i].src;
    368		else
    369			reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb);
    370
    371		sds_ring->crb_intr_mask = ahw->pci_base0 + reg2;
    372		sds_ring->crb_sts_consumer = ahw->pci_base0 + reg;
    373	}
    374
    375	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
    376	recv_ctx->context_id = le16_to_cpu(prsp->context_id);
    377	recv_ctx->virt_port = prsp->virt_port;
    378
    379	netdev_info(netdev, "Rx Context[%d] Created, state 0x%x\n",
    380		    recv_ctx->context_id, recv_ctx->state);
    381	qlcnic_free_mbx_args(&cmd);
    382
    383out_free_rsp:
    384	dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp,
    385			  cardrsp_phys_addr);
    386out_free_rq:
    387	dma_free_coherent(&adapter->pdev->dev, rq_size, prq, hostrq_phys_addr);
    388
    389	return err;
    390}
    391
    392void qlcnic_82xx_fw_cmd_del_rx_ctx(struct qlcnic_adapter *adapter)
    393{
    394	int err;
    395	struct qlcnic_cmd_args cmd;
    396	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
    397
    398	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX);
    399	if (err)
    400		return;
    401
    402	cmd.req.arg[1] = recv_ctx->context_id;
    403	err = qlcnic_issue_cmd(adapter, &cmd);
    404	if (err)
    405		dev_err(&adapter->pdev->dev,
    406			"Failed to destroy rx ctx in firmware\n");
    407
    408	recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
    409	qlcnic_free_mbx_args(&cmd);
    410}
    411
    412int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter,
    413				     struct qlcnic_host_tx_ring *tx_ring,
    414				     int ring)
    415{
    416	struct qlcnic_hardware_context *ahw = adapter->ahw;
    417	struct net_device *netdev = adapter->netdev;
    418	struct qlcnic_hostrq_tx_ctx	*prq;
    419	struct qlcnic_hostrq_cds_ring	*prq_cds;
    420	struct qlcnic_cardrsp_tx_ctx	*prsp;
    421	struct qlcnic_cmd_args cmd;
    422	u32 temp, intr_mask, temp_int_crb_mode;
    423	dma_addr_t rq_phys_addr, rsp_phys_addr;
    424	int temp_nsds_rings, index, err;
    425	void *rq_addr, *rsp_addr;
    426	size_t rq_size, rsp_size;
    427	u64 phys_addr;
    428	u16 msix_id;
    429
    430	/* reset host resources */
    431	tx_ring->producer = 0;
    432	tx_ring->sw_consumer = 0;
    433	*(tx_ring->hw_consumer) = 0;
    434
    435	rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
    436	rq_addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size,
    437				     &rq_phys_addr, GFP_KERNEL);
    438	if (!rq_addr)
    439		return -ENOMEM;
    440
    441	rsp_size = SIZEOF_CARDRSP_TX(struct qlcnic_cardrsp_tx_ctx);
    442	rsp_addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size,
    443				      &rsp_phys_addr, GFP_KERNEL);
    444	if (!rsp_addr) {
    445		err = -ENOMEM;
    446		goto out_free_rq;
    447	}
    448
    449	prq = rq_addr;
    450	prsp = rsp_addr;
    451
    452	prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);
    453
    454	temp = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN |
    455		QLCNIC_CAP0_LSO);
    456	if (qlcnic_check_multi_tx(adapter) && !adapter->ahw->diag_test)
    457		temp |= QLCNIC_CAP0_TX_MULTI;
    458
    459	prq->capabilities[0] = cpu_to_le32(temp);
    460
    461	if (qlcnic_check_multi_tx(adapter) &&
    462	    !adapter->ahw->diag_test) {
    463		temp_nsds_rings = adapter->drv_sds_rings;
    464		index = temp_nsds_rings + ring;
    465		msix_id = ahw->intr_tbl[index].id;
    466		prq->msi_index = cpu_to_le16(msix_id);
    467	} else {
    468		temp_int_crb_mode = QLCNIC_HOST_INT_CRB_MODE_SHARED;
    469		prq->host_int_crb_mode = cpu_to_le32(temp_int_crb_mode);
    470		prq->msi_index = 0;
    471	}
    472
    473	prq->interrupt_ctl = 0;
    474	prq->cmd_cons_dma_addr = cpu_to_le64(tx_ring->hw_cons_phys_addr);
    475
    476	prq_cds = &prq->cds_ring;
    477
    478	prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
    479	prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
    480
    481	phys_addr = rq_phys_addr;
    482
    483	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
    484	if (err)
    485		goto out_free_rsp;
    486
    487	cmd.req.arg[1] = MSD(phys_addr);
    488	cmd.req.arg[2] = LSD(phys_addr);
    489	cmd.req.arg[3] = rq_size;
    490	err = qlcnic_issue_cmd(adapter, &cmd);
    491
    492	if (err == QLCNIC_RCODE_SUCCESS) {
    493		tx_ring->state = le32_to_cpu(prsp->host_ctx_state);
    494		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
    495		tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp;
    496		tx_ring->ctx_id = le16_to_cpu(prsp->context_id);
    497		if (qlcnic_check_multi_tx(adapter) &&
    498		    !adapter->ahw->diag_test &&
    499		    (adapter->flags & QLCNIC_MSIX_ENABLED)) {
    500			index = adapter->drv_sds_rings + ring;
    501			intr_mask = ahw->intr_tbl[index].src;
    502			tx_ring->crb_intr_mask = ahw->pci_base0 + intr_mask;
    503		}
    504
    505		netdev_info(netdev, "Tx Context[0x%x] Created, state 0x%x\n",
    506			    tx_ring->ctx_id, tx_ring->state);
    507	} else {
    508		netdev_err(netdev, "Failed to create tx ctx in firmware%d\n",
    509			   err);
    510		err = -EIO;
    511	}
    512	qlcnic_free_mbx_args(&cmd);
    513
    514out_free_rsp:
    515	dma_free_coherent(&adapter->pdev->dev, rsp_size, rsp_addr,
    516			  rsp_phys_addr);
    517out_free_rq:
    518	dma_free_coherent(&adapter->pdev->dev, rq_size, rq_addr, rq_phys_addr);
    519
    520	return err;
    521}
    522
    523void qlcnic_82xx_fw_cmd_del_tx_ctx(struct qlcnic_adapter *adapter,
    524				   struct qlcnic_host_tx_ring *tx_ring)
    525{
    526	struct qlcnic_cmd_args cmd;
    527	int ret;
    528
    529	ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX);
    530	if (ret)
    531		return;
    532
    533	cmd.req.arg[1] = tx_ring->ctx_id;
    534	if (qlcnic_issue_cmd(adapter, &cmd))
    535		dev_err(&adapter->pdev->dev,
    536			"Failed to destroy tx ctx in firmware\n");
    537	qlcnic_free_mbx_args(&cmd);
    538}
    539
    540int
    541qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config)
    542{
    543	int err;
    544	struct qlcnic_cmd_args cmd;
    545
    546	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_PORT);
    547	if (err)
    548		return err;
    549
    550	cmd.req.arg[1] = config;
    551	err = qlcnic_issue_cmd(adapter, &cmd);
    552	qlcnic_free_mbx_args(&cmd);
    553	return err;
    554}
    555
    556int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
    557{
    558	void *addr;
    559	int err, ring;
    560	struct qlcnic_recv_context *recv_ctx;
    561	struct qlcnic_host_rds_ring *rds_ring;
    562	struct qlcnic_host_sds_ring *sds_ring;
    563	struct qlcnic_host_tx_ring *tx_ring;
    564	__le32 *ptr;
    565
    566	struct pci_dev *pdev = adapter->pdev;
    567
    568	recv_ctx = adapter->recv_ctx;
    569
    570	for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
    571		tx_ring = &adapter->tx_ring[ring];
    572		ptr = (__le32 *)dma_alloc_coherent(&pdev->dev, sizeof(u32),
    573						   &tx_ring->hw_cons_phys_addr,
    574						   GFP_KERNEL);
    575		if (ptr == NULL) {
    576			err = -ENOMEM;
    577			goto err_out_free;
    578		}
    579
    580		tx_ring->hw_consumer = ptr;
    581		/* cmd desc ring */
    582		addr = dma_alloc_coherent(&pdev->dev, TX_DESC_RINGSIZE(tx_ring),
    583					  &tx_ring->phys_addr,
    584					  GFP_KERNEL);
    585		if (addr == NULL) {
    586			err = -ENOMEM;
    587			goto err_out_free;
    588		}
    589
    590		tx_ring->desc_head = addr;
    591	}
    592
    593	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
    594		rds_ring = &recv_ctx->rds_rings[ring];
    595		addr = dma_alloc_coherent(&adapter->pdev->dev,
    596					  RCV_DESC_RINGSIZE(rds_ring),
    597					  &rds_ring->phys_addr, GFP_KERNEL);
    598		if (addr == NULL) {
    599			err = -ENOMEM;
    600			goto err_out_free;
    601		}
    602		rds_ring->desc_head = addr;
    603
    604	}
    605
    606	for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
    607		sds_ring = &recv_ctx->sds_rings[ring];
    608
    609		addr = dma_alloc_coherent(&adapter->pdev->dev,
    610					  STATUS_DESC_RINGSIZE(sds_ring),
    611					  &sds_ring->phys_addr, GFP_KERNEL);
    612		if (addr == NULL) {
    613			err = -ENOMEM;
    614			goto err_out_free;
    615		}
    616		sds_ring->desc_head = addr;
    617	}
    618
    619	return 0;
    620
    621err_out_free:
    622	qlcnic_free_hw_resources(adapter);
    623	return err;
    624}
    625
    626int qlcnic_fw_create_ctx(struct qlcnic_adapter *dev)
    627{
    628	int i, err, ring;
    629
    630	if (dev->flags & QLCNIC_NEED_FLR) {
    631		pci_reset_function(dev->pdev);
    632		dev->flags &= ~QLCNIC_NEED_FLR;
    633	}
    634
    635	if (qlcnic_83xx_check(dev) && (dev->flags & QLCNIC_MSIX_ENABLED)) {
    636		if (dev->ahw->diag_test != QLCNIC_LOOPBACK_TEST) {
    637			err = qlcnic_83xx_config_intrpt(dev, 1);
    638			if (err)
    639				return err;
    640		}
    641	}
    642
    643	if (qlcnic_82xx_check(dev) && (dev->flags & QLCNIC_MSIX_ENABLED) &&
    644	    qlcnic_check_multi_tx(dev) && !dev->ahw->diag_test) {
    645		err = qlcnic_82xx_mq_intrpt(dev, 1);
    646		if (err)
    647			return err;
    648	}
    649
    650	err = qlcnic_fw_cmd_create_rx_ctx(dev);
    651	if (err)
    652		goto err_out;
    653
    654	for (ring = 0; ring < dev->drv_tx_rings; ring++) {
    655		err = qlcnic_fw_cmd_create_tx_ctx(dev,
    656						  &dev->tx_ring[ring],
    657						  ring);
    658		if (err) {
    659			qlcnic_fw_cmd_del_rx_ctx(dev);
    660			if (ring == 0)
    661				goto err_out;
    662
    663			for (i = 0; i < ring; i++)
    664				qlcnic_fw_cmd_del_tx_ctx(dev, &dev->tx_ring[i]);
    665
    666			goto err_out;
    667		}
    668	}
    669
    670	set_bit(__QLCNIC_FW_ATTACHED, &dev->state);
    671
    672	return 0;
    673
    674err_out:
    675	if (qlcnic_82xx_check(dev) && (dev->flags & QLCNIC_MSIX_ENABLED) &&
    676	    qlcnic_check_multi_tx(dev) && !dev->ahw->diag_test)
    677			qlcnic_82xx_config_intrpt(dev, 0);
    678
    679	if (qlcnic_83xx_check(dev) && (dev->flags & QLCNIC_MSIX_ENABLED)) {
    680		if (dev->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
    681			qlcnic_83xx_config_intrpt(dev, 0);
    682	}
    683
    684	return err;
    685}
    686
    687void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
    688{
    689	int ring;
    690
    691	if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
    692		qlcnic_fw_cmd_del_rx_ctx(adapter);
    693		for (ring = 0; ring < adapter->drv_tx_rings; ring++)
    694			qlcnic_fw_cmd_del_tx_ctx(adapter,
    695						 &adapter->tx_ring[ring]);
    696
    697		if (qlcnic_82xx_check(adapter) &&
    698		    (adapter->flags & QLCNIC_MSIX_ENABLED) &&
    699		    qlcnic_check_multi_tx(adapter) &&
    700		    !adapter->ahw->diag_test)
    701				qlcnic_82xx_config_intrpt(adapter, 0);
    702
    703		if (qlcnic_83xx_check(adapter) &&
    704		    (adapter->flags & QLCNIC_MSIX_ENABLED)) {
    705			if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
    706				qlcnic_83xx_config_intrpt(adapter, 0);
    707		}
    708		/* Allow dma queues to drain after context reset */
    709		mdelay(20);
    710	}
    711}
    712
    713void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
    714{
    715	struct qlcnic_recv_context *recv_ctx;
    716	struct qlcnic_host_rds_ring *rds_ring;
    717	struct qlcnic_host_sds_ring *sds_ring;
    718	struct qlcnic_host_tx_ring *tx_ring;
    719	int ring;
    720
    721	recv_ctx = adapter->recv_ctx;
    722
    723	for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
    724		tx_ring = &adapter->tx_ring[ring];
    725		if (tx_ring->hw_consumer != NULL) {
    726			dma_free_coherent(&adapter->pdev->dev, sizeof(u32),
    727					  tx_ring->hw_consumer,
    728					  tx_ring->hw_cons_phys_addr);
    729
    730			tx_ring->hw_consumer = NULL;
    731		}
    732
    733		if (tx_ring->desc_head != NULL) {
    734			dma_free_coherent(&adapter->pdev->dev,
    735					  TX_DESC_RINGSIZE(tx_ring),
    736					  tx_ring->desc_head,
    737					  tx_ring->phys_addr);
    738			tx_ring->desc_head = NULL;
    739		}
    740	}
    741
    742	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
    743		rds_ring = &recv_ctx->rds_rings[ring];
    744
    745		if (rds_ring->desc_head != NULL) {
    746			dma_free_coherent(&adapter->pdev->dev,
    747					RCV_DESC_RINGSIZE(rds_ring),
    748					rds_ring->desc_head,
    749					rds_ring->phys_addr);
    750			rds_ring->desc_head = NULL;
    751		}
    752	}
    753
    754	for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
    755		sds_ring = &recv_ctx->sds_rings[ring];
    756
    757		if (sds_ring->desc_head != NULL) {
    758			dma_free_coherent(&adapter->pdev->dev,
    759				STATUS_DESC_RINGSIZE(sds_ring),
    760				sds_ring->desc_head,
    761				sds_ring->phys_addr);
    762			sds_ring->desc_head = NULL;
    763		}
    764	}
    765}
    766
    767int qlcnic_82xx_config_intrpt(struct qlcnic_adapter *adapter, u8 op_type)
    768{
    769	struct qlcnic_hardware_context *ahw = adapter->ahw;
    770	struct net_device *netdev = adapter->netdev;
    771	struct qlcnic_cmd_args cmd;
    772	u32 type, val;
    773	int i, err = 0;
    774
    775	for (i = 0; i < ahw->num_msix; i++) {
    776		err = qlcnic_alloc_mbx_args(&cmd, adapter,
    777					    QLCNIC_CMD_MQ_TX_CONFIG_INTR);
    778		if (err)
    779			return err;
    780		type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
    781		val = type | (ahw->intr_tbl[i].type << 4);
    782		if (ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
    783			val |= (ahw->intr_tbl[i].id << 16);
    784		cmd.req.arg[1] = val;
    785		err = qlcnic_issue_cmd(adapter, &cmd);
    786		if (err) {
    787			netdev_err(netdev, "Failed to %s interrupts %d\n",
    788				   op_type == QLCNIC_INTRPT_ADD ? "Add" :
    789				   "Delete", err);
    790			qlcnic_free_mbx_args(&cmd);
    791			return err;
    792		}
    793		val = cmd.rsp.arg[1];
    794		if (LSB(val)) {
    795			netdev_info(netdev,
    796				    "failed to configure interrupt for %d\n",
    797				    ahw->intr_tbl[i].id);
    798			continue;
    799		}
    800		if (op_type) {
    801			ahw->intr_tbl[i].id = MSW(val);
    802			ahw->intr_tbl[i].enabled = 1;
    803			ahw->intr_tbl[i].src = cmd.rsp.arg[2];
    804		} else {
    805			ahw->intr_tbl[i].id = i;
    806			ahw->intr_tbl[i].enabled = 0;
    807			ahw->intr_tbl[i].src = 0;
    808		}
    809		qlcnic_free_mbx_args(&cmd);
    810	}
    811
    812	return err;
    813}
    814
    815int qlcnic_82xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
    816				u8 function)
    817{
    818	int err, i;
    819	struct qlcnic_cmd_args cmd;
    820	u32 mac_low, mac_high;
    821
    822	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
    823	if (err)
    824		return err;
    825
    826	cmd.req.arg[1] = function | BIT_8;
    827	err = qlcnic_issue_cmd(adapter, &cmd);
    828
    829	if (err == QLCNIC_RCODE_SUCCESS) {
    830		mac_low = cmd.rsp.arg[1];
    831		mac_high = cmd.rsp.arg[2];
    832
    833		for (i = 0; i < 2; i++)
    834			mac[i] = (u8) (mac_high >> ((1 - i) * 8));
    835		for (i = 2; i < 6; i++)
    836			mac[i] = (u8) (mac_low >> ((5 - i) * 8));
    837	} else {
    838		dev_err(&adapter->pdev->dev,
    839			"Failed to get mac address%d\n", err);
    840		err = -EIO;
    841	}
    842	qlcnic_free_mbx_args(&cmd);
    843	return err;
    844}
    845
    846/* Get info of a NIC partition */
    847int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *adapter,
    848			     struct qlcnic_info *npar_info, u8 func_id)
    849{
    850	int	err;
    851	dma_addr_t nic_dma_t;
    852	const struct qlcnic_info_le *nic_info;
    853	void *nic_info_addr;
    854	struct qlcnic_cmd_args cmd;
    855	size_t  nic_size = sizeof(struct qlcnic_info_le);
    856
    857	nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size,
    858					   &nic_dma_t, GFP_KERNEL);
    859	if (!nic_info_addr)
    860		return -ENOMEM;
    861
    862	nic_info = nic_info_addr;
    863
    864	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
    865	if (err)
    866		goto out_free_dma;
    867
    868	cmd.req.arg[1] = MSD(nic_dma_t);
    869	cmd.req.arg[2] = LSD(nic_dma_t);
    870	cmd.req.arg[3] = (func_id << 16 | nic_size);
    871	err = qlcnic_issue_cmd(adapter, &cmd);
    872	if (err != QLCNIC_RCODE_SUCCESS) {
    873		dev_err(&adapter->pdev->dev,
    874			"Failed to get nic info%d\n", err);
    875		err = -EIO;
    876	} else {
    877		npar_info->pci_func = le16_to_cpu(nic_info->pci_func);
    878		npar_info->op_mode = le16_to_cpu(nic_info->op_mode);
    879		npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw);
    880		npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw);
    881		npar_info->phys_port = le16_to_cpu(nic_info->phys_port);
    882		npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode);
    883		npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
    884		npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
    885		npar_info->capabilities = le32_to_cpu(nic_info->capabilities);
    886		npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);
    887	}
    888
    889	qlcnic_free_mbx_args(&cmd);
    890out_free_dma:
    891	dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
    892			  nic_dma_t);
    893
    894	return err;
    895}
    896
    897/* Configure a NIC partition */
    898int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *adapter,
    899			     struct qlcnic_info *nic)
    900{
    901	int err = -EIO;
    902	dma_addr_t nic_dma_t;
    903	void *nic_info_addr;
    904	struct qlcnic_cmd_args cmd;
    905	struct qlcnic_info_le *nic_info;
    906	size_t nic_size = sizeof(struct qlcnic_info_le);
    907
    908	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
    909		return err;
    910
    911	nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size,
    912					   &nic_dma_t, GFP_KERNEL);
    913	if (!nic_info_addr)
    914		return -ENOMEM;
    915
    916	nic_info = nic_info_addr;
    917
    918	nic_info->pci_func = cpu_to_le16(nic->pci_func);
    919	nic_info->op_mode = cpu_to_le16(nic->op_mode);
    920	nic_info->phys_port = cpu_to_le16(nic->phys_port);
    921	nic_info->switch_mode = cpu_to_le16(nic->switch_mode);
    922	nic_info->capabilities = cpu_to_le32(nic->capabilities);
    923	nic_info->max_mac_filters = nic->max_mac_filters;
    924	nic_info->max_tx_ques = cpu_to_le16(nic->max_tx_ques);
    925	nic_info->max_rx_ques = cpu_to_le16(nic->max_rx_ques);
    926	nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw);
    927	nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw);
    928
    929	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
    930	if (err)
    931		goto out_free_dma;
    932
    933	cmd.req.arg[1] = MSD(nic_dma_t);
    934	cmd.req.arg[2] = LSD(nic_dma_t);
    935	cmd.req.arg[3] = ((nic->pci_func << 16) | nic_size);
    936	err = qlcnic_issue_cmd(adapter, &cmd);
    937
    938	if (err != QLCNIC_RCODE_SUCCESS) {
    939		dev_err(&adapter->pdev->dev,
    940			"Failed to set nic info%d\n", err);
    941		err = -EIO;
    942	}
    943
    944	qlcnic_free_mbx_args(&cmd);
    945out_free_dma:
    946	dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
    947			  nic_dma_t);
    948
    949	return err;
    950}
    951
    952/* Get PCI Info of a partition */
    953int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter,
    954			     struct qlcnic_pci_info *pci_info)
    955{
    956	struct qlcnic_hardware_context *ahw = adapter->ahw;
    957	size_t npar_size = sizeof(struct qlcnic_pci_info_le);
    958	size_t pci_size = npar_size * ahw->max_vnic_func;
    959	u16 nic = 0, fcoe = 0, iscsi = 0;
    960	struct qlcnic_pci_info_le *npar;
    961	struct qlcnic_cmd_args cmd;
    962	dma_addr_t pci_info_dma_t;
    963	void *pci_info_addr;
    964	int err = 0, i;
    965
    966	pci_info_addr = dma_alloc_coherent(&adapter->pdev->dev, pci_size,
    967					   &pci_info_dma_t, GFP_KERNEL);
    968	if (!pci_info_addr)
    969		return -ENOMEM;
    970
    971	npar = pci_info_addr;
    972	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
    973	if (err)
    974		goto out_free_dma;
    975
    976	cmd.req.arg[1] = MSD(pci_info_dma_t);
    977	cmd.req.arg[2] = LSD(pci_info_dma_t);
    978	cmd.req.arg[3] = pci_size;
    979	err = qlcnic_issue_cmd(adapter, &cmd);
    980
    981	ahw->total_nic_func = 0;
    982	if (err == QLCNIC_RCODE_SUCCESS) {
    983		for (i = 0; i < ahw->max_vnic_func; i++, npar++, pci_info++) {
    984			pci_info->id = le16_to_cpu(npar->id);
    985			pci_info->active = le16_to_cpu(npar->active);
    986			if (!pci_info->active)
    987				continue;
    988			pci_info->type = le16_to_cpu(npar->type);
    989			err = qlcnic_get_pci_func_type(adapter, pci_info->type,
    990						       &nic, &fcoe, &iscsi);
    991			pci_info->default_port =
    992				le16_to_cpu(npar->default_port);
    993			pci_info->tx_min_bw =
    994				le16_to_cpu(npar->tx_min_bw);
    995			pci_info->tx_max_bw =
    996				le16_to_cpu(npar->tx_max_bw);
    997			memcpy(pci_info->mac, npar->mac, ETH_ALEN);
    998		}
    999	} else {
   1000		dev_err(&adapter->pdev->dev,
   1001			"Failed to get PCI Info%d\n", err);
   1002		err = -EIO;
   1003	}
   1004
   1005	ahw->total_nic_func = nic;
   1006	ahw->total_pci_func = nic + fcoe + iscsi;
   1007	if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
   1008		dev_err(&adapter->pdev->dev,
   1009			"%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
   1010			__func__, ahw->total_nic_func, ahw->total_pci_func);
   1011		err = -EIO;
   1012	}
   1013	qlcnic_free_mbx_args(&cmd);
   1014out_free_dma:
   1015	dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr,
   1016		pci_info_dma_t);
   1017
   1018	return err;
   1019}
   1020
   1021/* Configure eSwitch for port mirroring */
   1022int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
   1023				 u8 enable_mirroring, u8 pci_func)
   1024{
   1025	struct device *dev = &adapter->pdev->dev;
   1026	struct qlcnic_cmd_args cmd;
   1027	int err = -EIO;
   1028	u32 arg1;
   1029
   1030	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC ||
   1031	    !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
   1032		dev_err(&adapter->pdev->dev, "%s: Not a management function\n",
   1033			__func__);
   1034		return err;
   1035	}
   1036
   1037	arg1 = id | (enable_mirroring ? BIT_4 : 0);
   1038	arg1 |= pci_func << 8;
   1039
   1040	err = qlcnic_alloc_mbx_args(&cmd, adapter,
   1041				    QLCNIC_CMD_SET_PORTMIRRORING);
   1042	if (err)
   1043		return err;
   1044
   1045	cmd.req.arg[1] = arg1;
   1046	err = qlcnic_issue_cmd(adapter, &cmd);
   1047
   1048	if (err != QLCNIC_RCODE_SUCCESS)
   1049		dev_err(dev, "Failed to configure port mirroring for vNIC function %d on eSwitch %d\n",
   1050			pci_func, id);
   1051	else
   1052		dev_info(dev, "Configured port mirroring for vNIC function %d on eSwitch %d\n",
   1053			 pci_func, id);
   1054	qlcnic_free_mbx_args(&cmd);
   1055
   1056	return err;
   1057}
   1058
   1059int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
   1060		const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
   1061
   1062	size_t stats_size = sizeof(struct qlcnic_esw_stats_le);
   1063	struct qlcnic_esw_stats_le *stats;
   1064	dma_addr_t stats_dma_t;
   1065	void *stats_addr;
   1066	u32 arg1;
   1067	struct qlcnic_cmd_args cmd;
   1068	int err;
   1069
   1070	if (esw_stats == NULL)
   1071		return -ENOMEM;
   1072
   1073	if ((adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) &&
   1074	    (func != adapter->ahw->pci_func)) {
   1075		dev_err(&adapter->pdev->dev,
   1076			"Not privilege to query stats for func=%d", func);
   1077		return -EIO;
   1078	}
   1079
   1080	stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size,
   1081					&stats_dma_t, GFP_KERNEL);
   1082	if (!stats_addr)
   1083		return -ENOMEM;
   1084
   1085	arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12;
   1086	arg1 |= rx_tx << 15 | stats_size << 16;
   1087
   1088	err = qlcnic_alloc_mbx_args(&cmd, adapter,
   1089				    QLCNIC_CMD_GET_ESWITCH_STATS);
   1090	if (err)
   1091		goto out_free_dma;
   1092
   1093	cmd.req.arg[1] = arg1;
   1094	cmd.req.arg[2] = MSD(stats_dma_t);
   1095	cmd.req.arg[3] = LSD(stats_dma_t);
   1096	err = qlcnic_issue_cmd(adapter, &cmd);
   1097
   1098	if (!err) {
   1099		stats = stats_addr;
   1100		esw_stats->context_id = le16_to_cpu(stats->context_id);
   1101		esw_stats->version = le16_to_cpu(stats->version);
   1102		esw_stats->size = le16_to_cpu(stats->size);
   1103		esw_stats->multicast_frames =
   1104				le64_to_cpu(stats->multicast_frames);
   1105		esw_stats->broadcast_frames =
   1106				le64_to_cpu(stats->broadcast_frames);
   1107		esw_stats->unicast_frames = le64_to_cpu(stats->unicast_frames);
   1108		esw_stats->dropped_frames = le64_to_cpu(stats->dropped_frames);
   1109		esw_stats->local_frames = le64_to_cpu(stats->local_frames);
   1110		esw_stats->errors = le64_to_cpu(stats->errors);
   1111		esw_stats->numbytes = le64_to_cpu(stats->numbytes);
   1112	}
   1113
   1114	qlcnic_free_mbx_args(&cmd);
   1115out_free_dma:
   1116	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
   1117			  stats_dma_t);
   1118
   1119	return err;
   1120}
   1121
   1122/* This routine will retrieve the MAC statistics from firmware */
   1123int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter,
   1124		struct qlcnic_mac_statistics *mac_stats)
   1125{
   1126	struct qlcnic_mac_statistics_le *stats;
   1127	struct qlcnic_cmd_args cmd;
   1128	size_t stats_size = sizeof(struct qlcnic_mac_statistics_le);
   1129	dma_addr_t stats_dma_t;
   1130	void *stats_addr;
   1131	int err;
   1132
   1133	if (mac_stats == NULL)
   1134		return -ENOMEM;
   1135
   1136	stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size,
   1137					&stats_dma_t, GFP_KERNEL);
   1138	if (!stats_addr)
   1139		return -ENOMEM;
   1140
   1141	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_MAC_STATS);
   1142	if (err)
   1143		goto out_free_dma;
   1144
   1145	cmd.req.arg[1] = stats_size << 16;
   1146	cmd.req.arg[2] = MSD(stats_dma_t);
   1147	cmd.req.arg[3] = LSD(stats_dma_t);
   1148	err = qlcnic_issue_cmd(adapter, &cmd);
   1149	if (!err) {
   1150		stats = stats_addr;
   1151		mac_stats->mac_tx_frames = le64_to_cpu(stats->mac_tx_frames);
   1152		mac_stats->mac_tx_bytes = le64_to_cpu(stats->mac_tx_bytes);
   1153		mac_stats->mac_tx_mcast_pkts =
   1154					le64_to_cpu(stats->mac_tx_mcast_pkts);
   1155		mac_stats->mac_tx_bcast_pkts =
   1156					le64_to_cpu(stats->mac_tx_bcast_pkts);
   1157		mac_stats->mac_rx_frames = le64_to_cpu(stats->mac_rx_frames);
   1158		mac_stats->mac_rx_bytes = le64_to_cpu(stats->mac_rx_bytes);
   1159		mac_stats->mac_rx_mcast_pkts =
   1160					le64_to_cpu(stats->mac_rx_mcast_pkts);
   1161		mac_stats->mac_rx_length_error =
   1162				le64_to_cpu(stats->mac_rx_length_error);
   1163		mac_stats->mac_rx_length_small =
   1164				le64_to_cpu(stats->mac_rx_length_small);
   1165		mac_stats->mac_rx_length_large =
   1166				le64_to_cpu(stats->mac_rx_length_large);
   1167		mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber);
   1168		mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped);
   1169		mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error);
   1170	} else {
   1171		dev_err(&adapter->pdev->dev,
   1172			"%s: Get mac stats failed, err=%d.\n", __func__, err);
   1173	}
   1174
   1175	qlcnic_free_mbx_args(&cmd);
   1176
   1177out_free_dma:
   1178	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
   1179			  stats_dma_t);
   1180
   1181	return err;
   1182}
   1183
   1184int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
   1185		const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
   1186
   1187	struct __qlcnic_esw_statistics port_stats;
   1188	u8 i;
   1189	int ret = -EIO;
   1190
   1191	if (esw_stats == NULL)
   1192		return -ENOMEM;
   1193	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
   1194		return -EIO;
   1195	if (adapter->npars == NULL)
   1196		return -EIO;
   1197
   1198	memset(esw_stats, 0, sizeof(u64));
   1199	esw_stats->unicast_frames = QLCNIC_STATS_NOT_AVAIL;
   1200	esw_stats->multicast_frames = QLCNIC_STATS_NOT_AVAIL;
   1201	esw_stats->broadcast_frames = QLCNIC_STATS_NOT_AVAIL;
   1202	esw_stats->dropped_frames = QLCNIC_STATS_NOT_AVAIL;
   1203	esw_stats->errors = QLCNIC_STATS_NOT_AVAIL;
   1204	esw_stats->local_frames = QLCNIC_STATS_NOT_AVAIL;
   1205	esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL;
   1206	esw_stats->context_id = eswitch;
   1207
   1208	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
   1209		if (adapter->npars[i].phy_port != eswitch)
   1210			continue;
   1211
   1212		memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
   1213		if (qlcnic_get_port_stats(adapter, adapter->npars[i].pci_func,
   1214					  rx_tx, &port_stats))
   1215			continue;
   1216
   1217		esw_stats->size = port_stats.size;
   1218		esw_stats->version = port_stats.version;
   1219		QLCNIC_ADD_ESW_STATS(esw_stats->unicast_frames,
   1220						port_stats.unicast_frames);
   1221		QLCNIC_ADD_ESW_STATS(esw_stats->multicast_frames,
   1222						port_stats.multicast_frames);
   1223		QLCNIC_ADD_ESW_STATS(esw_stats->broadcast_frames,
   1224						port_stats.broadcast_frames);
   1225		QLCNIC_ADD_ESW_STATS(esw_stats->dropped_frames,
   1226						port_stats.dropped_frames);
   1227		QLCNIC_ADD_ESW_STATS(esw_stats->errors,
   1228						port_stats.errors);
   1229		QLCNIC_ADD_ESW_STATS(esw_stats->local_frames,
   1230						port_stats.local_frames);
   1231		QLCNIC_ADD_ESW_STATS(esw_stats->numbytes,
   1232						port_stats.numbytes);
   1233		ret = 0;
   1234	}
   1235	return ret;
   1236}
   1237
   1238int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
   1239		const u8 port, const u8 rx_tx)
   1240{
   1241	struct qlcnic_hardware_context *ahw = adapter->ahw;
   1242	struct qlcnic_cmd_args cmd;
   1243	int err;
   1244	u32 arg1;
   1245
   1246	if (ahw->op_mode != QLCNIC_MGMT_FUNC)
   1247		return -EIO;
   1248
   1249	if (func_esw == QLCNIC_STATS_PORT) {
   1250		if (port >= ahw->max_vnic_func)
   1251			goto err_ret;
   1252	} else if (func_esw == QLCNIC_STATS_ESWITCH) {
   1253		if (port >= QLCNIC_NIU_MAX_XG_PORTS)
   1254			goto err_ret;
   1255	} else {
   1256		goto err_ret;
   1257	}
   1258
   1259	if (rx_tx > QLCNIC_QUERY_TX_COUNTER)
   1260		goto err_ret;
   1261
   1262	arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12;
   1263	arg1 |= BIT_14 | rx_tx << 15;
   1264
   1265	err = qlcnic_alloc_mbx_args(&cmd, adapter,
   1266				    QLCNIC_CMD_GET_ESWITCH_STATS);
   1267	if (err)
   1268		return err;
   1269
   1270	cmd.req.arg[1] = arg1;
   1271	err = qlcnic_issue_cmd(adapter, &cmd);
   1272	qlcnic_free_mbx_args(&cmd);
   1273	return err;
   1274
   1275err_ret:
   1276	dev_err(&adapter->pdev->dev,
   1277		"Invalid args func_esw %d port %d rx_ctx %d\n",
   1278		func_esw, port, rx_tx);
   1279	return -EIO;
   1280}
   1281
   1282static int __qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
   1283					    u32 *arg1, u32 *arg2)
   1284{
   1285	struct device *dev = &adapter->pdev->dev;
   1286	struct qlcnic_cmd_args cmd;
   1287	u8 pci_func = *arg1 >> 8;
   1288	int err;
   1289
   1290	err = qlcnic_alloc_mbx_args(&cmd, adapter,
   1291				    QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG);
   1292	if (err)
   1293		return err;
   1294
   1295	cmd.req.arg[1] = *arg1;
   1296	err = qlcnic_issue_cmd(adapter, &cmd);
   1297	*arg1 = cmd.rsp.arg[1];
   1298	*arg2 = cmd.rsp.arg[2];
   1299	qlcnic_free_mbx_args(&cmd);
   1300
   1301	if (err == QLCNIC_RCODE_SUCCESS)
   1302		dev_info(dev, "Get eSwitch port config for vNIC function %d\n",
   1303			 pci_func);
   1304	else
   1305		dev_err(dev, "Failed to get eswitch port config for vNIC function %d\n",
   1306			pci_func);
   1307	return err;
   1308}
   1309/* Configure eSwitch port
   1310op_mode = 0 for setting default port behavior
   1311op_mode = 1 for setting  vlan id
   1312op_mode = 2 for deleting vlan id
   1313op_type = 0 for vlan_id
   1314op_type = 1 for port vlan_id
   1315*/
   1316int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
   1317		struct qlcnic_esw_func_cfg *esw_cfg)
   1318{
   1319	struct device *dev = &adapter->pdev->dev;
   1320	struct qlcnic_cmd_args cmd;
   1321	int err = -EIO, index;
   1322	u32 arg1, arg2 = 0;
   1323	u8 pci_func;
   1324
   1325	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
   1326		dev_err(&adapter->pdev->dev, "%s: Not a management function\n",
   1327			__func__);
   1328		return err;
   1329	}
   1330
   1331	pci_func = esw_cfg->pci_func;
   1332	index = qlcnic_is_valid_nic_func(adapter, pci_func);
   1333	if (index < 0)
   1334		return err;
   1335	arg1 = (adapter->npars[index].phy_port & BIT_0);
   1336	arg1 |= (pci_func << 8);
   1337
   1338	if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
   1339		return err;
   1340	arg1 &= ~(0x0ff << 8);
   1341	arg1 |= (pci_func << 8);
   1342	arg1 &= ~(BIT_2 | BIT_3);
   1343	switch (esw_cfg->op_mode) {
   1344	case QLCNIC_PORT_DEFAULTS:
   1345		arg1 |= (BIT_4 | BIT_6 | BIT_7);
   1346		arg2 |= (BIT_0 | BIT_1);
   1347		if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
   1348			arg2 |= (BIT_2 | BIT_3);
   1349		if (!(esw_cfg->discard_tagged))
   1350			arg1 &= ~BIT_4;
   1351		if (!(esw_cfg->promisc_mode))
   1352			arg1 &= ~BIT_6;
   1353		if (!(esw_cfg->mac_override))
   1354			arg1 &= ~BIT_7;
   1355		if (!(esw_cfg->mac_anti_spoof))
   1356			arg2 &= ~BIT_0;
   1357		if (!(esw_cfg->offload_flags & BIT_0))
   1358			arg2 &= ~(BIT_1 | BIT_2 | BIT_3);
   1359		if (!(esw_cfg->offload_flags & BIT_1))
   1360			arg2 &= ~BIT_2;
   1361		if (!(esw_cfg->offload_flags & BIT_2))
   1362			arg2 &= ~BIT_3;
   1363		break;
   1364	case QLCNIC_ADD_VLAN:
   1365			arg1 &= ~(0x0ffff << 16);
   1366			arg1 |= (BIT_2 | BIT_5);
   1367			arg1 |= (esw_cfg->vlan_id << 16);
   1368			break;
   1369	case QLCNIC_DEL_VLAN:
   1370			arg1 |= (BIT_3 | BIT_5);
   1371			arg1 &= ~(0x0ffff << 16);
   1372			break;
   1373	default:
   1374		dev_err(&adapter->pdev->dev, "%s: Invalid opmode 0x%x\n",
   1375			__func__, esw_cfg->op_mode);
   1376		return err;
   1377	}
   1378
   1379	err = qlcnic_alloc_mbx_args(&cmd, adapter,
   1380				    QLCNIC_CMD_CONFIGURE_ESWITCH);
   1381	if (err)
   1382		return err;
   1383
   1384	cmd.req.arg[1] = arg1;
   1385	cmd.req.arg[2] = arg2;
   1386	err = qlcnic_issue_cmd(adapter, &cmd);
   1387	qlcnic_free_mbx_args(&cmd);
   1388
   1389	if (err != QLCNIC_RCODE_SUCCESS)
   1390		dev_err(dev, "Failed to configure eswitch for vNIC function %d\n",
   1391			pci_func);
   1392	else
   1393		dev_info(dev, "Configured eSwitch for vNIC function %d\n",
   1394			 pci_func);
   1395
   1396	return err;
   1397}
   1398
   1399int
   1400qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
   1401			struct qlcnic_esw_func_cfg *esw_cfg)
   1402{
   1403	u32 arg1, arg2;
   1404	int index;
   1405	u8 phy_port;
   1406
   1407	if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) {
   1408		index = qlcnic_is_valid_nic_func(adapter, esw_cfg->pci_func);
   1409		if (index < 0)
   1410			return -EIO;
   1411		phy_port = adapter->npars[index].phy_port;
   1412	} else {
   1413		phy_port = adapter->ahw->physical_port;
   1414	}
   1415	arg1 = phy_port;
   1416	arg1 |= (esw_cfg->pci_func << 8);
   1417	if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
   1418		return -EIO;
   1419
   1420	esw_cfg->discard_tagged = !!(arg1 & BIT_4);
   1421	esw_cfg->host_vlan_tag = !!(arg1 & BIT_5);
   1422	esw_cfg->promisc_mode = !!(arg1 & BIT_6);
   1423	esw_cfg->mac_override = !!(arg1 & BIT_7);
   1424	esw_cfg->vlan_id = LSW(arg1 >> 16);
   1425	esw_cfg->mac_anti_spoof = (arg2 & 0x1);
   1426	esw_cfg->offload_flags = ((arg2 >> 1) & 0x7);
   1427
   1428	return 0;
   1429}