// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) Intel Corporation * Author: Shao Guohua */ #ifndef DATAPATH_MISC31_H #define DATAPATH_MISC31_H #include #include #include "datapath_ppv4.h" #include #include #define PMAC_MAX_NUM 16 #define PAMC_LAN_MAX_NUM 7 #define VAP_DSL_OFFSET 3 #define NEW_CBM_API 1 #define PMAPPER_DISC_CTP 255 #define MAX_PPV4_PORTS 38 #define PPV4_PORT_BASE 90 /* For WLAN 8 bit Mode VAP=11:8 * For WLAN 9 bit Mode VAP=11:9 * For Non-WLAN Mode VAP=7:0 */ #define VAP_8BIT_OFFSET 8 #define VAP_8BIT_MASK 0xF #define VAP_9BIT_OFFSET 9 #define VAP_9BIT_MASK 0x7 #define VAP_NONWLAN_OFFSET 0 #define VAP_NONWLAN_MASK 0xFF #define GSWIP_O_DEV_NAME 1 #define GSWIP_L GSWIP_O_DEV_NAME #define GSWIP_R GSWIP_O_DEV_NAME #define MAX_SUBIF_PER_PORT 256 #define MAX_CTP 288 #define MAX_BP_NUM 128 #define CPU_PORT 0 #define CPU_SUBIF 0 /*cpu default subif ID*/ #define CPU_BP 0 /*cpu default bridge port ID */ #define CPU_FID 0 /*cpu default bridge ID */ #define SET_BP_MAP(x, ix) (x[(ix) / 16] |= 1 << ((ix) % 16)) #define GET_BP_MAP(x, ix) ((x[(ix) / 16] >> ((ix) % 16)) & 1) #define UNSET_BP_MAP(x, ix) (x[(ix) / 16] &= ~(1 << ((ix) % 16))) /* Max value for the limit of MAC addresses per bridge port. */ #define GSWIP_LEARN_LIMIT_PORT_MAX 254 enum CQE_LOOKUP_MODE { CQE_LU_MODE0 = 0, CQE_LU_MODE1, CQE_LU_MODE2, CQE_LU_MODE3, CQE_LU_MODE_NOT_VALID, }; #define PMAC_SIZE 8 struct gsw_itf { u8 ep; /*-1 means no assigned yet for dynamic case */ u8 fixed; /*fixed (1) or dynamically allocate (0)*/ u16 start; u16 end; u16 n; u8 mode; u8 cqe_mode; /*CQE look up mode */ }; struct cqm_deq_stat; struct pp_queue_stat; struct resv_q { int flag; int id; int physical_id; }; struct resv_sch { int flag; int id; }; struct resv_info { int num_resv_q; /*!< input:reserve the required number of queues*/ int num_resv_sched; /*!< input:reserve required number of schedulers*/ int flag_ops; /*!< saved op flags of enum DP_DEV_DATA_FLAG */ struct resv_q *resv_q; /*!< reserved queues info*/ struct resv_sch *resv_sched; /*!< reserved schedulers info */ }; struct ppv4_port_map_table { int flags[MAX_PPV4_PORTS]; }; struct pp_qos_dev; #define DP_TX_CB_LOCK_T spinlock_t #define DP_TX_CB_LOCK spin_lock_bh #define DP_TX_CB_UNLOCK spin_unlock_bh #define DP_TX_CB_LOCK_INIT spin_lock_init struct hal_priv { struct cqm_deq_stat deq_port_stat[MAX_CQM_DEQ]; struct pp_queue_stat qos_queue_stat[MAX_QUEUE]; struct pp_sch_stat qos_sch_stat[QOS_MAX_NODES]; struct resv_info resv[MAX_DP_PORTS]; int bp_def; struct pp_qos_dev *qdev; /* ppv4 qos dev */ s32 ppv4_drop_q; /* drop queue: physical id */ int cqm_drop_p; /* cqm drop/flush port id*/ u32 ppv4_drop_p; /* drop qos port(logical node_id):workaround for * PPV4 API issue to get physical queue id * before pp_qos_queue_set */ u32 ppv4_tmp_p; /* workaround for ppv4 queue allocate to * to get physical queue id */ struct ppv4_port_map_table ppv4_port_map; /* PPV4 Ports table map */ DP_TX_CB_LOCK_T cb_lock; DP_LOCK_T qos_lock; }; static inline bool is_xpon(int flags) { if (flags & (DP_F_GPON | DP_F_EPON)) return true; return false; } static inline bool is_qid_valid(int q_id) { if (q_id < 0 || q_id >= MAX_QUEUE) { pr_err("Wrong Parameter: QID[%d]Out Of Range\n", q_id); return false; } return true; } static inline bool is_sch_valid(int sch_id) { if (sch_id < 0 || sch_id >= QOS_MAX_NODES) { pr_err("Wrong Parameter: Sched[%d]Out Of Range\n", sch_id); return false; } return true; } static inline bool is_deqport_valid(int deq_port) { if (deq_port < 0 || deq_port >= MAX_CQM_DEQ) { pr_err("Wrong Parameter: Port[%d]Out Of Range\n", deq_port); return false; } return true; } static inline bool is_sch_child_free(struct hal_priv *priv, int sch_id) { if (priv->qos_sch_stat[sch_id].c_flag == PP_NODE_FREE) { pr_err("Sch child node is Free Sch ID %d flag:0x%x\n", sch_id, priv->qos_sch_stat[sch_id].c_flag); return true; } return false; } static inline bool is_sch_parent_free(struct hal_priv *priv, int sch_id) { if (priv->qos_sch_stat[sch_id].p_flag == PP_NODE_FREE) { pr_err("Sch Parent node is Free Sch ID %d Flag :0x%x\n", sch_id, priv->qos_sch_stat[sch_id].p_flag); return true; } return false; } static inline bool is_q_node_free(struct hal_priv *priv, int q_id) { if (priv->qos_queue_stat[q_id].flag == PP_NODE_FREE) { pr_err("Q Node is Free Qid %d flag:0x%x\n", q_id, priv->qos_queue_stat[q_id].flag); return true; } return false; } static inline bool is_port_node_free(struct hal_priv *priv, int port) { if (priv->deq_port_stat[port].flag == PP_NODE_FREE) { pr_err("Deq Port Node is Free Deq port %d flag:0x%x\n", port, priv->deq_port_stat[port].flag); return true; } return false; } struct datapath_ctrl { struct dentry *debugfs; const char *name; }; struct ctp_assign { u32 flag; /*Datapath Device Flag */ GSW_LogicalPortMode_t emode; /*mapped GSWIP CTP flag */ u16 num; /*Max CTP allowed for that GSWIP logical port*/ u16 num_subif; /*Max allowed number of subif for that logical port*/ u32 lookup_mode; /*CQE lookup mode */ u16 swdev_enable; /* To enable or disable switchdev feature */ }; /* brief structure to set special config for PON port registration */ struct pon_spl_cfg { int flag; u8 ingress; /* ingress special tag */ u8 egress; /* egress special tag */ u8 crc_check; /* Rx CRC check */ u32 fcs_gen; /* Tx FCS */ u32 flow_ctrl; /* Rx/Tx flow control */ /* special Mac operations */ MAC_OPER_CFG tx_spl_tag; MAC_OPER_CFG rx_time_stamp; MAC_OPER_CFG rx_spl_tag; MAC_OPER_CFG rx_fcs; }; #define SET_PMAC_IGP_EGP(pmac, port_id) ((pmac)->igp_egp = (port_id)&0xF) #define SET_PMAC_SUBIF(pmac, subif) \ do { \ (pmac)->src_dst_subif_id_lsb = (subif)&0xff; \ (pmac)->src_dst_subif_id_msb = ((subif) >> 8) & 0x1f; \ } while (0) int alloc_bridge_port(int inst, int portid, int subif, int fid, int bp_member, int flags); int free_bridge_port(int inst, int bp); struct gsw_itf *ctp_port_assign(int inst, u8 ep, int bp_default, u32 flags, struct dp_dev_data *data); void dp_sys_mib_reset_31(u32 flag); int dp_pmac_set_31(int inst, u32 port, dp_pmac_cfg_t *pmac_cfg); int dp_set_gsw_parser_31(u8 flag, u8 cpu, u8 mpe1, u8 mpe2, u8 mpe3); int dp_get_gsw_parser_31(u8 *cpu, u8 *mpe1, u8 *mpe2, u8 *mpe3); int gsw_mib_reset_31(int dev, u32 flag); #if IS_ENABLED(CONFIG_INTEL_DATAPATH_SWITCHDEV) int dp_gswip_mac_entry_add(int bport, int fid, int inst, u8 *addr); int dp_gswip_mac_entry_del(int bport, int fid, int inst, u8 *addr); int set_gswip_ext_vlan(struct core_ops *ops, struct ext_vlan_info *vlan, int flag); #endif int qos_platform_set(int cmd_id, void *node, int flag); int dp_node_alloc_31(struct dp_node_alloc *node, int flag); int dp_node_free_31(struct dp_node_alloc *node, int flag); int dp_deq_port_res_get_31(struct dp_dequeue_res *res, int flag); int dp_node_link_en_get_31(struct dp_node_link_enable *en, int flag); int dp_node_link_en_set_31(struct dp_node_link_enable *en, int flag); int dp_qos_link_prio_set_31(struct dp_node_prio *info, int flag); int dp_qos_link_prio_get_31(struct dp_node_prio *info, int flag); int dp_node_link_add_31(struct dp_node_link *info, int flag); int dp_link_add_31(struct dp_qos_link *cfg, int flag); int dp_link_get_31(struct dp_qos_link *cfg, int flag); int dp_node_unlink_31(struct dp_node_link *info, int flag); int dp_node_link_get_31(struct dp_node_link *info, int flag); int dp_queue_conf_set_31(struct dp_queue_conf *cfg, int flag); int dp_queue_conf_get_31(struct dp_queue_conf *cfg, int flag); int dp_shaper_conf_set_31(struct dp_shaper_conf *cfg, int flag); int dp_shaper_conf_get_31(struct dp_shaper_conf *cfg, int flag); int dp_queue_map_get_31(struct dp_queue_map_get *cfg, int flag); int dp_queue_map_set_31(struct dp_queue_map_set *cfg, int flag); int dp_counter_mode_set_31(struct dp_counter_conf *cfg, int flag); int dp_counter_mode_get_31(struct dp_counter_conf *cfg, int flag); int dp_set_gsw_pmapper_31(int inst, int bport, int lport, struct dp_pmapper *mapper, u32 flag); int dp_get_gsw_pmapper_31(int inst, int bport, int lport, struct dp_pmapper *mapper, u32 flag); int dp_children_get_31(struct dp_node_child *cfg, int flag); int dp_free_children_via_parent_31(struct dp_node_alloc *node, int flag); int dp_node_reserve(int inst, int ep, struct dp_dev_data *data, int flags); int dp_qos_level_get_31(struct dp_qos_level *dp, int flag); int dp_meter_alloc_31(int inst, int *meterid, int flag); int dp_meter_add_31(struct net_device *dev, struct dp_meter_cfg *meter, int flag, struct dp_meter_subif *mtr_subif); int dp_meter_del_31(struct net_device *dev, struct dp_meter_cfg *meter, int flag, struct dp_meter_subif *mtr_subif); int dp_qos_global_info_get_31(struct dp_qos_cfg_info *info, int flag); int dp_qos_port_conf_set_31(struct dp_port_cfg_info *info, int flag); int32_t dp_rx_31(struct sk_buff *skb, u32 flags); int32_t dp_xmit_31(struct net_device *rx_if, dp_subif_t *rx_subif, struct sk_buff *skb, int32_t len, uint32_t flags); void set_chksum(struct pmac_tx_hdr *pmac, u32 tcp_type, u32 ip_offset, int ip_off_hw_adjust, u32 tcp_h_offset); int dp_set_bp_attr_31(struct dp_bp_attr *conf, int bport, uint32_t flag); static inline char *parser_flag_str(u8 f) { if (f == DP_PARSER_F_DISABLE) return "No Parser"; else if (f == DP_PARSER_F_HDR_ENABLE) return "Parser Flag only"; else if (f == DP_PARSER_F_HDR_OFFSETS_ENABLE) return "Parser Full"; else return "Reserved"; } #ifdef CONFIG_DEBUG_FS int dp_sub_proc_install_31(void); int proc_print_ctp_bp_info(struct seq_file *s, int inst, struct pmac_port_info *port, int subif_index, u32 flag); #else static inline int dp_sub_proc_install_31(void) { return 0; } static inline int proc_print_ctp_bp_info(struct seq_file *s, int inst, struct pmac_port_info *port, int subif_index, u32 flag) { return 0; } #endif char *get_dma_flags_str31(u32 epn, char *buf, int buf_len); int lookup_dump31(struct seq_file *s, int pos); int lookup_start31(void); ssize_t proc_get_qid_via_index31(struct file *file, const char *buf, size_t count, loff_t *ppos); ssize_t proc_get_qid_via_index(struct file *file, const char *buf, size_t count, loff_t *ppos); int datapath_debugfs_init(struct datapath_ctrl *pctrl); int get_q_qocc(int inst, int qid, u32 *c); int get_q_mib(int inst, int qid, u32 *total_accept, u32 *total_drop, u32 *red_drop); int get_p_mib(int inst, int pid, u32 *green /* bytes*/, u32 *yellow /*bytes*/); int cpu_vlan_mod_dis(int inst); int set_port_lookup_mode_31(int inst, u8 ep, u32 flags); int tc_vlan_set_31(struct core_ops *ops, struct dp_tc_vlan *vlan, struct dp_tc_vlan_info *info, int flag); int dp_get_reinsert_cnt_31(int inst, int dp_port, int vap, int flag, struct dp_reinsert_count *dp_reins_count); int dp_queue_block_flush_31(struct dp_qos_blk_flush_queue *cfg, int flag); int dp_port_block_flush_31(struct dp_qos_blk_flush_port *cfg, int flag); int dp_register_br_vlan(struct br_info *br_info, int flags); int dp_register_bport_vlan(struct br_info *br_info, struct net_device *dev, int bport, int flags); int dp_ndo_br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags); int dp_ndo_br_dellink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags); #endif /* DATAPATH_MISC31_H */