common/cnxk: support NIX MAC operations
authorSunil Kumar Kori <skori@marvell.com>
Tue, 6 Apr 2021 14:41:13 +0000 (20:11 +0530)
committerJerin Jacob <jerinj@marvell.com>
Fri, 9 Apr 2021 06:32:24 +0000 (08:32 +0200)
Add support to different MAC related operations such as
MAC address set/get, link set/get, link status callback,
etc.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
drivers/common/cnxk/meson.build
drivers/common/cnxk/roc_nix.h
drivers/common/cnxk/roc_nix_mac.c [new file with mode: 0644]
drivers/common/cnxk/version.map

index 47e7c43..b9da55b 100644 (file)
@@ -17,6 +17,7 @@ sources = files('roc_dev.c',
                'roc_model.c',
                'roc_nix.c',
                'roc_nix_irq.c',
+               'roc_nix_mac.c',
                'roc_nix_queue.c',
                'roc_npa.c',
                'roc_npa_debug.c',
index 8027e6d..66e0bfa 100644 (file)
@@ -100,6 +100,23 @@ struct roc_nix_sq {
        void *fc;
 };
 
+struct roc_nix_link_info {
+       uint64_t status : 1;
+       uint64_t full_duplex : 1;
+       uint64_t lmac_type_id : 4;
+       uint64_t speed : 20;
+       uint64_t autoneg : 1;
+       uint64_t fec : 2;
+       uint64_t port : 8;
+};
+
+/* Link status update callback */
+typedef void (*link_status_t)(struct roc_nix *roc_nix,
+                             struct roc_nix_link_info *link);
+
+/* PTP info update callback */
+typedef int (*ptp_info_update_t)(struct roc_nix *roc_nix, bool enable);
+
 struct roc_nix {
        /* Input parameters */
        struct plt_pci_device *pci_dev;
@@ -152,6 +169,30 @@ void __roc_api roc_nix_unregister_queue_irqs(struct roc_nix *roc_nix);
 int __roc_api roc_nix_register_cq_irqs(struct roc_nix *roc_nix);
 void __roc_api roc_nix_unregister_cq_irqs(struct roc_nix *roc_nix);
 
+/* MAC */
+int __roc_api roc_nix_mac_rxtx_start_stop(struct roc_nix *roc_nix, bool start);
+int __roc_api roc_nix_mac_link_event_start_stop(struct roc_nix *roc_nix,
+                                               bool start);
+int __roc_api roc_nix_mac_loopback_enable(struct roc_nix *roc_nix, bool enable);
+int __roc_api roc_nix_mac_addr_set(struct roc_nix *roc_nix,
+                                  const uint8_t addr[]);
+int __roc_api roc_nix_mac_max_entries_get(struct roc_nix *roc_nix);
+int __roc_api roc_nix_mac_addr_add(struct roc_nix *roc_nix, uint8_t addr[]);
+int __roc_api roc_nix_mac_addr_del(struct roc_nix *roc_nix, uint32_t index);
+int __roc_api roc_nix_mac_promisc_mode_enable(struct roc_nix *roc_nix,
+                                             int enable);
+int __roc_api roc_nix_mac_link_state_set(struct roc_nix *roc_nix, uint8_t up);
+int __roc_api roc_nix_mac_link_info_set(struct roc_nix *roc_nix,
+                                       struct roc_nix_link_info *link_info);
+int __roc_api roc_nix_mac_link_info_get(struct roc_nix *roc_nix,
+                                       struct roc_nix_link_info *link_info);
+int __roc_api roc_nix_mac_mtu_set(struct roc_nix *roc_nix, uint16_t mtu);
+int __roc_api roc_nix_mac_max_rx_len_set(struct roc_nix *roc_nix,
+                                        uint16_t maxlen);
+int __roc_api roc_nix_mac_link_cb_register(struct roc_nix *roc_nix,
+                                          link_status_t link_update);
+void __roc_api roc_nix_mac_link_cb_unregister(struct roc_nix *roc_nix);
+
 /* Queue */
 int __roc_api roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq,
                              bool ena);
diff --git a/drivers/common/cnxk/roc_nix_mac.c b/drivers/common/cnxk/roc_nix_mac.c
new file mode 100644 (file)
index 0000000..682d5a7
--- /dev/null
@@ -0,0 +1,298 @@
+/* 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;
+}
index 90bbf07..1f41a88 100644 (file)
@@ -29,6 +29,21 @@ INTERNAL {
        roc_nix_is_vf_or_sdp;
        roc_nix_lf_alloc;
        roc_nix_lf_free;
+       roc_nix_mac_addr_add;
+       roc_nix_mac_addr_del;
+       roc_nix_mac_addr_set;
+       roc_nix_mac_link_cb_register;
+       roc_nix_mac_link_cb_unregister;
+       roc_nix_mac_link_event_start_stop;
+       roc_nix_mac_link_info_get;
+       roc_nix_mac_link_info_set;
+       roc_nix_mac_link_state_set;
+       roc_nix_mac_loopback_enable;
+       roc_nix_mac_max_entries_get;
+       roc_nix_mac_max_rx_len_set;
+       roc_nix_mac_mtu_set;
+       roc_nix_mac_promisc_mode_enable;
+       roc_nix_mac_rxtx_start_stop;
        roc_nix_max_pkt_len;
        roc_nix_ras_intr_ena_dis;
        roc_nix_register_cq_irqs;