aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/rndis.c
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2005-04-18 20:39:34 -0400
committerGreg K-H <gregkh@suse.de>2005-04-18 20:39:34 -0400
commit6cdee106e7571751ecc0e9f96606322f88b64a8d (patch)
treeedc75e42c3f3e9bbfecabc12a51b0f6d1bb37930 /drivers/usb/gadget/rndis.c
parent1bc3c9e1e44c2059fe2ffa6ff70ad0a925d7b05f (diff)
[PATCH] usb gadget: ethernet/rndis updates
Updates to the Ethernet/RNDIS gadget driver (mostly for RNDIS): - Fix brown-paper bag goof with RNDIS packet TX ... the wrong length field got set, so Windows would ignore data packets it received. - More consistent handling of CDC output filters (but not yet hooking things up so RNDIS uses the mechanism). - Zerocopy RX for RNDIS packets too (saving CPU cycles). - Use the pre-allocated interrupt/status request and buffer, rather than allocating and freeing one of each every few seconds (which could fail). - Some more "sparse" tweaks, making both dual-speed and single-speed configurations happier. - RNDIS speeds are reported in units of 100bps, not bps. Plus two minor cleanups (whitespace, messaging). Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/rndis.c')
-rw-r--r--drivers/usb/gadget/rndis.c40
1 files changed, 19 insertions, 21 deletions
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 6c5197850edc..7457268d5f28 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -37,6 +37,7 @@
37#include <asm/io.h> 37#include <asm/io.h>
38#include <asm/byteorder.h> 38#include <asm/byteorder.h>
39#include <asm/system.h> 39#include <asm/system.h>
40#include <asm/unaligned.h>
40 41
41 42
42#undef RNDIS_PM 43#undef RNDIS_PM
@@ -165,7 +166,7 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
165 166
166 /* mandatory */ 167 /* mandatory */
167 case OID_GEN_LINK_SPEED: 168 case OID_GEN_LINK_SPEED:
168 DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); 169// DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
169 length = 4; 170 length = 4;
170 if (rndis_per_dev_params [configNr].media_state 171 if (rndis_per_dev_params [configNr].media_state
171 == NDIS_MEDIA_STATE_DISCONNECTED) 172 == NDIS_MEDIA_STATE_DISCONNECTED)
@@ -729,7 +730,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
729 retval = 0; 730 retval = 0;
730 731
731 /* FIXME use these NDIS_PACKET_TYPE_* bitflags to 732 /* FIXME use these NDIS_PACKET_TYPE_* bitflags to
732 * filter packets in hard_start_xmit() 733 * set the cdc_filter; it's not RNDIS-specific
733 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in: 734 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
734 * PROMISCUOUS, DIRECTED, 735 * PROMISCUOUS, DIRECTED,
735 * MULTICAST, ALL_MULTICAST, BROADCAST 736 * MULTICAST, ALL_MULTICAST, BROADCAST
@@ -1194,10 +1195,10 @@ void rndis_add_hdr (struct sk_buff *skb)
1194 return; 1195 return;
1195 header = (void *) skb_push (skb, sizeof *header); 1196 header = (void *) skb_push (skb, sizeof *header);
1196 memset (header, 0, sizeof *header); 1197 memset (header, 0, sizeof *header);
1197 header->MessageType = __constant_cpu_to_le32 (1); 1198 header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
1198 header->MessageLength = cpu_to_le32(skb->len); 1199 header->MessageLength = cpu_to_le32(skb->len);
1199 header->DataOffset = __constant_cpu_to_le32 (36); 1200 header->DataOffset = __constant_cpu_to_le32 (36);
1200 header->OOBDataOffset = cpu_to_le32(skb->len - 44); 1201 header->DataLength = cpu_to_le32(skb->len - sizeof *header);
1201} 1202}
1202 1203
1203void rndis_free_response (int configNr, u8 *buf) 1204void rndis_free_response (int configNr, u8 *buf)
@@ -1253,26 +1254,23 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length)
1253 return r; 1254 return r;
1254} 1255}
1255 1256
1256int rndis_rm_hdr (u8 *buf, u32 *length) 1257int rndis_rm_hdr(struct sk_buff *skb)
1257{ 1258{
1258 u32 i, messageLen, dataOffset; 1259 /* tmp points to a struct rndis_packet_msg_type */
1259 __le32 *tmp; 1260 __le32 *tmp = (void *) skb->data;
1260
1261 tmp = (__le32 *) buf;
1262 1261
1263 if (!buf || !length) return -1; 1262 /* MessageType, MessageLength */
1264 if (le32_to_cpup(tmp++) != 1) return -1; 1263 if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
1265 1264 != get_unaligned(tmp++))
1266 messageLen = le32_to_cpup(tmp++); 1265 return -EINVAL;
1267 dataOffset = le32_to_cpup(tmp++) + 8; 1266 tmp++;
1267
1268 /* DataOffset, DataLength */
1269 if (!skb_pull(skb, le32_to_cpu(get_unaligned(tmp++))
1270 + 8 /* offset of DataOffset */))
1271 return -EOVERFLOW;
1272 skb_trim(skb, le32_to_cpu(get_unaligned(tmp++)));
1268 1273
1269 if (messageLen < dataOffset || messageLen > *length) return -1;
1270
1271 for (i = dataOffset; i < messageLen; i++)
1272 buf [i - dataOffset] = buf [i];
1273
1274 *length = messageLen - dataOffset;
1275
1276 return 0; 1274 return 0;
1277} 1275}
1278 1276