--- zzzz-none-000/linux-2.6.39.4/drivers/usb/gadget/rndis.c 2011-08-03 19:43:28.000000000 +0000 +++ puma6-atom-6490-729/linux-2.6.39.4/drivers/usb/gadget/rndis.c 2021-11-10 13:38:17.000000000 +0000 @@ -1,6 +1,8 @@ /* * RNDIS MSG parser * + * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $ + * * Authors: Benedikt Spranger, Pengutronix * Robert Schwebel, Pengutronix * @@ -21,6 +23,28 @@ * updates to merge with Linux 2.6, better match RNDIS spec */ +/* Copyright 2008, Texas Instruments Incorporated + * + * This program has been modified from its original operation by + * Texas Instruments to do the following: + * + * Explanation of modification: + * fixes/changes from Puma5 + * + * + * THIS MODIFIED SOFTWARE AND DOCUMENTATION ARE PROVIDED + * "AS IS," AND TEXAS INSTRUMENTS MAKES NO REPRESENTATIONS + * OR WARRENTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY + * PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR + * DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + * See The GNU General Public License for more details. + * + * These changes are covered under version 2 of the GNU General Public License, + * dated June 1991. + */ + #include #include #include @@ -28,8 +52,6 @@ #include #include #include -#include -#include #include #include @@ -38,7 +60,9 @@ #include -#undef VERBOSE_DEBUG +#undef RNDIS_PM +#undef RNDIS_WAKEUP +#undef VERBOSE #include "rndis.h" @@ -51,11 +75,19 @@ */ #if 0 +#define DEBUG(str,args...) do { \ + if (rndis_debug) \ + printk(KERN_DEBUG str , ## args ); \ + } while (0) static int rndis_debug = 0; + module_param (rndis_debug, int, 0); MODULE_PARM_DESC (rndis_debug, "enable debugging"); + #else + #define rndis_debug 0 +#define DEBUG(str,args...) do{}while(0) #endif #define RNDIS_MAX_CONFIGS 1 @@ -64,7 +96,7 @@ static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS]; /* Driver Version */ -static const __le32 rndis_driver_version = cpu_to_le32(1); +static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1); /* Function Prototypes */ static rndis_resp_t *rndis_add_response(int configNr, u32 length); @@ -89,6 +121,12 @@ OID_GEN_MAXIMUM_TOTAL_SIZE, OID_GEN_MEDIA_CONNECT_STATUS, OID_GEN_PHYSICAL_MEDIUM, +#if 0 + OID_GEN_RNDIS_CONFIG_PARAMETER, +#endif +#ifdef CONFIG_MACH_PUMA5 + OID_GEN_RNDIS_CONFIG_PARAMETER, +#endif /* the statistical stuff */ OID_GEN_XMIT_OK, @@ -136,14 +174,7 @@ #endif /* RNDIS_OPTIONAL_STATS */ #ifdef RNDIS_PM - /* PM and wakeup are "mandatory" for USB, but the RNDIS specs - * don't say what they mean ... and the NDIS specs are often - * confusing and/or ambiguous in this context. (That is, more - * so than their specs for the other OIDs.) - * - * FIXME someone who knows what these should do, please - * implement them! - */ + /* PM and wakeup are mandatory for USB: */ /* power management */ OID_PNP_CAPABILITIES, @@ -159,19 +190,22 @@ #endif /* RNDIS_PM */ }; +#ifdef CONFIG_MACH_PUMA5 +static void string_to_unicode (char *string, u16 *unicode_string, u16 *length); +static u8 unicode_to_macnibble (u16 value); +static int rndis_indicate_status_msg (int configNr, u32 status); +#endif /* NDIS Functions */ -static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, - unsigned buf_len, rndis_resp_t *r) +static int +gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, + rndis_resp_t *r) { int retval = -ENOTSUPP; u32 length = 4; /* usually */ __le32 *outbuf; int i, count; rndis_query_cmplt_type *resp; - struct net_device *net; - struct rtnl_link_stats64 temp; - const struct rtnl_link_stats64 *stats; if (!r) return -ENOMEM; resp = (rndis_query_cmplt_type *)r->buf; @@ -179,22 +213,19 @@ if (!resp) return -ENOMEM; if (buf_len && rndis_debug > 1) { - pr_debug("query OID %08x value, len %d:\n", OID, buf_len); + DEBUG("query OID %08x value, len %d:\n", OID, buf_len); for (i = 0; i < buf_len; i += 16) { - pr_debug("%03d: %08x %08x %08x %08x\n", i, - get_unaligned_le32(&buf[i]), - get_unaligned_le32(&buf[i + 4]), - get_unaligned_le32(&buf[i + 8]), - get_unaligned_le32(&buf[i + 12])); + DEBUG ("%03d: %08x %08x %08x %08x\n", i, + le32_to_cpup((__le32 *)&buf[i]), + le32_to_cpup((__le32 *)&buf[i + 4]), + le32_to_cpup((__le32 *)&buf[i + 8]), + le32_to_cpup((__le32 *)&buf[i + 12])); } } /* response goes here, right after the header */ outbuf = (__le32 *)&resp[1]; - resp->InformationBufferOffset = cpu_to_le32(16); - - net = rndis_per_dev_params[configNr].dev; - stats = dev_get_stats(net, &temp); + resp->InformationBufferOffset = __constant_cpu_to_le32 (16); switch (OID) { @@ -202,7 +233,7 @@ /* mandatory */ case OID_GEN_SUPPORTED_LIST: - pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__); + DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__); length = sizeof(oid_supported_list); count = length / sizeof(u32); for (i = 0; i < count; i++) @@ -212,27 +243,27 @@ /* mandatory */ case OID_GEN_HARDWARE_STATUS: - pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__); + DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); /* Bogus question! * Hardware must be ready to receive high level protocols. * BTW: * reddite ergo quae sunt Caesaris Caesari * et quae sunt Dei Deo! */ - *outbuf = cpu_to_le32(0); + *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; /* mandatory */ case OID_GEN_MEDIA_SUPPORTED: - pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__); + DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; break; /* mandatory */ case OID_GEN_MEDIA_IN_USE: - pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__); + DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); /* one medium, one transport... (maybe you do it better) */ *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; @@ -240,7 +271,7 @@ /* mandatory */ case OID_GEN_MAXIMUM_FRAME_SIZE: - pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); + DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -251,10 +282,10 @@ /* mandatory */ case OID_GEN_LINK_SPEED: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); + DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); if (rndis_per_dev_params[configNr].media_state == NDIS_MEDIA_STATE_DISCONNECTED) - *outbuf = cpu_to_le32(0); + *outbuf = __constant_cpu_to_le32 (0); else *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].speed); @@ -263,7 +294,7 @@ /* mandatory */ case OID_GEN_TRANSMIT_BLOCK_SIZE: - pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); + DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -273,7 +304,7 @@ /* mandatory */ case OID_GEN_RECEIVE_BLOCK_SIZE: - pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); + DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -283,7 +314,7 @@ /* mandatory */ case OID_GEN_VENDOR_ID: - pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__); + DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].vendorID); retval = 0; @@ -291,21 +322,15 @@ /* mandatory */ case OID_GEN_VENDOR_DESCRIPTION: - pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); - if (rndis_per_dev_params[configNr].vendorDescr) { - length = strlen(rndis_per_dev_params[configNr]. - vendorDescr); + DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); + length = strlen (rndis_per_dev_params [configNr].vendorDescr); memcpy(outbuf, - rndis_per_dev_params[configNr].vendorDescr, - length); - } else { - outbuf[0] = 0; - } + rndis_per_dev_params [configNr].vendorDescr, length); retval = 0; break; case OID_GEN_VENDOR_DRIVER_VERSION: - pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); + DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__); /* Created as LE */ *outbuf = rndis_driver_version; retval = 0; @@ -313,30 +338,38 @@ /* mandatory */ case OID_GEN_CURRENT_PACKET_FILTER: - pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__); + DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); +#ifdef CONFIG_MACH_PUMA5 + *outbuf = cpu_to_le32 (*(u16 *)rndis_per_dev_params[configNr].filter); +#else *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter); +#endif retval = 0; break; /* mandatory */ case OID_GEN_MAXIMUM_TOTAL_SIZE: - pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); - *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); + DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); retval = 0; break; /* mandatory */ case OID_GEN_MEDIA_CONNECT_STATUS: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); + DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__); *outbuf = cpu_to_le32(rndis_per_dev_params[configNr] .media_state); retval = 0; break; case OID_GEN_PHYSICAL_MEDIUM: - pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); - *outbuf = cpu_to_le32(0); + DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__); +#ifdef CONFIG_MACH_PUMA5 + *outbuf = __constant_cpu_to_le32 (2); //5 +#else + *outbuf = __constant_cpu_to_le32 (0); +#endif retval = 0; break; @@ -345,8 +378,8 @@ * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! */ case OID_GEN_MAC_OPTIONS: /* from WinME */ - pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); - *outbuf = cpu_to_le32( + DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32( NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_FULL_DUPLEX); retval = 0; @@ -357,10 +390,13 @@ /* mandatory */ case OID_GEN_XMIT_OK: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_XMIT_OK\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->tx_packets - - stats->tx_errors - stats->tx_dropped); + DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 ( + rndis_per_dev_params [configNr].stats->tx_packets - + rndis_per_dev_params [configNr].stats->tx_errors - + rndis_per_dev_params [configNr].stats->tx_dropped); +//printk(KERN_DEBUG "[vlad] %s:%d OID_GEN_XMIT_OK=0x%x\n", __func__, __LINE__, *outbuf); retval = 0; } break; @@ -368,10 +404,13 @@ /* mandatory */ case OID_GEN_RCV_OK: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_RCV_OK\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_packets - - stats->rx_errors - stats->rx_dropped); + DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 ( + rndis_per_dev_params [configNr].stats->rx_packets - + rndis_per_dev_params [configNr].stats->rx_errors - + rndis_per_dev_params [configNr].stats->rx_dropped); +//printk(KERN_DEBUG "[vlad] %s:%d OID_GEN_RCV_OK=0x%x\n", __func__, __LINE__, *outbuf); retval = 0; } break; @@ -379,9 +418,12 @@ /* mandatory */ case OID_GEN_XMIT_ERROR: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->tx_errors); + DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->tx_errors); + if (*outbuf) + //printk(KERN_DEBUG "[vlad] %s:%d OID_GEN_XMIT_ERROR=0x%x\n", __func__, __LINE__, *outbuf); retval = 0; } break; @@ -389,39 +431,188 @@ /* mandatory */ case OID_GEN_RCV_ERROR: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_errors); + DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->rx_errors); + if (*outbuf) + //printk(KERN_DEBUG "[vlad] %s:%d OID_GEN_RCV_ERROR=0x%x\n", __func__, __LINE__, *outbuf); retval = 0; } break; /* mandatory */ case OID_GEN_RCV_NO_BUFFER: - pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_dropped); + DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->rx_dropped); + //printk(KERN_DEBUG "[vlad] %s:%d OID_GEN_RCV_NO_BUFFER=0x%x\n", __func__, __LINE__, *outbuf); + retval = 0; + } + break; + +#ifdef RNDIS_OPTIONAL_STATS + case OID_GEN_DIRECTED_BYTES_XMIT: + DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); + /* + * Aunt Tilly's size of shoes + * minus antarctica count of penguins + * divided by weight of Alpha Centauri + */ + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 ( + (rndis_per_dev_params [configNr] + .stats->tx_packets - + rndis_per_dev_params [configNr] + .stats->tx_errors - + rndis_per_dev_params [configNr] + .stats->tx_dropped) + * 123); + retval = 0; + } + break; + + case OID_GEN_DIRECTED_FRAMES_XMIT: + DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); + /* dito */ + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 ( + (rndis_per_dev_params [configNr] + .stats->tx_packets - + rndis_per_dev_params [configNr] + .stats->tx_errors - + rndis_per_dev_params [configNr] + .stats->tx_dropped) + / 123); + retval = 0; + } + break; + + case OID_GEN_MULTICAST_BYTES_XMIT: + DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->multicast*1234); + retval = 0; + } + break; + + case OID_GEN_MULTICAST_FRAMES_XMIT: + DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->multicast); + retval = 0; + } + break; + + case OID_GEN_BROADCAST_BYTES_XMIT: + DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->tx_packets/42*255); + retval = 0; + } + break; + + case OID_GEN_BROADCAST_FRAMES_XMIT: + DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->tx_packets/42); + retval = 0; + } + break; + + case OID_GEN_DIRECTED_BYTES_RCV: + DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32 (0); + retval = 0; + break; + + case OID_GEN_DIRECTED_FRAMES_RCV: + DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32 (0); + retval = 0; + break; + + case OID_GEN_MULTICAST_BYTES_RCV: + DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->multicast * 1111); retval = 0; } break; + case OID_GEN_MULTICAST_FRAMES_RCV: + DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->multicast); + retval = 0; + } + break; + + case OID_GEN_BROADCAST_BYTES_RCV: + DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->rx_packets/42*255); + retval = 0; + } + break; + + case OID_GEN_BROADCAST_FRAMES_RCV: + DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->rx_packets/42); + retval = 0; + } + break; + + case OID_GEN_RCV_CRC_ERROR: + DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->rx_crc_errors); + retval = 0; + } + break; + + case OID_GEN_TRANSMIT_QUEUE_LENGTH: + DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32 (0); + retval = 0; + break; +#endif /* RNDIS_OPTIONAL_STATS */ + /* ieee802.3 OIDs (table 4-3) */ /* mandatory */ case OID_802_3_PERMANENT_ADDRESS: - pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__); + DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); + if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; +#ifdef CONFIG_MACH_PUMA5 + memcpy (outbuf, + rndis_per_dev_params [configNr].perm_mac, + length); +#else memcpy(outbuf, rndis_per_dev_params[configNr].host_mac, length); +#endif retval = 0; } break; /* mandatory */ case OID_802_3_CURRENT_ADDRESS: - pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__); + DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; memcpy(outbuf, @@ -433,23 +624,27 @@ /* mandatory */ case OID_802_3_MULTICAST_LIST: - pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); + DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); /* Multicast base address only */ - *outbuf = cpu_to_le32(0xE0000000); + *outbuf = __constant_cpu_to_le32 (0xE0000000); retval = 0; break; /* mandatory */ case OID_802_3_MAXIMUM_LIST_SIZE: - pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); + DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); /* Multicast base address only */ - *outbuf = cpu_to_le32(1); +#ifdef CONFIG_MACH_PUMA5 + *outbuf = __constant_cpu_to_le32 (32); /* TAG0008 */ +#else + *outbuf = __constant_cpu_to_le32 (1); +#endif retval = 0; break; case OID_802_3_MAC_OPTIONS: - pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); - *outbuf = cpu_to_le32(0); + DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32(0); retval = 0; break; @@ -457,36 +652,95 @@ /* mandatory */ case OID_802_3_RCV_ERROR_ALIGNMENT: - pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_frame_errors); + DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__); + if (rndis_per_dev_params [configNr].stats) { + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] + .stats->rx_frame_errors); retval = 0; } break; /* mandatory */ case OID_802_3_XMIT_ONE_COLLISION: - pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); - *outbuf = cpu_to_le32(0); + DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; /* mandatory */ case OID_802_3_XMIT_MORE_COLLISIONS: - pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); - *outbuf = cpu_to_le32(0); + DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); + *outbuf = __constant_cpu_to_le32 (0); + retval = 0; + break; + +#ifdef RNDIS_OPTIONAL_STATS + case OID_802_3_XMIT_DEFERRED: + DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); + /* TODO */ + break; + + case OID_802_3_XMIT_MAX_COLLISIONS: + DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); + /* TODO */ + break; + + case OID_802_3_RCV_OVERRUN: + DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); + /* TODO */ + break; + + case OID_802_3_XMIT_UNDERRUN: + DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); + /* TODO */ + break; + + case OID_802_3_XMIT_HEARTBEAT_FAILURE: + DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); + /* TODO */ + break; + + case OID_802_3_XMIT_TIMES_CRS_LOST: + DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); + /* TODO */ + break; + + case OID_802_3_XMIT_LATE_COLLISIONS: + DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); + /* TODO */ + break; +#endif /* RNDIS_OPTIONAL_STATS */ + +#ifdef RNDIS_PM + /* power management OIDs (table 4-5) */ + case OID_PNP_CAPABILITIES: + DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__); + + /* for now, no wakeup capabilities */ + length = sizeof (struct NDIS_PNP_CAPABILITIES); + memset(outbuf, 0, length); retval = 0; break; + case OID_PNP_QUERY_POWER: + DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__, + le32_to_cpup((__le32 *) buf) - 1); + /* only suspend is a real power state, and + * it can't be entered by OID_PNP_SET_POWER... + */ + length = 0; + retval = 0; + break; +#endif default: - pr_warning("%s: query unknown OID 0x%08X\n", - __func__, OID); + printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", + __FUNCTION__, OID); } if (retval < 0) length = 0; resp->InformationBufferLength = cpu_to_le32(length); - r->length = length + sizeof(*resp); + r->length = length + sizeof *resp; resp->MessageLength = cpu_to_le32(r->length); return retval; } @@ -505,13 +759,13 @@ return -ENOMEM; if (buf_len && rndis_debug > 1) { - pr_debug("set OID %08x value, len %d:\n", OID, buf_len); + DEBUG("set OID %08x value, len %d:\n", OID, buf_len); for (i = 0; i < buf_len; i += 16) { - pr_debug("%03d: %08x %08x %08x %08x\n", i, - get_unaligned_le32(&buf[i]), - get_unaligned_le32(&buf[i + 4]), - get_unaligned_le32(&buf[i + 8]), - get_unaligned_le32(&buf[i + 12])); + DEBUG ("%03d: %08x %08x %08x %08x\n", i, + le32_to_cpup((__le32 *)&buf[i]), + le32_to_cpup((__le32 *)&buf[i + 4]), + le32_to_cpup((__le32 *)&buf[i + 8]), + le32_to_cpup((__le32 *)&buf[i + 12])); } } @@ -525,14 +779,17 @@ * PROMISCUOUS, DIRECTED, * MULTICAST, ALL_MULTICAST, BROADCAST */ - *params->filter = (u16)get_unaligned_le32(buf); - pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", - __func__, *params->filter); + *params->filter = (u16) le32_to_cpup((__le32 *)buf); + DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", + __FUNCTION__, *params->filter); /* this call has a significant side effect: it's * what makes the packet flow start and stop, like * activating the CDC Ethernet altsetting. */ +#ifdef RNDIS_PM +update_linkstate: +#endif retval = 0; if (*params->filter) { params->state = RNDIS_DATA_INITIALIZED; @@ -548,13 +805,106 @@ case OID_802_3_MULTICAST_LIST: /* I think we can ignore this */ - pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); + DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); +#ifdef CONFIG_MACH_PUMA5 + /* TAG0010*/ + memset (rndis_per_dev_params [configNr].mcast_addr, 0, + RNDIS_MAX_MULTICAST_SIZE * 6); + memcpy (rndis_per_dev_params [configNr].mcast_addr, + buf, buf_len); + + retval = 0; + +#endif + break; +#ifdef CONFIG_MACH_PUMA5 + case OID_GEN_RNDIS_CONFIG_PARAMETER: + { + struct rndis_config_parameter *param; + char *strbuf; + u16 param_name [80], parlen, index = 0; + u8 first, second; + + + param = (struct rndis_config_parameter *) buf; + strbuf = buf + cpu_to_le32(param->ParameterNameOffset); + + string_to_unicode ("NetworkAddress", param_name, &parlen); + if ((parlen == cpu_to_le32(param->ParameterNameLength)) && + ((memcmp (param_name, strbuf, parlen) == 0))) + { + parlen = cpu_to_le32(param->ParameterValueLength); + strbuf = buf + cpu_to_le32(param->ParameterValueOffset); + while (parlen) + { + first = unicode_to_macnibble (cpu_to_le16p((u16*)strbuf)); + strbuf += 2; + second = unicode_to_macnibble (cpu_to_le16p((u16*)strbuf)); + strbuf += 2; + if ((first != 0xff) && (second != 0xff)) + { + rndis_per_dev_params[configNr].host_mac [index] = (first << 4) | second; + parlen -= 4; + index ++; + } else { + break; + } + } + retval = 0; + } + } + + break; +#else +#if 0 + case OID_GEN_RNDIS_CONFIG_PARAMETER: + { + struct rndis_config_parameter *param; + + param = (struct rndis_config_parameter *) buf; + + DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n", + __FUNCTION__, + min(cpu_to_le32(param->ParameterNameLength),80), + buf + param->ParameterNameOffset); retval = 0; break; +#endif +#endif + +#ifdef RNDIS_PM + case OID_PNP_SET_POWER: + /* The only real power state is USB suspend, and RNDIS requests + * can't enter it; this one isn't really about power. After + * resuming, Windows forces a reset, and then SET_POWER D0. + * FIXME ... then things go batty; Windows wedges itself. + */ + i = le32_to_cpup((__force __le32 *)buf); + DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1); + switch (i) { + case NdisDeviceStateD0: + *params->filter = params->saved_filter; + goto update_linkstate; + case NdisDeviceStateD3: + case NdisDeviceStateD2: + case NdisDeviceStateD1: + params->saved_filter = *params->filter; + retval = 0; + break; + } + break; + +#ifdef RNDIS_WAKEUP + // no wakeup support advertised, so wakeup OIDs always fail: + // - OID_PNP_ENABLE_WAKE_UP + // - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN +#endif + +#endif /* RNDIS_PM */ default: - pr_warning("%s: set unknown OID 0x%08X, size %d\n", - __func__, OID, buf_len); + printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", + __FUNCTION__, OID, buf_len); } return retval; @@ -568,35 +918,49 @@ { rndis_init_cmplt_type *resp; rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - if (!params->dev) - return -ENOTSUPP; + if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_init_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_INITIALIZE_CMPLT); - resp->MessageLength = cpu_to_le32(52); +#ifdef CONFIG_MACH_PUMA5 + if (!resp) return -ENOMEM; +#endif + + resp->MessageType = __constant_cpu_to_le32 ( + REMOTE_NDIS_INITIALIZE_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (52); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); - resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION); - resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION); - resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS); - resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3); - resp->MaxPacketsPerTransfer = cpu_to_le32(1); + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); + resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION); + resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION); + resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS); + resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3); + resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1); resp->MaxTransferSize = cpu_to_le32( - params->dev->mtu + rndis_per_dev_params [configNr].dev->mtu + sizeof(struct ethhdr) + sizeof(struct rndis_packet_msg_type) + 22); - resp->PacketAlignmentFactor = cpu_to_le32(0); - resp->AFListOffset = cpu_to_le32(0); - resp->AFListSize = cpu_to_le32(0); - - params->resp_avail(params->v); + resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0); + resp->AFListOffset = __constant_cpu_to_le32 (0); + resp->AFListSize = __constant_cpu_to_le32 (0); + + if (rndis_per_dev_params [configNr].ack) + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); +#ifdef CONFIG_MACH_PUMA5 + /* TAG0002 */ +/* + if (rndis_per_dev_params [configNr].media_state + == NDIS_MEDIA_STATE_CONNECTED) + rndis_indicate_status_msg (configNr, + RNDIS_STATUS_MEDIA_CONNECT); +*/ +#endif return 0; } @@ -604,11 +968,9 @@ { rndis_query_cmplt_type *resp; rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */ - if (!params->dev) - return -ENOTSUPP; + // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); + if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; /* * we need more memory: @@ -622,7 +984,7 @@ return -ENOMEM; resp = (rndis_query_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT); + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID), @@ -631,14 +993,17 @@ le32_to_cpu(buf->InformationBufferLength), r)) { /* OID not supported */ - resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); - resp->MessageLength = cpu_to_le32(sizeof *resp); - resp->InformationBufferLength = cpu_to_le32(0); - resp->InformationBufferOffset = cpu_to_le32(0); + resp->Status = __constant_cpu_to_le32 ( + RNDIS_STATUS_NOT_SUPPORTED); + resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp); + resp->InformationBufferLength = __constant_cpu_to_le32 (0); + resp->InformationBufferOffset = __constant_cpu_to_le32 (0); } else - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); - params->resp_avail(params->v); + if (rndis_per_dev_params [configNr].ack) + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); return 0; } @@ -647,7 +1012,6 @@ u32 BufLength, BufOffset; rndis_set_cmplt_type *resp; rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type)); if (!r) @@ -657,28 +1021,31 @@ BufLength = le32_to_cpu(buf->InformationBufferLength); BufOffset = le32_to_cpu(buf->InformationBufferOffset); -#ifdef VERBOSE_DEBUG - pr_debug("%s: Length: %d\n", __func__, BufLength); - pr_debug("%s: Offset: %d\n", __func__, BufOffset); - pr_debug("%s: InfoBuffer: ", __func__); +#ifdef VERBOSE + DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength); + DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset); + DEBUG("%s: InfoBuffer: ", __FUNCTION__); for (i = 0; i < BufLength; i++) { - pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); + DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); } - pr_debug("\n"); + DEBUG ("\n"); #endif - resp->MessageType = cpu_to_le32(REMOTE_NDIS_SET_CMPLT); - resp->MessageLength = cpu_to_le32(16); + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID), ((u8 *)buf) + 8 + BufOffset, BufLength, r)) - resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); else - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); + + if (rndis_per_dev_params [configNr].ack) + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); - params->resp_avail(params->v); return 0; } @@ -686,20 +1053,22 @@ { rndis_reset_cmplt_type *resp; rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_reset_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_RESET_CMPLT); - resp->MessageLength = cpu_to_le32(16); - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); + resp->MessageLength = __constant_cpu_to_le32 (16); + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); /* resent information */ - resp->AddressingReset = cpu_to_le32(1); + resp->AddressingReset = __constant_cpu_to_le32 (1); + + if (rndis_per_dev_params [configNr].ack) + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); - params->resp_avail(params->v); return 0; } @@ -708,7 +1077,6 @@ { rndis_keepalive_cmplt_type *resp; rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; /* host "should" check only in RNDIS_DATA_INITIALIZED state */ @@ -717,13 +1085,16 @@ return -ENOMEM; resp = (rndis_keepalive_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32( + resp->MessageType = __constant_cpu_to_le32 ( REMOTE_NDIS_KEEPALIVE_CMPLT); - resp->MessageLength = cpu_to_le32(16); + resp->MessageLength = __constant_cpu_to_le32 (16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); + + if (rndis_per_dev_params [configNr].ack) + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); - params->resp_avail(params->v); return 0; } @@ -735,24 +1106,27 @@ { rndis_indicate_status_msg_type *resp; rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - if (params->state == RNDIS_UNINITIALIZED) + if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED){ return -ENOTSUPP; - + } r = rndis_add_response(configNr, sizeof(rndis_indicate_status_msg_type)); if (!r) return -ENOMEM; + resp = (rndis_indicate_status_msg_type *)r->buf; - resp->MessageType = cpu_to_le32(REMOTE_NDIS_INDICATE_STATUS_MSG); - resp->MessageLength = cpu_to_le32(20); + resp->MessageType = __constant_cpu_to_le32 ( + REMOTE_NDIS_INDICATE_STATUS_MSG); + resp->MessageLength = __constant_cpu_to_le32 (20); resp->Status = cpu_to_le32(status); - resp->StatusBufferLength = cpu_to_le32(0); - resp->StatusBufferOffset = cpu_to_le32(0); + resp->StatusBufferLength = __constant_cpu_to_le32 (0); + resp->StatusBufferOffset = __constant_cpu_to_le32 (0); - params->resp_avail(params->v); + if (rndis_per_dev_params [configNr].ack) + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); return 0; } @@ -764,10 +1138,29 @@ RNDIS_STATUS_MEDIA_CONNECT); } +#ifdef CONFIG_MACH_PUMA5 +int rndis_signal_disconnect (int configNr, u8 logical) +#else int rndis_signal_disconnect(int configNr) +#endif { +#ifdef CONFIG_MACH_PUMA5 + u8 *buf; + u32 temp; +#endif rndis_per_dev_params[configNr].media_state = NDIS_MEDIA_STATE_DISCONNECTED; +#ifdef CONFIG_MACH_PUMA5 + if (!logical) + { + + rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; + while ((buf = rndis_get_next_response (configNr, &temp))) + rndis_free_response (configNr, buf); + return 0; + } else +#endif + return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_DISCONNECT); } @@ -779,16 +1172,19 @@ if (configNr >= RNDIS_MAX_CONFIGS) return; + rndis_per_dev_params [configNr].used = 0; rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED; /* drain the response queue */ while ((buf = rndis_get_next_response(configNr, &length))) rndis_free_response(configNr, buf); } - void rndis_set_host_mac(int configNr, const u8 *addr) { - rndis_per_dev_params[configNr].host_mac = addr; + rndis_per_dev_params [configNr].host_mac = (u8*)addr; +#ifdef CONFIG_MACH_PUMA5 + memcpy ((void *)rndis_per_dev_params[configNr].perm_mac, addr, 6); +#endif } /* @@ -804,8 +1200,9 @@ return -ENOMEM; tmp = (__le32 *)buf; - MsgType = get_unaligned_le32(tmp++); - MsgLength = get_unaligned_le32(tmp++); + + MsgType = le32_to_cpup(tmp++); + MsgLength = le32_to_cpup(tmp++); if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP; @@ -819,17 +1216,23 @@ /* For USB: responses may take up to 10 seconds */ switch (MsgType) { case REMOTE_NDIS_INITIALIZE_MSG: - pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", - __func__); + DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", + __FUNCTION__ ); params->state = RNDIS_INITIALIZED; + return rndis_init_response(configNr, (rndis_init_msg_type *)buf); case REMOTE_NDIS_HALT_MSG: - pr_debug("%s: REMOTE_NDIS_HALT_MSG\n", - __func__); + DEBUG("%s: REMOTE_NDIS_HALT_MSG\n", + __FUNCTION__ ); params->state = RNDIS_UNINITIALIZED; if (params->dev) { +#ifdef CONFIG_MACH_PUMA5 + memcpy ( + (void *)rndis_per_dev_params[configNr].host_mac, + (void *)rndis_per_dev_params[configNr].perm_mac, 6); +#endif netif_carrier_off(params->dev); netif_stop_queue(params->dev); } @@ -844,16 +1247,16 @@ (rndis_set_msg_type *)buf); case REMOTE_NDIS_RESET_MSG: - pr_debug("%s: REMOTE_NDIS_RESET_MSG\n", - __func__); + DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", + __FUNCTION__ ); return rndis_reset_response(configNr, (rndis_reset_msg_type *)buf); case REMOTE_NDIS_KEEPALIVE_MSG: /* For USB: host does this every 5 seconds */ if (rndis_debug > 1) - pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", - __func__); + DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", + __FUNCTION__ ); return rndis_keepalive_response(configNr, (rndis_keepalive_msg_type *) buf); @@ -863,12 +1266,13 @@ * In one case those messages seemed to relate to the host * suspending itself. */ - pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", - __func__, MsgType, MsgLength); + printk (KERN_WARNING + "%s: unknown RNDIS message 0x%08X len %d\n", + __FUNCTION__ , MsgType, MsgLength); { unsigned i; for (i = 0; i < MsgLength; i += 16) { - pr_debug("%03d: " + DEBUG ("%03d: " " %02x %02x %02x %02x" " %02x %02x %02x %02x" " %02x %02x %02x %02x" @@ -891,43 +1295,43 @@ return -ENOTSUPP; } -int rndis_register(void (*resp_avail)(void *v), void *v) +int rndis_register (int (* rndis_control_ack) (struct net_device *)) { u8 i; - if (!resp_avail) - return -EINVAL; - for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { if (!rndis_per_dev_params[i].used) { rndis_per_dev_params[i].used = 1; - rndis_per_dev_params[i].resp_avail = resp_avail; - rndis_per_dev_params[i].v = v; - pr_debug("%s: configNr = %d\n", __func__, i); + rndis_per_dev_params [i].ack = rndis_control_ack; + DEBUG("%s: configNr = %d\n", __FUNCTION__, i); return i; } } - pr_debug("failed\n"); + DEBUG("failed\n"); - return -ENODEV; + return -1; } void rndis_deregister(int configNr) { - pr_debug("%s:\n", __func__); + DEBUG("%s: \n", __FUNCTION__ ); if (configNr >= RNDIS_MAX_CONFIGS) return; rndis_per_dev_params[configNr].used = 0; + + return; } -int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) +int rndis_set_param_dev (u8 configNr, struct net_device *dev, + struct net_device_stats *stats, + u16 *cdc_filter) { - pr_debug("%s:\n", __func__); - if (!dev) - return -EINVAL; + DEBUG("%s:\n", __FUNCTION__ ); + if (!dev || !stats) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; rndis_per_dev_params[configNr].dev = dev; + rndis_per_dev_params [configNr].stats = stats; rndis_per_dev_params[configNr].filter = cdc_filter; return 0; @@ -935,7 +1339,7 @@ int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) { - pr_debug("%s:\n", __func__); + DEBUG("%s:\n", __FUNCTION__ ); if (!vendorDescr) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; @@ -947,7 +1351,8 @@ int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) { - pr_debug("%s: %u %u\n", __func__, medium, speed); + DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed); +// printk(KERN_EMERG "%s!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1: %u %u\n", __FUNCTION__, medium, speed); if (configNr >= RNDIS_MAX_CONFIGS) return -1; rndis_per_dev_params[configNr].medium = medium; @@ -955,6 +1360,14 @@ return 0; } +EXPORT_SYMBOL(rndis_set_param_medium); + +#ifdef CONFIG_MACH_PUMA5 +u32 rndis_get_param_filter (u8 configNr) +{ + return (u32)(*rndis_per_dev_params [configNr].filter); +} +#endif void rndis_add_hdr(struct sk_buff *skb) { @@ -962,12 +1375,12 @@ if (!skb) return; - header = (void *)skb_push(skb, sizeof(*header)); + header = (void *) skb_push (skb, sizeof *header); memset(header, 0, sizeof *header); - header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); + header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG); header->MessageLength = cpu_to_le32(skb->len); - header->DataOffset = cpu_to_le32(36); - header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); + header->DataOffset = __constant_cpu_to_le32 (36); + header->DataLength = cpu_to_le32(skb->len - sizeof *header); } void rndis_free_response(int configNr, u8 *buf) @@ -1024,39 +1437,36 @@ return r; } -int rndis_rm_hdr(struct gether *port, - struct sk_buff *skb, - struct sk_buff_head *list) +int rndis_rm_hdr(struct sk_buff *skb) { /* tmp points to a struct rndis_packet_msg_type */ __le32 *tmp = (void *)skb->data; /* MessageType, MessageLength */ - if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) - != get_unaligned(tmp++)) { - dev_kfree_skb_any(skb); + if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG) + != get_unaligned(tmp++)) return -EINVAL; - } tmp++; /* DataOffset, DataLength */ - if (!skb_pull(skb, get_unaligned_le32(tmp++) + 8)) { - dev_kfree_skb_any(skb); + if (!skb_pull(skb, le32_to_cpu(get_unaligned(tmp++)) + + 8 /* offset of DataOffset */)) return -EOVERFLOW; - } - skb_trim(skb, get_unaligned_le32(tmp++)); + skb_trim(skb, le32_to_cpu(get_unaligned(tmp++))); - skb_queue_tail(list, skb); return 0; } #ifdef CONFIG_USB_GADGET_DEBUG_FILES -static int rndis_proc_show(struct seq_file *m, void *v) +static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, + void *data) { - rndis_params *param = m->private; + char *out = page; + int len; + rndis_params *param = (rndis_params *) data; - seq_printf(m, + out += snprintf (out, count, "Config Nr. %d\n" "used : %s\n" "state : %s\n" @@ -1079,13 +1489,25 @@ (param->media_state) ? 0 : param->speed*100, (param->media_state) ? "disconnected" : "connected", param->vendorID, param->vendorDescr); + + len = out - page; + len -= off; + + if (len < count) { + *eof = 1; + if (len <= 0) return 0; + } else + len = count; + + *start = page + off; + return len; } -static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) +static int rndis_proc_write (struct file *file, const char __user *buffer, + unsigned long count, void *data) { - rndis_params *p = PDE(file->f_path.dentry->d_inode)->data; + rndis_params *p = data; u32 speed = 0; int i, fl_speed = 0; @@ -1113,11 +1535,15 @@ break; case 'D': case 'd': +#ifdef CONFIG_MACH_PUMA5 + rndis_signal_disconnect(p->confignr,0); +#else rndis_signal_disconnect(p->confignr); +#endif break; default: if (fl_speed) p->speed = speed; - else pr_debug("%c is not valid\n", c); + else DEBUG ("%c is not valid\n", c); break; } @@ -1127,20 +1553,6 @@ return count; } -static int rndis_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, rndis_proc_show, PDE(inode)->data); -} - -static const struct file_operations rndis_proc_fops = { - .owner = THIS_MODULE, - .open = rndis_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = rndis_proc_write, -}; - #define NAME_TEMPLATE "driver/rndis-%03d" static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; @@ -1148,7 +1560,7 @@ #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ -int rndis_init(void) +int __devinit rndis_init (void) { u8 i; @@ -1157,18 +1569,23 @@ char name [20]; sprintf(name, NAME_TEMPLATE, i); - rndis_connect_state[i] = proc_create_data(name, 0660, NULL, - &rndis_proc_fops, - (void *)(rndis_per_dev_params + i)); - if (!rndis_connect_state[i]) { - pr_debug("%s: remove entries", __func__); + if (!(rndis_connect_state [i] + = create_proc_entry (name, 0660, NULL))) + { + DEBUG ("%s :remove entries", __FUNCTION__); while (i) { sprintf(name, NAME_TEMPLATE, --i); remove_proc_entry(name, NULL); } - pr_debug("\n"); + DEBUG ("\n"); return -EIO; } + + rndis_connect_state [i]->nlink = 1; + rndis_connect_state [i]->write_proc = rndis_proc_write; + rndis_connect_state [i]->read_proc = rndis_proc_read; + rndis_connect_state [i]->data = (void *) + (rndis_per_dev_params + i); #endif rndis_per_dev_params[i].confignr = i; rndis_per_dev_params[i].used = 0; @@ -1193,3 +1610,74 @@ } #endif } + +#ifdef CONFIG_MACH_PUMA5 +char rndis_get_multicast_status (int cfg, const u8 *addr) +{ + u32 index = 0; + char status = 0; + + while (index < RNDIS_MAX_MULTICAST_SIZE) + { + if ((rndis_per_dev_params[cfg].mcast_addr[index][0] == addr[0]) && + (rndis_per_dev_params[cfg].mcast_addr[index][1] == addr[1]) && + (rndis_per_dev_params[cfg].mcast_addr[index][2] == addr[2]) && + (rndis_per_dev_params[cfg].mcast_addr[index][3] == addr[3]) && + (rndis_per_dev_params[cfg].mcast_addr[index][4] == addr[4]) && + (rndis_per_dev_params[cfg].mcast_addr[index][5] == addr[5])) + { + status = 1; + break; + } + index++; + } + + return status; +} +/* TAG0009 */ +static void string_to_unicode (char *string, u16 *unicode_string, u16 *length) +{ + u32 index; + + /* The UNICODE string will be twice the length of the ANSI string. */ + *length = 2 * strlen (string); + + /* Convert the ANSI String to UNICODE format. */ + for (index = 0; index < strlen (string); index++) + unicode_string[index] = cpu_to_le16((u16)(string[index])); + +} + +static u8 unicode_to_macnibble (u16 value) +{ + u8 retval = 0xff; + + if ( (value >= '0') && (value <= '9') ) + { + retval = value - '0'; + } else { + if ( (value >= 'A') && (value <= 'F') ) + { + retval = value - '7'; + } else { + if ( (value >= 'a') && (value <= 'f') ) + { + retval = value - 'W'; + } + } + } + + return retval; +} +int is_rndis_configured(int configNr) +{ + + if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED) + return 0; + else + if (rndis_per_dev_params [configNr].state == RNDIS_INITIALIZED) + return 1; + else + return -1; +} +#endif