/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* Copyright 2017-2019 NXP */ #ifndef __TSN_H__ #define __TSN_H__ #include #include enum tsn_notifier_type { TSN_QBV_CONFIGCHANGETIME_ARRIVE = 1, }; struct tsn_notifier_info { struct net_device *dev; union { struct tsn_qbv_conf qbv_notify; struct tsn_qci_psfp_sgi_conf qci_notify; } ntdata; }; static inline struct net_device * tsn_notifier_info_to_dev(const struct tsn_notifier_info *info) { return info->dev; } struct tsn_ops { void (*device_init)(struct net_device *ndev); void (*device_deinit)(struct net_device *ndev); u32 (*get_capability)(struct net_device *ndev); /* Qbv standard */ int (*qbv_set)(struct net_device *ndev, struct tsn_qbv_conf *qbvconf); int (*qbv_get)(struct net_device *ndev, struct tsn_qbv_conf *qbvconf); int (*qbv_get_status)(struct net_device *ndev, struct tsn_qbv_status *qbvstat); int (*cb_streamid_set)(struct net_device *ndev, u32 index, bool enable, struct tsn_cb_streamid *sid); int (*cb_streamid_get)(struct net_device *ndev, u32 index, struct tsn_cb_streamid *sid); int (*cb_streamid_counters_get)(struct net_device *ndev, u32 index, struct tsn_cb_streamid_counters *sidcounter); int (*qci_get_maxcap)(struct net_device *ndev, struct tsn_qci_psfp_stream_param *qcicapa); int (*qci_sfi_set)(struct net_device *ndev, u32 index, bool enable, struct tsn_qci_psfp_sfi_conf *sficonf); /* return: 0 stream filter instance not valid * 1 stream filter instance valid * -1 error happened */ int (*qci_sfi_get)(struct net_device *ndev, u32 index, struct tsn_qci_psfp_sfi_conf *sficonf); int (*qci_sfi_counters_get)(struct net_device *ndev, u32 index, struct tsn_qci_psfp_sfi_counters *sficounter); int (*qci_sgi_set)(struct net_device *ndev, u32 index, struct tsn_qci_psfp_sgi_conf *sgiconf); int (*qci_sgi_get)(struct net_device *ndev, u32 index, struct tsn_qci_psfp_sgi_conf *sgiconf); int (*qci_sgi_status_get)(struct net_device *ndev, u16 index, struct tsn_psfp_sgi_status *sgistat); int (*qci_fmi_set)(struct net_device *ndev, u32 index, bool enable, struct tsn_qci_psfp_fmi *fmi); int (*qci_fmi_get)(struct net_device *ndev, u32 index, struct tsn_qci_psfp_fmi *fmi, struct tsn_qci_psfp_fmi_counters *counters); int (*cbs_set)(struct net_device *ndev, u8 tc, u8 bw); int (*cbs_get)(struct net_device *ndev, u8 tc); /* To set a 8 bits vector shows 8 traffic classes * preemtable(1) or express(0) */ int (*qbu_set)(struct net_device *ndev, u8 ptvector); /* To get port preemtion status */ int (*qbu_get)(struct net_device *ndev, struct tsn_preempt_status *preemptstat); int (*tsd_set)(struct net_device *ndev, struct tsn_tsd *tsd); int (*tsd_get)(struct net_device *ndev, struct tsn_tsd_status *stats); int (*ct_set)(struct net_device *ndev, u8 cut_thru); int (*cbgen_set)(struct net_device *ndev, u32 index, struct tsn_seq_gen_conf *seqgen); int (*cbrec_set)(struct net_device *ndev, u32 index, struct tsn_seq_rec_conf *seqrec); int (*cb_get)(struct net_device *ndev, u32 index, struct tsn_cb_status *c); int (*dscp_set)(struct net_device *ndev, bool enable, const u8 dscp_ix, struct tsn_qos_switch_dscp_conf *c); }; enum ethdev_type { TSN_SWITCH, TSN_ENDPOINT, }; #define GROUP_OFFSET_SWITCH 256 struct tsn_port { u16 groupid; struct tsn_ops *tsnops; struct net_device *netdev; struct list_head list; enum ethdev_type type; u8 tc_nums; struct tsn_notifier_info nd; }; struct tsn_port *tsn_get_port(struct net_device *ndev); int register_tsn_notifier(struct notifier_block *nb); int unregister_tsn_notifier(struct notifier_block *nb); int call_tsn_notifiers(unsigned long val, struct net_device *dev, struct tsn_notifier_info *info); int tsn_port_register(struct net_device *netdev, struct tsn_ops *tsnops, u16 groupid); void tsn_port_unregister(struct net_device *netdev); #endif