// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*/
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include "hnae.h"
#include "hns_dsaf_mac.h"
#include "hns_dsaf_main.h"
#include "hns_dsaf_ppe.h"
#include "hns_dsaf_rcb.h"
static struct hns_mac_cb *hns_get_mac_cb(struct hnae_handle *handle)
{
struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle);
return vf_cb->mac_cb;
}
static struct dsaf_device *hns_ae_get_dsaf_dev(struct hnae_ae_dev *dev)
{
return container_of(dev, struct dsaf_device, ae_dev);
}
static struct hns_ppe_cb *hns_get_ppe_cb(struct hnae_handle *handle)
{
int ppe_index;
struct ppe_common_cb *ppe_comm;
struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle);
ppe_comm = vf_cb->dsaf_dev->ppe_common[0];
ppe_index = vf_cb->port_index;
return &ppe_comm->ppe_cb[ppe_index];
}
static int hns_ae_get_q_num_per_vf(
struct dsaf_device *dsaf_dev, int port)
{
return dsaf_dev->rcb_common[0]->max_q_per_vf;
}
static int hns_ae_get_vf_num_per_port(
struct dsaf_device *dsaf_dev, int port)
{
return dsaf_dev->rcb_common[0]->max_vfn;
}
static struct ring_pair_cb *hns_ae_get_base_ring_pair(
struct dsaf_device *dsaf_dev, int port)
{
struct rcb_common_cb *rcb_comm = dsaf_dev->rcb_common[0];
int q_num = rcb_comm->max_q_per_vf;
int vf_num = rcb_comm->max_vfn;
return &rcb_comm->ring_pair_cb[port * q_num * vf_num];
}
static struct ring_pair_cb *hns_ae_get_ring_pair(struct hnae_queue *q)
{
return container_of(q, struct ring_pair_cb, q);
}
static struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev,
u32 port_id)
{
int vfnum_per_port;
int qnum_per_vf;
int i;
struct dsaf_device *dsaf_dev;
struct hnae_handle *ae_handle;
struct ring_pair_cb *ring_pair_cb;
struct hnae_vf_cb *vf_cb;
dsaf_dev = hns_ae_get_dsaf_dev(dev);
ring_pair_cb = hns_ae_get_base_ring_pair(dsaf_dev, port_id);
vfnum_per_port = hns_ae_get_vf_num_per_port(dsaf_dev, port_id);
qnum_per_vf = hns_ae_get_q_num_per_vf(dsaf_dev, port_id);
vf_cb = kzalloc(sizeof(*vf_cb) +
qnum_per_vf * sizeof(struct hnae_queue *), GFP_KERNEL);
if (unlikely(!vf_cb)) {
dev_err(dsaf_dev->dev, "malloc vf_cb fail!\n");
ae_handle = ERR_PTR(-ENOMEM);
goto handle_err;
}
ae_handle = &vf_cb->ae_handle;
/* ae_handle Init */
ae_handle->owner_dev = dsaf_dev->dev;
ae_handle->dev = dev;
ae_handle->q_num = qnum_per_vf;
ae_handle->coal_param = HNAE_LOWEST_LATENCY_COAL_PARAM;
/* find ring pair, and set vf id*/
for (ae_handle->vf_id = 0;
ae_handle->vf_id < vfnum_per_port; ae_handle->vf_id++) {
if (!ring_pair_cb->used_by_vf)
break;
ring_pair_cb += qnum_per_vf;
}
if (ae_handle->vf_id >= vfnum_per_port) {
dev_err(dsaf_dev->dev, "malloc queue fail!\n");
ae_handle = ERR_PTR(-EINVAL);
goto vf_id_err;
}
ae_handle->qs = (struct hnae_queue **)(&ae_handle->qs + 1);
for (i = 0; i < qnum_per_vf; i++) {
ae_handle->qs[i] = &ring_pair_cb->q;
ae_handle->qs[i]->rx_ring.q = ae_handle->qs[i];
ae_handle->qs[i]->tx_ring.q = ae_handle->qs[i];
ring_pair_cb->