/*
 * Copyright (c) 2014-2015 Hisilicon Limited.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <asm/cacheflush.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/spinlock.h>

#include "hns_dsaf_main.h"
#include "hns_dsaf_ppe.h"
#include "hns_dsaf_rcb.h"

#define RCB_COMMON_REG_OFFSET 0x80000
#define TX_RING 0
#define RX_RING 1

#define RCB_RESET_WAIT_TIMES 30
#define RCB_RESET_TRY_TIMES 10

/**
 *hns_rcb_wait_fbd_clean - clean fbd
 *@qs: ring struct pointer array
 *@qnum: num of array
 *@flag: tx or rx flag
 */
void hns_rcb_wait_fbd_clean(struct hnae_queue **qs, int q_num, u32 flag)
{
	int i, wait_cnt;
	u32 fbd_num;

	for (wait_cnt = i = 0; i < q_num; wait_cnt++) {
		usleep_range(200, 300);
		fbd_num = 0;
		if (flag & RCB_INT_FLAG_TX)
			fbd_num += dsaf_read_dev(qs[i],
						 RCB_RING_TX_RING_FBDNUM_REG);
		if (flag & RCB_INT_FLAG_RX)
			fbd_num += dsaf_read_dev(qs[i],
						 RCB_RING_RX_RING_FBDNUM_REG);
		if (!fbd_num)
			i++;
		if (wait_cnt >= 10000)
			break;
	}

	if (i < q_num)
		dev_err(qs[i]->handle->owner_dev,
			"queue(%d) wait fbd(%d) clean fail!!\n", i, fbd_num);
}

/**
 *hns_rcb_reset_ring_hw - ring reset
 *@q: ring struct pointer
 */
void hns_rcb_reset_ring_hw(struct hnae_queue *q)
{
	u32 wait_cnt;
	u32 try_cnt = 0;
	u32 could_ret;

	u32 tx_fbd_num;

	while (try_cnt++ < RCB_RESET_TRY_TIMES) {
		usleep_range(100, 200);
		tx_fbd_num = dsaf_read_dev(q, RCB_RING_TX_RING_FBDNUM_REG);
		if (tx_fbd_num)
			continue;

		dsaf_write_dev(q, RCB_RING_PREFETCH_EN_REG, 0);

		dsaf_write_dev(q, RCB_RING_T0_BE_RST, 1);

		msleep(20);
		could_ret = dsaf_read_dev(q, RCB_RING_COULD_BE_RST);

		wait_cnt = 0;
		while (!could_ret && (wait_cnt < RCB_RESET_WAIT_TIMES)) {
			dsaf_write_dev(q, RCB_RING_T0_BE_RST, 0);

			dsaf_write_dev(q, RCB_RING_T0_BE_RST, 1);

			msleep(20);
			could_ret = dsaf_read_dev(q, RCB_RING_COULD_BE_RST);

			wait_cnt++;
		}

		dsaf_write_dev(q, RCB_RING_T0_BE_RST, 0);

		if (could_ret)
			break;
	}

	if (try_cnt >= RCB_RESET_TRY_TIMES)
		dev_err(q->dev->dev, "port%d reset ring fail\n",
			hns_ae_get_vf_cb(q->handle)->port_index);
}

/**
 *hns_rcb_int_ctrl_hw - rcb irq enable control
 *@q: hnae queue struct pointer
 *@flag:ring flag tx or rx
 *@mask:mask
 */
void hns_rcb_int_ctrl_hw(struct hnae_queue *q, u32 flag, u32 mask)
{
	u32 int_mask_en = !!mask;

	if (flag & RCB_INT_FLAG_TX) {
		dsaf_write_dev(q, RCB_RING_INTMSK_TXWL_REG, int_mask_en);
		dsaf_write_dev(q, RCB_RING_INTMSK_TX_OVERTIME_REG,
			       int_mask_en);
	}

	if (flag & RCB_INT_FLAG_RX) {
		dsaf_write_dev(q, RCB_RING_INTMSK_RXWL_REG, int_mask_en);
		dsaf_write_dev(q, RCB_RING_INTMSK_RX_OVERTIME_REG,
			       int_mask_en);
	}
}

void hns_rcb_int_clr_hw(struct hnae_queue *q, u32 flag)
{
	if (flag & RCB_INT_FLAG_TX) {
		dsaf_write_dev(q, RCB_RING_INTSTS_TX_RING_REG, 1);
		dsaf_write_dev(q, RCB_RING_INTSTS_TX_OVERTIME_REG, 1);
	}

	if (flag & RCB_INT_FLAG_RX) {
		dsaf_write_dev(q, RCB_RING_INTSTS_RX_RING_REG, 1);
		dsaf_write_dev(q, RCB_RING_INTSTS_RX_OVERTIME_REG, 1);
	}
}

void hns_rcbv2_int_ctrl_hw(struct hnae_queue *q, u32 flag, u32 mask)
{
	u32 int_mask_en = !!mask;

	if (flag & RCB_INT_FLAG_TX)
		dsaf_write_dev(q, RCB_RING_INTMSK_TXWL_REG, int_mask_en);

	if (flag & RCB_INT_FLAG_RX)
		dsaf_write_dev(q, RCB_RING_INTMSK_RXWL_REG, int_mask_en);
}

void hns_rcbv2_int_clr_hw(struct hnae_queue *q, u32 flag)
{
	if (flag & RCB_INT_FLAG_TX)
		dsaf_write_dev(q, RCBV2_TX_RING_INT_STS_REG, 1);

	if (flag & RCB_INT_FLAG_RX)
		dsaf_write_dev(q, RCBV2_RX_RING_INT_STS_REG, 1);
}

