^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * RNDIS MSG parser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors: Benedikt Spranger, Pengutronix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Robert Schwebel, Pengutronix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This software was originally developed in conformance with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Microsoft's Remote NDIS Specification License Agreement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Fixed message length bug in init_response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Fixed rndis_rm_hdr length bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Copyright (C) 2004 by David Brownell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * updates to merge with Linux 2.6, better match RNDIS spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "u_rndis.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #undef VERBOSE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "rndis.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* The driver for your USB chip needs to support ep0 OUT to work with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Windows hosts need an INF file like Documentation/usb/linux.inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * and will be happier if you provide the host_addr module parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int rndis_debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) module_param (rndis_debug, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MODULE_PARM_DESC (rndis_debug, "enable debugging");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define rndis_debug 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #ifdef CONFIG_USB_GADGET_DEBUG_FILES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define NAME_TEMPLATE "driver/rndis-%03d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static DEFINE_IDA(rndis_ida);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static DEFINE_SPINLOCK(resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Driver Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static const __le32 rndis_driver_version = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Function Prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static rndis_resp_t *rndis_add_response(struct rndis_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u32 length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #ifdef CONFIG_USB_GADGET_DEBUG_FILES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static const struct proc_ops rndis_proc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* supported OIDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static const u32 oid_supported_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* the general stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) RNDIS_OID_GEN_SUPPORTED_LIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) RNDIS_OID_GEN_HARDWARE_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) RNDIS_OID_GEN_MEDIA_SUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) RNDIS_OID_GEN_MEDIA_IN_USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) RNDIS_OID_GEN_LINK_SPEED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) RNDIS_OID_GEN_VENDOR_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) RNDIS_OID_GEN_VENDOR_DESCRIPTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) RNDIS_OID_GEN_VENDOR_DRIVER_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) RNDIS_OID_GEN_PHYSICAL_MEDIUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* the statistical stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) RNDIS_OID_GEN_XMIT_OK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) RNDIS_OID_GEN_RCV_OK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) RNDIS_OID_GEN_XMIT_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) RNDIS_OID_GEN_RCV_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) RNDIS_OID_GEN_RCV_NO_BUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #ifdef RNDIS_OPTIONAL_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) RNDIS_OID_GEN_DIRECTED_BYTES_XMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) RNDIS_OID_GEN_MULTICAST_BYTES_XMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) RNDIS_OID_GEN_BROADCAST_BYTES_XMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) RNDIS_OID_GEN_DIRECTED_BYTES_RCV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) RNDIS_OID_GEN_DIRECTED_FRAMES_RCV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) RNDIS_OID_GEN_MULTICAST_BYTES_RCV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) RNDIS_OID_GEN_MULTICAST_FRAMES_RCV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) RNDIS_OID_GEN_BROADCAST_BYTES_RCV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) RNDIS_OID_GEN_BROADCAST_FRAMES_RCV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) RNDIS_OID_GEN_RCV_CRC_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #endif /* RNDIS_OPTIONAL_STATS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* mandatory 802.3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* the general stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) RNDIS_OID_802_3_PERMANENT_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) RNDIS_OID_802_3_CURRENT_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) RNDIS_OID_802_3_MULTICAST_LIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) RNDIS_OID_802_3_MAC_OPTIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) RNDIS_OID_802_3_MAXIMUM_LIST_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* the statistical stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) RNDIS_OID_802_3_XMIT_ONE_COLLISION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) RNDIS_OID_802_3_XMIT_MORE_COLLISIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #ifdef RNDIS_OPTIONAL_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) RNDIS_OID_802_3_XMIT_DEFERRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) RNDIS_OID_802_3_XMIT_MAX_COLLISIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) RNDIS_OID_802_3_RCV_OVERRUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) RNDIS_OID_802_3_XMIT_UNDERRUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) RNDIS_OID_802_3_XMIT_LATE_COLLISIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #endif /* RNDIS_OPTIONAL_STATS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #ifdef RNDIS_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* PM and wakeup are "mandatory" for USB, but the RNDIS specs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * don't say what they mean ... and the NDIS specs are often
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * confusing and/or ambiguous in this context. (That is, more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * so than their specs for the other OIDs.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * FIXME someone who knows what these should do, please
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * implement them!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* power management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) OID_PNP_CAPABILITIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) OID_PNP_QUERY_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) OID_PNP_SET_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #ifdef RNDIS_WAKEUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* wake up host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) OID_PNP_ENABLE_WAKE_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) OID_PNP_ADD_WAKE_UP_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) OID_PNP_REMOVE_WAKE_UP_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #endif /* RNDIS_WAKEUP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #endif /* RNDIS_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* NDIS Functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static int gen_ndis_query_resp(struct rndis_params *params, u32 OID, u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned buf_len, rndis_resp_t *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int retval = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 length = 4; /* usually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) __le32 *outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int i, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) rndis_query_cmplt_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct net_device *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct rtnl_link_stats64 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) const struct rtnl_link_stats64 *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!r) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) resp = (rndis_query_cmplt_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!resp) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (buf_len && rndis_debug > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) pr_debug("query OID %08x value, len %d:\n", OID, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) for (i = 0; i < buf_len; i += 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) pr_debug("%03d: %08x %08x %08x %08x\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) get_unaligned_le32(&buf[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) get_unaligned_le32(&buf[i + 4]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) get_unaligned_le32(&buf[i + 8]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) get_unaligned_le32(&buf[i + 12]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* response goes here, right after the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) outbuf = (__le32 *)&resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) resp->InformationBufferOffset = cpu_to_le32(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) net = params->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) stats = dev_get_stats(net, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) switch (OID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* general oids (table 4-1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case RNDIS_OID_GEN_SUPPORTED_LIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pr_debug("%s: RNDIS_OID_GEN_SUPPORTED_LIST\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) length = sizeof(oid_supported_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) count = length / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) for (i = 0; i < count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) outbuf[i] = cpu_to_le32(oid_supported_list[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case RNDIS_OID_GEN_HARDWARE_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pr_debug("%s: RNDIS_OID_GEN_HARDWARE_STATUS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Bogus question!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * Hardware must be ready to receive high level protocols.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * BTW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * reddite ergo quae sunt Caesaris Caesari
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * et quae sunt Dei Deo!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *outbuf = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case RNDIS_OID_GEN_MEDIA_SUPPORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) pr_debug("%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *outbuf = cpu_to_le32(params->medium);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case RNDIS_OID_GEN_MEDIA_IN_USE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pr_debug("%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* one medium, one transport... (maybe you do it better) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *outbuf = cpu_to_le32(params->medium);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (params->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *outbuf = cpu_to_le32(params->dev->mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case RNDIS_OID_GEN_LINK_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (rndis_debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) pr_debug("%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (params->media_state == RNDIS_MEDIA_STATE_DISCONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *outbuf = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *outbuf = cpu_to_le32(params->speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pr_debug("%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (params->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *outbuf = cpu_to_le32(params->dev->mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) pr_debug("%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (params->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *outbuf = cpu_to_le32(params->dev->mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case RNDIS_OID_GEN_VENDOR_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pr_debug("%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) *outbuf = cpu_to_le32(params->vendorID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case RNDIS_OID_GEN_VENDOR_DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) pr_debug("%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (params->vendorDescr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) length = strlen(params->vendorDescr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) memcpy(outbuf, params->vendorDescr, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) outbuf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case RNDIS_OID_GEN_VENDOR_DRIVER_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pr_debug("%s: RNDIS_OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Created as LE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *outbuf = rndis_driver_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case RNDIS_OID_GEN_CURRENT_PACKET_FILTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *outbuf = cpu_to_le32(*params->filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) case RNDIS_OID_GEN_MEDIA_CONNECT_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (rndis_debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) pr_debug("%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *outbuf = cpu_to_le32(params->media_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case RNDIS_OID_GEN_PHYSICAL_MEDIUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) pr_debug("%s: RNDIS_OID_GEN_PHYSICAL_MEDIUM\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *outbuf = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* The RNDIS specification is incomplete/wrong. Some versions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * of MS-Windows expect OIDs that aren't specified there. Other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case RNDIS_OID_GEN_MAC_OPTIONS: /* from WinME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) pr_debug("%s: RNDIS_OID_GEN_MAC_OPTIONS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *outbuf = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) RNDIS_MAC_OPTION_RECEIVE_SERIALIZED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) | RNDIS_MAC_OPTION_FULL_DUPLEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* statistics OIDs (table 4-2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case RNDIS_OID_GEN_XMIT_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (rndis_debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pr_debug("%s: RNDIS_OID_GEN_XMIT_OK\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *outbuf = cpu_to_le32(stats->tx_packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) - stats->tx_errors - stats->tx_dropped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case RNDIS_OID_GEN_RCV_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (rndis_debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pr_debug("%s: RNDIS_OID_GEN_RCV_OK\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *outbuf = cpu_to_le32(stats->rx_packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) - stats->rx_errors - stats->rx_dropped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case RNDIS_OID_GEN_XMIT_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (rndis_debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) pr_debug("%s: RNDIS_OID_GEN_XMIT_ERROR\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *outbuf = cpu_to_le32(stats->tx_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) case RNDIS_OID_GEN_RCV_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (rndis_debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pr_debug("%s: RNDIS_OID_GEN_RCV_ERROR\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) *outbuf = cpu_to_le32(stats->rx_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) case RNDIS_OID_GEN_RCV_NO_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) pr_debug("%s: RNDIS_OID_GEN_RCV_NO_BUFFER\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *outbuf = cpu_to_le32(stats->rx_dropped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* ieee802.3 OIDs (table 4-3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case RNDIS_OID_802_3_PERMANENT_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) pr_debug("%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (params->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) length = ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) memcpy(outbuf, params->host_mac, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case RNDIS_OID_802_3_CURRENT_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pr_debug("%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (params->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) length = ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) memcpy(outbuf, params->host_mac, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case RNDIS_OID_802_3_MULTICAST_LIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* Multicast base address only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) *outbuf = cpu_to_le32(0xE0000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) case RNDIS_OID_802_3_MAXIMUM_LIST_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pr_debug("%s: RNDIS_OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* Multicast base address only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) *outbuf = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case RNDIS_OID_802_3_MAC_OPTIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pr_debug("%s: RNDIS_OID_802_3_MAC_OPTIONS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) *outbuf = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* ieee802.3 statistics OIDs (table 4-4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) case RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pr_debug("%s: RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) *outbuf = cpu_to_le32(stats->rx_frame_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case RNDIS_OID_802_3_XMIT_ONE_COLLISION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pr_debug("%s: RNDIS_OID_802_3_XMIT_ONE_COLLISION\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *outbuf = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* mandatory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) case RNDIS_OID_802_3_XMIT_MORE_COLLISIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) pr_debug("%s: RNDIS_OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) *outbuf = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) pr_warn("%s: query unknown OID 0x%08X\n", __func__, OID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) resp->InformationBufferLength = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) r->length = length + sizeof(*resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) resp->MessageLength = cpu_to_le32(r->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static int gen_ndis_set_resp(struct rndis_params *params, u32 OID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u8 *buf, u32 buf_len, rndis_resp_t *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) rndis_set_cmplt_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int i, retval = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) resp = (rndis_set_cmplt_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (buf_len && rndis_debug > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) pr_debug("set OID %08x value, len %d:\n", OID, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) for (i = 0; i < buf_len; i += 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) pr_debug("%03d: %08x %08x %08x %08x\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) get_unaligned_le32(&buf[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) get_unaligned_le32(&buf[i + 4]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) get_unaligned_le32(&buf[i + 8]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) get_unaligned_le32(&buf[i + 12]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) switch (OID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) case RNDIS_OID_GEN_CURRENT_PACKET_FILTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* these NDIS_PACKET_TYPE_* bitflags are shared with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * cdc_filter; it's not RNDIS-specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * PROMISCUOUS, DIRECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * MULTICAST, ALL_MULTICAST, BROADCAST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *params->filter = (u16)get_unaligned_le32(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) __func__, *params->filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* this call has a significant side effect: it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * what makes the packet flow start and stop, like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * activating the CDC Ethernet altsetting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (*params->filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) params->state = RNDIS_DATA_INITIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) netif_carrier_on(params->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (netif_running(params->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) netif_wake_queue(params->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) params->state = RNDIS_INITIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) netif_carrier_off(params->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) netif_stop_queue(params->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) case RNDIS_OID_802_3_MULTICAST_LIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* I think we can ignore this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) pr_warn("%s: set unknown OID 0x%08X, size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) __func__, OID, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * Response Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int rndis_init_response(struct rndis_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) rndis_init_msg_type *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) rndis_init_cmplt_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) rndis_resp_t *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!params->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) r = rndis_add_response(params, sizeof(rndis_init_cmplt_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) resp = (rndis_init_cmplt_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) resp->MessageType = cpu_to_le32(RNDIS_MSG_INIT_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) resp->MessageLength = cpu_to_le32(52);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) resp->MaxPacketsPerTransfer = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) resp->MaxTransferSize = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) params->dev->mtu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) + sizeof(struct ethhdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) + sizeof(struct rndis_packet_msg_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) + 22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) resp->PacketAlignmentFactor = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) resp->AFListOffset = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) resp->AFListSize = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) params->resp_avail(params->v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int rndis_query_response(struct rndis_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) rndis_query_msg_type *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) rndis_query_cmplt_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) rndis_resp_t *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (!params->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * we need more memory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * gen_ndis_query_resp expects enough space for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * rndis_query_cmplt_type followed by data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * oid_supported_list is the largest data reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) r = rndis_add_response(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) resp = (rndis_query_cmplt_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) resp->MessageType = cpu_to_le32(RNDIS_MSG_QUERY_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (gen_ndis_query_resp(params, le32_to_cpu(buf->OID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) le32_to_cpu(buf->InformationBufferOffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) + 8 + (u8 *)buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) le32_to_cpu(buf->InformationBufferLength),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* OID not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) resp->MessageLength = cpu_to_le32(sizeof *resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) resp->InformationBufferLength = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) resp->InformationBufferOffset = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) params->resp_avail(params->v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int rndis_set_response(struct rndis_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) rndis_set_msg_type *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) u32 BufLength, BufOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) rndis_set_cmplt_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) rndis_resp_t *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) BufLength = le32_to_cpu(buf->InformationBufferLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) BufOffset = le32_to_cpu(buf->InformationBufferOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if ((BufLength > RNDIS_MAX_TOTAL_SIZE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) (BufOffset > RNDIS_MAX_TOTAL_SIZE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) r = rndis_add_response(params, sizeof(rndis_set_cmplt_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) resp = (rndis_set_cmplt_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) #ifdef VERBOSE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) pr_debug("%s: Length: %d\n", __func__, BufLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) pr_debug("%s: Offset: %d\n", __func__, BufOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) pr_debug("%s: InfoBuffer: ", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) for (i = 0; i < BufLength; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) resp->MessageType = cpu_to_le32(RNDIS_MSG_SET_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) resp->MessageLength = cpu_to_le32(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (gen_ndis_set_resp(params, le32_to_cpu(buf->OID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ((u8 *)buf) + 8 + BufOffset, BufLength, r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) params->resp_avail(params->v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static int rndis_reset_response(struct rndis_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) rndis_reset_msg_type *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) rndis_reset_cmplt_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) rndis_resp_t *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) u8 *xbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* drain the response queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) while ((xbuf = rndis_get_next_response(params, &length)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) rndis_free_response(params, xbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) r = rndis_add_response(params, sizeof(rndis_reset_cmplt_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) resp = (rndis_reset_cmplt_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) resp->MessageType = cpu_to_le32(RNDIS_MSG_RESET_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) resp->MessageLength = cpu_to_le32(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* resent information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) resp->AddressingReset = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) params->resp_avail(params->v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int rndis_keepalive_response(struct rndis_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) rndis_keepalive_msg_type *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) rndis_keepalive_cmplt_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) rndis_resp_t *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /* host "should" check only in RNDIS_DATA_INITIALIZED state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) r = rndis_add_response(params, sizeof(rndis_keepalive_cmplt_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) resp = (rndis_keepalive_cmplt_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) resp->MessageType = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) resp->MessageLength = cpu_to_le32(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) params->resp_avail(params->v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * Device to Host Comunication
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int rndis_indicate_status_msg(struct rndis_params *params, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) rndis_indicate_status_msg_type *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) rndis_resp_t *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (params->state == RNDIS_UNINITIALIZED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) r = rndis_add_response(params, sizeof(rndis_indicate_status_msg_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) resp = (rndis_indicate_status_msg_type *)r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) resp->MessageType = cpu_to_le32(RNDIS_MSG_INDICATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) resp->MessageLength = cpu_to_le32(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) resp->Status = cpu_to_le32(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) resp->StatusBufferLength = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) resp->StatusBufferOffset = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) params->resp_avail(params->v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int rndis_signal_connect(struct rndis_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) params->media_state = RNDIS_MEDIA_STATE_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return rndis_indicate_status_msg(params, RNDIS_STATUS_MEDIA_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) EXPORT_SYMBOL_GPL(rndis_signal_connect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int rndis_signal_disconnect(struct rndis_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) params->media_state = RNDIS_MEDIA_STATE_DISCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return rndis_indicate_status_msg(params, RNDIS_STATUS_MEDIA_DISCONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) EXPORT_SYMBOL_GPL(rndis_signal_disconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) void rndis_uninit(struct rndis_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (!params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) params->state = RNDIS_UNINITIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* drain the response queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) while ((buf = rndis_get_next_response(params, &length)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) rndis_free_response(params, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) EXPORT_SYMBOL_GPL(rndis_uninit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) void rndis_set_host_mac(struct rndis_params *params, const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) params->host_mac = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) EXPORT_SYMBOL_GPL(rndis_set_host_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * Message Parser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int rndis_msg_parser(struct rndis_params *params, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) u32 MsgType, MsgLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) __le32 *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) tmp = (__le32 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) MsgType = get_unaligned_le32(tmp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) MsgLength = get_unaligned_le32(tmp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (!params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * rx/tx statistics and link status, in addition to KEEPALIVE traffic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * and normal HC level polling to see if there's any IN traffic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* For USB: responses may take up to 10 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) switch (MsgType) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case RNDIS_MSG_INIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) pr_debug("%s: RNDIS_MSG_INIT\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) params->state = RNDIS_INITIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return rndis_init_response(params, (rndis_init_msg_type *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) case RNDIS_MSG_HALT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) pr_debug("%s: RNDIS_MSG_HALT\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) params->state = RNDIS_UNINITIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (params->dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) netif_carrier_off(params->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) netif_stop_queue(params->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) case RNDIS_MSG_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return rndis_query_response(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) (rndis_query_msg_type *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case RNDIS_MSG_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return rndis_set_response(params, (rndis_set_msg_type *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case RNDIS_MSG_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pr_debug("%s: RNDIS_MSG_RESET\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return rndis_reset_response(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) (rndis_reset_msg_type *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) case RNDIS_MSG_KEEPALIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /* For USB: host does this every 5 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (rndis_debug > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) pr_debug("%s: RNDIS_MSG_KEEPALIVE\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return rndis_keepalive_response(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) (rndis_keepalive_msg_type *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) /* At least Windows XP emits some undefined RNDIS messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * In one case those messages seemed to relate to the host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * suspending itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) pr_warn("%s: unknown RNDIS message 0x%08X len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) __func__, MsgType, MsgLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* Garbled message can be huge, so limit what we display */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (MsgLength > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) MsgLength = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) print_hex_dump_bytes(__func__, DUMP_PREFIX_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) buf, MsgLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) EXPORT_SYMBOL_GPL(rndis_msg_parser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) static inline int rndis_get_nr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return ida_simple_get(&rndis_ida, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static inline void rndis_put_nr(int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) ida_simple_remove(&rndis_ida, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct rndis_params *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (!resp_avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) i = rndis_get_nr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) pr_debug("failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) params = kzalloc(sizeof(*params), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (!params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) rndis_put_nr(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) #ifdef CONFIG_USB_GADGET_DEBUG_FILES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct proc_dir_entry *proc_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) char name[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) sprintf(name, NAME_TEMPLATE, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) proc_entry = proc_create_data(name, 0660, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) &rndis_proc_ops, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (!proc_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) kfree(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) rndis_put_nr(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) params->confignr = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) params->used = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) params->state = RNDIS_UNINITIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) params->media_state = RNDIS_MEDIA_STATE_DISCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) params->resp_avail = resp_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) params->v = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) INIT_LIST_HEAD(¶ms->resp_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) pr_debug("%s: configNr = %d\n", __func__, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) EXPORT_SYMBOL_GPL(rndis_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) void rndis_deregister(struct rndis_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) pr_debug("%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) i = params->confignr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) #ifdef CONFIG_USB_GADGET_DEBUG_FILES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) char name[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) sprintf(name, NAME_TEMPLATE, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) remove_proc_entry(name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) kfree(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) rndis_put_nr(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) EXPORT_SYMBOL_GPL(rndis_deregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) int rndis_set_param_dev(struct rndis_params *params, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) u16 *cdc_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) pr_debug("%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) params->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) params->filter = cdc_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) EXPORT_SYMBOL_GPL(rndis_set_param_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) int rndis_set_param_vendor(struct rndis_params *params, u32 vendorID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) const char *vendorDescr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) pr_debug("%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (!vendorDescr) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) params->vendorID = vendorID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) params->vendorDescr = vendorDescr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) EXPORT_SYMBOL_GPL(rndis_set_param_vendor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) int rndis_set_param_medium(struct rndis_params *params, u32 medium, u32 speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) pr_debug("%s: %u %u\n", __func__, medium, speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (!params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) params->medium = medium;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) params->speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) EXPORT_SYMBOL_GPL(rndis_set_param_medium);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) void rndis_add_hdr(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct rndis_packet_msg_type *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) header = skb_push(skb, sizeof(*header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) memset(header, 0, sizeof *header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) header->MessageType = cpu_to_le32(RNDIS_MSG_PACKET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) header->MessageLength = cpu_to_le32(skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) header->DataOffset = cpu_to_le32(36);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) header->DataLength = cpu_to_le32(skb->len - sizeof(*header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) EXPORT_SYMBOL_GPL(rndis_add_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) void rndis_free_response(struct rndis_params *params, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) rndis_resp_t *r, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) spin_lock(&resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (r->buf == buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) list_del(&r->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) kfree(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) spin_unlock(&resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) EXPORT_SYMBOL_GPL(rndis_free_response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) u8 *rndis_get_next_response(struct rndis_params *params, u32 *length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) rndis_resp_t *r, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (!length) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) spin_lock(&resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) list_for_each_entry_safe(r, n, ¶ms->resp_queue, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (!r->send) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) r->send = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) *length = r->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) spin_unlock(&resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return r->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) spin_unlock(&resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) EXPORT_SYMBOL_GPL(rndis_get_next_response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static rndis_resp_t *rndis_add_response(struct rndis_params *params, u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) rndis_resp_t *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) r = kmalloc(sizeof(rndis_resp_t) + length, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (!r) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) r->buf = (u8 *)(r + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) r->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) r->send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) spin_lock(&resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) list_add_tail(&r->list, ¶ms->resp_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) spin_unlock(&resp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) int rndis_rm_hdr(struct gether *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct sk_buff_head *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /* tmp points to a struct rndis_packet_msg_type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) __le32 *tmp = (void *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* MessageType, MessageLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (cpu_to_le32(RNDIS_MSG_PACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) != get_unaligned(tmp++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) tmp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) /* DataOffset, DataLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (!skb_pull(skb, get_unaligned_le32(tmp++) + 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) skb_trim(skb, get_unaligned_le32(tmp++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) skb_queue_tail(list, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) EXPORT_SYMBOL_GPL(rndis_rm_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) #ifdef CONFIG_USB_GADGET_DEBUG_FILES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static int rndis_proc_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) rndis_params *param = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) "Config Nr. %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) "used : %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) "state : %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) "medium : 0x%08X\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) "speed : %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) "cable : %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) "vendor ID : 0x%08X\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) "vendor : %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) param->confignr, (param->used) ? "y" : "n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) ({ char *s = "?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) switch (param->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case RNDIS_UNINITIALIZED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) s = "RNDIS_UNINITIALIZED"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) case RNDIS_INITIALIZED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) s = "RNDIS_INITIALIZED"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) case RNDIS_DATA_INITIALIZED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) s = "RNDIS_DATA_INITIALIZED"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) } s; }),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) param->medium,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) (param->media_state) ? 0 : param->speed*100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) (param->media_state) ? "disconnected" : "connected",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) param->vendorID, param->vendorDescr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) rndis_params *p = PDE_DATA(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) u32 speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) int i, fl_speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (get_user(c, buffer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) case '0':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) case '1':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) case '2':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) case '3':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) case '4':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) case '5':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) case '6':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) case '7':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) case '8':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) case '9':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) fl_speed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) speed = speed * 10 + c - '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) rndis_signal_connect(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) case 'D':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) rndis_signal_disconnect(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (fl_speed) p->speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) else pr_debug("%c is not valid\n", c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) buffer++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) static int rndis_proc_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return single_open(file, rndis_proc_show, PDE_DATA(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) static const struct proc_ops rndis_proc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) .proc_open = rndis_proc_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) .proc_read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .proc_lseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) .proc_release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) .proc_write = rndis_proc_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) #define NAME_TEMPLATE "driver/rndis-%03d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) #endif /* CONFIG_USB_GADGET_DEBUG_FILES */