24 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/errno.h>
29 #include <linux/list.h>
31 #include <linux/slab.h>
33 #include <linux/netdevice.h>
36 #include <asm/byteorder.h>
37 #include <asm/unaligned.h>
60 #define RNDIS_MAX_CONFIGS 1
73 static const u32 oid_supported_list[] =
98 #ifdef RNDIS_OPTIONAL_STATS
127 #ifdef RNDIS_OPTIONAL_STATS
148 OID_PNP_CAPABILITIES,
154 OID_PNP_ENABLE_WAKE_UP,
155 OID_PNP_ADD_WAKE_UP_PATTERN,
156 OID_PNP_REMOVE_WAKE_UP_PATTERN,
163 static int gen_ndis_query_resp(
int configNr,
u32 OID,
u8 *
buf,
181 pr_debug(
"query OID %08x value, len %d:\n", OID, buf_len);
182 for (i = 0; i < buf_len; i += 16) {
183 pr_debug(
"%03d: %08x %08x %08x %08x\n", i,
192 outbuf = (
__le32 *)&resp[1];
195 net = rndis_per_dev_params[configNr].
dev;
204 pr_debug(
"%s: RNDIS_OID_GEN_SUPPORTED_LIST\n", __func__);
205 length =
sizeof(oid_supported_list);
206 count = length /
sizeof(
u32);
207 for (i = 0; i <
count; i++)
214 pr_debug(
"%s: RNDIS_OID_GEN_HARDWARE_STATUS\n", __func__);
227 pr_debug(
"%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__);
234 pr_debug(
"%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__);
242 pr_debug(
"%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
243 if (rndis_per_dev_params[configNr].
dev) {
245 rndis_per_dev_params[configNr].dev->mtu);
253 pr_debug(
"%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__);
254 if (rndis_per_dev_params[configNr].media_state
259 rndis_per_dev_params[configNr].speed);
265 pr_debug(
"%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
266 if (rndis_per_dev_params[configNr].dev) {
268 rndis_per_dev_params[configNr].dev->mtu);
275 pr_debug(
"%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
276 if (rndis_per_dev_params[configNr].dev) {
278 rndis_per_dev_params[configNr].dev->mtu);
285 pr_debug(
"%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__);
287 rndis_per_dev_params[configNr].vendorID);
293 pr_debug(
"%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__);
294 if (rndis_per_dev_params[configNr].vendorDescr) {
295 length =
strlen(rndis_per_dev_params[configNr].
298 rndis_per_dev_params[configNr].vendorDescr,
307 pr_debug(
"%s: RNDIS_OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
309 *outbuf = rndis_driver_version;
315 pr_debug(
"%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
322 pr_debug(
"%s: RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
330 pr_debug(
"%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
331 *outbuf =
cpu_to_le32(rndis_per_dev_params[configNr]
337 pr_debug(
"%s: RNDIS_OID_GEN_PHYSICAL_MEDIUM\n", __func__);
347 pr_debug(
"%s: RNDIS_OID_GEN_MAC_OPTIONS\n", __func__);
359 pr_debug(
"%s: RNDIS_OID_GEN_XMIT_OK\n", __func__);
370 pr_debug(
"%s: RNDIS_OID_GEN_RCV_OK\n", __func__);
381 pr_debug(
"%s: RNDIS_OID_GEN_XMIT_ERROR\n", __func__);
391 pr_debug(
"%s: RNDIS_OID_GEN_RCV_ERROR\n", __func__);
400 pr_debug(
"%s: RNDIS_OID_GEN_RCV_NO_BUFFER\n", __func__);
411 pr_debug(
"%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__);
412 if (rndis_per_dev_params[configNr].dev) {
415 rndis_per_dev_params[configNr].host_mac,
423 pr_debug(
"%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__);
424 if (rndis_per_dev_params[configNr].dev) {
427 rndis_per_dev_params [configNr].host_mac,
435 pr_debug(
"%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__);
443 pr_debug(
"%s: RNDIS_OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
450 pr_debug(
"%s: RNDIS_OID_802_3_MAC_OPTIONS\n", __func__);
459 pr_debug(
"%s: RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
468 pr_debug(
"%s: RNDIS_OID_802_3_XMIT_ONE_COLLISION\n", __func__);
475 pr_debug(
"%s: RNDIS_OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
488 r->
length = length +
sizeof(*resp);
493 static int gen_ndis_set_resp(
u8 configNr,
u32 OID,
u8 *buf,
u32 buf_len,
507 pr_debug(
"set OID %08x value, len %d:\n", OID, buf_len);
508 for (i = 0; i < buf_len; i += 16) {
509 pr_debug(
"%03d: %08x %08x %08x %08x\n", i,
517 params = &rndis_per_dev_params[configNr];
528 pr_debug(
"%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER %08x\n",
529 __func__, *params->
filter);
539 if (netif_running(params->
dev))
540 netif_wake_queue(params->
dev);
544 netif_stop_queue(params->
dev);
550 pr_debug(
"%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__);
555 pr_warning(
"%s: set unknown OID 0x%08X, size %d\n",
556 __func__, OID, buf_len);
570 struct rndis_params *params = rndis_per_dev_params + configNr;
606 struct rndis_params *params = rndis_per_dev_params + configNr;
618 r = rndis_add_response(configNr,
646 u32 BufLength, BufOffset;
649 struct rndis_params *params = rndis_per_dev_params + configNr;
660 pr_debug(
"%s: Length: %d\n", __func__, BufLength);
661 pr_debug(
"%s: Offset: %d\n", __func__, BufOffset);
662 pr_debug(
"%s: InfoBuffer: ", __func__);
664 for (i = 0; i < BufLength; i++) {
665 pr_debug(
"%02x ", *(((
u8 *) buf) + i + 8 + BufOffset));
675 ((
u8 *)buf) + 8 + BufOffset, BufLength, r))
688 struct rndis_params *params = rndis_per_dev_params + configNr;
705 static int rndis_keepalive_response(
int configNr,
710 struct rndis_params *params = rndis_per_dev_params + configNr;
732 static int rndis_indicate_status_msg(
int configNr,
u32 status)
736 struct rndis_params *params = rndis_per_dev_params + configNr;
741 r = rndis_add_response(configNr,
761 return rndis_indicate_status_msg(configNr,
769 return rndis_indicate_status_msg(configNr,
797 u32 MsgType, MsgLength;
810 params = &rndis_per_dev_params[configNr];
823 return rndis_init_response(configNr,
832 netif_stop_queue(params->
dev);
837 return rndis_query_response(configNr,
841 return rndis_set_response(configNr,
847 return rndis_reset_response(configNr,
853 pr_debug(
"%s: RNDIS_MSG_KEEPALIVE\n",
855 return rndis_keepalive_response(configNr,
864 pr_warning(
"%s: unknown RNDIS message 0x%08X len %d\n",
865 __func__, MsgType, MsgLength);
882 if (!rndis_per_dev_params[i].
used) {
883 rndis_per_dev_params[
i].
used = 1;
885 rndis_per_dev_params[
i].
v =
v;
886 pr_debug(
"%s: configNr = %d\n", __func__, i);
900 rndis_per_dev_params[configNr].
used = 0;
910 rndis_per_dev_params[configNr].
dev =
dev;
911 rndis_per_dev_params[configNr].
filter = cdc_filter;
919 if (!vendorDescr)
return -1;
930 pr_debug(
"%s: %u %u\n", __func__, medium, speed);
945 header = (
void *)
skb_push(skb,
sizeof(*header));
946 memset(header, 0,
sizeof *header);
959 &(rndis_per_dev_params[configNr].resp_queue))
962 if (r && r->
buf == buf) {
974 if (!length)
return NULL;
977 &(rndis_per_dev_params[configNr].resp_queue))
998 r->
buf = (
u8 *)(r + 1);
1003 &(rndis_per_dev_params[configNr].
resp_queue));
1033 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1035 static int rndis_proc_show(
struct seq_file *
m,
void *
v)
1046 "vendor ID : 0x%08X\n"
1050 switch (param->
state) {
1052 s =
"RNDIS_UNINITIALIZED";
break;
1054 s =
"RNDIS_INITIALIZED";
break;
1056 s =
"RNDIS_DATA_INITIALIZED";
break;
1060 (param->
media_state) ?
"disconnected" :
"connected",
1066 size_t count, loff_t *ppos)
1070 int i, fl_speed = 0;
1072 for (i = 0; i <
count; i++) {
1088 speed = speed * 10 + c -
'0';
1099 if (fl_speed) p->
speed = speed;
1100 else pr_debug(
"%c is not valid\n", c);
1110 static int rndis_proc_open(
struct inode *
inode,
struct file *file)
1117 .open = rndis_proc_open,
1121 .write = rndis_proc_write,
1124 #define NAME_TEMPLATE "driver/rndis-%03d"
1136 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1139 sprintf(name, NAME_TEMPLATE, i);
1142 (
void *)(rndis_per_dev_params + i));
1143 if (!rndis_connect_state[i]) {
1144 pr_debug(
"%s: remove entries", __func__);
1146 sprintf(name, NAME_TEMPLATE, --i);
1154 rndis_per_dev_params[
i].
used = 0;
1158 INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue));
1166 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1171 sprintf(name, NAME_TEMPLATE, i);