1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
|
/*
* Host Side support for RNDIS Networking Links
* Copyright (C) 2005 by David Brownell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __LINUX_USB_RNDIS_HOST_H
#define __LINUX_USB_RNDIS_HOST_H
/*
* CONTROL uses CDC "encapsulated commands" with funky notifications.
* - control-out: SEND_ENCAPSULATED
* - interrupt-in: RESPONSE_AVAILABLE
* - control-in: GET_ENCAPSULATED
*
* We'll try to ignore the RESPONSE_AVAILABLE notifications.
*
* REVISIT some RNDIS implementations seem to have curious issues still
* to be resolved.
*/
struct rndis_msg_hdr {
__le32 msg_type; /* RNDIS_MSG_* */
__le32 msg_len;
// followed by data that varies between messages
__le32 request_id;
__le32 status;
// ... and more
} __attribute__ ((packed));
/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
#define CONTROL_BUFFER_SIZE 1025
/* RNDIS defines an (absurdly huge) 10 second control timeout,
* but ActiveSync seems to use a more usual 5 second timeout
* (which matches the USB 2.0 spec).
*/
#define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000)
#define ccpu2 __constant_cpu_to_le32
#define RNDIS_MSG_COMPLETION ccpu2(0x80000000)
/* codes for "msg_type" field of rndis messages;
* only the data channel uses packet messages (maybe batched);
* everything else goes on the control channel.
*/
#define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */
#define RNDIS_MSG_INIT ccpu2(0x00000002)
#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
#define RNDIS_MSG_HALT ccpu2(0x00000003)
#define RNDIS_MSG_QUERY ccpu2(0x00000004)
#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
#define RNDIS_MSG_SET ccpu2(0x00000005)
#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
#define RNDIS_MSG_RESET ccpu2(0x00000006)
#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
#define RNDIS_MSG_INDICATE ccpu2(0x00000007)
#define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008)
#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
/* codes for "status" field of completion messages */
#define RNDIS_STATUS_SUCCESS ccpu2(0x00000000)
#define RNDIS_STATUS_FAILURE ccpu2(0xc0000001)
#define RNDIS_STATUS_INVALID_DATA ccpu2(0xc0010015)
#define RNDIS_STATUS_NOT_SUPPORTED ccpu2(0xc00000bb)
#define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b)
#define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c)
/* codes for OID_GEN_PHYSICAL_MEDIUM */
#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED ccpu2(0x00000000)
#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN ccpu2(0x00000001)
#define RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM ccpu2(0x00000002)
#define RNDIS_PHYSICAL_MEDIUM_PHONE_LINE ccpu2(0x00000003)
#define RNDIS_PHYSICAL_MEDIUM_POWER_LINE ccpu2(0x00000004)
#define RNDIS_PHYSICAL_MEDIUM_DSL ccpu2(0x00000005)
#define RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL ccpu2(0x00000006)
#define RNDIS_PHYSICAL_MEDIUM_1394 ccpu2(0x00000007)
#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN ccpu2(0x00000008)
#define RNDIS_PHYSICAL_MEDIUM_MAX ccpu2(0x00000009)
struct rndis_data_hdr {
__le32 msg_type; /* RNDIS_MSG_PACKET */
__le32 msg_len; // rndis_data_hdr + data_len + pad
__le32 data_offset; // 36 -- right after header
__le32 data_len; // ... real packet size
__le32 oob_data_offset; // zero
__le32 oob_data_len; // zero
__le32 num_oob; // zero
__le32 packet_data_offset; // zero
__le32 packet_data_len; // zero
__le32 vc_handle; // zero
__le32 reserved; // zero
} __attribute__ ((packed));
struct rndis_init { /* OUT */
// header and:
__le32 msg_type; /* RNDIS_MSG_INIT */
__le32 msg_len; // 24
__le32 request_id;
__le32 major_version; // of rndis (1.0)
__le32 minor_version;
__le32 max_transfer_size;
} __attribute__ ((packed));
struct rndis_init_c { /* IN */
// header and:
__le32 msg_type; /* RNDIS_MSG_INIT_C */
__le32 msg_len;
__le32 request_id;
__le32 status;
__le32 major_version; // of rndis (1.0)
__le32 minor_version;
__le32 device_flags;
__le32 medium; // zero == 802.3
__le32 max_packets_per_message;
__le32 max_transfer_size;
__le32 packet_alignment; // max 7; (1<<n) bytes
__le32 af_list_offset; // zero
__le32 af_list_size; // zero
} __attribute__ ((packed));
struct rndis_halt { /* OUT (no reply) */
// header and:
__le32 msg_type; /* RNDIS_MSG_HALT */
__le32 msg_len;
__le32 request_id;
} __attribute__ ((packed));
struct rndis_query { /* OUT */
// header and:
__le32 msg_type; /* RNDIS_MSG_QUERY */
__le32 msg_len;
__le32 request_id;
__le32 oid;
__le32 len;
__le32 offset;
/*?*/ __le32 handle; // zero
} __attribute__ ((packed));
struct rndis_query_c { /* IN */
// header and:
__le32 msg_type; /* RNDIS_MSG_QUERY_C */
__le32 msg_len;
__le32 request_id;
__le32 status;
__le32 len;
__le32 offset;
} __attribute__ ((packed));
struct rndis_set { /* OUT */
// header and:
__le32 msg_type; /* RNDIS_MSG_SET */
__le32 msg_len;
__le32 request_id;
__le32 oid;
__le32 len;
__le32 offset;
/*?*/ __le32 handle; // zero
} __attribute__ ((packed));
struct rndis_set_c { /* IN */
// header and:
__le32 msg_type; /* RNDIS_MSG_SET_C */
__le32 msg_len;
__le32 request_id;
__le32 status;
} __attribute__ ((packed));
struct rndis_reset { /* IN */
// header and:
__le32 msg_type; /* RNDIS_MSG_RESET */
__le32 msg_len;
__le32 reserved;
} __attribute__ ((packed));
struct rndis_reset_c { /* OUT */
// header and:
__le32 msg_type; /* RNDIS_MSG_RESET_C */
__le32 msg_len;
__le32 status;
__le32 addressing_lost;
} __attribute__ ((packed));
struct rndis_indicate { /* IN (unrequested) */
// header and:
__le32 msg_type; /* RNDIS_MSG_INDICATE */
__le32 msg_len;
__le32 status;
__le32 length;
__le32 offset;
/**/ __le32 diag_status;
__le32 error_offset;
/**/ __le32 message;
} __attribute__ ((packed));
struct rndis_keepalive { /* OUT (optionally IN) */
// header and:
__le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
__le32 msg_len;
__le32 request_id;
} __attribute__ ((packed));
struct rndis_keepalive_c { /* IN (optionally OUT) */
// header and:
__le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
__le32 msg_len;
__le32 request_id;
__le32 status;
} __attribute__ ((packed));
/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and
* there are gobs more that may optionally be supported. We'll avoid as much
* of that mess as possible.
*/
#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
#define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106)
#define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
#define OID_GEN_PHYSICAL_MEDIUM ccpu2(0x00010202)
/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
#define RNDIS_PACKET_TYPE_DIRECTED ccpu2(0x00000001)
#define RNDIS_PACKET_TYPE_MULTICAST ccpu2(0x00000002)
#define RNDIS_PACKET_TYPE_ALL_MULTICAST ccpu2(0x00000004)
#define RNDIS_PACKET_TYPE_BROADCAST ccpu2(0x00000008)
#define RNDIS_PACKET_TYPE_SOURCE_ROUTING ccpu2(0x00000010)
#define RNDIS_PACKET_TYPE_PROMISCUOUS ccpu2(0x00000020)
#define RNDIS_PACKET_TYPE_SMT ccpu2(0x00000040)
#define RNDIS_PACKET_TYPE_ALL_LOCAL ccpu2(0x00000080)
#define RNDIS_PACKET_TYPE_GROUP ccpu2(0x00001000)
#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL ccpu2(0x00002000)
#define RNDIS_PACKET_TYPE_FUNCTIONAL ccpu2(0x00004000)
#define RNDIS_PACKET_TYPE_MAC_FRAME ccpu2(0x00008000)
/* default filter used with RNDIS devices */
#define RNDIS_DEFAULT_FILTER ( \
RNDIS_PACKET_TYPE_DIRECTED | \
RNDIS_PACKET_TYPE_BROADCAST | \
RNDIS_PACKET_TYPE_ALL_MULTICAST | \
RNDIS_PACKET_TYPE_PROMISCUOUS)
/* Flags to require specific physical medium type for generic_rndis_bind() */
#define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001
#define FLAG_RNDIS_PHYM_WIRELESS 0x0002
extern void rndis_status(struct usbnet *dev, struct urb *urb);
extern int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf);
extern int
generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags);
extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf);
extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
extern struct sk_buff *
rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags);
#endif /* __LINUX_USB_RNDIS_HOST_H */
|