summaryrefslogtreecommitdiff
path: root/drivers/rmnet/perf/rmnet_perf_core.h
blob: 735cb3b85b2333ff7ce48759cc4065da4618da99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/* 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 <linux/skbuff.h>
#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_ */