1 /*
2 * Copyright (c) 2024 Archermind Technology (Nanjing) Co. Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <unistd.h>
32 #include "securec.h"
33 #include "osal_mem.h"
34 #include "osal_time.h"
35
36 #include "hdf_base.h"
37 #include "hdf_log.h"
38
39 #include "usb_ddk_pnp_loader.h"
40 #include "usb_ddk_interface.h"
41 #include "usb_net_host.h"
42 #include "rndis_rawapi.h"
43
44 #define HDF_LOG_TAG USB_HOST_RNDIS_RAW_API
45 #define URB_LEGAL_ACTUAL_LENGTH 8
46 #define ZERO_INDEX 0
47 #define ONE_INDEX 1
48 #define TWO_INDEX 2
49 #define THREE_INDEX 3
50 #define FOUR_INDEX 4
51 #define FIVE_INDEX 5
52
53 #define MSG_HEAD_LENGTH 4
54 #define UNION_OFFSET_LENGTH 8
55 #define COMMAND_COUNT_MAX 10
56 #define UNION_GETOFFSET_NUMBER 20
57 #define RNDIS_COMMAND_SLEEPTIME 40
58 #define RNDIS_QUERY_INPUT_LENGTH 48
59
60 /* define rndis union */
61 union {
62 void *buf;
63 struct RndisMsgHdr *header;
64 struct RndisInit *init;
65 struct RndisInitC *initC;
66 struct RndisQuery *get;
67 struct RndisQueryC *getC;
68 struct RndisSet *set;
69 struct RndisSetC *setC;
70 struct RndisHalt *halt;
71 } g_u;
72
UsbGetBulkEndpoint(struct UsbnetHost **ppUsbNet, const struct UsbRawEndpointDescriptor *endPoint)73 static int32_t UsbGetBulkEndpoint(struct UsbnetHost **ppUsbNet, const struct UsbRawEndpointDescriptor *endPoint)
74 {
75 if ((endPoint->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK) == USB_DDK_DIR_IN) {
76 /* get bulk in endpoint */
77 (*ppUsbNet)->dataInEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
78 if ((*ppUsbNet)->dataInEp == NULL) {
79 HDF_LOGE("%{public}s:%{public}d allocate dataInEp failed", __func__, __LINE__);
80 return HDF_FAILURE;
81 }
82 (*ppUsbNet)->dataInEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
83 (*ppUsbNet)->dataInEp->interval = endPoint->endpointDescriptor.bInterval;
84 (*ppUsbNet)->dataInEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
85 HARCH_INFO_PRINT("usbNet->dataInEp=[addr:%{public}#x, interval:%{public}d, maxPacketSize:%{public}hu]",
86 (*ppUsbNet)->dataInEp->addr, (*ppUsbNet)->dataInEp->interval, (*ppUsbNet)->dataInEp->maxPacketSize);
87 } else {
88 /* get bulk out endpoint */
89 (*ppUsbNet)->dataOutEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
90 if ((*ppUsbNet)->dataOutEp == NULL) {
91 HDF_LOGE("%{public}s:%{public}d allocate dataOutEp failed", __func__, __LINE__);
92 return HDF_FAILURE;
93 }
94 (*ppUsbNet)->dataOutEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
95 (*ppUsbNet)->dataOutEp->interval = endPoint->endpointDescriptor.bInterval;
96 (*ppUsbNet)->dataOutEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
97 HARCH_INFO_PRINT("usbNet->dataOutEp=[addr:%{public}#x, interval:%{public}d, maxPacketSize:%{public}hu]",
98 (*ppUsbNet)->dataOutEp->addr, (*ppUsbNet)->dataOutEp->interval, (*ppUsbNet)->dataOutEp->maxPacketSize);
99 }
100 return HDF_SUCCESS;
101 }
102
UsbParseConfigDescriptorProcess(struct UsbnetHost **ppUsbNet, const struct UsbRawInterface *interface, uint8_t interfaceIndex)103 static void UsbParseConfigDescriptorProcess(struct UsbnetHost **ppUsbNet,
104 const struct UsbRawInterface *interface, uint8_t interfaceIndex)
105 {
106 uint8_t ifaceClass = interface->altsetting->interfaceDescriptor.bInterfaceClass;
107 uint8_t numEndpoints = interface->altsetting->interfaceDescriptor.bNumEndpoints;
108 HARCH_INFO_PRINT("ifaceClass=%{public}d, numEndpoints=%{public}d", ifaceClass, numEndpoints);
109 switch (ifaceClass) {
110 case USB_DDK_CLASS_WIRELESS_CONTROLLER: //USB_DDK_CLASS_COMM:
111 (*ppUsbNet)->ctrlIface = interfaceIndex;
112 HARCH_INFO_PRINT("ctrlInface:%{public}d", interfaceIndex);
113 (*ppUsbNet)->statusEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
114 if ((*ppUsbNet)->statusEp == NULL) {
115 HDF_LOGE("%{public}s:%{public}d allocate endpoint failed", __func__, __LINE__);
116 break;
117 }
118 /* get the first endpoint by default */
119 (*ppUsbNet)->statusEp->addr = interface->altsetting->endPoint[0].endpointDescriptor.bEndpointAddress;
120 (*ppUsbNet)->statusEp->interval = interface->altsetting->endPoint[0].endpointDescriptor.bInterval;
121 (*ppUsbNet)->statusEp->maxPacketSize = interface->altsetting->endPoint[0].endpointDescriptor.wMaxPacketSize;
122
123 HARCH_INFO_PRINT("usbNet->statusEp=[addr:%{public}#x, interval:%{public}d, maxPacketSize:%{public}hu]",
124 (*ppUsbNet)->statusEp->addr, (*ppUsbNet)->statusEp->interval, (*ppUsbNet)->statusEp->maxPacketSize);
125 break;
126 case USB_DDK_CLASS_CDC_DATA:
127 (*ppUsbNet)->dataIface = interfaceIndex;
128 HARCH_INFO_PRINT("dataIface:%{public}d", interfaceIndex);
129 for (uint8_t j = 0; j < numEndpoints; j++) {
130 const struct UsbRawEndpointDescriptor *endPoint = &interface->altsetting->endPoint[j];
131 if (UsbGetBulkEndpoint(ppUsbNet, endPoint) != HDF_SUCCESS) {
132 HARCH_INFO_PRINT("");
133 break;
134 }
135 HARCH_INFO_PRINT("");
136 }
137 break;
138 default:
139 HARCH_INFO_PRINT("wrong descriptor type");
140 break;
141 }
142 }
143
UsbParseConfigDescriptor(struct UsbnetHost **ppUsbNet)144 static int32_t UsbParseConfigDescriptor(struct UsbnetHost **ppUsbNet)
145 {
146 const struct UsbRawInterface *interface = (*ppUsbNet)->config->interface[0];
147 //set 0 interface and 1 interface data endpoint and ctrl endpoint
148 int32_t ret = UsbRawClaimInterface((*ppUsbNet)->devHandle, 0);
149 if (ret != HDF_SUCCESS) {
150 HDF_LOGE("%{public}s:%{public}d claim interface failed", __func__, __LINE__);
151 return HDF_FAILURE;
152 }
153 HARCH_INFO_PRINT("");
154 UsbParseConfigDescriptorProcess(ppUsbNet, interface, 0);
155
156 const struct UsbRawInterface *interface1 = (*ppUsbNet)->config->interface[1];
157 ret = UsbRawClaimInterface((*ppUsbNet)->devHandle, 1);
158 if (ret != HDF_SUCCESS) {
159 HDF_LOGE("%{public}s:%{public}d claim interface failed", __func__, __LINE__);
160 return HDF_FAILURE;
161 }
162 HARCH_INFO_PRINT("");
163 UsbParseConfigDescriptorProcess(ppUsbNet, interface1, 1);
164 return HDF_SUCCESS;
165 }
166
167 /*
168 * RNDIS indicate messages.
169 */
HostRndisMsgIndicate(struct UsbnetHost *usbNet, struct RndisIndicate *msg, int buflen)170 static void HostRndisMsgIndicate(struct UsbnetHost *usbNet, struct RndisIndicate *msg, int buflen)
171 {
172 HARCH_INFO_PRINT("begin");
173 uint32_t status = CPU_TO_LE32(msg->status);
174 switch (status) {
175 case RNDIS_STATUS_MEDIA_CONNECT:
176 HARCH_INFO_PRINT("rndis media connect");
177 break;
178 case RNDIS_STATUS_MEDIA_DISCONNECT:
179 HARCH_INFO_PRINT("rndis media disconnect");
180 break;
181 default:
182 HARCH_INFO_PRINT("rndis indication: 0x%{public}08x\n", status);
183 /* fall-through */
184 }
185 }
186
UsbnetHostHandleNonRsp(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen, uint32_t msgType)187 static void UsbnetHostHandleNonRsp(struct UsbnetHost *usbNet,
188 struct RndisMsgHdr *buf, int buflen, uint32_t msgType)
189 {
190 switch (msgType) {
191 /* fault/event */
192 case RNDIS_MSG_INDICATE:
193 HostRndisMsgIndicate(usbNet, (void *)buf, buflen);
194 break;
195 case RNDIS_MSG_KEEPALIVE: {
196 /* ping */
197 struct RndisKeepaliveC *msg = (void *)buf;
198 msg->msgType = CPU_TO_LE32(RNDIS_MSG_KEEPALIVE_C);
199 msg->msgLen = CPU_TO_LE32(sizeof(struct RndisKeepaliveC));
200 msg->status = CPU_TO_LE32(RNDIS_STATUS_SUCCESS);
201
202 struct UsbnetHostCmdParam cmdParam = {};
203 cmdParam.cmd = USB_DDK_CDC_SEND_ENCAPSULATED_COMMAND;
204 cmdParam.reqtype = USB_DDK_DIR_OUT|USB_DDK_TYPE_CLASS|USB_DDK_RECIP_INTERFACE;
205 cmdParam.value = 0;
206 cmdParam.index = usbNet->curInterfaceNumber;
207 cmdParam.data = msg;
208 cmdParam.size = sizeof(struct RndisKeepaliveC);
209 int32_t retval = UsbnetHostWriteCmdSync(usbNet, cmdParam);
210 HARCH_INFO_PRINT("retval = %{public}d", retval);
211 if (retval < 0) {
212 HARCH_INFO_PRINT("rndis keepalive err %{public}d\n", retval);
213 }
214 }
215 break;
216 default:
217 HARCH_INFO_PRINT("unexpected rndis msg %{public}08x len %{public}d\n",
218 CPU_TO_LE32(buf->msgType), CPU_TO_LE32(buf->msgLen));
219 break;
220 }
221 }
222
UsbnetHostHandleMsg(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen, uint32_t xid)223 static int32_t UsbnetHostHandleMsg(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen, uint32_t xid)
224 {
225 uint32_t msgType = CPU_TO_LE32(buf->msgType);
226 uint32_t msgLen = CPU_TO_LE32(buf->msgLen);
227 uint32_t status = CPU_TO_LE32(buf->status);
228 uint32_t requestId = (uint32_t)buf->requestId;
229 uint32_t rsp = CPU_TO_LE32(buf->msgType) | RNDIS_MSG_COMPLETION;
230 HARCH_INFO_PRINT("rndis reply msgType = %{public}x, msgLen = %{public}x,"
231 "status = %{public}x, requestId = %{public}x",
232 msgType, msgLen, status, requestId);
233
234 if (msgType == rsp) {
235 if (requestId == xid) {
236 HARCH_INFO_PRINT("rndis reply status %{public}08x\n", status);
237 HARCH_INFO_PRINT("rndis reply rsp %{public}08x\n", rsp);
238 if (rsp == RNDIS_MSG_RESET_C) {
239 return HDF_SUCCESS;
240 }
241
242 if (RNDIS_STATUS_SUCCESS == status) {
243 return HDF_SUCCESS;
244 }
245
246 HARCH_INFO_PRINT("rndis reply status %{public}08x\n", status);
247 return -EL3RST;
248 }
249 /* then likely retry */
250 } else {
251 HARCH_INFO_PRINT("unexpected rndis msg %{public}08x len %{public}d\n", CPU_TO_LE32(buf->msgType), msgLen);
252 UsbnetHostHandleNonRsp(usbNet, buf, buflen, msgType);
253 }
254 return HDF_SUCCESS;
255 }
256
257 /*
258 * RPC done RNDIS-style. Caller guarantees:
259 * - message is properly byteswapped
260 * - there's no other request pending
261 * - buf can hold up to 1KB response (required by RNDIS spec)
262 * On return, the first few entries are already byteswapped.
263 *
264 * Call context is likely probe(), before interface name is known,
265 * which is why we won't try to use it in the diagnostics.
266 */
HostRndisCommand(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen)267 static int32_t HostRndisCommand(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen)
268 {
269 HARCH_INFO_PRINT("begin");
270 uint32_t msgType = CPU_TO_LE32(buf->msgType);
271 uint32_t xid = 0;
272
273 /* Issue the request; xid is unique, don't bother byteswapping it */
274 if (msgType != RNDIS_MSG_HALT && msgType != RNDIS_MSG_RESET) {
275 xid = usbNet->xid++;
276 if (!xid) {
277 xid = usbNet->xid++;
278 }
279 buf->requestId = (__le32) xid;
280 }
281 HARCH_INFO_PRINT("msgType= %{public}d, xid = %{public}d", msgType, xid);
282 struct UsbnetHostCmdParam cmdParam = {};
283 cmdParam.cmd = USB_DDK_CDC_SEND_ENCAPSULATED_COMMAND;
284 cmdParam.reqtype = USB_DDK_DIR_OUT|USB_DDK_TYPE_CLASS|USB_DDK_RECIP_INTERFACE;
285 cmdParam.value = 0;
286 cmdParam.index = usbNet->curInterfaceNumber;
287 cmdParam.data = buf;
288 cmdParam.size = CPU_TO_LE32(buf->msgLen);
289
290 int retval = UsbnetHostWriteCmdSync(usbNet, cmdParam);
291 HARCH_INFO_PRINT("retval = %{public}d", retval);
292 if (retval < 0 || xid == 0) {
293 return retval;
294 }
295 UsbnetWriteLog((char *)buf, CPU_TO_LE32(buf->msgLen), 0);
296 HARCH_INFO_PRINT("rndis xid %{public}d\n", xid);
297 uint32_t count = 0;
298 /* Poll the control channel; the request probably completed immediately */
299 for (count = 0; count < COMMAND_COUNT_MAX; count++) {
300 HARCH_INFO_PRINT("count = %{public}d, buflen = %{public}d", count, buflen);
301 memset_s(buf, CONTROL_BUFFER_SIZE, 0, CONTROL_BUFFER_SIZE);
302 cmdParam.cmd = USB_DDK_CDC_GET_ENCAPSULATED_RESPONSE;
303 cmdParam.reqtype = USB_DDK_DIR_IN|USB_DDK_TYPE_CLASS|USB_DDK_RECIP_INTERFACE;
304 cmdParam.value = 0;
305 cmdParam.index = usbNet->curInterfaceNumber;
306 cmdParam.data = buf;
307 cmdParam.size = buflen;
308 retval= UsbnetHostWriteCmdSync(usbNet, cmdParam);
309 HARCH_INFO_PRINT("retval = %{public}d", retval);
310 UsbnetWriteLog((char *)buf, buflen, 0);
311
312 if (retval > URB_LEGAL_ACTUAL_LENGTH) {
313 return UsbnetHostHandleMsg(usbNet, buf, buflen, xid);
314 } else {
315 /* device probably issued a protocol stall; ignore */
316 HARCH_INFO_PRINT("rndis response error = %{public}d", retval);
317 }
318 OsalMSleep(RNDIS_COMMAND_SLEEPTIME);
319 }
320 HARCH_INFO_PRINT("rndis response timeout");
321 return HDF_ERR_TIMEOUT;
322 }
323
324 /* Performs a query for @oid along with 0 or more bytes of payload as
325 * specified by @in_len. If @replyLen is not set to -1 then the reply
326 * length is checked against this value, resulting in an error if it
327 * doesn't match.
328 *
329 * NOTE: Adding a payload exactly or greater than the size of the expected
330 * response payload is an evident requirement MSFT added for ActiveSync.
331 *
332 * The only exception is for OIDs that return a variably sized response,
333 * in which case no payload should be added. This undocumented (and
334 * nonsensical!) issue was found by sniffing protocol requests from the
335 * ActiveSync 4.1 Windows driver.
336 */
HostRndisQuery(struct UsbnetHost *usbNet, struct RndisQueryParam queryParam, void **reply, int *replyLen)337 static int32_t HostRndisQuery(struct UsbnetHost *usbNet, struct RndisQueryParam queryParam, void **reply, int *replyLen)
338 {
339 HARCH_INFO_PRINT("begin");
340 int retval;
341 union {
342 void *buf;
343 struct RndisMsgHdr *header;
344 struct RndisQuery *get;
345 struct RndisQueryC *getC;
346 } uq;
347
348 uq.buf = queryParam.buf;
349 memset_s(uq.get, sizeof(struct RndisQuery) + queryParam.in_len, 0, sizeof(struct RndisQuery) + queryParam.in_len);
350 uq.get->msgType = CPU_TO_LE32(RNDIS_MSG_QUERY);
351 uq.get->msgLen = CPU_TO_LE32(sizeof(struct RndisQuery) + queryParam.in_len);
352 uq.get->oid = CPU_TO_LE32(queryParam.oid);
353 uq.get->len = CPU_TO_LE32(queryParam.in_len);
354 uq.get->offset = CPU_TO_LE32(UNION_GETOFFSET_NUMBER);
355
356 retval = HostRndisCommand(usbNet, uq.header, CONTROL_BUFFER_SIZE);
357 HARCH_INFO_PRINT("retval = %{public}d", retval);
358 HARCH_INFO_PRINT("RNDIS_MSG_QUERY(0x%{public}08x) %{public}d\n", queryParam.oid, retval);
359 if (retval < 0) {
360 HDF_LOGE("RNDIS_MSG_QUERY(0x%{public}08x) failed, %{public}d", queryParam.oid, retval);
361 return retval;
362 }
363
364 uint32_t off = CPU_TO_LE32(uq.getC->offset);
365 uint32_t len = CPU_TO_LE32(uq.getC->len);
366
367 HARCH_INFO_PRINT("off = %{public}d, len = %{public}d, retval = %{public}d", off, len, retval);
368 // CONTROL_BUFFER_SIZE_-UNION_OFFSET_LENGTH is valid memory range
369 if ((off > CONTROL_BUFFER_SIZE - UNION_OFFSET_LENGTH) || (len > CONTROL_BUFFER_SIZE - UNION_OFFSET_LENGTH - off)) {
370 goto response_error;
371 }
372
373 if (*replyLen != -1 && len != *replyLen) {
374 goto response_error;
375 }
376
377 *reply = (unsigned char *) &uq.getC->requestId + off;
378 *replyLen = len;
379
380 HARCH_INFO_PRINT("*replyLen = %{public}d, retval = %{public}d", len, retval);
381 return retval;
382
383 response_error:
384 HDF_LOGE("RNDIS_MSG_QUERY(0x%{public}08x) invalid response - off %{public}d len %{public}d",
385 queryParam.oid, off, len);
386
387 return -EDOM;
388 }
389
HostRndisInitUsbnet(struct UsbnetHost **ppUsbNet, int32_t *retval)390 static void HostRndisInitUsbnet(struct UsbnetHost **ppUsbNet, int32_t *retval)
391 {
392 /* max transfer (in spec) is 0x4000 at full speed, but for
393 * TX we'll stick to one Ethernet packet plus RNDIS framing.
394 * For RX we handle drivers that zero-pad to end-of-packet.
395 * Don't let userspace change these settings.
396 *
397 * NOTE: there still seems to be wierdness here, as if we need
398 * to do some more things to make sure WinCE targets accept this.
399 * They default to jumbograms of 8KB or 16KB, which is absurd
400 * for such low data rates and which is also more than Linux
401 * can usually expect to allocate for SKB data...
402 */
403 (*ppUsbNet)->net.hardHeaderLen += sizeof(struct RndisDataHdr);
404 (*ppUsbNet)->net.hardMtu = (*ppUsbNet)->net.mtu + (*ppUsbNet)->net.hardHeaderLen;
405 HARCH_INFO_PRINT("hardHeaderLen = %{public}d, hardMtu = %{public}d\n",
406 (*ppUsbNet)->net.hardHeaderLen, (*ppUsbNet)->net.hardMtu);
407 (*ppUsbNet)->net.maxpacket = (*ppUsbNet)->dataOutEp->maxPacketSize;
408
409 HARCH_INFO_PRINT("maxpacket = %{public}d\n", (*ppUsbNet)->net.maxpacket);
410 if ((*ppUsbNet)->net.maxpacket == 0) {
411 HDF_LOGE("usbNet->maxpacket can't be 0");
412 *retval = HDF_ERR_INVALID_PARAM;
413 return;
414 }
415
416 (*ppUsbNet)->net.rxUrbSize = (*ppUsbNet)->net.hardMtu + ((*ppUsbNet)->net.maxpacket + 1);
417 (*ppUsbNet)->net.rxUrbSize &= ~((*ppUsbNet)->net.maxpacket - 1);
418 HARCH_INFO_PRINT("rxUrbSize = %{public}d\n", (*ppUsbNet)->net.rxUrbSize);
419 }
420
HostRndisUpdateMtu(struct UsbnetHost **ppUsbNet, int32_t *retval)421 static void HostRndisUpdateMtu(struct UsbnetHost **ppUsbNet, int32_t *retval)
422 {
423 uint32_t tmp = CPU_TO_LE32(g_u.initC->maxTransferSize);
424 if (tmp < (*ppUsbNet)->net.hardMtu) {
425 if (tmp <= (*ppUsbNet)->net.hardHeaderLen) {
426 HARCH_INFO_PRINT("RNDIS init failed, %{public}d", *retval);
427 HDF_LOGE("usbNet can't take %{public}u byte packets (max %{public}u)", (*ppUsbNet)->net.hardMtu, tmp);
428 *retval = HDF_ERR_INVALID_PARAM;
429 }
430 HARCH_INFO_PRINT("usbNet can't take %{public}u byte packets (max %{public}u) adjusting MTU to %{public}u\n",
431 (*ppUsbNet)->net.hardMtu, tmp, tmp - (*ppUsbNet)->net.hardHeaderLen);
432 HDF_LOGW("usbNet can't take %{public}u byte packets (max %{public}u) adjusting MTU to %{public}u",
433 (*ppUsbNet)->net.hardMtu, tmp, tmp - (*ppUsbNet)->net.hardHeaderLen);
434 (*ppUsbNet)->net.hardMtu = tmp;
435 (*ppUsbNet)->net.mtu = (*ppUsbNet)->net.hardMtu - (*ppUsbNet)->net.hardHeaderLen;
436 }
437 HARCH_INFO_PRINT("hard mtu %{public}u (%{public}u from usbNet), rx buflen %{public}u, align %{public}d\n",
438 (*ppUsbNet)->net.hardMtu, tmp, (*ppUsbNet)->net.rxUrbSize, 1 << CPU_TO_LE32(g_u.initC->packetAlignment));
439 }
440
HostRndisSetmacAddrByBp(struct UsbnetHost **ppUsbNet, int32_t *retval)441 static void HostRndisSetmacAddrByBp(struct UsbnetHost **ppUsbNet, int32_t *retval)
442 {
443 int replyLen = MAC_ADDR_SIZE;
444 unsigned char *bp;
445 struct RndisQueryParam queryParam = {g_u.buf, RNDIS_OID_802_3_PERMANENT_ADDRESS, RNDIS_QUERY_INPUT_LENGTH};
446 *retval = HostRndisQuery(*ppUsbNet, queryParam, (void **)&bp, &replyLen);
447 if (*retval < 0) {
448 HDF_LOGE("rndis get ethaddr, %{public}d", *retval);
449 *retval = HDF_ERR_NOPERM;
450 }
451
452 HARCH_INFO_PRINT("bp 1= %{public}x", bp[ZERO_INDEX]);
453 HARCH_INFO_PRINT("bp 2= %{public}x", bp[ONE_INDEX]);
454 HARCH_INFO_PRINT("bp 3= %{public}x", bp[TWO_INDEX]);
455 HARCH_INFO_PRINT("bp 4= %{public}x", bp[THREE_INDEX]);
456 HARCH_INFO_PRINT("bp 5= %{public}x", bp[FOUR_INDEX]);
457 HARCH_INFO_PRINT("bp 6= %{public}x", bp[FIVE_INDEX]);
458
459 if (bp[0] & 0x02) {
460 HARCH_INFO_PRINT("not GetmacAddr");
461 (*ppUsbNet)->net.isGetmacAddr = 0;
462 size_t macAddrLen = sizeof((*ppUsbNet)->net.macAddr) / sizeof((*ppUsbNet)->net.macAddr[0]);
463 if (memset_s((*ppUsbNet)->net.macAddr, macAddrLen, 0, macAddrLen) !=EOK) {
464 HARCH_INFO_PRINT("HostRndisSetmacAddrByBp memset_s fail!");
465 return;
466 }
467 } else {
468 HARCH_INFO_PRINT("GetmacAddr");
469 (*ppUsbNet)->net.isGetmacAddr = 1;
470 etherAddrCopy((*ppUsbNet)->net.macAddr, bp);
471 }
472 }
473
HostRndisSetmacAddr(struct UsbnetHost **ppUsbNet, int32_t *retval)474 static void HostRndisSetmacAddr(struct UsbnetHost **ppUsbNet, int32_t *retval)
475 {
476 __le32 *phym = NULL;
477 __le32 phym_unspec;
478 int replyLen = sizeof(__le32);
479 /* Check physical medium */
480 struct RndisQueryParam queryParam = {g_u.buf, RNDIS_OID_GEN_PHYSICAL_MEDIUM, replyLen};
481 *retval = HostRndisQuery(*ppUsbNet, queryParam, (void **)&phym, &replyLen);
482 if ((retval != NULL && *retval != 0) || !phym) {
483 /* OID is optional so don't fail here. */
484 phym_unspec = CPU_TO_LE32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED);
485 phym = &phym_unspec;
486 }
487
488 if (((*ppUsbNet)->flags & FLAG_RNDIS_PHYM_WIRELESS) &&
489 CPU_TO_LE32(*phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
490 HDF_LOGE("driver requires wireless physical medium, but device is not");
491 *retval = HDF_ERR_NOPERM;
492 }
493
494 if (((*ppUsbNet)->flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
495 CPU_TO_LE32(*phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
496 HDF_LOGE("driver requires non-wireless physical medium, but device is wireless");
497 *retval = HDF_ERR_NOPERM;
498 }
499
500 /* Get designated host ethernet address */
501 HostRndisSetmacAddrByBp(ppUsbNet, retval);
502 }
503
HostRndisInitUnion(struct UsbnetHost *usbNet, int32_t *retval)504 static int32_t HostRndisInitUnion(struct UsbnetHost *usbNet, int32_t *retval)
505 {
506 int32_t ret = HDF_SUCCESS;
507 g_u.buf = OsalMemAlloc(CONTROL_BUFFER_SIZE);
508 if (!g_u.buf) {
509 HDF_LOGE("g_u.buf can't be 0");
510 ret = HDF_ERR_MALLOC_FAIL;
511 }
512
513 g_u.init->msgType = CPU_TO_LE32(RNDIS_MSG_INIT);
514 g_u.init->msgLen = CPU_TO_LE32(sizeof(struct RndisInit));
515 g_u.init->majorVersion = CPU_TO_LE32(1);
516 g_u.init->minorVersion = CPU_TO_LE32(0);
517
518 g_u.init->maxTransferSize = CPU_TO_LE32((usbNet)->net.rxUrbSize);
519 *retval = HostRndisCommand(usbNet, g_u.header, CONTROL_BUFFER_SIZE);
520 if (*retval < 0) {
521 /* it might not even be an RNDIS device!! */
522 HARCH_INFO_PRINT("RNDIS init failed, %{public}d", *retval);
523 HDF_LOGE("RNDIS init failed, %{public}d", *retval);
524 ret = HDF_DEV_ERR_OP;
525 }
526 return ret;
527 }
528
HostRndisEnableDataTransfers(struct UsbnetHost *usbNet)529 static int32_t HostRndisEnableDataTransfers(struct UsbnetHost *usbNet)
530 {
531 int32_t ret = HDF_SUCCESS;
532 /* set a nonzero filter to enable data transfers */
533 memset_s(g_u.set, sizeof(struct RndisSet), 0, sizeof(struct RndisSet));
534 g_u.set->msgType = CPU_TO_LE32(RNDIS_MSG_SET);
535 g_u.set->msgLen = CPU_TO_LE32(MSG_HEAD_LENGTH + sizeof(struct RndisSet));
536 g_u.set->oid = CPU_TO_LE32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER);
537 g_u.set->len = CPU_TO_LE32(MSG_HEAD_LENGTH);
538 g_u.set->offset = CPU_TO_LE32(sizeof(struct RndisSet) - UNION_OFFSET_LENGTH);
539 *(__le32 *)(g_u.buf + sizeof(struct RndisSet)) = CPU_TO_LE32(RNDIS_DEFAULT_FILTER);
540 int32_t retval = HostRndisCommand(usbNet, g_u.header, CONTROL_BUFFER_SIZE);
541 if (retval < 0) {
542 HDF_LOGE("rndis set packet filter, %{public}d", retval);
543 ret = HDF_FAILURE;
544 }
545 OsalMemFree(g_u.buf);
546 g_u.buf = NULL;
547 return ret;
548 }
549
550 /* function
551 1.get usb endpoints info
552 2.init usb device
553 3.get usb device adrress and status
554 4.set usb device work
555 */
HostRndisBind(struct UsbnetHost *usbNet)556 static int32_t HostRndisBind(struct UsbnetHost *usbNet)
557 {
558 int32_t retval = 0;
559 int32_t ret = UsbParseConfigDescriptor(&usbNet);
560 if (ret != HDF_SUCCESS) {
561 HDF_LOGE("%{public}s:%{public}d UsbParseConfigDescriptor failed", __func__, __LINE__);
562 UsbRawFreeConfigDescriptor(usbNet->config);
563 usbNet->config = NULL;
564 return ret;
565 }
566
567 HostRndisInitUsbnet(&usbNet, &retval);
568 if (retval == HDF_ERR_INVALID_PARAM) {
569 HDF_LOGE("%{public}s:%{public}d HostRndisInitUsbnet failed", __func__, __LINE__);
570 return retval;
571 }
572
573 ret = HostRndisInitUnion(usbNet, &retval);
574 if (ret == HDF_ERR_MALLOC_FAIL) {
575 HDF_LOGE("%{public}s:%{public}d HostRndisInitUnion failed", __func__, __LINE__);
576 return ret;
577 } else if (ret == HDF_DEV_ERR_OP) {
578 HDF_LOGE("%{public}s:%{public}d HostRndisInitUnion failed", __func__, __LINE__);
579 OsalMemFree(g_u.buf);
580 g_u.buf = NULL;
581 return ret;
582 }
583
584 HostRndisUpdateMtu(&usbNet, &retval);
585 if (retval == HDF_ERR_INVALID_PARAM) {
586 HDF_LOGE("%{public}s:%{public}d HostRndisUpdateMtu failed", __func__, __LINE__);
587 goto ERR_HALT_FAILED_AND_RELEASE;
588 return retval;
589 }
590
591 HostRndisSetmacAddr(&usbNet, &retval);
592 if (retval == HDF_ERR_NOPERM) {
593 HDF_LOGE("%{public}s:%{public}d HostRndisSetmacAddr failed", __func__, __LINE__);
594 goto ERR_HALT_FAILED_AND_RELEASE;
595 return retval;
596 }
597
598 ret = HostRndisEnableDataTransfers(usbNet);
599 if (ret != HDF_SUCCESS) {
600 HDF_LOGE("%{public}s:%{public}d HostRndisEnableDataTransfers failed", __func__, __LINE__);
601 goto ERR_HALT_FAILED_AND_RELEASE;
602 }
603 return ret;
604 ERR_HALT_FAILED_AND_RELEASE:
605 memset_s(g_u.halt, sizeof(struct RndisHalt), 0, sizeof(struct RndisHalt));
606 g_u.halt->msgType = CPU_TO_LE32(RNDIS_MSG_HALT);
607 g_u.halt->msgLen = CPU_TO_LE32(sizeof(struct RndisHalt));
608 (void)HostRndisCommand(usbNet, (void *)g_u.halt, CONTROL_BUFFER_SIZE);
609 return HDF_FAILURE;
610 }
611
HostRndisUnbind(struct UsbnetHost *usbNet)612 static void HostRndisUnbind(struct UsbnetHost *usbNet)
613 {
614 HARCH_INFO_PRINT();
615 struct RndisHalt *halt = OsalMemAlloc(sizeof(struct RndisHalt));
616
617 memset_s(halt, sizeof(struct RndisHalt), 0, sizeof(struct RndisHalt));
618 halt->msgType = CPU_TO_LE32(RNDIS_MSG_HALT);
619 halt->msgLen = CPU_TO_LE32(sizeof(struct RndisHalt));
620 (void) HostRndisCommand(usbNet, (void *)halt, CONTROL_BUFFER_SIZE);
621 OsalMemFree(halt);
622 }
623
624 static struct UsbnetHostDriverInfo g_hostRndisInfo = {
625 .description = "rndis device",
626 .bind = HostRndisBind,
627 .unbind = HostRndisUnbind,
628 };
629
HostRndisDriverDeviceDispatch( struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)630 static int32_t HostRndisDriverDeviceDispatch(
631 struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
632 {
633 return HDF_SUCCESS;
634 }
635
636 /* HdfDriverEntry implementations */
HostRndisDriverBind(struct HdfDeviceObject *device)637 static int32_t HostRndisDriverBind(struct HdfDeviceObject *device)
638 {
639 HARCH_INFO_PRINT("[-cbs-] HostRndisDriverBind begin !");
640 if (device == NULL) {
641 HDF_LOGE("%{public}s: device is null", __func__);
642 return HDF_ERR_INVALID_OBJECT;
643 }
644
645 struct UsbnetHost *usbNet = (struct UsbnetHost *)OsalMemCalloc(sizeof(*usbNet));
646 if (usbNet == NULL) {
647 HDF_LOGE("%{public}s: Alloc UsbnetHost memory failed", __func__);
648 return HDF_FAILURE;
649 }
650
651 struct UsbPnpNotifyServiceInfo *info = NULL;
652 info = (struct UsbPnpNotifyServiceInfo *)device->priv;
653 if (info != NULL) {
654 HARCH_INFO_PRINT("[-cbs-]bus:%{public}d+dev:%{public}d", info->busNum, info->devNum);
655 HARCH_INFO_PRINT("[-cbs-]interfaceLength:%{public}d", info->interfaceLength);
656 HARCH_INFO_PRINT("[-cbs-]curInterfaceNum:%{public}d", info->curInterfaceNumber);
657
658 usbNet->busNum = info->busNum;
659 usbNet->devAddr = info->devNum;
660 usbNet->curInterfaceNumber = info->curInterfaceNumber;
661 } else {
662 HDF_LOGE("%{public}s:%{public}d info is NULL!", __func__, __LINE__);
663 goto ERROR;
664 }
665
666 HDF_LOGE("%{public}s:%{public}d", __func__, __LINE__);
667 device->service = &(usbNet->service);
668 if (device->service == NULL) {
669 HDF_LOGE("%{public}s:%{public}d", __func__, __LINE__);
670 }
671
672 device->service->Dispatch = HostRndisDriverDeviceDispatch;
673 usbNet->deviceObject = device;
674
675 /* here need to choose device driver */
676 struct UsbnetHostDriverInfo *driver = &g_hostRndisInfo;
677 //function
678 usbNet->driverInfo = driver;
679
680 HARCH_INFO_PRINT("bind ok");
681 return HDF_SUCCESS;
682 ERROR:
683 OsalMemFree(usbNet);
684 return HDF_SUCCESS;
685 }
686
HostRndisDriverInit(struct HdfDeviceObject *device)687 static int32_t HostRndisDriverInit(struct HdfDeviceObject *device)
688 {
689 HARCH_INFO_PRINT("[-cbs-] HostRndisDriverInit begin !");
690 if (device == NULL) {
691 HDF_LOGE("%{public}s: device is null", __func__);
692 return HDF_ERR_INVALID_OBJECT;
693 }
694 int32_t ret = HDF_SUCCESS;
695
696 struct UsbnetHost *usbNet = (struct UsbnetHost *)device->service;
697 //net init
698 ret = UsbnetHostProbe(usbNet);
699 if (ret != HDF_SUCCESS) {
700 HARCH_INFO_PRINT("[-cbs-] UsbnetHostProbe error !");
701 }
702 //usb init
703 return ret;
704 }
705
HostRndisDriverRelease(struct HdfDeviceObject *device)706 static void HostRndisDriverRelease(struct HdfDeviceObject *device)
707 {
708 HARCH_INFO_PRINT();
709 struct UsbPnpNotifyServiceInfo *info = NULL;
710 info = (struct UsbPnpNotifyServiceInfo *)device->priv;
711 if (info != NULL) {
712 HARCH_INFO_PRINT("bus:%{public}d+dev:%{public}d", info->busNum, info->devNum);
713 HARCH_INFO_PRINT("interfaceLength:%{public}d", info->interfaceLength);
714 }
715 struct UsbnetHost *usbNet = (struct UsbnetHost *)device->service;
716 if (usbNet == NULL) {
717 HDF_LOGE("%{public}s: Alloc UsbnetHost memory failed", __func__);
718 return;
719 }
720
721 UsbnetHostRelease(usbNet);
722 usbNet->driverInfo->unbind(usbNet);
723
724 //free momory
725 OsalMemFree(usbNet);
726 return;
727 }
728
729 struct HdfDriverEntry g_hostRndisRawDriverEntry = {
730 .moduleVersion = 1,
731 .moduleName = "usbhost_rndis_rawapi",
732 .Bind = HostRndisDriverBind,
733 .Init = HostRndisDriverInit,
734 .Release = HostRndisDriverRelease,
735 };
736 HDF_INIT(g_hostRndisRawDriverEntry);
737