linux/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Marvell RVU Ethernet driver
   3 *
   4 * Copyright (C) 2021 Marvell.
   5 *
   6 */
   7
   8#include "otx2_common.h"
   9
  10static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
  11                               u8 *dmac_index)
  12{
  13        struct cgx_mac_addr_add_req *req;
  14        struct cgx_mac_addr_add_rsp *rsp;
  15        int err;
  16
  17        mutex_lock(&pf->mbox.lock);
  18
  19        req = otx2_mbox_alloc_msg_cgx_mac_addr_add(&pf->mbox);
  20        if (!req) {
  21                mutex_unlock(&pf->mbox.lock);
  22                return -ENOMEM;
  23        }
  24
  25        ether_addr_copy(req->mac_addr, mac);
  26        err = otx2_sync_mbox_msg(&pf->mbox);
  27
  28        if (!err) {
  29                rsp = (struct cgx_mac_addr_add_rsp *)
  30                         otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
  31                *dmac_index = rsp->index;
  32        }
  33
  34        mutex_unlock(&pf->mbox.lock);
  35        return err;
  36}
  37
  38static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf)
  39{
  40        struct cgx_mac_addr_set_or_get *req;
  41        int err;
  42
  43        mutex_lock(&pf->mbox.lock);
  44
  45        req = otx2_mbox_alloc_msg_cgx_mac_addr_set(&pf->mbox);
  46        if (!req) {
  47                mutex_unlock(&pf->mbox.lock);
  48                return -ENOMEM;
  49        }
  50
  51        ether_addr_copy(req->mac_addr, pf->netdev->dev_addr);
  52        err = otx2_sync_mbox_msg(&pf->mbox);
  53
  54        mutex_unlock(&pf->mbox.lock);
  55        return err;
  56}
  57
  58int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos)
  59{
  60        u8 *dmacindex;
  61
  62        /* Store dmacindex returned by CGX/RPM driver which will
  63         * be used for macaddr update/remove
  64         */
  65        dmacindex = &pf->flow_cfg->bmap_to_dmacindex[bit_pos];
  66
  67        if (ether_addr_equal(mac, pf->netdev->dev_addr))
  68                return otx2_dmacflt_add_pfmac(pf);
  69        else
  70                return otx2_dmacflt_do_add(pf, mac, dmacindex);
  71}
  72
  73static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac,
  74                                  u8 dmac_index)
  75{
  76        struct cgx_mac_addr_del_req *req;
  77        int err;
  78
  79        mutex_lock(&pfvf->mbox.lock);
  80        req = otx2_mbox_alloc_msg_cgx_mac_addr_del(&pfvf->mbox);
  81        if (!req) {
  82                mutex_unlock(&pfvf->mbox.lock);
  83                return -ENOMEM;
  84        }
  85
  86        req->index = dmac_index;
  87
  88        err = otx2_sync_mbox_msg(&pfvf->mbox);
  89        mutex_unlock(&pfvf->mbox.lock);
  90
  91        return err;
  92}
  93
  94static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
  95{
  96        struct msg_req *req;
  97        int err;
  98
  99        mutex_lock(&pf->mbox.lock);
 100        req = otx2_mbox_alloc_msg_cgx_mac_addr_reset(&pf->mbox);
 101        if (!req) {
 102                mutex_unlock(&pf->mbox.lock);
 103                return -ENOMEM;
 104        }
 105
 106        err = otx2_sync_mbox_msg(&pf->mbox);
 107
 108        mutex_unlock(&pf->mbox.lock);
 109        return err;
 110}
 111
 112int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac,
 113                        u8 bit_pos)
 114{
 115        u8 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
 116
 117        if (ether_addr_equal(mac, pf->netdev->dev_addr))
 118                return otx2_dmacflt_remove_pfmac(pf);
 119        else
 120                return otx2_dmacflt_do_remove(pf, mac, dmacindex);
 121}
 122
 123/* CGX/RPM blocks support max unicast entries of 32.
 124 * on typical configuration MAC block associated
 125 * with 4 lmacs, each lmac will have 8 dmac entries
 126 */
 127int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf)
 128{
 129        struct cgx_max_dmac_entries_get_rsp *rsp;
 130        struct msg_req *msg;
 131        int err;
 132
 133        mutex_lock(&pf->mbox.lock);
 134        msg = otx2_mbox_alloc_msg_cgx_mac_max_entries_get(&pf->mbox);
 135
 136        if (!msg) {
 137                mutex_unlock(&pf->mbox.lock);
 138                return -ENOMEM;
 139        }
 140
 141        err = otx2_sync_mbox_msg(&pf->mbox);
 142        if (err)
 143                goto out;
 144
 145        rsp = (struct cgx_max_dmac_entries_get_rsp *)
 146                     otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &msg->hdr);
 147        pf->flow_cfg->dmacflt_max_flows = rsp->max_dmac_filters;
 148
 149out:
 150        mutex_unlock(&pf->mbox.lock);
 151        return err;
 152}
 153
 154int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos)
 155{
 156        struct cgx_mac_addr_update_req *req;
 157        int rc;
 158
 159        mutex_lock(&pf->mbox.lock);
 160
 161        req = otx2_mbox_alloc_msg_cgx_mac_addr_update(&pf->mbox);
 162
 163        if (!req) {
 164                mutex_unlock(&pf->mbox.lock);
 165                return -ENOMEM;
 166        }
 167
 168        ether_addr_copy(req->mac_addr, mac);
 169        req->index = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
 170        rc = otx2_sync_mbox_msg(&pf->mbox);
 171
 172        mutex_unlock(&pf->mbox.lock);
 173        return rc;
 174}
 175