/**
 *hns_rcb_ring_enable_hw - enable ring
 *@ring: rcb ring
 */
void hns_rcb_ring_enable_hw(struct hnae_queue *q, u32 val)
{
	dsaf_write_dev(q, RCB_RING_PREFETCH_EN_REG, !!val);
}

void hns_rcb_start(struct hnae_queue *q, u32 val)
{
	hns_rcb_ring_enable_hw(q, val);
}

/**
 *hns_rcb_common_init_commit_hw - make rcb common init completed
 *@rcb_common: rcb common device
 */
void hns_rcb_common_init_commit_hw(struct rcb_common_cb *rcb_common)
{
	wmb();	/* Sync point before breakpoint */
	dsaf_write_dev(rcb_common, RCB_COM_CFG_SYS_FSH_REG, 1);
	wmb();	/* Sync point after breakpoint */
}

/**
 *hns_rcb_ring_init - init rcb ring
 *@ring_pair: ring pair control block
 *@ring_type: ring type, RX_RING or TX_RING
 */
static void hns_rcb_ring_init(struct ring_pair_cb *ring_pair, int ring_type)
{
	struct hnae_queue *q = &ring_pair->q;
	struct rcb_common_cb *rcb_common = ring_pair->rcb_common;
	u32 bd_size_type = rcb_common->dsaf_dev->buf_size_type;
	struct hnae_ring *ring =
		(ring_type == RX_RING) ? &q->rx_ring : &q->tx_ring;
	dma_addr_t dma = ring->desc_dma_addr;

	if (ring_type == RX_RING) {
		dsaf_write_dev(q, RCB_RING_RX_RING_BASEADDR_L_REG,
			       (u32)dma);
		dsaf_write_dev(q, RCB_RING_RX_RING_BASEADDR_H_REG,
			       (u32)((dma >> 31) >> 1));

		dsaf_write_dev(q, RCB_RING_RX_RING_BD_LEN_REG,
			       bd_size_type);
		dsaf_write_dev(q, RCB_RING_RX_RING_BD_NUM_REG,
			       ring_pair->port_id_in_comm);
		dsaf_write_dev(q, RCB_RING_RX_RING_PKTLINE_REG,
			       ring_pair->port_id_in_comm);
	} else {
		dsaf_write_dev(q, RCB_RING_TX_RING_BASEADDR_L_REG,
			       (u32)dma);
		dsaf_write_dev(q, RCB_RING_TX_RING_BASEADDR_H_REG,
			       (u32)((dma >> 31) >> 1));

		dsaf_write_dev(q, RCB_RING_TX_RING_BD_LEN_REG,
			       bd_size_type);
		dsaf_write_dev(q, RCB_RING_TX_RING_BD_NUM_REG,
			       ring_pair->port_id_in_comm);
		dsaf_write_dev(q, RCB_RING_TX_RING_PKTLINE_REG,
			       ring_pair->port_id_in_comm);
	}
}

/**
 *hns_rcb_init_hw - init rcb hardware
 *@ring: rcb ring
 */
void hns_rcb_init_hw(struct ring_pair_cb *ring)
{
	hns_rcb_ring_init(ring, RX_RING);
	hns_rcb_ring_init(ring, TX_RING);
}

/**
 *hns_rcb_set_port_desc_cnt - set rcb port description num
 *@rcb_common: rcb_common device
 *@port_idx:port index
 *@desc_cnt:BD num
 */
static void hns_rcb_set_port_desc_cnt(struct rcb_common_cb *rcb_common,
				      u32 port_idx, u32 desc_cnt)
{
	dsaf_write_dev(rcb_common, RCB_CFG_BD_NUM_REG + port_idx * 4,
		       desc_cnt);
}

static void hns_rcb_set_port_timeout(
	struct rcb_common_cb *rcb_common, u32 port_idx, u32 timeout)
{
	if (AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver))
		dsaf_write_dev(rcb_common, RCB_CFG_OVERTIME_REG,
			       timeout * HNS_RCB_CLK_FREQ_MHZ);
	else
		dsaf_write_dev(rcb_common,
			       RCB_PORT_CFG_OVERTIME_REG + port_idx * 4,
			       timeout);
}

static int hns_rcb_common_get_port_num(struct rcb_common_cb *rcb_common)
{
	if (!HNS_DSAF_IS_DEBUG(rcb_common->dsaf_dev))
		return HNS_RCB_SERVICE_NW_ENGINE_NUM;
	else
		return HNS_RCB_DEBUG_NW_ENGINE_NUM;
}

/*clr rcb comm exception irq**/
static void hns_rcb_comm_exc_irq_en(
			struct rcb_common_cb *rcb_common, int en)
{
	u32 clr_vlue = 0xfffffffful;
	u32 msk_vlue = en ? 0 : 0xfffffffful;

	/* clr int*/
	dsaf_write_dev(rcb_common, RCB_COM_INTSTS_ECC_ERR_REG, clr_vlue);

	dsaf_write_dev(rcb_common, RCB_COM_SF_CFG_RING_STS, clr_vlue);

	dsaf_write_dev(rcb_common, RCB_COM_SF_CFG_BD_RINT_STS, clr_vlue);

	dsaf_write_dev(rcb_common, RCB_COM_RINT_TX_PKT_REG, clr_vlue);
	dsaf_write_dev(rcb_common, RCB_COM_AXI_ERR_STS, clr_vlue);

