1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Host Side support for RNDIS Networking Links 4*4882a593Smuzhiyun * Copyright (C) 2005 by David Brownell 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify 7*4882a593Smuzhiyun * it under the terms of the GNU General Public License as published by 8*4882a593Smuzhiyun * the Free Software Foundation; either version 2 of the License, or 9*4882a593Smuzhiyun * (at your option) any later version. 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 12*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*4882a593Smuzhiyun * GNU General Public License for more details. 15*4882a593Smuzhiyun * 16*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License 17*4882a593Smuzhiyun * along with this program; if not, write to the Free Software 18*4882a593Smuzhiyun * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19*4882a593Smuzhiyun */ 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun #ifndef __LINUX_USB_RNDIS_HOST_H 22*4882a593Smuzhiyun #define __LINUX_USB_RNDIS_HOST_H 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #include <linux/rndis.h> 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun /* 27*4882a593Smuzhiyun * CONTROL uses CDC "encapsulated commands" with funky notifications. 28*4882a593Smuzhiyun * - control-out: SEND_ENCAPSULATED 29*4882a593Smuzhiyun * - interrupt-in: RESPONSE_AVAILABLE 30*4882a593Smuzhiyun * - control-in: GET_ENCAPSULATED 31*4882a593Smuzhiyun * 32*4882a593Smuzhiyun * We'll try to ignore the RESPONSE_AVAILABLE notifications. 33*4882a593Smuzhiyun * 34*4882a593Smuzhiyun * REVISIT some RNDIS implementations seem to have curious issues still 35*4882a593Smuzhiyun * to be resolved. 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun struct rndis_msg_hdr { 38*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_* */ 39*4882a593Smuzhiyun __le32 msg_len; 40*4882a593Smuzhiyun /* followed by data that varies between messages */ 41*4882a593Smuzhiyun __le32 request_id; 42*4882a593Smuzhiyun __le32 status; 43*4882a593Smuzhiyun /* ... and more */ 44*4882a593Smuzhiyun } __attribute__ ((packed)); 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun /* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */ 47*4882a593Smuzhiyun #define CONTROL_BUFFER_SIZE 1025 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /* RNDIS defines an (absurdly huge) 10 second control timeout, 50*4882a593Smuzhiyun * but ActiveSync seems to use a more usual 5 second timeout 51*4882a593Smuzhiyun * (which matches the USB 2.0 spec). 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun #define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000) 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun struct rndis_data_hdr { 56*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_PACKET */ 57*4882a593Smuzhiyun __le32 msg_len; /* rndis_data_hdr + data_len + pad */ 58*4882a593Smuzhiyun __le32 data_offset; /* 36 -- right after header */ 59*4882a593Smuzhiyun __le32 data_len; /* ... real packet size */ 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun __le32 oob_data_offset; /* zero */ 62*4882a593Smuzhiyun __le32 oob_data_len; /* zero */ 63*4882a593Smuzhiyun __le32 num_oob; /* zero */ 64*4882a593Smuzhiyun __le32 packet_data_offset; /* zero */ 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun __le32 packet_data_len; /* zero */ 67*4882a593Smuzhiyun __le32 vc_handle; /* zero */ 68*4882a593Smuzhiyun __le32 reserved; /* zero */ 69*4882a593Smuzhiyun } __attribute__ ((packed)); 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun struct rndis_init { /* OUT */ 72*4882a593Smuzhiyun /* header and: */ 73*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_INIT */ 74*4882a593Smuzhiyun __le32 msg_len; /* 24 */ 75*4882a593Smuzhiyun __le32 request_id; 76*4882a593Smuzhiyun __le32 major_version; /* of rndis (1.0) */ 77*4882a593Smuzhiyun __le32 minor_version; 78*4882a593Smuzhiyun __le32 max_transfer_size; 79*4882a593Smuzhiyun } __attribute__ ((packed)); 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun struct rndis_init_c { /* IN */ 82*4882a593Smuzhiyun /* header and: */ 83*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_INIT_C */ 84*4882a593Smuzhiyun __le32 msg_len; 85*4882a593Smuzhiyun __le32 request_id; 86*4882a593Smuzhiyun __le32 status; 87*4882a593Smuzhiyun __le32 major_version; /* of rndis (1.0) */ 88*4882a593Smuzhiyun __le32 minor_version; 89*4882a593Smuzhiyun __le32 device_flags; 90*4882a593Smuzhiyun __le32 medium; /* zero == 802.3 */ 91*4882a593Smuzhiyun __le32 max_packets_per_message; 92*4882a593Smuzhiyun __le32 max_transfer_size; 93*4882a593Smuzhiyun __le32 packet_alignment; /* max 7; (1<<n) bytes */ 94*4882a593Smuzhiyun __le32 af_list_offset; /* zero */ 95*4882a593Smuzhiyun __le32 af_list_size; /* zero */ 96*4882a593Smuzhiyun } __attribute__ ((packed)); 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun struct rndis_halt { /* OUT (no reply) */ 99*4882a593Smuzhiyun /* header and: */ 100*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_HALT */ 101*4882a593Smuzhiyun __le32 msg_len; 102*4882a593Smuzhiyun __le32 request_id; 103*4882a593Smuzhiyun } __attribute__ ((packed)); 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun struct rndis_query { /* OUT */ 106*4882a593Smuzhiyun /* header and: */ 107*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_QUERY */ 108*4882a593Smuzhiyun __le32 msg_len; 109*4882a593Smuzhiyun __le32 request_id; 110*4882a593Smuzhiyun __le32 oid; 111*4882a593Smuzhiyun __le32 len; 112*4882a593Smuzhiyun __le32 offset; 113*4882a593Smuzhiyun /*?*/ __le32 handle; /* zero */ 114*4882a593Smuzhiyun } __attribute__ ((packed)); 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun struct rndis_query_c { /* IN */ 117*4882a593Smuzhiyun /* header and: */ 118*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_QUERY_C */ 119*4882a593Smuzhiyun __le32 msg_len; 120*4882a593Smuzhiyun __le32 request_id; 121*4882a593Smuzhiyun __le32 status; 122*4882a593Smuzhiyun __le32 len; 123*4882a593Smuzhiyun __le32 offset; 124*4882a593Smuzhiyun } __attribute__ ((packed)); 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun struct rndis_set { /* OUT */ 127*4882a593Smuzhiyun /* header and: */ 128*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_SET */ 129*4882a593Smuzhiyun __le32 msg_len; 130*4882a593Smuzhiyun __le32 request_id; 131*4882a593Smuzhiyun __le32 oid; 132*4882a593Smuzhiyun __le32 len; 133*4882a593Smuzhiyun __le32 offset; 134*4882a593Smuzhiyun /*?*/ __le32 handle; /* zero */ 135*4882a593Smuzhiyun } __attribute__ ((packed)); 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun struct rndis_set_c { /* IN */ 138*4882a593Smuzhiyun /* header and: */ 139*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_SET_C */ 140*4882a593Smuzhiyun __le32 msg_len; 141*4882a593Smuzhiyun __le32 request_id; 142*4882a593Smuzhiyun __le32 status; 143*4882a593Smuzhiyun } __attribute__ ((packed)); 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun struct rndis_reset { /* IN */ 146*4882a593Smuzhiyun /* header and: */ 147*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_RESET */ 148*4882a593Smuzhiyun __le32 msg_len; 149*4882a593Smuzhiyun __le32 reserved; 150*4882a593Smuzhiyun } __attribute__ ((packed)); 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun struct rndis_reset_c { /* OUT */ 153*4882a593Smuzhiyun /* header and: */ 154*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_RESET_C */ 155*4882a593Smuzhiyun __le32 msg_len; 156*4882a593Smuzhiyun __le32 status; 157*4882a593Smuzhiyun __le32 addressing_lost; 158*4882a593Smuzhiyun } __attribute__ ((packed)); 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun struct rndis_indicate { /* IN (unrequested) */ 161*4882a593Smuzhiyun /* header and: */ 162*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_INDICATE */ 163*4882a593Smuzhiyun __le32 msg_len; 164*4882a593Smuzhiyun __le32 status; 165*4882a593Smuzhiyun __le32 length; 166*4882a593Smuzhiyun __le32 offset; 167*4882a593Smuzhiyun /**/ __le32 diag_status; 168*4882a593Smuzhiyun __le32 error_offset; 169*4882a593Smuzhiyun /**/ __le32 message; 170*4882a593Smuzhiyun } __attribute__ ((packed)); 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun struct rndis_keepalive { /* OUT (optionally IN) */ 173*4882a593Smuzhiyun /* header and: */ 174*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_KEEPALIVE */ 175*4882a593Smuzhiyun __le32 msg_len; 176*4882a593Smuzhiyun __le32 request_id; 177*4882a593Smuzhiyun } __attribute__ ((packed)); 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun struct rndis_keepalive_c { /* IN (optionally OUT) */ 180*4882a593Smuzhiyun /* header and: */ 181*4882a593Smuzhiyun __le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */ 182*4882a593Smuzhiyun __le32 msg_len; 183*4882a593Smuzhiyun __le32 request_id; 184*4882a593Smuzhiyun __le32 status; 185*4882a593Smuzhiyun } __attribute__ ((packed)); 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun /* default filter used with RNDIS devices */ 188*4882a593Smuzhiyun #define RNDIS_DEFAULT_FILTER ( \ 189*4882a593Smuzhiyun RNDIS_PACKET_TYPE_DIRECTED | \ 190*4882a593Smuzhiyun RNDIS_PACKET_TYPE_BROADCAST | \ 191*4882a593Smuzhiyun RNDIS_PACKET_TYPE_ALL_MULTICAST | \ 192*4882a593Smuzhiyun RNDIS_PACKET_TYPE_PROMISCUOUS) 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun /* Flags to require specific physical medium type for generic_rndis_bind() */ 195*4882a593Smuzhiyun #define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001 196*4882a593Smuzhiyun #define FLAG_RNDIS_PHYM_WIRELESS 0x0002 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun /* Flags for driver_info::data */ 199*4882a593Smuzhiyun #define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */ 200*4882a593Smuzhiyun 201*4882a593Smuzhiyun extern void rndis_status(struct usbnet *dev, struct urb *urb); 202*4882a593Smuzhiyun extern int 203*4882a593Smuzhiyun rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen); 204*4882a593Smuzhiyun extern int 205*4882a593Smuzhiyun generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags); 206*4882a593Smuzhiyun extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf); 207*4882a593Smuzhiyun extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb); 208*4882a593Smuzhiyun extern struct sk_buff * 209*4882a593Smuzhiyun rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags); 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun #endif /* __LINUX_USB_RNDIS_HOST_H */ 212