numam-dpdk/drivers/common/cnxk/roc_nix_mac.c
Harman Kalra 02719901d5 common/cnxk: send link status event to VF
Currently link event is only sent to the PF by AF as soon as it comes
up, or in case of any physical change in link. PF will broadcast
these link events to all its VFs as soon as it receives it.
But no event is sent when a new VF comes up, hence it will not have
the link status.
Adding support for sending link status to the VF once it comes up
successfully.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
2021-09-16 16:28:51 +02:00

322 lines
6.9 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2021 Marvell.
*/
#include "roc_api.h"
#include "roc_priv.h"
static inline struct mbox *
nix_to_mbox(struct nix *nix)
{
struct dev *dev = &nix->dev;
return dev->mbox;
}
int
roc_nix_mac_rxtx_start_stop(struct roc_nix *roc_nix, bool start)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
if (roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
if (start)
mbox_alloc_msg_cgx_start_rxtx(mbox);
else
mbox_alloc_msg_cgx_stop_rxtx(mbox);
return mbox_process(mbox);
}
int
roc_nix_mac_link_event_start_stop(struct roc_nix *roc_nix, bool start)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
if (roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
if (start)
mbox_alloc_msg_cgx_start_linkevents(mbox);
else
mbox_alloc_msg_cgx_stop_linkevents(mbox);
return mbox_process(mbox);
}
int
roc_nix_mac_loopback_enable(struct roc_nix *roc_nix, bool enable)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
if (enable && roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
if (enable)
mbox_alloc_msg_cgx_intlbk_enable(mbox);
else
mbox_alloc_msg_cgx_intlbk_disable(mbox);
return mbox_process(mbox);
}
int
roc_nix_mac_addr_set(struct roc_nix *roc_nix, const uint8_t addr[])
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct cgx_mac_addr_set_or_get *req;
if (roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
if (dev_active_vfs(&nix->dev))
return NIX_ERR_OP_NOTSUP;
req = mbox_alloc_msg_cgx_mac_addr_set(mbox);
mbox_memcpy(req->mac_addr, addr, PLT_ETHER_ADDR_LEN);
return mbox_process(mbox);
}
int
roc_nix_mac_max_entries_get(struct roc_nix *roc_nix)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct cgx_max_dmac_entries_get_rsp *rsp;
struct mbox *mbox = nix_to_mbox(nix);
int rc;
if (roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
mbox_alloc_msg_cgx_mac_max_entries_get(mbox);
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
return rc;
return rsp->max_dmac_filters ? rsp->max_dmac_filters : 1;
}
int
roc_nix_mac_addr_add(struct roc_nix *roc_nix, uint8_t addr[])
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct cgx_mac_addr_add_req *req;
struct cgx_mac_addr_add_rsp *rsp;
int rc;
if (roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
if (dev_active_vfs(&nix->dev))
return NIX_ERR_OP_NOTSUP;
req = mbox_alloc_msg_cgx_mac_addr_add(mbox);
mbox_memcpy(req->mac_addr, addr, PLT_ETHER_ADDR_LEN);
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc < 0)
return rc;
return rsp->index;
}
int
roc_nix_mac_addr_del(struct roc_nix *roc_nix, uint32_t index)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct cgx_mac_addr_del_req *req;
int rc = -ENOSPC;
if (roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
req = mbox_alloc_msg_cgx_mac_addr_del(mbox);
if (req == NULL)
return rc;
req->index = index;
return mbox_process(mbox);
}
int
roc_nix_mac_promisc_mode_enable(struct roc_nix *roc_nix, int enable)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
if (roc_nix_is_vf_or_sdp(roc_nix))
return NIX_ERR_OP_NOTSUP;
if (enable)
mbox_alloc_msg_cgx_promisc_enable(mbox);
else
mbox_alloc_msg_cgx_promisc_disable(mbox);
return mbox_process(mbox);
}
int
roc_nix_mac_link_info_get(struct roc_nix *roc_nix,
struct roc_nix_link_info *link_info)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct cgx_link_info_msg *rsp;
int rc;
mbox_alloc_msg_cgx_get_linkinfo(mbox);
rc = mbox_process_msg(mbox, (void *)&rsp);
if (rc)
return rc;
link_info->status = rsp->link_info.link_up;
link_info->full_duplex = rsp->link_info.full_duplex;
link_info->lmac_type_id = rsp->link_info.lmac_type_id;
link_info->speed = rsp->link_info.speed;
link_info->autoneg = rsp->link_info.an;
link_info->fec = rsp->link_info.fec;
link_info->port = rsp->link_info.port;
return 0;
}
int
roc_nix_mac_link_state_set(struct roc_nix *roc_nix, uint8_t up)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct cgx_set_link_state_msg *req;
int rc = -ENOSPC;
req = mbox_alloc_msg_cgx_set_link_state(mbox);
if (req == NULL)
return rc;
req->enable = up;
return mbox_process(mbox);
}
int
roc_nix_mac_link_info_set(struct roc_nix *roc_nix,
struct roc_nix_link_info *link_info)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct cgx_set_link_mode_req *req;
int rc;
rc = roc_nix_mac_link_state_set(roc_nix, link_info->status);
if (rc)
return rc;
req = mbox_alloc_msg_cgx_set_link_mode(mbox);
if (req == NULL)
return -ENOSPC;
req->args.speed = link_info->speed;
req->args.duplex = link_info->full_duplex;
req->args.an = link_info->autoneg;
return mbox_process(mbox);
}
int
roc_nix_mac_mtu_set(struct roc_nix *roc_nix, uint16_t mtu)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct nix_frs_cfg *req;
bool sdp_link = false;
int rc = -ENOSPC;
if (roc_nix_is_sdp(roc_nix))
sdp_link = true;
req = mbox_alloc_msg_nix_set_hw_frs(mbox);
if (req == NULL)
return rc;
req->maxlen = mtu;
req->update_smq = true;
req->sdp_link = sdp_link;
rc = mbox_process(mbox);
if (rc)
return rc;
/* Save MTU for later use */
nix->mtu = mtu;
return 0;
}
int
roc_nix_mac_max_rx_len_set(struct roc_nix *roc_nix, uint16_t maxlen)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct mbox *mbox = nix_to_mbox(nix);
struct nix_frs_cfg *req;
bool sdp_link = false;
int rc = -ENOSPC;
if (roc_nix_is_sdp(roc_nix))
sdp_link = true;
req = mbox_alloc_msg_nix_set_hw_frs(mbox);
if (req == NULL)
return rc;
req->sdp_link = sdp_link;
req->maxlen = maxlen;
return mbox_process(mbox);
}
int
roc_nix_mac_link_cb_register(struct roc_nix *roc_nix, link_status_t link_update)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
if (link_update == NULL)
return NIX_ERR_PARAM;
dev->ops->link_status_update = (link_info_t)link_update;
return 0;
}
void
roc_nix_mac_link_cb_unregister(struct roc_nix *roc_nix)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
dev->ops->link_status_update = NULL;
}
int
roc_nix_mac_link_info_get_cb_register(struct roc_nix *roc_nix,
link_info_get_t link_info_get)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
if (link_info_get == NULL)
return NIX_ERR_PARAM;
dev->ops->link_status_get = (link_info_t)link_info_get;
return 0;
}
void
roc_nix_mac_link_info_get_cb_unregister(struct roc_nix *roc_nix)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
dev->ops->link_status_get = NULL;
}