/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h> #include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h> #include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.h> #ifndef _RMNET_PERF_CORE_H_ #define _RMNET_PERF_CORE_H_ #define RMNET_PERF_NUM_64K_BUFFS 50 #define RMNET_PERF_CORE_RECYCLE_SKB_SIZE 65600//33000//32768//65600 struct rmnet_perf { struct rmnet_perf_opt_meta *opt_meta; struct rmnet_perf_core_meta *core_meta; struct rmnet_port *rmnet_port; }; /* Identifying info for the current packet being deaggregated * this is so we don't have to redundantly check things in the * header of the packet. Also prevents excessive parameters */ struct rmnet_perf_pkt_info { /* True if this is the first packet being put into a flow node. */ bool first_packet; bool csum_valid; /* Header protocols */ u8 ip_proto; u8 trans_proto; /* Header lengths */ u16 ip_len; u16 trans_len; /* Data length */ u16 payload_len; /* Hash over standard 5 tuple */ u32 hash_key; /* TCP timestamp */ u32 curr_timestamp; /* Headers */ union { struct iphdr *v4hdr; struct ipv6hdr *v6hdr; } ip_hdr; union { struct tcphdr *tp; struct udphdr *up; } trans_hdr; struct rmnet_endpoint *ep; /* The base packet itself */ union { struct sk_buff *skb; struct rmnet_frag_descriptor *frag_desc; }; }; struct rmnet_perf_core_64k_buff_pool { u8 index; struct sk_buff *available[RMNET_PERF_NUM_64K_BUFFS]; }; struct rmnet_perf_core_burst_marker_state { bool wait_for_start; /* If the callbacks fail to register, then we want to flush at the * end of every chain */ bool callbacks_valid; u32 curr_seq; u32 expect_packets; }; //list of SKB's which we will free after some set amount of data. //currently sized for 400k of data (266 1500 byte packets rounded to 350 //for safety) struct rmnet_perf_core_skb_list { u16 num_skbs_held; struct sk_buff *head; struct sk_buff *tail; }; struct rmnet_perf_core_meta { /* skbs from physical device */ struct rmnet_perf_core_skb_list *skb_needs_free_list; /* recycled buffer pool */ struct rmnet_perf_core_64k_buff_pool *buff_pool; struct net_device *dev; struct rmnet_perf_core_burst_marker_state *bm_state; struct rmnet_map_dl_ind *dl_ind; struct qmi_rmnet_ps_ind *ps_ind; }; enum rmnet_perf_core_flush_reasons { RMNET_PERF_CORE_IPA_ZERO_FLUSH, RMNET_PERF_CORE_SK_BUFF_HELD_LIMIT, RMNET_PERF_CORE_DL_MARKER_FLUSHES, RMNET_PERF_CORE_PS_MODE_ON, RMNET_PERF_CORE_NUM_CONDITIONS }; enum rmnet_perf_core_pkt_size_e { RMNET_PERF_CORE_50000_PLUS, RMNET_PERF_CORE_30000_PLUS, //32k full bucket RMNET_PERF_CORE_23000_PLUS, //24k full bucket RMNET_PERF_CORE_14500_PLUS, //16k full bucket RMNET_PERF_CORE_7000_PLUS, //8k full bucket RMNET_PERF_CORE_1400_PLUS, RMNET_PERF_CORE_0_PLUS, RMNET_PERF_CORE_DEBUG_BUCKETS_MAX }; enum rmnet_perf_trace_func { RMNET_PERF_MODULE, }; enum rmnet_perf_trace_evt { RMNET_PERF_START_DL_MRK, RMNET_PERF_END_DL_MRK, RMNET_PERF_DEAG_PKT, }; void rmnet_perf_core_grab_lock(void); void rmnet_perf_core_release_lock(void); void rmnet_perf_core_ps_on(void *port); void rmnet_perf_core_ps_off(void *port); bool rmnet_perf_core_is_deag_mode(void); void rmnet_perf_core_set_ingress_hook(void); void rmnet_perf_core_reset_recycled_skb(struct sk_buff *skb); struct sk_buff *rmnet_perf_core_elligible_for_cache_skb(u32 len); void rmnet_perf_core_free_held_skbs(void); void rmnet_perf_core_send_skb(struct sk_buff *skb, struct rmnet_endpoint *ep); void rmnet_perf_core_send_desc(struct rmnet_frag_descriptor *frag_desc); void rmnet_perf_core_flush_curr_pkt(struct rmnet_perf_pkt_info *pkt_info, u16 packet_len, bool flush_shs, bool skip_hash); void rmnet_perf_core_deaggregate(struct sk_buff *skb, struct rmnet_port *port); void rmnet_perf_core_desc_entry(struct rmnet_frag_descriptor *frag_desc, struct rmnet_port *port); u32 rmnet_perf_core_compute_flow_hash(struct rmnet_perf_pkt_info *pkt_info); void rmnet_perf_core_flush_single_gro_flow(u32 hash_key); void rmnet_perf_core_handle_map_control_end_v2(struct rmnet_map_dl_ind_trl *dltrl, struct rmnet_map_control_command_header *qcmd); void rmnet_perf_core_handle_map_control_start_v2(struct rmnet_map_dl_ind_hdr *dlhdr, struct rmnet_map_control_command_header *qcmd); void rmnet_perf_core_handle_map_control_end(struct rmnet_map_dl_ind_trl *dltrl); void rmnet_perf_core_handle_map_control_start(struct rmnet_map_dl_ind_hdr *dlhdr); #endif /* _RMNET_PERF_CORE_H_ */