diff options
-rw-r--r-- | drivers/net/usb/rndis_host.c | 36 | ||||
-rw-r--r-- | drivers/net/usb/rndis_host.h | 19 |
2 files changed, 51 insertions, 4 deletions
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 800c9d02c3f4..0606e11510ae 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -271,7 +271,8 @@ response_error: | |||
271 | return -EDOM; | 271 | return -EDOM; |
272 | } | 272 | } |
273 | 273 | ||
274 | int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf) | 274 | int |
275 | generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | ||
275 | { | 276 | { |
276 | int retval; | 277 | int retval; |
277 | struct net_device *net = dev->net; | 278 | struct net_device *net = dev->net; |
@@ -287,7 +288,7 @@ int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf) | |||
287 | struct rndis_set_c *set_c; | 288 | struct rndis_set_c *set_c; |
288 | struct rndis_halt *halt; | 289 | struct rndis_halt *halt; |
289 | } u; | 290 | } u; |
290 | u32 tmp; | 291 | u32 tmp, *phym; |
291 | int reply_len; | 292 | int reply_len; |
292 | unsigned char *bp; | 293 | unsigned char *bp; |
293 | 294 | ||
@@ -358,6 +359,30 @@ int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf) | |||
358 | dev->driver_info->early_init(dev) != 0) | 359 | dev->driver_info->early_init(dev) != 0) |
359 | goto halt_fail_and_release; | 360 | goto halt_fail_and_release; |
360 | 361 | ||
362 | /* Check physical medium */ | ||
363 | reply_len = sizeof *phym; | ||
364 | retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, | ||
365 | 0, (void **) &phym, &reply_len); | ||
366 | if (retval != 0) | ||
367 | /* OID is optional so don't fail here. */ | ||
368 | *phym = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; | ||
369 | if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && | ||
370 | *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { | ||
371 | if (netif_msg_probe(dev)) | ||
372 | dev_dbg(&intf->dev, "driver requires wireless " | ||
373 | "physical medium, but device is not.\n"); | ||
374 | retval = -ENODEV; | ||
375 | goto halt_fail_and_release; | ||
376 | } | ||
377 | if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && | ||
378 | *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { | ||
379 | if (netif_msg_probe(dev)) | ||
380 | dev_dbg(&intf->dev, "driver requires non-wireless " | ||
381 | "physical medium, but device is wireless.\n"); | ||
382 | retval = -ENODEV; | ||
383 | goto halt_fail_and_release; | ||
384 | } | ||
385 | |||
361 | /* Get designated host ethernet address */ | 386 | /* Get designated host ethernet address */ |
362 | reply_len = ETH_ALEN; | 387 | reply_len = ETH_ALEN; |
363 | retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, | 388 | retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, |
@@ -403,6 +428,11 @@ fail: | |||
403 | } | 428 | } |
404 | EXPORT_SYMBOL_GPL(generic_rndis_bind); | 429 | EXPORT_SYMBOL_GPL(generic_rndis_bind); |
405 | 430 | ||
431 | static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) | ||
432 | { | ||
433 | return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS); | ||
434 | } | ||
435 | |||
406 | void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) | 436 | void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) |
407 | { | 437 | { |
408 | struct rndis_halt *halt; | 438 | struct rndis_halt *halt; |
@@ -518,7 +548,7 @@ EXPORT_SYMBOL_GPL(rndis_tx_fixup); | |||
518 | static const struct driver_info rndis_info = { | 548 | static const struct driver_info rndis_info = { |
519 | .description = "RNDIS device", | 549 | .description = "RNDIS device", |
520 | .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, | 550 | .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, |
521 | .bind = generic_rndis_bind, | 551 | .bind = rndis_bind, |
522 | .unbind = rndis_unbind, | 552 | .unbind = rndis_unbind, |
523 | .status = rndis_status, | 553 | .status = rndis_status, |
524 | .rx_fixup = rndis_rx_fixup, | 554 | .rx_fixup = rndis_rx_fixup, |
diff --git a/drivers/net/usb/rndis_host.h b/drivers/net/usb/rndis_host.h index 61f1fd8f5ff6..edc1d4a0e272 100644 --- a/drivers/net/usb/rndis_host.h +++ b/drivers/net/usb/rndis_host.h | |||
@@ -82,6 +82,17 @@ struct rndis_msg_hdr { | |||
82 | #define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b) | 82 | #define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b) |
83 | #define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c) | 83 | #define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c) |
84 | 84 | ||
85 | /* codes for OID_GEN_PHYSICAL_MEDIUM */ | ||
86 | #define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED ccpu2(0x00000000) | ||
87 | #define RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN ccpu2(0x00000001) | ||
88 | #define RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM ccpu2(0x00000002) | ||
89 | #define RNDIS_PHYSICAL_MEDIUM_PHONE_LINE ccpu2(0x00000003) | ||
90 | #define RNDIS_PHYSICAL_MEDIUM_POWER_LINE ccpu2(0x00000004) | ||
91 | #define RNDIS_PHYSICAL_MEDIUM_DSL ccpu2(0x00000005) | ||
92 | #define RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL ccpu2(0x00000006) | ||
93 | #define RNDIS_PHYSICAL_MEDIUM_1394 ccpu2(0x00000007) | ||
94 | #define RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN ccpu2(0x00000008) | ||
95 | #define RNDIS_PHYSICAL_MEDIUM_MAX ccpu2(0x00000009) | ||
85 | 96 | ||
86 | struct rndis_data_hdr { | 97 | struct rndis_data_hdr { |
87 | __le32 msg_type; /* RNDIS_MSG_PACKET */ | 98 | __le32 msg_type; /* RNDIS_MSG_PACKET */ |
@@ -222,6 +233,7 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */ | |||
222 | #define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101) | 233 | #define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101) |
223 | #define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106) | 234 | #define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106) |
224 | #define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e) | 235 | #define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e) |
236 | #define OID_GEN_PHYSICAL_MEDIUM ccpu2(0x00010202) | ||
225 | 237 | ||
226 | /* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ | 238 | /* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ |
227 | #define RNDIS_PACKET_TYPE_DIRECTED ccpu2(0x00000001) | 239 | #define RNDIS_PACKET_TYPE_DIRECTED ccpu2(0x00000001) |
@@ -244,10 +256,15 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */ | |||
244 | RNDIS_PACKET_TYPE_ALL_MULTICAST | \ | 256 | RNDIS_PACKET_TYPE_ALL_MULTICAST | \ |
245 | RNDIS_PACKET_TYPE_PROMISCUOUS) | 257 | RNDIS_PACKET_TYPE_PROMISCUOUS) |
246 | 258 | ||
259 | /* Flags to require specific physical medium type for generic_rndis_bind() */ | ||
260 | #define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001 | ||
261 | #define FLAG_RNDIS_PHYM_WIRELESS 0x0002 | ||
262 | |||
247 | 263 | ||
248 | extern void rndis_status(struct usbnet *dev, struct urb *urb); | 264 | extern void rndis_status(struct usbnet *dev, struct urb *urb); |
249 | extern int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf); | 265 | extern int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf); |
250 | extern int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf); | 266 | extern int |
267 | generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags); | ||
251 | extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf); | 268 | extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf); |
252 | extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb); | 269 | extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb); |
253 | extern struct sk_buff * | 270 | extern struct sk_buff * |