	/*en msk*/
	dsaf_write_dev(rcb_common, RCB_COM_INTMASK_ECC_ERR_REG, msk_vlue);

	dsaf_write_dev(rcb_common, RCB_COM_SF_CFG_INTMASK_RING, msk_vlue);

	/*for tx bd neednot cacheline, so msk sf_txring_fbd_intmask (bit 1)**/
	dsaf_write_dev(rcb_common, RCB_COM_SF_CFG_INTMASK_BD, msk_vlue | 2);

	dsaf_write_dev(rcb_common, RCB_COM_INTMSK_TX_PKT_REG, msk_vlue);
	dsaf_write_dev(rcb_common, RCB_COM_AXI_WR_ERR_INTMASK, msk_vlue);
}

/**
 *hns_rcb_common_init_hw - init rcb common hardware
 *@rcb_common: rcb_common device
 *retuen 0 - success , negative --fail
 */
int hns_rcb_common_init_hw(struct rcb_common_cb *rcb_common)
{
	u32 reg_val;
	int i;
	int port_num = hns_rcb_common_get_port_num(rcb_common);

	hns_rcb_comm_exc_irq_en(rcb_common, 0);

	reg_val = dsaf_read_dev(rcb_common, RCB_COM_CFG_INIT_FLAG_REG);
	if (0x1 != (reg_val & 0x1)) {
		dev_err(rcb_common->dsaf_dev->dev,
			"RCB_COM_CFG_INIT_FLAG_REG reg = 0x%x\n", reg_val);
		return -EBUSY;
	}

	for (i = 0; i < port_num; i++) {
		hns_rcb_set_port_desc_cnt(rcb_common, i, rcb_common->desc_num);
		(void)hns_rcb_set_coalesced_frames(
			rcb_common, i, HNS_RCB_DEF_COALESCED_FRAMES);
		hns_rcb_set_port_timeout(
			rcb_common, i, HNS_RCB_DEF_COALESCED_USECS);
	}

	dsaf_write_dev(rcb_common, RCB_COM_CFG_ENDIAN_REG,
		       HNS_RCB_COMMON_ENDIAN);

	if (AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver)) {
		dsaf_write_dev(rcb_common, RCB_COM_CFG_FNA_REG, 0x0);
		dsaf_write_dev(rcb_common, RCB_COM_CFG_FA_REG, 0x1);
	} else {
		dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_USER_REG,
				 RCB_COM_CFG_FNA_B, false);
		dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_USER_REG,
				 RCB_COM_CFG_FA_B, true);
		dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_TSO_MODE_REG,
				 RCB_COM_TSO_MODE_B, HNS_TSO_MODE_8BD_32K);
	}

	return 0;
}

int hns_rcb_buf_size2type(u32 buf_size)
{
	int bd_size_type;

	switch (buf_size) {
	case 512:
		bd_size_type = HNS_BD_SIZE_512_TYPE;
		break;
	case 1024:
		bd_size_type = HNS_BD_SIZE_1024_TYPE;
		break;
	case 2048:
		bd_size_type = HNS_BD_SIZE_2048_TYPE;
		break;
	case 4096:
		bd_size_type = HNS_BD_SIZE_4096_TYPE;
		break;
	default:
		bd_size_type = -EINVAL;
	}

	return bd_size_type;
}

static void hns_rcb_ring_get_cfg(struct hnae_queue *q, int ring_type)
{
	struct hnae_ring *ring;
	struct rcb_common_cb *rcb_common;
	struct ring_pair_cb *ring_pair_cb;
	u32 buf_size;
	u16 desc_num, mdnum_ppkt;
	bool irq_idx, is_ver1;

	ring_pair_cb = container_of(q, struct ring_pair_cb, q);
	is_ver1 = AE_IS_VER1(ring_pair_cb->rcb_common->dsaf_dev->dsaf_ver);
	if (ring_type == RX_RING) {
		ring = &q->rx_ring;
		ring->io_base = ring_pair_cb->q.io_base;
		irq_idx = HNS_RCB_IRQ_IDX_RX;
		mdnum_ppkt = HNS_RCB_RING_MAX_BD_PER_PKT;
	} else {
		ring = &q->tx_ring;
		ring->io_base = (u8 __iomem *)ring_pair_cb->q.io_base +
			HNS_RCB_TX_REG_OFFSET;
		irq_idx = HNS_RCB_IRQ_IDX_TX;
		mdnum_ppkt = is_ver1 ? HNS_RCB_RING_MAX_TXBD_PER_PKT :
				 HNS_RCBV2_RING_MAX_TXBD_PER_PKT;
	}

	rcb_common = ring_pair_cb->rcb_common;
	buf_size = rcb_common->dsaf_dev->buf_size;
	desc_num = rcb_common->dsaf_dev->desc_num;

	ring->desc = NULL;
	ring->desc_cb = NULL;

	ring->irq = ring_pair_cb->virq[irq_idx];
	ring->desc_dma_addr = 0;

	ring->buf_size = buf_size;
	ring->desc_num = desc_num;
	ring->max_desc_num_per_pkt = mdnum_ppkt;
	ring->max_raw_data_sz_per_desc = HNS_RCB_MAX_PKT_SIZE;
	ring->max_pkt_size = HNS_RCB_MAX_PKT_SIZE;
	ring->next_to_use = 0;
	ring->next_to_clean = 0;
}

static void hns_rcb_ring_pair_get_cfg(struct ring_pair_cb *ring_pair_cb)
{
	ring_pair_cb->q.handle = NULL;

	hns_rcb_ring_get_cfg(&ring_pair_cb->q, RX_RING);
	hns_rcb_ring_get_cfg(&ring_pair_cb->q, TX_RING);
}

static int hns_rcb_get_port_in_comm(
	struct rcb_common_cb *rcb_common, int ring_idx)
{
	return ring_idx / (rcb_common->max_q_per_vf * rcb_common->max_vfn);
}

#define SERVICE_RING_IRQ_IDX(v1) \
	((v1) ? HNS_SERVICE_RING_IRQ_IDX : HNSV2_SERVICE_RING_IRQ_IDX)
static int hns_rcb_get_base_irq_idx(struct rcb_common_cb *rcb_common)
{
	bool is_ver1 = AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver);

	if (!HNS_DSAF_IS_DEBUG(rcb_common->dsaf_dev))
		return SERVICE_RING_IRQ_IDX(is_ver1);
	else
		return  HNS_DEBUG_RING_IRQ_IDX;
}

#define RCB_COMM_BASE_TO_RING_BASE(base, ringid)\
	((base) + 0x10000 + HNS_RCB_REG_OFFSET * (ringid))
/**
 *hns_rcb_get_cfg - get rcb config
 *@rcb_common: rcb common device
 */
void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common)
{
	struct ring_pair_cb *ring_pair_cb;
	u32 i;
	u32 ring_num = rcb_common->ring_num;
	int base_irq_idx = hns_rcb_get_base_irq_idx(rcb_common);
	struct platform_device *pdev =
		to_platform_device(rcb_common->dsaf_dev->dev);
	bool is_ver1 = AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver);

	for (i = 0; i < ring_num; i++) {
		ring_pair_cb = &rcb_common->ring_pair_cb[i];
		ring_pair_cb->rcb_common = rcb_common;
		ring_pair_cb->dev = rcb_common->dsaf_dev->dev;
		ring_pair_cb->index = i;
		ring_pair_cb->q.io_base =
			RCB_COMM_BASE_TO_RING_BASE(rcb_common->io_base, i);
		ring_pair_cb->port_id_in_comm =
			hns_rcb_get_port_in_comm(rcb_common, i);
		ring_pair_cb->virq[HNS_RCB_IRQ_IDX_TX] =
		is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2) :
			  platform_get_irq(pdev, base_irq_idx + i * 3 + 1);
		ring_pair_cb->virq[HNS_RCB_IRQ_IDX_RX] =
		is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2 + 1) :
			  platform_get_irq(pdev, base_irq_idx + i * 3);
		ring_pair_cb->q.phy_base =
			RCB_COMM_BASE_TO_RING_BASE(rcb_common->phy_base, i);
		hns_rcb_ring_pair_get_cfg(ring_pair_cb);
	}
}

/**
 *hns_rcb_get_coalesced_frames - get rcb port coalesced frames
 *@rcb_common: rcb_common device
 *@port_idx:port id in comm
 *
 *Returns: coalesced_frames
 */
u32 hns_rcb_get_coalesced_frames(
	struct rcb_common_cb *rcb_common, u32 port_idx)
{
	return dsaf_read_dev(rcb_common, RCB_CFG_PKTLINE_REG + port_idx * 4);
}

/**
 *hns_rcb_get_coalesce_usecs - get rcb port coalesced time_out
 *@rcb_common: rcb_common device
 *@port_idx:port id in comm
 *
 *Returns: time_out
 */
u32 hns_rcb_get_coalesce_usecs(
	struct rcb_common_cb *rcb_common, u32 port_idx)
{
	if (AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver))
		return dsaf_read_dev(rcb_common, RCB_CFG_OVERTIME_REG) /
		       HNS_RCB_CLK_FREQ_MHZ;
	else
		return dsaf_read_dev(rcb_common,
				     RCB_PORT_CFG_OVERTIME_REG + port_idx * 4);
}

/**
 *hns_rcb_set_coalesce_usecs - set rcb port coalesced time_out
 *@rcb_common: rcb_common device
 *@port_idx:port id in comm
 *@timeout:tx/rx time for coalesced time_out
 *
 * Returns:
 * Zero for success, or an error code in case of failure
 */
int hns_rcb_set_coalesce_usecs(
	struct rcb_common_cb *rcb_common, u32 port_idx, u32 timeout)
{
	u32 old_timeout = hns_rcb_get_coalesce_usecs(rcb_common, port_idx);

	if (timeout == old_timeout)
		return 0;

	if (AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver)) {
		if (!HNS_DSAF_IS_DEBUG(rcb_common->dsaf_dev)) {
			dev_err(rcb_common->dsaf_dev->dev,
				"error: not support coalesce_usecs setting!\n");
			return -EINVAL;
		}
	}
	if (timeout > HNS_RCB_MAX_COALESCED_USECS) {
		dev_err(rcb_common->dsaf_dev->dev,
			"error: coalesce_usecs setting supports 0~1023us\n");
		return -EINVAL;
	}

	if (!AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver)) {
		if (timeout == 0)
			/* set timeout to 0, Disable gap time */
			dsaf_set_reg_field(rcb_common->io_base,
					   RCB_INT_GAP_TIME_REG + port_idx * 4,
					   PPE_INT_GAPTIME_M, PPE_INT_GAPTIME_B,
					   0);
		else
			/* set timeout non 0, restore gap time to 1 */
			dsaf_set_reg_field(rcb_common->io_base,
					   RCB_INT_GAP_TIME_REG + port_idx * 4,
					   PPE_INT_GAPTIME_M, PPE_INT_GAPTIME_B,
					   1);
	}

	hns_rcb_set_port_timeout(rcb_common, port_idx, timeout);
	return 0;
}

/**
 *hns_rcb_set_coalesced_frames - set rcb coalesced frames
 *@rcb_common: rcb_common device
 *@port_idx:port id in comm
 *@coalesced_frames:tx/rx BD num for coalesced frames
 *
 * Returns:
 * Zero for success, or an error code in case of failure
 */
int hns_rcb_set_coalesced_frames(
	struct rcb_common_cb *rcb_common, u32 port_idx, u32 coalesced_frames)
{
	u32 old_waterline = hns_rcb_get_coalesced_frames(rcb_common, port_idx);

	if (coalesced_frames == old_waterline)
		return 0;

	if (coalesced_frames >= rcb_common->desc_num ||
	    coalesced_frames > HNS_RCB_MAX_COALESCED_FRAMES ||
	    coalesced_frames < HNS_RCB_MIN_COALESCED_FRAMES) {
		dev_err(rcb_common->dsaf_dev->dev,
			"error: not support coalesce_frames setting!\n");
		return -EINVAL;
	}

	dsaf_write_dev(rcb_common, RCB_CFG_PKTLINE_REG + port_idx * 4,
		       coalesced_frames);
	return 0;
}

/**
 *hns_rcb_get_queue_mode - get max VM number and max ring number per VM
 *						accordding to dsaf mode
 *@dsaf_mode: dsaf mode
 *@max_vfn : max vfn number
 *@max_q_per_vf:max ring number per vm
 */
void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, u16 *max_vfn,
			    u16 *max_q_per_vf)
{
	switch (dsaf_mode) {
	case DSAF_MODE_DISABLE_6PORT_0VM:
		*max_vfn = 1;
		*max_q_per_vf = 16;
		break;
	case DSAF_MODE_DISABLE_FIX:
	case DSAF_MODE_DISABLE_SP:
		*max_vfn = 1;
		*max_q_per_vf = 1;
		break;
	case DSAF_MODE_DISABLE_2PORT_64VM:
		*max_vfn = 64;
		*max_q_per_vf = 1;
		break;
	case DSAF_MODE_DISABLE_6PORT_16VM:
		*max_vfn = 16;
		*max_q_per_vf = 1;
		break;
	default:
		*max_vfn = 1;
		*max_q_per_vf = 16;
		break;
	}
}

int hns_rcb_get_ring_num(struct dsaf_device *dsaf_dev)
{
	switch (dsaf_dev->dsaf_mode) {
	case DSAF_MODE_ENABLE_FIX:
	case DSAF_MODE_DISABLE_SP:
		return 1;

	case DSAF_MODE_DISABLE_FIX:
		return 6;

	case DSAF_MODE_ENABLE_0VM:
		return 32;

	case DSAF_MODE_DISABLE_6PORT_0VM:
	case DSAF_MODE_ENABLE_16VM:
	case DSAF_MODE_DISABLE_6PORT_2VM:
	case DSAF_MODE_DISABLE_6PORT_16VM:
	case DSAF_MODE_DISABLE_6PORT_4VM:
	case DSAF_MODE_ENABLE_8VM:
		return 96;

	case DSAF_MODE_DISABLE_2PORT_16VM:
	case DSAF_MODE_DISABLE_2PORT_8VM:
	case DSAF_MODE_ENABLE_32VM:
	case DSAF_MODE_DISABLE_2PORT_64VM:
	case DSAF_MODE_ENABLE_128VM:
		return 128;

	default:
		dev_warn(dsaf_dev->dev,
			 "get ring num fail,use default!dsaf_mode=%d\n",
			 dsaf_dev->dsaf_mode);
		return 128;
	}
}

void __iomem *hns_rcb_common_get_vaddr(struct rcb_common_cb *rcb_common)
{
	struct dsaf_device *dsaf_dev = rcb_common->dsaf_dev;

	return dsaf_dev->ppe_base + RCB_COMMON_REG_OFFSET;
}

static phys_addr_t hns_rcb_common_get_paddr(struct rcb_common_cb *rcb_common)
{
	struct dsaf_device *dsaf_dev = rcb_common->dsaf_dev;

	return dsaf_dev->ppe_paddr + RCB_COMMON_REG_OFFSET;
}

int hns_rcb_common_get_cfg(struct dsaf_device *dsaf_dev,
			   int comm_index)
{
	struct rcb_common_cb *rcb_common;
	enum dsaf_mode dsaf_mode = dsaf_dev->dsaf_mode;
	u16 max_vfn;
	u16 max_q_per_vf;
	int ring_num = hns_rcb_get_ring_num(dsaf_dev);

	rcb_common =
		devm_kzalloc(dsaf_dev->dev, sizeof(*rcb_common) +
			ring_num * sizeof(struct ring_pair_cb), GFP_KERNEL);
	if (!rcb_common) {
		dev_err(dsaf_dev->dev, "rcb common devm_kzalloc fail!\n");
		return -ENOMEM;
	}
	rcb_common->comm_index = comm_index;
	rcb_common->ring_num = ring_num;
	rcb_common->dsaf_dev = dsaf_dev;

	rcb_common->desc_num = dsaf_dev->desc_num;

	hns_rcb_get_queue_mode(dsaf_mode, &max_vfn, &max_q_per_vf);
	rcb_common->max_vfn = max_vfn;
	rcb_common->max_q_per_vf = max_q_per_vf;

	rcb_common->io_base = hns_rcb_common_get_vaddr(rcb_common);
	rcb_common->phy_base = hns_rcb_common_get_paddr(rcb_common);

	dsaf_dev->rcb_common[comm_index] = rcb_common;
	return 0;
}

void hns_rcb_common_free_cfg(struct dsaf_device *dsaf_dev,
			     u32 comm_index)
{
	dsaf_dev->rcb_common[comm_index] = NULL;
}

void hns_rcb_update_stats(struct hnae_queue *queue)
{
	struct ring_pair_cb *ring =
		container_of(queue, struct ring_pair_cb, q);
	struct dsaf_device *dsaf_dev = ring->rcb_common->dsaf_dev;
	struct ppe_common_cb *ppe_common
		= dsaf_dev->ppe_common[ring->rcb_common->comm_index];
	struct hns_ring_hw_stats *hw_stats = &ring->hw_stats;

	hw_stats->rx_pkts += dsaf_read_dev(queue,
			 RCB_RING_RX_RING_PKTNUM_RECORD_REG);
	dsaf_write_dev(queue, RCB_RING_RX_RING_PKTNUM_RECORD_REG, 0x1);

	hw_stats->ppe_rx_ok_pkts += dsaf_read_dev(ppe_common,
			 PPE_COM_HIS_RX_PKT_QID_OK_CNT_REG + 4 * ring->index);
	hw_stats->ppe_rx_drop_pkts += dsaf_read_dev(ppe_common,
			 PPE_COM_HIS_RX_PKT_QID_DROP_CNT_REG + 4 * ring->index);

	hw_stats->tx_pkts += dsaf_read_dev(queue,
			 RCB_RING_TX_RING_PKTNUM_RECORD_REG);
	dsaf_write_dev(queue, RCB_RING_TX_RING_PKTNUM_RECORD_REG, 0x1);

	hw_stats->ppe_tx_ok_pkts += dsaf_read_dev(ppe_common,
			 PPE_COM_HIS_TX_PKT_QID_OK_CNT_REG + 4 * ring->index);
	hw_stats->ppe_tx_drop_pkts += dsaf_read_dev(ppe_common,
			 PPE_COM_HIS_TX_PKT_QID_ERR_CNT_REG + 4 * ring->index);
}

/**
 *hns_rcb_get_stats - get rcb statistic
 *@ring: rcb ring
 *@data:statistic value
 */
void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data)
{
	u64 *regs_buff = data;
	struct ring_pair_cb *ring =
		container_of(queue, struct ring_pair_cb, q);
	struct hns_ring_hw_stats *hw_stats = &ring->hw_stats;

	regs_buff[0] = hw_stats->tx_pkts;
	regs_buff[1] = hw_stats->ppe_tx_ok_pkts;
	regs_buff[2] = hw_stats->ppe_tx_drop_pkts;
	regs_buff[3] =
		dsaf_read_dev(queue, RCB_RING_TX_RING_FBDNUM_REG);

	regs_buff[4] = queue->tx_ring.stats.tx_pkts;
	regs_buff[5] = queue->tx_ring.stats.tx_bytes;
	regs_buff[6] = queue->tx_ring.stats.tx_err_cnt;
	regs_buff[7] = queue->tx_ring.stats.io_err_cnt;
	regs_buff[8] = queue->tx_ring.stats.sw_err_cnt;
	regs_buff[9] = queue->tx_ring.stats.seg_pkt_cnt;
	regs_buff[10] = queue->tx_ring.stats.restart_queue;
	regs_buff[11] = queue->tx_ring.stats.tx_busy;

	regs_buff[12] = hw_stats->rx_pkts;
	regs_buff[13] = hw_stats->ppe_rx_ok_pkts;
	regs_buff[14] = hw_stats->ppe_rx_drop_pkts;
	regs_buff[15] =
		dsaf_read_dev(queue, RCB_RING_RX_RING_FBDNUM_REG);

	regs_buff[16] = queue->rx_ring.stats.rx_pkts;
	regs_buff[17] = queue->rx_ring.stats.rx_bytes;
	regs_buff[18] = queue->rx_ring.stats.rx_err_cnt;
	regs_buff[19] = queue->rx_ring.stats.io_err_cnt;
	regs_buff[20] = queue->rx_ring.stats.sw_err_cnt;
	regs_buff[21] = queue->rx_ring.stats.seg_pkt_cnt;
	regs_buff[22] = queue->rx_ring.stats.reuse_pg_cnt;
	regs_buff[23] = queue->rx_ring.stats.err_pkt_len;
	regs_buff[24] = queue->rx_ring.stats.non_vld_descs;
	regs_buff[25] = queue->rx_ring.stats.err_bd_num;
	regs_buff[26] = queue->rx_ring.stats.l2_err;
	regs_buff[27] = queue->rx_ring.stats.l3l4_csum_err;
}

/**
 *hns_rcb_get_ring_sset_count - rcb string set count
 *@stringset:ethtool cmd
 *return rcb ring string set count
 */
int hns_rcb_get_ring_sset_count(int stringset)
{
	if (stringset == ETH_SS_STATS)
		return HNS_RING_STATIC_REG_NUM;

	return 0;
}

/**
 *hns_rcb_get_common_regs_count - rcb common regs count
 *return regs count
 */
int hns_rcb_get_common_regs_count(void)
{
	return HNS_RCB_COMMON_DUMP_REG_NUM;
}

/**
 *rcb_get_sset_count - rcb ring regs count
 *return regs count
 */
int hns_rcb_get_ring_regs_count(void)
{
	return HNS_RCB_RING_DUMP_REG_NUM;
}

/**
 *hns_rcb_get_strings - get rcb string set
 *@stringset:string set index
 *@data:strings name value
 *@index:queue index
 */
