blob: d74777150c0a84d6c6a1235d6536d5c4083a76e2 [file] [log] [blame]
Skylar Changf3a7dac2017-01-25 09:16:55 -08001/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
Amir Levy9659e592016-10-27 18:08:27 +03002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13/*
14 * WWAN Transport Network Driver.
15 */
16
17#include <linux/completion.h>
18#include <linux/errno.h>
19#include <linux/if_arp.h>
20#include <linux/interrupt.h>
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/netdevice.h>
25#include <linux/of_device.h>
26#include <linux/string.h>
27#include <linux/skbuff.h>
28#include <linux/version.h>
29#include <linux/workqueue.h>
30#include <net/pkt_sched.h>
31#include <soc/qcom/subsystem_restart.h>
32#include <soc/qcom/subsystem_notif.h>
33#include "ipa_qmi_service.h"
34#include <linux/rmnet_ipa_fd_ioctl.h>
35#include <linux/ipa.h>
36#include <uapi/linux/net_map.h>
Gidon Studinski3021a6f2016-11-10 12:48:48 +020037#include <uapi/linux/msm_rmnet.h>
38#include <net/rmnet_config.h>
Amir Levy9659e592016-10-27 18:08:27 +030039
40#include "ipa_trace.h"
41
42#define WWAN_METADATA_SHFT 24
43#define WWAN_METADATA_MASK 0xFF000000
44#define WWAN_DATA_LEN 2000
45#define IPA_RM_INACTIVITY_TIMER 100 /* IPA_RM */
46#define HEADROOM_FOR_QMAP 8 /* for mux header */
47#define TAILROOM 0 /* for padding by mux layer */
48#define MAX_NUM_OF_MUX_CHANNEL 10 /* max mux channels */
49#define UL_FILTER_RULE_HANDLE_START 69
Ghanim Fodic6b67492017-03-15 14:19:56 +020050#define DEFAULT_OUTSTANDING_HIGH 128
51#define DEFAULT_OUTSTANDING_HIGH_CTL (DEFAULT_OUTSTANDING_HIGH+32)
52#define DEFAULT_OUTSTANDING_LOW 64
Amir Levy9659e592016-10-27 18:08:27 +030053
54#define IPA_WWAN_DEV_NAME "rmnet_ipa%d"
55
56#define IPA_WWAN_RX_SOFTIRQ_THRESH 16
57
58#define INVALID_MUX_ID 0xFF
59#define IPA_QUOTA_REACH_ALERT_MAX_SIZE 64
60#define IPA_QUOTA_REACH_IF_NAME_MAX_SIZE 64
61#define IPA_UEVENT_NUM_EVNP 4 /* number of event pointers */
62#define NAPI_WEIGHT 60
63
64#define IPA_NETDEV() \
65 ((rmnet_ipa3_ctx && rmnet_ipa3_ctx->wwan_priv) ? \
66 rmnet_ipa3_ctx->wwan_priv->net : NULL)
67
68
69static int ipa3_wwan_add_ul_flt_rule_to_ipa(void);
70static int ipa3_wwan_del_ul_flt_rule_to_ipa(void);
71static void ipa3_wwan_msg_free_cb(void*, u32, u32);
72static void ipa3_rmnet_rx_cb(void *priv);
73static int ipa3_rmnet_poll(struct napi_struct *napi, int budget);
74
75static void ipa3_wake_tx_queue(struct work_struct *work);
76static DECLARE_WORK(ipa3_tx_wakequeue_work, ipa3_wake_tx_queue);
77
78static void tethering_stats_poll_queue(struct work_struct *work);
79static DECLARE_DELAYED_WORK(ipa_tether_stats_poll_wakequeue_work,
80 tethering_stats_poll_queue);
81
82enum ipa3_wwan_device_status {
83 WWAN_DEVICE_INACTIVE = 0,
84 WWAN_DEVICE_ACTIVE = 1
85};
86
87struct ipa3_rmnet_plat_drv_res {
88 bool ipa_rmnet_ssr;
89 bool ipa_loaduC;
90 bool ipa_advertise_sg_support;
91 bool ipa_napi_enable;
92};
93
94/**
95 * struct ipa3_wwan_private - WWAN private data
96 * @net: network interface struct implemented by this driver
97 * @stats: iface statistics
98 * @outstanding_pkts: number of packets sent to IPA without TX complete ACKed
99 * @outstanding_high: number of outstanding packets allowed
100 * @outstanding_low: number of outstanding packets which shall cause
101 * @ch_id: channel id
102 * @lock: spinlock for mutual exclusion
103 * @device_status: holds device status
104 *
105 * WWAN private - holds all relevant info about WWAN driver
106 */
107struct ipa3_wwan_private {
108 struct net_device *net;
109 struct net_device_stats stats;
110 atomic_t outstanding_pkts;
111 int outstanding_high_ctl;
112 int outstanding_high;
113 int outstanding_low;
114 uint32_t ch_id;
115 spinlock_t lock;
116 struct completion resource_granted_completion;
117 enum ipa3_wwan_device_status device_status;
118 struct napi_struct napi;
119};
120
121struct rmnet_ipa3_context {
122 struct ipa3_wwan_private *wwan_priv;
123 struct ipa_sys_connect_params apps_to_ipa_ep_cfg;
124 struct ipa_sys_connect_params ipa_to_apps_ep_cfg;
125 u32 qmap_hdr_hdl;
126 u32 dflt_v4_wan_rt_hdl;
127 u32 dflt_v6_wan_rt_hdl;
128 struct ipa3_rmnet_mux_val mux_channel[MAX_NUM_OF_MUX_CHANNEL];
129 int num_q6_rules;
130 int old_num_q6_rules;
131 int rmnet_index;
132 bool egress_set;
133 bool a7_ul_flt_set;
134 struct workqueue_struct *rm_q6_wq;
135 atomic_t is_initialized;
136 atomic_t is_ssr;
137 void *subsys_notify_handle;
138 u32 apps_to_ipa3_hdl;
139 u32 ipa3_to_apps_hdl;
Ghanim Fodic6b67492017-03-15 14:19:56 +0200140 struct mutex pipe_handle_guard;
Amir Levy9659e592016-10-27 18:08:27 +0300141};
142
143static struct rmnet_ipa3_context *rmnet_ipa3_ctx;
144static struct ipa3_rmnet_plat_drv_res ipa3_rmnet_res;
145
146/**
147* ipa3_setup_a7_qmap_hdr() - Setup default a7 qmap hdr
148*
149* Return codes:
150* 0: success
151* -ENOMEM: failed to allocate memory
152* -EPERM: failed to add the tables
153*/
154static int ipa3_setup_a7_qmap_hdr(void)
155{
156 struct ipa_ioc_add_hdr *hdr;
157 struct ipa_hdr_add *hdr_entry;
158 u32 pyld_sz;
159 int ret;
160
161 /* install the basic exception header */
162 pyld_sz = sizeof(struct ipa_ioc_add_hdr) + 1 *
163 sizeof(struct ipa_hdr_add);
164 hdr = kzalloc(pyld_sz, GFP_KERNEL);
165 if (!hdr) {
166 IPAWANERR("fail to alloc exception hdr\n");
167 return -ENOMEM;
168 }
169 hdr->num_hdrs = 1;
170 hdr->commit = 1;
171 hdr_entry = &hdr->hdr[0];
172
173 strlcpy(hdr_entry->name, IPA_A7_QMAP_HDR_NAME,
174 IPA_RESOURCE_NAME_MAX);
175 hdr_entry->hdr_len = IPA_QMAP_HEADER_LENGTH; /* 4 bytes */
176
177 if (ipa3_add_hdr(hdr)) {
178 IPAWANERR("fail to add IPA_A7_QMAP hdr\n");
179 ret = -EPERM;
180 goto bail;
181 }
182
183 if (hdr_entry->status) {
184 IPAWANERR("fail to add IPA_A7_QMAP hdr\n");
185 ret = -EPERM;
186 goto bail;
187 }
188 rmnet_ipa3_ctx->qmap_hdr_hdl = hdr_entry->hdr_hdl;
189
190 ret = 0;
191bail:
192 kfree(hdr);
193 return ret;
194}
195
196static void ipa3_del_a7_qmap_hdr(void)
197{
198 struct ipa_ioc_del_hdr *del_hdr;
199 struct ipa_hdr_del *hdl_entry;
200 u32 pyld_sz;
201 int ret;
202
203 pyld_sz = sizeof(struct ipa_ioc_del_hdr) + 1 *
204 sizeof(struct ipa_hdr_del);
205 del_hdr = kzalloc(pyld_sz, GFP_KERNEL);
206 if (!del_hdr) {
207 IPAWANERR("fail to alloc exception hdr_del\n");
208 return;
209 }
210
211 del_hdr->commit = 1;
212 del_hdr->num_hdls = 1;
213 hdl_entry = &del_hdr->hdl[0];
214 hdl_entry->hdl = rmnet_ipa3_ctx->qmap_hdr_hdl;
215
216 ret = ipa3_del_hdr(del_hdr);
217 if (ret || hdl_entry->status)
218 IPAWANERR("ipa3_del_hdr failed\n");
219 else
220 IPAWANDBG("hdrs deletion done\n");
221
222 rmnet_ipa3_ctx->qmap_hdr_hdl = 0;
223 kfree(del_hdr);
224}
225
226static void ipa3_del_qmap_hdr(uint32_t hdr_hdl)
227{
228 struct ipa_ioc_del_hdr *del_hdr;
229 struct ipa_hdr_del *hdl_entry;
230 u32 pyld_sz;
231 int ret;
232
233 if (hdr_hdl == 0) {
234 IPAWANERR("Invalid hdr_hdl provided\n");
235 return;
236 }
237
238 pyld_sz = sizeof(struct ipa_ioc_del_hdr) + 1 *
239 sizeof(struct ipa_hdr_del);
240 del_hdr = kzalloc(pyld_sz, GFP_KERNEL);
241 if (!del_hdr) {
242 IPAWANERR("fail to alloc exception hdr_del\n");
243 return;
244 }
245
246 del_hdr->commit = 1;
247 del_hdr->num_hdls = 1;
248 hdl_entry = &del_hdr->hdl[0];
249 hdl_entry->hdl = hdr_hdl;
250
251 ret = ipa3_del_hdr(del_hdr);
252 if (ret || hdl_entry->status)
253 IPAWANERR("ipa3_del_hdr failed\n");
254 else
255 IPAWANDBG("header deletion done\n");
256
257 rmnet_ipa3_ctx->qmap_hdr_hdl = 0;
258 kfree(del_hdr);
259}
260
261static void ipa3_del_mux_qmap_hdrs(void)
262{
263 int index;
264
265 for (index = 0; index < rmnet_ipa3_ctx->rmnet_index; index++) {
266 ipa3_del_qmap_hdr(rmnet_ipa3_ctx->mux_channel[index].hdr_hdl);
267 rmnet_ipa3_ctx->mux_channel[index].hdr_hdl = 0;
268 }
269}
270
271static int ipa3_add_qmap_hdr(uint32_t mux_id, uint32_t *hdr_hdl)
272{
273 struct ipa_ioc_add_hdr *hdr;
274 struct ipa_hdr_add *hdr_entry;
275 char hdr_name[IPA_RESOURCE_NAME_MAX];
276 u32 pyld_sz;
277 int ret;
278
279 pyld_sz = sizeof(struct ipa_ioc_add_hdr) + 1 *
280 sizeof(struct ipa_hdr_add);
281 hdr = kzalloc(pyld_sz, GFP_KERNEL);
282 if (!hdr) {
283 IPAWANERR("fail to alloc exception hdr\n");
284 return -ENOMEM;
285 }
286 hdr->num_hdrs = 1;
287 hdr->commit = 1;
288 hdr_entry = &hdr->hdr[0];
289
290 snprintf(hdr_name, IPA_RESOURCE_NAME_MAX, "%s%d",
291 A2_MUX_HDR_NAME_V4_PREF,
292 mux_id);
293 strlcpy(hdr_entry->name, hdr_name,
294 IPA_RESOURCE_NAME_MAX);
295
296 hdr_entry->hdr_len = IPA_QMAP_HEADER_LENGTH; /* 4 bytes */
297 hdr_entry->hdr[1] = (uint8_t) mux_id;
298 IPAWANDBG("header (%s) with mux-id: (%d)\n",
299 hdr_name,
300 hdr_entry->hdr[1]);
301 if (ipa3_add_hdr(hdr)) {
302 IPAWANERR("fail to add IPA_QMAP hdr\n");
303 ret = -EPERM;
304 goto bail;
305 }
306
307 if (hdr_entry->status) {
308 IPAWANERR("fail to add IPA_QMAP hdr\n");
309 ret = -EPERM;
310 goto bail;
311 }
312
313 ret = 0;
314 *hdr_hdl = hdr_entry->hdr_hdl;
315bail:
316 kfree(hdr);
317 return ret;
318}
319
320/**
321* ipa3_setup_dflt_wan_rt_tables() - Setup default wan routing tables
322*
323* Return codes:
324* 0: success
325* -ENOMEM: failed to allocate memory
326* -EPERM: failed to add the tables
327*/
328static int ipa3_setup_dflt_wan_rt_tables(void)
329{
330 struct ipa_ioc_add_rt_rule *rt_rule;
331 struct ipa_rt_rule_add *rt_rule_entry;
332
333 rt_rule =
334 kzalloc(sizeof(struct ipa_ioc_add_rt_rule) + 1 *
335 sizeof(struct ipa_rt_rule_add), GFP_KERNEL);
336 if (!rt_rule) {
337 IPAWANERR("fail to alloc mem\n");
338 return -ENOMEM;
339 }
340 /* setup a default v4 route to point to Apps */
341 rt_rule->num_rules = 1;
342 rt_rule->commit = 1;
343 rt_rule->ip = IPA_IP_v4;
344 strlcpy(rt_rule->rt_tbl_name, IPA_DFLT_WAN_RT_TBL_NAME,
345 IPA_RESOURCE_NAME_MAX);
346
347 rt_rule_entry = &rt_rule->rules[0];
348 rt_rule_entry->at_rear = 1;
349 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
350 rt_rule_entry->rule.hdr_hdl = rmnet_ipa3_ctx->qmap_hdr_hdl;
351
352 if (ipa3_add_rt_rule(rt_rule)) {
353 IPAWANERR("fail to add dflt_wan v4 rule\n");
354 kfree(rt_rule);
355 return -EPERM;
356 }
357
358 IPAWANDBG("dflt v4 rt rule hdl=%x\n", rt_rule_entry->rt_rule_hdl);
359 rmnet_ipa3_ctx->dflt_v4_wan_rt_hdl = rt_rule_entry->rt_rule_hdl;
360
361 /* setup a default v6 route to point to A5 */
362 rt_rule->ip = IPA_IP_v6;
363 if (ipa3_add_rt_rule(rt_rule)) {
364 IPAWANERR("fail to add dflt_wan v6 rule\n");
365 kfree(rt_rule);
366 return -EPERM;
367 }
368 IPAWANDBG("dflt v6 rt rule hdl=%x\n", rt_rule_entry->rt_rule_hdl);
369 rmnet_ipa3_ctx->dflt_v6_wan_rt_hdl = rt_rule_entry->rt_rule_hdl;
370
371 kfree(rt_rule);
372 return 0;
373}
374
375static void ipa3_del_dflt_wan_rt_tables(void)
376{
377 struct ipa_ioc_del_rt_rule *rt_rule;
378 struct ipa_rt_rule_del *rt_rule_entry;
379 int len;
380
381 len = sizeof(struct ipa_ioc_del_rt_rule) + 1 *
382 sizeof(struct ipa_rt_rule_del);
383 rt_rule = kzalloc(len, GFP_KERNEL);
384 if (!rt_rule) {
385 IPAWANERR("unable to allocate memory for del route rule\n");
386 return;
387 }
388
389 memset(rt_rule, 0, len);
390 rt_rule->commit = 1;
391 rt_rule->num_hdls = 1;
392 rt_rule->ip = IPA_IP_v4;
393
394 rt_rule_entry = &rt_rule->hdl[0];
395 rt_rule_entry->status = -1;
396 rt_rule_entry->hdl = rmnet_ipa3_ctx->dflt_v4_wan_rt_hdl;
397
398 IPAWANERR("Deleting Route hdl:(0x%x) with ip type: %d\n",
399 rt_rule_entry->hdl, IPA_IP_v4);
400 if (ipa3_del_rt_rule(rt_rule) ||
401 (rt_rule_entry->status)) {
402 IPAWANERR("Routing rule deletion failed!\n");
403 }
404
405 rt_rule->ip = IPA_IP_v6;
406 rt_rule_entry->hdl = rmnet_ipa3_ctx->dflt_v6_wan_rt_hdl;
407 IPAWANERR("Deleting Route hdl:(0x%x) with ip type: %d\n",
408 rt_rule_entry->hdl, IPA_IP_v6);
409 if (ipa3_del_rt_rule(rt_rule) ||
410 (rt_rule_entry->status)) {
411 IPAWANERR("Routing rule deletion failed!\n");
412 }
413
414 kfree(rt_rule);
415}
416
417int ipa3_copy_ul_filter_rule_to_ipa(struct ipa_install_fltr_rule_req_msg_v01
418 *rule_req)
419{
420 int i, j;
421
422 if (rule_req->filter_spec_ex_list_valid == true) {
423 rmnet_ipa3_ctx->num_q6_rules =
424 rule_req->filter_spec_ex_list_len;
425 IPAWANDBG("Received (%d) install_flt_req\n",
426 rmnet_ipa3_ctx->num_q6_rules);
427 } else {
428 rmnet_ipa3_ctx->num_q6_rules = 0;
429 IPAWANERR("got no UL rules from modem\n");
430 return -EINVAL;
431 }
432
433 /* copy UL filter rules from Modem*/
434 for (i = 0; i < rmnet_ipa3_ctx->num_q6_rules; i++) {
435 /* check if rules overside the cache*/
436 if (i == MAX_NUM_Q6_RULE) {
437 IPAWANERR("Reaching (%d) max cache ",
438 MAX_NUM_Q6_RULE);
439 IPAWANERR(" however total (%d)\n",
440 rmnet_ipa3_ctx->num_q6_rules);
441 goto failure;
442 }
443 ipa3_qmi_ctx->q6_ul_filter_rule[i].ip =
444 rule_req->filter_spec_ex_list[i].ip_type;
445 ipa3_qmi_ctx->q6_ul_filter_rule[i].action =
446 rule_req->filter_spec_ex_list[i].filter_action;
447 if (rule_req->filter_spec_ex_list[i].
448 is_routing_table_index_valid == true)
449 ipa3_qmi_ctx->q6_ul_filter_rule[i].rt_tbl_idx =
450 rule_req->filter_spec_ex_list[i].route_table_index;
451 if (rule_req->filter_spec_ex_list[i].is_mux_id_valid == true)
452 ipa3_qmi_ctx->q6_ul_filter_rule[i].mux_id =
453 rule_req->filter_spec_ex_list[i].mux_id;
454 ipa3_qmi_ctx->q6_ul_filter_rule[i].rule_id =
455 rule_req->filter_spec_ex_list[i].rule_id;
456 ipa3_qmi_ctx->q6_ul_filter_rule[i].is_rule_hashable =
457 rule_req->filter_spec_ex_list[i].is_rule_hashable;
458 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.rule_eq_bitmap =
459 rule_req->filter_spec_ex_list[i].filter_rule.
460 rule_eq_bitmap;
461 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tos_eq_present =
462 rule_req->filter_spec_ex_list[i].filter_rule.
463 tos_eq_present;
464 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tos_eq =
465 rule_req->filter_spec_ex_list[i].filter_rule.tos_eq;
466 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
467 protocol_eq_present = rule_req->filter_spec_ex_list[i].
468 filter_rule.protocol_eq_present;
469 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.protocol_eq =
470 rule_req->filter_spec_ex_list[i].filter_rule.
471 protocol_eq;
472
473 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
474 num_ihl_offset_range_16 =
475 rule_req->filter_spec_ex_list[i].
476 filter_rule.num_ihl_offset_range_16;
477 for (j = 0; j < ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
478 num_ihl_offset_range_16; j++) {
479 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
480 ihl_offset_range_16[j].offset = rule_req->
481 filter_spec_ex_list[i].filter_rule.
482 ihl_offset_range_16[j].offset;
483 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
484 ihl_offset_range_16[j].range_low = rule_req->
485 filter_spec_ex_list[i].filter_rule.
486 ihl_offset_range_16[j].range_low;
487 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
488 ihl_offset_range_16[j].range_high = rule_req->
489 filter_spec_ex_list[i].filter_rule.
490 ihl_offset_range_16[j].range_high;
491 }
492 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.num_offset_meq_32 =
493 rule_req->filter_spec_ex_list[i].filter_rule.
494 num_offset_meq_32;
495 for (j = 0; j < ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
496 num_offset_meq_32; j++) {
497 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
498 offset_meq_32[j].offset =
499 rule_req->filter_spec_ex_list[i].
500 filter_rule.offset_meq_32[j].offset;
501 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
502 offset_meq_32[j].mask =
503 rule_req->filter_spec_ex_list[i].
504 filter_rule.offset_meq_32[j].mask;
505 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
506 offset_meq_32[j].value =
507 rule_req->filter_spec_ex_list[i].
508 filter_rule.offset_meq_32[j].value;
509 }
510
511 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tc_eq_present =
512 rule_req->filter_spec_ex_list[i].
513 filter_rule.tc_eq_present;
514 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tc_eq =
515 rule_req->filter_spec_ex_list[i].filter_rule.tc_eq;
516 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.fl_eq_present =
517 rule_req->filter_spec_ex_list[i].filter_rule.
518 flow_eq_present;
519 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.fl_eq =
520 rule_req->filter_spec_ex_list[i].filter_rule.flow_eq;
521 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
522 ihl_offset_eq_16_present = rule_req->filter_spec_ex_list[i].
523 filter_rule.ihl_offset_eq_16_present;
524 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
525 ihl_offset_eq_16.offset = rule_req->filter_spec_ex_list[i].
526 filter_rule.ihl_offset_eq_16.offset;
527 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
528 ihl_offset_eq_16.value = rule_req->filter_spec_ex_list[i].
529 filter_rule.ihl_offset_eq_16.value;
530
531 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
532 ihl_offset_eq_32_present = rule_req->filter_spec_ex_list[i].
533 filter_rule.ihl_offset_eq_32_present;
534 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
535 ihl_offset_eq_32.offset = rule_req->filter_spec_ex_list[i].
536 filter_rule.ihl_offset_eq_32.offset;
537 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
538 ihl_offset_eq_32.value = rule_req->filter_spec_ex_list[i].
539 filter_rule.ihl_offset_eq_32.value;
540
541 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
542 num_ihl_offset_meq_32 = rule_req->filter_spec_ex_list[i].
543 filter_rule.num_ihl_offset_meq_32;
544 for (j = 0; j < ipa3_qmi_ctx->q6_ul_filter_rule[i].
545 eq_attrib.num_ihl_offset_meq_32; j++) {
546 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
547 ihl_offset_meq_32[j].offset = rule_req->
548 filter_spec_ex_list[i].filter_rule.
549 ihl_offset_meq_32[j].offset;
550 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
551 ihl_offset_meq_32[j].mask = rule_req->
552 filter_spec_ex_list[i].filter_rule.
553 ihl_offset_meq_32[j].mask;
554 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
555 ihl_offset_meq_32[j].value = rule_req->
556 filter_spec_ex_list[i].filter_rule.
557 ihl_offset_meq_32[j].value;
558 }
559 ipa3_qmi_ctx->
560 q6_ul_filter_rule[i].eq_attrib.num_offset_meq_128 =
561 rule_req->filter_spec_ex_list[i].filter_rule.
562 num_offset_meq_128;
563 for (j = 0; j < ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
564 num_offset_meq_128; j++) {
565 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
566 offset_meq_128[j].offset = rule_req->
567 filter_spec_ex_list[i].filter_rule.
568 offset_meq_128[j].offset;
569 memcpy(ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
570 offset_meq_128[j].mask,
571 rule_req->filter_spec_ex_list[i].
572 filter_rule.offset_meq_128[j].mask, 16);
573 memcpy(ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
574 offset_meq_128[j].value, rule_req->
575 filter_spec_ex_list[i].filter_rule.
576 offset_meq_128[j].value, 16);
577 }
578
579 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
580 metadata_meq32_present =
581 rule_req->filter_spec_ex_list[i].
582 filter_rule.metadata_meq32_present;
583 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
584 metadata_meq32.offset =
585 rule_req->filter_spec_ex_list[i].
586 filter_rule.metadata_meq32.offset;
587 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
588 metadata_meq32.mask = rule_req->filter_spec_ex_list[i].
589 filter_rule.metadata_meq32.mask;
590 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.metadata_meq32.
591 value = rule_req->filter_spec_ex_list[i].filter_rule.
592 metadata_meq32.value;
593 ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.
594 ipv4_frag_eq_present = rule_req->filter_spec_ex_list[i].
595 filter_rule.ipv4_frag_eq_present;
596 }
597
598 if (rule_req->xlat_filter_indices_list_valid) {
599 if (rule_req->xlat_filter_indices_list_len >
600 rmnet_ipa3_ctx->num_q6_rules) {
601 IPAWANERR("Number of xlat indices is not valid: %d\n",
602 rule_req->xlat_filter_indices_list_len);
603 goto failure;
604 }
605 IPAWANDBG("Receive %d XLAT indices: ",
606 rule_req->xlat_filter_indices_list_len);
607 for (i = 0; i < rule_req->xlat_filter_indices_list_len; i++)
608 IPAWANDBG("%d ", rule_req->xlat_filter_indices_list[i]);
609 IPAWANDBG("\n");
610
611 for (i = 0; i < rule_req->xlat_filter_indices_list_len; i++) {
612 if (rule_req->xlat_filter_indices_list[i]
613 >= rmnet_ipa3_ctx->num_q6_rules) {
614 IPAWANERR("Xlat rule idx is wrong: %d\n",
615 rule_req->xlat_filter_indices_list[i]);
616 goto failure;
617 } else {
618 ipa3_qmi_ctx->q6_ul_filter_rule
619 [rule_req->xlat_filter_indices_list[i]]
620 .is_xlat_rule = 1;
621 IPAWANDBG("Rule %d is xlat rule\n",
622 rule_req->xlat_filter_indices_list[i]);
623 }
624 }
625 }
626 goto success;
627
628failure:
629 rmnet_ipa3_ctx->num_q6_rules = 0;
630 memset(ipa3_qmi_ctx->q6_ul_filter_rule, 0,
631 sizeof(ipa3_qmi_ctx->q6_ul_filter_rule));
632 return -EINVAL;
633
634success:
635 return 0;
636}
637
638static int ipa3_wwan_add_ul_flt_rule_to_ipa(void)
639{
640 u32 pyld_sz;
641 int i, retval = 0;
642 struct ipa_ioc_add_flt_rule *param;
643 struct ipa_flt_rule_add flt_rule_entry;
644 struct ipa_fltr_installed_notif_req_msg_v01 *req;
645
646 pyld_sz = sizeof(struct ipa_ioc_add_flt_rule) +
647 sizeof(struct ipa_flt_rule_add);
648 param = kzalloc(pyld_sz, GFP_KERNEL);
649 if (!param)
650 return -ENOMEM;
651
652 req = (struct ipa_fltr_installed_notif_req_msg_v01 *)
653 kzalloc(sizeof(struct ipa_fltr_installed_notif_req_msg_v01),
654 GFP_KERNEL);
655 if (!req) {
656 kfree(param);
657 return -ENOMEM;
658 }
659
660 param->commit = 1;
Ghanim Fodic6b67492017-03-15 14:19:56 +0200661 param->ep = IPA_CLIENT_APPS_WAN_PROD;
Amir Levy9659e592016-10-27 18:08:27 +0300662 param->global = false;
663 param->num_rules = (uint8_t)1;
664
665 for (i = 0; i < rmnet_ipa3_ctx->num_q6_rules; i++) {
666 param->ip = ipa3_qmi_ctx->q6_ul_filter_rule[i].ip;
667 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
668 flt_rule_entry.at_rear = true;
669 flt_rule_entry.rule.action =
670 ipa3_qmi_ctx->q6_ul_filter_rule[i].action;
671 flt_rule_entry.rule.rt_tbl_idx
672 = ipa3_qmi_ctx->q6_ul_filter_rule[i].rt_tbl_idx;
673 flt_rule_entry.rule.retain_hdr = true;
674 flt_rule_entry.rule.hashable =
675 ipa3_qmi_ctx->q6_ul_filter_rule[i].is_rule_hashable;
676 flt_rule_entry.rule.rule_id =
677 ipa3_qmi_ctx->q6_ul_filter_rule[i].rule_id;
678
679 /* debug rt-hdl*/
680 IPAWANDBG("install-IPA index(%d),rt-tbl:(%d)\n",
681 i, flt_rule_entry.rule.rt_tbl_idx);
682 flt_rule_entry.rule.eq_attrib_type = true;
683 memcpy(&(flt_rule_entry.rule.eq_attrib),
684 &ipa3_qmi_ctx->q6_ul_filter_rule[i].eq_attrib,
685 sizeof(struct ipa_ipfltri_rule_eq));
686 memcpy(&(param->rules[0]), &flt_rule_entry,
687 sizeof(struct ipa_flt_rule_add));
688 if (ipa3_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) {
689 retval = -EFAULT;
690 IPAWANERR("add A7 UL filter rule(%d) failed\n", i);
691 } else {
692 /* store the rule handler */
693 ipa3_qmi_ctx->q6_ul_filter_rule_hdl[i] =
694 param->rules[0].flt_rule_hdl;
695 }
696 }
697
698 /* send ipa_fltr_installed_notif_req_msg_v01 to Q6*/
699 req->source_pipe_index =
Ghanim Fodic6b67492017-03-15 14:19:56 +0200700 ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_PROD);
Amir Levy9659e592016-10-27 18:08:27 +0300701 req->install_status = QMI_RESULT_SUCCESS_V01;
702 req->rule_id_valid = 1;
703 req->rule_id_len = rmnet_ipa3_ctx->num_q6_rules;
704 for (i = 0; i < rmnet_ipa3_ctx->num_q6_rules; i++) {
705 req->rule_id[i] =
706 ipa3_qmi_ctx->q6_ul_filter_rule[i].rule_id;
707 }
708 if (ipa3_qmi_filter_notify_send(req)) {
709 IPAWANDBG("add filter rule index on A7-RX failed\n");
710 retval = -EFAULT;
711 }
712 rmnet_ipa3_ctx->old_num_q6_rules = rmnet_ipa3_ctx->num_q6_rules;
713 IPAWANDBG("add (%d) filter rule index on A7-RX\n",
714 rmnet_ipa3_ctx->old_num_q6_rules);
715 kfree(param);
716 kfree(req);
717 return retval;
718}
719
720static int ipa3_wwan_del_ul_flt_rule_to_ipa(void)
721{
722 u32 pyld_sz;
723 int i, retval = 0;
724 struct ipa_ioc_del_flt_rule *param;
725 struct ipa_flt_rule_del flt_rule_entry;
726
727 pyld_sz = sizeof(struct ipa_ioc_del_flt_rule) +
728 sizeof(struct ipa_flt_rule_del);
729 param = kzalloc(pyld_sz, GFP_KERNEL);
730 if (!param) {
731 IPAWANERR("kzalloc failed\n");
732 return -ENOMEM;
733 }
734
735 param->commit = 1;
736 param->num_hdls = (uint8_t) 1;
737
738 for (i = 0; i < rmnet_ipa3_ctx->old_num_q6_rules; i++) {
739 param->ip = ipa3_qmi_ctx->q6_ul_filter_rule[i].ip;
740 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
741 flt_rule_entry.hdl = ipa3_qmi_ctx->q6_ul_filter_rule_hdl[i];
742 /* debug rt-hdl*/
743 IPAWANDBG("delete-IPA rule index(%d)\n", i);
744 memcpy(&(param->hdl[0]), &flt_rule_entry,
745 sizeof(struct ipa_flt_rule_del));
746 if (ipa3_del_flt_rule((struct ipa_ioc_del_flt_rule *)param)) {
747 IPAWANERR("del A7 UL filter rule(%d) failed\n", i);
748 kfree(param);
749 return -EFAULT;
750 }
751 }
752
753 /* set UL filter-rule add-indication */
754 rmnet_ipa3_ctx->a7_ul_flt_set = false;
755 rmnet_ipa3_ctx->old_num_q6_rules = 0;
756
757 kfree(param);
758 return retval;
759}
760
761static int ipa3_find_mux_channel_index(uint32_t mux_id)
762{
763 int i;
764
765 for (i = 0; i < MAX_NUM_OF_MUX_CHANNEL; i++) {
766 if (mux_id == rmnet_ipa3_ctx->mux_channel[i].mux_id)
767 return i;
768 }
769 return MAX_NUM_OF_MUX_CHANNEL;
770}
771
772static int find_vchannel_name_index(const char *vchannel_name)
773{
774 int i;
775
776 for (i = 0; i < MAX_NUM_OF_MUX_CHANNEL; i++) {
777 if (strcmp(rmnet_ipa3_ctx->mux_channel[i].vchannel_name,
778 vchannel_name) == 0)
779 return i;
780 }
781 return MAX_NUM_OF_MUX_CHANNEL;
782}
783
784static int ipa3_wwan_register_to_ipa(int index)
785{
786 struct ipa_tx_intf tx_properties = {0};
787 struct ipa_ioc_tx_intf_prop tx_ioc_properties[2] = { {0}, {0} };
788 struct ipa_ioc_tx_intf_prop *tx_ipv4_property;
789 struct ipa_ioc_tx_intf_prop *tx_ipv6_property;
790 struct ipa_rx_intf rx_properties = {0};
791 struct ipa_ioc_rx_intf_prop rx_ioc_properties[2] = { {0}, {0} };
792 struct ipa_ioc_rx_intf_prop *rx_ipv4_property;
793 struct ipa_ioc_rx_intf_prop *rx_ipv6_property;
794 struct ipa_ext_intf ext_properties = {0};
795 struct ipa_ioc_ext_intf_prop *ext_ioc_properties;
796 u32 pyld_sz;
797 int ret = 0, i;
798
799 IPAWANDBG("index(%d) device[%s]:\n", index,
800 rmnet_ipa3_ctx->mux_channel[index].vchannel_name);
801 if (!rmnet_ipa3_ctx->mux_channel[index].mux_hdr_set) {
802 ret = ipa3_add_qmap_hdr(
803 rmnet_ipa3_ctx->mux_channel[index].mux_id,
804 &rmnet_ipa3_ctx->mux_channel[index].hdr_hdl);
805 if (ret) {
806 IPAWANERR("ipa_add_mux_hdr failed (%d)\n", index);
807 return ret;
808 }
809 rmnet_ipa3_ctx->mux_channel[index].mux_hdr_set = true;
810 }
811 tx_properties.prop = tx_ioc_properties;
812 tx_ipv4_property = &tx_properties.prop[0];
813 tx_ipv4_property->ip = IPA_IP_v4;
814 tx_ipv4_property->dst_pipe = IPA_CLIENT_APPS_WAN_CONS;
815 snprintf(tx_ipv4_property->hdr_name, IPA_RESOURCE_NAME_MAX, "%s%d",
816 A2_MUX_HDR_NAME_V4_PREF,
817 rmnet_ipa3_ctx->mux_channel[index].mux_id);
818 tx_ipv6_property = &tx_properties.prop[1];
819 tx_ipv6_property->ip = IPA_IP_v6;
820 tx_ipv6_property->dst_pipe = IPA_CLIENT_APPS_WAN_CONS;
821 /* no need use A2_MUX_HDR_NAME_V6_PREF, same header */
822 snprintf(tx_ipv6_property->hdr_name, IPA_RESOURCE_NAME_MAX, "%s%d",
823 A2_MUX_HDR_NAME_V4_PREF,
824 rmnet_ipa3_ctx->mux_channel[index].mux_id);
825 tx_properties.num_props = 2;
826
827 rx_properties.prop = rx_ioc_properties;
828 rx_ipv4_property = &rx_properties.prop[0];
829 rx_ipv4_property->ip = IPA_IP_v4;
830 rx_ipv4_property->attrib.attrib_mask |= IPA_FLT_META_DATA;
831 rx_ipv4_property->attrib.meta_data =
832 rmnet_ipa3_ctx->mux_channel[index].mux_id << WWAN_METADATA_SHFT;
833 rx_ipv4_property->attrib.meta_data_mask = WWAN_METADATA_MASK;
Ghanim Fodic6b67492017-03-15 14:19:56 +0200834 rx_ipv4_property->src_pipe = IPA_CLIENT_APPS_WAN_PROD;
Amir Levy9659e592016-10-27 18:08:27 +0300835 rx_ipv6_property = &rx_properties.prop[1];
836 rx_ipv6_property->ip = IPA_IP_v6;
837 rx_ipv6_property->attrib.attrib_mask |= IPA_FLT_META_DATA;
838 rx_ipv6_property->attrib.meta_data =
839 rmnet_ipa3_ctx->mux_channel[index].mux_id << WWAN_METADATA_SHFT;
840 rx_ipv6_property->attrib.meta_data_mask = WWAN_METADATA_MASK;
Ghanim Fodic6b67492017-03-15 14:19:56 +0200841 rx_ipv6_property->src_pipe = IPA_CLIENT_APPS_WAN_PROD;
Amir Levy9659e592016-10-27 18:08:27 +0300842 rx_properties.num_props = 2;
843
844 pyld_sz = rmnet_ipa3_ctx->num_q6_rules *
845 sizeof(struct ipa_ioc_ext_intf_prop);
846 ext_ioc_properties = kmalloc(pyld_sz, GFP_KERNEL);
847 if (!ext_ioc_properties) {
848 IPAWANERR("Error allocate memory\n");
849 return -ENOMEM;
850 }
851
852 ext_properties.prop = ext_ioc_properties;
853 ext_properties.excp_pipe_valid = true;
854 ext_properties.excp_pipe = IPA_CLIENT_APPS_WAN_CONS;
855 ext_properties.num_props = rmnet_ipa3_ctx->num_q6_rules;
856 for (i = 0; i < rmnet_ipa3_ctx->num_q6_rules; i++) {
857 memcpy(&(ext_properties.prop[i]),
858 &(ipa3_qmi_ctx->q6_ul_filter_rule[i]),
859 sizeof(struct ipa_ioc_ext_intf_prop));
860 ext_properties.prop[i].mux_id =
861 rmnet_ipa3_ctx->mux_channel[index].mux_id;
862 IPAWANDBG("index %d ip: %d rt-tbl:%d\n", i,
863 ext_properties.prop[i].ip,
864 ext_properties.prop[i].rt_tbl_idx);
865 IPAWANDBG("action: %d mux:%d\n",
866 ext_properties.prop[i].action,
867 ext_properties.prop[i].mux_id);
868 }
869 ret = ipa3_register_intf_ext(rmnet_ipa3_ctx->mux_channel[index].
870 vchannel_name, &tx_properties,
871 &rx_properties, &ext_properties);
872 if (ret) {
873 IPAWANERR("[%s]:ipa3_register_intf failed %d\n",
874 rmnet_ipa3_ctx->mux_channel[index].vchannel_name, ret);
875 goto fail;
876 }
877 rmnet_ipa3_ctx->mux_channel[index].ul_flt_reg = true;
878fail:
879 kfree(ext_ioc_properties);
880 return ret;
881}
882
883static void ipa3_cleanup_deregister_intf(void)
884{
885 int i;
886 int ret;
887
888 for (i = 0; i < rmnet_ipa3_ctx->rmnet_index; i++) {
889 if (rmnet_ipa3_ctx->mux_channel[i].ul_flt_reg) {
890 ret = ipa3_deregister_intf(
891 rmnet_ipa3_ctx->mux_channel[i].vchannel_name);
892 if (ret < 0) {
893 IPAWANERR("de-register device %s(%d) failed\n",
894 rmnet_ipa3_ctx->mux_channel[i].
895 vchannel_name,
896 i);
897 return;
898 }
899 IPAWANDBG("de-register device %s(%d) success\n",
900 rmnet_ipa3_ctx->mux_channel[i].vchannel_name,
901 i);
902 }
903 rmnet_ipa3_ctx->mux_channel[i].ul_flt_reg = false;
904 }
905}
906
907int ipa3_wwan_update_mux_channel_prop(void)
908{
909 int ret = 0, i;
910 /* install UL filter rules */
911 if (rmnet_ipa3_ctx->egress_set) {
912 if (ipa3_qmi_ctx->modem_cfg_emb_pipe_flt == false) {
913 IPAWANDBG("setup UL filter rules\n");
914 if (rmnet_ipa3_ctx->a7_ul_flt_set) {
915 IPAWANDBG("del previous UL filter rules\n");
916 /* delete rule hdlers */
917 ret = ipa3_wwan_del_ul_flt_rule_to_ipa();
918 if (ret) {
919 IPAWANERR("failed to del old rules\n");
920 return -EINVAL;
921 }
922 IPAWANDBG("deleted old UL rules\n");
923 }
924 ret = ipa3_wwan_add_ul_flt_rule_to_ipa();
925 }
926 if (ret)
927 IPAWANERR("failed to install UL rules\n");
928 else
929 rmnet_ipa3_ctx->a7_ul_flt_set = true;
930 }
931 /* update Tx/Rx/Ext property */
932 IPAWANDBG("update Tx/Rx/Ext property in IPA\n");
933 if (rmnet_ipa3_ctx->rmnet_index == 0) {
934 IPAWANDBG("no Tx/Rx/Ext property registered in IPA\n");
935 return ret;
936 }
937
938 ipa3_cleanup_deregister_intf();
939
940 for (i = 0; i < rmnet_ipa3_ctx->rmnet_index; i++) {
941 ret = ipa3_wwan_register_to_ipa(i);
942 if (ret < 0) {
943 IPAWANERR("failed to re-regist %s, mux %d, index %d\n",
944 rmnet_ipa3_ctx->mux_channel[i].vchannel_name,
945 rmnet_ipa3_ctx->mux_channel[i].mux_id,
946 i);
947 return -ENODEV;
948 }
949 IPAWANERR("dev(%s) has registered to IPA\n",
950 rmnet_ipa3_ctx->mux_channel[i].vchannel_name);
951 rmnet_ipa3_ctx->mux_channel[i].ul_flt_reg = true;
952 }
953 return ret;
954}
955
956#ifdef INIT_COMPLETION
957#define reinit_completion(x) INIT_COMPLETION(*(x))
958#endif /* INIT_COMPLETION */
959
960static int __ipa_wwan_open(struct net_device *dev)
961{
962 struct ipa3_wwan_private *wwan_ptr = netdev_priv(dev);
963
964 IPAWANDBG("[%s] __wwan_open()\n", dev->name);
965 if (wwan_ptr->device_status != WWAN_DEVICE_ACTIVE)
966 reinit_completion(&wwan_ptr->resource_granted_completion);
967 wwan_ptr->device_status = WWAN_DEVICE_ACTIVE;
968
969 if (ipa3_rmnet_res.ipa_napi_enable)
970 napi_enable(&(wwan_ptr->napi));
971 return 0;
972}
973
974/**
975 * wwan_open() - Opens the wwan network interface. Opens logical
976 * channel on A2 MUX driver and starts the network stack queue
977 *
978 * @dev: network device
979 *
980 * Return codes:
981 * 0: success
982 * -ENODEV: Error while opening logical channel on A2 MUX driver
983 */
984static int ipa3_wwan_open(struct net_device *dev)
985{
986 int rc = 0;
987
988 IPAWANDBG("[%s] wwan_open()\n", dev->name);
989 rc = __ipa_wwan_open(dev);
990 if (rc == 0)
991 netif_start_queue(dev);
992 return rc;
993}
994
995static int __ipa_wwan_close(struct net_device *dev)
996{
997 struct ipa3_wwan_private *wwan_ptr = netdev_priv(dev);
998 int rc = 0;
999
1000 if (wwan_ptr->device_status == WWAN_DEVICE_ACTIVE) {
1001 wwan_ptr->device_status = WWAN_DEVICE_INACTIVE;
1002 /* do not close wwan port once up, this causes
1003 * remote side to hang if tried to open again
1004 */
1005 reinit_completion(&wwan_ptr->resource_granted_completion);
1006 rc = ipa3_deregister_intf(dev->name);
1007 if (rc) {
1008 IPAWANERR("[%s]: ipa3_deregister_intf failed %d\n",
1009 dev->name, rc);
1010 return rc;
1011 }
1012 return rc;
1013 } else {
1014 return -EBADF;
1015 }
1016}
1017
1018/**
1019 * ipa3_wwan_stop() - Stops the wwan network interface. Closes
1020 * logical channel on A2 MUX driver and stops the network stack
1021 * queue
1022 *
1023 * @dev: network device
1024 *
1025 * Return codes:
1026 * 0: success
1027 * -ENODEV: Error while opening logical channel on A2 MUX driver
1028 */
1029static int ipa3_wwan_stop(struct net_device *dev)
1030{
1031 IPAWANDBG("[%s] ipa3_wwan_stop()\n", dev->name);
1032 __ipa_wwan_close(dev);
1033 netif_stop_queue(dev);
1034 return 0;
1035}
1036
1037static int ipa3_wwan_change_mtu(struct net_device *dev, int new_mtu)
1038{
1039 if (0 > new_mtu || WWAN_DATA_LEN < new_mtu)
1040 return -EINVAL;
1041 IPAWANDBG("[%s] MTU change: old=%d new=%d\n",
1042 dev->name, dev->mtu, new_mtu);
1043 dev->mtu = new_mtu;
1044 return 0;
1045}
1046
1047/**
1048 * ipa3_wwan_xmit() - Transmits an skb.
1049 *
1050 * @skb: skb to be transmitted
1051 * @dev: network device
1052 *
1053 * Return codes:
1054 * 0: success
1055 * NETDEV_TX_BUSY: Error while transmitting the skb. Try again
1056 * later
1057 * -EFAULT: Error while transmitting the skb
1058 */
1059static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev)
1060{
1061 int ret = 0;
1062 bool qmap_check;
1063 struct ipa3_wwan_private *wwan_ptr = netdev_priv(dev);
1064 struct ipa_tx_meta meta;
1065
1066 if (skb->protocol != htons(ETH_P_MAP)) {
1067 IPAWANDBG_LOW
1068 ("SW filtering out none QMAP packet received from %s",
1069 current->comm);
Sunil Paidimarri6c818e82016-10-17 18:33:13 -07001070 dev_kfree_skb_any(skb);
1071 dev->stats.tx_dropped++;
Amir Levy9659e592016-10-27 18:08:27 +03001072 return NETDEV_TX_OK;
1073 }
1074
1075 qmap_check = RMNET_MAP_GET_CD_BIT(skb);
1076 if (netif_queue_stopped(dev)) {
1077 if (qmap_check &&
1078 atomic_read(&wwan_ptr->outstanding_pkts) <
1079 wwan_ptr->outstanding_high_ctl) {
1080 pr_err("[%s]Queue stop, send ctrl pkts\n", dev->name);
1081 goto send;
1082 } else {
Sunil Paidimarri6c818e82016-10-17 18:33:13 -07001083 pr_err("[%s]fatal: ipa3_wwan_xmit stopped\n",
1084 dev->name);
Amir Levy9659e592016-10-27 18:08:27 +03001085 return NETDEV_TX_BUSY;
1086 }
1087 }
1088
1089 /* checking High WM hit */
1090 if (atomic_read(&wwan_ptr->outstanding_pkts) >=
1091 wwan_ptr->outstanding_high) {
1092 if (!qmap_check) {
1093 IPAWANDBG_LOW("pending(%d)/(%d)- stop(%d)\n",
1094 atomic_read(&wwan_ptr->outstanding_pkts),
1095 wwan_ptr->outstanding_high,
1096 netif_queue_stopped(dev));
1097 IPAWANDBG_LOW("qmap_chk(%d)\n", qmap_check);
1098 netif_stop_queue(dev);
1099 return NETDEV_TX_BUSY;
1100 }
1101 }
1102
1103send:
1104 /* IPA_RM checking start */
1105 ret = ipa_rm_inactivity_timer_request_resource(
1106 IPA_RM_RESOURCE_WWAN_0_PROD);
1107 if (ret == -EINPROGRESS) {
1108 netif_stop_queue(dev);
1109 return NETDEV_TX_BUSY;
1110 }
1111 if (ret) {
1112 pr_err("[%s] fatal: ipa rm timer request resource failed %d\n",
1113 dev->name, ret);
Sunil Paidimarri6c818e82016-10-17 18:33:13 -07001114 dev_kfree_skb_any(skb);
1115 dev->stats.tx_dropped++;
Amir Levy9659e592016-10-27 18:08:27 +03001116 return -EFAULT;
1117 }
1118 /* IPA_RM checking end */
1119
1120 if (RMNET_MAP_GET_CD_BIT(skb)) {
1121 memset(&meta, 0, sizeof(meta));
1122 meta.pkt_init_dst_ep_valid = true;
1123 meta.pkt_init_dst_ep_remote = true;
Ghanim Fodic6b67492017-03-15 14:19:56 +02001124 meta.pkt_init_dst_ep = IPA_CLIENT_Q6_LAN_CONS;
1125 ret = ipa3_tx_dp(IPA_CLIENT_APPS_WAN_PROD, skb, &meta);
Amir Levy9659e592016-10-27 18:08:27 +03001126 } else {
Ghanim Fodic6b67492017-03-15 14:19:56 +02001127 ret = ipa3_tx_dp(IPA_CLIENT_APPS_WAN_PROD, skb, NULL);
Amir Levy9659e592016-10-27 18:08:27 +03001128 }
1129
1130 if (ret) {
1131 ret = NETDEV_TX_BUSY;
Amir Levy9659e592016-10-27 18:08:27 +03001132 goto out;
1133 }
1134
1135 atomic_inc(&wwan_ptr->outstanding_pkts);
1136 dev->stats.tx_packets++;
1137 dev->stats.tx_bytes += skb->len;
1138 ret = NETDEV_TX_OK;
1139out:
Skylar Changf3a7dac2017-01-25 09:16:55 -08001140 if (atomic_read(&wwan_ptr->outstanding_pkts) == 0)
1141 ipa_rm_inactivity_timer_release_resource(
1142 IPA_RM_RESOURCE_WWAN_0_PROD);
Amir Levy9659e592016-10-27 18:08:27 +03001143 return ret;
1144}
1145
1146static void ipa3_wwan_tx_timeout(struct net_device *dev)
1147{
1148 IPAWANERR("[%s] ipa3_wwan_tx_timeout(), data stall in UL\n", dev->name);
1149}
1150
1151/**
1152 * apps_ipa_tx_complete_notify() - Rx notify
1153 *
1154 * @priv: driver context
1155 * @evt: event type
1156 * @data: data provided with event
1157 *
1158 * Check that the packet is the one we sent and release it
1159 * This function will be called in defered context in IPA wq.
1160 */
1161static void apps_ipa_tx_complete_notify(void *priv,
1162 enum ipa_dp_evt_type evt,
1163 unsigned long data)
1164{
1165 struct sk_buff *skb = (struct sk_buff *)data;
1166 struct net_device *dev = (struct net_device *)priv;
1167 struct ipa3_wwan_private *wwan_ptr;
1168
1169 if (dev != IPA_NETDEV()) {
1170 IPAWANDBG("Received pre-SSR packet completion\n");
1171 dev_kfree_skb_any(skb);
1172 return;
1173 }
1174
1175 if (evt != IPA_WRITE_DONE) {
1176 IPAWANERR("unsupported evt on Tx callback, Drop the packet\n");
1177 dev_kfree_skb_any(skb);
1178 dev->stats.tx_dropped++;
1179 return;
1180 }
1181
1182 wwan_ptr = netdev_priv(dev);
1183 atomic_dec(&wwan_ptr->outstanding_pkts);
1184 __netif_tx_lock_bh(netdev_get_tx_queue(dev, 0));
1185 if (!atomic_read(&rmnet_ipa3_ctx->is_ssr) &&
1186 netif_queue_stopped(wwan_ptr->net) &&
1187 atomic_read(&wwan_ptr->outstanding_pkts) <
1188 (wwan_ptr->outstanding_low)) {
1189 IPAWANDBG_LOW("Outstanding low (%d) - waking up queue\n",
1190 wwan_ptr->outstanding_low);
1191 netif_wake_queue(wwan_ptr->net);
1192 }
Skylar Changf3a7dac2017-01-25 09:16:55 -08001193
1194 if (atomic_read(&wwan_ptr->outstanding_pkts) == 0)
1195 ipa_rm_inactivity_timer_release_resource(
1196 IPA_RM_RESOURCE_WWAN_0_PROD);
Amir Levy9659e592016-10-27 18:08:27 +03001197 __netif_tx_unlock_bh(netdev_get_tx_queue(dev, 0));
1198 dev_kfree_skb_any(skb);
Amir Levy9659e592016-10-27 18:08:27 +03001199}
1200
1201/**
1202 * apps_ipa_packet_receive_notify() - Rx notify
1203 *
1204 * @priv: driver context
1205 * @evt: event type
1206 * @data: data provided with event
1207 *
1208 * IPA will pass a packet to the Linux network stack with skb->data
1209 */
1210static void apps_ipa_packet_receive_notify(void *priv,
1211 enum ipa_dp_evt_type evt,
1212 unsigned long data)
1213{
1214 struct net_device *dev = (struct net_device *)priv;
1215
1216 if (evt == IPA_RECEIVE) {
1217 struct sk_buff *skb = (struct sk_buff *)data;
1218 int result;
1219 unsigned int packet_len = skb->len;
1220
1221 IPAWANDBG_LOW("Rx packet was received");
1222 skb->dev = IPA_NETDEV();
1223 skb->protocol = htons(ETH_P_MAP);
1224
1225 if (ipa3_rmnet_res.ipa_napi_enable) {
1226 trace_rmnet_ipa_netif_rcv_skb3(dev->stats.rx_packets);
1227 result = netif_receive_skb(skb);
1228 } else {
1229 if (dev->stats.rx_packets % IPA_WWAN_RX_SOFTIRQ_THRESH
1230 == 0) {
1231 trace_rmnet_ipa_netifni3(dev->stats.rx_packets);
1232 result = netif_rx_ni(skb);
1233 } else {
1234 trace_rmnet_ipa_netifrx3(dev->stats.rx_packets);
1235 result = netif_rx(skb);
1236 }
1237 }
1238
1239 if (result) {
1240 pr_err_ratelimited(DEV_NAME " %s:%d fail on netif_receive_skb\n",
1241 __func__, __LINE__);
1242 dev->stats.rx_dropped++;
1243 }
1244 dev->stats.rx_packets++;
1245 dev->stats.rx_bytes += packet_len;
1246 } else if (evt == IPA_CLIENT_START_POLL)
1247 ipa3_rmnet_rx_cb(priv);
1248 else if (evt == IPA_CLIENT_COMP_NAPI) {
1249 if (ipa3_rmnet_res.ipa_napi_enable)
1250 napi_complete(&(rmnet_ipa3_ctx->wwan_priv->napi));
1251 } else
1252 IPAWANERR("Invalid evt %d received in wan_ipa_receive\n", evt);
1253}
1254
Gidon Studinski3021a6f2016-11-10 12:48:48 +02001255static int handle3_ingress_format(struct net_device *dev,
1256 struct rmnet_ioctl_extended_s *in)
1257{
1258 int ret = 0;
1259 struct ipa_sys_connect_params *ipa_wan_ep_cfg;
1260 struct rmnet_phys_ep_conf_s *ep_cfg;
1261
1262 IPAWANDBG("Get RMNET_IOCTL_SET_INGRESS_DATA_FORMAT\n");
1263 ipa_wan_ep_cfg = &rmnet_ipa3_ctx->ipa_to_apps_ep_cfg;
1264 if ((in->u.data) & RMNET_IOCTL_INGRESS_FORMAT_CHECKSUM)
1265 ipa_wan_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
1266 IPA_ENABLE_CS_OFFLOAD_DL;
1267
1268 if ((in->u.data) & RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA) {
Ghanim Fodic6b67492017-03-15 14:19:56 +02001269 IPAWANDBG("get AGG size %d count %d\n",
Gidon Studinski3021a6f2016-11-10 12:48:48 +02001270 in->u.ingress_format.agg_size,
1271 in->u.ingress_format.agg_count);
1272
1273 ret = ipa_disable_apps_wan_cons_deaggr(
1274 in->u.ingress_format.agg_size,
1275 in->u.ingress_format.agg_count);
1276
1277 if (!ret) {
1278 ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_byte_limit =
1279 in->u.ingress_format.agg_size;
1280 ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_pkt_limit =
1281 in->u.ingress_format.agg_count;
1282
1283 if (ipa_wan_ep_cfg->napi_enabled) {
1284 ipa_wan_ep_cfg->recycle_enabled = true;
1285 ep_cfg = (struct rmnet_phys_ep_conf_s *)
1286 rcu_dereference(dev->rx_handler_data);
1287 ep_cfg->recycle = ipa_recycle_wan_skb;
1288 pr_info("Wan Recycle Enabled\n");
1289 }
1290 }
1291 }
1292
1293 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 4;
1294 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
1295 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata = 1;
1296 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1;
1297 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 2;
1298
1299 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_valid = true;
1300 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad = 0;
1301 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_payload_len_inc_padding = true;
1302 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_offset = 0;
1303 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_little_endian = 0;
1304 ipa_wan_ep_cfg->ipa_ep_cfg.metadata_mask.metadata_mask = 0xFF000000;
1305
1306 ipa_wan_ep_cfg->client = IPA_CLIENT_APPS_WAN_CONS;
1307 ipa_wan_ep_cfg->notify = apps_ipa_packet_receive_notify;
1308 ipa_wan_ep_cfg->priv = dev;
1309
1310 ipa_wan_ep_cfg->napi_enabled = ipa3_rmnet_res.ipa_napi_enable;
1311 if (ipa_wan_ep_cfg->napi_enabled)
1312 ipa_wan_ep_cfg->desc_fifo_sz = IPA_WAN_CONS_DESC_FIFO_SZ;
1313 else
1314 ipa_wan_ep_cfg->desc_fifo_sz = IPA_SYS_DESC_FIFO_SZ;
1315
Ghanim Fodic6b67492017-03-15 14:19:56 +02001316 mutex_lock(&rmnet_ipa3_ctx->pipe_handle_guard);
Gidon Studinski3021a6f2016-11-10 12:48:48 +02001317
1318 if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
1319 IPAWANDBG("In SSR sequence/recovery\n");
Ghanim Fodic6b67492017-03-15 14:19:56 +02001320 mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
Gidon Studinski3021a6f2016-11-10 12:48:48 +02001321 return -EFAULT;
1322 }
1323 ret = ipa3_setup_sys_pipe(&rmnet_ipa3_ctx->ipa_to_apps_ep_cfg,
1324 &rmnet_ipa3_ctx->ipa3_to_apps_hdl);
1325
Ghanim Fodic6b67492017-03-15 14:19:56 +02001326 mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
Gidon Studinski3021a6f2016-11-10 12:48:48 +02001327
1328 if (ret)
1329 IPAWANERR("failed to configure ingress\n");
1330
1331 return ret;
1332}
1333
Amir Levy9659e592016-10-27 18:08:27 +03001334/**
Ghanim Fodic6b67492017-03-15 14:19:56 +02001335 * handle3_egress_format() - Egress data format configuration
1336 *
1337 * Setup IPA egress system pipe and Configure:
1338 * header handling, checksum, de-aggregation and fifo size
1339 *
1340 * @dev: network device
1341 * @e: egress configuration
1342 */
1343static int handle3_egress_format(struct net_device *dev,
1344 struct rmnet_ioctl_extended_s *e)
1345{
1346 int rc;
1347 struct ipa_sys_connect_params *ipa_wan_ep_cfg;
1348
1349 IPAWANDBG("get RMNET_IOCTL_SET_EGRESS_DATA_FORMAT\n");
1350 ipa_wan_ep_cfg = &rmnet_ipa3_ctx->apps_to_ipa_ep_cfg;
1351 if ((e->u.data) & RMNET_IOCTL_EGRESS_FORMAT_CHECKSUM) {
1352 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 8;
1353 ipa_wan_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en =
1354 IPA_ENABLE_CS_OFFLOAD_UL;
1355 ipa_wan_ep_cfg->ipa_ep_cfg.cfg.cs_metadata_hdr_offset = 1;
1356 } else {
1357 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_len = 4;
1358 }
1359
1360 if ((e->u.data) & RMNET_IOCTL_EGRESS_FORMAT_AGGREGATION) {
1361 IPAWANERR("WAN UL Aggregation not supported!!\n");
1362 WARN_ON(1);
1363 return -EINVAL;
1364 ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_en = IPA_ENABLE_DEAGGR;
1365 ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr = IPA_QCMAP;
1366
1367 ipa_wan_ep_cfg->ipa_ep_cfg.deaggr.packet_offset_valid = false;
1368
1369 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 2;
1370
1371 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_valid =
1372 true;
1373 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad =
1374 IPA_HDR_PAD;
1375 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_pad_to_alignment =
1376 2;
1377 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_payload_len_inc_padding =
1378 true;
1379 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_total_len_or_pad_offset =
1380 0;
1381 ipa_wan_ep_cfg->ipa_ep_cfg.hdr_ext.hdr_little_endian =
1382 false;
1383 } else {
1384 IPAWANDBG("WAN UL Aggregation disabled\n");
1385 ipa_wan_ep_cfg->ipa_ep_cfg.aggr.aggr_en = IPA_BYPASS_AGGR;
1386 }
1387
1388 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
1389 /* modem want offset at 0! */
1390 ipa_wan_ep_cfg->ipa_ep_cfg.hdr.hdr_ofst_metadata = 0;
1391
1392 ipa_wan_ep_cfg->ipa_ep_cfg.mode.dst = IPA_CLIENT_APPS_WAN_PROD;
1393 ipa_wan_ep_cfg->ipa_ep_cfg.mode.mode = IPA_BASIC;
1394
1395 ipa_wan_ep_cfg->client = IPA_CLIENT_APPS_WAN_PROD;
1396 ipa_wan_ep_cfg->notify = apps_ipa_tx_complete_notify;
1397 ipa_wan_ep_cfg->desc_fifo_sz = IPA_SYS_TX_DATA_DESC_FIFO_SZ;
1398 ipa_wan_ep_cfg->priv = dev;
1399
1400 mutex_lock(&rmnet_ipa3_ctx->pipe_handle_guard);
1401 if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
1402 IPAWANDBG("In SSR sequence/recovery\n");
1403 mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
1404 return -EFAULT;
1405 }
1406 rc = ipa3_setup_sys_pipe(
1407 ipa_wan_ep_cfg, &rmnet_ipa3_ctx->apps_to_ipa3_hdl);
1408 if (rc) {
1409 IPAWANERR("failed to config egress endpoint\n");
1410 mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
1411 return rc;
1412 }
1413 mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
1414
1415 if (rmnet_ipa3_ctx->num_q6_rules != 0) {
1416 /* already got Q6 UL filter rules*/
1417 if (ipa3_qmi_ctx->modem_cfg_emb_pipe_flt == false)
1418 rc = ipa3_wwan_add_ul_flt_rule_to_ipa();
1419 if (rc)
1420 IPAWANERR("install UL rules failed\n");
1421 else
1422 rmnet_ipa3_ctx->a7_ul_flt_set = true;
1423 } else {
1424 /* wait Q6 UL filter rules*/
1425 IPAWANDBG("no UL-rules\n");
1426 }
1427 rmnet_ipa3_ctx->egress_set = true;
1428
1429 return rc;
1430}
1431
1432/**
Amir Levy9659e592016-10-27 18:08:27 +03001433 * ipa3_wwan_ioctl() - I/O control for wwan network driver.
1434 *
1435 * @dev: network device
1436 * @ifr: ignored
1437 * @cmd: cmd to be excecuded. can be one of the following:
1438 * IPA_WWAN_IOCTL_OPEN - Open the network interface
1439 * IPA_WWAN_IOCTL_CLOSE - Close the network interface
1440 *
1441 * Return codes:
1442 * 0: success
1443 * NETDEV_TX_BUSY: Error while transmitting the skb. Try again
1444 * later
1445 * -EFAULT: Error while transmitting the skb
1446 */
1447static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1448{
1449 int rc = 0;
1450 int mru = 1000, epid = 1, mux_index, len;
1451 struct ipa_msg_meta msg_meta;
1452 struct ipa_wan_msg *wan_msg = NULL;
1453 struct rmnet_ioctl_extended_s extend_ioctl_data;
1454 struct rmnet_ioctl_data_s ioctl_data;
1455 struct ipa3_rmnet_mux_val *mux_channel;
1456 int rmnet_index;
1457
1458 IPAWANDBG("rmnet_ipa got ioctl number 0x%08x", cmd);
1459 switch (cmd) {
1460 /* Set Ethernet protocol */
1461 case RMNET_IOCTL_SET_LLP_ETHERNET:
1462 break;
1463 /* Set RAWIP protocol */
1464 case RMNET_IOCTL_SET_LLP_IP:
1465 break;
1466 /* Get link protocol */
1467 case RMNET_IOCTL_GET_LLP:
1468 ioctl_data.u.operation_mode = RMNET_MODE_LLP_IP;
1469 if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
1470 sizeof(struct rmnet_ioctl_data_s)))
1471 rc = -EFAULT;
1472 break;
1473 /* Set QoS header enabled */
1474 case RMNET_IOCTL_SET_QOS_ENABLE:
1475 return -EINVAL;
1476 /* Set QoS header disabled */
1477 case RMNET_IOCTL_SET_QOS_DISABLE:
1478 break;
1479 /* Get QoS header state */
1480 case RMNET_IOCTL_GET_QOS:
1481 ioctl_data.u.operation_mode = RMNET_MODE_NONE;
1482 if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
1483 sizeof(struct rmnet_ioctl_data_s)))
1484 rc = -EFAULT;
1485 break;
1486 /* Get operation mode */
1487 case RMNET_IOCTL_GET_OPMODE:
1488 ioctl_data.u.operation_mode = RMNET_MODE_LLP_IP;
1489 if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
1490 sizeof(struct rmnet_ioctl_data_s)))
1491 rc = -EFAULT;
1492 break;
1493 /* Open transport port */
1494 case RMNET_IOCTL_OPEN:
1495 break;
1496 /* Close transport port */
1497 case RMNET_IOCTL_CLOSE:
1498 break;
1499 /* Flow enable */
1500 case RMNET_IOCTL_FLOW_ENABLE:
1501 IPAWANDBG("Received flow enable\n");
1502 if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
1503 sizeof(struct rmnet_ioctl_data_s))) {
1504 rc = -EFAULT;
1505 break;
1506 }
1507 ipa3_flow_control(IPA_CLIENT_USB_PROD, true,
1508 ioctl_data.u.tcm_handle);
1509 break;
1510 /* Flow disable */
1511 case RMNET_IOCTL_FLOW_DISABLE:
1512 IPAWANDBG("Received flow disable\n");
1513 if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
1514 sizeof(struct rmnet_ioctl_data_s))) {
1515 rc = -EFAULT;
1516 break;
1517 }
1518 ipa3_flow_control(IPA_CLIENT_USB_PROD, false,
1519 ioctl_data.u.tcm_handle);
1520 break;
1521 /* Set flow handle */
1522 case RMNET_IOCTL_FLOW_SET_HNDL:
1523 break;
1524
1525 /* Extended IOCTLs */
1526 case RMNET_IOCTL_EXTENDED:
1527 IPAWANDBG("get ioctl: RMNET_IOCTL_EXTENDED\n");
1528 if (copy_from_user(&extend_ioctl_data,
1529 (u8 *)ifr->ifr_ifru.ifru_data,
1530 sizeof(struct rmnet_ioctl_extended_s))) {
1531 IPAWANERR("failed to copy extended ioctl data\n");
1532 rc = -EFAULT;
1533 break;
1534 }
1535 switch (extend_ioctl_data.extended_ioctl) {
1536 /* Get features */
1537 case RMNET_IOCTL_GET_SUPPORTED_FEATURES:
1538 IPAWANDBG("get RMNET_IOCTL_GET_SUPPORTED_FEATURES\n");
1539 extend_ioctl_data.u.data =
1540 (RMNET_IOCTL_FEAT_NOTIFY_MUX_CHANNEL |
1541 RMNET_IOCTL_FEAT_SET_EGRESS_DATA_FORMAT |
1542 RMNET_IOCTL_FEAT_SET_INGRESS_DATA_FORMAT);
1543 if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
1544 &extend_ioctl_data,
1545 sizeof(struct rmnet_ioctl_extended_s)))
1546 rc = -EFAULT;
1547 break;
1548 /* Set MRU */
1549 case RMNET_IOCTL_SET_MRU:
1550 mru = extend_ioctl_data.u.data;
1551 IPAWANDBG("get MRU size %d\n",
1552 extend_ioctl_data.u.data);
1553 break;
1554 /* Get MRU */
1555 case RMNET_IOCTL_GET_MRU:
1556 extend_ioctl_data.u.data = mru;
1557 if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
1558 &extend_ioctl_data,
1559 sizeof(struct rmnet_ioctl_extended_s)))
1560 rc = -EFAULT;
1561 break;
1562 /* GET SG support */
1563 case RMNET_IOCTL_GET_SG_SUPPORT:
1564 extend_ioctl_data.u.data =
1565 ipa3_rmnet_res.ipa_advertise_sg_support;
1566 if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
1567 &extend_ioctl_data,
1568 sizeof(struct rmnet_ioctl_extended_s)))
1569 rc = -EFAULT;
1570 break;
1571 /* Get endpoint ID */
1572 case RMNET_IOCTL_GET_EPID:
1573 IPAWANDBG("get ioctl: RMNET_IOCTL_GET_EPID\n");
1574 extend_ioctl_data.u.data = epid;
1575 if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
1576 &extend_ioctl_data,
1577 sizeof(struct rmnet_ioctl_extended_s)))
1578 rc = -EFAULT;
1579 if (copy_from_user(&extend_ioctl_data,
1580 (u8 *)ifr->ifr_ifru.ifru_data,
1581 sizeof(struct rmnet_ioctl_extended_s))) {
1582 IPAWANERR("copy extended ioctl data failed\n");
1583 rc = -EFAULT;
1584 break;
1585 }
1586 IPAWANDBG("RMNET_IOCTL_GET_EPID return %d\n",
1587 extend_ioctl_data.u.data);
1588 break;
1589 /* Endpoint pair */
1590 case RMNET_IOCTL_GET_EP_PAIR:
1591 IPAWANDBG("get ioctl: RMNET_IOCTL_GET_EP_PAIR\n");
1592 extend_ioctl_data.u.ipa_ep_pair.consumer_pipe_num =
Ghanim Fodic6b67492017-03-15 14:19:56 +02001593 ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_PROD);
Amir Levy9659e592016-10-27 18:08:27 +03001594 extend_ioctl_data.u.ipa_ep_pair.producer_pipe_num =
1595 ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS);
1596 if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
1597 &extend_ioctl_data,
1598 sizeof(struct rmnet_ioctl_extended_s)))
1599 rc = -EFAULT;
1600 if (copy_from_user(&extend_ioctl_data,
1601 (u8 *)ifr->ifr_ifru.ifru_data,
1602 sizeof(struct rmnet_ioctl_extended_s))) {
1603 IPAWANERR("copy extended ioctl data failed\n");
1604 rc = -EFAULT;
1605 break;
1606 }
1607 IPAWANDBG("RMNET_IOCTL_GET_EP_PAIR c: %d p: %d\n",
1608 extend_ioctl_data.u.ipa_ep_pair.consumer_pipe_num,
1609 extend_ioctl_data.u.ipa_ep_pair.producer_pipe_num);
1610 break;
1611 /* Get driver name */
1612 case RMNET_IOCTL_GET_DRIVER_NAME:
1613 memcpy(&extend_ioctl_data.u.if_name,
1614 IPA_NETDEV()->name,
1615 sizeof(IFNAMSIZ));
1616 if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
1617 &extend_ioctl_data,
1618 sizeof(struct rmnet_ioctl_extended_s)))
1619 rc = -EFAULT;
1620 break;
1621 /* Add MUX ID */
1622 case RMNET_IOCTL_ADD_MUX_CHANNEL:
1623 mux_index = ipa3_find_mux_channel_index(
1624 extend_ioctl_data.u.rmnet_mux_val.mux_id);
1625 if (mux_index < MAX_NUM_OF_MUX_CHANNEL) {
1626 IPAWANDBG("already setup mux(%d)\n",
1627 extend_ioctl_data.u.
1628 rmnet_mux_val.mux_id);
1629 return rc;
1630 }
1631 if (rmnet_ipa3_ctx->rmnet_index
1632 >= MAX_NUM_OF_MUX_CHANNEL) {
1633 IPAWANERR("Exceed mux_channel limit(%d)\n",
1634 rmnet_ipa3_ctx->rmnet_index);
1635 return -EFAULT;
1636 }
1637 IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n",
1638 extend_ioctl_data.u.rmnet_mux_val.mux_id,
1639 extend_ioctl_data.u.rmnet_mux_val.vchannel_name);
1640 /* cache the mux name and id */
1641 mux_channel = rmnet_ipa3_ctx->mux_channel;
1642 rmnet_index = rmnet_ipa3_ctx->rmnet_index;
1643
1644 mux_channel[rmnet_index].mux_id =
1645 extend_ioctl_data.u.rmnet_mux_val.mux_id;
1646 memcpy(mux_channel[rmnet_index].vchannel_name,
1647 extend_ioctl_data.u.rmnet_mux_val.vchannel_name,
1648 sizeof(mux_channel[rmnet_index]
1649 .vchannel_name));
1650 IPAWANDBG("cashe device[%s:%d] in IPA_wan[%d]\n",
1651 mux_channel[rmnet_index].vchannel_name,
1652 mux_channel[rmnet_index].mux_id,
1653 rmnet_index);
1654 /* check if UL filter rules coming*/
1655 if (rmnet_ipa3_ctx->num_q6_rules != 0) {
1656 IPAWANERR("dev(%s) register to IPA\n",
1657 extend_ioctl_data.u.rmnet_mux_val.
1658 vchannel_name);
1659 rc = ipa3_wwan_register_to_ipa(
1660 rmnet_ipa3_ctx->rmnet_index);
1661 if (rc < 0) {
1662 IPAWANERR("device %s reg IPA failed\n",
1663 extend_ioctl_data.u.
1664 rmnet_mux_val.vchannel_name);
1665 return -ENODEV;
1666 }
1667 mux_channel[rmnet_index].mux_channel_set = true;
1668 mux_channel[rmnet_index].ul_flt_reg = true;
1669 } else {
1670 IPAWANDBG("dev(%s) haven't registered to IPA\n",
1671 extend_ioctl_data.u.
1672 rmnet_mux_val.vchannel_name);
1673 mux_channel[rmnet_index].mux_channel_set = true;
1674 mux_channel[rmnet_index].ul_flt_reg = false;
1675 }
1676 rmnet_ipa3_ctx->rmnet_index++;
1677 break;
1678 case RMNET_IOCTL_SET_EGRESS_DATA_FORMAT:
Ghanim Fodic6b67492017-03-15 14:19:56 +02001679 rc = handle3_egress_format(dev, &extend_ioctl_data);
Amir Levy9659e592016-10-27 18:08:27 +03001680 break;
1681 case RMNET_IOCTL_SET_INGRESS_DATA_FORMAT:/* Set IDF */
Gidon Studinski3021a6f2016-11-10 12:48:48 +02001682 rc = handle3_ingress_format(dev, &extend_ioctl_data);
Amir Levy9659e592016-10-27 18:08:27 +03001683 break;
1684 case RMNET_IOCTL_SET_XLAT_DEV_INFO:
1685 wan_msg = kzalloc(sizeof(struct ipa_wan_msg),
1686 GFP_KERNEL);
1687 if (!wan_msg) {
1688 IPAWANERR("Failed to allocate memory.\n");
1689 return -ENOMEM;
1690 }
1691 len = sizeof(wan_msg->upstream_ifname) >
1692 sizeof(extend_ioctl_data.u.if_name) ?
1693 sizeof(extend_ioctl_data.u.if_name) :
1694 sizeof(wan_msg->upstream_ifname);
1695 strlcpy(wan_msg->upstream_ifname,
1696 extend_ioctl_data.u.if_name, len);
1697 memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
1698 msg_meta.msg_type = WAN_XLAT_CONNECT;
1699 msg_meta.msg_len = sizeof(struct ipa_wan_msg);
1700 rc = ipa3_send_msg(&msg_meta, wan_msg,
1701 ipa3_wwan_msg_free_cb);
1702 if (rc) {
1703 IPAWANERR("Failed to send XLAT_CONNECT msg\n");
1704 kfree(wan_msg);
1705 }
1706 break;
1707 /* Get agg count */
1708 case RMNET_IOCTL_GET_AGGREGATION_COUNT:
1709 break;
1710 /* Set agg count */
1711 case RMNET_IOCTL_SET_AGGREGATION_COUNT:
1712 break;
1713 /* Get agg size */
1714 case RMNET_IOCTL_GET_AGGREGATION_SIZE:
1715 break;
1716 /* Set agg size */
1717 case RMNET_IOCTL_SET_AGGREGATION_SIZE:
1718 break;
1719 /* Do flow control */
1720 case RMNET_IOCTL_FLOW_CONTROL:
1721 break;
1722 /* For legacy use */
1723 case RMNET_IOCTL_GET_DFLT_CONTROL_CHANNEL:
1724 break;
1725 /* Get HW/SW map */
1726 case RMNET_IOCTL_GET_HWSW_MAP:
1727 break;
1728 /* Set RX Headroom */
1729 case RMNET_IOCTL_SET_RX_HEADROOM:
1730 break;
1731 default:
1732 IPAWANERR("[%s] unsupported extended cmd[%d]",
1733 dev->name,
1734 extend_ioctl_data.extended_ioctl);
1735 rc = -EINVAL;
1736 }
1737 break;
1738 default:
1739 IPAWANERR("[%s] unsupported cmd[%d]",
1740 dev->name, cmd);
1741 rc = -EINVAL;
1742 }
1743 return rc;
1744}
1745
1746static const struct net_device_ops ipa3_wwan_ops_ip = {
1747 .ndo_open = ipa3_wwan_open,
1748 .ndo_stop = ipa3_wwan_stop,
1749 .ndo_start_xmit = ipa3_wwan_xmit,
1750 .ndo_tx_timeout = ipa3_wwan_tx_timeout,
1751 .ndo_do_ioctl = ipa3_wwan_ioctl,
1752 .ndo_change_mtu = ipa3_wwan_change_mtu,
1753 .ndo_set_mac_address = 0,
1754 .ndo_validate_addr = 0,
1755};
1756
1757/**
1758 * wwan_setup() - Setups the wwan network driver.
1759 *
1760 * @dev: network device
1761 *
1762 * Return codes:
1763 * None
1764 */
1765
1766static void ipa3_wwan_setup(struct net_device *dev)
1767{
1768 dev->netdev_ops = &ipa3_wwan_ops_ip;
1769 ether_setup(dev);
1770 /* set this after calling ether_setup */
1771 dev->header_ops = 0; /* No header */
1772 dev->type = ARPHRD_RAWIP;
1773 dev->hard_header_len = 0;
1774 dev->mtu = WWAN_DATA_LEN;
1775 dev->addr_len = 0;
1776 dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
1777 dev->needed_headroom = HEADROOM_FOR_QMAP;
1778 dev->needed_tailroom = TAILROOM;
1779 dev->watchdog_timeo = 1000;
1780}
1781
1782/* IPA_RM related functions start*/
1783static void ipa3_q6_prod_rm_request_resource(struct work_struct *work);
1784static DECLARE_DELAYED_WORK(ipa3_q6_con_rm_request,
1785 ipa3_q6_prod_rm_request_resource);
1786static void ipa3_q6_prod_rm_release_resource(struct work_struct *work);
1787static DECLARE_DELAYED_WORK(ipa3_q6_con_rm_release,
1788 ipa3_q6_prod_rm_release_resource);
1789
1790static void ipa3_q6_prod_rm_request_resource(struct work_struct *work)
1791{
1792 int ret = 0;
1793
1794 ret = ipa_rm_request_resource(IPA_RM_RESOURCE_Q6_PROD);
1795 if (ret < 0 && ret != -EINPROGRESS) {
1796 IPAWANERR("%s: ipa_rm_request_resource failed %d\n", __func__,
1797 ret);
1798 return;
1799 }
1800}
1801
1802static int ipa3_q6_rm_request_resource(void)
1803{
1804 queue_delayed_work(rmnet_ipa3_ctx->rm_q6_wq,
1805 &ipa3_q6_con_rm_request, 0);
1806 return 0;
1807}
1808
1809static void ipa3_q6_prod_rm_release_resource(struct work_struct *work)
1810{
1811 int ret = 0;
1812
1813 ret = ipa_rm_release_resource(IPA_RM_RESOURCE_Q6_PROD);
1814 if (ret < 0 && ret != -EINPROGRESS) {
1815 IPAWANERR("%s: ipa_rm_release_resource failed %d\n", __func__,
1816 ret);
1817 return;
1818 }
1819}
1820
1821
1822static int ipa3_q6_rm_release_resource(void)
1823{
1824 queue_delayed_work(rmnet_ipa3_ctx->rm_q6_wq,
1825 &ipa3_q6_con_rm_release, 0);
1826 return 0;
1827}
1828
1829
1830static void ipa3_q6_rm_notify_cb(void *user_data,
1831 enum ipa_rm_event event,
1832 unsigned long data)
1833{
1834 switch (event) {
1835 case IPA_RM_RESOURCE_GRANTED:
1836 IPAWANDBG_LOW("%s: Q6_PROD GRANTED CB\n", __func__);
1837 break;
1838 case IPA_RM_RESOURCE_RELEASED:
1839 IPAWANDBG_LOW("%s: Q6_PROD RELEASED CB\n", __func__);
1840 break;
1841 default:
1842 return;
1843 }
1844}
1845static int ipa3_q6_initialize_rm(void)
1846{
1847 struct ipa_rm_create_params create_params;
1848 struct ipa_rm_perf_profile profile;
1849 int result;
1850
1851 /* Initialize IPA_RM workqueue */
1852 rmnet_ipa3_ctx->rm_q6_wq = create_singlethread_workqueue("clnt_req");
1853 if (!rmnet_ipa3_ctx->rm_q6_wq)
1854 return -ENOMEM;
1855
1856 memset(&create_params, 0, sizeof(create_params));
1857 create_params.name = IPA_RM_RESOURCE_Q6_PROD;
1858 create_params.reg_params.notify_cb = &ipa3_q6_rm_notify_cb;
1859 result = ipa_rm_create_resource(&create_params);
1860 if (result)
1861 goto create_rsrc_err1;
1862 memset(&create_params, 0, sizeof(create_params));
1863 create_params.name = IPA_RM_RESOURCE_Q6_CONS;
1864 create_params.release_resource = &ipa3_q6_rm_release_resource;
1865 create_params.request_resource = &ipa3_q6_rm_request_resource;
1866 result = ipa_rm_create_resource(&create_params);
1867 if (result)
1868 goto create_rsrc_err2;
1869 /* add dependency*/
1870 result = ipa_rm_add_dependency(IPA_RM_RESOURCE_Q6_PROD,
1871 IPA_RM_RESOURCE_APPS_CONS);
1872 if (result)
1873 goto add_dpnd_err;
1874 /* setup Performance profile */
1875 memset(&profile, 0, sizeof(profile));
1876 profile.max_supported_bandwidth_mbps = 100;
1877 result = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_Q6_PROD,
1878 &profile);
1879 if (result)
1880 goto set_perf_err;
1881 result = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_Q6_CONS,
1882 &profile);
1883 if (result)
1884 goto set_perf_err;
1885 return result;
1886
1887set_perf_err:
1888 ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
1889 IPA_RM_RESOURCE_APPS_CONS);
1890add_dpnd_err:
1891 result = ipa_rm_delete_resource(IPA_RM_RESOURCE_Q6_CONS);
1892 if (result < 0)
1893 IPAWANERR("Error deleting resource %d, ret=%d\n",
1894 IPA_RM_RESOURCE_Q6_CONS, result);
1895create_rsrc_err2:
1896 result = ipa_rm_delete_resource(IPA_RM_RESOURCE_Q6_PROD);
1897 if (result < 0)
1898 IPAWANERR("Error deleting resource %d, ret=%d\n",
1899 IPA_RM_RESOURCE_Q6_PROD, result);
1900create_rsrc_err1:
1901 destroy_workqueue(rmnet_ipa3_ctx->rm_q6_wq);
1902 return result;
1903}
1904
1905void ipa3_q6_deinitialize_rm(void)
1906{
1907 int ret;
1908
1909 ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
1910 IPA_RM_RESOURCE_APPS_CONS);
1911 if (ret < 0)
1912 IPAWANERR("Error deleting dependency %d->%d, ret=%d\n",
1913 IPA_RM_RESOURCE_Q6_PROD, IPA_RM_RESOURCE_APPS_CONS,
1914 ret);
1915 ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_Q6_CONS);
1916 if (ret < 0)
1917 IPAWANERR("Error deleting resource %d, ret=%d\n",
1918 IPA_RM_RESOURCE_Q6_CONS, ret);
1919 ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_Q6_PROD);
1920 if (ret < 0)
1921 IPAWANERR("Error deleting resource %d, ret=%d\n",
1922 IPA_RM_RESOURCE_Q6_PROD, ret);
1923 destroy_workqueue(rmnet_ipa3_ctx->rm_q6_wq);
1924}
1925
1926static void ipa3_wake_tx_queue(struct work_struct *work)
1927{
1928 if (IPA_NETDEV()) {
1929 __netif_tx_lock_bh(netdev_get_tx_queue(IPA_NETDEV(), 0));
1930 netif_wake_queue(IPA_NETDEV());
1931 __netif_tx_unlock_bh(netdev_get_tx_queue(IPA_NETDEV(), 0));
1932 }
1933}
1934
1935/**
1936 * ipa3_rm_resource_granted() - Called upon
1937 * IPA_RM_RESOURCE_GRANTED event. Wakes up queue is was stopped.
1938 *
1939 * @work: work object supplied ny workqueue
1940 *
1941 * Return codes:
1942 * None
1943 */
1944static void ipa3_rm_resource_granted(void *dev)
1945{
1946 IPAWANDBG_LOW("Resource Granted - starting queue\n");
1947 schedule_work(&ipa3_tx_wakequeue_work);
1948}
1949
1950/**
1951 * ipa3_rm_notify() - Callback function for RM events. Handles
1952 * IPA_RM_RESOURCE_GRANTED and IPA_RM_RESOURCE_RELEASED events.
1953 * IPA_RM_RESOURCE_GRANTED is handled in the context of shared
1954 * workqueue.
1955 *
1956 * @dev: network device
1957 * @event: IPA RM event
1958 * @data: Additional data provided by IPA RM
1959 *
1960 * Return codes:
1961 * None
1962 */
1963static void ipa3_rm_notify(void *dev, enum ipa_rm_event event,
1964 unsigned long data)
1965{
1966 struct ipa3_wwan_private *wwan_ptr = netdev_priv(dev);
1967
1968 pr_debug("%s: event %d\n", __func__, event);
1969 switch (event) {
1970 case IPA_RM_RESOURCE_GRANTED:
1971 if (wwan_ptr->device_status == WWAN_DEVICE_INACTIVE) {
1972 complete_all(&wwan_ptr->resource_granted_completion);
1973 break;
1974 }
1975 ipa3_rm_resource_granted(dev);
1976 break;
1977 case IPA_RM_RESOURCE_RELEASED:
1978 break;
1979 default:
1980 pr_err("%s: unknown event %d\n", __func__, event);
1981 break;
1982 }
1983}
1984
1985/* IPA_RM related functions end*/
1986
1987static int ipa3_ssr_notifier_cb(struct notifier_block *this,
1988 unsigned long code,
1989 void *data);
1990
1991static struct notifier_block ipa3_ssr_notifier = {
1992 .notifier_call = ipa3_ssr_notifier_cb,
1993};
1994
1995static int get_ipa_rmnet_dts_configuration(struct platform_device *pdev,
1996 struct ipa3_rmnet_plat_drv_res *ipa_rmnet_drv_res)
1997{
1998 ipa_rmnet_drv_res->ipa_rmnet_ssr =
1999 of_property_read_bool(pdev->dev.of_node,
2000 "qcom,rmnet-ipa-ssr");
2001 pr_info("IPA SSR support = %s\n",
2002 ipa_rmnet_drv_res->ipa_rmnet_ssr ? "True" : "False");
2003 ipa_rmnet_drv_res->ipa_loaduC =
2004 of_property_read_bool(pdev->dev.of_node,
2005 "qcom,ipa-loaduC");
2006 pr_info("IPA ipa-loaduC = %s\n",
2007 ipa_rmnet_drv_res->ipa_loaduC ? "True" : "False");
2008
2009 ipa_rmnet_drv_res->ipa_advertise_sg_support =
2010 of_property_read_bool(pdev->dev.of_node,
2011 "qcom,ipa-advertise-sg-support");
2012 pr_info("IPA SG support = %s\n",
2013 ipa_rmnet_drv_res->ipa_advertise_sg_support ? "True" : "False");
Gidon Studinski3021a6f2016-11-10 12:48:48 +02002014
2015 ipa_rmnet_drv_res->ipa_napi_enable =
2016 of_property_read_bool(pdev->dev.of_node,
2017 "qcom,ipa-napi-enable");
2018 pr_info("IPA Napi Enable = %s\n",
2019 ipa_rmnet_drv_res->ipa_napi_enable ? "True" : "False");
Amir Levy9659e592016-10-27 18:08:27 +03002020 return 0;
2021}
2022
2023struct ipa3_rmnet_context ipa3_rmnet_ctx;
2024static int ipa3_wwan_probe(struct platform_device *pdev);
2025struct platform_device *m_pdev;
2026
2027static void ipa3_delayed_probe(struct work_struct *work)
2028{
2029 (void)ipa3_wwan_probe(m_pdev);
2030}
2031
2032static DECLARE_WORK(ipa3_scheduled_probe, ipa3_delayed_probe);
2033
2034static void ipa3_ready_cb(void *user_data)
2035{
2036 struct platform_device *pdev = (struct platform_device *)(user_data);
2037
2038 m_pdev = pdev;
2039
2040 IPAWANDBG("IPA ready callback has been triggered!\n");
2041
2042 schedule_work(&ipa3_scheduled_probe);
2043}
2044
2045/**
2046 * ipa3_wwan_probe() - Initialized the module and registers as a
2047 * network interface to the network stack
2048 *
2049 * Note: In case IPA driver hasn't initialized already, the probe function
2050 * will return immediately after registering a callback to be invoked when
2051 * IPA driver initialization is complete.
2052 *
2053 * Return codes:
2054 * 0: success
2055 * -ENOMEM: No memory available
2056 * -EFAULT: Internal error
2057 */
2058static int ipa3_wwan_probe(struct platform_device *pdev)
2059{
2060 int ret, i;
2061 struct net_device *dev;
2062 struct ipa_rm_create_params ipa_rm_params; /* IPA_RM */
2063 struct ipa_rm_perf_profile profile; /* IPA_RM */
2064
2065 pr_info("rmnet_ipa3 started initialization\n");
2066
2067 if (!ipa3_is_ready()) {
2068 IPAWANDBG("IPA driver not ready, registering callback\n");
2069 ret = ipa_register_ipa_ready_cb(ipa3_ready_cb, (void *)pdev);
2070
2071 /*
2072 * If we received -EEXIST, IPA has initialized. So we need
2073 * to continue the probing process.
2074 */
2075 if (ret != -EEXIST) {
2076 if (ret)
2077 IPAWANERR("IPA CB reg failed - %d\n", ret);
2078 return ret;
2079 }
2080 }
2081
2082 ret = get_ipa_rmnet_dts_configuration(pdev, &ipa3_rmnet_res);
2083 ipa3_rmnet_ctx.ipa_rmnet_ssr = ipa3_rmnet_res.ipa_rmnet_ssr;
2084
2085 ret = ipa3_init_q6_smem();
2086 if (ret) {
2087 IPAWANERR("ipa3_init_q6_smem failed!\n");
2088 return ret;
2089 }
2090
2091 /* initialize tx/rx endpoint setup */
2092 memset(&rmnet_ipa3_ctx->apps_to_ipa_ep_cfg, 0,
2093 sizeof(struct ipa_sys_connect_params));
2094 memset(&rmnet_ipa3_ctx->ipa_to_apps_ep_cfg, 0,
2095 sizeof(struct ipa_sys_connect_params));
2096
2097 /* initialize ex property setup */
2098 rmnet_ipa3_ctx->num_q6_rules = 0;
2099 rmnet_ipa3_ctx->old_num_q6_rules = 0;
2100 rmnet_ipa3_ctx->rmnet_index = 0;
2101 rmnet_ipa3_ctx->egress_set = false;
2102 rmnet_ipa3_ctx->a7_ul_flt_set = false;
2103 for (i = 0; i < MAX_NUM_OF_MUX_CHANNEL; i++)
2104 memset(&rmnet_ipa3_ctx->mux_channel[i], 0,
2105 sizeof(struct ipa3_rmnet_mux_val));
2106
2107 /* start A7 QMI service/client */
2108 if (ipa3_rmnet_res.ipa_loaduC)
2109 /* Android platform loads uC */
2110 ipa3_qmi_service_init(QMI_IPA_PLATFORM_TYPE_MSM_ANDROID_V01);
2111 else
2112 /* LE platform not loads uC */
2113 ipa3_qmi_service_init(QMI_IPA_PLATFORM_TYPE_LE_V01);
2114
2115 /* construct default WAN RT tbl for IPACM */
2116 ret = ipa3_setup_a7_qmap_hdr();
2117 if (ret)
2118 goto setup_a7_qmap_hdr_err;
2119 ret = ipa3_setup_dflt_wan_rt_tables();
2120 if (ret)
2121 goto setup_dflt_wan_rt_tables_err;
2122
2123 if (!atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
2124 /* Start transport-driver fd ioctl for ipacm for first init */
2125 ret = ipa3_wan_ioctl_init();
2126 if (ret)
2127 goto wan_ioctl_init_err;
2128 } else {
2129 /* Enable sending QMI messages after SSR */
2130 ipa3_wan_ioctl_enable_qmi_messages();
2131 }
2132
2133 /* initialize wan-driver netdev */
2134 dev = alloc_netdev(sizeof(struct ipa3_wwan_private),
2135 IPA_WWAN_DEV_NAME,
2136 NET_NAME_UNKNOWN,
2137 ipa3_wwan_setup);
2138 if (!dev) {
2139 IPAWANERR("no memory for netdev\n");
2140 ret = -ENOMEM;
2141 goto alloc_netdev_err;
2142 }
2143 rmnet_ipa3_ctx->wwan_priv = netdev_priv(dev);
2144 memset(rmnet_ipa3_ctx->wwan_priv, 0,
2145 sizeof(*(rmnet_ipa3_ctx->wwan_priv)));
2146 IPAWANDBG("wwan_ptr (private) = %p", rmnet_ipa3_ctx->wwan_priv);
2147 rmnet_ipa3_ctx->wwan_priv->net = dev;
2148 rmnet_ipa3_ctx->wwan_priv->outstanding_high = DEFAULT_OUTSTANDING_HIGH;
2149 rmnet_ipa3_ctx->wwan_priv->outstanding_low = DEFAULT_OUTSTANDING_LOW;
2150 atomic_set(&rmnet_ipa3_ctx->wwan_priv->outstanding_pkts, 0);
2151 spin_lock_init(&rmnet_ipa3_ctx->wwan_priv->lock);
2152 init_completion(
2153 &rmnet_ipa3_ctx->wwan_priv->resource_granted_completion);
2154
2155 if (!atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
2156 /* IPA_RM configuration starts */
2157 ret = ipa3_q6_initialize_rm();
2158 if (ret) {
2159 IPAWANERR("%s: ipa3_q6_initialize_rm failed, ret: %d\n",
2160 __func__, ret);
2161 goto q6_init_err;
2162 }
2163 }
2164
2165 memset(&ipa_rm_params, 0, sizeof(struct ipa_rm_create_params));
2166 ipa_rm_params.name = IPA_RM_RESOURCE_WWAN_0_PROD;
2167 ipa_rm_params.reg_params.user_data = dev;
2168 ipa_rm_params.reg_params.notify_cb = ipa3_rm_notify;
2169 ret = ipa_rm_create_resource(&ipa_rm_params);
2170 if (ret) {
2171 pr_err("%s: unable to create resourse %d in IPA RM\n",
2172 __func__, IPA_RM_RESOURCE_WWAN_0_PROD);
2173 goto create_rsrc_err;
2174 }
2175 ret = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_WWAN_0_PROD,
2176 IPA_RM_INACTIVITY_TIMER);
2177 if (ret) {
2178 pr_err("%s: ipa rm timer init failed %d on resourse %d\n",
2179 __func__, ret, IPA_RM_RESOURCE_WWAN_0_PROD);
2180 goto timer_init_err;
2181 }
2182 /* add dependency */
2183 ret = ipa_rm_add_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
2184 IPA_RM_RESOURCE_Q6_CONS);
2185 if (ret)
2186 goto add_dpnd_err;
2187 /* setup Performance profile */
2188 memset(&profile, 0, sizeof(profile));
2189 profile.max_supported_bandwidth_mbps = IPA_APPS_MAX_BW_IN_MBPS;
2190 ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_WWAN_0_PROD,
2191 &profile);
2192 if (ret)
2193 goto set_perf_err;
2194 /* IPA_RM configuration ends */
2195
2196 /* Enable SG support in netdevice. */
2197 if (ipa3_rmnet_res.ipa_advertise_sg_support)
2198 dev->hw_features |= NETIF_F_SG;
2199
2200 if (ipa3_rmnet_res.ipa_napi_enable)
2201 netif_napi_add(dev, &(rmnet_ipa3_ctx->wwan_priv->napi),
2202 ipa3_rmnet_poll, NAPI_WEIGHT);
2203 ret = register_netdev(dev);
2204 if (ret) {
2205 IPAWANERR("unable to register ipa_netdev %d rc=%d\n",
2206 0, ret);
2207 goto set_perf_err;
2208 }
2209
2210 IPAWANDBG("IPA-WWAN devices (%s) initialization ok :>>>>\n", dev->name);
2211 if (ret) {
2212 IPAWANERR("default configuration failed rc=%d\n",
2213 ret);
2214 goto config_err;
2215 }
2216 atomic_set(&rmnet_ipa3_ctx->is_initialized, 1);
2217 if (!atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
2218 /* offline charging mode */
2219 ipa3_proxy_clk_unvote();
2220 }
2221 atomic_set(&rmnet_ipa3_ctx->is_ssr, 0);
2222
2223 pr_info("rmnet_ipa completed initialization\n");
2224 return 0;
2225config_err:
2226 if (ipa3_rmnet_res.ipa_napi_enable)
2227 netif_napi_del(&(rmnet_ipa3_ctx->wwan_priv->napi));
2228 unregister_netdev(dev);
2229set_perf_err:
2230 ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
2231 IPA_RM_RESOURCE_Q6_CONS);
2232 if (ret)
2233 IPAWANERR("Error deleting dependency %d->%d, ret=%d\n",
2234 IPA_RM_RESOURCE_WWAN_0_PROD, IPA_RM_RESOURCE_Q6_CONS,
2235 ret);
2236add_dpnd_err:
2237 ret = ipa_rm_inactivity_timer_destroy(
2238 IPA_RM_RESOURCE_WWAN_0_PROD); /* IPA_RM */
2239 if (ret)
2240 IPAWANERR("Error ipa_rm_inactivity_timer_destroy %d, ret=%d\n",
2241 IPA_RM_RESOURCE_WWAN_0_PROD, ret);
2242timer_init_err:
2243 ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
2244 if (ret)
2245 IPAWANERR("Error deleting resource %d, ret=%d\n",
2246 IPA_RM_RESOURCE_WWAN_0_PROD, ret);
2247create_rsrc_err:
2248 ipa3_q6_deinitialize_rm();
2249q6_init_err:
2250 free_netdev(dev);
2251 rmnet_ipa3_ctx->wwan_priv = NULL;
2252alloc_netdev_err:
2253 ipa3_wan_ioctl_deinit();
2254wan_ioctl_init_err:
2255 ipa3_del_dflt_wan_rt_tables();
2256setup_dflt_wan_rt_tables_err:
2257 ipa3_del_a7_qmap_hdr();
2258setup_a7_qmap_hdr_err:
2259 ipa3_qmi_service_exit();
2260 atomic_set(&rmnet_ipa3_ctx->is_ssr, 0);
2261 return ret;
2262}
2263
2264static int ipa3_wwan_remove(struct platform_device *pdev)
2265{
2266 int ret;
2267
2268 pr_info("rmnet_ipa started deinitialization\n");
Ghanim Fodic6b67492017-03-15 14:19:56 +02002269 mutex_lock(&rmnet_ipa3_ctx->pipe_handle_guard);
Amir Levy9659e592016-10-27 18:08:27 +03002270 ret = ipa3_teardown_sys_pipe(rmnet_ipa3_ctx->ipa3_to_apps_hdl);
2271 if (ret < 0)
2272 IPAWANERR("Failed to teardown IPA->APPS pipe\n");
2273 else
2274 rmnet_ipa3_ctx->ipa3_to_apps_hdl = -1;
Ghanim Fodic6b67492017-03-15 14:19:56 +02002275 ret = ipa3_teardown_sys_pipe(rmnet_ipa3_ctx->apps_to_ipa3_hdl);
2276 if (ret < 0)
2277 IPAWANERR("Failed to teardown APPS->IPA pipe\n");
2278 else
2279 rmnet_ipa3_ctx->apps_to_ipa3_hdl = -1;
Amir Levy9659e592016-10-27 18:08:27 +03002280 if (ipa3_rmnet_res.ipa_napi_enable)
2281 netif_napi_del(&(rmnet_ipa3_ctx->wwan_priv->napi));
Ghanim Fodic6b67492017-03-15 14:19:56 +02002282 mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
Amir Levy9659e592016-10-27 18:08:27 +03002283 unregister_netdev(IPA_NETDEV());
2284 ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
2285 IPA_RM_RESOURCE_Q6_CONS);
2286 if (ret < 0)
2287 IPAWANERR("Error deleting dependency %d->%d, ret=%d\n",
2288 IPA_RM_RESOURCE_WWAN_0_PROD, IPA_RM_RESOURCE_Q6_CONS,
2289 ret);
2290 ret = ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_WWAN_0_PROD);
2291 if (ret < 0)
2292 IPAWANERR(
2293 "Error ipa_rm_inactivity_timer_destroy resource %d, ret=%d\n",
2294 IPA_RM_RESOURCE_WWAN_0_PROD, ret);
2295 ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
2296 if (ret < 0)
2297 IPAWANERR("Error deleting resource %d, ret=%d\n",
2298 IPA_RM_RESOURCE_WWAN_0_PROD, ret);
2299 cancel_work_sync(&ipa3_tx_wakequeue_work);
2300 cancel_delayed_work(&ipa_tether_stats_poll_wakequeue_work);
2301 if (IPA_NETDEV())
2302 free_netdev(IPA_NETDEV());
2303 rmnet_ipa3_ctx->wwan_priv = NULL;
2304 /* No need to remove wwan_ioctl during SSR */
2305 if (!atomic_read(&rmnet_ipa3_ctx->is_ssr))
2306 ipa3_wan_ioctl_deinit();
2307 ipa3_del_dflt_wan_rt_tables();
2308 ipa3_del_a7_qmap_hdr();
2309 ipa3_del_mux_qmap_hdrs();
2310 if (ipa3_qmi_ctx->modem_cfg_emb_pipe_flt == false)
2311 ipa3_wwan_del_ul_flt_rule_to_ipa();
2312 ipa3_cleanup_deregister_intf();
2313 atomic_set(&rmnet_ipa3_ctx->is_initialized, 0);
2314 pr_info("rmnet_ipa completed deinitialization\n");
2315 return 0;
2316}
2317
2318/**
2319* rmnet_ipa_ap_suspend() - suspend callback for runtime_pm
2320* @dev: pointer to device
2321*
2322* This callback will be invoked by the runtime_pm framework when an AP suspend
2323* operation is invoked, usually by pressing a suspend button.
2324*
2325* Returns -EAGAIN to runtime_pm framework in case there are pending packets
2326* in the Tx queue. This will postpone the suspend operation until all the
2327* pending packets will be transmitted.
2328*
2329* In case there are no packets to send, releases the WWAN0_PROD entity.
2330* As an outcome, the number of IPA active clients should be decremented
2331* until IPA clocks can be gated.
2332*/
2333static int rmnet_ipa_ap_suspend(struct device *dev)
2334{
2335 struct net_device *netdev = IPA_NETDEV();
2336 struct ipa3_wwan_private *wwan_ptr;
2337
2338 IPAWANDBG_LOW("Enter...\n");
2339 if (netdev == NULL) {
2340 IPAWANERR("netdev is NULL.\n");
2341 return 0;
2342 }
2343
2344 wwan_ptr = netdev_priv(netdev);
2345 if (wwan_ptr == NULL) {
2346 IPAWANERR("wwan_ptr is NULL.\n");
2347 return 0;
2348 }
2349
2350 /* Do not allow A7 to suspend in case there are oustanding packets */
2351 if (atomic_read(&wwan_ptr->outstanding_pkts) != 0) {
2352 IPAWANDBG("Outstanding packets, postponing AP suspend.\n");
2353 return -EAGAIN;
2354 }
2355
2356 /* Make sure that there is no Tx operation ongoing */
2357 netif_tx_lock_bh(netdev);
2358 ipa_rm_release_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
2359 netif_tx_unlock_bh(netdev);
2360 IPAWANDBG_LOW("Exit\n");
2361
2362 return 0;
2363}
2364
2365/**
2366* rmnet_ipa_ap_resume() - resume callback for runtime_pm
2367* @dev: pointer to device
2368*
2369* This callback will be invoked by the runtime_pm framework when an AP resume
2370* operation is invoked.
2371*
2372* Enables the network interface queue and returns success to the
2373* runtime_pm framework.
2374*/
2375static int rmnet_ipa_ap_resume(struct device *dev)
2376{
2377 struct net_device *netdev = IPA_NETDEV();
2378
2379 IPAWANDBG_LOW("Enter...\n");
2380 if (netdev)
2381 netif_wake_queue(netdev);
2382 IPAWANDBG_LOW("Exit\n");
2383
2384 return 0;
2385}
2386
2387static void ipa_stop_polling_stats(void)
2388{
2389 cancel_delayed_work(&ipa_tether_stats_poll_wakequeue_work);
2390 ipa3_rmnet_ctx.polling_interval = 0;
2391}
2392
2393static const struct of_device_id rmnet_ipa_dt_match[] = {
2394 {.compatible = "qcom,rmnet-ipa3"},
2395 {},
2396};
2397MODULE_DEVICE_TABLE(of, rmnet_ipa_dt_match);
2398
2399static const struct dev_pm_ops rmnet_ipa_pm_ops = {
2400 .suspend_noirq = rmnet_ipa_ap_suspend,
2401 .resume_noirq = rmnet_ipa_ap_resume,
2402};
2403
2404static struct platform_driver rmnet_ipa_driver = {
2405 .driver = {
2406 .name = "rmnet_ipa3",
2407 .owner = THIS_MODULE,
2408 .pm = &rmnet_ipa_pm_ops,
2409 .of_match_table = rmnet_ipa_dt_match,
2410 },
2411 .probe = ipa3_wwan_probe,
2412 .remove = ipa3_wwan_remove,
2413};
2414
2415static int ipa3_ssr_notifier_cb(struct notifier_block *this,
2416 unsigned long code,
2417 void *data)
2418{
2419 if (!ipa3_rmnet_ctx.ipa_rmnet_ssr)
2420 return NOTIFY_DONE;
2421
2422 switch (code) {
2423 case SUBSYS_BEFORE_SHUTDOWN:
2424 IPAWANINFO("IPA received MPSS BEFORE_SHUTDOWN\n");
2425 atomic_set(&rmnet_ipa3_ctx->is_ssr, 1);
2426 ipa3_q6_pre_shutdown_cleanup();
2427 if (IPA_NETDEV())
2428 netif_stop_queue(IPA_NETDEV());
2429 ipa3_qmi_stop_workqueues();
2430 ipa3_wan_ioctl_stop_qmi_messages();
2431 ipa_stop_polling_stats();
2432 if (atomic_read(&rmnet_ipa3_ctx->is_initialized))
2433 platform_driver_unregister(&rmnet_ipa_driver);
2434 IPAWANINFO("IPA BEFORE_SHUTDOWN handling is complete\n");
2435 break;
2436 case SUBSYS_AFTER_SHUTDOWN:
2437 IPAWANINFO("IPA Received MPSS AFTER_SHUTDOWN\n");
2438 if (atomic_read(&rmnet_ipa3_ctx->is_ssr))
2439 ipa3_q6_post_shutdown_cleanup();
2440 IPAWANINFO("IPA AFTER_SHUTDOWN handling is complete\n");
2441 break;
2442 case SUBSYS_BEFORE_POWERUP:
2443 IPAWANINFO("IPA received MPSS BEFORE_POWERUP\n");
2444 if (atomic_read(&rmnet_ipa3_ctx->is_ssr))
2445 /* clean up cached QMI msg/handlers */
2446 ipa3_qmi_service_exit();
2447 /*hold a proxy vote for the modem*/
2448 ipa3_proxy_clk_vote();
Skylar Change1209942017-02-02 14:26:38 -08002449 ipa3_reset_freeze_vote();
Amir Levy9659e592016-10-27 18:08:27 +03002450 IPAWANINFO("IPA BEFORE_POWERUP handling is complete\n");
2451 break;
2452 case SUBSYS_AFTER_POWERUP:
2453 IPAWANINFO("%s:%d IPA received MPSS AFTER_POWERUP\n",
2454 __func__, __LINE__);
2455 if (!atomic_read(&rmnet_ipa3_ctx->is_initialized) &&
2456 atomic_read(&rmnet_ipa3_ctx->is_ssr))
2457 platform_driver_register(&rmnet_ipa_driver);
2458
2459 IPAWANINFO("IPA AFTER_POWERUP handling is complete\n");
2460 break;
2461 default:
2462 IPAWANDBG("Unsupported subsys notification, IPA received: %lu",
2463 code);
2464 break;
2465 }
2466
2467 IPAWANDBG_LOW("Exit\n");
2468 return NOTIFY_DONE;
2469}
2470
2471/**
2472 * rmnet_ipa_free_msg() - Free the msg sent to user space via ipa_send_msg
2473 * @buff: pointer to buffer containing the message
2474 * @len: message len
2475 * @type: message type
2476 *
2477 * This function is invoked when ipa_send_msg is complete (Provided as a
2478 * free function pointer along with the message).
2479 */
2480static void rmnet_ipa_free_msg(void *buff, u32 len, u32 type)
2481{
2482 if (!buff) {
2483 IPAWANERR("Null buffer\n");
2484 return;
2485 }
2486
2487 if (type != IPA_TETHERING_STATS_UPDATE_STATS &&
2488 type != IPA_TETHERING_STATS_UPDATE_NETWORK_STATS) {
2489 IPAWANERR("Wrong type given. buff %p type %d\n",
2490 buff, type);
2491 }
2492 kfree(buff);
2493}
2494
2495/**
2496 * rmnet_ipa_get_stats_and_update() - Gets pipe stats from Modem
2497 *
2498 * This function queries the IPA Modem driver for the pipe stats
2499 * via QMI, and updates the user space IPA entity.
2500 */
2501static void rmnet_ipa_get_stats_and_update(void)
2502{
2503 struct ipa_get_data_stats_req_msg_v01 req;
2504 struct ipa_get_data_stats_resp_msg_v01 *resp;
2505 struct ipa_msg_meta msg_meta;
2506 int rc;
2507
2508 resp = kzalloc(sizeof(struct ipa_get_data_stats_resp_msg_v01),
2509 GFP_KERNEL);
2510 if (!resp) {
2511 IPAWANERR("Can't allocate memory for stats message\n");
2512 return;
2513 }
2514
2515 memset(&req, 0, sizeof(struct ipa_get_data_stats_req_msg_v01));
2516 memset(resp, 0, sizeof(struct ipa_get_data_stats_resp_msg_v01));
2517
2518 req.ipa_stats_type = QMI_IPA_STATS_TYPE_PIPE_V01;
2519
2520 rc = ipa3_qmi_get_data_stats(&req, resp);
Gidon Studinski3021a6f2016-11-10 12:48:48 +02002521 if (rc) {
2522 IPAWANERR("ipa3_qmi_get_data_stats failed: %d\n", rc);
2523 kfree(resp);
2524 return;
2525 }
Amir Levy9659e592016-10-27 18:08:27 +03002526
Gidon Studinski3021a6f2016-11-10 12:48:48 +02002527 memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
2528 msg_meta.msg_type = IPA_TETHERING_STATS_UPDATE_STATS;
2529 msg_meta.msg_len = sizeof(struct ipa_get_data_stats_resp_msg_v01);
2530 rc = ipa_send_msg(&msg_meta, resp, rmnet_ipa_free_msg);
2531 if (rc) {
2532 IPAWANERR("ipa_send_msg failed: %d\n", rc);
2533 kfree(resp);
2534 return;
Amir Levy9659e592016-10-27 18:08:27 +03002535 }
2536}
2537
2538/**
2539 * tethering_stats_poll_queue() - Stats polling function
2540 * @work - Work entry
2541 *
2542 * This function is scheduled periodically (per the interval) in
2543 * order to poll the IPA Modem driver for the pipe stats.
2544 */
2545static void tethering_stats_poll_queue(struct work_struct *work)
2546{
2547 rmnet_ipa_get_stats_and_update();
2548
2549 /* Schedule again only if there's an active polling interval */
2550 if (ipa3_rmnet_ctx.polling_interval != 0)
2551 schedule_delayed_work(&ipa_tether_stats_poll_wakequeue_work,
2552 msecs_to_jiffies(ipa3_rmnet_ctx.polling_interval*1000));
2553}
2554
2555/**
2556 * rmnet_ipa_get_network_stats_and_update() - Get network stats from IPA Modem
2557 *
2558 * This function retrieves the data usage (used quota) from the IPA Modem driver
2559 * via QMI, and updates IPA user space entity.
2560 */
2561static void rmnet_ipa_get_network_stats_and_update(void)
2562{
2563 struct ipa_get_apn_data_stats_req_msg_v01 req;
2564 struct ipa_get_apn_data_stats_resp_msg_v01 *resp;
2565 struct ipa_msg_meta msg_meta;
2566 int rc;
2567
2568 resp = kzalloc(sizeof(struct ipa_get_apn_data_stats_resp_msg_v01),
2569 GFP_KERNEL);
2570 if (!resp) {
2571 IPAWANERR("Can't allocate memory for network stats message\n");
2572 return;
2573 }
2574
2575 memset(&req, 0, sizeof(struct ipa_get_apn_data_stats_req_msg_v01));
2576 memset(resp, 0, sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
2577
2578 req.mux_id_list_valid = true;
2579 req.mux_id_list_len = 1;
2580 req.mux_id_list[0] = ipa3_rmnet_ctx.metered_mux_id;
2581
2582 rc = ipa3_qmi_get_network_stats(&req, resp);
Gidon Studinski3021a6f2016-11-10 12:48:48 +02002583 if (rc) {
2584 IPAWANERR("ipa3_qmi_get_network_stats failed: %d\n", rc);
2585 kfree(resp);
2586 return;
2587 }
Amir Levy9659e592016-10-27 18:08:27 +03002588
Gidon Studinski3021a6f2016-11-10 12:48:48 +02002589 memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
2590 msg_meta.msg_type = IPA_TETHERING_STATS_UPDATE_NETWORK_STATS;
2591 msg_meta.msg_len = sizeof(struct ipa_get_apn_data_stats_resp_msg_v01);
2592 rc = ipa_send_msg(&msg_meta, resp, rmnet_ipa_free_msg);
2593 if (rc) {
2594 IPAWANERR("ipa_send_msg failed: %d\n", rc);
2595 kfree(resp);
2596 return;
Amir Levy9659e592016-10-27 18:08:27 +03002597 }
2598}
2599
2600/**
2601 * rmnet_ipa3_poll_tethering_stats() - Tethering stats polling IOCTL handler
2602 * @data - IOCTL data
2603 *
2604 * This function handles WAN_IOC_POLL_TETHERING_STATS.
2605 * In case polling interval received is 0, polling will stop
2606 * (If there's a polling in progress, it will allow it to finish), and then will
2607 * fetch network stats, and update the IPA user space.
2608 *
2609 * Return codes:
2610 * 0: Success
2611 */
2612int rmnet_ipa3_poll_tethering_stats(struct wan_ioctl_poll_tethering_stats *data)
2613{
2614 ipa3_rmnet_ctx.polling_interval = data->polling_interval_secs;
2615
2616 cancel_delayed_work_sync(&ipa_tether_stats_poll_wakequeue_work);
2617
2618 if (ipa3_rmnet_ctx.polling_interval == 0) {
2619 ipa3_qmi_stop_data_qouta();
2620 rmnet_ipa_get_network_stats_and_update();
2621 rmnet_ipa_get_stats_and_update();
2622 return 0;
2623 }
2624
2625 schedule_delayed_work(&ipa_tether_stats_poll_wakequeue_work, 0);
2626 return 0;
2627}
2628
2629/**
2630 * rmnet_ipa_set_data_quota() - Data quota setting IOCTL handler
2631 * @data - IOCTL data
2632 *
2633 * This function handles WAN_IOC_SET_DATA_QUOTA.
2634 * It translates the given interface name to the Modem MUX ID and
2635 * sends the request of the quota to the IPA Modem driver via QMI.
2636 *
2637 * Return codes:
2638 * 0: Success
2639 * -EFAULT: Invalid interface name provided
2640 * other: See ipa_qmi_set_data_quota
2641 */
2642int rmnet_ipa3_set_data_quota(struct wan_ioctl_set_data_quota *data)
2643{
2644 u32 mux_id;
2645 int index;
2646 struct ipa_set_data_usage_quota_req_msg_v01 req;
2647
2648 index = find_vchannel_name_index(data->interface_name);
2649 IPAWANERR("iface name %s, quota %lu\n",
2650 data->interface_name,
2651 (unsigned long int) data->quota_mbytes);
2652
2653 if (index == MAX_NUM_OF_MUX_CHANNEL) {
2654 IPAWANERR("%s is an invalid iface name\n",
2655 data->interface_name);
2656 return -EFAULT;
2657 }
2658
2659 mux_id = rmnet_ipa3_ctx->mux_channel[index].mux_id;
2660 ipa3_rmnet_ctx.metered_mux_id = mux_id;
2661
2662 memset(&req, 0, sizeof(struct ipa_set_data_usage_quota_req_msg_v01));
2663 req.apn_quota_list_valid = true;
2664 req.apn_quota_list_len = 1;
2665 req.apn_quota_list[0].mux_id = mux_id;
2666 req.apn_quota_list[0].num_Mbytes = data->quota_mbytes;
2667
2668 return ipa3_qmi_set_data_quota(&req);
2669}
2670
2671 /* rmnet_ipa_set_tether_client_pipe() -
2672 * @data - IOCTL data
2673 *
2674 * This function handles WAN_IOC_SET_DATA_QUOTA.
2675 * It translates the given interface name to the Modem MUX ID and
2676 * sends the request of the quota to the IPA Modem driver via QMI.
2677 *
2678 * Return codes:
2679 * 0: Success
2680 * -EFAULT: Invalid interface name provided
2681 * other: See ipa_qmi_set_data_quota
2682 */
2683int rmnet_ipa3_set_tether_client_pipe(
2684 struct wan_ioctl_set_tether_client_pipe *data)
2685{
2686 int number, i;
2687
Skylar Chang345c8142016-11-30 14:41:24 -08002688 /* error checking if ul_src_pipe_len valid or not*/
2689 if (data->ul_src_pipe_len > QMI_IPA_MAX_PIPES_V01 ||
2690 data->ul_src_pipe_len < 0) {
2691 IPAWANERR("UL src pipes %d exceeding max %d\n",
2692 data->ul_src_pipe_len,
2693 QMI_IPA_MAX_PIPES_V01);
2694 return -EFAULT;
2695 }
2696 /* error checking if dl_dst_pipe_len valid or not*/
2697 if (data->dl_dst_pipe_len > QMI_IPA_MAX_PIPES_V01 ||
2698 data->dl_dst_pipe_len < 0) {
2699 IPAWANERR("DL dst pipes %d exceeding max %d\n",
2700 data->dl_dst_pipe_len,
2701 QMI_IPA_MAX_PIPES_V01);
2702 return -EFAULT;
2703 }
2704
Amir Levy9659e592016-10-27 18:08:27 +03002705 IPAWANDBG("client %d, UL %d, DL %d, reset %d\n",
2706 data->ipa_client,
2707 data->ul_src_pipe_len,
2708 data->dl_dst_pipe_len,
2709 data->reset_client);
2710 number = data->ul_src_pipe_len;
2711 for (i = 0; i < number; i++) {
2712 IPAWANDBG("UL index-%d pipe %d\n", i,
2713 data->ul_src_pipe_list[i]);
2714 if (data->reset_client)
2715 ipa3_set_client(data->ul_src_pipe_list[i],
2716 0, false);
2717 else
2718 ipa3_set_client(data->ul_src_pipe_list[i],
2719 data->ipa_client, true);
2720 }
2721 number = data->dl_dst_pipe_len;
2722 for (i = 0; i < number; i++) {
2723 IPAWANDBG("DL index-%d pipe %d\n", i,
2724 data->dl_dst_pipe_list[i]);
2725 if (data->reset_client)
2726 ipa3_set_client(data->dl_dst_pipe_list[i],
2727 0, false);
2728 else
2729 ipa3_set_client(data->dl_dst_pipe_list[i],
2730 data->ipa_client, false);
2731 }
2732 return 0;
2733}
2734
2735int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
2736 bool reset)
2737{
2738 struct ipa_get_data_stats_req_msg_v01 *req;
2739 struct ipa_get_data_stats_resp_msg_v01 *resp;
2740 int pipe_len, rc;
2741
2742 req = kzalloc(sizeof(struct ipa_get_data_stats_req_msg_v01),
2743 GFP_KERNEL);
2744 if (!req) {
2745 IPAWANERR("Can't allocate memory for stats message\n");
2746 return -ENOMEM;
2747 }
2748 resp = kzalloc(sizeof(struct ipa_get_data_stats_resp_msg_v01),
2749 GFP_KERNEL);
2750 if (!resp) {
2751 IPAWANERR("Can't allocate memory for stats message\n");
2752 kfree(req);
2753 return -ENOMEM;
2754 }
2755 memset(req, 0, sizeof(struct ipa_get_data_stats_req_msg_v01));
2756 memset(resp, 0, sizeof(struct ipa_get_data_stats_resp_msg_v01));
2757
2758 req->ipa_stats_type = QMI_IPA_STATS_TYPE_PIPE_V01;
2759 if (reset) {
2760 req->reset_stats_valid = true;
2761 req->reset_stats = true;
2762 IPAWANERR("reset the pipe stats\n");
2763 } else {
2764 /* print tethered-client enum */
2765 IPAWANDBG_LOW("Tethered-client enum(%d)\n", data->ipa_client);
2766 }
2767
2768 rc = ipa3_qmi_get_data_stats(req, resp);
2769 if (rc) {
2770 IPAWANERR("can't get ipa_qmi_get_data_stats\n");
2771 kfree(req);
2772 kfree(resp);
2773 return rc;
2774 } else if (reset) {
2775 kfree(req);
2776 kfree(resp);
2777 return 0;
2778 }
2779
2780 if (resp->dl_dst_pipe_stats_list_valid) {
2781 for (pipe_len = 0; pipe_len < resp->dl_dst_pipe_stats_list_len;
2782 pipe_len++) {
2783 IPAWANDBG_LOW("Check entry(%d) dl_dst_pipe(%d)\n",
2784 pipe_len, resp->dl_dst_pipe_stats_list
2785 [pipe_len].pipe_index);
2786 IPAWANDBG_LOW("dl_p_v4(%lu)v6(%lu)\n",
2787 (unsigned long int) resp->
2788 dl_dst_pipe_stats_list[pipe_len].
2789 num_ipv4_packets,
2790 (unsigned long int) resp->
2791 dl_dst_pipe_stats_list[pipe_len].
2792 num_ipv6_packets);
2793 IPAWANDBG_LOW("dl_b_v4(%lu)v6(%lu)\n",
2794 (unsigned long int) resp->
2795 dl_dst_pipe_stats_list[pipe_len].
2796 num_ipv4_bytes,
2797 (unsigned long int) resp->
2798 dl_dst_pipe_stats_list[pipe_len].
2799 num_ipv6_bytes);
2800 if (ipa_get_client_uplink(resp->
2801 dl_dst_pipe_stats_list[pipe_len].
2802 pipe_index) == false) {
2803 if (data->ipa_client == ipa_get_client(resp->
2804 dl_dst_pipe_stats_list[pipe_len].
2805 pipe_index)) {
2806 /* update the DL stats */
2807 data->ipv4_rx_packets += resp->
2808 dl_dst_pipe_stats_list[pipe_len].
2809 num_ipv4_packets;
2810 data->ipv6_rx_packets += resp->
2811 dl_dst_pipe_stats_list[pipe_len].
2812 num_ipv6_packets;
2813 data->ipv4_rx_bytes += resp->
2814 dl_dst_pipe_stats_list[pipe_len].
2815 num_ipv4_bytes;
2816 data->ipv6_rx_bytes += resp->
2817 dl_dst_pipe_stats_list[pipe_len].
2818 num_ipv6_bytes;
2819 }
2820 }
2821 }
2822 }
2823 IPAWANDBG_LOW("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n",
2824 (unsigned long int) data->ipv4_rx_packets,
2825 (unsigned long int) data->ipv6_rx_packets,
2826 (unsigned long int) data->ipv4_rx_bytes,
2827 (unsigned long int) data->ipv6_rx_bytes);
2828
2829 if (resp->ul_src_pipe_stats_list_valid) {
2830 for (pipe_len = 0; pipe_len < resp->ul_src_pipe_stats_list_len;
2831 pipe_len++) {
2832 IPAWANDBG_LOW("Check entry(%d) ul_dst_pipe(%d)\n",
2833 pipe_len,
2834 resp->ul_src_pipe_stats_list[pipe_len].
2835 pipe_index);
2836 IPAWANDBG_LOW("ul_p_v4(%lu)v6(%lu)\n",
2837 (unsigned long int) resp->
2838 ul_src_pipe_stats_list[pipe_len].
2839 num_ipv4_packets,
2840 (unsigned long int) resp->
2841 ul_src_pipe_stats_list[pipe_len].
2842 num_ipv6_packets);
2843 IPAWANDBG_LOW("ul_b_v4(%lu)v6(%lu)\n",
2844 (unsigned long int) resp->
2845 ul_src_pipe_stats_list[pipe_len].
2846 num_ipv4_bytes,
2847 (unsigned long int) resp->
2848 ul_src_pipe_stats_list[pipe_len].
2849 num_ipv6_bytes);
2850 if (ipa_get_client_uplink(resp->
2851 ul_src_pipe_stats_list[pipe_len].
2852 pipe_index) == true) {
2853 if (data->ipa_client == ipa_get_client(resp->
2854 ul_src_pipe_stats_list[pipe_len].
2855 pipe_index)) {
2856 /* update the DL stats */
2857 data->ipv4_tx_packets += resp->
2858 ul_src_pipe_stats_list[pipe_len].
2859 num_ipv4_packets;
2860 data->ipv6_tx_packets += resp->
2861 ul_src_pipe_stats_list[pipe_len].
2862 num_ipv6_packets;
2863 data->ipv4_tx_bytes += resp->
2864 ul_src_pipe_stats_list[pipe_len].
2865 num_ipv4_bytes;
2866 data->ipv6_tx_bytes += resp->
2867 ul_src_pipe_stats_list[pipe_len].
2868 num_ipv6_bytes;
2869 }
2870 }
2871 }
2872 }
2873 IPAWANDBG_LOW("tx_p_v4(%lu)v6(%lu)tx_b_v4(%lu) v6(%lu)\n",
2874 (unsigned long int) data->ipv4_tx_packets,
2875 (unsigned long int) data->ipv6_tx_packets,
2876 (unsigned long int) data->ipv4_tx_bytes,
2877 (unsigned long int) data->ipv6_tx_bytes);
2878 kfree(req);
2879 kfree(resp);
2880 return 0;
2881}
2882
2883/**
2884 * ipa3_broadcast_quota_reach_ind() - Send Netlink broadcast on Quota
2885 * @mux_id - The MUX ID on which the quota has been reached
2886 *
2887 * This function broadcasts a Netlink event using the kobject of the
2888 * rmnet_ipa interface in order to alert the user space that the quota
2889 * on the specific interface which matches the mux_id has been reached.
2890 *
2891 */
2892void ipa3_broadcast_quota_reach_ind(u32 mux_id)
2893{
2894 char alert_msg[IPA_QUOTA_REACH_ALERT_MAX_SIZE];
2895 char iface_name_m[IPA_QUOTA_REACH_IF_NAME_MAX_SIZE];
2896 char iface_name_l[IPA_QUOTA_REACH_IF_NAME_MAX_SIZE];
2897 char *envp[IPA_UEVENT_NUM_EVNP] = {
2898 alert_msg, iface_name_l, iface_name_m, NULL };
2899 int res;
2900 int index;
2901
2902 index = ipa3_find_mux_channel_index(mux_id);
2903
2904 if (index == MAX_NUM_OF_MUX_CHANNEL) {
2905 IPAWANERR("%u is an mux ID\n", mux_id);
2906 return;
2907 }
2908
2909 res = snprintf(alert_msg, IPA_QUOTA_REACH_ALERT_MAX_SIZE,
2910 "ALERT_NAME=%s", "quotaReachedAlert");
2911 if (res >= IPA_QUOTA_REACH_ALERT_MAX_SIZE) {
2912 IPAWANERR("message too long (%d)", res);
2913 return;
2914 }
2915 /* posting msg for L-release for CNE */
2916 res = snprintf(iface_name_l, IPA_QUOTA_REACH_IF_NAME_MAX_SIZE,
2917 "UPSTREAM=%s", rmnet_ipa3_ctx->mux_channel[index].vchannel_name);
2918 if (res >= IPA_QUOTA_REACH_IF_NAME_MAX_SIZE) {
2919 IPAWANERR("message too long (%d)", res);
2920 return;
2921 }
2922 /* posting msg for M-release for CNE */
2923 res = snprintf(iface_name_m, IPA_QUOTA_REACH_IF_NAME_MAX_SIZE,
2924 "INTERFACE=%s", rmnet_ipa3_ctx->mux_channel[index].vchannel_name);
2925 if (res >= IPA_QUOTA_REACH_IF_NAME_MAX_SIZE) {
2926 IPAWANERR("message too long (%d)", res);
2927 return;
2928 }
2929
2930 IPAWANERR("putting nlmsg: <%s> <%s> <%s>\n",
2931 alert_msg, iface_name_l, iface_name_m);
2932 kobject_uevent_env(&(IPA_NETDEV()->dev.kobj),
2933 KOBJ_CHANGE, envp);
2934}
2935
2936/**
2937 * ipa3_q6_handshake_complete() - Perform operations once Q6 is up
2938 * @ssr_bootup - Indicates whether this is a cold boot-up or post-SSR.
2939 *
2940 * This function is invoked once the handshake between the IPA AP driver
2941 * and IPA Q6 driver is complete. At this point, it is possible to perform
2942 * operations which can't be performed until IPA Q6 driver is up.
2943 *
2944 */
2945void ipa3_q6_handshake_complete(bool ssr_bootup)
2946{
2947 /* It is required to recover the network stats after SSR recovery */
2948 if (ssr_bootup) {
2949 /*
2950 * In case the uC is required to be loaded by the Modem,
2951 * the proxy vote will be removed only when uC loading is
2952 * complete and indication is received by the AP. After SSR,
2953 * uC is already loaded. Therefore, proxy vote can be removed
2954 * once Modem init is complete.
2955 */
2956 ipa3_proxy_clk_unvote();
2957
2958 /*
2959 * It is required to recover the network stats after
2960 * SSR recovery
2961 */
2962 rmnet_ipa_get_network_stats_and_update();
2963 }
2964}
2965
2966static int __init ipa3_wwan_init(void)
2967{
2968 rmnet_ipa3_ctx = kzalloc(sizeof(*rmnet_ipa3_ctx), GFP_KERNEL);
2969 if (!rmnet_ipa3_ctx) {
2970 IPAWANERR("no memory\n");
2971 return -ENOMEM;
2972 }
2973
2974 atomic_set(&rmnet_ipa3_ctx->is_initialized, 0);
2975 atomic_set(&rmnet_ipa3_ctx->is_ssr, 0);
2976
Ghanim Fodic6b67492017-03-15 14:19:56 +02002977 mutex_init(&rmnet_ipa3_ctx->pipe_handle_guard);
Amir Levy9659e592016-10-27 18:08:27 +03002978 rmnet_ipa3_ctx->ipa3_to_apps_hdl = -1;
Ghanim Fodic6b67492017-03-15 14:19:56 +02002979 rmnet_ipa3_ctx->apps_to_ipa3_hdl = -1;
Amir Levy9659e592016-10-27 18:08:27 +03002980 /* Register for Modem SSR */
2981 rmnet_ipa3_ctx->subsys_notify_handle = subsys_notif_register_notifier(
2982 SUBSYS_MODEM,
2983 &ipa3_ssr_notifier);
2984 if (!IS_ERR(rmnet_ipa3_ctx->subsys_notify_handle))
2985 return platform_driver_register(&rmnet_ipa_driver);
2986 else
2987 return (int)PTR_ERR(rmnet_ipa3_ctx->subsys_notify_handle);
2988}
2989
2990static void __exit ipa3_wwan_cleanup(void)
2991{
2992 int ret;
2993
Ghanim Fodic6b67492017-03-15 14:19:56 +02002994 mutex_destroy(&rmnet_ipa3_ctx->pipe_handle_guard);
Amir Levy9659e592016-10-27 18:08:27 +03002995 ret = subsys_notif_unregister_notifier(
2996 rmnet_ipa3_ctx->subsys_notify_handle, &ipa3_ssr_notifier);
2997 if (ret)
2998 IPAWANERR(
2999 "Error subsys_notif_unregister_notifier system %s, ret=%d\n",
3000 SUBSYS_MODEM, ret);
3001 platform_driver_unregister(&rmnet_ipa_driver);
3002 kfree(rmnet_ipa3_ctx);
3003 rmnet_ipa3_ctx = NULL;
3004}
3005
3006static void ipa3_wwan_msg_free_cb(void *buff, u32 len, u32 type)
3007{
3008 if (!buff)
3009 IPAWANERR("Null buffer.\n");
3010 kfree(buff);
3011}
3012
3013static void ipa3_rmnet_rx_cb(void *priv)
3014{
3015 IPAWANDBG_LOW("\n");
3016 napi_schedule(&(rmnet_ipa3_ctx->wwan_priv->napi));
3017}
3018
3019static int ipa3_rmnet_poll(struct napi_struct *napi, int budget)
3020{
3021 int rcvd_pkts = 0;
3022
3023 rcvd_pkts = ipa_rx_poll(rmnet_ipa3_ctx->ipa3_to_apps_hdl,
3024 NAPI_WEIGHT);
3025 IPAWANDBG_LOW("rcvd packets: %d\n", rcvd_pkts);
3026 return rcvd_pkts;
3027}
3028
3029late_initcall(ipa3_wwan_init);
3030module_exit(ipa3_wwan_cleanup);
3031MODULE_DESCRIPTION("WWAN Network Interface");
3032MODULE_LICENSE("GPL v2");