149 lines
4.8 KiB
C
149 lines
4.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (C) 2021 - 2023, Shanghai Yunsilicon Technology Co., Ltd.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#ifndef ESWITCH_H
|
|
#define ESWITCH_H
|
|
|
|
#include <linux/if_ether.h>
|
|
#include <linux/if_link.h>
|
|
#include <linux/atomic.h>
|
|
#include <linux/if_vlan.h>
|
|
#include <linux/bitmap.h>
|
|
#include <net/devlink.h>
|
|
#include "common/xsc_core.h"
|
|
#include "common/vport.h"
|
|
|
|
struct xsc_vport_drop_stats {
|
|
u64 rx_dropped;
|
|
u64 tx_dropped;
|
|
};
|
|
|
|
int xsc_eswitch_init(struct xsc_core_device *dev);
|
|
void xsc_eswitch_cleanup(struct xsc_core_device *dev);
|
|
int xsc_eswitch_enable_locked(struct xsc_eswitch *esw, int mode, int num_vfs);
|
|
int xsc_eswitch_enable(struct xsc_eswitch *esw, int mode, int num_vfs);
|
|
void xsc_eswitch_disable_locked(struct xsc_eswitch *esw, bool clear_vf);
|
|
void xsc_eswitch_disable(struct xsc_eswitch *esw, bool clear_vf);
|
|
|
|
int xsc_devlink_eswitch_mode_set(struct devlink *devlink, u16 mod, struct netlink_ext_ack *extack);
|
|
int xsc_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode);
|
|
|
|
struct xsc_vport *__must_check
|
|
xsc_eswitch_get_vport(struct xsc_eswitch *esw, u16 vport_num);
|
|
int xsc_eswitch_get_vport_config(struct xsc_eswitch *esw,
|
|
u16 vport, struct ifla_vf_info *ivi);
|
|
int xsc_eswitch_set_vport_mac(struct xsc_eswitch *esw,
|
|
u16 vport, u8 mac[ETH_ALEN]);
|
|
int xsc_eswitch_get_vport_mac(struct xsc_eswitch *esw,
|
|
u16 vport, u8 *mac);
|
|
int xsc_eswitch_set_vport_vlan(struct xsc_eswitch *esw, int vport,
|
|
u16 vlan, u8 qos, __be16 vlan_proto);
|
|
int xsc_eswitch_set_vport_state(struct xsc_eswitch *esw,
|
|
u16 vport, int link_state);
|
|
int xsc_eswitch_set_vport_spoofchk(struct xsc_eswitch *esw,
|
|
u16 vport, u8 spoofchk);
|
|
int xsc_eswitch_set_vport_trust(struct xsc_eswitch *esw,
|
|
u16 vport_num, bool setting);
|
|
int xsc_eswitch_set_vport_rate(struct xsc_eswitch *esw, u16 vport,
|
|
u32 max_rate, u32 min_rate);
|
|
int xsc_eswitch_vport_update_group(struct xsc_eswitch *esw, int vport_num,
|
|
u32 group_id);
|
|
int xsc_eswitch_set_vgroup_rate(struct xsc_eswitch *esw, int group_id,
|
|
u32 max_rate);
|
|
int xsc_eswitch_set_vgroup_max_rate(struct xsc_eswitch *esw, int group_id,
|
|
u32 max_rate);
|
|
int xsc_eswitch_set_vgroup_min_rate(struct xsc_eswitch *esw, int group_id,
|
|
u32 min_rate);
|
|
int xsc_eswitch_add_vport_trunk_range(struct xsc_eswitch *esw,
|
|
int vport, u16 start_vlan, u16 end_vlan);
|
|
int xsc_eswitch_del_vport_trunk_range(struct xsc_eswitch *esw,
|
|
int vport, u16 start_vlan, u16 end_vlan);
|
|
int xsc_eswitch_modify_esw_vport_context(struct xsc_eswitch *esw, u16 vport,
|
|
bool other_vport,
|
|
void *in, int inlen);
|
|
int xsc_eswitch_query_esw_vport_context(struct xsc_eswitch *esw, u16 vport,
|
|
bool other_vport,
|
|
void *out, int outlen);
|
|
int xsc_eswitch_get_vport_stats(struct xsc_eswitch *esw,
|
|
u16 vport,
|
|
struct ifla_vf_stats *vf_stats);
|
|
int xsc_eswitch_query_vport_drop_stats(struct xsc_core_device *dev,
|
|
struct xsc_vport *vport,
|
|
struct xsc_vport_drop_stats *stats);
|
|
|
|
#define xsc_esw_for_all_vports(esw, i, vport) \
|
|
for ((i) = XSC_VPORT_PF; \
|
|
(vport) = &(esw)->vports[(i)], \
|
|
(i) < (esw)->total_vports; (i)++)
|
|
|
|
#define xsc_esw_for_each_vf_vport(esw, i, vport, nvfs) \
|
|
for ((i) = XSC_VPORT_FIRST_VF; \
|
|
(vport) = &(esw)->vports[(i)], \
|
|
(i) <= (nvfs); (i)++)
|
|
|
|
static inline int xsc_eswitch_uplink_idx(struct xsc_eswitch *esw)
|
|
{
|
|
/* Uplink always locate at the last element of the array.*/
|
|
return esw->total_vports - 1;
|
|
}
|
|
|
|
static inline int xsc_eswitch_ecpf_idx(struct xsc_eswitch *esw)
|
|
{
|
|
return esw->total_vports - 2;
|
|
}
|
|
|
|
static inline int xsc_eswitch_vport_num_to_index(struct xsc_eswitch *esw,
|
|
u16 vport_num)
|
|
{
|
|
if (vport_num == XSC_VPORT_ECPF) {
|
|
if (!xsc_ecpf_vport_exists(esw->dev) &&
|
|
!xsc_core_is_ecpf_esw_manager(esw->dev))
|
|
xsc_core_warn(esw->dev, "ECPF vport doesn't exist!\n");
|
|
return xsc_eswitch_ecpf_idx(esw);
|
|
}
|
|
|
|
if (vport_num == XSC_VPORT_UPLINK)
|
|
return xsc_eswitch_uplink_idx(esw);
|
|
|
|
/* PF and VF vports start from 0 to max_vfs */
|
|
return vport_num;
|
|
}
|
|
|
|
static inline u16 xsc_eswitch_index_to_vport_num(struct xsc_eswitch *esw,
|
|
int index)
|
|
{
|
|
if (index == xsc_eswitch_uplink_idx(esw))
|
|
return XSC_VPORT_UPLINK;
|
|
return index;
|
|
}
|
|
|
|
static inline u16 xsc_eswitch_manager_vport(struct xsc_core_device *dev)
|
|
{
|
|
return xsc_core_is_ecpf_esw_manager(dev) ?
|
|
XSC_VPORT_ECPF : XSC_VPORT_PF;
|
|
}
|
|
|
|
static inline u16 xsc_eswitch_first_host_vport_num(struct xsc_core_device *dev)
|
|
{
|
|
return xsc_core_is_ecpf_esw_manager(dev) ?
|
|
XSC_VPORT_PF : XSC_VPORT_FIRST_VF;
|
|
}
|
|
|
|
static inline u8 xsc_get_eswitch_mode(struct xsc_core_device *dev)
|
|
{
|
|
struct xsc_eswitch *esw = dev->priv.eswitch;
|
|
|
|
return ESW_ALLOWED(esw) ? esw->mode : XSC_ESWITCH_NONE;
|
|
}
|
|
|
|
static inline bool xsc_get_pp_bypass_res(struct xsc_core_device *dev)
|
|
{
|
|
return (xsc_get_eswitch_mode(dev) == XSC_ESWITCH_OFFLOADS) ||
|
|
(dev->device_id == XSC_MF_HOST_PF_DEV_ID);
|
|
}
|
|
|
|
#endif /* ESWITCH_H */
|
|
|