void hns_rcb_get_strings(int stringset, u8 *data, int index)
{
	char *buff = (char *)data;

	if (stringset != ETH_SS_STATS)
		return;

	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_rcb_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_ppe_tx_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_ppe_drop_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_fbd_num", index);
	buff = buff + ETH_GSTRING_LEN;

	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_bytes", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_err_cnt", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_io_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_sw_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_seg_pkt", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_restart_queue", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "tx_ring%d_tx_busy", index);
	buff = buff + ETH_GSTRING_LEN;

	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_rcb_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_ppe_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_ppe_drop_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_fbd_num", index);
	buff = buff + ETH_GSTRING_LEN;

	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_pkt_num", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_bytes", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_err_cnt", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_io_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_sw_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_seg_pkt", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_reuse_pg", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_len_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_non_vld_desc_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_bd_num_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_l2_err", index);
	buff = buff + ETH_GSTRING_LEN;
	snprintf(buff, ETH_GSTRING_LEN, "rx_ring%d_l3l4csum_err", index);
}

void hns_rcb_get_common_regs(struct rcb_common_cb *rcb_com, void *data)
{
	u32 *regs = data;
	bool is_ver1 = AE_IS_VER1(rcb_com->dsaf_dev->dsaf_ver);
	bool is_dbg = HNS_DSAF_IS_DEBUG(rcb_com->dsaf_dev);
	u32 reg_tmp;
	u32 reg_num_tmp;
	u32 i = 0;

	/*rcb common registers */
	regs[0] = dsaf_read_dev(rcb_com, RCB_COM_CFG_ENDIAN_REG);
	regs[1] = dsaf_read_dev(rcb_com, RCB_COM_CFG_SYS_FSH_REG);
	regs[2] = dsaf_read_dev(rcb_com, RCB_COM_CFG_INIT_FLAG_REG);

	regs[3] = dsaf_read_dev(rcb_com, RCB_COM_CFG_PKT_REG);
	regs[4] = dsaf_read_dev(rcb_com, RCB_COM_CFG_RINVLD_REG);
	regs[5] = dsaf_read_dev(rcb_com, RCB_COM_CFG_FNA_REG);
	regs[6] = dsaf_read_dev(rcb_com, RCB_COM_CFG_FA_REG);
	regs[7] = dsaf_read_dev(rcb_com, RCB_COM_CFG_PKT_TC_BP_REG);
	regs[8] = dsaf_read_dev(rcb_com, RCB_COM_CFG_PPE_TNL_CLKEN_REG);

	regs[9] = dsaf_read_dev(rcb_com, RCB_COM_INTMSK_TX_PKT_REG);
	regs[10] = dsaf_read_dev(rcb_com, RCB_COM_RINT_TX_PKT_REG);
	regs[11] = dsaf_read_dev(rcb_com, RCB_COM_INTMASK_ECC_ERR_REG);
	regs[12] = dsaf_read_dev(rcb_com, RCB_COM_INTSTS_ECC_ERR_REG);
	regs[13] = dsaf_read_dev(rcb_com, RCB_COM_EBD_SRAM_ERR_REG);
	regs[14] = dsaf_read_dev(rcb_com, RCB_COM_RXRING_ERR_REG);
	regs[15] = dsaf_read_dev(rcb_com, RCB_COM_TXRING_ERR_REG);
	regs[16] = dsaf_read_dev(rcb_com, RCB_COM_TX_FBD_ERR_REG);
	regs[17] = dsaf_read_dev(rcb_com, RCB_SRAM_ECC_CHK_EN_REG);
	regs[18] = dsaf_read_dev(rcb_com, RCB_SRAM_ECC_CHK0_REG);
	regs[19] = dsaf_read_dev(rcb_com, RCB_SRAM_ECC_CHK1_REG);
	regs[20] = dsaf_read_dev(rcb_com, RCB_SRAM_ECC_CHK2_REG);
	regs[21] = dsaf_read_dev(rcb_com, RCB_SRAM_ECC_CHK3_REG);
	regs[22] = dsaf_read_dev(rcb_com, RCB_SRAM_ECC_CHK4_REG);
	regs[23] = dsaf_read_dev(rcb_com, RCB_SRAM_ECC_CHK5_REG);
	regs[24] = dsaf_read_dev(rcb_com, RCB_ECC_ERR_ADDR0_REG);
	regs[25] = dsaf_read_dev(rcb_com, RCB_ECC_ERR_ADDR3_REG);
	regs[26] = dsaf_read_dev(rcb_com, RCB_ECC_ERR_ADDR4_REG);
	regs[27] = dsaf_read_dev(rcb_com, RCB_ECC_ERR_ADDR5_REG);

	regs[28] = dsaf_read_dev(rcb_com, RCB_COM_SF_CFG_INTMASK_RING);
	regs[29] = dsaf_read_dev(rcb_com, RCB_COM_SF_CFG_RING_STS);
	regs[30] = dsaf_read_dev(rcb_com, RCB_COM_SF_CFG_RING);
	regs[31] = dsaf_read_dev(rcb_com, RCB_COM_SF_CFG_INTMASK_BD);
	regs[32] = dsaf_read_dev(rcb_com, RCB_COM_SF_CFG_BD_RINT_STS);
	regs[33] = dsaf_read_dev(rcb_com, RCB_COM_RCB_RD_BD_BUSY);
	regs[34] = dsaf_read_dev(rcb_com, RCB_COM_RCB_FBD_CRT_EN);
	regs[35] = dsaf_read_dev(rcb_com, RCB_COM_AXI_WR_ERR_INTMASK);
	regs[36] = dsaf_read_dev(rcb_com, RCB_COM_AXI_ERR_STS);
	regs[37] = dsaf_read_dev(rcb_com, RCB_COM_CHK_TX_FBD_NUM_REG);

	/* rcb common entry registers */
	for (i = 0; i < 16; i++) { /* total 16 model registers */
		regs[38 + i]
			= dsaf_read_dev(rcb_com, RCB_CFG_BD_NUM_REG + 4 * i);
		regs[54 + i]
			= dsaf_read_dev(rcb_com, RCB_CFG_PKTLINE_REG + 4 * i);
	}

	reg_tmp = is_ver1 ? RCB_CFG_OVERTIME_REG : RCB_PORT_CFG_OVERTIME_REG;
	reg_num_tmp = (is_ver1 || is_dbg) ? 1 : 6;
	for (i = 0; i < reg_num_tmp; i++)
		regs[70 + i] = dsaf_read_dev(rcb_com, reg_tmp);

	regs[76] = dsaf_read_dev(rcb_com, RCB_CFG_PKTLINE_INT_NUM_REG);
	regs[77] = dsaf_read_dev(rcb_com, RCB_CFG_OVERTIME_INT_NUM_REG);

	/* mark end of rcb common regs */
	for (i = 78; i < 80; i++)
		regs[i] = 0xcccccccc;
}

