rndis.c 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905
  1. /****************************************************************************
  2. * drivers/usbdev/rndis.c
  3. *
  4. * Copyright (C) 2011-2018 Gregory Nutt. All rights reserved.
  5. * Authors: Sakari Kapanen <sakari.m.kapanen@gmail.com>,
  6. * Petteri Aimonen <jpa@git.mail.kapsi.fi>
  7. *
  8. * References:
  9. * [MS-RNDIS]:
  10. * Remote Network Driver Interface Specification (RNDIS) Protocol
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions
  14. * are met:
  15. *
  16. * 1. Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. * 2. Redistributions in binary form must reproduce the above copyright
  19. * notice, this list of conditions and the following disclaimer in
  20. * the documentation and/or other materials provided with the
  21. * distribution.
  22. * 3. Neither the name NuttX nor the names of its contributors may be
  23. * used to endorse or promote products derived from this software
  24. * without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  29. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  30. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  31. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  32. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  33. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  34. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37. * POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. ****************************************************************************/
  40. /****************************************************************************
  41. * Included Files
  42. ****************************************************************************/
  43. #include <queue.h>
  44. #include <errno.h>
  45. #include <string.h>
  46. #include <stdlib.h>
  47. #include <stdio.h>
  48. #include <nuttx/net/net.h>
  49. #include <nuttx/net/netdev.h>
  50. #include <nuttx/net/arp.h>
  51. #include <nuttx/kmalloc.h>
  52. #include <nuttx/arch.h>
  53. #include <nuttx/usb/usb.h>
  54. #include <nuttx/usb/cdc.h>
  55. #include <nuttx/usb/usbdev.h>
  56. #include <nuttx/usb/usbdev_trace.h>
  57. #include <nuttx/usb/rndis.h>
  58. #include <nuttx/wdog.h>
  59. #include <nuttx/wqueue.h>
  60. #include "rndis_std.h"
  61. /****************************************************************************
  62. * Pre-processor definitions
  63. ****************************************************************************/
  64. #define CONFIG_RNDIS_EP0MAXPACKET 64
  65. #ifndef CONFIG_RNDIS_NWRREQS
  66. # define CONFIG_RNDIS_NWRREQS (2)
  67. #endif
  68. #define RNDIS_PACKET_HDR_SIZE (sizeof(struct rndis_packet_msg))
  69. #define CONFIG_RNDIS_BULKIN_REQLEN \
  70. (CONFIG_NET_ETH_PKTSIZE + CONFIG_NET_GUARDSIZE + RNDIS_PACKET_HDR_SIZE)
  71. #define CONFIG_RNDIS_BULKOUT_REQLEN CONFIG_RNDIS_BULKIN_REQLEN
  72. #define RNDIS_NCONFIGS (1)
  73. #define RNDIS_CONFIGID (1)
  74. #define RNDIS_CONFIGIDNONE (0)
  75. #define RNDIS_NINTERFACES (2)
  76. #define RNDIS_EPINTIN_ADDR USB_EPIN(3)
  77. #define RNDIS_EPBULKIN_ADDR USB_EPIN(1)
  78. #define RNDIS_EPBULKOUT_ADDR USB_EPOUT(2)
  79. #define RNDIS_NUM_EPS (3)
  80. #define RNDIS_MANUFACTURERSTRID (1)
  81. #define RNDIS_PRODUCTSTRID (2)
  82. #define RNDIS_SERIALSTRID (3)
  83. #define RNDIS_STR_LANGUAGE (0x0409) /* en-us */
  84. #define RNDIS_MXDESCLEN (128)
  85. #define RNDIS_MAXSTRLEN (RNDIS_MXDESCLEN-2)
  86. #define RNDIS_CTRLREQ_LEN (512)
  87. #define RNDIS_BUFFER_SIZE CONFIG_NET_ETH_PKTSIZE
  88. #define RNDIS_BUFFER_COUNT 4
  89. /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
  90. #define RNDIS_WDDELAY (1*CLK_TCK)
  91. /* Work queue to use for network operations. LPWORK should be used here */
  92. #define ETHWORK LPWORK
  93. #ifndef min
  94. # define min(a,b) ((a)<(b)?(a):(b))
  95. #endif
  96. #ifndef max
  97. # define max(a,b) ((a)>(b)?(a):(b))
  98. #endif
  99. /****************************************************************************
  100. * Private Types
  101. ****************************************************************************/
  102. /* Container to support a list of requests */
  103. struct rndis_req_s
  104. {
  105. FAR struct rndis_req_s *flink; /* Implements a singly linked list */
  106. FAR struct usbdev_req_s *req; /* The contained request */
  107. };
  108. /* This structure describes the internal state of the driver */
  109. struct rndis_dev_s
  110. {
  111. struct net_driver_s netdev; /* Network driver structure */
  112. struct usbdev_devinfo_s devinfo;
  113. FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
  114. FAR struct usbdev_ep_s *epintin; /* Interrupt IN endpoint structure */
  115. FAR struct usbdev_ep_s *epbulkin; /* Bulk IN endpoint structure */
  116. FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint structure */
  117. FAR struct usbdev_req_s *ctrlreq; /* Pointer to preallocated control request */
  118. FAR struct usbdev_req_s *epintin_req; /* Pointer to preallocated interrupt in endpoint request */
  119. FAR struct usbdev_req_s *rdreq; /* Pointer to Preallocated control endpoint read request */
  120. struct sq_queue_s reqlist; /* List of free write request containers */
  121. /* Preallocated USB request buffers */
  122. struct rndis_req_s wrreqs[CONFIG_RNDIS_NWRREQS];
  123. struct work_s rxwork; /* Worker for dispatching RX packets */
  124. WDOG_ID txpoll; /* TX poll watchdog */
  125. struct work_s pollwork; /* TX poll worker */
  126. bool registered; /* Has netdev_register() been called */
  127. uint8_t config; /* USB Configuration number */
  128. FAR struct rndis_req_s *net_req; /* Pointer to request whose buffer is assigned to network */
  129. FAR struct rndis_req_s *rx_req; /* Pointer request container that holds RX buffer */
  130. size_t current_rx_received; /* Number of bytes of current RX datagram received over USB */
  131. size_t current_rx_datagram_size; /* Total number of bytes of the current RX datagram */
  132. size_t current_rx_datagram_offset; /* Offset of current RX datagram */
  133. size_t current_rx_msglen; /* Length of the entire message to be received */
  134. bool rdreq_submitted; /* Indicates if the read request is submitted */
  135. bool rx_blocked; /* Indicates if we can receive packets on bulk in endpoint */
  136. bool ctrlreq_has_encap_response; /* Indicates if ctrlreq buffer holds a response */
  137. bool connected; /* Connection status indicator */
  138. uint32_t rndis_packet_filter; /* RNDIS packet filter value */
  139. uint32_t rndis_host_tx_count; /* TX packet counter */
  140. uint32_t rndis_host_rx_count; /* RX packet counter */
  141. uint8_t host_mac_address[6]; /* Host side MAC address */
  142. };
  143. /* The internal version of the class driver */
  144. struct rndis_driver_s
  145. {
  146. struct usbdevclass_driver_s drvr;
  147. FAR struct rndis_dev_s *dev;
  148. };
  149. /* This is what is allocated */
  150. struct rndis_alloc_s
  151. {
  152. struct rndis_dev_s dev;
  153. struct rndis_driver_s drvr;
  154. };
  155. /* RNDIS USB configuration descriptor */
  156. struct rndis_cfgdesc_s
  157. {
  158. #ifndef CONFIG_RNDIS_COMPOSITE
  159. struct usb_cfgdesc_s cfgdesc; /* Configuration descriptor */
  160. #endif
  161. struct usb_iaddesc_s assoc_desc; /* Interface association descriptor */
  162. struct usb_ifdesc_s comm_ifdesc; /* Communication interface descriptor */
  163. struct usb_epdesc_s epintindesc; /* Interrupt endpoint descriptor */
  164. struct usb_ifdesc_s data_ifdesc; /* Data interface descriptor */
  165. struct usb_epdesc_s epbulkindesc; /* Bulk in interface descriptor */
  166. struct usb_epdesc_s epbulkoutdesc; /* Bulk out interface descriptor */
  167. };
  168. /* RNDIS object ID - value pair structure */
  169. struct rndis_oid_value_s
  170. {
  171. uint32_t objid;
  172. uint32_t length;
  173. uint32_t value;
  174. FAR const void *data; /* Data pointer overrides value if non-NULL. */
  175. };
  176. /****************************************************************************
  177. * Private Function Prototypes
  178. ****************************************************************************/
  179. /* Netdev driver callbacks */
  180. static int rndis_ifup(FAR struct net_driver_s *dev);
  181. static int rndis_ifdown(FAR struct net_driver_s *dev);
  182. static int rndis_txavail(FAR struct net_driver_s *dev);
  183. static int rndis_transmit(FAR struct rndis_dev_s *priv);
  184. static int rndis_txpoll(FAR struct net_driver_s *dev);
  185. static void rndis_polltimer(int argc, uint32_t arg, ...);
  186. /* usbclass callbacks */
  187. static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
  188. FAR struct usbdev_s *dev,
  189. FAR const struct usb_ctrlreq_s *ctrl,
  190. FAR uint8_t *dataout, size_t outlen);
  191. static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
  192. FAR struct usbdev_s *dev);
  193. static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
  194. FAR struct usbdev_s *dev);
  195. static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
  196. FAR struct usbdev_s *dev);
  197. static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config);
  198. static void usbclass_resetconfig(FAR struct rndis_dev_s *priv);
  199. /* usbclass helpers */
  200. static int usbclass_copy_epdesc(int epid, FAR struct usb_epdesc_s *epdesc,
  201. FAR struct usbdev_devinfo_s *devinfo,
  202. bool hispeed);
  203. /****************************************************************************
  204. * Private Data
  205. ****************************************************************************/
  206. /* USB driver operations */
  207. const static struct usbdevclass_driverops_s g_driverops =
  208. {
  209. &usbclass_bind,
  210. &usbclass_unbind,
  211. &usbclass_setup,
  212. &usbclass_disconnect,
  213. NULL,
  214. NULL
  215. };
  216. #ifndef CONFIG_RNDIS_COMPOSITE
  217. static const struct usb_devdesc_s g_devdesc =
  218. {
  219. USB_SIZEOF_DEVDESC, /* len */
  220. USB_DESC_TYPE_DEVICE, /* type */
  221. {LSBYTE(0x0200), MSBYTE(0x0200)}, /* usb */
  222. 0, /* classid */
  223. 0, /* subclass */
  224. 0, /* protocol */
  225. CONFIG_RNDIS_EP0MAXPACKET, /* maxpacketsize */
  226. { LSBYTE(CONFIG_RNDIS_VENDORID), /* vendor */
  227. MSBYTE(CONFIG_RNDIS_VENDORID) },
  228. { LSBYTE(CONFIG_RNDIS_PRODUCTID), /* product */
  229. MSBYTE(CONFIG_RNDIS_PRODUCTID) },
  230. { LSBYTE(CONFIG_RNDIS_VERSIONNO), /* device */
  231. MSBYTE(CONFIG_RNDIS_VERSIONNO) },
  232. RNDIS_MANUFACTURERSTRID, /* imfgr */
  233. RNDIS_PRODUCTSTRID, /* iproduct */
  234. RNDIS_SERIALSTRID, /* serno */
  235. RNDIS_NCONFIGS /* nconfigs */
  236. };
  237. #endif
  238. const static struct rndis_cfgdesc_s g_rndis_cfgdesc =
  239. {
  240. #ifndef CONFIG_RNDIS_COMPOSITE
  241. {
  242. .len = USB_SIZEOF_CFGDESC,
  243. .type = USB_DESC_TYPE_CONFIG,
  244. .totallen = {0, 0},
  245. .ninterfaces = RNDIS_NINTERFACES,
  246. .cfgvalue = RNDIS_CONFIGID,
  247. .icfg = 0,
  248. .attr = USB_CONFIG_ATTR_ONE | USB_CONFIG_ATTR_SELFPOWER,
  249. .mxpower = (CONFIG_USBDEV_MAXPOWER + 1) / 2
  250. },
  251. #endif
  252. {
  253. .len = USB_SIZEOF_IADDESC,
  254. .type = USB_DESC_TYPE_INTERFACEASSOCIATION,
  255. .firstif = 0,
  256. .nifs = RNDIS_NINTERFACES,
  257. .classid = 0xef,
  258. .subclass = 0x04,
  259. .protocol = 0x01,
  260. .ifunction = 0
  261. },
  262. {
  263. .len = USB_SIZEOF_IFDESC,
  264. .type = USB_DESC_TYPE_INTERFACE,
  265. .ifno = 0,
  266. .alt = 0,
  267. .neps = 1,
  268. .classid = USB_CLASS_CDC,
  269. .subclass = CDC_SUBCLASS_ACM,
  270. .protocol = CDC_PROTO_VENDOR,
  271. .iif = 0
  272. },
  273. {
  274. .len = USB_SIZEOF_EPDESC,
  275. .type = USB_DESC_TYPE_ENDPOINT,
  276. .addr = RNDIS_EPINTIN_ADDR,
  277. .attr = USB_EP_ATTR_XFER_INT,
  278. .mxpacketsize = { LSBYTE(16), MSBYTE(16) },
  279. .interval = 1
  280. },
  281. {
  282. .len = USB_SIZEOF_IFDESC,
  283. .type = USB_DESC_TYPE_INTERFACE,
  284. .ifno = 1,
  285. .alt = 0,
  286. .neps = 2,
  287. .classid = USB_CLASS_CDC_DATA,
  288. .subclass = 0,
  289. .protocol = 0,
  290. .iif = 0
  291. },
  292. {
  293. .len = USB_SIZEOF_EPDESC,
  294. .type = USB_DESC_TYPE_ENDPOINT,
  295. .addr = RNDIS_EPBULKIN_ADDR,
  296. .attr = USB_EP_ATTR_XFER_BULK,
  297. #ifdef CONFIG_USBDEV_DUALSPEED
  298. .mxpacketsize = { LSBYTE(512), MSBYTE(512) },
  299. .interval = 0
  300. #else
  301. .mxpacketsize = { LSBYTE(64), MSBYTE(64) },
  302. .interval = 1
  303. #endif
  304. },
  305. {
  306. .len = USB_SIZEOF_EPDESC,
  307. .type = USB_DESC_TYPE_ENDPOINT,
  308. .addr = RNDIS_EPBULKOUT_ADDR,
  309. .attr = USB_EP_ATTR_XFER_BULK,
  310. #ifdef CONFIG_USBDEV_DUALSPEED
  311. .mxpacketsize = { LSBYTE(512), MSBYTE(512) },
  312. .interval = 0
  313. #else
  314. .mxpacketsize = { LSBYTE(64), MSBYTE(64) },
  315. .interval = 1
  316. #endif
  317. }
  318. };
  319. /* Default MAC address given to the host side of the interface. */
  320. static uint8_t g_rndis_default_mac_addr[6] =
  321. {
  322. 0x02, 0x00, 0x00, 0x11, 0x22, 0x33
  323. };
  324. /* These lists give dummy responses to be returned to PC. The values are
  325. * chosen so that Windows is happy - other operating systems don't really care
  326. * much.
  327. */
  328. static const uint32_t g_rndis_supported_oids[] =
  329. {
  330. RNDIS_OID_GEN_SUPPORTED_LIST,
  331. RNDIS_OID_GEN_HARDWARE_STATUS,
  332. RNDIS_OID_GEN_MEDIA_SUPPORTED,
  333. RNDIS_OID_GEN_MEDIA_IN_USE,
  334. RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
  335. RNDIS_OID_GEN_LINK_SPEED,
  336. RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE,
  337. RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE,
  338. RNDIS_OID_GEN_VENDOR_ID,
  339. RNDIS_OID_GEN_VENDOR_DESCRIPTION,
  340. RNDIS_OID_GEN_VENDOR_DRIVER_VERSION,
  341. RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
  342. RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE,
  343. RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
  344. RNDIS_OID_GEN_PHYSICAL_MEDIUM,
  345. RNDIS_OID_GEN_XMIT_OK,
  346. RNDIS_OID_GEN_RCV_OK,
  347. RNDIS_OID_GEN_XMIT_ERROR,
  348. RNDIS_OID_GEN_RCV_ERROR,
  349. RNDIS_OID_GEN_RCV_NO_BUFFER,
  350. RNDIS_OID_802_3_PERMANENT_ADDRESS,
  351. RNDIS_OID_802_3_CURRENT_ADDRESS,
  352. RNDIS_OID_802_3_MULTICAST_LIST,
  353. RNDIS_OID_802_3_MAC_OPTIONS,
  354. RNDIS_OID_802_3_MAXIMUM_LIST_SIZE,
  355. RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT,
  356. RNDIS_OID_802_3_XMIT_ONE_COLLISION,
  357. RNDIS_OID_802_3_XMIT_MORE_COLLISION,
  358. };
  359. static const struct rndis_oid_value_s g_rndis_oid_values[] =
  360. {
  361. {RNDIS_OID_GEN_SUPPORTED_LIST, sizeof(g_rndis_supported_oids), 0, g_rndis_supported_oids},
  362. {RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, 4, CONFIG_NET_ETH_PKTSIZE, NULL},
  363. #ifdef CONFIG_USBDEV_DUALSPEED
  364. {RNDIS_OID_GEN_LINK_SPEED, 4, 100000, NULL},
  365. #else
  366. {RNDIS_OID_GEN_LINK_SPEED, 4, 2000000, NULL},
  367. #endif
  368. {RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE, 4, CONFIG_NET_ETH_PKTSIZE, NULL},
  369. {RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE, 4, CONFIG_NET_ETH_PKTSIZE, NULL},
  370. {RNDIS_OID_GEN_VENDOR_ID, 4, 0x00FFFFFF, NULL},
  371. {RNDIS_OID_GEN_VENDOR_DESCRIPTION, 6, 0, "RNDIS"},
  372. {RNDIS_OID_GEN_CURRENT_PACKET_FILTER, 4, 0, NULL},
  373. {RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE, 4, 2048, NULL},
  374. {RNDIS_OID_GEN_XMIT_OK, 4, 0, NULL},
  375. {RNDIS_OID_GEN_RCV_OK, 4, 0, NULL},
  376. {RNDIS_OID_802_3_PERMANENT_ADDRESS, 6, 0, NULL},
  377. {RNDIS_OID_802_3_CURRENT_ADDRESS, 6, 0, NULL},
  378. {RNDIS_OID_802_3_MULTICAST_LIST, 4, 0xE0000000, NULL},
  379. {RNDIS_OID_802_3_MAXIMUM_LIST_SIZE, 4, 1, NULL},
  380. {0x0, 4, 0, NULL}, /* Default fallback */
  381. };
  382. /****************************************************************************
  383. * Private Data
  384. ****************************************************************************/
  385. /****************************************************************************
  386. * Buffering of data is implemented in the following manner:
  387. *
  388. * RNDIS driver holds a number of preallocated bulk IN endpoint write
  389. * requests along with buffers large enough to hold an Ethernet packet and
  390. * the corresponding RNDIS header.
  391. *
  392. * One of these is always reserved for packet reception - when data arrives
  393. * on the bulk OUT endpoint, it is copied to the reserved request buffer.
  394. * When the reception of an Ethernet packet is complete, a worker to process
  395. * the packet is scheduled and bulk OUT endpoint is set to NAK.
  396. *
  397. * The processing worker passes the buffer to the network. When the network is
  398. * done processing the packet, the buffer might contain data to be sent.
  399. * If so, the corresponding write request is queued on the bulk IN endpoint.
  400. * The NAK state on bulk OUT endpoint is cleared to allow new packets to
  401. * arrive. If there's no data to send, the request is returned to the list of
  402. * free requests.
  403. *
  404. * When a bulk IN write operation is complete, the request is added to the
  405. * list of free requests.
  406. *
  407. ****************************************************************************/
  408. /****************************************************************************
  409. * Name: rndis_submit_rdreq
  410. *
  411. * Description:
  412. * Submits the bulk OUT read request. Takes care not to submit the request
  413. * when the RX packet buffer is already in use.
  414. *
  415. * Input Parameters:
  416. * priv: pointer to RNDIS device driver structure
  417. *
  418. * Returned Value:
  419. * The return value of the EP_SUBMIT operation
  420. *
  421. ****************************************************************************/
  422. static int rndis_submit_rdreq(FAR struct rndis_dev_s *priv)
  423. {
  424. irqstate_t flags = enter_critical_section();
  425. int ret = OK;
  426. if (!priv->rdreq_submitted && !priv->rx_blocked)
  427. {
  428. priv->rdreq->len = priv->epbulkout->maxpacket;
  429. ret = EP_SUBMIT(priv->epbulkout, priv->rdreq);
  430. if (ret != OK)
  431. {
  432. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT),
  433. (uint16_t)-priv->rdreq->result);
  434. }
  435. else
  436. {
  437. priv->rdreq_submitted = true;
  438. }
  439. }
  440. leave_critical_section(flags);
  441. return ret;
  442. }
  443. /****************************************************************************
  444. * Name: rndis_cancel_rdreq
  445. *
  446. * Description:
  447. * Cancels the bulk OUT endpoint read request.
  448. *
  449. * Input Parameters:
  450. * priv: pointer to RNDIS device driver structure
  451. *
  452. ****************************************************************************/
  453. static void rndis_cancel_rdreq(FAR struct rndis_dev_s *priv)
  454. {
  455. irqstate_t flags = enter_critical_section();
  456. if (priv->rdreq_submitted)
  457. {
  458. EP_CANCEL(priv->epbulkout, priv->rdreq);
  459. priv->rdreq_submitted = false;
  460. }
  461. leave_critical_section(flags);
  462. }
  463. /****************************************************************************
  464. * Name: rndis_block_rx
  465. *
  466. * Description:
  467. * Blocks reception of further bulk OUT endpoint data.
  468. *
  469. * Input Parameters:
  470. * priv: pointer to RNDIS device driver structure
  471. *
  472. ****************************************************************************/
  473. static void rndis_block_rx(FAR struct rndis_dev_s *priv)
  474. {
  475. irqstate_t flags = enter_critical_section();
  476. priv->rx_blocked = true;
  477. rndis_cancel_rdreq(priv);
  478. leave_critical_section(flags);
  479. }
  480. /****************************************************************************
  481. * Name: rndis_unblock_rx
  482. *
  483. * Description:
  484. * Unblocks reception of bulk OUT endpoint data.
  485. *
  486. * Input Parameters:
  487. * priv: pointer to RNDIS device driver structure
  488. *
  489. * Assumptions:
  490. * Called from critical section
  491. *
  492. ****************************************************************************/
  493. static void rndis_unblock_rx(FAR struct rndis_dev_s *priv)
  494. {
  495. priv->rx_blocked = false;
  496. }
  497. /****************************************************************************
  498. * Name: rndis_allocwrreq
  499. *
  500. * Description:
  501. * Allocates a bulk IN endpoint request from the list of free request
  502. * buffers.
  503. *
  504. * Input Parameters:
  505. * priv: pointer to RNDIS device driver structure
  506. *
  507. * Returned Value:
  508. * NULL if allocation failed; pointer to allocated request if succeeded
  509. *
  510. * Assumptions:
  511. * Called from critical section
  512. *
  513. ****************************************************************************/
  514. static FAR struct rndis_req_s *rndis_allocwrreq(FAR struct rndis_dev_s *priv)
  515. {
  516. return (FAR struct rndis_req_s *)sq_remfirst(&priv->reqlist);
  517. }
  518. /****************************************************************************
  519. * Name: rndis_hasfreereqs
  520. *
  521. * Description:
  522. * Checks if there are free requests usable for TX data.
  523. *
  524. * Input Parameters:
  525. * priv: pointer to RNDIS device driver structure
  526. *
  527. * Returned Value:
  528. * true if requests available; false if no requests available
  529. *
  530. * Assumptions:
  531. * Called from critical section
  532. *
  533. ****************************************************************************/
  534. static bool rndis_hasfreereqs(FAR struct rndis_dev_s *priv)
  535. {
  536. return sq_count(&priv->reqlist) > 1;
  537. }
  538. /****************************************************************************
  539. * Name: rndis_freewrreq
  540. *
  541. * Description:
  542. * Returns a bulk IN endpoint write requests to the list of free requests.
  543. *
  544. * Input Parameters:
  545. * priv: pointer to RNDIS device driver structure
  546. * req: pointer to the request
  547. *
  548. * Assumptions:
  549. * Called with interrupts disabled.
  550. *
  551. ****************************************************************************/
  552. static void rndis_freewrreq(FAR struct rndis_dev_s *priv,
  553. FAR struct rndis_req_s *req)
  554. {
  555. DEBUGASSERT(req != NULL);
  556. sq_addlast((FAR sq_entry_t *)req, &priv->reqlist);
  557. rndis_submit_rdreq(priv);
  558. }
  559. /****************************************************************************
  560. * Name: rndis_allocnetreq
  561. *
  562. * Description:
  563. * Allocates a request buffer to be used on the network.
  564. *
  565. * Input Parameters:
  566. * priv: pointer to RNDIS device driver structure
  567. *
  568. * Returned Value:
  569. * true if succeeded; false if failed
  570. *
  571. * Assumptions:
  572. * Caller holds the network lock
  573. *
  574. ****************************************************************************/
  575. static bool rndis_allocnetreq(FAR struct rndis_dev_s *priv)
  576. {
  577. irqstate_t flags = enter_critical_section();
  578. DEBUGASSERT(priv->net_req == NULL);
  579. if (!rndis_hasfreereqs(priv))
  580. {
  581. leave_critical_section(flags);
  582. return false;
  583. }
  584. priv->net_req = rndis_allocwrreq(priv);
  585. if (priv->net_req)
  586. {
  587. priv->netdev.d_buf = &priv->net_req->req->buf[RNDIS_PACKET_HDR_SIZE];
  588. priv->netdev.d_len = CONFIG_NET_ETH_PKTSIZE;
  589. }
  590. leave_critical_section(flags);
  591. return priv->net_req != NULL;
  592. }
  593. /****************************************************************************
  594. * Name: rndis_sendnetreq
  595. *
  596. * Description:
  597. * Submits the request buffer held by the network.
  598. *
  599. * Input Parameters:
  600. * priv: pointer to RNDIS device driver structure
  601. *
  602. * Assumptions:
  603. * Caller holds the network lock
  604. *
  605. ****************************************************************************/
  606. static void rndis_sendnetreq(FAR struct rndis_dev_s *priv)
  607. {
  608. irqstate_t flags = enter_critical_section();
  609. DEBUGASSERT(priv->net_req != NULL);
  610. priv->net_req->req->priv = priv->net_req;
  611. EP_SUBMIT(priv->epbulkin, priv->net_req->req);
  612. priv->net_req = NULL;
  613. priv->netdev.d_buf = NULL;
  614. priv->netdev.d_len = 0;
  615. leave_critical_section(flags);
  616. }
  617. /****************************************************************************
  618. * Name: rndis_freenetreq
  619. *
  620. * Description:
  621. * Frees the request buffer held by the network.
  622. *
  623. * Input Parameters:
  624. * priv: pointer to RNDIS device driver structure
  625. *
  626. * Assumptions:
  627. * Caller holds the network lock
  628. *
  629. ****************************************************************************/
  630. static void rndis_freenetreq(FAR struct rndis_dev_s *priv)
  631. {
  632. irqstate_t flags = enter_critical_section();
  633. rndis_freewrreq(priv, priv->net_req);
  634. priv->net_req = NULL;
  635. priv->netdev.d_buf = NULL;
  636. priv->netdev.d_len = 0;
  637. leave_critical_section(flags);
  638. }
  639. /****************************************************************************
  640. * Name: rndis_allocrxreq
  641. *
  642. * Description:
  643. * Allocates a buffer for packet reception if there already isn't one.
  644. *
  645. * Input Parameters:
  646. * priv: pointer to RNDIS device driver structure
  647. *
  648. * Returned Value:
  649. * true if succeeded; false if failed
  650. *
  651. * Assumptions:
  652. * Called from critical section
  653. *
  654. ****************************************************************************/
  655. static bool rndis_allocrxreq(FAR struct rndis_dev_s *priv)
  656. {
  657. if (priv->rx_req != NULL)
  658. {
  659. return true;
  660. }
  661. priv->rx_req = rndis_allocwrreq(priv);
  662. return priv->rx_req != NULL;
  663. }
  664. /****************************************************************************
  665. * Name: rndis_giverxreq
  666. *
  667. * Description:
  668. * Passes the RX packet buffer to the network
  669. *
  670. * Input Parameters:
  671. * priv: pointer to RNDIS device driver structure
  672. *
  673. * Assumptions:
  674. * Caller holds the network lock
  675. *
  676. ****************************************************************************/
  677. static void rndis_giverxreq(FAR struct rndis_dev_s *priv)
  678. {
  679. DEBUGASSERT(priv->rx_req != NULL);
  680. DEBUGASSERT(priv->net_req == NULL);
  681. priv->net_req = priv->rx_req;
  682. priv->netdev.d_buf = &priv->net_req->req->buf[RNDIS_PACKET_HDR_SIZE];
  683. priv->netdev.d_len = CONFIG_NET_ETH_PKTSIZE;
  684. priv->rx_req = NULL;
  685. }
  686. /****************************************************************************
  687. * Name: rndis_fillrequest
  688. *
  689. * Description:
  690. * Fills the RNDIS header to the request buffer
  691. *
  692. * Input Parameters:
  693. * priv: pointer to RNDIS device driver structure
  694. * req: the request whose buffer we should fill
  695. *
  696. * Returned Value:
  697. * The total length of the request data
  698. *
  699. * Assumptions:
  700. * Caller holds the network lock
  701. *
  702. ****************************************************************************/
  703. static uint16_t rndis_fillrequest(FAR struct rndis_dev_s *priv,
  704. FAR struct usbdev_req_s *req)
  705. {
  706. size_t datalen;
  707. req->len = 0;
  708. datalen = min(priv->netdev.d_len,
  709. CONFIG_RNDIS_BULKIN_REQLEN - RNDIS_PACKET_HDR_SIZE);
  710. if (datalen > 0)
  711. {
  712. /* Send the required headers */
  713. FAR struct rndis_packet_msg *msg = (FAR struct rndis_packet_msg *)req->buf;
  714. memset(msg, 0, RNDIS_PACKET_HDR_SIZE);
  715. msg->msgtype = RNDIS_PACKET_MSG;
  716. msg->msglen = RNDIS_PACKET_HDR_SIZE + datalen;
  717. msg->dataoffset = RNDIS_PACKET_HDR_SIZE - 8;
  718. msg->datalen = datalen;
  719. req->flags = USBDEV_REQFLAGS_NULLPKT;
  720. req->len = datalen + RNDIS_PACKET_HDR_SIZE;
  721. }
  722. return req->len;
  723. }
  724. /****************************************************************************
  725. * Name: rndis_rxdispatch
  726. *
  727. * Description:
  728. * Processes the received Ethernet packet. Called from work queue.
  729. *
  730. * Input Parameters:
  731. * arg: pointer to RNDIS device driver structure
  732. *
  733. ****************************************************************************/
  734. static void rndis_rxdispatch(FAR void *arg)
  735. {
  736. FAR struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)arg;
  737. FAR struct eth_hdr_s *hdr;
  738. irqstate_t flags;
  739. net_lock();
  740. flags = enter_critical_section();
  741. rndis_giverxreq(priv);
  742. priv->netdev.d_len = priv->current_rx_datagram_size;
  743. leave_critical_section(flags);
  744. hdr = (FAR struct eth_hdr_s *)priv->netdev.d_buf;
  745. /* We only accept IP packets of the configured type and ARP packets */
  746. #ifdef CONFIG_NET_IPv4
  747. if (hdr->type == HTONS(ETHTYPE_IP))
  748. {
  749. NETDEV_RXIPV4(&priv->netdev);
  750. /* Handle ARP on input then give the IPv4 packet to the network
  751. * layer
  752. */
  753. arp_ipin(&priv->netdev);
  754. ipv4_input(&priv->netdev);
  755. if (priv->netdev.d_len > 0)
  756. {
  757. /* Update the Ethernet header with the correct MAC address */
  758. #ifdef CONFIG_NET_IPv6
  759. if (IFF_IS_IPv4(priv->netdev.d_flags))
  760. #endif
  761. {
  762. arp_out(&priv->netdev);
  763. }
  764. #ifdef CONFIG_NET_IPv6
  765. else
  766. {
  767. neighbor_out(&priv->netdev);
  768. }
  769. #endif
  770. /* And send the packet */
  771. rndis_transmit(priv);
  772. }
  773. }
  774. else
  775. #endif
  776. #ifdef CONFIG_NET_IPv6
  777. if (hdr->type == HTONS(ETHTYPE_IP6))
  778. {
  779. NETDEV_RXIPV6(&priv->netdev);
  780. /* Give the IPv6 packet to the network layer */
  781. arp_ipin(&priv->netdev);
  782. ipv6_input(&priv->netdev);
  783. if (priv->netdev.d_len > 0)
  784. {
  785. /* Update the Ethernet header with the correct MAC address */
  786. #ifdef CONFIG_NET_IPv4
  787. if (IFF_IS_IPv4(priv->netdev.d_flags))
  788. {
  789. arp_out(&priv->netdev);
  790. }
  791. else
  792. #endif
  793. #ifdef CONFIG_NET_IPv6
  794. {
  795. neighbor_out(&priv->netdev);
  796. }
  797. #endif
  798. /* And send the packet */
  799. rndis_transmit(priv);
  800. }
  801. }
  802. else
  803. #endif
  804. #ifdef CONFIG_NET_ARP
  805. if (hdr->type == htons(ETHTYPE_ARP))
  806. {
  807. NETDEV_RXARP(&priv->netdev);
  808. arp_arpin(&priv->netdev);
  809. if (priv->netdev.d_len > 0)
  810. {
  811. rndis_transmit(priv);
  812. }
  813. }
  814. else
  815. #endif
  816. {
  817. uerr("ERROR: Unsupported packet type dropped (%02x)\n", htons(hdr->type));
  818. NETDEV_RXDROPPED(&priv->netdev);
  819. priv->netdev.d_len = 0;
  820. }
  821. priv->current_rx_datagram_size = 0;
  822. rndis_unblock_rx(priv);
  823. if (priv->net_req != NULL)
  824. {
  825. rndis_freenetreq(priv);
  826. }
  827. net_unlock();
  828. }
  829. /****************************************************************************
  830. * Name: rndis_txpoll
  831. *
  832. * Description:
  833. * Sends the packet that is stored in the network packet buffer. Called
  834. * from work queue by e.g. txavail and txpoll callbacks.
  835. *
  836. * Input Parameters:
  837. * dev: pointer to network driver structure
  838. *
  839. * Assumptions:
  840. * Caller holds the network lock
  841. *
  842. ****************************************************************************/
  843. static int rndis_txpoll(FAR struct net_driver_s *dev)
  844. {
  845. FAR struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)dev->d_private;
  846. int ret = OK;
  847. if (!priv->connected)
  848. {
  849. return -EBUSY;
  850. }
  851. /* If the polling resulted in data that should be sent out on the network,
  852. * the field d_len is set to a value > 0.
  853. */
  854. ninfo("Poll result: d_len=%d\n", priv->netdev.d_len);
  855. if (priv->netdev.d_len > 0)
  856. {
  857. /* Look up the destination MAC address and add it to the Ethernet
  858. * header.
  859. */
  860. #ifdef CONFIG_NET_IPv4
  861. #ifdef CONFIG_NET_IPv6
  862. if (IFF_IS_IPv4(priv->netdev.d_flags))
  863. #endif
  864. {
  865. arp_out(&priv->netdev);
  866. }
  867. #endif /* CONFIG_NET_IPv4 */
  868. #ifdef CONFIG_NET_IPv6
  869. #ifdef CONFIG_NET_IPv4
  870. else
  871. #endif
  872. {
  873. neighbor_out(&priv->netdev);
  874. }
  875. #endif /* CONFIG_NET_IPv6 */
  876. if (!devif_loopback(&priv->netdev))
  877. {
  878. ret = rndis_transmit(priv);
  879. }
  880. }
  881. /* If zero is returned, the polling will continue until all connections have
  882. * been examined.
  883. */
  884. return ret;
  885. }
  886. /****************************************************************************
  887. * Name: rndis_transmit
  888. *
  889. * Description:
  890. * Start hardware transmission.
  891. *
  892. ****************************************************************************/
  893. static int rndis_transmit(FAR struct rndis_dev_s *priv)
  894. {
  895. int ret = OK;
  896. /* Queue the packet */
  897. rndis_fillrequest(priv, priv->net_req->req);
  898. rndis_sendnetreq(priv);
  899. if (!rndis_allocnetreq(priv))
  900. {
  901. ret = -EBUSY;
  902. }
  903. return ret;
  904. }
  905. /****************************************************************************
  906. * Name: rndis_pollworker
  907. *
  908. * Description:
  909. * Worker function called by txpoll worker.
  910. *
  911. ****************************************************************************/
  912. static void rndis_pollworker(FAR void *arg)
  913. {
  914. FAR struct rndis_dev_s *priv = (struct rndis_dev_s *)arg;
  915. DEBUGASSERT(priv != NULL);
  916. net_lock();
  917. if (rndis_allocnetreq(priv))
  918. {
  919. devif_timer(&priv->netdev, rndis_txpoll);
  920. if (priv->net_req != NULL)
  921. {
  922. rndis_freenetreq(priv);
  923. }
  924. }
  925. net_unlock();
  926. }
  927. /****************************************************************************
  928. * Name: rndis_polltimer
  929. *
  930. * Description:
  931. * Network poll watchdog timer callback
  932. *
  933. ****************************************************************************/
  934. static void rndis_polltimer(int argc, uint32_t arg, ...)
  935. {
  936. FAR struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)arg;
  937. int ret;
  938. if (work_available(&priv->pollwork))
  939. {
  940. ret = work_queue(ETHWORK, &priv->pollwork, rndis_pollworker,
  941. (FAR void *)priv, 0);
  942. DEBUGASSERT(ret == OK);
  943. UNUSED(ret);
  944. }
  945. /* Setup the watchdog poll timer again */
  946. (void)wd_start(priv->txpoll, RNDIS_WDDELAY, rndis_polltimer, 1,
  947. (wdparm_t)arg);
  948. }
  949. /****************************************************************************
  950. * Name: rndis_ifup
  951. *
  952. * Description:
  953. * Network ifup callback
  954. *
  955. ****************************************************************************/
  956. static int rndis_ifup(FAR struct net_driver_s *dev)
  957. {
  958. FAR struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)dev->d_private;
  959. (void)wd_start(priv->txpoll, RNDIS_WDDELAY, rndis_polltimer,
  960. 1, (wdparm_t)priv);
  961. return OK;
  962. }
  963. /****************************************************************************
  964. * Name: rndis_ifdown
  965. *
  966. * Description:
  967. * Network ifdown callback
  968. *
  969. ****************************************************************************/
  970. static int rndis_ifdown(FAR struct net_driver_s *dev)
  971. {
  972. FAR struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)dev->d_private;
  973. wd_cancel(priv->txpoll);
  974. return OK;
  975. }
  976. /****************************************************************************
  977. * Name: rndis_txavail_work
  978. *
  979. * Description:
  980. * txavail worker function
  981. *
  982. ****************************************************************************/
  983. static void rndis_txavail_work(FAR void *arg)
  984. {
  985. FAR struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)arg;
  986. net_lock();
  987. if (rndis_allocnetreq(priv))
  988. {
  989. devif_poll(&priv->netdev, rndis_txpoll);
  990. if (priv->net_req != NULL)
  991. {
  992. rndis_freenetreq(priv);
  993. }
  994. }
  995. net_unlock();
  996. }
  997. /****************************************************************************
  998. * Name: rndis_txavail
  999. *
  1000. * Description:
  1001. * Network txavail callback that's called when there are buffers available
  1002. * for sending data. May be called from an interrupt, so we must queue a
  1003. * worker to do the actual processing.
  1004. *
  1005. ****************************************************************************/
  1006. static int rndis_txavail(FAR struct net_driver_s *dev)
  1007. {
  1008. FAR struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)dev->d_private;
  1009. if (work_available(&priv->pollwork))
  1010. {
  1011. work_queue(ETHWORK, &priv->pollwork, rndis_txavail_work, priv, 0);
  1012. }
  1013. return OK;
  1014. }
  1015. /************************************************************************************
  1016. * Name: rndis_recvpacket
  1017. *
  1018. * Description:
  1019. * Handles a USB packet arriving on the data bulk out endpoint.
  1020. *
  1021. * Assumptions:
  1022. * Called from the USB interrupt handler with interrupts disabled.
  1023. *
  1024. ************************************************************************************/
  1025. static inline int rndis_recvpacket(FAR struct rndis_dev_s *priv,
  1026. FAR uint8_t *reqbuf, uint16_t reqlen)
  1027. {
  1028. if (!rndis_allocrxreq(priv))
  1029. {
  1030. return -ENOMEM;
  1031. }
  1032. if (!priv->connected)
  1033. {
  1034. return -EBUSY;
  1035. }
  1036. if (!priv->current_rx_datagram_size)
  1037. {
  1038. if (reqlen < 16)
  1039. {
  1040. /* Packet too small to contain a message header */
  1041. }
  1042. else
  1043. {
  1044. /* The packet contains a RNDIS packet message header */
  1045. FAR struct rndis_packet_msg *msg = (FAR struct rndis_packet_msg *)reqbuf;
  1046. if (msg->msgtype == RNDIS_PACKET_MSG)
  1047. {
  1048. priv->current_rx_received = reqlen;
  1049. priv->current_rx_datagram_size = msg->datalen;
  1050. priv->current_rx_msglen = msg->msglen;
  1051. /* According to RNDIS-over-USB send, if the message length is a
  1052. * multiple of endpoint max packet size, the host must send an
  1053. * additional single-byte zero packet. Take that in account here.
  1054. */
  1055. if ((priv->current_rx_msglen % priv->epbulkout->maxpacket) == 0)
  1056. {
  1057. priv->current_rx_msglen += 1;
  1058. }
  1059. /* Data offset is defined as an offset from the beginning of the
  1060. * offset field itself
  1061. */
  1062. priv->current_rx_datagram_offset = msg->dataoffset + 8;
  1063. if (priv->current_rx_datagram_offset < reqlen)
  1064. {
  1065. memcpy(&priv->rx_req->req->buf[RNDIS_PACKET_HDR_SIZE],
  1066. &reqbuf[priv->current_rx_datagram_offset],
  1067. reqlen - priv->current_rx_datagram_offset);
  1068. }
  1069. }
  1070. else
  1071. {
  1072. uerr("Unknown RNDIS message type %u\n", msg->msgtype);
  1073. }
  1074. }
  1075. }
  1076. else
  1077. {
  1078. if (priv->current_rx_received >= priv->current_rx_datagram_offset &&
  1079. priv->current_rx_received <= priv->current_rx_datagram_size +
  1080. priv->current_rx_datagram_offset)
  1081. {
  1082. size_t index = priv->current_rx_received - priv->current_rx_datagram_offset;
  1083. size_t copysize = min(reqlen, priv->current_rx_datagram_size - index);
  1084. /* Check if the received packet exceeds request buffer */
  1085. if ((index + copysize) <= CONFIG_NET_ETH_PKTSIZE)
  1086. {
  1087. memcpy(&priv->rx_req->req->buf[RNDIS_PACKET_HDR_SIZE + index], reqbuf,
  1088. copysize);
  1089. }
  1090. else
  1091. {
  1092. uerr("The packet exceeds request buffer (reqlen=%d) \n", reqlen);
  1093. }
  1094. }
  1095. priv->current_rx_received += reqlen;
  1096. }
  1097. if (priv->current_rx_received >= priv->current_rx_msglen)
  1098. {
  1099. /* Check for a usable packet length (4 added for the CRC) */
  1100. if (priv->current_rx_datagram_size > (CONFIG_NET_ETH_PKTSIZE + 4) ||
  1101. priv->current_rx_datagram_size <= (ETH_HDRLEN + 4))
  1102. {
  1103. uerr("ERROR: Bad packet size dropped (%d)\n",
  1104. priv->current_rx_datagram_size);
  1105. NETDEV_RXERRORS(&priv->netdev);
  1106. priv->current_rx_datagram_size = 0;
  1107. }
  1108. else
  1109. {
  1110. int ret;
  1111. DEBUGASSERT(work_available(&priv->rxwork));
  1112. ret = work_queue(ETHWORK, &priv->rxwork, rndis_rxdispatch,
  1113. priv, 0);
  1114. DEBUGASSERT(ret == 0);
  1115. UNUSED(ret);
  1116. rndis_block_rx(priv);
  1117. priv->rndis_host_tx_count++;
  1118. return -EBUSY;
  1119. }
  1120. }
  1121. return OK;
  1122. }
  1123. /****************************************************************************
  1124. * Name: rndis_prepare_response
  1125. *
  1126. * Description:
  1127. * Passes the RX packet buffer to the network
  1128. *
  1129. * Input Parameters:
  1130. * priv: pointer to RNDIS device driver structure
  1131. *
  1132. * Assumptions:
  1133. * Called from critical section
  1134. *
  1135. ****************************************************************************/
  1136. static bool rndis_prepare_response(FAR struct rndis_dev_s *priv, size_t size,
  1137. FAR struct rndis_command_header *request_hdr)
  1138. {
  1139. FAR struct rndis_response_header *hdr =
  1140. (FAR struct rndis_response_header *)priv->ctrlreq->buf;
  1141. hdr->msgtype = request_hdr->msgtype | RNDIS_MSG_COMPLETE;
  1142. hdr->msglen = size;
  1143. hdr->reqid = request_hdr->reqid;
  1144. hdr->status = RNDIS_STATUS_SUCCESS;
  1145. priv->ctrlreq_has_encap_response = true;
  1146. return true;
  1147. }
  1148. /****************************************************************************
  1149. * Name: rndis_send_encapsulated_response
  1150. *
  1151. * Description:
  1152. * Give a notification to the host that there is an encapsulated response
  1153. * available.
  1154. *
  1155. * Input Parameters:
  1156. * priv: pointer to RNDIS device driver structure
  1157. *
  1158. * Assumptions:
  1159. * Called from critical section
  1160. *
  1161. ****************************************************************************/
  1162. static int rndis_send_encapsulated_response(FAR struct rndis_dev_s *priv)
  1163. {
  1164. FAR struct rndis_notification *notif =
  1165. (FAR struct rndis_notification *)priv->epintin_req->buf;
  1166. notif->notification = RNDIS_NOTIFICATION_RESPONSE_AVAILABLE;
  1167. notif->reserved = 0;
  1168. priv->epintin_req->len = sizeof(struct rndis_notification);
  1169. EP_CANCEL(priv->epintin, priv->epintin_req);
  1170. EP_SUBMIT(priv->epintin, priv->epintin_req);
  1171. return OK;
  1172. }
  1173. /****************************************************************************
  1174. * Name: rndis_handle_control_message
  1175. *
  1176. * Description:
  1177. * Handle a RNDIS control message.
  1178. *
  1179. * Input Parameters:
  1180. * priv: pointer to RNDIS device driver structure
  1181. *
  1182. * Assumptions:
  1183. * Called from critical section
  1184. *
  1185. ****************************************************************************/
  1186. static int rndis_handle_control_message(FAR struct rndis_dev_s *priv,
  1187. FAR uint8_t *dataout, uint16_t outlen)
  1188. {
  1189. FAR struct rndis_command_header *cmd_hdr =
  1190. (FAR struct rndis_command_header *)dataout;
  1191. switch (cmd_hdr->msgtype)
  1192. {
  1193. case RNDIS_INITIALIZE_MSG:
  1194. {
  1195. FAR struct rndis_initialize_cmplt *resp;
  1196. rndis_prepare_response(priv, sizeof(struct rndis_initialize_cmplt), cmd_hdr);
  1197. resp = (FAR struct rndis_initialize_cmplt *)priv->ctrlreq->buf;
  1198. resp->major = RNDIS_MAJOR_VERSION;
  1199. resp->minor = RNDIS_MINOR_VERSION;
  1200. resp->devflags = RNDIS_DEVICEFLAGS;
  1201. resp->medium = RNDIS_MEDIUM_802_3;
  1202. resp->pktperxfer = 1;
  1203. resp->xfrsize = (4 + 44 + 22) + RNDIS_BUFFER_SIZE;
  1204. resp->pktalign = 2;
  1205. rndis_send_encapsulated_response(priv);
  1206. }
  1207. break;
  1208. case RNDIS_HALT_MSG:
  1209. {
  1210. priv->connected = false;
  1211. }
  1212. break;
  1213. case RNDIS_QUERY_MSG:
  1214. {
  1215. int i;
  1216. size_t max_reply_size = sizeof(struct rndis_query_cmplt) +
  1217. sizeof(g_rndis_supported_oids);
  1218. rndis_prepare_response(priv, max_reply_size, cmd_hdr);
  1219. FAR struct rndis_query_msg *req =
  1220. (FAR struct rndis_query_msg *)dataout;
  1221. FAR struct rndis_query_cmplt *resp =
  1222. (FAR struct rndis_query_cmplt *)priv->ctrlreq->buf;
  1223. resp->hdr.msglen = sizeof(struct rndis_query_cmplt);
  1224. resp->bufoffset = 0;
  1225. resp->buflen = 0;
  1226. resp->hdr.status = RNDIS_STATUS_NOT_SUPPORTED;
  1227. for (i = 0;
  1228. i < sizeof(g_rndis_oid_values)/sizeof(g_rndis_oid_values[0]);
  1229. i++)
  1230. {
  1231. bool match = (g_rndis_oid_values[i].objid == req->objid);
  1232. if (!match && g_rndis_oid_values[i].objid == 0)
  1233. {
  1234. int j;
  1235. /* Check whether to apply the fallback entry */
  1236. for (j = 0; j < sizeof(g_rndis_supported_oids)/sizeof(uint32_t); j++)
  1237. {
  1238. if (g_rndis_supported_oids[j] == req->objid)
  1239. {
  1240. match = true;
  1241. break;
  1242. }
  1243. }
  1244. }
  1245. if (match)
  1246. {
  1247. resp->hdr.status = RNDIS_STATUS_SUCCESS;
  1248. resp->bufoffset = 16;
  1249. resp->buflen = g_rndis_oid_values[i].length;
  1250. if (req->objid == RNDIS_OID_GEN_CURRENT_PACKET_FILTER)
  1251. {
  1252. resp->buffer[0] = priv->rndis_packet_filter;
  1253. }
  1254. else if (req->objid == RNDIS_OID_GEN_XMIT_OK)
  1255. {
  1256. resp->buffer[0] = priv->rndis_host_tx_count;
  1257. }
  1258. else if (req->objid == RNDIS_OID_GEN_RCV_OK)
  1259. {
  1260. resp->buffer[0] = priv->rndis_host_rx_count;
  1261. }
  1262. else if (req->objid == RNDIS_OID_802_3_CURRENT_ADDRESS ||
  1263. req->objid == RNDIS_OID_802_3_PERMANENT_ADDRESS)
  1264. {
  1265. memcpy(resp->buffer, priv->host_mac_address, 6);
  1266. }
  1267. else if (g_rndis_oid_values[i].data)
  1268. {
  1269. memcpy(resp->buffer, g_rndis_oid_values[i].data,
  1270. resp->buflen);
  1271. }
  1272. else
  1273. {
  1274. memcpy(resp->buffer, &g_rndis_oid_values[i].value,
  1275. resp->buflen);
  1276. }
  1277. break;
  1278. }
  1279. }
  1280. uinfo("RNDIS Query RID=%08x OID=%08x LEN=%d DAT=%08x",
  1281. (unsigned)req->hdr.reqid, (unsigned)req->objid,
  1282. (int)resp->buflen, (unsigned)resp->buffer[0]);
  1283. resp->hdr.msglen += resp->buflen;
  1284. rndis_send_encapsulated_response(priv);
  1285. }
  1286. break;
  1287. case RNDIS_SET_MSG:
  1288. {
  1289. FAR struct rndis_set_msg *req;
  1290. FAR struct rndis_response_header *resp;
  1291. rndis_prepare_response(priv, sizeof(struct rndis_response_header),
  1292. cmd_hdr);
  1293. req = (FAR struct rndis_set_msg *)dataout;
  1294. resp = (FAR struct rndis_response_header *)priv->ctrlreq->buf;
  1295. uinfo("RNDIS SET RID=%08x OID=%08x LEN=%d DAT=%08x",
  1296. (unsigned)req->hdr.reqid, (unsigned)req->objid,
  1297. (int)req->buflen, (unsigned)req->buffer[0]);
  1298. if (req->objid == RNDIS_OID_GEN_CURRENT_PACKET_FILTER)
  1299. {
  1300. priv->rndis_packet_filter = req->buffer[0];
  1301. if (req->buffer[0] == 0)
  1302. {
  1303. priv->connected = false;
  1304. }
  1305. else
  1306. {
  1307. uinfo("RNDIS is now connected");
  1308. priv->connected = true;
  1309. }
  1310. }
  1311. else if (req->objid == RNDIS_OID_802_3_MULTICAST_LIST)
  1312. {
  1313. uinfo("RNDIS multicast list ignored");
  1314. }
  1315. else
  1316. {
  1317. uinfo("RNDIS unsupported set %08x", (unsigned)req->objid);
  1318. resp->status = RNDIS_STATUS_NOT_SUPPORTED;
  1319. }
  1320. rndis_send_encapsulated_response(priv);
  1321. }
  1322. break;
  1323. case RNDIS_RESET_MSG:
  1324. {
  1325. FAR struct rndis_reset_cmplt *resp;
  1326. rndis_prepare_response(priv, sizeof(struct rndis_reset_cmplt),
  1327. cmd_hdr);
  1328. resp = (FAR struct rndis_reset_cmplt *)priv->ctrlreq->buf;
  1329. resp->addreset = 0;
  1330. priv->connected = false;
  1331. rndis_send_encapsulated_response(priv);
  1332. }
  1333. break;
  1334. case RNDIS_KEEPALIVE_MSG:
  1335. {
  1336. rndis_prepare_response(priv, sizeof(struct rndis_response_header),
  1337. cmd_hdr);
  1338. rndis_send_encapsulated_response(priv);
  1339. }
  1340. break;
  1341. default:
  1342. uwarn("Unsupported RNDIS control message: %u\n", cmd_hdr->msgtype);
  1343. }
  1344. return OK;
  1345. }
  1346. /****************************************************************************
  1347. * Name: rndis_rdcomplete
  1348. *
  1349. * Description:
  1350. * Handle completion of read request on the bulk OUT endpoint.
  1351. *
  1352. ****************************************************************************/
  1353. static void rndis_rdcomplete(FAR struct usbdev_ep_s *ep,
  1354. FAR struct usbdev_req_s *req)
  1355. {
  1356. FAR struct rndis_dev_s *priv;
  1357. irqstate_t flags;
  1358. int ret;
  1359. /* Sanity check */
  1360. #ifdef CONFIG_DEBUG_FEATURES
  1361. if (!ep || !ep->priv || !req)
  1362. {
  1363. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
  1364. return;
  1365. }
  1366. #endif
  1367. /* Extract references to private data */
  1368. priv = (FAR struct rndis_dev_s *)ep->priv;
  1369. /* Process the received data unless this is some unusual condition */
  1370. ret = OK;
  1371. flags = enter_critical_section();
  1372. priv->rdreq_submitted = false;
  1373. switch (req->result)
  1374. {
  1375. case 0: /* Normal completion */
  1376. ret = rndis_recvpacket(priv, req->buf, req->xfrd);
  1377. DEBUGASSERT(ret != -ENOMEM);
  1378. break;
  1379. case -ESHUTDOWN: /* Disconnection */
  1380. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSHUTDOWN), 0);
  1381. leave_critical_section(flags);
  1382. return;
  1383. default: /* Some other error occurred */
  1384. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDUNEXPECTED), (uint16_t)-req->result);
  1385. break;
  1386. };
  1387. if (ret == OK)
  1388. {
  1389. rndis_submit_rdreq(priv);
  1390. }
  1391. leave_critical_section(flags);
  1392. }
  1393. /****************************************************************************
  1394. * Name: rndis_wrcomplete
  1395. *
  1396. * Description:
  1397. * Handle completion of write request. This function probably executes
  1398. * in the context of an interrupt handler.
  1399. *
  1400. ****************************************************************************/
  1401. static void rndis_wrcomplete(FAR struct usbdev_ep_s *ep,
  1402. FAR struct usbdev_req_s *req)
  1403. {
  1404. FAR struct rndis_dev_s *priv;
  1405. FAR struct rndis_req_s *reqcontainer;
  1406. irqstate_t flags;
  1407. /* Sanity check */
  1408. #ifdef CONFIG_DEBUG_FEATURES
  1409. if (!ep || !ep->priv || !req || !req->priv)
  1410. {
  1411. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
  1412. return;
  1413. }
  1414. #endif
  1415. /* Extract references to our private data */
  1416. priv = (FAR struct rndis_dev_s *)ep->priv;
  1417. reqcontainer = (FAR struct rndis_req_s *)req->priv;
  1418. /* Return the write request to the free list */
  1419. flags = enter_critical_section();
  1420. rndis_freewrreq(priv, reqcontainer);
  1421. if (rndis_hasfreereqs(priv))
  1422. {
  1423. rndis_txavail(&priv->netdev);
  1424. }
  1425. switch (req->result)
  1426. {
  1427. case OK: /* Normal completion */
  1428. priv->rndis_host_rx_count++;
  1429. break;
  1430. case -ESHUTDOWN: /* Disconnection */
  1431. break;
  1432. default: /* Some other error occurred */
  1433. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRUNEXPECTED),
  1434. (uint16_t)-req->result);
  1435. break;
  1436. }
  1437. leave_critical_section(flags);
  1438. }
  1439. /****************************************************************************
  1440. * Name: usbclass_ep0incomplete
  1441. *
  1442. * Description:
  1443. * Handle completion of EP0 control operations
  1444. *
  1445. ****************************************************************************/
  1446. static void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep,
  1447. FAR struct usbdev_req_s *req)
  1448. {
  1449. if (req->result || req->xfrd != req->len)
  1450. {
  1451. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_REQRESULT),
  1452. (uint16_t)-req->result);
  1453. }
  1454. else if (req->len > 0)
  1455. {
  1456. struct rndis_dev_s *priv = (FAR struct rndis_dev_s *)ep->priv;
  1457. priv->ctrlreq_has_encap_response = false;
  1458. }
  1459. }
  1460. /****************************************************************************
  1461. * Name: usbclass_ep0incomplete
  1462. *
  1463. * Description:
  1464. * Handle completion of interrupt IN endpoint operations
  1465. *
  1466. ****************************************************************************/
  1467. static void usbclass_epintin_complete(FAR struct usbdev_ep_s *ep,
  1468. FAR struct usbdev_req_s *req)
  1469. {
  1470. if (req->result || req->xfrd != req->len)
  1471. {
  1472. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_REQRESULT),
  1473. (uint16_t)-req->result);
  1474. }
  1475. }
  1476. /****************************************************************************
  1477. * Name: usbclass_freereq
  1478. *
  1479. * Description:
  1480. * Free a request instance along with its buffer
  1481. *
  1482. ****************************************************************************/
  1483. static void usbclass_freereq(FAR struct usbdev_ep_s *ep,
  1484. FAR struct usbdev_req_s *req)
  1485. {
  1486. if (ep != NULL && req != NULL)
  1487. {
  1488. if (req->buf != NULL)
  1489. {
  1490. EP_FREEBUFFER(ep, req->buf);
  1491. }
  1492. EP_FREEREQ(ep, req);
  1493. }
  1494. }
  1495. /****************************************************************************
  1496. * Name: usbclass_allocreq
  1497. *
  1498. * Description:
  1499. * Allocate a request instance along with its buffer
  1500. *
  1501. ****************************************************************************/
  1502. static FAR struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep,
  1503. uint16_t len)
  1504. {
  1505. FAR struct usbdev_req_s *req;
  1506. req = EP_ALLOCREQ(ep);
  1507. if (req != NULL)
  1508. {
  1509. req->len = len;
  1510. req->buf = EP_ALLOCBUFFER(ep, len);
  1511. if (req->buf == NULL)
  1512. {
  1513. EP_FREEREQ(ep, req);
  1514. req = NULL;
  1515. }
  1516. }
  1517. return req;
  1518. }
  1519. /****************************************************************************
  1520. * Name: usbclass_mkstrdesc
  1521. *
  1522. * Description:
  1523. * Construct a string descriptor
  1524. *
  1525. ****************************************************************************/
  1526. static int usbclass_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc)
  1527. {
  1528. FAR const char *str;
  1529. int len;
  1530. int ndata;
  1531. int i;
  1532. switch (id)
  1533. {
  1534. #ifndef CONFIG_RNDIS_COMPOSITE
  1535. case 0:
  1536. {
  1537. /* Descriptor 0 is the language id */
  1538. strdesc->len = 4;
  1539. strdesc->type = USB_DESC_TYPE_STRING;
  1540. strdesc->data[0] = LSBYTE(RNDIS_STR_LANGUAGE);
  1541. strdesc->data[1] = MSBYTE(RNDIS_STR_LANGUAGE);
  1542. return 4;
  1543. }
  1544. case RNDIS_MANUFACTURERSTRID:
  1545. str = CONFIG_RNDIS_VENDORSTR;
  1546. break;
  1547. case RNDIS_PRODUCTSTRID:
  1548. str = CONFIG_RNDIS_PRODUCTSTR;
  1549. break;
  1550. case RNDIS_SERIALSTRID:
  1551. str = CONFIG_RNDIS_SERIALSTR;
  1552. break;
  1553. #endif
  1554. default:
  1555. return -EINVAL;
  1556. }
  1557. /* The string is utf16-le. The poor man's utf-8 to utf16-le
  1558. * conversion below will only handle 7-bit en-us ascii
  1559. */
  1560. len = strlen(str);
  1561. if (len > (RNDIS_MAXSTRLEN / 2))
  1562. {
  1563. len = (RNDIS_MAXSTRLEN / 2);
  1564. }
  1565. for (i = 0, ndata = 0; i < len; i++, ndata += 2)
  1566. {
  1567. strdesc->data[ndata] = str[i];
  1568. strdesc->data[ndata+1] = 0;
  1569. }
  1570. strdesc->len = ndata+2;
  1571. strdesc->type = USB_DESC_TYPE_STRING;
  1572. return strdesc->len;
  1573. }
  1574. /****************************************************************************
  1575. * Name: usbclass_copy_epdesc
  1576. *
  1577. * Description:
  1578. * Copies the requested Endpoint Description into the buffer given.
  1579. * Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ).
  1580. *
  1581. ****************************************************************************/
  1582. static int usbclass_copy_epdesc(int epid, FAR struct usb_epdesc_s *epdesc,
  1583. FAR struct usbdev_devinfo_s *devinfo,
  1584. bool hispeed)
  1585. {
  1586. #ifndef CONFIG_USBDEV_DUALSPEED
  1587. UNUSED(hispeed);
  1588. #endif
  1589. switch (epid)
  1590. {
  1591. case RNDIS_EP_INTIN_IDX: /* Interrupt IN endpoint */
  1592. {
  1593. epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
  1594. epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
  1595. epdesc->addr = RNDIS_MKEPINTIN(devinfo); /* Endpoint address */
  1596. epdesc->attr = RNDIS_EPINTIN_ATTR; /* Endpoint attributes */
  1597. #ifdef CONFIG_USBDEV_DUALSPEED
  1598. if (hispeed)
  1599. {
  1600. /* Maximum packet size (high speed) */
  1601. epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPINTIN_HSSIZE);
  1602. epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPINTIN_HSSIZE);
  1603. }
  1604. else
  1605. #endif
  1606. {
  1607. /* Maximum packet size (full speed) */
  1608. epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPINTIN_FSSIZE);
  1609. epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPINTIN_FSSIZE);
  1610. }
  1611. epdesc->interval = 10; /* Interval */
  1612. }
  1613. break;
  1614. case RNDIS_EP_BULKOUT_IDX: /* Bulk OUT endpoint */
  1615. {
  1616. epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
  1617. epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
  1618. epdesc->addr = RNDIS_MKEPBULKOUT(devinfo); /* Endpoint address */
  1619. epdesc->attr = RNDIS_EPOUTBULK_ATTR; /* Endpoint attributes */
  1620. #ifdef CONFIG_USBDEV_DUALSPEED
  1621. if (hispeed)
  1622. {
  1623. /* Maximum packet size (high speed) */
  1624. epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKOUT_HSSIZE);
  1625. epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKOUT_HSSIZE);
  1626. }
  1627. else
  1628. #endif
  1629. {
  1630. /* Maximum packet size (full speed) */
  1631. epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKOUT_FSSIZE);
  1632. epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKOUT_FSSIZE);
  1633. }
  1634. epdesc->interval = 0; /* Interval */
  1635. }
  1636. break;
  1637. case RNDIS_EP_BULKIN_IDX: /* Bulk IN endpoint */
  1638. {
  1639. epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
  1640. epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
  1641. epdesc->addr = RNDIS_MKEPBULKIN(devinfo); /* Endpoint address */
  1642. epdesc->attr = RNDIS_EPINBULK_ATTR; /* Endpoint attributes */
  1643. #ifdef CONFIG_USBDEV_DUALSPEED
  1644. if (hispeed)
  1645. {
  1646. /* Maximum packet size (high speed) */
  1647. epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKIN_HSSIZE);
  1648. epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKIN_HSSIZE);
  1649. }
  1650. else
  1651. #endif
  1652. {
  1653. /* Maximum packet size (full speed) */
  1654. epdesc->mxpacketsize[0] = LSBYTE(CONFIG_RNDIS_EPBULKIN_FSSIZE);
  1655. epdesc->mxpacketsize[1] = MSBYTE(CONFIG_RNDIS_EPBULKIN_FSSIZE);
  1656. }
  1657. epdesc->interval = 0; /* Interval */
  1658. }
  1659. break;
  1660. default:
  1661. return 0;
  1662. }
  1663. return sizeof(struct usb_epdesc_s);
  1664. }
  1665. /****************************************************************************
  1666. * Name: usbclass_mkcfgdesc
  1667. *
  1668. * Description:
  1669. * Construct the configuration descriptor
  1670. *
  1671. ****************************************************************************/
  1672. static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
  1673. FAR struct usbdev_devinfo_s *devinfo)
  1674. {
  1675. FAR struct rndis_cfgdesc_s *dest = (FAR struct rndis_cfgdesc_s *)buf;
  1676. uint16_t totallen;
  1677. /* This is the total length of the configuration (not necessarily the
  1678. * size that we will be sending now).
  1679. */
  1680. totallen = sizeof(g_rndis_cfgdesc);
  1681. memcpy(dest, &g_rndis_cfgdesc, totallen);
  1682. #ifndef CONFIG_RNDIS_COMPOSITE
  1683. /* For a stand-alone device, just fill in the total length */
  1684. dest->cfgdesc.totallen[0] = LSBYTE(totallen);
  1685. dest->cfgdesc.totallen[1] = MSBYTE(totallen);
  1686. #else
  1687. /* For composite device, apply possible offset to the interface numbers */
  1688. dest->assoc_desc.firstif += devinfo->ifnobase;
  1689. dest->comm_ifdesc.ifno += devinfo->ifnobase;
  1690. dest->epintindesc.addr = USB_EPIN(devinfo->epno[RNDIS_EP_INTIN_IDX]);
  1691. dest->data_ifdesc.ifno += devinfo->ifnobase;
  1692. dest->epbulkindesc.addr = USB_EPIN(devinfo->epno[RNDIS_EP_BULKIN_IDX]);
  1693. dest->epbulkoutdesc.addr = USB_EPOUT(devinfo->epno[RNDIS_EP_BULKOUT_IDX]);
  1694. #endif
  1695. return totallen;
  1696. }
  1697. /****************************************************************************
  1698. * Name: usbclass_bind
  1699. *
  1700. * Description:
  1701. * Invoked when the driver is bound to a USB device driver
  1702. *
  1703. ****************************************************************************/
  1704. static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
  1705. FAR struct usbdev_s *dev)
  1706. {
  1707. FAR struct rndis_dev_s *priv = ((FAR struct rndis_driver_s *)driver)->dev;
  1708. FAR struct rndis_req_s *reqcontainer;
  1709. irqstate_t flags;
  1710. uint16_t reqlen;
  1711. int ret;
  1712. int i;
  1713. usbtrace(TRACE_CLASSBIND, 0);
  1714. /* Bind the structures */
  1715. priv->usbdev = dev;
  1716. /* Save the reference to our private data structure in EP0 so that it
  1717. * can be recovered in ep0 completion events (Unless we are part of
  1718. * a composite device and, in that case, the composite device owns
  1719. * EP0).
  1720. */
  1721. dev->ep0->priv = priv;
  1722. /* Preallocate control request */
  1723. priv->ctrlreq = usbclass_allocreq(dev->ep0, RNDIS_CTRLREQ_LEN);
  1724. if (priv->ctrlreq == NULL)
  1725. {
  1726. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCCTRLREQ), 0);
  1727. ret = -ENOMEM;
  1728. goto errout;
  1729. }
  1730. priv->ctrlreq->callback = usbclass_ep0incomplete;
  1731. /* Pre-allocate all endpoints... the endpoints will not be functional
  1732. * until the SET CONFIGURATION request is processed in usbclass_setconfig.
  1733. * This is done here because there may be calls to kmm_malloc and the SET
  1734. * CONFIGURATION processing probably occurs within interrupt handling
  1735. * logic where kmm_malloc calls will fail.
  1736. */
  1737. /* Pre-allocate the IN interrupt endpoint */
  1738. priv->epintin = DEV_ALLOCEP(dev, USB_EPIN(priv->devinfo.epno[RNDIS_EP_INTIN_IDX]),
  1739. true, USB_EP_ATTR_XFER_INT);
  1740. if (!priv->epintin)
  1741. {
  1742. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINALLOCFAIL), 0);
  1743. ret = -ENODEV;
  1744. goto errout;
  1745. }
  1746. priv->epintin->priv = priv;
  1747. priv->epintin_req = usbclass_allocreq(priv->epintin, sizeof(struct rndis_notification));
  1748. if (priv->epintin_req == NULL)
  1749. {
  1750. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDALLOCREQ), -ENOMEM);
  1751. ret = -ENOMEM;
  1752. goto errout;
  1753. }
  1754. priv->epintin_req->callback = usbclass_epintin_complete;
  1755. /* Pre-allocate the IN bulk endpoint */
  1756. priv->epbulkin = DEV_ALLOCEP(dev, USB_EPIN(priv->devinfo.epno[RNDIS_EP_BULKIN_IDX]),
  1757. true, USB_EP_ATTR_XFER_BULK);
  1758. if (!priv->epbulkin)
  1759. {
  1760. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINALLOCFAIL), 0);
  1761. ret = -ENODEV;
  1762. goto errout;
  1763. }
  1764. priv->epbulkin->priv = priv;
  1765. /* Pre-allocate the OUT bulk endpoint */
  1766. priv->epbulkout = DEV_ALLOCEP(dev, USB_EPOUT(priv->devinfo.epno[RNDIS_EP_BULKOUT_IDX]),
  1767. false, USB_EP_ATTR_XFER_BULK);
  1768. if (!priv->epbulkout)
  1769. {
  1770. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTALLOCFAIL), 0);
  1771. ret = -ENODEV;
  1772. goto errout;
  1773. }
  1774. priv->epbulkout->priv = priv;
  1775. /* Pre-allocate read requests. The buffer size is one full packet. */
  1776. reqlen = 64;
  1777. if (CONFIG_RNDIS_BULKOUT_REQLEN > reqlen)
  1778. {
  1779. reqlen = CONFIG_RNDIS_BULKOUT_REQLEN;
  1780. }
  1781. priv->rdreq = usbclass_allocreq(priv->epbulkout, reqlen);
  1782. if (priv->rdreq == NULL)
  1783. {
  1784. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDALLOCREQ), -ENOMEM);
  1785. ret = -ENOMEM;
  1786. goto errout;
  1787. }
  1788. priv->rdreq->callback = rndis_rdcomplete;
  1789. /* Pre-allocate write request containers and put in a free list.
  1790. * The buffer size should be larger than a full packet. Otherwise,
  1791. * we will send a bogus null packet at the end of each packet.
  1792. *
  1793. * Pick the larger of the max packet size and the configured request
  1794. * size.
  1795. */
  1796. reqlen = 64;
  1797. if (CONFIG_RNDIS_BULKIN_REQLEN > reqlen)
  1798. {
  1799. reqlen = CONFIG_RNDIS_BULKIN_REQLEN;
  1800. }
  1801. for (i = 0; i < CONFIG_RNDIS_NWRREQS; i++)
  1802. {
  1803. reqcontainer = &priv->wrreqs[i];
  1804. reqcontainer->req = usbclass_allocreq(priv->epbulkin, reqlen);
  1805. if (reqcontainer->req == NULL)
  1806. {
  1807. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRALLOCREQ), -ENOMEM);
  1808. ret = -ENOMEM;
  1809. goto errout;
  1810. }
  1811. reqcontainer->req->priv = reqcontainer;
  1812. reqcontainer->req->callback = rndis_wrcomplete;
  1813. flags = enter_critical_section();
  1814. sq_addlast((FAR sq_entry_t *)reqcontainer, &priv->reqlist);
  1815. leave_critical_section(flags);
  1816. }
  1817. /* Report if we are selfpowered */
  1818. #ifndef CONFIG_RNDIS_COMPOSITE
  1819. #ifdef CONFIG_USBDEV_SELFPOWERED
  1820. DEV_SETSELFPOWERED(dev);
  1821. #endif
  1822. /* And pull-up the data line for the soft connect function */
  1823. DEV_CONNECT(dev);
  1824. #endif
  1825. return OK;
  1826. errout:
  1827. usbclass_unbind(driver, dev);
  1828. return ret;
  1829. }
  1830. /****************************************************************************
  1831. * Name: usbclass_unbind
  1832. *
  1833. * Description:
  1834. * Invoked when the driver is unbound from a USB device driver
  1835. *
  1836. ****************************************************************************/
  1837. static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
  1838. FAR struct usbdev_s *dev)
  1839. {
  1840. FAR struct rndis_dev_s *priv;
  1841. FAR struct rndis_req_s *reqcontainer;
  1842. irqstate_t flags;
  1843. usbtrace(TRACE_CLASSUNBIND, 0);
  1844. #ifdef CONFIG_DEBUG_FEATURES
  1845. if (!driver || !dev || !dev->ep0)
  1846. {
  1847. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
  1848. return;
  1849. }
  1850. #endif
  1851. /* Extract reference to private data */
  1852. priv = ((FAR struct rndis_driver_s *)driver)->dev;
  1853. #ifdef CONFIG_DEBUG_FEATURES
  1854. if (!priv)
  1855. {
  1856. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
  1857. return;
  1858. }
  1859. #endif
  1860. /* Make sure that we are not already unbound */
  1861. if (priv != NULL)
  1862. {
  1863. /* Make sure that the endpoints have been unconfigured. If
  1864. * we were terminated gracefully, then the configuration should
  1865. * already have been reset. If not, then calling usbclass_resetconfig
  1866. * should cause the endpoints to immediately terminate all
  1867. * transfers and return the requests to us (with result == -ESHUTDOWN)
  1868. */
  1869. usbclass_resetconfig(priv);
  1870. up_mdelay(50);
  1871. /* Free the interrupt IN endpoint */
  1872. if (priv->epintin)
  1873. {
  1874. DEV_FREEEP(dev, priv->epintin);
  1875. priv->epintin = NULL;
  1876. }
  1877. /* Free the bulk IN endpoint */
  1878. if (priv->epbulkin)
  1879. {
  1880. DEV_FREEEP(dev, priv->epbulkin);
  1881. priv->epbulkin = NULL;
  1882. }
  1883. /* Free the pre-allocated control request */
  1884. if (priv->ctrlreq != NULL)
  1885. {
  1886. usbclass_freereq(dev->ep0, priv->ctrlreq);
  1887. priv->ctrlreq = NULL;
  1888. }
  1889. if (priv->epintin_req != NULL)
  1890. {
  1891. usbclass_freereq(priv->epintin, priv->epintin_req);
  1892. priv->epintin_req = NULL;
  1893. }
  1894. /* Free pre-allocated read requests (which should all have
  1895. * been returned to the free list at this time -- we don't check)
  1896. */
  1897. if (priv->rdreq)
  1898. {
  1899. usbclass_freereq(priv->epbulkout, priv->rdreq);
  1900. }
  1901. /* Free the bulk OUT endpoint */
  1902. if (priv->epbulkout)
  1903. {
  1904. DEV_FREEEP(dev, priv->epbulkout);
  1905. priv->epbulkout = NULL;
  1906. }
  1907. netdev_unregister(&priv->netdev);
  1908. /* Free write requests that are not in use (which should be all
  1909. * of them
  1910. */
  1911. flags = enter_critical_section();
  1912. while (!sq_empty(&priv->reqlist))
  1913. {
  1914. reqcontainer = (struct rndis_req_s *)sq_remfirst(&priv->reqlist);
  1915. if (reqcontainer->req != NULL)
  1916. {
  1917. usbclass_freereq(priv->epbulkin, reqcontainer->req);
  1918. }
  1919. }
  1920. leave_critical_section(flags);
  1921. }
  1922. }
  1923. /****************************************************************************
  1924. * Name: usbclass_setup
  1925. *
  1926. * Description:
  1927. * Invoked for ep0 control requests. This function probably executes
  1928. * in the context of an interrupt handler.
  1929. *
  1930. ****************************************************************************/
  1931. static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
  1932. FAR struct usbdev_s *dev,
  1933. FAR const struct usb_ctrlreq_s *ctrl,
  1934. FAR uint8_t *dataout, size_t outlen)
  1935. {
  1936. FAR struct rndis_dev_s *priv;
  1937. FAR struct usbdev_req_s *ctrlreq;
  1938. uint16_t value;
  1939. uint16_t len;
  1940. int ret = -EOPNOTSUPP;
  1941. #ifdef CONFIG_DEBUG_FEATURES
  1942. if (!driver || !dev || !dev->ep0 || !ctrl)
  1943. {
  1944. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
  1945. return -EIO;
  1946. }
  1947. #endif
  1948. /* Extract reference to private data */
  1949. usbtrace(TRACE_CLASSSETUP, ctrl->req);
  1950. priv = ((FAR struct rndis_driver_s *)driver)->dev;
  1951. #ifdef CONFIG_DEBUG_FEATURES
  1952. if (!priv || !priv->ctrlreq)
  1953. {
  1954. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
  1955. return -ENODEV;
  1956. }
  1957. #endif
  1958. ctrlreq = priv->ctrlreq;
  1959. /* Extract the little-endian 16-bit values to host order */
  1960. value = GETUINT16(ctrl->value);
  1961. len = GETUINT16(ctrl->len);
  1962. uinfo("type=%02x req=%02x value=%04x len=%04x\n",
  1963. ctrl->type, ctrl->req, value, len);
  1964. switch (ctrl->type & USB_REQ_TYPE_MASK)
  1965. {
  1966. /***********************************************************************
  1967. * Standard Requests
  1968. ***********************************************************************/
  1969. case USB_REQ_TYPE_STANDARD:
  1970. {
  1971. switch (ctrl->req)
  1972. {
  1973. case USB_REQ_GETDESCRIPTOR:
  1974. {
  1975. /* The value field specifies the descriptor type in the MS byte and the
  1976. * descriptor index in the LS byte (order is little endian)
  1977. */
  1978. switch (ctrl->value[1])
  1979. {
  1980. #ifndef CONFIG_RNDIS_COMPOSITE
  1981. case USB_DESC_TYPE_DEVICE:
  1982. {
  1983. ret = USB_SIZEOF_DEVDESC;
  1984. memcpy(ctrlreq->buf, &g_devdesc, ret);
  1985. }
  1986. break;
  1987. #endif
  1988. case USB_DESC_TYPE_CONFIG:
  1989. {
  1990. ret = usbclass_mkcfgdesc(ctrlreq->buf, &priv->devinfo);
  1991. }
  1992. break;
  1993. case USB_DESC_TYPE_STRING:
  1994. {
  1995. /* index == language code. */
  1996. ret = usbclass_mkstrdesc(ctrl->value[0],
  1997. (FAR struct usb_strdesc_s *)ctrlreq->buf);
  1998. }
  1999. break;
  2000. default:
  2001. {
  2002. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_GETUNKNOWNDESC), value);
  2003. }
  2004. break;
  2005. }
  2006. }
  2007. break;
  2008. case USB_REQ_SETCONFIGURATION:
  2009. {
  2010. if (ctrl->type == 0)
  2011. {
  2012. ret = usbclass_setconfig(priv, value);
  2013. }
  2014. }
  2015. break;
  2016. case USB_REQ_GETCONFIGURATION:
  2017. {
  2018. if (ctrl->type == USB_DIR_IN)
  2019. {
  2020. *(FAR uint8_t *)ctrlreq->buf = priv->config;
  2021. ret = 1;
  2022. }
  2023. }
  2024. break;
  2025. default:
  2026. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
  2027. break;
  2028. }
  2029. }
  2030. break;
  2031. /* Class requests */
  2032. case USB_REQ_TYPE_CLASS:
  2033. {
  2034. if ((ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE)
  2035. {
  2036. if (ctrl->req == RNDIS_SEND_ENCAPSULATED_COMMAND)
  2037. {
  2038. ret = rndis_handle_control_message(priv, dataout, outlen);
  2039. }
  2040. else if (ctrl->req == RNDIS_GET_ENCAPSULATED_RESPONSE)
  2041. {
  2042. if (!priv->ctrlreq_has_encap_response)
  2043. {
  2044. ret = 1;
  2045. ctrlreq->buf[0] = 0;
  2046. }
  2047. else
  2048. {
  2049. /* There is data prepared in the ctrlreq buffer.
  2050. * Just assign the length.
  2051. */
  2052. FAR struct rndis_response_header *hdr =
  2053. (struct rndis_response_header *)ctrlreq->buf;
  2054. ret = hdr->msglen;
  2055. }
  2056. }
  2057. }
  2058. }
  2059. break;
  2060. default:
  2061. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDTYPE), ctrl->type);
  2062. break;
  2063. }
  2064. /* Respond to the setup command if data was returned. On an error return
  2065. * value (ret < 0), the USB driver will stall.
  2066. */
  2067. if (ret >= 0)
  2068. {
  2069. ctrlreq->len = min(len, ret);
  2070. ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
  2071. ret = EP_SUBMIT(dev->ep0, ctrlreq);
  2072. if (ret < 0)
  2073. {
  2074. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPRESPQ), (uint16_t)-ret);
  2075. ctrlreq->result = OK;
  2076. usbclass_ep0incomplete(dev->ep0, ctrlreq);
  2077. }
  2078. }
  2079. return ret;
  2080. }
  2081. /****************************************************************************
  2082. * Name: usbclass_disconnect
  2083. *
  2084. * Description:
  2085. * Invoked after all transfers have been stopped, when the host is
  2086. * disconnected. This function is probably called from the context of an
  2087. * interrupt handler.
  2088. *
  2089. ****************************************************************************/
  2090. static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
  2091. FAR struct usbdev_s *dev)
  2092. {
  2093. FAR struct rndis_dev_s *priv;
  2094. irqstate_t flags;
  2095. usbtrace(TRACE_CLASSDISCONNECT, 0);
  2096. #ifdef CONFIG_DEBUG_FEATURES
  2097. if (!driver || !dev || !dev->ep0)
  2098. {
  2099. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
  2100. return;
  2101. }
  2102. #endif
  2103. /* Extract reference to private data */
  2104. priv = ((FAR struct rndis_driver_s *)driver)->dev;
  2105. #ifdef CONFIG_DEBUG_FEATURES
  2106. if (!priv)
  2107. {
  2108. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
  2109. return;
  2110. }
  2111. #endif
  2112. /* Inform the "upper half" network driver that we have lost the USB
  2113. * connection.
  2114. */
  2115. priv->netdev.d_ifdown(&priv->netdev);
  2116. flags = enter_critical_section();
  2117. /* Reset the configuration */
  2118. usbclass_resetconfig(priv);
  2119. leave_critical_section(flags);
  2120. /* Perform the soft connect function so that we will we can be
  2121. * re-enumerated.
  2122. */
  2123. DEV_CONNECT(dev);
  2124. }
  2125. /****************************************************************************
  2126. * Name: usbclass_resetconfig
  2127. *
  2128. * Description:
  2129. * Mark the device as not configured and disable all endpoints.
  2130. *
  2131. ****************************************************************************/
  2132. static void usbclass_resetconfig(FAR struct rndis_dev_s *priv)
  2133. {
  2134. /* Are we configured? */
  2135. if (priv->config != RNDIS_CONFIGIDNONE)
  2136. {
  2137. /* Yes.. but not anymore */
  2138. priv->config = RNDIS_CONFIGIDNONE;
  2139. priv->netdev.d_ifdown(&priv->netdev);
  2140. /* Disable endpoints. This should force completion of all pending
  2141. * transfers.
  2142. */
  2143. EP_DISABLE(priv->epintin);
  2144. EP_DISABLE(priv->epbulkin);
  2145. EP_DISABLE(priv->epbulkout);
  2146. }
  2147. }
  2148. /****************************************************************************
  2149. * Name: usbclass_setconfig
  2150. *
  2151. * Description:
  2152. * Set the device configuration by allocating and configuring endpoints and
  2153. * by allocating and queue read and write requests.
  2154. *
  2155. ****************************************************************************/
  2156. static int usbclass_setconfig(FAR struct rndis_dev_s *priv, uint8_t config)
  2157. {
  2158. struct usb_epdesc_s epdesc;
  2159. bool hispeed = false;
  2160. int ret = 0;
  2161. #ifdef CONFIG_DEBUG_FEATURES
  2162. if (priv == NULL)
  2163. {
  2164. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
  2165. return -EIO;
  2166. }
  2167. #endif
  2168. #ifdef CONFIG_USBDEV_DUALSPEED
  2169. hispeed = (priv->usbdev->speed == USB_SPEED_HIGH);
  2170. #endif
  2171. if (config == priv->config)
  2172. {
  2173. /* Already configured -- Do nothing */
  2174. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALREADYCONFIGURED), 0);
  2175. return 0;
  2176. }
  2177. /* Discard the previous configuration data */
  2178. usbclass_resetconfig(priv);
  2179. /* Was this a request to simply discard the current configuration? */
  2180. if (config == RNDIS_CONFIGIDNONE)
  2181. {
  2182. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGNONE), 0);
  2183. return 0;
  2184. }
  2185. /* We only accept one configuration */
  2186. if (config != RNDIS_CONFIGID)
  2187. {
  2188. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGIDBAD), 0);
  2189. return -EINVAL;
  2190. }
  2191. /* Configure the IN interrupt endpoint */
  2192. usbclass_copy_epdesc(RNDIS_EP_INTIN_IDX, &epdesc, &priv->devinfo, hispeed);
  2193. ret = EP_CONFIGURE(priv->epintin, &epdesc, false);
  2194. if (ret < 0)
  2195. {
  2196. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINCONFIGFAIL), 0);
  2197. goto errout;
  2198. }
  2199. priv->epintin->priv = priv;
  2200. /* Configure the IN bulk endpoint */
  2201. usbclass_copy_epdesc(RNDIS_EP_BULKIN_IDX, &epdesc, &priv->devinfo, hispeed);
  2202. ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false);
  2203. if (ret < 0)
  2204. {
  2205. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINCONFIGFAIL), 0);
  2206. goto errout;
  2207. }
  2208. priv->epbulkin->priv = priv;
  2209. /* Configure the OUT bulk endpoint */
  2210. usbclass_copy_epdesc(RNDIS_EP_BULKOUT_IDX, &epdesc, &priv->devinfo, hispeed);
  2211. ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true);
  2212. if (ret < 0)
  2213. {
  2214. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTCONFIGFAIL), 0);
  2215. goto errout;
  2216. }
  2217. priv->epbulkout->priv = priv;
  2218. /* Queue read requests in the bulk OUT endpoint */
  2219. priv->rdreq->callback = rndis_rdcomplete;
  2220. ret = rndis_submit_rdreq(priv);
  2221. if (ret != OK)
  2222. {
  2223. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-ret);
  2224. goto errout;
  2225. }
  2226. /* We are successfully configured */
  2227. priv->config = config;
  2228. if (priv->netdev.d_ifup(&priv->netdev) == OK)
  2229. {
  2230. priv->netdev.d_flags |= IFF_UP;
  2231. }
  2232. return OK;
  2233. errout:
  2234. usbclass_resetconfig(priv);
  2235. return ret;
  2236. }
  2237. /****************************************************************************
  2238. * Name: usbclass_classobject
  2239. *
  2240. * Description:
  2241. * Allocate memory for the RNDIS driver class object
  2242. *
  2243. * Returned Value:
  2244. * 0 on success, negative error code on failure.
  2245. *
  2246. ****************************************************************************/
  2247. static int usbclass_classobject(int minor,
  2248. FAR struct usbdev_devinfo_s *devinfo,
  2249. FAR struct usbdevclass_driver_s **classdev)
  2250. {
  2251. FAR struct rndis_alloc_s *alloc;
  2252. FAR struct rndis_dev_s *priv;
  2253. FAR struct rndis_driver_s *drvr;
  2254. int ret;
  2255. /* Allocate the structures needed */
  2256. alloc = (FAR struct rndis_alloc_s *)kmm_zalloc(sizeof(struct rndis_alloc_s));
  2257. if (!alloc)
  2258. {
  2259. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0);
  2260. return -ENOMEM;
  2261. }
  2262. /* Convenience pointers into the allocated blob */
  2263. priv = &alloc->dev;
  2264. drvr = &alloc->drvr;
  2265. *classdev = &drvr->drvr;
  2266. #ifdef CONFIG_RNDIS_COMPOSITE
  2267. priv->devinfo = *devinfo;
  2268. #else
  2269. priv->devinfo.epno[RNDIS_EP_INTIN_IDX] = USB_EPNO(RNDIS_EPINTIN_ADDR);
  2270. priv->devinfo.epno[RNDIS_EP_BULKIN_IDX] = USB_EPNO(RNDIS_EPBULKIN_ADDR);
  2271. priv->devinfo.epno[RNDIS_EP_BULKOUT_IDX] = USB_EPNO(RNDIS_EPBULKOUT_ADDR);
  2272. #endif
  2273. /* Initialize the USB ethernet driver structure */
  2274. sq_init(&priv->reqlist);
  2275. memcpy(priv->host_mac_address, g_rndis_default_mac_addr, 6);
  2276. priv->txpoll = wd_create();
  2277. priv->netdev.d_private = priv;
  2278. priv->netdev.d_ifup = &rndis_ifup;
  2279. priv->netdev.d_ifdown = &rndis_ifdown;
  2280. priv->netdev.d_txavail = &rndis_txavail;
  2281. /* MAC address filtering is purposefully left out of this driver. Since
  2282. * in the RNDIS USB scenario there are only two devices in the network
  2283. * (host and us), there shouldn't be any packets received that don't
  2284. * belong to us.
  2285. */
  2286. /* Initialize the USB class driver structure */
  2287. drvr->drvr.speed = USB_SPEED_FULL;
  2288. drvr->drvr.ops = &g_driverops;
  2289. drvr->dev = priv;
  2290. ret = netdev_register(&priv->netdev, NET_LL_ETHERNET);
  2291. if (ret)
  2292. {
  2293. uerr("Failed to register net device");
  2294. return ret;
  2295. }
  2296. drvr->dev->registered = true;
  2297. return OK;
  2298. }
  2299. static void usbclass_uninitialize(FAR struct usbdevclass_driver_s *classdev)
  2300. {
  2301. FAR struct rndis_driver_s *drvr = (FAR struct rndis_driver_s *)classdev;
  2302. FAR struct rndis_alloc_s *alloc = (FAR struct rndis_alloc_s *)drvr->dev;
  2303. if (drvr->dev->registered)
  2304. {
  2305. netdev_unregister(&drvr->dev->netdev);
  2306. drvr->dev->registered = false;
  2307. }
  2308. else
  2309. {
  2310. kmm_free(alloc);
  2311. }
  2312. }
  2313. /****************************************************************************
  2314. * Public Functions
  2315. ****************************************************************************/
  2316. /****************************************************************************
  2317. * Name: usbdev_rndis_initialize
  2318. *
  2319. * Description:
  2320. * Initialize the RNDIS USB device driver.
  2321. *
  2322. * Input Parameters:
  2323. * mac_address: pointer to an array of six octets which is the MAC address
  2324. * of the host side of the interface. May be NULL to use the
  2325. * default MAC address.
  2326. *
  2327. * Returned Value:
  2328. * 0 on success, -errno on failure
  2329. *
  2330. ****************************************************************************/
  2331. #ifndef CONFIG_RNDIS_COMPOSITE
  2332. int usbdev_rndis_initialize(FAR const uint8_t *mac_address)
  2333. {
  2334. int ret;
  2335. FAR struct usbdevclass_driver_s *classdev;
  2336. FAR struct rndis_driver_s *drvr;
  2337. ret = usbclass_classobject(0, NULL, &classdev);
  2338. if (ret)
  2339. {
  2340. nerr("usbclass_classobject failed: %d\n", ret);
  2341. return ret;
  2342. }
  2343. drvr = (FAR struct rndis_driver_s *)classdev;
  2344. if (mac_address)
  2345. {
  2346. memcpy(drvr->dev->host_mac_address, mac_address, 6);
  2347. }
  2348. ret = usbdev_register(&drvr->drvr);
  2349. if (ret)
  2350. {
  2351. nerr("usbdev_register failed: %d\n", ret);
  2352. usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_DEVREGISTER), (uint16_t)-ret);
  2353. usbclass_uninitialize(classdev);
  2354. return ret;
  2355. }
  2356. return OK;
  2357. }
  2358. #endif
  2359. /****************************************************************************
  2360. * Name: usbdev_rndis_set_host_mac_addr
  2361. *
  2362. * Description:
  2363. * Set host MAC address. Mainly for use with composite devices where
  2364. * the MAC cannot be given directly to usbdev_rndis_initialize().
  2365. *
  2366. * Input Parameters:
  2367. * netdev: pointer to the network interface. Can be obtained from
  2368. * e.g. netdev_findbyname().
  2369. *
  2370. * mac_address: pointer to an array of six octets which is the MAC address
  2371. * of the host side of the interface. May be NULL to use the
  2372. * default MAC address.
  2373. *
  2374. * Returned Value:
  2375. * 0 on success, -errno on failure
  2376. *
  2377. ****************************************************************************/
  2378. int usbdev_rndis_set_host_mac_addr(FAR struct net_driver_s *netdev,
  2379. FAR const uint8_t *mac_address)
  2380. {
  2381. FAR struct rndis_dev_s *dev = (FAR struct rndis_dev_s *)netdev;
  2382. if (mac_address)
  2383. {
  2384. memcpy(dev->host_mac_address, mac_address, 6);
  2385. }
  2386. else
  2387. {
  2388. memcpy(dev->host_mac_address, g_rndis_default_mac_addr, 6);
  2389. }
  2390. return OK;
  2391. }
  2392. /****************************************************************************
  2393. * Name: usbdev_rndis_get_composite_devdesc
  2394. *
  2395. * Description:
  2396. * Helper function to fill in some constants into the composite
  2397. * configuration struct.
  2398. *
  2399. * Input Parameters:
  2400. * dev - Pointer to the configuration struct we should fill
  2401. *
  2402. * Returned Value:
  2403. * None
  2404. *
  2405. ****************************************************************************/
  2406. #ifdef CONFIG_RNDIS_COMPOSITE
  2407. void usbdev_rndis_get_composite_devdesc(struct composite_devdesc_s *dev)
  2408. {
  2409. memset(dev, 0, sizeof(struct composite_devdesc_s));
  2410. dev->mkconfdesc = usbclass_mkcfgdesc;
  2411. dev->mkstrdesc = usbclass_mkstrdesc;
  2412. dev->classobject = usbclass_classobject;
  2413. dev->uninitialize = usbclass_uninitialize;
  2414. dev->nconfigs = RNDIS_NCONFIGS;
  2415. dev->configid = RNDIS_CONFIGID;
  2416. dev->cfgdescsize = sizeof(g_rndis_cfgdesc);
  2417. dev->devinfo.ninterfaces = RNDIS_NINTERFACES;
  2418. dev->devinfo.nstrings = 0;
  2419. dev->devinfo.nendpoints = RNDIS_NUM_EPS;
  2420. /* Default endpoint indexes, board-specific logic can override these */
  2421. dev->devinfo.epno[RNDIS_EP_INTIN_IDX] = USB_EPNO(RNDIS_EPINTIN_ADDR);
  2422. dev->devinfo.epno[RNDIS_EP_BULKIN_IDX] = USB_EPNO(RNDIS_EPBULKIN_ADDR);
  2423. dev->devinfo.epno[RNDIS_EP_BULKOUT_IDX] = USB_EPNO(RNDIS_EPBULKOUT_ADDR);
  2424. }
  2425. #endif