rndis.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  1. /*
  2. * RNDIS MSG parser
  3. *
  4. * Authors: Benedikt Spranger, Pengutronix
  5. * Robert Schwebel, Pengutronix
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * version 2, as published by the Free Software Foundation.
  10. *
  11. * This software was originally developed in conformance with
  12. * Microsoft's Remote NDIS Specification License Agreement.
  13. *
  14. * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
  15. * Fixed message length bug in init_response
  16. *
  17. * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
  18. * Fixed rndis_rm_hdr length bug.
  19. *
  20. * Copyright (C) 2004 by David Brownell
  21. * updates to merge with Linux 2.6, better match RNDIS spec
  22. */
  23. #include <common.h>
  24. #include <net.h>
  25. #include <malloc.h>
  26. #include <linux/types.h>
  27. #include <linux/list.h>
  28. #include <linux/netdevice.h>
  29. #include <asm/byteorder.h>
  30. #include <asm/unaligned.h>
  31. #include <asm/errno.h>
  32. #undef RNDIS_PM
  33. #undef RNDIS_WAKEUP
  34. #undef VERBOSE
  35. #include "rndis.h"
  36. #define ETH_ALEN 6 /* Octets in one ethernet addr */
  37. #define ETH_HLEN 14 /* Total octets in header. */
  38. #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
  39. #define ETH_DATA_LEN 1500 /* Max. octets in payload */
  40. #define ETH_FRAME_LEN PKTSIZE_ALIGN /* Max. octets in frame sans FCS */
  41. #define ETH_FCS_LEN 4 /* Octets in the FCS */
  42. #define ENOTSUPP 524 /* Operation is not supported */
  43. /*
  44. * The driver for your USB chip needs to support ep0 OUT to work with
  45. * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
  46. *
  47. * Windows hosts need an INF file like Documentation/usb/linux.inf
  48. * and will be happier if you provide the host_addr module parameter.
  49. */
  50. #define RNDIS_MAX_CONFIGS 1
  51. static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS];
  52. /* Driver Version */
  53. static const __le32 rndis_driver_version = __constant_cpu_to_le32(1);
  54. /* Function Prototypes */
  55. static rndis_resp_t *rndis_add_response(int configNr, u32 length);
  56. /* supported OIDs */
  57. static const u32 oid_supported_list[] = {
  58. /* the general stuff */
  59. OID_GEN_SUPPORTED_LIST,
  60. OID_GEN_HARDWARE_STATUS,
  61. OID_GEN_MEDIA_SUPPORTED,
  62. OID_GEN_MEDIA_IN_USE,
  63. OID_GEN_MAXIMUM_FRAME_SIZE,
  64. OID_GEN_LINK_SPEED,
  65. OID_GEN_TRANSMIT_BLOCK_SIZE,
  66. OID_GEN_RECEIVE_BLOCK_SIZE,
  67. OID_GEN_VENDOR_ID,
  68. OID_GEN_VENDOR_DESCRIPTION,
  69. OID_GEN_VENDOR_DRIVER_VERSION,
  70. OID_GEN_CURRENT_PACKET_FILTER,
  71. OID_GEN_MAXIMUM_TOTAL_SIZE,
  72. OID_GEN_MEDIA_CONNECT_STATUS,
  73. OID_GEN_PHYSICAL_MEDIUM,
  74. #if 0
  75. OID_GEN_RNDIS_CONFIG_PARAMETER,
  76. #endif
  77. /* the statistical stuff */
  78. OID_GEN_XMIT_OK,
  79. OID_GEN_RCV_OK,
  80. OID_GEN_XMIT_ERROR,
  81. OID_GEN_RCV_ERROR,
  82. OID_GEN_RCV_NO_BUFFER,
  83. #ifdef RNDIS_OPTIONAL_STATS
  84. OID_GEN_DIRECTED_BYTES_XMIT,
  85. OID_GEN_DIRECTED_FRAMES_XMIT,
  86. OID_GEN_MULTICAST_BYTES_XMIT,
  87. OID_GEN_MULTICAST_FRAMES_XMIT,
  88. OID_GEN_BROADCAST_BYTES_XMIT,
  89. OID_GEN_BROADCAST_FRAMES_XMIT,
  90. OID_GEN_DIRECTED_BYTES_RCV,
  91. OID_GEN_DIRECTED_FRAMES_RCV,
  92. OID_GEN_MULTICAST_BYTES_RCV,
  93. OID_GEN_MULTICAST_FRAMES_RCV,
  94. OID_GEN_BROADCAST_BYTES_RCV,
  95. OID_GEN_BROADCAST_FRAMES_RCV,
  96. OID_GEN_RCV_CRC_ERROR,
  97. OID_GEN_TRANSMIT_QUEUE_LENGTH,
  98. #endif /* RNDIS_OPTIONAL_STATS */
  99. /* mandatory 802.3 */
  100. /* the general stuff */
  101. OID_802_3_PERMANENT_ADDRESS,
  102. OID_802_3_CURRENT_ADDRESS,
  103. OID_802_3_MULTICAST_LIST,
  104. OID_802_3_MAC_OPTIONS,
  105. OID_802_3_MAXIMUM_LIST_SIZE,
  106. /* the statistical stuff */
  107. OID_802_3_RCV_ERROR_ALIGNMENT,
  108. OID_802_3_XMIT_ONE_COLLISION,
  109. OID_802_3_XMIT_MORE_COLLISIONS,
  110. #ifdef RNDIS_OPTIONAL_STATS
  111. OID_802_3_XMIT_DEFERRED,
  112. OID_802_3_XMIT_MAX_COLLISIONS,
  113. OID_802_3_RCV_OVERRUN,
  114. OID_802_3_XMIT_UNDERRUN,
  115. OID_802_3_XMIT_HEARTBEAT_FAILURE,
  116. OID_802_3_XMIT_TIMES_CRS_LOST,
  117. OID_802_3_XMIT_LATE_COLLISIONS,
  118. #endif /* RNDIS_OPTIONAL_STATS */
  119. #ifdef RNDIS_PM
  120. /* PM and wakeup are mandatory for USB: */
  121. /* power management */
  122. OID_PNP_CAPABILITIES,
  123. OID_PNP_QUERY_POWER,
  124. OID_PNP_SET_POWER,
  125. #ifdef RNDIS_WAKEUP
  126. /* wake up host */
  127. OID_PNP_ENABLE_WAKE_UP,
  128. OID_PNP_ADD_WAKE_UP_PATTERN,
  129. OID_PNP_REMOVE_WAKE_UP_PATTERN,
  130. #endif /* RNDIS_WAKEUP */
  131. #endif /* RNDIS_PM */
  132. };
  133. /* NDIS Functions */
  134. static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf,
  135. unsigned buf_len, rndis_resp_t *r)
  136. {
  137. int retval = -ENOTSUPP;
  138. u32 length = 4; /* usually */
  139. __le32 *outbuf;
  140. int i, count;
  141. rndis_query_cmplt_type *resp;
  142. rndis_params *params;
  143. if (!r)
  144. return -ENOMEM;
  145. resp = (rndis_query_cmplt_type *) r->buf;
  146. if (!resp)
  147. return -ENOMEM;
  148. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  149. if (buf_len) {
  150. debug("query OID %08x value, len %d:\n", OID, buf_len);
  151. for (i = 0; i < buf_len; i += 16) {
  152. debug("%03d: %08x %08x %08x %08x\n", i,
  153. get_unaligned_le32(&buf[i]),
  154. get_unaligned_le32(&buf[i + 4]),
  155. get_unaligned_le32(&buf[i + 8]),
  156. get_unaligned_le32(&buf[i + 12]));
  157. }
  158. }
  159. #endif
  160. /* response goes here, right after the header */
  161. outbuf = (__le32 *) &resp[1];
  162. resp->InformationBufferOffset = __constant_cpu_to_le32(16);
  163. params = &rndis_per_dev_params[configNr];
  164. switch (OID) {
  165. /* general oids (table 4-1) */
  166. /* mandatory */
  167. case OID_GEN_SUPPORTED_LIST:
  168. debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
  169. length = sizeof(oid_supported_list);
  170. count = length / sizeof(u32);
  171. for (i = 0; i < count; i++)
  172. outbuf[i] = cpu_to_le32(oid_supported_list[i]);
  173. retval = 0;
  174. break;
  175. /* mandatory */
  176. case OID_GEN_HARDWARE_STATUS:
  177. debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
  178. /*
  179. * Bogus question!
  180. * Hardware must be ready to receive high level protocols.
  181. * BTW:
  182. * reddite ergo quae sunt Caesaris Caesari
  183. * et quae sunt Dei Deo!
  184. */
  185. *outbuf = __constant_cpu_to_le32(0);
  186. retval = 0;
  187. break;
  188. /* mandatory */
  189. case OID_GEN_MEDIA_SUPPORTED:
  190. debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
  191. *outbuf = cpu_to_le32(params->medium);
  192. retval = 0;
  193. break;
  194. /* mandatory */
  195. case OID_GEN_MEDIA_IN_USE:
  196. debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
  197. /* one medium, one transport... (maybe you do it better) */
  198. *outbuf = cpu_to_le32(params->medium);
  199. retval = 0;
  200. break;
  201. /* mandatory */
  202. case OID_GEN_MAXIMUM_FRAME_SIZE:
  203. debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
  204. if (params->dev) {
  205. *outbuf = cpu_to_le32(params->mtu);
  206. retval = 0;
  207. }
  208. break;
  209. /* mandatory */
  210. case OID_GEN_LINK_SPEED:
  211. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  212. debug("%s: OID_GEN_LINK_SPEED\n", __func__);
  213. #endif
  214. if (params->media_state == NDIS_MEDIA_STATE_DISCONNECTED)
  215. *outbuf = __constant_cpu_to_le32(0);
  216. else
  217. *outbuf = cpu_to_le32(params->speed);
  218. retval = 0;
  219. break;
  220. /* mandatory */
  221. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  222. debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
  223. if (params->dev) {
  224. *outbuf = cpu_to_le32(params->mtu);
  225. retval = 0;
  226. }
  227. break;
  228. /* mandatory */
  229. case OID_GEN_RECEIVE_BLOCK_SIZE:
  230. debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
  231. if (params->dev) {
  232. *outbuf = cpu_to_le32(params->mtu);
  233. retval = 0;
  234. }
  235. break;
  236. /* mandatory */
  237. case OID_GEN_VENDOR_ID:
  238. debug("%s: OID_GEN_VENDOR_ID\n", __func__);
  239. *outbuf = cpu_to_le32(params->vendorID);
  240. retval = 0;
  241. break;
  242. /* mandatory */
  243. case OID_GEN_VENDOR_DESCRIPTION:
  244. debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
  245. length = strlen(params->vendorDescr);
  246. memcpy(outbuf, params->vendorDescr, length);
  247. retval = 0;
  248. break;
  249. case OID_GEN_VENDOR_DRIVER_VERSION:
  250. debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
  251. /* Created as LE */
  252. *outbuf = rndis_driver_version;
  253. retval = 0;
  254. break;
  255. /* mandatory */
  256. case OID_GEN_CURRENT_PACKET_FILTER:
  257. debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
  258. *outbuf = cpu_to_le32(*params->filter);
  259. retval = 0;
  260. break;
  261. /* mandatory */
  262. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  263. debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
  264. *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
  265. retval = 0;
  266. break;
  267. /* mandatory */
  268. case OID_GEN_MEDIA_CONNECT_STATUS:
  269. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  270. debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
  271. #endif
  272. *outbuf = cpu_to_le32(params->media_state);
  273. retval = 0;
  274. break;
  275. case OID_GEN_PHYSICAL_MEDIUM:
  276. debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
  277. *outbuf = __constant_cpu_to_le32(0);
  278. retval = 0;
  279. break;
  280. /*
  281. * The RNDIS specification is incomplete/wrong. Some versions
  282. * of MS-Windows expect OIDs that aren't specified there. Other
  283. * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
  284. */
  285. case OID_GEN_MAC_OPTIONS: /* from WinME */
  286. debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
  287. *outbuf = __constant_cpu_to_le32(
  288. NDIS_MAC_OPTION_RECEIVE_SERIALIZED
  289. | NDIS_MAC_OPTION_FULL_DUPLEX);
  290. retval = 0;
  291. break;
  292. /* statistics OIDs (table 4-2) */
  293. /* mandatory */
  294. case OID_GEN_XMIT_OK:
  295. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  296. debug("%s: OID_GEN_XMIT_OK\n", __func__);
  297. #endif
  298. if (params->stats) {
  299. *outbuf = cpu_to_le32(
  300. params->stats->tx_packets -
  301. params->stats->tx_errors -
  302. params->stats->tx_dropped);
  303. retval = 0;
  304. }
  305. break;
  306. /* mandatory */
  307. case OID_GEN_RCV_OK:
  308. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  309. debug("%s: OID_GEN_RCV_OK\n", __func__);
  310. #endif
  311. if (params->stats) {
  312. *outbuf = cpu_to_le32(
  313. params->stats->rx_packets -
  314. params->stats->rx_errors -
  315. params->stats->rx_dropped);
  316. retval = 0;
  317. }
  318. break;
  319. /* mandatory */
  320. case OID_GEN_XMIT_ERROR:
  321. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  322. debug("%s: OID_GEN_XMIT_ERROR\n", __func__);
  323. #endif
  324. if (params->stats) {
  325. *outbuf = cpu_to_le32(params->stats->tx_errors);
  326. retval = 0;
  327. }
  328. break;
  329. /* mandatory */
  330. case OID_GEN_RCV_ERROR:
  331. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  332. debug("%s: OID_GEN_RCV_ERROR\n", __func__);
  333. #endif
  334. if (params->stats) {
  335. *outbuf = cpu_to_le32(params->stats->rx_errors);
  336. retval = 0;
  337. }
  338. break;
  339. /* mandatory */
  340. case OID_GEN_RCV_NO_BUFFER:
  341. debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
  342. if (params->stats) {
  343. *outbuf = cpu_to_le32(params->stats->rx_dropped);
  344. retval = 0;
  345. }
  346. break;
  347. #ifdef RNDIS_OPTIONAL_STATS
  348. case OID_GEN_DIRECTED_BYTES_XMIT:
  349. debug("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__);
  350. /*
  351. * Aunt Tilly's size of shoes
  352. * minus antarctica count of penguins
  353. * divided by weight of Alpha Centauri
  354. */
  355. if (params->stats) {
  356. *outbuf = cpu_to_le32(
  357. (params->stats->tx_packets -
  358. params->stats->tx_errors -
  359. params->stats->tx_dropped)
  360. * 123);
  361. retval = 0;
  362. }
  363. break;
  364. case OID_GEN_DIRECTED_FRAMES_XMIT:
  365. debug("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__);
  366. /* dito */
  367. if (params->stats) {
  368. *outbuf = cpu_to_le32(
  369. (params->stats->tx_packets -
  370. params->stats->tx_errors -
  371. params->stats->tx_dropped)
  372. / 123);
  373. retval = 0;
  374. }
  375. break;
  376. case OID_GEN_MULTICAST_BYTES_XMIT:
  377. debug("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__);
  378. if (params->stats) {
  379. *outbuf = cpu_to_le32(params->stats->multicast * 1234);
  380. retval = 0;
  381. }
  382. break;
  383. case OID_GEN_MULTICAST_FRAMES_XMIT:
  384. debug("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__);
  385. if (params->stats) {
  386. *outbuf = cpu_to_le32(params->stats->multicast);
  387. retval = 0;
  388. }
  389. break;
  390. case OID_GEN_BROADCAST_BYTES_XMIT:
  391. debug("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__);
  392. if (params->stats) {
  393. *outbuf = cpu_to_le32(params->stats->tx_packets/42*255);
  394. retval = 0;
  395. }
  396. break;
  397. case OID_GEN_BROADCAST_FRAMES_XMIT:
  398. debug("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__);
  399. if (params->stats) {
  400. *outbuf = cpu_to_le32(params->stats->tx_packets / 42);
  401. retval = 0;
  402. }
  403. break;
  404. case OID_GEN_DIRECTED_BYTES_RCV:
  405. debug("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__);
  406. *outbuf = __constant_cpu_to_le32(0);
  407. retval = 0;
  408. break;
  409. case OID_GEN_DIRECTED_FRAMES_RCV:
  410. debug("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__);
  411. *outbuf = __constant_cpu_to_le32(0);
  412. retval = 0;
  413. break;
  414. case OID_GEN_MULTICAST_BYTES_RCV:
  415. debug("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__);
  416. if (params->stats) {
  417. *outbuf = cpu_to_le32(params->stats->multicast * 1111);
  418. retval = 0;
  419. }
  420. break;
  421. case OID_GEN_MULTICAST_FRAMES_RCV:
  422. debug("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__);
  423. if (params->stats) {
  424. *outbuf = cpu_to_le32(params->stats->multicast);
  425. retval = 0;
  426. }
  427. break;
  428. case OID_GEN_BROADCAST_BYTES_RCV:
  429. debug("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__);
  430. if (params->stats) {
  431. *outbuf = cpu_to_le32(params->stats->rx_packets/42*255);
  432. retval = 0;
  433. }
  434. break;
  435. case OID_GEN_BROADCAST_FRAMES_RCV:
  436. debug("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__);
  437. if (params->stats) {
  438. *outbuf = cpu_to_le32(params->stats->rx_packets / 42);
  439. retval = 0;
  440. }
  441. break;
  442. case OID_GEN_RCV_CRC_ERROR:
  443. debug("%s: OID_GEN_RCV_CRC_ERROR\n", __func__);
  444. if (params->stats) {
  445. *outbuf = cpu_to_le32(params->stats->rx_crc_errors);
  446. retval = 0;
  447. }
  448. break;
  449. case OID_GEN_TRANSMIT_QUEUE_LENGTH:
  450. debug("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__);
  451. *outbuf = __constant_cpu_to_le32(0);
  452. retval = 0;
  453. break;
  454. #endif /* RNDIS_OPTIONAL_STATS */
  455. /* ieee802.3 OIDs (table 4-3) */
  456. /* mandatory */
  457. case OID_802_3_PERMANENT_ADDRESS:
  458. debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
  459. if (params->dev) {
  460. length = ETH_ALEN;
  461. memcpy(outbuf, params->host_mac, length);
  462. retval = 0;
  463. }
  464. break;
  465. /* mandatory */
  466. case OID_802_3_CURRENT_ADDRESS:
  467. debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
  468. if (params->dev) {
  469. length = ETH_ALEN;
  470. memcpy(outbuf, params->host_mac, length);
  471. retval = 0;
  472. }
  473. break;
  474. /* mandatory */
  475. case OID_802_3_MULTICAST_LIST:
  476. debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
  477. /* Multicast base address only */
  478. *outbuf = __constant_cpu_to_le32(0xE0000000);
  479. retval = 0;
  480. break;
  481. /* mandatory */
  482. case OID_802_3_MAXIMUM_LIST_SIZE:
  483. debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
  484. /* Multicast base address only */
  485. *outbuf = __constant_cpu_to_le32(1);
  486. retval = 0;
  487. break;
  488. case OID_802_3_MAC_OPTIONS:
  489. debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
  490. break;
  491. /* ieee802.3 statistics OIDs (table 4-4) */
  492. /* mandatory */
  493. case OID_802_3_RCV_ERROR_ALIGNMENT:
  494. debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
  495. if (params->stats) {
  496. *outbuf = cpu_to_le32(params->stats->rx_frame_errors);
  497. retval = 0;
  498. }
  499. break;
  500. /* mandatory */
  501. case OID_802_3_XMIT_ONE_COLLISION:
  502. debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
  503. *outbuf = __constant_cpu_to_le32(0);
  504. retval = 0;
  505. break;
  506. /* mandatory */
  507. case OID_802_3_XMIT_MORE_COLLISIONS:
  508. debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
  509. *outbuf = __constant_cpu_to_le32(0);
  510. retval = 0;
  511. break;
  512. #ifdef RNDIS_OPTIONAL_STATS
  513. case OID_802_3_XMIT_DEFERRED:
  514. debug("%s: OID_802_3_XMIT_DEFERRED\n", __func__);
  515. /* TODO */
  516. break;
  517. case OID_802_3_XMIT_MAX_COLLISIONS:
  518. debug("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__);
  519. /* TODO */
  520. break;
  521. case OID_802_3_RCV_OVERRUN:
  522. debug("%s: OID_802_3_RCV_OVERRUN\n", __func__);
  523. /* TODO */
  524. break;
  525. case OID_802_3_XMIT_UNDERRUN:
  526. debug("%s: OID_802_3_XMIT_UNDERRUN\n", __func__);
  527. /* TODO */
  528. break;
  529. case OID_802_3_XMIT_HEARTBEAT_FAILURE:
  530. debug("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__);
  531. /* TODO */
  532. break;
  533. case OID_802_3_XMIT_TIMES_CRS_LOST:
  534. debug("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__);
  535. /* TODO */
  536. break;
  537. case OID_802_3_XMIT_LATE_COLLISIONS:
  538. debug("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__);
  539. /* TODO */
  540. break;
  541. #endif /* RNDIS_OPTIONAL_STATS */
  542. #ifdef RNDIS_PM
  543. /* power management OIDs (table 4-5) */
  544. case OID_PNP_CAPABILITIES:
  545. debug("%s: OID_PNP_CAPABILITIES\n", __func__);
  546. /* for now, no wakeup capabilities */
  547. length = sizeof(struct NDIS_PNP_CAPABILITIES);
  548. memset(outbuf, 0, length);
  549. retval = 0;
  550. break;
  551. case OID_PNP_QUERY_POWER:
  552. debug("%s: OID_PNP_QUERY_POWER D%d\n", __func__,
  553. get_unaligned_le32(buf) - 1);
  554. /*
  555. * only suspend is a real power state, and
  556. * it can't be entered by OID_PNP_SET_POWER...
  557. */
  558. length = 0;
  559. retval = 0;
  560. break;
  561. #endif
  562. default:
  563. debug("%s: query unknown OID 0x%08X\n", __func__, OID);
  564. }
  565. if (retval < 0)
  566. length = 0;
  567. resp->InformationBufferLength = cpu_to_le32(length);
  568. r->length = length + sizeof *resp;
  569. resp->MessageLength = cpu_to_le32(r->length);
  570. return retval;
  571. }
  572. static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len,
  573. rndis_resp_t *r)
  574. {
  575. rndis_set_cmplt_type *resp;
  576. int retval = -ENOTSUPP;
  577. struct rndis_params *params;
  578. #if (defined(DEBUG) && defined(DEBUG_VERBOSE)) || defined(RNDIS_PM)
  579. int i;
  580. #endif
  581. if (!r)
  582. return -ENOMEM;
  583. resp = (rndis_set_cmplt_type *) r->buf;
  584. if (!resp)
  585. return -ENOMEM;
  586. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  587. if (buf_len) {
  588. debug("set OID %08x value, len %d:\n", OID, buf_len);
  589. for (i = 0; i < buf_len; i += 16) {
  590. debug("%03d: %08x %08x %08x %08x\n", i,
  591. get_unaligned_le32(&buf[i]),
  592. get_unaligned_le32(&buf[i + 4]),
  593. get_unaligned_le32(&buf[i + 8]),
  594. get_unaligned_le32(&buf[i + 12]));
  595. }
  596. }
  597. #endif
  598. params = &rndis_per_dev_params[configNr];
  599. switch (OID) {
  600. case OID_GEN_CURRENT_PACKET_FILTER:
  601. /*
  602. * these NDIS_PACKET_TYPE_* bitflags are shared with
  603. * cdc_filter; it's not RNDIS-specific
  604. * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
  605. * PROMISCUOUS, DIRECTED,
  606. * MULTICAST, ALL_MULTICAST, BROADCAST
  607. */
  608. *params->filter = (u16) get_unaligned_le32(buf);
  609. debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
  610. __func__, *params->filter);
  611. /*
  612. * this call has a significant side effect: it's
  613. * what makes the packet flow start and stop, like
  614. * activating the CDC Ethernet altsetting.
  615. */
  616. #ifdef RNDIS_PM
  617. update_linkstate:
  618. #endif
  619. retval = 0;
  620. if (*params->filter)
  621. params->state = RNDIS_DATA_INITIALIZED;
  622. else
  623. params->state = RNDIS_INITIALIZED;
  624. break;
  625. case OID_802_3_MULTICAST_LIST:
  626. /* I think we can ignore this */
  627. debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
  628. retval = 0;
  629. break;
  630. #if 0
  631. case OID_GEN_RNDIS_CONFIG_PARAMETER:
  632. {
  633. struct rndis_config_parameter *param;
  634. param = (struct rndis_config_parameter *) buf;
  635. debug("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
  636. __func__,
  637. min(cpu_to_le32(param->ParameterNameLength), 80),
  638. buf + param->ParameterNameOffset);
  639. retval = 0;
  640. }
  641. break;
  642. #endif
  643. #ifdef RNDIS_PM
  644. case OID_PNP_SET_POWER:
  645. /*
  646. * The only real power state is USB suspend, and RNDIS requests
  647. * can't enter it; this one isn't really about power. After
  648. * resuming, Windows forces a reset, and then SET_POWER D0.
  649. * FIXME ... then things go batty; Windows wedges itself.
  650. */
  651. i = get_unaligned_le32(buf);
  652. debug("%s: OID_PNP_SET_POWER D%d\n", __func__, i - 1);
  653. switch (i) {
  654. case NdisDeviceStateD0:
  655. *params->filter = params->saved_filter;
  656. goto update_linkstate;
  657. case NdisDeviceStateD3:
  658. case NdisDeviceStateD2:
  659. case NdisDeviceStateD1:
  660. params->saved_filter = *params->filter;
  661. retval = 0;
  662. break;
  663. }
  664. break;
  665. #ifdef RNDIS_WAKEUP
  666. /*
  667. * no wakeup support advertised, so wakeup OIDs always fail:
  668. * - OID_PNP_ENABLE_WAKE_UP
  669. * - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
  670. */
  671. #endif
  672. #endif /* RNDIS_PM */
  673. default:
  674. debug("%s: set unknown OID 0x%08X, size %d\n",
  675. __func__, OID, buf_len);
  676. }
  677. return retval;
  678. }
  679. /*
  680. * Response Functions
  681. */
  682. static int rndis_init_response(int configNr, rndis_init_msg_type *buf)
  683. {
  684. rndis_init_cmplt_type *resp;
  685. rndis_resp_t *r;
  686. if (!rndis_per_dev_params[configNr].dev)
  687. return -ENOTSUPP;
  688. r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type));
  689. if (!r)
  690. return -ENOMEM;
  691. resp = (rndis_init_cmplt_type *) r->buf;
  692. resp->MessageType = __constant_cpu_to_le32(
  693. REMOTE_NDIS_INITIALIZE_CMPLT);
  694. resp->MessageLength = __constant_cpu_to_le32(52);
  695. resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
  696. resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
  697. resp->MajorVersion = __constant_cpu_to_le32(RNDIS_MAJOR_VERSION);
  698. resp->MinorVersion = __constant_cpu_to_le32(RNDIS_MINOR_VERSION);
  699. resp->DeviceFlags = __constant_cpu_to_le32(RNDIS_DF_CONNECTIONLESS);
  700. resp->Medium = __constant_cpu_to_le32(RNDIS_MEDIUM_802_3);
  701. resp->MaxPacketsPerTransfer = __constant_cpu_to_le32(1);
  702. resp->MaxTransferSize = cpu_to_le32(
  703. rndis_per_dev_params[configNr].mtu
  704. + ETHER_HDR_SIZE
  705. + sizeof(struct rndis_packet_msg_type)
  706. + 22);
  707. resp->PacketAlignmentFactor = __constant_cpu_to_le32(0);
  708. resp->AFListOffset = __constant_cpu_to_le32(0);
  709. resp->AFListSize = __constant_cpu_to_le32(0);
  710. if (rndis_per_dev_params[configNr].ack)
  711. rndis_per_dev_params[configNr].ack(
  712. rndis_per_dev_params[configNr].dev);
  713. return 0;
  714. }
  715. static int rndis_query_response(int configNr, rndis_query_msg_type *buf)
  716. {
  717. rndis_query_cmplt_type *resp;
  718. rndis_resp_t *r;
  719. debug("%s: OID = %08X\n", __func__, get_unaligned_le32(&buf->OID));
  720. if (!rndis_per_dev_params[configNr].dev)
  721. return -ENOTSUPP;
  722. /*
  723. * we need more memory:
  724. * gen_ndis_query_resp expects enough space for
  725. * rndis_query_cmplt_type followed by data.
  726. * oid_supported_list is the largest data reply
  727. */
  728. r = rndis_add_response(configNr,
  729. sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type));
  730. if (!r)
  731. return -ENOMEM;
  732. resp = (rndis_query_cmplt_type *) r->buf;
  733. resp->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT);
  734. resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
  735. if (gen_ndis_query_resp(configNr, get_unaligned_le32(&buf->OID),
  736. get_unaligned_le32(&buf->InformationBufferOffset)
  737. + 8 + (u8 *) buf,
  738. get_unaligned_le32(&buf->InformationBufferLength),
  739. r)) {
  740. /* OID not supported */
  741. resp->Status = __constant_cpu_to_le32(
  742. RNDIS_STATUS_NOT_SUPPORTED);
  743. resp->MessageLength = __constant_cpu_to_le32(sizeof *resp);
  744. resp->InformationBufferLength = __constant_cpu_to_le32(0);
  745. resp->InformationBufferOffset = __constant_cpu_to_le32(0);
  746. } else
  747. resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
  748. if (rndis_per_dev_params[configNr].ack)
  749. rndis_per_dev_params[configNr].ack(
  750. rndis_per_dev_params[configNr].dev);
  751. return 0;
  752. }
  753. static int rndis_set_response(int configNr, rndis_set_msg_type *buf)
  754. {
  755. u32 BufLength, BufOffset;
  756. rndis_set_cmplt_type *resp;
  757. rndis_resp_t *r;
  758. r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type));
  759. if (!r)
  760. return -ENOMEM;
  761. resp = (rndis_set_cmplt_type *) r->buf;
  762. BufLength = get_unaligned_le32(&buf->InformationBufferLength);
  763. BufOffset = get_unaligned_le32(&buf->InformationBufferOffset);
  764. #ifdef VERBOSE
  765. debug("%s: Length: %d\n", __func__, BufLength);
  766. debug("%s: Offset: %d\n", __func__, BufOffset);
  767. debug("%s: InfoBuffer: ", __func__);
  768. for (i = 0; i < BufLength; i++)
  769. debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
  770. debug("\n");
  771. #endif
  772. resp->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_SET_CMPLT);
  773. resp->MessageLength = __constant_cpu_to_le32(16);
  774. resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
  775. if (gen_ndis_set_resp(configNr, get_unaligned_le32(&buf->OID),
  776. ((u8 *) buf) + 8 + BufOffset, BufLength, r))
  777. resp->Status = __constant_cpu_to_le32(
  778. RNDIS_STATUS_NOT_SUPPORTED);
  779. else
  780. resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
  781. if (rndis_per_dev_params[configNr].ack)
  782. rndis_per_dev_params[configNr].ack(
  783. rndis_per_dev_params[configNr].dev);
  784. return 0;
  785. }
  786. static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf)
  787. {
  788. rndis_reset_cmplt_type *resp;
  789. rndis_resp_t *r;
  790. r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type));
  791. if (!r)
  792. return -ENOMEM;
  793. resp = (rndis_reset_cmplt_type *) r->buf;
  794. resp->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_RESET_CMPLT);
  795. resp->MessageLength = __constant_cpu_to_le32(16);
  796. resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
  797. /* resent information */
  798. resp->AddressingReset = __constant_cpu_to_le32(1);
  799. if (rndis_per_dev_params[configNr].ack)
  800. rndis_per_dev_params[configNr].ack(
  801. rndis_per_dev_params[configNr].dev);
  802. return 0;
  803. }
  804. static int rndis_keepalive_response(int configNr,
  805. rndis_keepalive_msg_type *buf)
  806. {
  807. rndis_keepalive_cmplt_type *resp;
  808. rndis_resp_t *r;
  809. /* host "should" check only in RNDIS_DATA_INITIALIZED state */
  810. r = rndis_add_response(configNr, sizeof(rndis_keepalive_cmplt_type));
  811. if (!r)
  812. return -ENOMEM;
  813. resp = (rndis_keepalive_cmplt_type *) r->buf;
  814. resp->MessageType = __constant_cpu_to_le32(
  815. REMOTE_NDIS_KEEPALIVE_CMPLT);
  816. resp->MessageLength = __constant_cpu_to_le32(16);
  817. resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
  818. resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
  819. if (rndis_per_dev_params[configNr].ack)
  820. rndis_per_dev_params[configNr].ack(
  821. rndis_per_dev_params[configNr].dev);
  822. return 0;
  823. }
  824. /*
  825. * Device to Host Comunication
  826. */
  827. static int rndis_indicate_status_msg(int configNr, u32 status)
  828. {
  829. rndis_indicate_status_msg_type *resp;
  830. rndis_resp_t *r;
  831. if (rndis_per_dev_params[configNr].state == RNDIS_UNINITIALIZED)
  832. return -ENOTSUPP;
  833. r = rndis_add_response(configNr,
  834. sizeof(rndis_indicate_status_msg_type));
  835. if (!r)
  836. return -ENOMEM;
  837. resp = (rndis_indicate_status_msg_type *) r->buf;
  838. resp->MessageType = __constant_cpu_to_le32(
  839. REMOTE_NDIS_INDICATE_STATUS_MSG);
  840. resp->MessageLength = __constant_cpu_to_le32(20);
  841. resp->Status = cpu_to_le32(status);
  842. resp->StatusBufferLength = __constant_cpu_to_le32(0);
  843. resp->StatusBufferOffset = __constant_cpu_to_le32(0);
  844. if (rndis_per_dev_params[configNr].ack)
  845. rndis_per_dev_params[configNr].ack(
  846. rndis_per_dev_params[configNr].dev);
  847. return 0;
  848. }
  849. int rndis_signal_connect(int configNr)
  850. {
  851. rndis_per_dev_params[configNr].media_state
  852. = NDIS_MEDIA_STATE_CONNECTED;
  853. return rndis_indicate_status_msg(configNr,
  854. RNDIS_STATUS_MEDIA_CONNECT);
  855. }
  856. int rndis_signal_disconnect(int configNr)
  857. {
  858. rndis_per_dev_params[configNr].media_state
  859. = NDIS_MEDIA_STATE_DISCONNECTED;
  860. #ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT
  861. return rndis_indicate_status_msg(configNr,
  862. RNDIS_STATUS_MEDIA_DISCONNECT);
  863. #else
  864. return 0;
  865. #endif
  866. }
  867. void rndis_uninit(int configNr)
  868. {
  869. u8 *buf;
  870. u32 length;
  871. if (configNr >= RNDIS_MAX_CONFIGS)
  872. return;
  873. rndis_per_dev_params[configNr].used = 0;
  874. rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED;
  875. /* drain the response queue */
  876. while ((buf = rndis_get_next_response(configNr, &length)))
  877. rndis_free_response(configNr, buf);
  878. }
  879. void rndis_set_host_mac(int configNr, const u8 *addr)
  880. {
  881. rndis_per_dev_params[configNr].host_mac = addr;
  882. }
  883. enum rndis_state rndis_get_state(int configNr)
  884. {
  885. if (configNr >= RNDIS_MAX_CONFIGS || configNr < 0)
  886. return -ENOTSUPP;
  887. return rndis_per_dev_params[configNr].state;
  888. }
  889. /*
  890. * Message Parser
  891. */
  892. int rndis_msg_parser(u8 configNr, u8 *buf)
  893. {
  894. u32 MsgType, MsgLength;
  895. __le32 *tmp;
  896. struct rndis_params *params;
  897. debug("%s: configNr = %d, %p\n", __func__, configNr, buf);
  898. if (!buf)
  899. return -ENOMEM;
  900. tmp = (__le32 *) buf;
  901. MsgType = get_unaligned_le32(tmp++);
  902. MsgLength = get_unaligned_le32(tmp++);
  903. if (configNr >= RNDIS_MAX_CONFIGS)
  904. return -ENOTSUPP;
  905. params = &rndis_per_dev_params[configNr];
  906. /*
  907. * NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
  908. * rx/tx statistics and link status, in addition to KEEPALIVE traffic
  909. * and normal HC level polling to see if there's any IN traffic.
  910. */
  911. /* For USB: responses may take up to 10 seconds */
  912. switch (MsgType) {
  913. case REMOTE_NDIS_INITIALIZE_MSG:
  914. debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __func__);
  915. params->state = RNDIS_INITIALIZED;
  916. return rndis_init_response(configNr,
  917. (rndis_init_msg_type *) buf);
  918. case REMOTE_NDIS_HALT_MSG:
  919. debug("%s: REMOTE_NDIS_HALT_MSG\n", __func__);
  920. params->state = RNDIS_UNINITIALIZED;
  921. return 0;
  922. case REMOTE_NDIS_QUERY_MSG:
  923. return rndis_query_response(configNr,
  924. (rndis_query_msg_type *) buf);
  925. case REMOTE_NDIS_SET_MSG:
  926. return rndis_set_response(configNr,
  927. (rndis_set_msg_type *) buf);
  928. case REMOTE_NDIS_RESET_MSG:
  929. debug("%s: REMOTE_NDIS_RESET_MSG\n", __func__);
  930. return rndis_reset_response(configNr,
  931. (rndis_reset_msg_type *) buf);
  932. case REMOTE_NDIS_KEEPALIVE_MSG:
  933. /* For USB: host does this every 5 seconds */
  934. #if defined(DEBUG) && defined(DEBUG_VERBOSE)
  935. debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __func__);
  936. #endif
  937. return rndis_keepalive_response(configNr,
  938. (rndis_keepalive_msg_type *) buf);
  939. default:
  940. /*
  941. * At least Windows XP emits some undefined RNDIS messages.
  942. * In one case those messages seemed to relate to the host
  943. * suspending itself.
  944. */
  945. debug("%s: unknown RNDIS message 0x%08X len %d\n",
  946. __func__ , MsgType, MsgLength);
  947. {
  948. unsigned i;
  949. for (i = 0; i < MsgLength; i += 16) {
  950. debug("%03d: "
  951. " %02x %02x %02x %02x"
  952. " %02x %02x %02x %02x"
  953. " %02x %02x %02x %02x"
  954. " %02x %02x %02x %02x"
  955. "\n",
  956. i,
  957. buf[i], buf[i+1],
  958. buf[i+2], buf[i+3],
  959. buf[i+4], buf[i+5],
  960. buf[i+6], buf[i+7],
  961. buf[i+8], buf[i+9],
  962. buf[i+10], buf[i+11],
  963. buf[i+12], buf[i+13],
  964. buf[i+14], buf[i+15]);
  965. }
  966. }
  967. break;
  968. }
  969. return -ENOTSUPP;
  970. }
  971. int rndis_register(int (*rndis_control_ack)(struct eth_device *))
  972. {
  973. u8 i;
  974. for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
  975. if (!rndis_per_dev_params[i].used) {
  976. rndis_per_dev_params[i].used = 1;
  977. rndis_per_dev_params[i].ack = rndis_control_ack;
  978. debug("%s: configNr = %d\n", __func__, i);
  979. return i;
  980. }
  981. }
  982. debug("%s failed\n", __func__);
  983. return -1;
  984. }
  985. void rndis_deregister(int configNr)
  986. {
  987. debug("%s: configNr = %d\n", __func__, configNr);
  988. if (configNr >= RNDIS_MAX_CONFIGS)
  989. return;
  990. rndis_per_dev_params[configNr].used = 0;
  991. return;
  992. }
  993. int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu,
  994. struct net_device_stats *stats, u16 *cdc_filter)
  995. {
  996. debug("%s: configNr = %d\n", __func__, configNr);
  997. if (!dev || !stats)
  998. return -1;
  999. if (configNr >= RNDIS_MAX_CONFIGS)
  1000. return -1;
  1001. rndis_per_dev_params[configNr].dev = dev;
  1002. rndis_per_dev_params[configNr].stats = stats;
  1003. rndis_per_dev_params[configNr].mtu = mtu;
  1004. rndis_per_dev_params[configNr].filter = cdc_filter;
  1005. return 0;
  1006. }
  1007. int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr)
  1008. {
  1009. debug("%s: configNr = %d\n", __func__, configNr);
  1010. if (!vendorDescr)
  1011. return -1;
  1012. if (configNr >= RNDIS_MAX_CONFIGS)
  1013. return -1;
  1014. rndis_per_dev_params[configNr].vendorID = vendorID;
  1015. rndis_per_dev_params[configNr].vendorDescr = vendorDescr;
  1016. return 0;
  1017. }
  1018. int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed)
  1019. {
  1020. debug("%s: configNr = %d, %u %u\n", __func__, configNr, medium, speed);
  1021. if (configNr >= RNDIS_MAX_CONFIGS)
  1022. return -1;
  1023. rndis_per_dev_params[configNr].medium = medium;
  1024. rndis_per_dev_params[configNr].speed = speed;
  1025. return 0;
  1026. }
  1027. void rndis_add_hdr(void *buf, int length)
  1028. {
  1029. struct rndis_packet_msg_type *header;
  1030. header = buf;
  1031. memset(header, 0, sizeof *header);
  1032. header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
  1033. header->MessageLength = cpu_to_le32(length + sizeof *header);
  1034. header->DataOffset = __constant_cpu_to_le32(36);
  1035. header->DataLength = cpu_to_le32(length);
  1036. }
  1037. void rndis_free_response(int configNr, u8 *buf)
  1038. {
  1039. rndis_resp_t *r;
  1040. struct list_head *act, *tmp;
  1041. list_for_each_safe(act, tmp,
  1042. &(rndis_per_dev_params[configNr].resp_queue))
  1043. {
  1044. r = list_entry(act, rndis_resp_t, list);
  1045. if (r && r->buf == buf) {
  1046. list_del(&r->list);
  1047. free(r);
  1048. }
  1049. }
  1050. }
  1051. u8 *rndis_get_next_response(int configNr, u32 *length)
  1052. {
  1053. rndis_resp_t *r;
  1054. struct list_head *act, *tmp;
  1055. if (!length)
  1056. return NULL;
  1057. list_for_each_safe(act, tmp,
  1058. &(rndis_per_dev_params[configNr].resp_queue))
  1059. {
  1060. r = list_entry(act, rndis_resp_t, list);
  1061. if (!r->send) {
  1062. r->send = 1;
  1063. *length = r->length;
  1064. return r->buf;
  1065. }
  1066. }
  1067. return NULL;
  1068. }
  1069. static rndis_resp_t *rndis_add_response(int configNr, u32 length)
  1070. {
  1071. rndis_resp_t *r;
  1072. /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
  1073. r = malloc(sizeof(rndis_resp_t) + length);
  1074. if (!r)
  1075. return NULL;
  1076. r->buf = (u8 *) (r + 1);
  1077. r->length = length;
  1078. r->send = 0;
  1079. list_add_tail(&r->list,
  1080. &(rndis_per_dev_params[configNr].resp_queue));
  1081. return r;
  1082. }
  1083. int rndis_rm_hdr(void *buf, int length)
  1084. {
  1085. /* tmp points to a struct rndis_packet_msg_type */
  1086. __le32 *tmp = buf;
  1087. int offs, len;
  1088. /* MessageType, MessageLength */
  1089. if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
  1090. != get_unaligned(tmp++))
  1091. return -EINVAL;
  1092. tmp++;
  1093. /* DataOffset, DataLength */
  1094. offs = get_unaligned_le32(tmp++) + 8 /* offset of DataOffset */;
  1095. if (offs != sizeof(struct rndis_packet_msg_type))
  1096. debug("%s: unexpected DataOffset: %d\n", __func__, offs);
  1097. if (offs >= length)
  1098. return -EOVERFLOW;
  1099. len = get_unaligned_le32(tmp++);
  1100. if (len + sizeof(struct rndis_packet_msg_type) != length)
  1101. debug("%s: unexpected DataLength: %d, packet length=%d\n",
  1102. __func__, len, length);
  1103. memmove(buf, buf + offs, len);
  1104. return offs;
  1105. }
  1106. int rndis_init(void)
  1107. {
  1108. u8 i;
  1109. for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
  1110. rndis_per_dev_params[i].confignr = i;
  1111. rndis_per_dev_params[i].used = 0;
  1112. rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED;
  1113. rndis_per_dev_params[i].media_state
  1114. = NDIS_MEDIA_STATE_DISCONNECTED;
  1115. INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue));
  1116. }
  1117. return 0;
  1118. }
  1119. void rndis_exit(void)
  1120. {
  1121. /* Nothing to do */
  1122. }