void hns_rcb_get_ring_regs(struct hnae_queue *queue, void *data)
{
	u32 *regs = data;
	struct ring_pair_cb *ring_pair
		= container_of(queue, struct ring_pair_cb, q);
	u32 i = 0;

	/*rcb ring registers */
	regs[0] = dsaf_read_dev(queue, RCB_RING_RX_RING_BASEADDR_L_REG);
	regs[1] = dsaf_read_dev(queue, RCB_RING_RX_RING_BASEADDR_H_REG);
	regs[2] = dsaf_read_dev(queue, RCB_RING_RX_RING_BD_NUM_REG);
	regs[3] = dsaf_read_dev(queue, RCB_RING_RX_RING_BD_LEN_REG);
	regs[4] = dsaf_read_dev(queue, RCB_RING_RX_RING_PKTLINE_REG);
	regs[5] = dsaf_read_dev(queue, RCB_RING_RX_RING_TAIL_REG);
	regs[6] = dsaf_read_dev(queue, RCB_RING_RX_RING_HEAD_REG);
	regs[7] = dsaf_read_dev(queue, RCB_RING_RX_RING_FBDNUM_REG);
	regs[8] = dsaf_read_dev(queue, RCB_RING_RX_RING_PKTNUM_RECORD_REG);

	regs[9] = dsaf_read_dev(queue, RCB_RING_TX_RING_BASEADDR_L_REG);
	regs[10] = dsaf_read_dev(queue, RCB_RING_TX_RING_BASEADDR_H_REG);
	regs[11] = dsaf_read_dev(queue, RCB_RING_TX_RING_BD_NUM_REG);
	regs[12] = dsaf_read_dev(queue, RCB_RING_TX_RING_BD_LEN_REG);
	regs[13] = dsaf_read_dev(queue, RCB_RING_TX_RING_PKTLINE_REG);
	regs[15] = dsaf_read_dev(queue, RCB_RING_TX_RING_TAIL_REG);
	regs[16] = dsaf_read_dev(queue, RCB_RING_TX_RING_HEAD_REG);
	regs[17] = dsaf_read_dev(queue, RCB_RING_TX_RING_FBDNUM_REG);
	regs[18] = dsaf_read_dev(queue, RCB_RING_TX_RING_OFFSET_REG);
	regs[19] = dsaf_read_dev(queue, RCB_RING_TX_RING_PKTNUM_RECORD_REG);

	regs[20] = dsaf_read_dev(queue, RCB_RING_PREFETCH_EN_REG);
	regs[21] = dsaf_read_dev(queue, RCB_RING_CFG_VF_NUM_REG);
	regs[22] = dsaf_read_dev(queue, RCB_RING_ASID_REG);
	regs[23] = dsaf_read_dev(queue, RCB_RING_RX_VM_REG);
	regs[24] = dsaf_read_dev(queue, RCB_RING_T0_BE_RST);
	regs[25] = dsaf_read_dev(queue, RCB_RING_COULD_BE_RST);
	regs[26] = dsaf_read_dev(queue, RCB_RING_WRR_WEIGHT_REG);

	regs[27] = dsaf_read_dev(queue, RCB_RING_INTMSK_RXWL_REG);
	regs[28] = dsaf_read_dev(queue, RCB_RING_INTSTS_RX_RING_REG);
	regs[29] = dsaf_read_dev(queue, RCB_RING_INTMSK_TXWL_REG);
	regs[30] = dsaf_read_dev(queue, RCB_RING_INTSTS_TX_RING_REG);
	regs[31] = dsaf_read_dev(queue, RCB_RING_INTMSK_RX_OVERTIME_REG);
	regs[32] = dsaf_read_dev(queue, RCB_RING_INTSTS_RX_OVERTIME_REG);
	regs[33] = dsaf_read_dev(queue, RCB_RING_INTMSK_TX_OVERTIME_REG);
	regs[34] = dsaf_read_dev(queue, RCB_RING_INTSTS_TX_OVERTIME_REG);

	/* mark end of ring regs */
	for (i = 35; i < 40; i++)
		regs[i] = 0xcccccc00 + ring_pair->index;
}
