teth_bridge.c 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283
  1. /* Copyright (c) 2013, The Linux Foundation. All rights reserved.
  2. *
  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. #include <linux/completion.h>
  13. #include <linux/debugfs.h>
  14. #include <linux/export.h>
  15. #include <linux/fs.h>
  16. #include <linux/if_ether.h>
  17. #include <linux/ioctl.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/msm_ipa.h>
  21. #include <linux/mutex.h>
  22. #include <linux/skbuff.h>
  23. #include <linux/types.h>
  24. #include <mach/ipa.h>
  25. #include <mach/sps.h>
  26. #include "ipa_i.h"
  27. #define TETH_BRIDGE_DRV_NAME "ipa_tethering_bridge"
  28. #define TETH_DBG(fmt, args...) \
  29. pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d " fmt, \
  30. __func__, __LINE__, ## args)
  31. #define TETH_DBG_FUNC_ENTRY() \
  32. pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d ENTRY\n", __func__, __LINE__)
  33. #define TETH_DBG_FUNC_EXIT() \
  34. pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d EXIT\n", __func__, __LINE__)
  35. #define TETH_ERR(fmt, args...) \
  36. pr_err(TETH_BRIDGE_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
  37. #define USB_ETH_HDR_NAME_IPV4 "usb_bridge_ipv4"
  38. #define USB_ETH_HDR_NAME_IPV6 "usb_bridge_ipv6"
  39. #define A2_ETH_HDR_NAME_IPV4 "a2_bridge_ipv4"
  40. #define A2_ETH_HDR_NAME_IPV6 "a2_bridge_ipv6"
  41. #define USB_TO_A2_RT_TBL_NAME_IPV4 "usb_a2_rt_tbl_ipv4"
  42. #define A2_TO_USB_RT_TBL_NAME_IPV4 "a2_usb_rt_tbl_ipv4"
  43. #define USB_TO_A2_RT_TBL_NAME_IPV6 "usb_a2_rt_tbl_ipv6"
  44. #define A2_TO_USB_RT_TBL_NAME_IPV6 "a2_usb_rt_tbl_ipv6"
  45. #define MBIM_HEADER_NAME "mbim_header"
  46. #define TETH_DEFAULT_AGGR_TIME_LIMIT 1
  47. #define ETHERTYPE_IPV4 0x0800
  48. #define ETHERTYPE_IPV6 0x86DD
  49. #define TETH_AGGR_MAX_DATAGRAMS_DEFAULT 16
  50. #define TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT (8*1024)
  51. #define TETH_MTU_BYTE 1500
  52. #define TETH_INACTIVITY_TIME_MSEC (1000)
  53. #define TETH_WORKQUEUE_NAME "tethering_bridge_wq"
  54. #define TETH_TOTAL_HDR_ENTRIES 6
  55. #define TETH_TOTAL_RT_ENTRIES_IP 3
  56. #define TETH_TOTAL_FLT_ENTRIES_IP 2
  57. #define TETH_IP_FAMILIES 2
  58. /**
  59. * struct mac_addresses_type - store host PC and device MAC addresses
  60. * @host_pc_mac_addr: MAC address of the host PC
  61. * @host_pc_mac_addr_known: is the MAC address of the host PC known ?
  62. * @device_mac_addr: MAC address of the device
  63. * @device_mac_addr_known: is the MAC address of the device known ?
  64. */
  65. struct mac_addresses_type {
  66. u8 host_pc_mac_addr[ETH_ALEN];
  67. bool host_pc_mac_addr_known;
  68. u8 device_mac_addr[ETH_ALEN];
  69. bool device_mac_addr_known;
  70. };
  71. /**
  72. * struct stats - driver statistics, viewable using debugfs
  73. * @a2_to_usb_num_sw_tx_packets: number of packets bridged from A2 to USB using
  74. * the SW bridge
  75. * @usb_to_a2_num_sw_tx_packets: number of packets bridged from USB to A2 using
  76. * the SW bridge
  77. * @num_sw_tx_packets_during_resource_wakeup: number of packets bridged during a
  78. * resource wakeup period, there is a special treatment for these kind of
  79. * packets
  80. */
  81. struct stats {
  82. u64 a2_to_usb_num_sw_tx_packets;
  83. u64 usb_to_a2_num_sw_tx_packets;
  84. u64 num_sw_tx_packets_during_resource_wakeup;
  85. };
  86. /**
  87. * struct teth_bridge_ctx - Tethering bridge driver context information
  88. * @class: kernel class pointer
  89. * @dev_num: kernel device number
  90. * @dev: kernel device struct pointer
  91. * @cdev: kernel character device struct
  92. * @usb_ipa_pipe_hdl: USB to IPA pipe handle
  93. * @ipa_usb_pipe_hdl: IPA to USB pipe handle
  94. * @a2_ipa_pipe_hdl: A2 to IPA pipe handle
  95. * @ipa_a2_pipe_hdl: IPA to A2 pipe handle
  96. * @is_connected: is the tethered bridge connected ?
  97. * @link_protocol: IP / Ethernet
  98. * @mac_addresses: Struct which holds host pc and device MAC addresses, relevant
  99. * in ethernet mode only
  100. * @is_hw_bridge_complete: is HW bridge setup ?
  101. * @aggr_params: aggregation parmeters
  102. * @aggr_params_known: are the aggregation parameters known ?
  103. * @tethering_mode: Rmnet / MBIM
  104. * @is_bridge_prod_up: completion object signaled when the bridge producer
  105. * finished its resource request procedure
  106. * @is_bridge_prod_down: completion object signaled when the bridge producer
  107. * finished its resource release procedure
  108. * @comp_hw_bridge_work: used for setting up the HW bridge using a workqueue
  109. * @comp_hw_bridge_in_progress: true when the HW bridge setup is in progress
  110. * @aggr_caps: aggregation capabilities
  111. * @stats: statistics, how many packets were transmitted using the SW bridge
  112. * @teth_wq: dedicated workqueue, used for setting up the HW bridge and for
  113. * sending packets using the SW bridge when the system is waking up from power
  114. * collapse
  115. * @a2_ipa_hdr_len: A2 to IPA header length, used for configuring the A2
  116. * endpoint for header removal
  117. * @ipa_a2_hdr_len: IPA to A2 header length, used for configuring the A2
  118. * endpoint for header removal
  119. * @hdr_del: array to store the headers handles in order to delete them later
  120. * @routing_del: array of routing rules handles, one array for IPv4 and one for
  121. * IPv6
  122. * @filtering_del: array of routing rules handles, one array for IPv4 and one
  123. * for IPv6
  124. */
  125. struct teth_bridge_ctx {
  126. struct class *class;
  127. dev_t dev_num;
  128. struct device *dev;
  129. struct cdev cdev;
  130. u32 usb_ipa_pipe_hdl;
  131. u32 ipa_usb_pipe_hdl;
  132. u32 a2_ipa_pipe_hdl;
  133. u32 ipa_a2_pipe_hdl;
  134. bool is_connected;
  135. enum teth_link_protocol_type link_protocol;
  136. struct mac_addresses_type mac_addresses;
  137. bool is_hw_bridge_complete;
  138. struct teth_aggr_params aggr_params;
  139. bool aggr_params_known;
  140. enum teth_tethering_mode tethering_mode;
  141. struct completion is_bridge_prod_up;
  142. struct completion is_bridge_prod_down;
  143. struct work_struct comp_hw_bridge_work;
  144. bool comp_hw_bridge_in_progress;
  145. struct teth_aggr_capabilities *aggr_caps;
  146. struct stats stats;
  147. struct workqueue_struct *teth_wq;
  148. u16 a2_ipa_hdr_len;
  149. u16 ipa_a2_hdr_len;
  150. struct ipa_ioc_del_hdr *hdr_del;
  151. struct ipa_ioc_del_rt_rule *routing_del[TETH_IP_FAMILIES];
  152. struct ipa_ioc_del_flt_rule *filtering_del[TETH_IP_FAMILIES];
  153. };
  154. static struct teth_bridge_ctx *teth_ctx;
  155. enum teth_packet_direction {
  156. TETH_USB_TO_A2,
  157. TETH_A2_TO_USB,
  158. };
  159. /**
  160. * struct teth_work - wrapper for an skb which is sent using a workqueue
  161. * @work: used by the workqueue
  162. * @skb: pointer to the skb to be sent
  163. * @dir: direction of send, A2 to USB or USB to A2
  164. */
  165. struct teth_work {
  166. struct work_struct work;
  167. struct sk_buff *skb;
  168. enum teth_packet_direction dir;
  169. };
  170. #ifdef CONFIG_DEBUG_FS
  171. #define TETH_MAX_MSG_LEN 512
  172. static char dbg_buff[TETH_MAX_MSG_LEN];
  173. #endif
  174. /**
  175. * add_eth_hdrs() - add Ethernet headers to IPA
  176. * @hdr_name_ipv4: header name for IPv4
  177. * @hdr_name_ipv6: header name for IPv6
  178. * @src_mac_addr: source MAC address
  179. * @dst_mac_addr: destination MAC address
  180. *
  181. * This function is called only when link protocol is Ethernet
  182. */
  183. static int add_eth_hdrs(char *hdr_name_ipv4, char *hdr_name_ipv6,
  184. u8 *src_mac_addr, u8 *dst_mac_addr)
  185. {
  186. int res;
  187. struct ipa_ioc_add_hdr *hdrs;
  188. struct ethhdr hdr_ipv4;
  189. struct ethhdr hdr_ipv6;
  190. int idx1;
  191. TETH_DBG_FUNC_ENTRY();
  192. memcpy(hdr_ipv4.h_source, src_mac_addr, ETH_ALEN);
  193. memcpy(hdr_ipv4.h_dest, dst_mac_addr, ETH_ALEN);
  194. hdr_ipv4.h_proto = htons(ETHERTYPE_IPV4);
  195. memcpy(hdr_ipv6.h_source, src_mac_addr, ETH_ALEN);
  196. memcpy(hdr_ipv6.h_dest, dst_mac_addr, ETH_ALEN);
  197. hdr_ipv6.h_proto = htons(ETHERTYPE_IPV6);
  198. /* Add headers to the header insertion tables */
  199. hdrs = kzalloc(sizeof(struct ipa_ioc_add_hdr) +
  200. 2 * sizeof(struct ipa_hdr_add), GFP_KERNEL);
  201. if (hdrs == NULL) {
  202. TETH_ERR("Failed allocating memory for headers !\n");
  203. return -ENOMEM;
  204. }
  205. hdrs->commit = 0;
  206. hdrs->num_hdrs = 2;
  207. /* Ethernet IPv4 header */
  208. strlcpy(hdrs->hdr[0].name, hdr_name_ipv4, IPA_RESOURCE_NAME_MAX);
  209. hdrs->hdr[0].hdr_len = ETH_HLEN;
  210. memcpy(hdrs->hdr[0].hdr, &hdr_ipv4, ETH_HLEN);
  211. /* Ethernet IPv6 header */
  212. strlcpy(hdrs->hdr[1].name, hdr_name_ipv6, IPA_RESOURCE_NAME_MAX);
  213. hdrs->hdr[1].hdr_len = ETH_HLEN;
  214. memcpy(hdrs->hdr[1].hdr, &hdr_ipv6, ETH_HLEN);
  215. res = ipa_add_hdr(hdrs);
  216. if (res || hdrs->hdr[0].status || hdrs->hdr[1].status)
  217. TETH_ERR("Header insertion failed\n");
  218. /* Save the headers handles in order to delete them later */
  219. for (idx1 = 0; idx1 < hdrs->num_hdrs; idx1++) {
  220. int idx2 = teth_ctx->hdr_del->num_hdls++;
  221. teth_ctx->hdr_del->hdl[idx2].hdl = hdrs->hdr[idx1].hdr_hdl;
  222. }
  223. kfree(hdrs);
  224. TETH_DBG_FUNC_EXIT();
  225. return res;
  226. }
  227. static int configure_ipa_header_block_internal(u32 usb_ipa_hdr_len,
  228. u32 a2_ipa_hdr_len,
  229. u32 ipa_usb_hdr_len,
  230. u32 ipa_a2_hdr_len)
  231. {
  232. struct ipa_ep_cfg_hdr hdr_cfg;
  233. int res;
  234. TETH_DBG_FUNC_ENTRY();
  235. /* Configure header removal for the USB->IPA pipe and A2->IPA pipe */
  236. memset(&hdr_cfg, 0, sizeof(hdr_cfg));
  237. hdr_cfg.hdr_len = usb_ipa_hdr_len;
  238. res = ipa_cfg_ep_hdr(teth_ctx->usb_ipa_pipe_hdl, &hdr_cfg);
  239. if (res) {
  240. TETH_ERR("Header removal config for USB->IPA pipe failed\n");
  241. goto bail;
  242. }
  243. hdr_cfg.hdr_len = a2_ipa_hdr_len;
  244. teth_ctx->a2_ipa_hdr_len = a2_ipa_hdr_len;
  245. res = ipa_cfg_ep_hdr(teth_ctx->a2_ipa_pipe_hdl, &hdr_cfg);
  246. if (res) {
  247. TETH_ERR("Header removal config for A2->IPA pipe failed\n");
  248. goto bail;
  249. }
  250. /* Configure header insertion for the IPA->USB pipe and IPA->A2 pipe */
  251. hdr_cfg.hdr_len = ipa_usb_hdr_len;
  252. res = ipa_cfg_ep_hdr(teth_ctx->ipa_usb_pipe_hdl, &hdr_cfg);
  253. if (res) {
  254. TETH_ERR("Header insertion config for IPA->USB pipe failed\n");
  255. goto bail;
  256. }
  257. hdr_cfg.hdr_len = ipa_a2_hdr_len;
  258. teth_ctx->ipa_a2_hdr_len = ipa_a2_hdr_len;
  259. res = ipa_cfg_ep_hdr(teth_ctx->ipa_a2_pipe_hdl, &hdr_cfg);
  260. if (res) {
  261. TETH_ERR("Header insertion config for IPA->A2 pipe failed\n");
  262. goto bail;
  263. }
  264. TETH_DBG_FUNC_EXIT();
  265. bail:
  266. return res;
  267. }
  268. static int add_mbim_hdr(void)
  269. {
  270. int res;
  271. struct ipa_ioc_add_hdr *mbim_hdr;
  272. u8 mbim_stream_id = 0;
  273. int idx;
  274. TETH_DBG_FUNC_ENTRY();
  275. mbim_hdr = kzalloc(sizeof(struct ipa_ioc_add_hdr) +
  276. sizeof(struct ipa_hdr_add),
  277. GFP_KERNEL);
  278. if (!mbim_hdr) {
  279. TETH_ERR("Failed allocating memory for MBIM header\n");
  280. return -ENOMEM;
  281. }
  282. mbim_hdr->commit = 0;
  283. mbim_hdr->num_hdrs = 1;
  284. strlcpy(mbim_hdr->hdr[0].name, MBIM_HEADER_NAME, IPA_RESOURCE_NAME_MAX);
  285. memcpy(mbim_hdr->hdr[0].hdr, &mbim_stream_id, sizeof(u8));
  286. mbim_hdr->hdr[0].hdr_len = sizeof(u8);
  287. mbim_hdr->hdr[0].is_partial = false;
  288. res = ipa_add_hdr(mbim_hdr);
  289. if (res || mbim_hdr->hdr[0].status) {
  290. TETH_ERR("Failed adding MBIM header\n");
  291. res = -EFAULT;
  292. } else {
  293. TETH_DBG("Added MBIM stream ID header\n");
  294. }
  295. /* Save the header handle in order to delete it later */
  296. idx = teth_ctx->hdr_del->num_hdls++;
  297. teth_ctx->hdr_del->hdl[idx].hdl = mbim_hdr->hdr[0].hdr_hdl;
  298. kfree(mbim_hdr);
  299. TETH_DBG_FUNC_EXIT();
  300. return res;
  301. }
  302. /**
  303. * configure_ipa_header_block() - adds headers and configures endpoint registers
  304. *
  305. * - For IP link protocol and MBIM aggregation, configure MBIM header
  306. * - For Ethernet link protocol, configure Ethernet headers
  307. */
  308. static int configure_ipa_header_block(void)
  309. {
  310. int res;
  311. u32 hdr_len = 0;
  312. u32 ipa_usb_hdr_len = 0;
  313. TETH_DBG_FUNC_ENTRY();
  314. if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_IP) {
  315. /*
  316. * Create a new header for MBIM stream ID and associate it with
  317. * the IPA->USB routing table
  318. */
  319. if (teth_ctx->aggr_params.dl.aggr_prot ==
  320. TETH_AGGR_PROTOCOL_MBIM) {
  321. ipa_usb_hdr_len = 1;
  322. res = add_mbim_hdr();
  323. if (res) {
  324. TETH_ERR("Failed adding MBIM header\n");
  325. goto bail;
  326. }
  327. }
  328. } else if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) {
  329. /* Add a header entry for USB */
  330. res = add_eth_hdrs(USB_ETH_HDR_NAME_IPV4,
  331. USB_ETH_HDR_NAME_IPV6,
  332. teth_ctx->mac_addresses.device_mac_addr,
  333. teth_ctx->mac_addresses.host_pc_mac_addr);
  334. if (res) {
  335. TETH_ERR("Failed adding USB Ethernet header\n");
  336. goto bail;
  337. }
  338. TETH_DBG("Added USB Ethernet headers (IPv4 / IPv6)\n");
  339. /* Add a header entry for A2 */
  340. res = add_eth_hdrs(A2_ETH_HDR_NAME_IPV4,
  341. A2_ETH_HDR_NAME_IPV6,
  342. teth_ctx->mac_addresses.host_pc_mac_addr,
  343. teth_ctx->mac_addresses.device_mac_addr);
  344. if (res) {
  345. TETH_ERR("Failed adding A2 Ethernet header\n");
  346. goto bail;
  347. }
  348. TETH_DBG("Added A2 Ethernet headers (IPv4 / IPv6\n");
  349. hdr_len = ETH_HLEN;
  350. ipa_usb_hdr_len = ETH_HLEN;
  351. }
  352. res = configure_ipa_header_block_internal(hdr_len,
  353. hdr_len,
  354. ipa_usb_hdr_len,
  355. hdr_len);
  356. if (res) {
  357. TETH_ERR("Configuration of header removal/insertion failed\n");
  358. goto bail;
  359. }
  360. TETH_DBG_FUNC_EXIT();
  361. bail:
  362. return res;
  363. }
  364. static int configure_routing_by_ip(char *hdr_name,
  365. char *rt_tbl_name,
  366. enum ipa_client_type dst,
  367. enum ipa_ip_type ip_address_family)
  368. {
  369. struct ipa_ioc_add_rt_rule *rt_rule;
  370. struct ipa_ioc_get_hdr hdr_info;
  371. int res;
  372. int idx;
  373. TETH_DBG_FUNC_ENTRY();
  374. /* Get the header handle */
  375. memset(&hdr_info, 0, sizeof(hdr_info));
  376. strlcpy(hdr_info.name, hdr_name, IPA_RESOURCE_NAME_MAX);
  377. ipa_get_hdr(&hdr_info);
  378. rt_rule = kzalloc(sizeof(struct ipa_ioc_add_rt_rule) +
  379. 1 * sizeof(struct ipa_rt_rule_add),
  380. GFP_KERNEL);
  381. if (!rt_rule) {
  382. TETH_ERR("Memory allocation failure");
  383. return -ENOMEM;
  384. }
  385. /* Match all, do not commit to HW*/
  386. rt_rule->commit = 0;
  387. rt_rule->num_rules = 1;
  388. rt_rule->ip = ip_address_family;
  389. strlcpy(rt_rule->rt_tbl_name, rt_tbl_name, IPA_RESOURCE_NAME_MAX);
  390. rt_rule->rules[0].rule.dst = dst;
  391. rt_rule->rules[0].rule.hdr_hdl = hdr_info.hdl;
  392. rt_rule->rules[0].rule.attrib.attrib_mask = 0; /* Match all */
  393. res = ipa_add_rt_rule(rt_rule);
  394. if (res || rt_rule->rules[0].status)
  395. TETH_ERR("Failed adding routing rule\n");
  396. /* Save the routing rule handle in order to delete it later */
  397. idx = teth_ctx->routing_del[ip_address_family]->num_hdls++;
  398. teth_ctx->routing_del[ip_address_family]->hdl[idx].hdl =
  399. rt_rule->rules[0].rt_rule_hdl;
  400. kfree(rt_rule);
  401. TETH_DBG_FUNC_EXIT();
  402. return res;
  403. }
  404. static int configure_routing(char *hdr_name_ipv4,
  405. char *rt_tbl_name_ipv4,
  406. char *hdr_name_ipv6,
  407. char *rt_tbl_name_ipv6,
  408. enum ipa_client_type dst)
  409. {
  410. int res;
  411. TETH_DBG_FUNC_ENTRY();
  412. /* Configure IPv4 routing table */
  413. res = configure_routing_by_ip(hdr_name_ipv4,
  414. rt_tbl_name_ipv4,
  415. dst,
  416. IPA_IP_v4);
  417. if (res) {
  418. TETH_ERR("Failed adding IPv4 routing table\n");
  419. goto bail;
  420. }
  421. /* Configure IPv6 routing table */
  422. res = configure_routing_by_ip(hdr_name_ipv6,
  423. rt_tbl_name_ipv6,
  424. dst,
  425. IPA_IP_v6);
  426. if (res) {
  427. TETH_ERR("Failed adding IPv6 routing table\n");
  428. goto bail;
  429. }
  430. TETH_DBG_FUNC_EXIT();
  431. bail:
  432. return res;
  433. }
  434. /**
  435. * configure_ipa_routing_block() - Configure the IPA routing block
  436. *
  437. * This function configures IPA for:
  438. * - Route all packets from USB to A2
  439. * - Route all packets from A2 to USB
  440. * - Use the correct headers in Ethernet or MBIM cases
  441. */
  442. static int configure_ipa_routing_block(void)
  443. {
  444. int res;
  445. char hdr_name_ipv4[IPA_RESOURCE_NAME_MAX];
  446. char hdr_name_ipv6[IPA_RESOURCE_NAME_MAX];
  447. TETH_DBG_FUNC_ENTRY();
  448. hdr_name_ipv4[0] = '\0';
  449. hdr_name_ipv6[0] = '\0';
  450. /* Configure USB -> A2 routing table */
  451. if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) {
  452. strlcpy(hdr_name_ipv4,
  453. A2_ETH_HDR_NAME_IPV4,
  454. IPA_RESOURCE_NAME_MAX);
  455. strlcpy(hdr_name_ipv6,
  456. A2_ETH_HDR_NAME_IPV6,
  457. IPA_RESOURCE_NAME_MAX);
  458. }
  459. res = configure_routing(hdr_name_ipv4,
  460. USB_TO_A2_RT_TBL_NAME_IPV4,
  461. hdr_name_ipv6,
  462. USB_TO_A2_RT_TBL_NAME_IPV6,
  463. IPA_CLIENT_A2_TETHERED_CONS);
  464. if (res) {
  465. TETH_ERR("USB to A2 routing block configuration failed\n");
  466. goto bail;
  467. }
  468. /* Configure A2 -> USB routing table */
  469. if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) {
  470. strlcpy(hdr_name_ipv4,
  471. USB_ETH_HDR_NAME_IPV4,
  472. IPA_RESOURCE_NAME_MAX);
  473. strlcpy(hdr_name_ipv6,
  474. USB_ETH_HDR_NAME_IPV6,
  475. IPA_RESOURCE_NAME_MAX);
  476. } else if (teth_ctx->aggr_params.dl.aggr_prot ==
  477. TETH_AGGR_PROTOCOL_MBIM) {
  478. strlcpy(hdr_name_ipv4,
  479. MBIM_HEADER_NAME,
  480. IPA_RESOURCE_NAME_MAX);
  481. strlcpy(hdr_name_ipv6,
  482. MBIM_HEADER_NAME,
  483. IPA_RESOURCE_NAME_MAX);
  484. }
  485. res = configure_routing(hdr_name_ipv4,
  486. A2_TO_USB_RT_TBL_NAME_IPV4,
  487. hdr_name_ipv6,
  488. A2_TO_USB_RT_TBL_NAME_IPV6,
  489. IPA_CLIENT_USB_CONS);
  490. if (res) {
  491. TETH_ERR("A2 to USB routing block configuration failed\n");
  492. goto bail;
  493. }
  494. TETH_DBG_FUNC_EXIT();
  495. bail:
  496. return res;
  497. }
  498. static int configure_filtering_by_ip(char *rt_tbl_name,
  499. enum ipa_client_type src,
  500. enum ipa_ip_type ip_address_family)
  501. {
  502. struct ipa_ioc_add_flt_rule *flt_tbl;
  503. struct ipa_ioc_get_rt_tbl rt_tbl_info;
  504. int res;
  505. int idx;
  506. TETH_DBG_FUNC_ENTRY();
  507. /* Get the needed routing table handle */
  508. rt_tbl_info.ip = ip_address_family;
  509. strlcpy(rt_tbl_info.name, rt_tbl_name, IPA_RESOURCE_NAME_MAX);
  510. res = ipa_get_rt_tbl(&rt_tbl_info);
  511. if (res) {
  512. TETH_ERR("Failed getting routing table handle\n");
  513. goto bail;
  514. }
  515. flt_tbl = kzalloc(sizeof(struct ipa_ioc_add_flt_rule) +
  516. 1 * sizeof(struct ipa_flt_rule_add), GFP_KERNEL);
  517. if (!flt_tbl) {
  518. TETH_ERR("Filtering table memory allocation failure\n");
  519. return -ENOMEM;
  520. }
  521. flt_tbl->commit = 0;
  522. flt_tbl->ep = src;
  523. flt_tbl->global = 0;
  524. flt_tbl->ip = ip_address_family;
  525. flt_tbl->num_rules = 1;
  526. flt_tbl->rules[0].rule.action = IPA_PASS_TO_ROUTING;
  527. flt_tbl->rules[0].rule.rt_tbl_hdl = rt_tbl_info.hdl;
  528. flt_tbl->rules[0].rule.attrib.attrib_mask = 0; /* Match all */
  529. res = ipa_add_flt_rule(flt_tbl);
  530. if (res || flt_tbl->rules[0].status)
  531. TETH_ERR("Failed adding filtering table\n");
  532. /* Save the filtering rule handle in order to delete it later */
  533. idx = teth_ctx->filtering_del[ip_address_family]->num_hdls++;
  534. teth_ctx->filtering_del[ip_address_family]->hdl[idx].hdl =
  535. flt_tbl->rules[0].flt_rule_hdl;
  536. kfree(flt_tbl);
  537. TETH_DBG_FUNC_EXIT();
  538. bail:
  539. return res;
  540. }
  541. static int configure_filtering(char *rt_tbl_name_ipv4,
  542. char *rt_tbl_name_ipv6,
  543. enum ipa_client_type src)
  544. {
  545. int res;
  546. TETH_DBG_FUNC_ENTRY();
  547. res = configure_filtering_by_ip(rt_tbl_name_ipv4, src, IPA_IP_v4);
  548. if (res) {
  549. TETH_ERR("Failed adding IPv4 filtering table\n");
  550. goto bail;
  551. }
  552. res = configure_filtering_by_ip(rt_tbl_name_ipv6, src, IPA_IP_v6);
  553. if (res) {
  554. TETH_ERR("Failed adding IPv4 filtering table\n");
  555. goto bail;
  556. }
  557. TETH_DBG_FUNC_EXIT();
  558. bail:
  559. return res;
  560. }
  561. /**
  562. * configure_ipa_filtering_block() - Configures IPA filtering block
  563. *
  564. * This function configures IPA for:
  565. * - Filter all traffic coming from USB to A2 pointing routing table
  566. * - Filter all traffic coming from A2 to USB pointing routing table
  567. */
  568. static int configure_ipa_filtering_block(void)
  569. {
  570. int res;
  571. TETH_DBG_FUNC_ENTRY();
  572. /* Filter all traffic coming from USB to A2 */
  573. res = configure_filtering(USB_TO_A2_RT_TBL_NAME_IPV4,
  574. USB_TO_A2_RT_TBL_NAME_IPV6,
  575. IPA_CLIENT_USB_PROD);
  576. if (res) {
  577. TETH_ERR("USB_PROD ep filtering configuration failed\n");
  578. goto bail;
  579. }
  580. /* Filter all traffic coming from A2 to USB */
  581. res = configure_filtering(A2_TO_USB_RT_TBL_NAME_IPV4,
  582. A2_TO_USB_RT_TBL_NAME_IPV6,
  583. IPA_CLIENT_A2_TETHERED_PROD);
  584. if (res) {
  585. TETH_ERR("A2_PROD filtering configuration failed\n");
  586. goto bail;
  587. }
  588. TETH_DBG_FUNC_EXIT();
  589. bail:
  590. return res;
  591. }
  592. static int prepare_ipa_aggr_struct(
  593. const struct teth_aggr_params_link *teth_aggr_params,
  594. struct ipa_ep_cfg_aggr *ipa_aggr_params,
  595. bool client_is_prod)
  596. {
  597. TETH_DBG_FUNC_ENTRY();
  598. memset(ipa_aggr_params, 0, sizeof(*ipa_aggr_params));
  599. switch (teth_aggr_params->aggr_prot) {
  600. case TETH_AGGR_PROTOCOL_NONE:
  601. ipa_aggr_params->aggr_en = IPA_BYPASS_AGGR;
  602. break;
  603. case TETH_AGGR_PROTOCOL_MBIM:
  604. ipa_aggr_params->aggr = IPA_MBIM_16;
  605. ipa_aggr_params->aggr_en = (client_is_prod) ?
  606. IPA_ENABLE_DEAGGR : IPA_ENABLE_AGGR;
  607. break;
  608. case TETH_AGGR_PROTOCOL_TLP:
  609. ipa_aggr_params->aggr = IPA_TLP;
  610. ipa_aggr_params->aggr_en = (client_is_prod) ?
  611. IPA_ENABLE_DEAGGR : IPA_ENABLE_AGGR;
  612. break;
  613. default:
  614. TETH_ERR("Unsupported aggregation protocol\n");
  615. return -EFAULT;
  616. }
  617. /*
  618. * Due to a HW 'feature', the maximal aggregated packet size may be the
  619. * requested aggr_byte_limit plus the MTU. Therefore, the MTU is
  620. * subtracted from the requested aggr_byte_limit so that the requested
  621. * byte limit is honored .
  622. */
  623. ipa_aggr_params->aggr_byte_limit =
  624. (teth_aggr_params->max_transfer_size_byte - TETH_MTU_BYTE) /
  625. 1024;
  626. ipa_aggr_params->aggr_time_limit = TETH_DEFAULT_AGGR_TIME_LIMIT;
  627. TETH_DBG_FUNC_EXIT();
  628. return 0;
  629. }
  630. static int teth_set_aggr_per_ep(
  631. const struct teth_aggr_params_link *teth_aggr_params,
  632. bool client_is_prod,
  633. u32 pipe_hdl)
  634. {
  635. struct ipa_ep_cfg_aggr agg_params;
  636. int res;
  637. TETH_DBG_FUNC_ENTRY();
  638. res = prepare_ipa_aggr_struct(teth_aggr_params,
  639. &agg_params,
  640. client_is_prod);
  641. if (res) {
  642. TETH_ERR("prepare_ipa_aggregation_struct() failed\n");
  643. goto bail;
  644. }
  645. res = ipa_cfg_ep_aggr(pipe_hdl, &agg_params);
  646. if (res) {
  647. TETH_ERR("ipa_cfg_ep_aggr() failed\n");
  648. goto bail;
  649. }
  650. TETH_DBG_FUNC_EXIT();
  651. bail:
  652. return res;
  653. }
  654. static void aggr_prot_to_str(enum teth_aggr_protocol_type aggr_prot,
  655. char *buff,
  656. uint buff_size)
  657. {
  658. switch (aggr_prot) {
  659. case TETH_AGGR_PROTOCOL_NONE:
  660. strlcpy(buff, "NONE", buff_size);
  661. break;
  662. case TETH_AGGR_PROTOCOL_MBIM:
  663. strlcpy(buff, "MBIM", buff_size);
  664. break;
  665. case TETH_AGGR_PROTOCOL_TLP:
  666. strlcpy(buff, "TLP", buff_size);
  667. break;
  668. default:
  669. strlcpy(buff, "ERROR", buff_size);
  670. break;
  671. }
  672. }
  673. /**
  674. * teth_set_aggregation() - set aggregation parameters to IPA
  675. *
  676. * The parameters to this function are passed in the context variable ipa_ctx.
  677. */
  678. static int teth_set_aggregation(void)
  679. {
  680. int res;
  681. char aggr_prot_str[20];
  682. TETH_DBG_FUNC_ENTRY();
  683. if (!teth_ctx->aggr_params_known) {
  684. TETH_ERR("Aggregation parameters unknown.\n");
  685. return -EINVAL;
  686. }
  687. if ((teth_ctx->usb_ipa_pipe_hdl == 0) ||
  688. (teth_ctx->ipa_usb_pipe_hdl == 0))
  689. return 0;
  690. /*
  691. * Returning 0 in case pipe handles are 0 becuase aggregation
  692. * params will be set later
  693. */
  694. if (teth_ctx->aggr_params.ul.aggr_prot == TETH_AGGR_PROTOCOL_MBIM ||
  695. teth_ctx->aggr_params.dl.aggr_prot == TETH_AGGR_PROTOCOL_MBIM) {
  696. res = ipa_set_aggr_mode(IPA_MBIM);
  697. if (res) {
  698. TETH_ERR("ipa_set_aggr_mode() failed\n");
  699. goto bail;
  700. }
  701. res = ipa_set_single_ndp_per_mbim(false);
  702. if (res) {
  703. TETH_ERR("ipa_set_single_ndp_per_mbim() failed\n");
  704. goto bail;
  705. }
  706. }
  707. aggr_prot_to_str(teth_ctx->aggr_params.ul.aggr_prot,
  708. aggr_prot_str,
  709. sizeof(aggr_prot_str)-1);
  710. TETH_DBG("Setting %s aggregation on UL\n", aggr_prot_str);
  711. aggr_prot_to_str(teth_ctx->aggr_params.dl.aggr_prot,
  712. aggr_prot_str,
  713. sizeof(aggr_prot_str)-1);
  714. TETH_DBG("Setting %s aggregation on DL\n", aggr_prot_str);
  715. /* Configure aggregation on UL producer (USB->IPA) */
  716. res = teth_set_aggr_per_ep(&teth_ctx->aggr_params.ul,
  717. true,
  718. teth_ctx->usb_ipa_pipe_hdl);
  719. if (res) {
  720. TETH_ERR("teth_set_aggregation_per_ep() failed\n");
  721. goto bail;
  722. }
  723. /* Configure aggregation on DL consumer (IPA->USB) */
  724. res = teth_set_aggr_per_ep(&teth_ctx->aggr_params.dl,
  725. false,
  726. teth_ctx->ipa_usb_pipe_hdl);
  727. if (res) {
  728. TETH_ERR("teth_set_aggregation_per_ep() failed\n");
  729. goto bail;
  730. }
  731. TETH_DBG_FUNC_EXIT();
  732. bail:
  733. return res;
  734. }
  735. /**
  736. * teth_request_resource() - wrapper function to
  737. * ipa_rm_inactivity_timer_request_resource()
  738. *
  739. * - initialize the is_bridge_prod_up completion object
  740. * - request the resource
  741. * - error handling
  742. */
  743. static int teth_request_resource(void)
  744. {
  745. int res;
  746. INIT_COMPLETION(teth_ctx->is_bridge_prod_up);
  747. res = ipa_rm_inactivity_timer_request_resource(
  748. IPA_RM_RESOURCE_BRIDGE_PROD);
  749. if (res < 0) {
  750. if (res == -EINPROGRESS)
  751. wait_for_completion(&teth_ctx->is_bridge_prod_up);
  752. else
  753. return res;
  754. }
  755. return 0;
  756. }
  757. /**
  758. * complete_hw_bridge() - setup the HW bridge from USB to A2 and back through
  759. * IPA
  760. */
  761. static void complete_hw_bridge(struct work_struct *work)
  762. {
  763. int res;
  764. TETH_DBG_FUNC_ENTRY();
  765. TETH_DBG("Completing HW bridge in %s mode\n",
  766. (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) ?
  767. "ETHERNET" :
  768. "IP");
  769. res = teth_request_resource();
  770. if (res) {
  771. TETH_ERR("request_resource() failed.\n");
  772. goto bail;
  773. }
  774. res = teth_set_aggregation();
  775. if (res) {
  776. TETH_ERR("Failed setting aggregation params\n");
  777. goto bail;
  778. }
  779. res = configure_ipa_header_block();
  780. if (res) {
  781. TETH_ERR("Configuration of IPA header block Failed\n");
  782. goto bail;
  783. }
  784. res = configure_ipa_routing_block();
  785. if (res) {
  786. TETH_ERR("Configuration of IPA routing block Failed\n");
  787. goto bail;
  788. }
  789. res = configure_ipa_filtering_block();
  790. if (res) {
  791. TETH_ERR("Configuration of IPA filtering block Failed\n");
  792. goto bail;
  793. }
  794. /*
  795. * Commit all the data to HW, including header, routing and filtering
  796. * blocks, IPv4 and IPv6
  797. */
  798. res = ipa_commit_hdr();
  799. if (res) {
  800. TETH_ERR("Failed committing headers / routing / filtering.\n");
  801. goto bail;
  802. }
  803. teth_ctx->is_hw_bridge_complete = true;
  804. bail:
  805. teth_ctx->comp_hw_bridge_in_progress = false;
  806. ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
  807. TETH_DBG_FUNC_EXIT();
  808. return;
  809. }
  810. static void mac_addr_to_str(u8 mac_addr[ETH_ALEN],
  811. char *buff,
  812. uint buff_size)
  813. {
  814. scnprintf(buff, buff_size, "%02x-%02x-%02x-%02x-%02x-%02x",
  815. mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
  816. mac_addr[4], mac_addr[5]);
  817. }
  818. /**
  819. * check_to_complete_hw_bridge() - can HW bridge be set up ?
  820. * @param skb: pointer to socket buffer
  821. * @param my_mac_addr: pointer to write 'my' extracted MAC address to
  822. * @param my_mac_addr_known: pointer to update whether 'my' extracted MAC
  823. * address is known
  824. * @param peer_mac_addr_known: pointer to update whether the 'peer' extracted
  825. * MAC address is known
  826. *
  827. * This function is used by both A2 and USB callback functions, therefore the
  828. * meaning of 'my' and 'peer' changes according to the context.
  829. * Extracts MAC address from the packet in Ethernet link protocol,
  830. * Sets up the HW bridge in case all conditions are met.
  831. */
  832. static void check_to_complete_hw_bridge(struct sk_buff *skb,
  833. u8 *my_mac_addr,
  834. bool *my_mac_addr_known,
  835. bool *peer_mac_addr_known)
  836. {
  837. bool both_mac_addresses_known;
  838. char mac_addr_str[20];
  839. if ((teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET) &&
  840. (!(*my_mac_addr_known))) {
  841. memcpy(my_mac_addr, &skb->data[ETH_ALEN], ETH_ALEN);
  842. mac_addr_to_str(my_mac_addr,
  843. mac_addr_str,
  844. sizeof(mac_addr_str)-1);
  845. TETH_DBG("Extracted MAC addr: %s\n", mac_addr_str);
  846. *my_mac_addr_known = true;
  847. }
  848. both_mac_addresses_known = *my_mac_addr_known && *peer_mac_addr_known;
  849. if ((both_mac_addresses_known ||
  850. (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_IP)) &&
  851. (!teth_ctx->comp_hw_bridge_in_progress) &&
  852. (teth_ctx->aggr_params_known)) {
  853. INIT_WORK(&teth_ctx->comp_hw_bridge_work, complete_hw_bridge);
  854. teth_ctx->comp_hw_bridge_in_progress = true;
  855. queue_work(teth_ctx->teth_wq, &teth_ctx->comp_hw_bridge_work);
  856. }
  857. }
  858. /**
  859. * teth_send_skb_work() - workqueue function for sending a packet
  860. */
  861. static void teth_send_skb_work(struct work_struct *work)
  862. {
  863. struct teth_work *work_data =
  864. container_of(work, struct teth_work, work);
  865. int res;
  866. res = teth_request_resource();
  867. if (res) {
  868. TETH_ERR("Packet send failure, dropping packet !\n");
  869. goto bail;
  870. }
  871. switch (work_data->dir) {
  872. case TETH_USB_TO_A2:
  873. res = a2_mux_write(A2_MUX_TETHERED_0, work_data->skb);
  874. if (res) {
  875. TETH_ERR("Packet send failure, dropping packet !\n");
  876. goto bail;
  877. }
  878. teth_ctx->stats.usb_to_a2_num_sw_tx_packets++;
  879. break;
  880. case TETH_A2_TO_USB:
  881. res = ipa_tx_dp(IPA_CLIENT_USB_CONS, work_data->skb, NULL);
  882. if (res) {
  883. TETH_ERR("Packet send failure, dropping packet !\n");
  884. goto bail;
  885. }
  886. teth_ctx->stats.a2_to_usb_num_sw_tx_packets++;
  887. break;
  888. default:
  889. TETH_ERR("Unsupported direction to send !\n");
  890. WARN_ON(1);
  891. }
  892. ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
  893. kfree(work_data);
  894. teth_ctx->stats.num_sw_tx_packets_during_resource_wakeup++;
  895. return;
  896. bail:
  897. ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
  898. dev_kfree_skb(work_data->skb);
  899. kfree(work_data);
  900. }
  901. /**
  902. * defer_skb_send() - defer sending an skb using the SW bridge to a workqueue
  903. * @param skb: pointer to the socket buffer
  904. * @param dir: direction of send
  905. *
  906. * In case where during a packet send, the A2 or USB needs to wake up from power
  907. * collapse, defer the send and return the context to IPA driver. This is
  908. * important since IPA driver has a single threaded Rx path.
  909. */
  910. static void defer_skb_send(struct sk_buff *skb, enum teth_packet_direction dir)
  911. {
  912. struct teth_work *work = kmalloc(sizeof(struct teth_work), GFP_KERNEL);
  913. if (!work) {
  914. TETH_ERR("No mem, dropping packet\n");
  915. dev_kfree_skb(skb);
  916. ipa_rm_inactivity_timer_release_resource
  917. (IPA_RM_RESOURCE_BRIDGE_PROD);
  918. return;
  919. }
  920. /*
  921. * Since IPA uses a single Rx thread, we don't
  922. * want to wait for completion here
  923. */
  924. INIT_WORK(&work->work, teth_send_skb_work);
  925. work->dir = dir;
  926. work->skb = skb;
  927. queue_work(teth_ctx->teth_wq, &work->work);
  928. }
  929. /**
  930. * usb_notify_cb() - callback function for sending packets from USB to A2
  931. * @param priv: private data
  932. * @param evt: event - RECEIVE or WRITE_DONE
  933. * @param data: pointer to skb to be sent
  934. *
  935. * This callback function is installed by the IPA driver, it is invoked in 2
  936. * cases:
  937. * 1. When a packet comes from the USB pipe and is routed to A5 (SW bridging)
  938. * 2. After a packet has been bridged from USB to A2 and its skb should be freed
  939. *
  940. * Invocation: sps driver --> IPA driver --> bridge driver
  941. *
  942. * In the event of IPA_RECEIVE:
  943. * - Checks whether the HW bridge can be set up..
  944. * - Requests the BRIDGE_PROD resource so that A2 and USB are not in power
  945. * collapse. In case where the resource is waking up, defer the send operation
  946. * to a workqueue in order to not block the IPA driver single threaded Rx path.
  947. * - Sends the packets to A2 using a2_service driver API.
  948. * - Releases the BRIDGE_PROD resource.
  949. *
  950. * In the event of IPA_WRITE_DONE:
  951. * - Frees the skb memory
  952. */
  953. static void usb_notify_cb(void *priv,
  954. enum ipa_dp_evt_type evt,
  955. unsigned long data)
  956. {
  957. struct sk_buff *skb = (struct sk_buff *)data;
  958. int res;
  959. switch (evt) {
  960. case IPA_RECEIVE:
  961. if (!teth_ctx->is_hw_bridge_complete)
  962. check_to_complete_hw_bridge(
  963. skb,
  964. teth_ctx->mac_addresses.host_pc_mac_addr,
  965. &teth_ctx->mac_addresses.host_pc_mac_addr_known,
  966. &teth_ctx->mac_addresses.device_mac_addr_known);
  967. /*
  968. * Request the BRIDGE_PROD resource, send the packet and release
  969. * the resource
  970. */
  971. res = ipa_rm_inactivity_timer_request_resource(
  972. IPA_RM_RESOURCE_BRIDGE_PROD);
  973. if (res < 0) {
  974. if (res == -EINPROGRESS) {
  975. /* The resource is waking up */
  976. defer_skb_send(skb, TETH_USB_TO_A2);
  977. } else {
  978. TETH_ERR(
  979. "Packet send failure, dropping packet !\n");
  980. dev_kfree_skb(skb);
  981. }
  982. ipa_rm_inactivity_timer_release_resource(
  983. IPA_RM_RESOURCE_BRIDGE_PROD);
  984. return;
  985. }
  986. res = a2_mux_write(A2_MUX_TETHERED_0, skb);
  987. if (res) {
  988. TETH_ERR("Packet send failure, dropping packet !\n");
  989. dev_kfree_skb(skb);
  990. ipa_rm_inactivity_timer_release_resource(
  991. IPA_RM_RESOURCE_BRIDGE_PROD);
  992. return;
  993. }
  994. teth_ctx->stats.usb_to_a2_num_sw_tx_packets++;
  995. ipa_rm_inactivity_timer_release_resource(
  996. IPA_RM_RESOURCE_BRIDGE_PROD);
  997. break;
  998. case IPA_WRITE_DONE:
  999. dev_kfree_skb(skb);
  1000. break;
  1001. default:
  1002. TETH_ERR("Unsupported IPA event !\n");
  1003. WARN_ON(1);
  1004. }
  1005. return;
  1006. }
  1007. /**
  1008. * a2_notify_cb() - callback function for sending packets from A2 to USB
  1009. * @param user_data: private data
  1010. * @param event: event - RECEIVE or WRITE_DONE
  1011. * @param data: pointer to skb to be sent
  1012. *
  1013. * This callback function is installed by the IPA driver, it is invoked in 2
  1014. * cases:
  1015. * 1. When a packet comes from the A2 pipe and is routed to A5 (SW bridging)
  1016. * 2. After a packet has been bridged from A2 to USB and its skb should be freed
  1017. *
  1018. * Invocation: sps driver --> IPA driver --> a2_service driver --> bridge driver
  1019. *
  1020. * In the event of A2_MUX_RECEIVE:
  1021. * - Checks whether the HW bridge can be set up..
  1022. * - Requests the BRIDGE_PROD resource so that A2 and USB are not in power
  1023. * collapse. In case where the resource is waking up, defer the send operation
  1024. * to a workqueue in order to not block the IPA driver single threaded Rx path.
  1025. * - Sends the packets to USB using IPA drivers ipa_tx_dp() API.
  1026. * - Releases the BRIDGE_PROD resource.
  1027. *
  1028. * In the event of A2_MUX_WRITE_DONE:
  1029. * - Frees the skb memory
  1030. */
  1031. static void a2_notify_cb(void *user_data,
  1032. enum a2_mux_event_type event,
  1033. unsigned long data)
  1034. {
  1035. struct sk_buff *skb = (struct sk_buff *)data;
  1036. int res;
  1037. switch (event) {
  1038. case A2_MUX_RECEIVE:
  1039. if (!teth_ctx->is_hw_bridge_complete)
  1040. check_to_complete_hw_bridge(
  1041. skb,
  1042. teth_ctx->mac_addresses.device_mac_addr,
  1043. &teth_ctx->mac_addresses.device_mac_addr_known,
  1044. &teth_ctx->
  1045. mac_addresses.host_pc_mac_addr_known);
  1046. /*
  1047. * Request the BRIDGE_PROD resource, send the packet and release
  1048. * the resource
  1049. */
  1050. res = ipa_rm_inactivity_timer_request_resource(
  1051. IPA_RM_RESOURCE_BRIDGE_PROD);
  1052. if (res < 0) {
  1053. if (res == -EINPROGRESS) {
  1054. /* The resource is waking up */
  1055. defer_skb_send(skb, TETH_A2_TO_USB);
  1056. } else {
  1057. TETH_ERR(
  1058. "Packet send failure, dropping packet !\n");
  1059. dev_kfree_skb(skb);
  1060. }
  1061. ipa_rm_inactivity_timer_release_resource(
  1062. IPA_RM_RESOURCE_BRIDGE_PROD);
  1063. return;
  1064. }
  1065. res = ipa_tx_dp(IPA_CLIENT_USB_CONS, skb, NULL);
  1066. if (res) {
  1067. TETH_ERR("Packet send failure, dropping packet !\n");
  1068. dev_kfree_skb(skb);
  1069. ipa_rm_inactivity_timer_release_resource(
  1070. IPA_RM_RESOURCE_BRIDGE_PROD);
  1071. return;
  1072. }
  1073. teth_ctx->stats.a2_to_usb_num_sw_tx_packets++;
  1074. ipa_rm_inactivity_timer_release_resource(
  1075. IPA_RM_RESOURCE_BRIDGE_PROD);
  1076. break;
  1077. case A2_MUX_WRITE_DONE:
  1078. dev_kfree_skb(skb);
  1079. break;
  1080. default:
  1081. TETH_ERR("Unsupported IPA event !\n");
  1082. WARN_ON(1);
  1083. }
  1084. return;
  1085. }
  1086. /**
  1087. * bridge_prod_notify_cb() - IPA Resource Manager callback function
  1088. * @param notify_cb_data: private data
  1089. * @param event: RESOURCE_GRANTED / RESOURCE_RELEASED
  1090. * @param data: not used in this case
  1091. *
  1092. * This callback function is called by IPA resource manager to notify the
  1093. * BRIDGE_PROD entity of events like RESOURCE_GRANTED and RESOURCE_RELEASED.
  1094. */
  1095. static void bridge_prod_notify_cb(void *notify_cb_data,
  1096. enum ipa_rm_event event,
  1097. unsigned long data)
  1098. {
  1099. switch (event) {
  1100. case IPA_RM_RESOURCE_GRANTED:
  1101. complete(&teth_ctx->is_bridge_prod_up);
  1102. break;
  1103. case IPA_RM_RESOURCE_RELEASED:
  1104. complete(&teth_ctx->is_bridge_prod_down);
  1105. break;
  1106. default:
  1107. TETH_ERR("Unsupported notification!\n");
  1108. WARN_ON(1);
  1109. break;
  1110. }
  1111. return;
  1112. }
  1113. static void a2_prod_notify_cb(void *notify_cb_data,
  1114. enum ipa_rm_event event,
  1115. unsigned long data)
  1116. {
  1117. int res;
  1118. struct ipa_ep_cfg ipa_ep_cfg;
  1119. switch (event) {
  1120. case IPA_RM_RESOURCE_GRANTED:
  1121. res = a2_mux_get_tethered_client_handles(
  1122. A2_MUX_TETHERED_0,
  1123. &teth_ctx->ipa_a2_pipe_hdl,
  1124. &teth_ctx->a2_ipa_pipe_hdl);
  1125. if (res) {
  1126. TETH_ERR(
  1127. "a2_mux_get_tethered_client_handles() failed, res = %d\n",
  1128. res);
  1129. return;
  1130. }
  1131. /* Reset the various endpoints configuration */
  1132. memset(&ipa_ep_cfg, 0, sizeof(ipa_ep_cfg));
  1133. ipa_ep_cfg.hdr.hdr_len = teth_ctx->ipa_a2_hdr_len;
  1134. ipa_cfg_ep(teth_ctx->ipa_a2_pipe_hdl, &ipa_ep_cfg);
  1135. memset(&ipa_ep_cfg, 0, sizeof(ipa_ep_cfg));
  1136. ipa_ep_cfg.hdr.hdr_len = teth_ctx->a2_ipa_hdr_len;
  1137. ipa_cfg_ep(teth_ctx->a2_ipa_pipe_hdl, &ipa_ep_cfg);
  1138. break;
  1139. case IPA_RM_RESOURCE_RELEASED:
  1140. break;
  1141. default:
  1142. TETH_ERR("Unsupported notification!\n");
  1143. WARN_ON(1);
  1144. break;
  1145. }
  1146. return;
  1147. }
  1148. /**
  1149. * teth_bridge_init() - Initialize the Tethering bridge driver
  1150. * @usb_notify_cb_ptr: Callback function which should be used by the caller.
  1151. * Output parameter.
  1152. * @private_data_ptr: Data for the callback function. Should be used by the
  1153. * caller. Output parameter.
  1154. *
  1155. * USB driver gets a pointer to a callback function (usb_notify_cb) and an
  1156. * associated data. USB driver installs this callback function in the call to
  1157. * ipa_connect().
  1158. *
  1159. * Builds IPA resource manager dependency graph.
  1160. *
  1161. * Return codes: 0: success,
  1162. * -EINVAL - Bad parameter
  1163. * Other negative value - Failure
  1164. */
  1165. int teth_bridge_init(ipa_notify_cb *usb_notify_cb_ptr, void **private_data_ptr)
  1166. {
  1167. int res = 0;
  1168. struct ipa_rm_register_params a2_prod_reg_params;
  1169. TETH_DBG_FUNC_ENTRY();
  1170. if (usb_notify_cb_ptr == NULL) {
  1171. TETH_ERR("Bad parameter\n");
  1172. res = -EINVAL;
  1173. goto bail;
  1174. }
  1175. *usb_notify_cb_ptr = usb_notify_cb;
  1176. *private_data_ptr = NULL;
  1177. /* Build IPA Resource manager dependency graph */
  1178. res = ipa_rm_add_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
  1179. IPA_RM_RESOURCE_USB_CONS);
  1180. if (res && res != -EINPROGRESS) {
  1181. TETH_ERR("ipa_rm_add_dependency() failed\n");
  1182. goto bail;
  1183. }
  1184. res = ipa_rm_add_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
  1185. IPA_RM_RESOURCE_A2_CONS);
  1186. if (res && res != -EINPROGRESS) {
  1187. TETH_ERR("ipa_rm_add_dependency() failed\n");
  1188. goto fail_add_dependency_1;
  1189. }
  1190. res = ipa_rm_add_dependency(IPA_RM_RESOURCE_USB_PROD,
  1191. IPA_RM_RESOURCE_A2_CONS);
  1192. if (res && res != -EINPROGRESS) {
  1193. TETH_ERR("ipa_rm_add_dependency() failed\n");
  1194. goto fail_add_dependency_2;
  1195. }
  1196. res = ipa_rm_add_dependency(IPA_RM_RESOURCE_A2_PROD,
  1197. IPA_RM_RESOURCE_USB_CONS);
  1198. if (res && res != -EINPROGRESS) {
  1199. TETH_ERR("ipa_rm_add_dependency() failed\n");
  1200. goto fail_add_dependency_3;
  1201. }
  1202. /* Register for A2_PROD resource notifications */
  1203. a2_prod_reg_params.user_data = NULL;
  1204. a2_prod_reg_params.notify_cb = a2_prod_notify_cb;
  1205. res = ipa_rm_register(IPA_RM_RESOURCE_A2_PROD, &a2_prod_reg_params);
  1206. if (res) {
  1207. TETH_ERR("ipa_rm_register() failed\n");
  1208. goto fail_add_dependency_4;
  1209. }
  1210. /* Return 0 as EINPROGRESS is a valid return value at this point */
  1211. res = 0;
  1212. goto bail;
  1213. fail_add_dependency_4:
  1214. ipa_rm_delete_dependency(IPA_RM_RESOURCE_A2_PROD,
  1215. IPA_RM_RESOURCE_USB_CONS);
  1216. fail_add_dependency_3:
  1217. ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD,
  1218. IPA_RM_RESOURCE_A2_CONS);
  1219. fail_add_dependency_2:
  1220. ipa_rm_delete_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
  1221. IPA_RM_RESOURCE_A2_CONS);
  1222. fail_add_dependency_1:
  1223. ipa_rm_delete_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
  1224. IPA_RM_RESOURCE_USB_CONS);
  1225. bail:
  1226. TETH_DBG_FUNC_EXIT();
  1227. return res;
  1228. }
  1229. EXPORT_SYMBOL(teth_bridge_init);
  1230. /**
  1231. * initialize_context() - Initialize the ipa_ctx struct
  1232. */
  1233. static void initialize_context(void)
  1234. {
  1235. TETH_DBG_FUNC_ENTRY();
  1236. /* Initialize context variables */
  1237. teth_ctx->usb_ipa_pipe_hdl = 0;
  1238. teth_ctx->ipa_a2_pipe_hdl = 0;
  1239. teth_ctx->a2_ipa_pipe_hdl = 0;
  1240. teth_ctx->ipa_usb_pipe_hdl = 0;
  1241. teth_ctx->is_connected = false;
  1242. /* The default link protocol is Ethernet */
  1243. teth_ctx->link_protocol = TETH_LINK_PROTOCOL_ETHERNET;
  1244. memset(&teth_ctx->mac_addresses, 0, sizeof(teth_ctx->mac_addresses));
  1245. teth_ctx->is_hw_bridge_complete = false;
  1246. memset(&teth_ctx->aggr_params, 0, sizeof(teth_ctx->aggr_params));
  1247. teth_ctx->aggr_params_known = false;
  1248. teth_ctx->tethering_mode = 0;
  1249. INIT_COMPLETION(teth_ctx->is_bridge_prod_up);
  1250. INIT_COMPLETION(teth_ctx->is_bridge_prod_down);
  1251. teth_ctx->comp_hw_bridge_in_progress = false;
  1252. memset(&teth_ctx->stats, 0, sizeof(teth_ctx->stats));
  1253. teth_ctx->a2_ipa_hdr_len = 0;
  1254. teth_ctx->ipa_a2_hdr_len = 0;
  1255. memset(teth_ctx->hdr_del,
  1256. 0,
  1257. sizeof(struct ipa_ioc_del_hdr) + TETH_TOTAL_HDR_ENTRIES *
  1258. sizeof(struct ipa_hdr_del));
  1259. memset(teth_ctx->routing_del[IPA_IP_v4],
  1260. 0,
  1261. sizeof(struct ipa_ioc_del_rt_rule) +
  1262. TETH_TOTAL_RT_ENTRIES_IP * sizeof(struct ipa_rt_rule_del));
  1263. teth_ctx->routing_del[IPA_IP_v4]->ip = IPA_IP_v4;
  1264. memset(teth_ctx->routing_del[IPA_IP_v6],
  1265. 0,
  1266. sizeof(struct ipa_ioc_del_rt_rule) +
  1267. TETH_TOTAL_RT_ENTRIES_IP * sizeof(struct ipa_rt_rule_del));
  1268. teth_ctx->routing_del[IPA_IP_v6]->ip = IPA_IP_v6;
  1269. memset(teth_ctx->filtering_del[IPA_IP_v4],
  1270. 0,
  1271. sizeof(struct ipa_ioc_del_flt_rule) +
  1272. TETH_TOTAL_FLT_ENTRIES_IP * sizeof(struct ipa_flt_rule_del));
  1273. teth_ctx->filtering_del[IPA_IP_v4]->ip = IPA_IP_v4;
  1274. memset(teth_ctx->filtering_del[IPA_IP_v6],
  1275. 0,
  1276. sizeof(struct ipa_ioc_del_flt_rule) +
  1277. TETH_TOTAL_FLT_ENTRIES_IP * sizeof(struct ipa_flt_rule_del));
  1278. teth_ctx->filtering_del[IPA_IP_v6]->ip = IPA_IP_v6;
  1279. TETH_DBG_FUNC_EXIT();
  1280. }
  1281. /**
  1282. * teth_bridge_disconnect() - Disconnect tethering bridge module
  1283. */
  1284. int teth_bridge_disconnect(void)
  1285. {
  1286. int res;
  1287. struct ipa_rm_register_params a2_prod_reg_params;
  1288. TETH_DBG_FUNC_ENTRY();
  1289. if (!teth_ctx->is_connected) {
  1290. TETH_ERR(
  1291. "Trying to disconnect an already disconnected bridge\n");
  1292. goto bail;
  1293. }
  1294. /*
  1295. * Delete part of IPA resource manager dependency graph. Only the
  1296. * BRIDGE_PROD <-> A2 dependency remains intact
  1297. */
  1298. res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
  1299. IPA_RM_RESOURCE_USB_CONS);
  1300. if ((res != 0) && (res != -EINPROGRESS))
  1301. TETH_ERR(
  1302. "Failed deleting ipa_rm dependency BRIDGE_PROD <-> USB_CONS\n");
  1303. res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD,
  1304. IPA_RM_RESOURCE_A2_CONS);
  1305. if ((res != 0) && (res != -EINPROGRESS))
  1306. TETH_ERR(
  1307. "Failed deleting ipa_rm dependency USB_PROD <-> A2_CONS\n");
  1308. res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_A2_PROD,
  1309. IPA_RM_RESOURCE_USB_CONS);
  1310. if ((res != 0) && (res != -EINPROGRESS))
  1311. TETH_ERR(
  1312. "Failed deleting ipa_rm dependency A2_PROD <-> USB_CONS\n");
  1313. /* Request the BRIDGE_PROD resource, A2 and IPA should power up */
  1314. res = teth_request_resource();
  1315. if (res) {
  1316. TETH_ERR("request_resource() failed.\n");
  1317. goto bail;
  1318. }
  1319. /* Close the channel to A2 */
  1320. if (a2_mux_close_channel(A2_MUX_TETHERED_0))
  1321. TETH_ERR("a2_mux_close_channel() failed\n");
  1322. /* Teardown the IPA HW bridge */
  1323. if (teth_ctx->is_hw_bridge_complete) {
  1324. /* Delete header entries */
  1325. if (ipa_del_hdr(teth_ctx->hdr_del))
  1326. TETH_ERR("ipa_del_hdr() failed\n");
  1327. /* Delete installed routing rules */
  1328. if (ipa_del_rt_rule(teth_ctx->routing_del[IPA_IP_v4]))
  1329. TETH_ERR("ipa_del_rt_rule() failed\n");
  1330. if (ipa_del_rt_rule(teth_ctx->routing_del[IPA_IP_v6]))
  1331. TETH_ERR("ipa_del_rt_rule() failed\n");
  1332. /* Delete installed filtering rules */
  1333. if (ipa_del_flt_rule(teth_ctx->filtering_del[IPA_IP_v4]))
  1334. TETH_ERR("ipa_del_flt_rule() failed\n");
  1335. if (ipa_del_flt_rule(teth_ctx->filtering_del[IPA_IP_v6]))
  1336. TETH_ERR("ipa_del_flt_rule() failed\n");
  1337. /*
  1338. * Commit all the data to HW, including header, routing and
  1339. * filtering blocks, IPv4 and IPv6
  1340. */
  1341. if (ipa_commit_hdr())
  1342. TETH_ERR("Failed committing headers\n");
  1343. }
  1344. initialize_context();
  1345. ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
  1346. /* Delete the last ipa_rm dependency - BRIDGE_PROD <-> A2 */
  1347. res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_BRIDGE_PROD,
  1348. IPA_RM_RESOURCE_A2_CONS);
  1349. if ((res != 0) && (res != -EINPROGRESS))
  1350. TETH_ERR(
  1351. "Failed deleting ipa_rm dependency BRIDGE_PROD <-> A2_CONS\n");
  1352. /* Deregister from A2_PROD notifications */
  1353. a2_prod_reg_params.user_data = NULL;
  1354. a2_prod_reg_params.notify_cb = a2_prod_notify_cb;
  1355. res = ipa_rm_deregister(IPA_RM_RESOURCE_A2_PROD, &a2_prod_reg_params);
  1356. if (res)
  1357. TETH_ERR("Failed deregistering from A2_prod notifications.\n");
  1358. teth_ctx->is_connected = false;
  1359. bail:
  1360. TETH_DBG_FUNC_EXIT();
  1361. return 0;
  1362. }
  1363. EXPORT_SYMBOL(teth_bridge_disconnect);
  1364. /**
  1365. * teth_bridge_connect() - Connect bridge for a tethered Rmnet / MBIM call
  1366. * @connect_params: Connection info
  1367. *
  1368. * Return codes: 0: success
  1369. * -EINVAL: invalid parameters
  1370. * -EPERM: Operation not permitted as the bridge is already
  1371. * connected
  1372. */
  1373. int teth_bridge_connect(struct teth_bridge_connect_params *connect_params)
  1374. {
  1375. int res;
  1376. struct ipa_ep_cfg ipa_ep_cfg;
  1377. TETH_DBG_FUNC_ENTRY();
  1378. if (teth_ctx->is_connected) {
  1379. TETH_ERR("Trying to connect an already connected bridge !\n");
  1380. return -EPERM;
  1381. }
  1382. if (connect_params == NULL ||
  1383. connect_params->ipa_usb_pipe_hdl <= 0 ||
  1384. connect_params->usb_ipa_pipe_hdl <= 0 ||
  1385. connect_params->tethering_mode >= TETH_TETHERING_MODE_MAX ||
  1386. connect_params->tethering_mode < 0)
  1387. return -EINVAL;
  1388. teth_ctx->ipa_usb_pipe_hdl = connect_params->ipa_usb_pipe_hdl;
  1389. teth_ctx->usb_ipa_pipe_hdl = connect_params->usb_ipa_pipe_hdl;
  1390. teth_ctx->tethering_mode = connect_params->tethering_mode;
  1391. res = teth_request_resource();
  1392. if (res) {
  1393. TETH_ERR("request_resource() failed.\n");
  1394. goto bail;
  1395. }
  1396. res = a2_mux_open_channel(A2_MUX_TETHERED_0,
  1397. NULL,
  1398. a2_notify_cb);
  1399. if (res) {
  1400. TETH_ERR("a2_mux_open_channel() failed\n");
  1401. goto bail;
  1402. }
  1403. res = a2_mux_get_tethered_client_handles(A2_MUX_TETHERED_0,
  1404. &teth_ctx->ipa_a2_pipe_hdl,
  1405. &teth_ctx->a2_ipa_pipe_hdl);
  1406. if (res) {
  1407. TETH_ERR(
  1408. "a2_mux_get_tethered_client_handles() failed, res = %d\n", res);
  1409. goto bail;
  1410. }
  1411. /* Reset the various endpoints configuration */
  1412. memset(&ipa_ep_cfg, 0, sizeof(ipa_ep_cfg));
  1413. ipa_cfg_ep(teth_ctx->ipa_usb_pipe_hdl, &ipa_ep_cfg);
  1414. ipa_cfg_ep(teth_ctx->usb_ipa_pipe_hdl, &ipa_ep_cfg);
  1415. ipa_cfg_ep(teth_ctx->ipa_a2_pipe_hdl, &ipa_ep_cfg);
  1416. ipa_cfg_ep(teth_ctx->a2_ipa_pipe_hdl, &ipa_ep_cfg);
  1417. teth_ctx->is_connected = true;
  1418. if (teth_ctx->tethering_mode == TETH_TETHERING_MODE_MBIM)
  1419. teth_ctx->link_protocol = TETH_LINK_PROTOCOL_IP;
  1420. if (teth_ctx->aggr_params_known) {
  1421. res = teth_set_aggregation();
  1422. if (res) {
  1423. TETH_ERR("Failed setting aggregation params\n");
  1424. goto bail;
  1425. }
  1426. }
  1427. /* In case of IP link protocol, complete HW bridge */
  1428. if ((teth_ctx->link_protocol == TETH_LINK_PROTOCOL_IP) &&
  1429. (!teth_ctx->comp_hw_bridge_in_progress) &&
  1430. (teth_ctx->aggr_params_known) &&
  1431. (!teth_ctx->is_hw_bridge_complete)) {
  1432. INIT_WORK(&teth_ctx->comp_hw_bridge_work, complete_hw_bridge);
  1433. teth_ctx->comp_hw_bridge_in_progress = true;
  1434. queue_work(teth_ctx->teth_wq, &teth_ctx->comp_hw_bridge_work);
  1435. }
  1436. bail:
  1437. ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
  1438. TETH_DBG_FUNC_EXIT();
  1439. return res;
  1440. }
  1441. EXPORT_SYMBOL(teth_bridge_connect);
  1442. static void set_aggr_default_params(struct teth_aggr_params_link *params)
  1443. {
  1444. if (params->max_datagrams == 0)
  1445. params->max_datagrams =
  1446. TETH_AGGR_MAX_DATAGRAMS_DEFAULT;
  1447. if (params->max_transfer_size_byte == 0)
  1448. params->max_transfer_size_byte =
  1449. TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT;
  1450. }
  1451. /**
  1452. * teth_set_bridge_mode() - set the link protocol (IP / Ethernet)
  1453. */
  1454. static void teth_set_bridge_mode(enum teth_link_protocol_type link_protocol)
  1455. {
  1456. teth_ctx->link_protocol = link_protocol;
  1457. teth_ctx->is_hw_bridge_complete = false;
  1458. memset(&teth_ctx->mac_addresses, 0, sizeof(teth_ctx->mac_addresses));
  1459. }
  1460. /**
  1461. * teth_bridge_set_aggr_params() - kernel API to set aggregation parameters
  1462. * @param aggr_params: aggregation parmeters for uplink and downlink
  1463. *
  1464. * Besides setting the aggregation parameters, the function enforces max tranfer
  1465. * size which is less then 8K and also forbids Ethernet link protocol with MBIM
  1466. * aggregation which is not supported by HW.
  1467. */
  1468. int teth_bridge_set_aggr_params(struct teth_aggr_params *aggr_params)
  1469. {
  1470. int res;
  1471. TETH_DBG_FUNC_ENTRY();
  1472. if (!aggr_params) {
  1473. TETH_ERR("Invalid parameter\n");
  1474. return -EINVAL;
  1475. }
  1476. /*
  1477. * In case the requested max transfer size is larger than 8K, set it to
  1478. * to the default 8K
  1479. */
  1480. if (aggr_params->dl.max_transfer_size_byte >
  1481. TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT)
  1482. aggr_params->dl.max_transfer_size_byte =
  1483. TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT;
  1484. if (aggr_params->ul.max_transfer_size_byte >
  1485. TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT)
  1486. aggr_params->ul.max_transfer_size_byte =
  1487. TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT;
  1488. /* Ethernet link protocol and MBIM aggregation is not supported */
  1489. if (teth_ctx->link_protocol == TETH_LINK_PROTOCOL_ETHERNET &&
  1490. (aggr_params->dl.aggr_prot == TETH_AGGR_PROTOCOL_MBIM ||
  1491. aggr_params->ul.aggr_prot == TETH_AGGR_PROTOCOL_MBIM)) {
  1492. TETH_ERR("Ethernet with MBIM is not supported.\n");
  1493. return -EINVAL;
  1494. }
  1495. res = teth_request_resource();
  1496. if (res) {
  1497. TETH_ERR("request_resource() failed.\n");
  1498. return res;
  1499. }
  1500. memcpy(&teth_ctx->aggr_params,
  1501. aggr_params,
  1502. sizeof(struct teth_aggr_params));
  1503. set_aggr_default_params(&teth_ctx->aggr_params.dl);
  1504. set_aggr_default_params(&teth_ctx->aggr_params.ul);
  1505. teth_ctx->aggr_params_known = true;
  1506. res = teth_set_aggregation();
  1507. if (res)
  1508. TETH_ERR("Failed setting aggregation params\n");
  1509. ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_BRIDGE_PROD);
  1510. TETH_DBG_FUNC_EXIT();
  1511. return res;
  1512. }
  1513. EXPORT_SYMBOL(teth_bridge_set_aggr_params);
  1514. static long teth_bridge_ioctl(struct file *filp,
  1515. unsigned int cmd,
  1516. unsigned long arg)
  1517. {
  1518. int res = 0;
  1519. struct teth_aggr_params aggr_params;
  1520. TETH_DBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd));
  1521. if ((_IOC_TYPE(cmd) != TETH_BRIDGE_IOC_MAGIC) ||
  1522. (_IOC_NR(cmd) >= TETH_BRIDGE_IOCTL_MAX)) {
  1523. TETH_ERR("Invalid ioctl\n");
  1524. return -ENOIOCTLCMD;
  1525. }
  1526. switch (cmd) {
  1527. case TETH_BRIDGE_IOC_SET_BRIDGE_MODE:
  1528. TETH_DBG("TETH_BRIDGE_IOC_SET_BRIDGE_MODE ioctl called\n");
  1529. if (teth_ctx->link_protocol != arg)
  1530. teth_set_bridge_mode(arg);
  1531. break;
  1532. case TETH_BRIDGE_IOC_SET_AGGR_PARAMS:
  1533. TETH_DBG("TETH_BRIDGE_IOC_SET_AGGR_PARAMS ioctl called\n");
  1534. res = copy_from_user(&aggr_params,
  1535. (struct teth_aggr_params *)arg,
  1536. sizeof(struct teth_aggr_params));
  1537. if (res) {
  1538. TETH_ERR("Error, res = %d\n", res);
  1539. res = -EFAULT;
  1540. break;
  1541. }
  1542. res = teth_bridge_set_aggr_params(&aggr_params);
  1543. if (res)
  1544. break;
  1545. /* In case of IP link protocol, complete HW bridge */
  1546. if ((teth_ctx->link_protocol == TETH_LINK_PROTOCOL_IP) &&
  1547. (!teth_ctx->comp_hw_bridge_in_progress) &&
  1548. (!teth_ctx->is_hw_bridge_complete)) {
  1549. INIT_WORK(&teth_ctx->comp_hw_bridge_work,
  1550. complete_hw_bridge);
  1551. teth_ctx->comp_hw_bridge_in_progress = true;
  1552. queue_work(teth_ctx->teth_wq,
  1553. &teth_ctx->comp_hw_bridge_work);
  1554. }
  1555. break;
  1556. case TETH_BRIDGE_IOC_GET_AGGR_PARAMS:
  1557. TETH_DBG("TETH_BRIDGE_IOC_GET_AGGR_PARAMS ioctl called\n");
  1558. if (copy_to_user((u8 *)arg, (u8 *)&teth_ctx->aggr_params,
  1559. sizeof(struct teth_aggr_params))) {
  1560. res = -EFAULT;
  1561. break;
  1562. }
  1563. break;
  1564. case TETH_BRIDGE_IOC_GET_AGGR_CAPABILITIES:
  1565. {
  1566. u16 sz;
  1567. u16 pyld_sz;
  1568. struct teth_aggr_capabilities caps;
  1569. TETH_DBG("GET_AGGR_CAPABILITIES ioctl called\n");
  1570. sz = sizeof(struct teth_aggr_capabilities);
  1571. if (copy_from_user(&caps,
  1572. (struct teth_aggr_capabilities *)arg,
  1573. sz)) {
  1574. res = -EFAULT;
  1575. break;
  1576. }
  1577. if (caps.num_protocols != teth_ctx->aggr_caps->num_protocols) {
  1578. caps.num_protocols = teth_ctx->aggr_caps->num_protocols;
  1579. if (copy_to_user((struct teth_aggr_capabilities *)arg,
  1580. &caps,
  1581. sz)) {
  1582. res = -EFAULT;
  1583. break;
  1584. }
  1585. TETH_DBG("Not enough space allocated.\n");
  1586. res = -EAGAIN;
  1587. break;
  1588. }
  1589. pyld_sz = sz + caps.num_protocols *
  1590. sizeof(struct teth_aggr_params_link);
  1591. if (copy_to_user((u8 *)arg,
  1592. (u8 *)(teth_ctx->aggr_caps),
  1593. pyld_sz)) {
  1594. res = -EFAULT;
  1595. break;
  1596. }
  1597. }
  1598. break;
  1599. }
  1600. return res;
  1601. }
  1602. /**
  1603. * set_aggr_capabilities() - allocates and fills the aggregation capabilities
  1604. * struct
  1605. */
  1606. static int set_aggr_capabilities(void)
  1607. {
  1608. u16 NUM_PROTOCOLS = 2;
  1609. teth_ctx->aggr_caps = kzalloc(sizeof(struct teth_aggr_capabilities) +
  1610. NUM_PROTOCOLS *
  1611. sizeof(struct teth_aggr_params_link),
  1612. GFP_KERNEL);
  1613. if (!teth_ctx->aggr_caps) {
  1614. TETH_ERR("Memory alloc failed for aggregation capabilities.\n");
  1615. return -ENOMEM;
  1616. }
  1617. teth_ctx->aggr_caps->num_protocols = NUM_PROTOCOLS;
  1618. teth_ctx->aggr_caps->prot_caps[0].aggr_prot = TETH_AGGR_PROTOCOL_MBIM;
  1619. set_aggr_default_params(&teth_ctx->aggr_caps->prot_caps[0]);
  1620. teth_ctx->aggr_caps->prot_caps[1].aggr_prot = TETH_AGGR_PROTOCOL_TLP;
  1621. set_aggr_default_params(&teth_ctx->aggr_caps->prot_caps[1]);
  1622. return 0;
  1623. }
  1624. /**
  1625. * teth_bridge_get_client_handles() - Get USB <--> IPA pipe handles
  1626. * @producer_handle: USB --> IPA pipe handle
  1627. * @consumer_handle: IPA --> USB pipe handle
  1628. */
  1629. void teth_bridge_get_client_handles(u32 *producer_handle,
  1630. u32 *consumer_handle)
  1631. {
  1632. if (producer_handle == NULL || consumer_handle == NULL)
  1633. return;
  1634. *producer_handle = teth_ctx->usb_ipa_pipe_hdl;
  1635. *consumer_handle = teth_ctx->ipa_usb_pipe_hdl;
  1636. }
  1637. #ifdef CONFIG_DEBUG_FS
  1638. static struct dentry *dent;
  1639. static struct dentry *dfile_link_protocol;
  1640. static struct dentry *dfile_get_aggr_params;
  1641. static struct dentry *dfile_set_aggr_protocol;
  1642. static struct dentry *dfile_stats;
  1643. static struct dentry *dfile_is_hw_bridge_complete;
  1644. static ssize_t teth_debugfs_read_link_protocol(struct file *file,
  1645. char __user *ubuf,
  1646. size_t count,
  1647. loff_t *ppos)
  1648. {
  1649. int nbytes;
  1650. nbytes = scnprintf(dbg_buff, TETH_MAX_MSG_LEN, "Link protocol = %s\n",
  1651. (teth_ctx->link_protocol ==
  1652. TETH_LINK_PROTOCOL_ETHERNET) ?
  1653. "ETHERNET" :
  1654. "IP");
  1655. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
  1656. }
  1657. static ssize_t teth_debugfs_write_link_protocol(struct file *file,
  1658. const char __user *ubuf,
  1659. size_t count,
  1660. loff_t *ppos)
  1661. {
  1662. unsigned long missing;
  1663. enum teth_link_protocol_type link_protocol;
  1664. if (sizeof(dbg_buff) < count + 1)
  1665. return -EFAULT;
  1666. missing = copy_from_user(dbg_buff, ubuf, count);
  1667. if (missing)
  1668. return -EFAULT;
  1669. if (count > 0)
  1670. dbg_buff[count-1] = '\0';
  1671. if (strcmp(dbg_buff, "ETHERNET") == 0) {
  1672. link_protocol = TETH_LINK_PROTOCOL_ETHERNET;
  1673. } else if (strcmp(dbg_buff, "IP") == 0) {
  1674. link_protocol = TETH_LINK_PROTOCOL_IP;
  1675. } else {
  1676. TETH_ERR("Bad link protocol, got %s,\n"
  1677. "Use <ETHERNET> or <IP>.\n", dbg_buff);
  1678. return count;
  1679. }
  1680. teth_set_bridge_mode(link_protocol);
  1681. return count;
  1682. }
  1683. static ssize_t teth_debugfs_read_aggr_params(struct file *file,
  1684. char __user *ubuf,
  1685. size_t count,
  1686. loff_t *ppos)
  1687. {
  1688. int nbytes = 0;
  1689. char aggr_str[20];
  1690. aggr_prot_to_str(teth_ctx->aggr_params.ul.aggr_prot,
  1691. aggr_str,
  1692. sizeof(aggr_str)-1);
  1693. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
  1694. "Aggregation parameters for uplink:\n");
  1695. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
  1696. " Aggregation protocol: %s\n",
  1697. aggr_str);
  1698. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
  1699. " Max transfer size [byte]: %d\n",
  1700. teth_ctx->aggr_params.ul.max_transfer_size_byte);
  1701. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
  1702. " Max datagrams: %d\n",
  1703. teth_ctx->aggr_params.ul.max_datagrams);
  1704. aggr_prot_to_str(teth_ctx->aggr_params.dl.aggr_prot,
  1705. aggr_str,
  1706. sizeof(aggr_str)-1);
  1707. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN,
  1708. "Aggregation parameters for downlink:\n");
  1709. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
  1710. " Aggregation protocol: %s\n",
  1711. aggr_str);
  1712. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
  1713. " Max transfer size [byte]: %d\n",
  1714. teth_ctx->aggr_params.dl.max_transfer_size_byte);
  1715. nbytes += scnprintf(&dbg_buff[nbytes], TETH_MAX_MSG_LEN - nbytes,
  1716. " Max datagrams: %d\n",
  1717. teth_ctx->aggr_params.dl.max_datagrams);
  1718. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
  1719. }
  1720. static ssize_t teth_debugfs_set_aggr_protocol(struct file *file,
  1721. const char __user *ubuf,
  1722. size_t count, loff_t *ppos)
  1723. {
  1724. unsigned long missing;
  1725. enum teth_aggr_protocol_type aggr_prot;
  1726. int res;
  1727. if (sizeof(dbg_buff) < count + 1)
  1728. return -EFAULT;
  1729. missing = copy_from_user(dbg_buff, ubuf, count);
  1730. if (missing)
  1731. return -EFAULT;
  1732. if (count > 0)
  1733. dbg_buff[count-1] = '\0';
  1734. set_aggr_default_params(&teth_ctx->aggr_params.dl);
  1735. set_aggr_default_params(&teth_ctx->aggr_params.ul);
  1736. if (strcmp(dbg_buff, "NONE") == 0) {
  1737. aggr_prot = TETH_AGGR_PROTOCOL_NONE;
  1738. } else if (strcmp(dbg_buff, "MBIM") == 0) {
  1739. aggr_prot = TETH_AGGR_PROTOCOL_MBIM;
  1740. } else if (strcmp(dbg_buff, "TLP") == 0) {
  1741. aggr_prot = TETH_AGGR_PROTOCOL_TLP;
  1742. } else {
  1743. TETH_ERR("Bad aggregation protocol, got %s,\n"
  1744. "Use <NONE>, <MBIM> or <TLP>.\n", dbg_buff);
  1745. return count;
  1746. }
  1747. teth_ctx->aggr_params.dl.aggr_prot = aggr_prot;
  1748. teth_ctx->aggr_params.ul.aggr_prot = aggr_prot;
  1749. teth_ctx->aggr_params_known = true;
  1750. res = teth_set_aggregation();
  1751. if (res)
  1752. TETH_ERR("Failed setting aggregation params\n");
  1753. return count;
  1754. }
  1755. static ssize_t teth_debugfs_stats(struct file *file,
  1756. char __user *ubuf,
  1757. size_t count,
  1758. loff_t *ppos)
  1759. {
  1760. int nbytes = 0;
  1761. nbytes += scnprintf(&dbg_buff[nbytes],
  1762. TETH_MAX_MSG_LEN - nbytes,
  1763. "USB to A2 SW Tx packets: %lld\n",
  1764. teth_ctx->stats.usb_to_a2_num_sw_tx_packets);
  1765. nbytes += scnprintf(&dbg_buff[nbytes],
  1766. TETH_MAX_MSG_LEN - nbytes,
  1767. "A2 to USB SW Tx packets: %lld\n",
  1768. teth_ctx->stats.a2_to_usb_num_sw_tx_packets);
  1769. nbytes += scnprintf(
  1770. &dbg_buff[nbytes],
  1771. TETH_MAX_MSG_LEN - nbytes,
  1772. "SW Tx packets sent during resource wakeup: %lld\n",
  1773. teth_ctx->stats.num_sw_tx_packets_during_resource_wakeup);
  1774. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
  1775. }
  1776. static ssize_t teth_debugfs_hw_bridge_status(struct file *file,
  1777. char __user *ubuf,
  1778. size_t count,
  1779. loff_t *ppos)
  1780. {
  1781. int nbytes = 0;
  1782. if (teth_ctx->is_hw_bridge_complete)
  1783. nbytes += scnprintf(&dbg_buff[nbytes],
  1784. TETH_MAX_MSG_LEN - nbytes,
  1785. "HW bridge is in use.\n");
  1786. else
  1787. nbytes += scnprintf(&dbg_buff[nbytes],
  1788. TETH_MAX_MSG_LEN - nbytes,
  1789. "SW bridge is in use. HW bridge not complete yet.\n");
  1790. return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
  1791. }
  1792. const struct file_operations teth_link_protocol_ops = {
  1793. .read = teth_debugfs_read_link_protocol,
  1794. .write = teth_debugfs_write_link_protocol,
  1795. };
  1796. const struct file_operations teth_get_aggr_params_ops = {
  1797. .read = teth_debugfs_read_aggr_params,
  1798. };
  1799. const struct file_operations teth_set_aggr_protocol_ops = {
  1800. .write = teth_debugfs_set_aggr_protocol,
  1801. };
  1802. const struct file_operations teth_stats_ops = {
  1803. .read = teth_debugfs_stats,
  1804. };
  1805. const struct file_operations teth_hw_bridge_status_ops = {
  1806. .read = teth_debugfs_hw_bridge_status,
  1807. };
  1808. void teth_debugfs_init(void)
  1809. {
  1810. const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
  1811. const mode_t read_write_mode = S_IRUSR | S_IRGRP | S_IROTH |
  1812. S_IWUSR | S_IWGRP | S_IWOTH;
  1813. dent = debugfs_create_dir("ipa_teth", 0);
  1814. if (IS_ERR(dent)) {
  1815. IPAERR("fail to create folder ipa_teth debug_fs.\n");
  1816. return;
  1817. }
  1818. dfile_link_protocol =
  1819. debugfs_create_file("link_protocol", read_write_mode, dent, 0,
  1820. &teth_link_protocol_ops);
  1821. if (!dfile_link_protocol || IS_ERR(dfile_link_protocol)) {
  1822. IPAERR("fail to create file link_protocol\n");
  1823. goto fail;
  1824. }
  1825. dfile_get_aggr_params =
  1826. debugfs_create_file("get_aggr_params", read_only_mode, dent, 0,
  1827. &teth_get_aggr_params_ops);
  1828. if (!dfile_get_aggr_params || IS_ERR(dfile_get_aggr_params)) {
  1829. IPAERR("fail to create file get_aggr_params\n");
  1830. goto fail;
  1831. }
  1832. dfile_set_aggr_protocol =
  1833. debugfs_create_file("set_aggr_protocol", read_only_mode, dent,
  1834. 0, &teth_set_aggr_protocol_ops);
  1835. if (!dfile_set_aggr_protocol || IS_ERR(dfile_set_aggr_protocol)) {
  1836. IPAERR("fail to create file set_aggr_protocol\n");
  1837. goto fail;
  1838. }
  1839. dfile_stats =
  1840. debugfs_create_file("stats", read_only_mode, dent,
  1841. 0, &teth_stats_ops);
  1842. if (!dfile_stats || IS_ERR(dfile_stats)) {
  1843. IPAERR("fail to create file stats\n");
  1844. goto fail;
  1845. }
  1846. dfile_is_hw_bridge_complete =
  1847. debugfs_create_file("is_hw_bridge_complete", read_only_mode,
  1848. dent, 0, &teth_hw_bridge_status_ops);
  1849. if (!dfile_is_hw_bridge_complete ||
  1850. IS_ERR(dfile_is_hw_bridge_complete)) {
  1851. IPAERR("fail to create file is_hw_bridge_complete\n");
  1852. goto fail;
  1853. }
  1854. return;
  1855. fail:
  1856. debugfs_remove_recursive(dent);
  1857. }
  1858. #else
  1859. void teth_debugfs_init(void) {}
  1860. #endif /* CONFIG_DEBUG_FS */
  1861. static const struct file_operations teth_bridge_drv_fops = {
  1862. .owner = THIS_MODULE,
  1863. .unlocked_ioctl = teth_bridge_ioctl,
  1864. };
  1865. /**
  1866. * teth_bridge_driver_init() - Initialize tethering bridge driver
  1867. *
  1868. */
  1869. int teth_bridge_driver_init(void)
  1870. {
  1871. int res;
  1872. struct ipa_rm_create_params bridge_prod_params;
  1873. TETH_DBG("Tethering bridge driver init\n");
  1874. teth_ctx = kzalloc(sizeof(*teth_ctx), GFP_KERNEL);
  1875. if (!teth_ctx) {
  1876. TETH_ERR("kzalloc err.\n");
  1877. return -ENOMEM;
  1878. }
  1879. res = set_aggr_capabilities();
  1880. if (res) {
  1881. TETH_ERR("kzalloc err.\n");
  1882. goto fail_alloc_aggr_caps;
  1883. }
  1884. res = -ENOMEM;
  1885. teth_ctx->hdr_del = kzalloc(sizeof(struct ipa_ioc_del_hdr) +
  1886. TETH_TOTAL_HDR_ENTRIES *
  1887. sizeof(struct ipa_hdr_del),
  1888. GFP_KERNEL);
  1889. if (!teth_ctx->hdr_del) {
  1890. TETH_ERR("kzalloc err.\n");
  1891. goto fail_alloc_hdr_del;
  1892. }
  1893. teth_ctx->routing_del[IPA_IP_v4] =
  1894. kzalloc(sizeof(struct ipa_ioc_del_rt_rule) +
  1895. TETH_TOTAL_RT_ENTRIES_IP *
  1896. sizeof(struct ipa_rt_rule_del),
  1897. GFP_KERNEL);
  1898. if (!teth_ctx->routing_del[IPA_IP_v4]) {
  1899. TETH_ERR("kzalloc err.\n");
  1900. goto fail_alloc_routing_del_ipv4;
  1901. }
  1902. teth_ctx->routing_del[IPA_IP_v6] =
  1903. kzalloc(sizeof(struct ipa_ioc_del_rt_rule) +
  1904. TETH_TOTAL_RT_ENTRIES_IP *
  1905. sizeof(struct ipa_rt_rule_del),
  1906. GFP_KERNEL);
  1907. if (!teth_ctx->routing_del[IPA_IP_v6]) {
  1908. TETH_ERR("kzalloc err.\n");
  1909. goto fail_alloc_routing_del_ipv6;
  1910. }
  1911. teth_ctx->filtering_del[IPA_IP_v4] =
  1912. kzalloc(sizeof(struct ipa_ioc_del_flt_rule) +
  1913. TETH_TOTAL_FLT_ENTRIES_IP *
  1914. sizeof(struct ipa_flt_rule_del),
  1915. GFP_KERNEL);
  1916. if (!teth_ctx->filtering_del[IPA_IP_v4]) {
  1917. TETH_ERR("kzalloc err.\n");
  1918. goto fail_alloc_filtering_del_ipv4;
  1919. }
  1920. teth_ctx->filtering_del[IPA_IP_v6] =
  1921. kzalloc(sizeof(struct ipa_ioc_del_flt_rule) +
  1922. TETH_TOTAL_FLT_ENTRIES_IP *
  1923. sizeof(struct ipa_flt_rule_del),
  1924. GFP_KERNEL);
  1925. if (!teth_ctx->filtering_del[IPA_IP_v6]) {
  1926. TETH_ERR("kzalloc err.\n");
  1927. goto fail_alloc_filtering_del_ipv6;
  1928. }
  1929. teth_ctx->class = class_create(THIS_MODULE, TETH_BRIDGE_DRV_NAME);
  1930. res = alloc_chrdev_region(&teth_ctx->dev_num, 0, 1,
  1931. TETH_BRIDGE_DRV_NAME);
  1932. if (res) {
  1933. TETH_ERR("alloc_chrdev_region err.\n");
  1934. res = -ENODEV;
  1935. goto fail_alloc_chrdev_region;
  1936. }
  1937. teth_ctx->dev = device_create(teth_ctx->class, NULL, teth_ctx->dev_num,
  1938. teth_ctx, TETH_BRIDGE_DRV_NAME);
  1939. if (IS_ERR(teth_ctx->dev)) {
  1940. TETH_ERR(":device_create err.\n");
  1941. res = -ENODEV;
  1942. goto fail_device_create;
  1943. }
  1944. cdev_init(&teth_ctx->cdev, &teth_bridge_drv_fops);
  1945. teth_ctx->cdev.owner = THIS_MODULE;
  1946. teth_ctx->cdev.ops = &teth_bridge_drv_fops;
  1947. res = cdev_add(&teth_ctx->cdev, teth_ctx->dev_num, 1);
  1948. if (res) {
  1949. TETH_ERR(":cdev_add err=%d\n", -res);
  1950. res = -ENODEV;
  1951. goto fail_cdev_add;
  1952. }
  1953. teth_debugfs_init();
  1954. /* Create BRIDGE_PROD entity in IPA Resource Manager */
  1955. bridge_prod_params.name = IPA_RM_RESOURCE_BRIDGE_PROD;
  1956. bridge_prod_params.reg_params.user_data = NULL;
  1957. bridge_prod_params.reg_params.notify_cb = bridge_prod_notify_cb;
  1958. res = ipa_rm_create_resource(&bridge_prod_params);
  1959. if (res) {
  1960. TETH_ERR("ipa_rm_create_resource() failed\n");
  1961. goto fail_cdev_add;
  1962. }
  1963. init_completion(&teth_ctx->is_bridge_prod_up);
  1964. init_completion(&teth_ctx->is_bridge_prod_down);
  1965. res = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_BRIDGE_PROD,
  1966. TETH_INACTIVITY_TIME_MSEC);
  1967. if (res) {
  1968. TETH_ERR("ipa_rm_inactivity_timer_init() failed, res=%d\n",
  1969. res);
  1970. goto fail_cdev_add;
  1971. }
  1972. teth_ctx->teth_wq = create_workqueue(TETH_WORKQUEUE_NAME);
  1973. if (!teth_ctx->teth_wq) {
  1974. TETH_ERR("workqueue creation failed\n");
  1975. goto fail_cdev_add;
  1976. }
  1977. initialize_context();
  1978. TETH_DBG("Tethering bridge driver init OK\n");
  1979. return 0;
  1980. fail_cdev_add:
  1981. device_destroy(teth_ctx->class, teth_ctx->dev_num);
  1982. fail_device_create:
  1983. unregister_chrdev_region(teth_ctx->dev_num, 1);
  1984. fail_alloc_chrdev_region:
  1985. kfree(teth_ctx->filtering_del[IPA_IP_v6]);
  1986. fail_alloc_filtering_del_ipv6:
  1987. kfree(teth_ctx->filtering_del[IPA_IP_v4]);
  1988. fail_alloc_filtering_del_ipv4:
  1989. kfree(teth_ctx->routing_del[IPA_IP_v6]);
  1990. fail_alloc_routing_del_ipv6:
  1991. kfree(teth_ctx->routing_del[IPA_IP_v4]);
  1992. fail_alloc_routing_del_ipv4:
  1993. kfree(teth_ctx->hdr_del);
  1994. fail_alloc_hdr_del:
  1995. kfree(teth_ctx->aggr_caps);
  1996. fail_alloc_aggr_caps:
  1997. kfree(teth_ctx);
  1998. teth_ctx = NULL;
  1999. return res;
  2000. }
  2001. EXPORT_SYMBOL(teth_bridge_driver_init);
  2002. MODULE_LICENSE("GPL v2");
  2003. MODULE_DESCRIPTION("Tethering bridge driver");