Commit 920f873a authored by David Brownell's avatar David Brownell Committed by Linus Torvalds

[PATCH] USB: rndis gadget driver updates

Various build fixes:  64bit (Andrew Morton), static linking,
broken on big-endian, etc.

Tighten up the integration with the main "ether" driver, so
state transitions and host ethernet addresses are shared too.
Add missing spinlock calls around RNDIS command outcall,
fix GET_INTERFACE issue, host mustn't clobber netdev flags.

Minor code cleanups.
parent 836115bf
...@@ -120,6 +120,7 @@ struct eth_dev { ...@@ -120,6 +120,7 @@ struct eth_dev {
unsigned long todo; unsigned long todo;
#define WORK_RX_MEMORY 0 #define WORK_RX_MEMORY 0
int rndis_config; int rndis_config;
u8 host_mac [ETH_ALEN];
}; };
/* This version autoconfigures as much as possible at run-time. /* This version autoconfigures as much as possible at run-time.
...@@ -159,9 +160,8 @@ static const char *EP_STATUS_NAME; ...@@ -159,9 +160,8 @@ static const char *EP_STATUS_NAME;
/* For hardware that can talk RNDIS and either of the above protocols, /* For hardware that can talk RNDIS and either of the above protocols,
* use this ID ... the windows INF files will know it. Unless it's * use this ID ... the windows INF files will know it. Unless it's
* used with CDC Ethernet, Linux hosts will need updates to choose the * used with CDC Ethernet, Linux 2.4 hosts will need updates to choose
* non-MSFT configuration, either in the kernel (2.4) or else from a * the non-RNDIS configuration.
* hotplug script (2.6).
*/ */
#define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ #define RNDIS_VENDOR_NUM 0x0525 /* NetChip */
#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ #define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
...@@ -1334,8 +1334,10 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req) ...@@ -1334,8 +1334,10 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
struct eth_dev *dev = ep->driver_data; struct eth_dev *dev = ep->driver_data;
/* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */ /* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */
spin_lock(&dev->lock);
if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf)) if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf))
ERROR(dev, "%s: rndis parse error\n", __FUNCTION__ ); ERROR(dev, "%s: rndis parse error\n", __FUNCTION__ );
spin_unlock(&dev->lock);
} }
#endif /* RNDIS */ #endif /* RNDIS */
...@@ -1486,14 +1488,14 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1486,14 +1488,14 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|| !dev->config || !dev->config
|| ctrl->wIndex > 1) || ctrl->wIndex > 1)
break; break;
if (!dev->cdc && ctrl->wIndex != 0) if (!(dev->cdc || dev->rndis) && ctrl->wIndex != 0)
break; break;
/* if carrier is on, data interface is active. */ /* for CDC, iff carrier is on, data interface is active. */
*(u8 *)req->buf = if (dev->rndis || ctrl->wIndex != 1)
((ctrl->wIndex == 1) && netif_carrier_ok (dev->net)) *(u8 *)req->buf = 0;
? 1 else
: 0, *(u8 *)req->buf = netif_carrier_ok (dev->net) ? 1 : 0;
value = min (ctrl->wLength, (u16) 1); value = min (ctrl->wLength, (u16) 1);
break; break;
...@@ -1552,6 +1554,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1552,6 +1554,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
memcpy (req->buf, buf, value); memcpy (req->buf, buf, value);
req->complete = rndis_response_complete; req->complete = rndis_response_complete;
} }
/* else stalls ... spec says to avoid that */
} }
break; break;
#endif /* RNDIS */ #endif /* RNDIS */
...@@ -1590,6 +1593,8 @@ eth_disconnect (struct usb_gadget *gadget) ...@@ -1590,6 +1593,8 @@ eth_disconnect (struct usb_gadget *gadget)
eth_reset_config (dev); eth_reset_config (dev);
spin_unlock_irqrestore (&dev->lock, flags); spin_unlock_irqrestore (&dev->lock, flags);
/* FIXME RNDIS should enter RNDIS_UNINITIALIZED */
/* next we may get setup() calls to enumerate new connections; /* next we may get setup() calls to enumerate new connections;
* or an unbind() during shutdown (including removing module). * or an unbind() during shutdown (including removing module).
*/ */
...@@ -2376,19 +2381,19 @@ eth_bind (struct usb_gadget *gadget) ...@@ -2376,19 +2381,19 @@ eth_bind (struct usb_gadget *gadget)
*/ */
random_ether_addr(net->dev_addr); random_ether_addr(net->dev_addr);
#ifdef DEV_CONFIG_CDC
/* ... another address for the host, on the other end of the /* ... another address for the host, on the other end of the
* link, gets exported through CDC (see CDC spec table 41) * link, gets exported through CDC (see CDC spec table 41)
* and RNDIS.
*/ */
if (cdc) { if (cdc || rndis) {
u8 node_id [ETH_ALEN]; random_ether_addr(dev->host_mac);
#ifdef DEV_CONFIG_CDC
random_ether_addr(node_id);
snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
node_id [0], node_id [1], node_id [2], dev->host_mac [0], dev->host_mac [1],
node_id [3], node_id [4], node_id [5]); dev->host_mac [2], dev->host_mac [3],
} dev->host_mac [4], dev->host_mac [5]);
#endif #endif
}
if (rndis) { if (rndis) {
status = rndis_init(); status = rndis_init();
...@@ -2448,10 +2453,11 @@ eth_bind (struct usb_gadget *gadget) ...@@ -2448,10 +2453,11 @@ eth_bind (struct usb_gadget *gadget)
net->dev_addr [2], net->dev_addr [3], net->dev_addr [2], net->dev_addr [3],
net->dev_addr [4], net->dev_addr [5]); net->dev_addr [4], net->dev_addr [5]);
#ifdef DEV_CONFIG_CDC if (cdc || rndis)
if (cdc) INFO (dev, "HOST MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
INFO (dev, "CDC host enet %s\n", ethaddr); dev->host_mac [0], dev->host_mac [1],
#endif dev->host_mac [2], dev->host_mac [3],
dev->host_mac [4], dev->host_mac [5]);
#ifdef CONFIG_USB_ETH_RNDIS #ifdef CONFIG_USB_ETH_RNDIS
if (rndis) { if (rndis) {
...@@ -2468,6 +2474,7 @@ eth_bind (struct usb_gadget *gadget) ...@@ -2468,6 +2474,7 @@ eth_bind (struct usb_gadget *gadget)
} }
/* these set up a lot of the OIDs that RNDIS needs */ /* these set up a lot of the OIDs that RNDIS needs */
rndis_set_host_mac (dev->rndis_config, dev->host_mac);
if (rndis_set_param_dev (dev->rndis_config, dev->net, if (rndis_set_param_dev (dev->rndis_config, dev->net,
&dev->stats)) &dev->stats))
goto fail0; goto fail0;
......
...@@ -37,6 +37,16 @@ ...@@ -37,6 +37,16 @@
#include "rndis.h" #include "rndis.h"
/* The driver for your USB chip needs to support ep0 OUT to work with
* RNDIS, plus the same three descriptors as CDC Ethernet.
*
* Windows hosts need an INF file like Documentation/usb/linux.inf
*/
#ifndef __LITTLE_ENDIAN
#warning this code is missing all cpu_to_leXX() calls ...
#endif
#if 0 #if 0
#define DEBUG if (rndis_debug) printk #define DEBUG if (rndis_debug) printk
static int rndis_debug = 0; static int rndis_debug = 0;
...@@ -89,8 +99,12 @@ static u32 devFlags2currentFilter (struct net_device *dev) ...@@ -89,8 +99,12 @@ static u32 devFlags2currentFilter (struct net_device *dev)
static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev) static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
{ {
/* FIXME the filter is supposed to control what gets
* forwarded from gadget to host; but dev->flags controls
* reporting from host to gadget ...
*/
#if 0
if (!dev) return; if (!dev) return;
if (currentFilter & NDIS_PACKET_TYPE_MULTICAST) if (currentFilter & NDIS_PACKET_TYPE_MULTICAST)
dev->flags |= IFF_MULTICAST; dev->flags |= IFF_MULTICAST;
if (currentFilter & NDIS_PACKET_TYPE_BROADCAST) if (currentFilter & NDIS_PACKET_TYPE_BROADCAST)
...@@ -99,8 +113,13 @@ static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev) ...@@ -99,8 +113,13 @@ static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
dev->flags |= IFF_ALLMULTI; dev->flags |= IFF_ALLMULTI;
if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS) if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
dev->flags |= IFF_PROMISC; dev->flags |= IFF_PROMISC;
#endif
} }
/* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include
* - power management (OID_PNP_CAPABILITIES, ...)
* - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...)
*/
/* NDIS Functions */ /* NDIS Functions */
static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
...@@ -114,8 +133,6 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -114,8 +133,6 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
if (!resp) return -ENOMEM; if (!resp) return -ENOMEM;
if (!resp) return -ENOMEM;
switch (OID) { switch (OID) {
/* mandatory */ /* mandatory */
case OID_GEN_SUPPORTED_LIST: case OID_GEN_SUPPORTED_LIST:
...@@ -178,7 +195,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -178,7 +195,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case OID_GEN_LINK_SPEED: case OID_GEN_LINK_SPEED:
DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
length = 4; length = 4;
if (rndis_per_dev_params [configNr].media_state) if (rndis_per_dev_params [configNr].media_state
== NDIS_MEDIA_STATE_DISCONNECTED)
*((u32 *) resp + 6) = 0; *((u32 *) resp + 6) = 0;
else else
*((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed; *((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed;
...@@ -611,15 +629,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -611,15 +629,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case OID_802_3_PERMANENT_ADDRESS: case OID_802_3_PERMANENT_ADDRESS:
DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].dev) { if (rndis_per_dev_params [configNr].dev) {
length = 6; length = ETH_ALEN;
memcpy ((u8 *) resp + 24, memcpy ((u8 *) resp + 24,
rndis_per_dev_params [configNr].dev->dev_addr, rndis_per_dev_params [configNr].host_mac,
length); length);
/*
* we need a MAC address and hope that
* (our MAC + 1) is not in use
*/
*((u8 *) resp + 29) += 1;
retval = 0; retval = 0;
} else { } else {
*((u32 *) resp + 6) = 0; *((u32 *) resp + 6) = 0;
...@@ -631,15 +644,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r) ...@@ -631,15 +644,10 @@ static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
case OID_802_3_CURRENT_ADDRESS: case OID_802_3_CURRENT_ADDRESS:
DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].dev) { if (rndis_per_dev_params [configNr].dev) {
length = 6; length = ETH_ALEN;
memcpy ((u8 *) resp + 24, memcpy ((u8 *) resp + 24,
rndis_per_dev_params [configNr].dev->dev_addr, rndis_per_dev_params [configNr].host_mac,
length); length);
/*
* we need a MAC address and hope that
* (our MAC + 1) is not in use
*/
*((u8 *) resp + 29) += 1;
retval = 0; retval = 0;
} }
break; break;
...@@ -746,22 +754,38 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, ...@@ -746,22 +754,38 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
rndis_set_cmplt_type *resp; rndis_set_cmplt_type *resp;
int i, retval = -ENOTSUPP; int i, retval = -ENOTSUPP;
struct rndis_config_parameter *param; struct rndis_config_parameter *param;
struct rndis_params *params;
if (!r) return -ENOMEM; u8 *cp;
if (!r)
return -ENOMEM;
resp = (rndis_set_cmplt_type *) r->buf; resp = (rndis_set_cmplt_type *) r->buf;
if (!resp)
if (!resp) return -ENOMEM; return -ENOMEM;
cp = (u8 *)resp;
switch (OID) { switch (OID) {
case OID_GEN_CURRENT_PACKET_FILTER: case OID_GEN_CURRENT_PACKET_FILTER:
DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
currentFilter2devFlags ((u32) ((u8 *) resp + 28), params = &rndis_per_dev_params [configNr];
rndis_per_dev_params [configNr].dev); currentFilter2devFlags(cp[28], params->dev);
retval = 0; retval = 0;
if ((u32) ((u8 *) resp + 28))
rndis_per_dev_params [configNr].state = RNDIS_INITIALIZED; /* this call has a significant side effect: it's
else * what makes the packet flow start and stop, like
rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; * activating the CDC Ethernet altsetting.
*/
if (cp[28]) {
params->state = RNDIS_DATA_INITIALIZED;
netif_carrier_on(params->dev);
if (netif_running(params->dev))
netif_wake_queue (params->dev);
} else {
params->state = RNDIS_INITIALIZED;
netif_carrier_off (params->dev);
netif_stop_queue (params->dev);
}
break; break;
case OID_802_3_MULTICAST_LIST: case OID_802_3_MULTICAST_LIST:
...@@ -937,10 +961,9 @@ static int rndis_keepalive_response (int configNr, ...@@ -937,10 +961,9 @@ static int rndis_keepalive_response (int configNr,
{ {
rndis_keepalive_cmplt_type *resp; rndis_keepalive_cmplt_type *resp;
rndis_resp_t *r; rndis_resp_t *r;
/* respond only in RNDIS_INITIALIZED state */ /* host "should" check only in RNDIS_DATA_INITIALIZED state */
if (rndis_per_dev_params [configNr].state != RNDIS_INITIALIZED)
return 0;
r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type)); r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
resp = (rndis_keepalive_cmplt_type *) r->buf; resp = (rndis_keepalive_cmplt_type *) r->buf;
if (!resp) return -ENOMEM; if (!resp) return -ENOMEM;
...@@ -1004,35 +1027,48 @@ int rndis_signal_disconnect (int configNr) ...@@ -1004,35 +1027,48 @@ int rndis_signal_disconnect (int configNr)
RNDIS_STATUS_MEDIA_DISCONNECT); RNDIS_STATUS_MEDIA_DISCONNECT);
} }
void rndis_set_host_mac (int configNr, const u8 *addr)
{
rndis_per_dev_params [configNr].host_mac = addr;
}
/* /*
* Message Parser * Message Parser
*/ */
int rndis_msg_parser (u8 configNr, u8 *buf) int rndis_msg_parser (u8 configNr, u8 *buf)
{ {
u32 MsgType, MsgLength, *tmp; u32 MsgType, MsgLength, *tmp;
struct rndis_params *params;
if (!buf) return -ENOMEM; if (!buf)
return -ENOMEM;
tmp = (u32 *) buf; tmp = (u32 *) buf;
MsgType = *tmp; MsgType = *tmp;
MsgLength = *(tmp + 1); MsgLength = *(tmp + 1);
if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP; if (configNr >= RNDIS_MAX_CONFIGS)
return -ENOTSUPP;
params = &rndis_per_dev_params [configNr];
/* For USB: responses may take up to 10 seconds */
switch (MsgType) switch (MsgType)
{ {
case REMOTE_NDIS_INIZIALIZE_MSG: case REMOTE_NDIS_INITIALIZE_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_INIZIALIZE_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_INITIALIZE_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
rndis_per_dev_params [configNr].state = RNDIS_INITIALIZED; params->state = RNDIS_INITIALIZED;
return rndis_init_response (configNr, return rndis_init_response (configNr,
(rndis_init_msg_type *) buf); (rndis_init_msg_type *) buf);
break;
case REMOTE_NDIS_HALT_MSG: case REMOTE_NDIS_HALT_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; params->state = RNDIS_UNINITIALIZED;
if (params->dev) {
netif_carrier_off (params->dev);
netif_stop_queue (params->dev);
}
return 0; return 0;
case REMOTE_NDIS_QUERY_MSG: case REMOTE_NDIS_QUERY_MSG:
...@@ -1040,29 +1076,26 @@ int rndis_msg_parser (u8 configNr, u8 *buf) ...@@ -1040,29 +1076,26 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
__FUNCTION__ ); __FUNCTION__ );
return rndis_query_response (configNr, return rndis_query_response (configNr,
(rndis_query_msg_type *) buf); (rndis_query_msg_type *) buf);
break;
case REMOTE_NDIS_SET_MSG: case REMOTE_NDIS_SET_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
return rndis_set_response (configNr, return rndis_set_response (configNr,
(rndis_set_msg_type *) buf); (rndis_set_msg_type *) buf);
break;
case REMOTE_NDIS_RESET_MSG: case REMOTE_NDIS_RESET_MSG:
DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
return rndis_reset_response (configNr, return rndis_reset_response (configNr,
(rndis_reset_msg_type *) buf); (rndis_reset_msg_type *) buf);
break;
case REMOTE_NDIS_KEEPALIVE_MSG: case REMOTE_NDIS_KEEPALIVE_MSG:
/* For USB: host does this every 5 seconds */
DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n", DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
__FUNCTION__ ); __FUNCTION__ );
return rndis_keepalive_response (configNr, return rndis_keepalive_response (configNr,
(rndis_keepalive_msg_type *) (rndis_keepalive_msg_type *)
buf); buf);
break;
default: default:
printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n", printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n",
...@@ -1240,9 +1273,15 @@ int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, ...@@ -1240,9 +1273,15 @@ int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
"vendor ID : 0x%08X\n" "vendor ID : 0x%08X\n"
"vendor : %s\n", "vendor : %s\n",
param->confignr, (param->used) ? "y" : "n", param->confignr, (param->used) ? "y" : "n",
(param->state) ({ char *s = "?";
? "RNDIS_INITIALIZED" switch (param->state) {
: "RNDIS_UNINITIALIZED", case RNDIS_UNINITIALIZED:
s = "RNDIS_UNINITIALIZED"; break;
case RNDIS_INITIALIZED:
s = "RNDIS_INITIALIZED"; break;
case RNDIS_DATA_INITIALIZED:
s = "RNDIS_DATA_INITIALIZED"; break;
}; s; }),
param->medium, param->medium,
(param->media_state) ? 0 : param->speed*100, (param->media_state) ? 0 : param->speed*100,
(param->media_state) ? "disconnected" : "connected", (param->media_state) ? "disconnected" : "connected",
...@@ -1353,7 +1392,7 @@ int __init rndis_init (void) ...@@ -1353,7 +1392,7 @@ int __init rndis_init (void)
return 0; return 0;
} }
void __exit rndis_exit (void) void rndis_exit (void)
{ {
u8 i; u8 i;
char name [4]; char name [4];
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
*/ */
/* Message Set for Connectionless (802.3) Devices */ /* Message Set for Connectionless (802.3) Devices */
#define REMOTE_NDIS_INIZIALIZE_MSG 0x00000002U /* Initialize device */ #define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */
#define REMOTE_NDIS_HALT_MSG 0x00000003U #define REMOTE_NDIS_HALT_MSG 0x00000003U
#define REMOTE_NDIS_QUERY_MSG 0x00000004U #define REMOTE_NDIS_QUERY_MSG 0x00000004U
#define REMOTE_NDIS_SET_MSG 0x00000005U #define REMOTE_NDIS_SET_MSG 0x00000005U
...@@ -280,6 +280,7 @@ typedef struct rndis_params ...@@ -280,6 +280,7 @@ typedef struct rndis_params
u32 medium; u32 medium;
u32 speed; u32 speed;
u32 media_state; u32 media_state;
const u8 *host_mac;
struct net_device *dev; struct net_device *dev;
struct net_device_stats *stats; struct net_device_stats *stats;
u32 vendorID; u32 vendorID;
...@@ -301,11 +302,13 @@ void rndis_add_hdr (struct sk_buff *skb); ...@@ -301,11 +302,13 @@ void rndis_add_hdr (struct sk_buff *skb);
int rndis_rm_hdr (u8 *buf, u32 *length); int rndis_rm_hdr (u8 *buf, u32 *length);
u8 *rndis_get_next_response (int configNr, u32 *length); u8 *rndis_get_next_response (int configNr, u32 *length);
void rndis_free_response (int configNr, u8 *buf); void rndis_free_response (int configNr, u8 *buf);
int rndis_signal_connect (int configNr); int rndis_signal_connect (int configNr);
int rndis_signal_disconnect (int configNr); int rndis_signal_disconnect (int configNr);
int rndis_state (int configNr); int rndis_state (int configNr);
extern void rndis_set_host_mac (int configNr, const u8 *addr);
int __init rndis_init (void); int __init rndis_init (void);
void __exit rndis_exit (void); void rndis_exit (void);
#endif /* _LINUX_RNDIS_H */ #endif /* _LINUX_RNDIS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment