diff options
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/chelsio/Makefile | 2 | ||||
| -rw-r--r-- | drivers/net/irda/irda-usb.c | 363 | ||||
| -rw-r--r-- | drivers/net/irda/irda-usb.h | 43 | ||||
| -rw-r--r-- | drivers/net/irda/smsc-ircc2.c | 311 | ||||
| -rw-r--r-- | drivers/net/netconsole.c | 1 | ||||
| -rw-r--r-- | drivers/net/tg3.c | 100 | ||||
| -rw-r--r-- | drivers/net/tg3.h | 3 |
7 files changed, 743 insertions, 80 deletions
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile index 91e927827c43..54c78d94f48b 100644 --- a/drivers/net/chelsio/Makefile +++ b/drivers/net/chelsio/Makefile | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_CHELSIO_T1) += cxgb.o | 5 | obj-$(CONFIG_CHELSIO_T1) += cxgb.o |
| 6 | 6 | ||
| 7 | EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/chelsio $(DEBUG_FLAGS) | 7 | EXTRA_CFLAGS += -Idrivers/net/chelsio $(DEBUG_FLAGS) |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o | 10 | cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 6e2ec56cde0b..606243d11793 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Filename: irda-usb.c | 3 | * Filename: irda-usb.c |
| 4 | * Version: 0.9b | 4 | * Version: 0.10 |
| 5 | * Description: IrDA-USB Driver | 5 | * Description: IrDA-USB Driver |
| 6 | * Status: Experimental | 6 | * Status: Experimental |
| 7 | * Author: Dag Brattli <dag@brattli.net> | 7 | * Author: Dag Brattli <dag@brattli.net> |
| @@ -9,6 +9,9 @@ | |||
| 9 | * Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at> | 9 | * Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at> |
| 10 | * Copyright (C) 2001, Dag Brattli <dag@brattli.net> | 10 | * Copyright (C) 2001, Dag Brattli <dag@brattli.net> |
| 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> | 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> |
| 12 | * Copyright (C) 2004, SigmaTel, Inc. <irquality@sigmatel.com> | ||
| 13 | * Copyright (C) 2005, Milan Beno <beno@pobox.sk> | ||
| 14 | * Copyright (C) 2006, Nick Fedchik <nick@fedchik.org.ua> | ||
| 12 | * | 15 | * |
| 13 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
| 14 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
| @@ -61,6 +64,7 @@ | |||
| 61 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
| 62 | #include <linux/rtnetlink.h> | 65 | #include <linux/rtnetlink.h> |
| 63 | #include <linux/usb.h> | 66 | #include <linux/usb.h> |
| 67 | #include <linux/firmware.h> | ||
| 64 | 68 | ||
| 65 | #include "irda-usb.h" | 69 | #include "irda-usb.h" |
| 66 | 70 | ||
| @@ -78,8 +82,12 @@ static struct usb_device_id dongles[] = { | |||
| 78 | { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, | 82 | { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, |
| 79 | /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ | 83 | /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ |
| 80 | { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, | 84 | { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, |
| 85 | /* SigmaTel STIR4210/4220/4116 USB IrDA (VFIR) Bridge */ | ||
| 86 | { USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
| 87 | { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
| 88 | { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
| 81 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | | 89 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | |
| 82 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | 90 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, |
| 83 | .bInterfaceClass = USB_CLASS_APP_SPEC, | 91 | .bInterfaceClass = USB_CLASS_APP_SPEC, |
| 84 | .bInterfaceSubClass = USB_CLASS_IRDA, | 92 | .bInterfaceSubClass = USB_CLASS_IRDA, |
| 85 | .driver_info = IUC_DEFAULT, }, | 93 | .driver_info = IUC_DEFAULT, }, |
| @@ -99,6 +107,7 @@ MODULE_DEVICE_TABLE(usb, dongles); | |||
| 99 | 107 | ||
| 100 | /*------------------------------------------------------------------*/ | 108 | /*------------------------------------------------------------------*/ |
| 101 | 109 | ||
| 110 | static void irda_usb_init_qos(struct irda_usb_cb *self) ; | ||
| 102 | static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); | 111 | static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); |
| 103 | static void irda_usb_disconnect(struct usb_interface *intf); | 112 | static void irda_usb_disconnect(struct usb_interface *intf); |
| 104 | static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); | 113 | static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); |
| @@ -141,7 +150,24 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
| 141 | __u8 *header, | 150 | __u8 *header, |
| 142 | int force) | 151 | int force) |
| 143 | { | 152 | { |
| 144 | /* Set the negotiated link speed */ | 153 | /* Here we check if we have an STIR421x chip, |
| 154 | * and if either speed or xbofs (or both) needs | ||
| 155 | * to be changed. | ||
| 156 | */ | ||
| 157 | if (self->capability & IUC_STIR_4210 && | ||
| 158 | ((self->new_speed != -1) || (self->new_xbofs != -1))) { | ||
| 159 | |||
| 160 | /* With STIR421x, speed and xBOFs must be set at the same | ||
| 161 | * time, even if only one of them changes. | ||
| 162 | */ | ||
| 163 | if (self->new_speed == -1) | ||
| 164 | self->new_speed = self->speed ; | ||
| 165 | |||
| 166 | if (self->new_xbofs == -1) | ||
| 167 | self->new_xbofs = self->xbofs ; | ||
| 168 | } | ||
| 169 | |||
| 170 | /* Set the link speed */ | ||
| 145 | if (self->new_speed != -1) { | 171 | if (self->new_speed != -1) { |
| 146 | /* Hum... Ugly hack :-( | 172 | /* Hum... Ugly hack :-( |
| 147 | * Some device are not compliant with the spec and change | 173 | * Some device are not compliant with the spec and change |
| @@ -191,7 +217,11 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
| 191 | *header = SPEED_4000000; | 217 | *header = SPEED_4000000; |
| 192 | self->new_xbofs = 0; | 218 | self->new_xbofs = 0; |
| 193 | break; | 219 | break; |
| 194 | } | 220 | case 16000000: |
| 221 | *header = SPEED_16000000; | ||
| 222 | self->new_xbofs = 0; | ||
| 223 | break; | ||
| 224 | } | ||
| 195 | } else | 225 | } else |
| 196 | /* No change */ | 226 | /* No change */ |
| 197 | *header = 0; | 227 | *header = 0; |
| @@ -235,6 +265,32 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
| 235 | } | 265 | } |
| 236 | } | 266 | } |
| 237 | 267 | ||
| 268 | /* | ||
| 269 | * calculate turnaround time for SigmaTel header | ||
| 270 | */ | ||
| 271 | static __u8 get_turnaround_time(struct sk_buff *skb) | ||
| 272 | { | ||
| 273 | int turnaround_time = irda_get_mtt(skb); | ||
| 274 | |||
| 275 | if ( turnaround_time == 0 ) | ||
| 276 | return 0; | ||
| 277 | else if ( turnaround_time <= 10 ) | ||
| 278 | return 1; | ||
| 279 | else if ( turnaround_time <= 50 ) | ||
| 280 | return 2; | ||
| 281 | else if ( turnaround_time <= 100 ) | ||
| 282 | return 3; | ||
| 283 | else if ( turnaround_time <= 500 ) | ||
| 284 | return 4; | ||
| 285 | else if ( turnaround_time <= 1000 ) | ||
| 286 | return 5; | ||
| 287 | else if ( turnaround_time <= 5000 ) | ||
| 288 | return 6; | ||
| 289 | else | ||
| 290 | return 7; | ||
| 291 | } | ||
| 292 | |||
| 293 | |||
| 238 | /*------------------------------------------------------------------*/ | 294 | /*------------------------------------------------------------------*/ |
| 239 | /* | 295 | /* |
| 240 | * Send a command to change the speed of the dongle | 296 | * Send a command to change the speed of the dongle |
| @@ -262,12 +318,18 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) | |||
| 262 | /* Set the new speed and xbofs in this fake frame */ | 318 | /* Set the new speed and xbofs in this fake frame */ |
| 263 | irda_usb_build_header(self, frame, 1); | 319 | irda_usb_build_header(self, frame, 1); |
| 264 | 320 | ||
| 321 | if ( self->capability & IUC_STIR_4210 ) { | ||
| 322 | if (frame[0] == 0) return ; // do nothing if no change | ||
| 323 | frame[1] = 0; // other parameters don't change here | ||
| 324 | frame[2] = 0; | ||
| 325 | } | ||
| 326 | |||
| 265 | /* Submit the 0 length IrDA frame to trigger new speed settings */ | 327 | /* Submit the 0 length IrDA frame to trigger new speed settings */ |
| 266 | usb_fill_bulk_urb(urb, self->usbdev, | 328 | usb_fill_bulk_urb(urb, self->usbdev, |
| 267 | usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), | 329 | usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), |
| 268 | frame, IRDA_USB_SPEED_MTU, | 330 | frame, IRDA_USB_SPEED_MTU, |
| 269 | speed_bulk_callback, self); | 331 | speed_bulk_callback, self); |
| 270 | urb->transfer_buffer_length = USB_IRDA_HEADER; | 332 | urb->transfer_buffer_length = self->header_length; |
| 271 | urb->transfer_flags = 0; | 333 | urb->transfer_flags = 0; |
| 272 | 334 | ||
| 273 | /* Irq disabled -> GFP_ATOMIC */ | 335 | /* Irq disabled -> GFP_ATOMIC */ |
| @@ -383,16 +445,35 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
| 383 | * allocation will be done lower in skb_push(). | 445 | * allocation will be done lower in skb_push(). |
| 384 | * Also, we don't use directly skb_cow(), because it require | 446 | * Also, we don't use directly skb_cow(), because it require |
| 385 | * headroom >= 16, which force unnecessary copies - Jean II */ | 447 | * headroom >= 16, which force unnecessary copies - Jean II */ |
| 386 | if (skb_headroom(skb) < USB_IRDA_HEADER) { | 448 | if (skb_headroom(skb) < self->header_length) { |
| 387 | IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); | 449 | IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); |
| 388 | if (skb_cow(skb, USB_IRDA_HEADER)) { | 450 | if (skb_cow(skb, self->header_length)) { |
| 389 | IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); | 451 | IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); |
| 390 | goto drop; | 452 | goto drop; |
| 391 | } | 453 | } |
| 392 | } | 454 | } |
| 393 | 455 | ||
| 394 | /* Change setting for next frame */ | 456 | /* Change setting for next frame */ |
| 395 | irda_usb_build_header(self, skb_push(skb, USB_IRDA_HEADER), 0); | 457 | |
| 458 | if ( self->capability & IUC_STIR_4210 ) { | ||
| 459 | __u8 turnaround_time; | ||
| 460 | __u8* frame; | ||
| 461 | turnaround_time = get_turnaround_time( skb ); | ||
| 462 | frame= skb_push(skb, self->header_length); | ||
| 463 | irda_usb_build_header(self, frame, 0); | ||
| 464 | frame[2] = turnaround_time; | ||
| 465 | if ((skb->len != 0) && | ||
| 466 | ((skb->len % 128) == 0) && | ||
| 467 | ((skb->len % 512) != 0)) { | ||
| 468 | /* add extra byte for special SigmaTel feature */ | ||
| 469 | frame[1] = 1; | ||
| 470 | skb_put(skb, 1); | ||
| 471 | } else { | ||
| 472 | frame[1] = 0; | ||
| 473 | } | ||
| 474 | } else { | ||
| 475 | irda_usb_build_header(self, skb_push(skb, self->header_length), 0); | ||
| 476 | } | ||
| 396 | 477 | ||
| 397 | /* FIXME: Make macro out of this one */ | 478 | /* FIXME: Make macro out of this one */ |
| 398 | ((struct irda_skb_cb *)skb->cb)->context = self; | 479 | ((struct irda_skb_cb *)skb->cb)->context = self; |
| @@ -795,7 +876,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
| 795 | } | 876 | } |
| 796 | 877 | ||
| 797 | /* Check for empty frames */ | 878 | /* Check for empty frames */ |
| 798 | if (urb->actual_length <= USB_IRDA_HEADER) { | 879 | if (urb->actual_length <= self->header_length) { |
| 799 | IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); | 880 | IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); |
| 800 | goto done; | 881 | goto done; |
| 801 | } | 882 | } |
| @@ -816,7 +897,11 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
| 816 | docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); | 897 | docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); |
| 817 | 898 | ||
| 818 | /* Allocate a new skb */ | 899 | /* Allocate a new skb */ |
| 819 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); | 900 | if ( self->capability & IUC_STIR_4210 ) |
| 901 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU + USB_IRDA_SIGMATEL_HEADER); | ||
| 902 | else | ||
| 903 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); | ||
| 904 | |||
| 820 | if (!newskb) { | 905 | if (!newskb) { |
| 821 | self->stats.rx_dropped++; | 906 | self->stats.rx_dropped++; |
| 822 | /* We could deliver the current skb, but this would stall | 907 | /* We could deliver the current skb, but this would stall |
| @@ -845,7 +930,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
| 845 | 930 | ||
| 846 | /* Set proper length on skb & remove USB-IrDA header */ | 931 | /* Set proper length on skb & remove USB-IrDA header */ |
| 847 | skb_put(dataskb, urb->actual_length); | 932 | skb_put(dataskb, urb->actual_length); |
| 848 | skb_pull(dataskb, USB_IRDA_HEADER); | 933 | skb_pull(dataskb, self->header_length); |
| 849 | 934 | ||
| 850 | /* Ask the networking layer to queue the packet for the IrDA stack */ | 935 | /* Ask the networking layer to queue the packet for the IrDA stack */ |
| 851 | dataskb->dev = self->netdev; | 936 | dataskb->dev = self->netdev; |
| @@ -937,6 +1022,191 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) | |||
| 937 | return 0; /* For now */ | 1022 | return 0; /* For now */ |
| 938 | } | 1023 | } |
| 939 | 1024 | ||
| 1025 | |||
| 1026 | #define STIR421X_PATCH_PRODUCT_VERSION_STR "Product Version: " | ||
| 1027 | #define STIR421X_PATCH_COMPONENT_VERSION_STR "Component Version: " | ||
| 1028 | #define STIR421X_PATCH_DATA_TAG_STR "STMP" | ||
| 1029 | #define STIR421X_PATCH_FILE_VERSION_MAX_OFFSET 512 /* version info is before here */ | ||
| 1030 | #define STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET 512 /* patch image starts before here */ | ||
| 1031 | #define STIR421X_PATCH_FILE_END_OF_HEADER_TAG 0x1A /* marks end of patch file header (PC DOS text file EOF character) */ | ||
| 1032 | |||
| 1033 | /* | ||
| 1034 | * Known firmware patches for STIR421x dongles | ||
| 1035 | */ | ||
| 1036 | static char * stir421x_patches[] = { | ||
| 1037 | "42101001.sb", | ||
| 1038 | "42101002.sb", | ||
| 1039 | }; | ||
| 1040 | |||
| 1041 | static int stir421x_get_patch_version(unsigned char * patch, const unsigned long patch_len) | ||
| 1042 | { | ||
| 1043 | unsigned int version_offset; | ||
| 1044 | unsigned long version_major, version_minor, version_build; | ||
| 1045 | unsigned char * version_start; | ||
| 1046 | int version_found = 0; | ||
| 1047 | |||
| 1048 | for (version_offset = 0; | ||
| 1049 | version_offset < STIR421X_PATCH_FILE_END_OF_HEADER_TAG; | ||
| 1050 | version_offset++) { | ||
| 1051 | if (!memcmp(patch + version_offset, | ||
| 1052 | STIR421X_PATCH_PRODUCT_VERSION_STR, | ||
| 1053 | sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1)) { | ||
| 1054 | version_found = 1; | ||
| 1055 | version_start = patch + | ||
| 1056 | version_offset + | ||
| 1057 | sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1; | ||
| 1058 | break; | ||
| 1059 | } | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | /* We couldn't find a product version on this patch */ | ||
| 1063 | if (!version_found) | ||
| 1064 | return -EINVAL; | ||
| 1065 | |||
| 1066 | /* Let's check if the product version is dotted */ | ||
| 1067 | if (version_start[3] != '.' || | ||
| 1068 | version_start[7] != '.') | ||
| 1069 | return -EINVAL; | ||
| 1070 | |||
| 1071 | version_major = simple_strtoul(version_start, NULL, 10); | ||
| 1072 | version_minor = simple_strtoul(version_start + 4, NULL, 10); | ||
| 1073 | version_build = simple_strtoul(version_start + 8, NULL, 10); | ||
| 1074 | |||
| 1075 | IRDA_DEBUG(2, "%s(), Major: %ld Minor: %ld Build: %ld\n", | ||
| 1076 | __FUNCTION__, | ||
| 1077 | version_major, version_minor, version_build); | ||
| 1078 | |||
| 1079 | return (((version_major) << 12) + | ||
| 1080 | ((version_minor) << 8) + | ||
| 1081 | ((version_build / 10) << 4) + | ||
| 1082 | (version_build % 10)); | ||
| 1083 | |||
| 1084 | } | ||
| 1085 | |||
| 1086 | |||
| 1087 | static int stir421x_upload_patch (struct irda_usb_cb *self, | ||
| 1088 | unsigned char * patch, | ||
| 1089 | const unsigned int patch_len) | ||
| 1090 | { | ||
| 1091 | int retval = 0; | ||
| 1092 | int actual_len; | ||
| 1093 | unsigned int i = 0, download_amount = 0; | ||
| 1094 | unsigned char * patch_chunk; | ||
| 1095 | |||
| 1096 | IRDA_DEBUG (2, "%s(), Uploading STIR421x Patch\n", __FUNCTION__); | ||
| 1097 | |||
| 1098 | patch_chunk = kzalloc(STIR421X_MAX_PATCH_DOWNLOAD_SIZE, GFP_KERNEL); | ||
| 1099 | if (patch_chunk == NULL) | ||
| 1100 | return -ENOMEM; | ||
| 1101 | |||
| 1102 | /* break up patch into 1023-byte sections */ | ||
| 1103 | for (i = 0; retval >= 0 && i < patch_len; i += download_amount) { | ||
| 1104 | download_amount = patch_len - i; | ||
| 1105 | if (download_amount > STIR421X_MAX_PATCH_DOWNLOAD_SIZE) | ||
| 1106 | download_amount = STIR421X_MAX_PATCH_DOWNLOAD_SIZE; | ||
| 1107 | |||
| 1108 | /* download the patch section */ | ||
| 1109 | memcpy(patch_chunk, patch + i, download_amount); | ||
| 1110 | |||
| 1111 | retval = usb_bulk_msg (self->usbdev, | ||
| 1112 | usb_sndbulkpipe (self->usbdev, | ||
| 1113 | self->bulk_out_ep), | ||
| 1114 | patch_chunk, download_amount, | ||
| 1115 | &actual_len, msecs_to_jiffies (500)); | ||
| 1116 | IRDA_DEBUG (2, "%s(), Sent %u bytes\n", __FUNCTION__, | ||
| 1117 | actual_len); | ||
| 1118 | if (retval == 0) | ||
| 1119 | mdelay(10); | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | kfree(patch_chunk); | ||
| 1123 | |||
| 1124 | if (i != patch_len) { | ||
| 1125 | IRDA_ERROR ("%s(), Pushed %d bytes (!= patch_len (%d))\n", | ||
| 1126 | __FUNCTION__, i, patch_len); | ||
| 1127 | retval = -EIO; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | if (retval < 0) | ||
| 1131 | /* todo - mark device as not ready */ | ||
| 1132 | IRDA_ERROR ("%s(), STIR421x patch upload failed (%d)\n", | ||
| 1133 | __FUNCTION__, retval); | ||
| 1134 | |||
| 1135 | return retval; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | |||
| 1139 | static int stir421x_patch_device(struct irda_usb_cb *self) | ||
| 1140 | { | ||
| 1141 | unsigned int i, patch_found = 0, data_found = 0, data_offset; | ||
| 1142 | int patch_version, ret = 0; | ||
| 1143 | const struct firmware *fw_entry; | ||
| 1144 | |||
| 1145 | for (i = 0; i < ARRAY_SIZE(stir421x_patches); i++) { | ||
| 1146 | if(request_firmware(&fw_entry, stir421x_patches[i], &self->usbdev->dev) != 0) { | ||
| 1147 | IRDA_ERROR( "%s(), Patch %s is not available\n", __FUNCTION__, stir421x_patches[i]); | ||
| 1148 | continue; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | /* We found a patch from userspace */ | ||
| 1152 | patch_version = stir421x_get_patch_version (fw_entry->data, fw_entry->size); | ||
| 1153 | |||
| 1154 | if (patch_version < 0) { | ||
| 1155 | /* Couldn't fetch a version, let's move on to the next file */ | ||
| 1156 | IRDA_ERROR("%s(), version parsing failed\n", __FUNCTION__); | ||
| 1157 | ret = patch_version; | ||
| 1158 | release_firmware(fw_entry); | ||
| 1159 | continue; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | if (patch_version != self->usbdev->descriptor.bcdDevice) { | ||
| 1163 | /* Patch version and device don't match */ | ||
| 1164 | IRDA_ERROR ("%s(), wrong patch version (%d <-> %d)\n", | ||
| 1165 | __FUNCTION__, | ||
| 1166 | patch_version, self->usbdev->descriptor.bcdDevice); | ||
| 1167 | ret = -EINVAL; | ||
| 1168 | release_firmware(fw_entry); | ||
| 1169 | continue; | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | /* If we're here, we've found a correct patch */ | ||
| 1173 | patch_found = 1; | ||
| 1174 | break; | ||
| 1175 | |||
| 1176 | } | ||
| 1177 | |||
| 1178 | /* We couldn't find a valid firmware, let's leave */ | ||
| 1179 | if (!patch_found) | ||
| 1180 | return ret; | ||
| 1181 | |||
| 1182 | /* The actual image starts after the "STMP" keyword */ | ||
| 1183 | for (data_offset = 0; data_offset < STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET; data_offset++) { | ||
| 1184 | if (!memcmp(fw_entry->data + data_offset, | ||
| 1185 | STIR421X_PATCH_DATA_TAG_STR, | ||
| 1186 | sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))) { | ||
| 1187 | IRDA_DEBUG(2, "%s(), found patch data for STIR421x at offset %d\n", | ||
| 1188 | __FUNCTION__, data_offset); | ||
| 1189 | data_found = 1; | ||
| 1190 | break; | ||
| 1191 | } | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | /* We couldn't find "STMP" from the header */ | ||
| 1195 | if (!data_found) | ||
| 1196 | return -EINVAL; | ||
| 1197 | |||
| 1198 | /* Let's upload the patch to the target */ | ||
| 1199 | ret = stir421x_upload_patch(self, | ||
| 1200 | &fw_entry->data[data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)], | ||
| 1201 | fw_entry->size - (data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))); | ||
| 1202 | |||
| 1203 | release_firmware(fw_entry); | ||
| 1204 | |||
| 1205 | return ret; | ||
| 1206 | |||
| 1207 | } | ||
| 1208 | |||
| 1209 | |||
| 940 | /********************** IRDA DEVICE CALLBACKS **********************/ | 1210 | /********************** IRDA DEVICE CALLBACKS **********************/ |
| 941 | /* | 1211 | /* |
| 942 | * Main calls from the IrDA/Network subsystem. | 1212 | * Main calls from the IrDA/Network subsystem. |
| @@ -972,6 +1242,11 @@ static int irda_usb_net_open(struct net_device *netdev) | |||
| 972 | return -1; | 1242 | return -1; |
| 973 | } | 1243 | } |
| 974 | 1244 | ||
| 1245 | if(self->needspatch) { | ||
| 1246 | IRDA_WARNING("%s(), device needs patch\n", __FUNCTION__) ; | ||
| 1247 | return -EIO ; | ||
| 1248 | } | ||
| 1249 | |||
| 975 | /* Initialise default speed and xbofs value | 1250 | /* Initialise default speed and xbofs value |
| 976 | * (IrLAP will change that soon) */ | 1251 | * (IrLAP will change that soon) */ |
| 977 | self->speed = -1; | 1252 | self->speed = -1; |
| @@ -1050,7 +1325,7 @@ static int irda_usb_net_close(struct net_device *netdev) | |||
| 1050 | del_timer(&self->rx_defer_timer); | 1325 | del_timer(&self->rx_defer_timer); |
| 1051 | 1326 | ||
| 1052 | /* Deallocate all the Rx path buffers (URBs and skb) */ | 1327 | /* Deallocate all the Rx path buffers (URBs and skb) */ |
| 1053 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1328 | for (i = 0; i < self->max_rx_urb; i++) { |
| 1054 | struct urb *urb = self->rx_urb[i]; | 1329 | struct urb *urb = self->rx_urb[i]; |
| 1055 | struct sk_buff *skb = (struct sk_buff *) urb->context; | 1330 | struct sk_buff *skb = (struct sk_buff *) urb->context; |
| 1056 | /* Cancel the receive command */ | 1331 | /* Cancel the receive command */ |
| @@ -1426,8 +1701,22 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
| 1426 | spin_lock_init(&self->lock); | 1701 | spin_lock_init(&self->lock); |
| 1427 | init_timer(&self->rx_defer_timer); | 1702 | init_timer(&self->rx_defer_timer); |
| 1428 | 1703 | ||
| 1704 | self->capability = id->driver_info; | ||
| 1705 | self->needspatch = ((self->capability & IUC_STIR_4210) != 0) ; | ||
| 1706 | |||
| 1429 | /* Create all of the needed urbs */ | 1707 | /* Create all of the needed urbs */ |
| 1430 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1708 | if (self->capability & IUC_STIR_4210) { |
| 1709 | self->max_rx_urb = IU_SIGMATEL_MAX_RX_URBS; | ||
| 1710 | self->header_length = USB_IRDA_SIGMATEL_HEADER; | ||
| 1711 | } else { | ||
| 1712 | self->max_rx_urb = IU_MAX_RX_URBS; | ||
| 1713 | self->header_length = USB_IRDA_HEADER; | ||
| 1714 | } | ||
| 1715 | |||
| 1716 | self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *), | ||
| 1717 | GFP_KERNEL); | ||
| 1718 | |||
| 1719 | for (i = 0; i < self->max_rx_urb; i++) { | ||
| 1431 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); | 1720 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); |
| 1432 | if (!self->rx_urb[i]) { | 1721 | if (!self->rx_urb[i]) { |
| 1433 | goto err_out_1; | 1722 | goto err_out_1; |
| @@ -1479,17 +1768,28 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
| 1479 | goto err_out_3; | 1768 | goto err_out_3; |
| 1480 | } | 1769 | } |
| 1481 | 1770 | ||
| 1771 | self->usbdev = dev; | ||
| 1772 | |||
| 1482 | /* Find IrDA class descriptor */ | 1773 | /* Find IrDA class descriptor */ |
| 1483 | irda_desc = irda_usb_find_class_desc(intf); | 1774 | irda_desc = irda_usb_find_class_desc(intf); |
| 1484 | ret = -ENODEV; | 1775 | ret = -ENODEV; |
| 1485 | if (irda_desc == NULL) | 1776 | if (irda_desc == NULL) |
| 1486 | goto err_out_3; | 1777 | goto err_out_3; |
| 1487 | 1778 | ||
| 1779 | if (self->needspatch) { | ||
| 1780 | ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), | ||
| 1781 | 0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500)); | ||
| 1782 | if (ret < 0) { | ||
| 1783 | IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); | ||
| 1784 | goto err_out_3; | ||
| 1785 | } else { | ||
| 1786 | mdelay(10); | ||
| 1787 | } | ||
| 1788 | } | ||
| 1789 | |||
| 1488 | self->irda_desc = irda_desc; | 1790 | self->irda_desc = irda_desc; |
| 1489 | self->present = 1; | 1791 | self->present = 1; |
| 1490 | self->netopen = 0; | 1792 | self->netopen = 0; |
| 1491 | self->capability = id->driver_info; | ||
| 1492 | self->usbdev = dev; | ||
| 1493 | self->usbintf = intf; | 1793 | self->usbintf = intf; |
| 1494 | 1794 | ||
| 1495 | /* Allocate the buffer for speed changes */ | 1795 | /* Allocate the buffer for speed changes */ |
| @@ -1508,6 +1808,28 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
| 1508 | 1808 | ||
| 1509 | IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); | 1809 | IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); |
| 1510 | usb_set_intfdata(intf, self); | 1810 | usb_set_intfdata(intf, self); |
| 1811 | |||
| 1812 | if (self->needspatch) { | ||
| 1813 | /* Now we fetch and upload the firmware patch */ | ||
| 1814 | ret = stir421x_patch_device(self); | ||
| 1815 | self->needspatch = (ret < 0); | ||
| 1816 | if (ret < 0) { | ||
| 1817 | printk("patch_device failed\n"); | ||
| 1818 | goto err_out_4; | ||
| 1819 | } | ||
| 1820 | |||
| 1821 | /* replace IrDA class descriptor with what patched device is now reporting */ | ||
| 1822 | irda_desc = irda_usb_find_class_desc (self->usbintf); | ||
| 1823 | if (irda_desc == NULL) { | ||
| 1824 | ret = -ENODEV; | ||
| 1825 | goto err_out_4; | ||
| 1826 | } | ||
| 1827 | if (self->irda_desc) | ||
| 1828 | kfree (self->irda_desc); | ||
| 1829 | self->irda_desc = irda_desc; | ||
| 1830 | irda_usb_init_qos(self); | ||
| 1831 | } | ||
| 1832 | |||
| 1511 | return 0; | 1833 | return 0; |
| 1512 | 1834 | ||
| 1513 | err_out_4: | 1835 | err_out_4: |
| @@ -1518,7 +1840,7 @@ err_out_3: | |||
| 1518 | err_out_2: | 1840 | err_out_2: |
| 1519 | usb_free_urb(self->tx_urb); | 1841 | usb_free_urb(self->tx_urb); |
| 1520 | err_out_1: | 1842 | err_out_1: |
| 1521 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1843 | for (i = 0; i < self->max_rx_urb; i++) { |
| 1522 | if (self->rx_urb[i]) | 1844 | if (self->rx_urb[i]) |
| 1523 | usb_free_urb(self->rx_urb[i]); | 1845 | usb_free_urb(self->rx_urb[i]); |
| 1524 | } | 1846 | } |
| @@ -1571,7 +1893,7 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
| 1571 | /*netif_device_detach(self->netdev);*/ | 1893 | /*netif_device_detach(self->netdev);*/ |
| 1572 | netif_stop_queue(self->netdev); | 1894 | netif_stop_queue(self->netdev); |
| 1573 | /* Stop all the receive URBs. Must be synchronous. */ | 1895 | /* Stop all the receive URBs. Must be synchronous. */ |
| 1574 | for (i = 0; i < IU_MAX_RX_URBS; i++) | 1896 | for (i = 0; i < self->max_rx_urb; i++) |
| 1575 | usb_kill_urb(self->rx_urb[i]); | 1897 | usb_kill_urb(self->rx_urb[i]); |
| 1576 | /* Cancel Tx and speed URB. | 1898 | /* Cancel Tx and speed URB. |
| 1577 | * Make sure it's synchronous to avoid races. */ | 1899 | * Make sure it's synchronous to avoid races. */ |
| @@ -1586,8 +1908,9 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
| 1586 | self->usbintf = NULL; | 1908 | self->usbintf = NULL; |
| 1587 | 1909 | ||
| 1588 | /* Clean up our urbs */ | 1910 | /* Clean up our urbs */ |
| 1589 | for (i = 0; i < IU_MAX_RX_URBS; i++) | 1911 | for (i = 0; i < self->max_rx_urb; i++) |
| 1590 | usb_free_urb(self->rx_urb[i]); | 1912 | usb_free_urb(self->rx_urb[i]); |
| 1913 | kfree(self->rx_urb); | ||
| 1591 | /* Clean up Tx and speed URB */ | 1914 | /* Clean up Tx and speed URB */ |
| 1592 | usb_free_urb(self->tx_urb); | 1915 | usb_free_urb(self->tx_urb); |
| 1593 | usb_free_urb(self->speed_urb); | 1916 | usb_free_urb(self->speed_urb); |
| @@ -1648,6 +1971,6 @@ module_exit(usb_irda_cleanup); | |||
| 1648 | */ | 1971 | */ |
| 1649 | module_param(qos_mtt_bits, int, 0); | 1972 | module_param(qos_mtt_bits, int, 0); |
| 1650 | MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); | 1973 | MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); |
| 1651 | MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net> and Jean Tourrilhes <jt@hpl.hp.com>"); | 1974 | MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net>, Jean Tourrilhes <jt@hpl.hp.com> and Nick Fedchik <nick@fedchik.org.ua>"); |
| 1652 | MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); | 1975 | MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); |
| 1653 | MODULE_LICENSE("GPL"); | 1976 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index 4026af42dd47..d833db52cebf 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Filename: irda-usb.h | 3 | * Filename: irda-usb.h |
| 4 | * Version: 0.9b | 4 | * Version: 0.10 |
| 5 | * Description: IrDA-USB Driver | 5 | * Description: IrDA-USB Driver |
| 6 | * Status: Experimental | 6 | * Status: Experimental |
| 7 | * Author: Dag Brattli <dag@brattli.net> | 7 | * Author: Dag Brattli <dag@brattli.net> |
| @@ -9,6 +9,9 @@ | |||
| 9 | * Copyright (C) 2001, Roman Weissgaerber <weissg@vienna.at> | 9 | * Copyright (C) 2001, Roman Weissgaerber <weissg@vienna.at> |
| 10 | * Copyright (C) 2000, Dag Brattli <dag@brattli.net> | 10 | * Copyright (C) 2000, Dag Brattli <dag@brattli.net> |
| 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> | 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> |
| 12 | * Copyright (C) 2004, SigmaTel, Inc. <irquality@sigmatel.com> | ||
| 13 | * Copyright (C) 2005, Milan Beno <beno@pobox.sk> | ||
| 14 | * Copyright (C) 2006, Nick FEdchik <nick@fedchik.org.ua> | ||
| 12 | * | 15 | * |
| 13 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
| 14 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
| @@ -31,6 +34,9 @@ | |||
| 31 | #include <net/irda/irda.h> | 34 | #include <net/irda/irda.h> |
| 32 | #include <net/irda/irda_device.h> /* struct irlap_cb */ | 35 | #include <net/irda/irda_device.h> /* struct irlap_cb */ |
| 33 | 36 | ||
| 37 | #define PATCH_FILE_SIZE_MAX 65536 | ||
| 38 | #define PATCH_FILE_SIZE_MIN 80 | ||
| 39 | |||
| 34 | #define RX_COPY_THRESHOLD 200 | 40 | #define RX_COPY_THRESHOLD 200 |
| 35 | #define IRDA_USB_MAX_MTU 2051 | 41 | #define IRDA_USB_MAX_MTU 2051 |
| 36 | #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ | 42 | #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ |
| @@ -79,15 +85,16 @@ | |||
| 79 | /* Inbound header */ | 85 | /* Inbound header */ |
| 80 | #define MEDIA_BUSY 0x80 | 86 | #define MEDIA_BUSY 0x80 |
| 81 | 87 | ||
| 82 | #define SPEED_2400 0x01 | 88 | #define SPEED_2400 0x01 |
| 83 | #define SPEED_9600 0x02 | 89 | #define SPEED_9600 0x02 |
| 84 | #define SPEED_19200 0x03 | 90 | #define SPEED_19200 0x03 |
| 85 | #define SPEED_38400 0x04 | 91 | #define SPEED_38400 0x04 |
| 86 | #define SPEED_57600 0x05 | 92 | #define SPEED_57600 0x05 |
| 87 | #define SPEED_115200 0x06 | 93 | #define SPEED_115200 0x06 |
| 88 | #define SPEED_576000 0x07 | 94 | #define SPEED_576000 0x07 |
| 89 | #define SPEED_1152000 0x08 | 95 | #define SPEED_1152000 0x08 |
| 90 | #define SPEED_4000000 0x09 | 96 | #define SPEED_4000000 0x09 |
| 97 | #define SPEED_16000000 0x0a | ||
| 91 | 98 | ||
| 92 | /* Basic capabilities */ | 99 | /* Basic capabilities */ |
| 93 | #define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ | 100 | #define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ |
| @@ -100,11 +107,14 @@ | |||
| 100 | #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ | 107 | #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ |
| 101 | #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ | 108 | #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ |
| 102 | #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ | 109 | #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ |
| 110 | #define IUC_STIR_4210 0x80 /* SigmaTel 4210/4220/4116 VFIR */ | ||
| 103 | 111 | ||
| 104 | /* USB class definitions */ | 112 | /* USB class definitions */ |
| 105 | #define USB_IRDA_HEADER 0x01 | 113 | #define USB_IRDA_HEADER 0x01 |
| 106 | #define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ | 114 | #define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ |
| 107 | #define USB_DT_IRDA 0x21 | 115 | #define USB_DT_IRDA 0x21 |
| 116 | #define USB_IRDA_SIGMATEL_HEADER 0x03 | ||
| 117 | #define IU_SIGMATEL_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + USB_IRDA_SIGMATEL_HEADER) | ||
| 108 | 118 | ||
| 109 | struct irda_class_desc { | 119 | struct irda_class_desc { |
| 110 | __u8 bLength; | 120 | __u8 bLength; |
| @@ -123,6 +133,7 @@ struct irda_class_desc { | |||
| 123 | * (6.2.5, USB-IrDA class spec 1.0) */ | 133 | * (6.2.5, USB-IrDA class spec 1.0) */ |
| 124 | 134 | ||
| 125 | #define IU_REQ_GET_CLASS_DESC 0x06 | 135 | #define IU_REQ_GET_CLASS_DESC 0x06 |
| 136 | #define STIR421X_MAX_PATCH_DOWNLOAD_SIZE 1023 | ||
| 126 | 137 | ||
| 127 | struct irda_usb_cb { | 138 | struct irda_usb_cb { |
| 128 | struct irda_class_desc *irda_desc; | 139 | struct irda_class_desc *irda_desc; |
| @@ -136,7 +147,8 @@ struct irda_usb_cb { | |||
| 136 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ | 147 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ |
| 137 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ | 148 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ |
| 138 | 149 | ||
| 139 | struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ | 150 | __u8 max_rx_urb; |
| 151 | struct urb **rx_urb; /* URBs used to receive data frames */ | ||
| 140 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ | 152 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ |
| 141 | struct urb *tx_urb; /* URB used to send data frames */ | 153 | struct urb *tx_urb; /* URB used to send data frames */ |
| 142 | struct urb *speed_urb; /* URB used to send speed commands */ | 154 | struct urb *speed_urb; /* URB used to send speed commands */ |
| @@ -157,6 +169,9 @@ struct irda_usb_cb { | |||
| 157 | __u32 speed; /* Current speed */ | 169 | __u32 speed; /* Current speed */ |
| 158 | __s32 new_speed; /* speed we need to set */ | 170 | __s32 new_speed; /* speed we need to set */ |
| 159 | 171 | ||
| 172 | __u8 header_length; /* USB-IrDA frame header size */ | ||
| 173 | int needspatch; /* device needs firmware patch */ | ||
| 174 | |||
| 160 | struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ | 175 | struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ |
| 161 | }; | 176 | }; |
| 162 | 177 | ||
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index ec94ecdb103d..bbcfc8ec35a1 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | * Copyright (c) 2002 Daniele Peri | 11 | * Copyright (c) 2002 Daniele Peri |
| 12 | * All Rights Reserved. | 12 | * All Rights Reserved. |
| 13 | * Copyright (c) 2002 Jean Tourrilhes | 13 | * Copyright (c) 2002 Jean Tourrilhes |
| 14 | * Copyright (c) 2006 Linus Walleij | ||
| 14 | * | 15 | * |
| 15 | * | 16 | * |
| 16 | * Based on smc-ircc.c: | 17 | * Based on smc-ircc.c: |
| @@ -61,6 +62,9 @@ | |||
| 61 | 62 | ||
| 62 | #include <linux/spinlock.h> | 63 | #include <linux/spinlock.h> |
| 63 | #include <linux/pm.h> | 64 | #include <linux/pm.h> |
| 65 | #ifdef CONFIG_PCI | ||
| 66 | #include <linux/pci.h> | ||
| 67 | #endif | ||
| 64 | 68 | ||
| 65 | #include <net/irda/wrapper.h> | 69 | #include <net/irda/wrapper.h> |
| 66 | #include <net/irda/irda.h> | 70 | #include <net/irda/irda.h> |
| @@ -100,6 +104,22 @@ MODULE_PARM_DESC(ircc_transceiver, "Transceiver type"); | |||
| 100 | 104 | ||
| 101 | /* Types */ | 105 | /* Types */ |
| 102 | 106 | ||
| 107 | #ifdef CONFIG_PCI | ||
| 108 | struct smsc_ircc_subsystem_configuration { | ||
| 109 | unsigned short vendor; /* PCI vendor ID */ | ||
| 110 | unsigned short device; /* PCI vendor ID */ | ||
| 111 | unsigned short subvendor; /* PCI subsystem vendor ID */ | ||
| 112 | unsigned short subdevice; /* PCI sybsystem device ID */ | ||
| 113 | unsigned short sir_io; /* I/O port for SIR */ | ||
| 114 | unsigned short fir_io; /* I/O port for FIR */ | ||
| 115 | unsigned char fir_irq; /* FIR IRQ */ | ||
| 116 | unsigned char fir_dma; /* FIR DMA */ | ||
| 117 | unsigned short cfg_base; /* I/O port for chip configuration */ | ||
| 118 | int (*preconfigure)(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); /* Preconfig function */ | ||
| 119 | const char *name; /* name shown as info */ | ||
| 120 | }; | ||
| 121 | #endif | ||
| 122 | |||
| 103 | struct smsc_transceiver { | 123 | struct smsc_transceiver { |
| 104 | char *name; | 124 | char *name; |
| 105 | void (*set_for_speed)(int fir_base, u32 speed); | 125 | void (*set_for_speed)(int fir_base, u32 speed); |
| @@ -202,6 +222,16 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor | |||
| 202 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); | 222 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); |
| 203 | static int __init smsc_superio_fdc(unsigned short cfg_base); | 223 | static int __init smsc_superio_fdc(unsigned short cfg_base); |
| 204 | static int __init smsc_superio_lpc(unsigned short cfg_base); | 224 | static int __init smsc_superio_lpc(unsigned short cfg_base); |
| 225 | #ifdef CONFIG_PCI | ||
| 226 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); | ||
| 227 | static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | ||
| 228 | static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | ||
| 229 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | ||
| 230 | unsigned short ircc_fir, | ||
| 231 | unsigned short ircc_sir, | ||
| 232 | unsigned char ircc_dma, | ||
| 233 | unsigned char ircc_irq); | ||
| 234 | #endif | ||
| 205 | 235 | ||
| 206 | /* Transceivers specific functions */ | 236 | /* Transceivers specific functions */ |
| 207 | 237 | ||
| @@ -353,6 +383,13 @@ static int __init smsc_ircc_init(void) | |||
| 353 | return ret; | 383 | return ret; |
| 354 | } | 384 | } |
| 355 | 385 | ||
| 386 | #ifdef CONFIG_PCI | ||
| 387 | if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { | ||
| 388 | /* Ignore errors from preconfiguration */ | ||
| 389 | IRDA_ERROR("%s, Preconfiguration failed !\n", driver_name); | ||
| 390 | } | ||
| 391 | #endif | ||
| 392 | |||
| 356 | dev_count = 0; | 393 | dev_count = 0; |
| 357 | 394 | ||
| 358 | if (ircc_fir > 0 && ircc_sir > 0) { | 395 | if (ircc_fir > 0 && ircc_sir > 0) { |
| @@ -2285,6 +2322,280 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) | |||
| 2285 | return ret; | 2322 | return ret; |
| 2286 | } | 2323 | } |
| 2287 | 2324 | ||
| 2325 | /* | ||
| 2326 | * Look for some specific subsystem setups that need | ||
| 2327 | * pre-configuration not properly done by the BIOS (especially laptops) | ||
| 2328 | * This code is based in part on smcinit.c, tosh1800-smcinit.c | ||
| 2329 | * and tosh2450-smcinit.c. The table lists the device entries | ||
| 2330 | * for ISA bridges with an LPC (Local Peripheral Configurator) | ||
| 2331 | * that are in turn used to configure the SMSC device with default | ||
| 2332 | * SIR and FIR I/O ports, DMA and IRQ. | ||
| 2333 | */ | ||
| 2334 | #ifdef CONFIG_PCI | ||
| 2335 | #define PCIID_VENDOR_INTEL 0x8086 | ||
| 2336 | #define PCIID_VENDOR_ALI 0x10b9 | ||
| 2337 | static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitdata = { | ||
| 2338 | { | ||
| 2339 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ | ||
| 2340 | .device = 0x24cc, | ||
| 2341 | .subvendor = 0x103c, | ||
| 2342 | .subdevice = 0x088c, | ||
| 2343 | .sir_io = 0x02f8, /* Quite certain these are the same for nc8000 as for nc6000 */ | ||
| 2344 | .fir_io = 0x0130, | ||
| 2345 | .fir_irq = 0x09, | ||
| 2346 | .fir_dma = 0x03, | ||
| 2347 | .cfg_base = 0x004e, | ||
| 2348 | .preconfigure = preconfigure_through_82801, | ||
| 2349 | .name = "HP nc8000", | ||
| 2350 | }, | ||
| 2351 | { | ||
| 2352 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ | ||
| 2353 | .device = 0x24cc, | ||
| 2354 | .subvendor = 0x103c, | ||
| 2355 | .subdevice = 0x0890, | ||
| 2356 | .sir_io = 0x02f8, | ||
| 2357 | .fir_io = 0x0130, | ||
| 2358 | .fir_irq = 0x09, | ||
| 2359 | .fir_dma = 0x03, | ||
| 2360 | .cfg_base = 0x004e, | ||
| 2361 | .preconfigure = preconfigure_through_82801, | ||
| 2362 | .name = "HP nc6000", | ||
| 2363 | }, | ||
| 2364 | { | ||
| 2365 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ | ||
| 2366 | .device = 0x24c0, | ||
| 2367 | .subvendor = 0x1179, | ||
| 2368 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
| 2369 | .sir_io = 0x03f8, | ||
| 2370 | .fir_io = 0x0130, | ||
| 2371 | .fir_irq = 0x07, | ||
| 2372 | .fir_dma = 0x01, | ||
| 2373 | .cfg_base = 0x002e, | ||
| 2374 | .preconfigure = preconfigure_through_82801, | ||
| 2375 | .name = "Toshiba Satellite 2450", | ||
| 2376 | }, | ||
| 2377 | { | ||
| 2378 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ | ||
| 2379 | .device = 0x248c, /* Some use 24cc? */ | ||
| 2380 | .subvendor = 0x1179, | ||
| 2381 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
| 2382 | .sir_io = 0x03f8, | ||
| 2383 | .fir_io = 0x0130, | ||
| 2384 | .fir_irq = 0x03, | ||
| 2385 | .fir_dma = 0x03, | ||
| 2386 | .cfg_base = 0x002e, | ||
| 2387 | .preconfigure = preconfigure_through_82801, | ||
| 2388 | .name = "Toshiba Satellite 5100/5200, Tecra 9100", | ||
| 2389 | }, | ||
| 2390 | { | ||
| 2391 | .vendor = PCIID_VENDOR_ALI, /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ | ||
| 2392 | .device = 0x1533, | ||
| 2393 | .subvendor = 0x1179, | ||
| 2394 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
| 2395 | .sir_io = 0x02e8, | ||
| 2396 | .fir_io = 0x02f8, | ||
| 2397 | .fir_irq = 0x07, | ||
| 2398 | .fir_dma = 0x03, | ||
| 2399 | .cfg_base = 0x002e, | ||
| 2400 | .preconfigure = preconfigure_through_ali, | ||
| 2401 | .name = "Toshiba Satellite 1800", | ||
| 2402 | }, | ||
| 2403 | { } // Terminator | ||
| 2404 | }; | ||
| 2405 | |||
| 2406 | |||
| 2407 | /* | ||
| 2408 | * This sets up the basic SMSC parameters (FIR port, SIR port, FIR DMA, FIR IRQ) | ||
| 2409 | * through the chip configuration port. | ||
| 2410 | */ | ||
| 2411 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf) | ||
| 2412 | { | ||
| 2413 | unsigned short iobase = conf->cfg_base; | ||
| 2414 | unsigned char tmpbyte; | ||
| 2415 | |||
| 2416 | outb(LPC47N227_CFGACCESSKEY, iobase); // enter configuration state | ||
| 2417 | outb(SMSCSIOFLAT_DEVICEID_REG, iobase); // set for device ID | ||
| 2418 | tmpbyte = inb(iobase +1); // Read device ID | ||
| 2419 | IRDA_DEBUG(0, "Detected Chip id: 0x%02x, setting up registers...\n",tmpbyte); | ||
| 2420 | |||
| 2421 | /* Disable UART1 and set up SIR I/O port */ | ||
| 2422 | outb(0x24, iobase); // select CR24 - UART1 base addr | ||
| 2423 | outb(0x00, iobase + 1); // disable UART1 | ||
| 2424 | outb(SMSCSIOFLAT_UART2BASEADDR_REG, iobase); // select CR25 - UART2 base addr | ||
| 2425 | outb( (conf->sir_io >> 2), iobase + 1); // bits 2-9 of 0x3f8 | ||
| 2426 | tmpbyte = inb(iobase + 1); | ||
| 2427 | if (tmpbyte != (conf->sir_io >> 2) ) { | ||
| 2428 | IRDA_WARNING("ERROR: could not configure SIR ioport.\n"); | ||
| 2429 | return -ENXIO; | ||
| 2430 | } | ||
| 2431 | |||
| 2432 | /* Set up FIR IRQ channel for UART2 */ | ||
| 2433 | outb(SMSCSIOFLAT_UARTIRQSELECT_REG, iobase); // select CR28 - UART1,2 IRQ select | ||
| 2434 | tmpbyte = inb(iobase + 1); | ||
| 2435 | tmpbyte &= SMSCSIOFLAT_UART1IRQSELECT_MASK; // Do not touch the UART1 portion | ||
| 2436 | tmpbyte |= (conf->fir_irq & SMSCSIOFLAT_UART2IRQSELECT_MASK); | ||
| 2437 | outb(tmpbyte, iobase + 1); | ||
| 2438 | tmpbyte = inb(iobase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; | ||
| 2439 | if (tmpbyte != conf->fir_irq) { | ||
| 2440 | IRDA_WARNING("ERROR: could not configure FIR IRQ channel.\n"); | ||
| 2441 | return -ENXIO; | ||
| 2442 | } | ||
| 2443 | |||
| 2444 | /* Set up FIR I/O port */ | ||
| 2445 | outb(SMSCSIOFLAT_FIRBASEADDR_REG, iobase); // CR2B - SCE (FIR) base addr | ||
| 2446 | outb((conf->fir_io >> 3), iobase + 1); | ||
| 2447 | tmpbyte = inb(iobase + 1); | ||
| 2448 | if (tmpbyte != (conf->fir_io >> 3) ) { | ||
| 2449 | IRDA_WARNING("ERROR: could not configure FIR I/O port.\n"); | ||
| 2450 | return -ENXIO; | ||
| 2451 | } | ||
| 2452 | |||
| 2453 | /* Set up FIR DMA channel */ | ||
| 2454 | outb(SMSCSIOFLAT_FIRDMASELECT_REG, iobase); // CR2C - SCE (FIR) DMA select | ||
| 2455 | outb((conf->fir_dma & LPC47N227_FIRDMASELECT_MASK), iobase + 1); // DMA | ||
| 2456 | tmpbyte = inb(iobase + 1) & LPC47N227_FIRDMASELECT_MASK; | ||
| 2457 | if (tmpbyte != (conf->fir_dma & LPC47N227_FIRDMASELECT_MASK)) { | ||
| 2458 | IRDA_WARNING("ERROR: could not configure FIR DMA channel.\n"); | ||
| 2459 | return -ENXIO; | ||
| 2460 | } | ||
| 2461 | |||
| 2462 | outb(SMSCSIOFLAT_UARTMODE0C_REG, iobase); // CR0C - UART mode | ||
| 2463 | tmpbyte = inb(iobase + 1); | ||
| 2464 | tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK | SMSCSIOFLAT_UART2MODE_VAL_IRDA; | ||
| 2465 | outb(tmpbyte, iobase + 1); // enable IrDA (HPSIR) mode, high speed | ||
| 2466 | |||
| 2467 | outb(LPC47N227_APMBOOTDRIVE_REG, iobase); // CR07 - Auto Pwr Mgt/boot drive sel | ||
| 2468 | tmpbyte = inb(iobase + 1); | ||
| 2469 | outb(tmpbyte | LPC47N227_UART2AUTOPWRDOWN_MASK, iobase + 1); // enable UART2 autopower down | ||
| 2470 | |||
| 2471 | /* This one was not part of tosh1800 */ | ||
| 2472 | outb(0x0a, iobase); // CR0a - ecp fifo / ir mux | ||
| 2473 | tmpbyte = inb(iobase + 1); | ||
| 2474 | outb(tmpbyte | 0x40, iobase + 1); // send active device to ir port | ||
| 2475 | |||
| 2476 | outb(LPC47N227_UART12POWER_REG, iobase); // CR02 - UART 1,2 power | ||
| 2477 | tmpbyte = inb(iobase + 1); | ||
| 2478 | outb(tmpbyte | LPC47N227_UART2POWERDOWN_MASK, iobase + 1); // UART2 power up mode, UART1 power down | ||
| 2479 | |||
| 2480 | outb(LPC47N227_FDCPOWERVALIDCONF_REG, iobase); // CR00 - FDC Power/valid config cycle | ||
| 2481 | tmpbyte = inb(iobase + 1); | ||
| 2482 | outb(tmpbyte | LPC47N227_VALID_MASK, iobase + 1); // valid config cycle done | ||
| 2483 | |||
| 2484 | outb(LPC47N227_CFGEXITKEY, iobase); // Exit configuration | ||
| 2485 | |||
| 2486 | return 0; | ||
| 2487 | } | ||
| 2488 | |||
| 2489 | /* 82801CAM registers */ | ||
| 2490 | #define VID 0x00 | ||
| 2491 | #define DID 0x02 | ||
| 2492 | #define PIRQA_ROUT 0x60 | ||
| 2493 | #define PCI_DMA_C 0x90 | ||
| 2494 | #define COM_DEC 0xe0 | ||
| 2495 | #define LPC_EN 0xe6 | ||
| 2496 | #define GEN2_DEC 0xec | ||
| 2497 | /* | ||
| 2498 | * Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge or | ||
| 2499 | * Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. They all work the same way! | ||
| 2500 | */ | ||
| 2501 | static int __init preconfigure_through_82801(struct pci_dev *dev, | ||
| 2502 | struct smsc_ircc_subsystem_configuration *conf) | ||
| 2503 | { | ||
| 2504 | unsigned short tmpword; | ||
| 2505 | int ret; | ||
| 2506 | |||
| 2507 | IRDA_MESSAGE("Setting up the SMSC device via the 82801 controller.\n"); | ||
| 2508 | pci_write_config_byte(dev, COM_DEC, 0x10); | ||
| 2509 | |||
| 2510 | /* Enable LPC */ | ||
| 2511 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | ||
| 2512 | tmpword &= 0xfffd; /* mask bit 1 */ | ||
| 2513 | tmpword |= 0x0001; /* set bit 0 : COMA addr range enable */ | ||
| 2514 | pci_write_config_word(dev, LPC_EN, tmpword); | ||
| 2515 | |||
| 2516 | /* Setup DMA */ | ||
| 2517 | pci_write_config_word(dev, PCI_DMA_C, 0xc0c0); /* LPC I/F DMA on, channel 3 -- rtm (?? PCI DMA ?) */ | ||
| 2518 | pci_write_config_word(dev, GEN2_DEC, 0x131); /* LPC I/F 2nd decode range */ | ||
| 2519 | |||
| 2520 | /* Pre-configure chip */ | ||
| 2521 | ret = preconfigure_smsc_chip(conf); | ||
| 2522 | |||
| 2523 | /* Disable LPC */ | ||
| 2524 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | ||
| 2525 | tmpword &= 0xfffc; /* mask bit 1 and bit 0, COMA addr range disable */ | ||
| 2526 | pci_write_config_word(dev, LPC_EN, tmpword); | ||
| 2527 | return ret; | ||
| 2528 | } | ||
| 2529 | |||
| 2530 | static int __init preconfigure_through_ali(struct pci_dev *dev, | ||
| 2531 | struct smsc_ircc_subsystem_configuration *conf) | ||
| 2532 | { | ||
| 2533 | /* TODO: put in ALi 1533 configuration here. */ | ||
| 2534 | IRDA_MESSAGE("SORRY: %s has an unsupported bridge controller (ALi): not pre-configured.\n", conf->name); | ||
| 2535 | return -ENODEV; | ||
| 2536 | } | ||
| 2537 | |||
| 2538 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | ||
| 2539 | unsigned short ircc_fir, | ||
| 2540 | unsigned short ircc_sir, | ||
| 2541 | unsigned char ircc_dma, | ||
| 2542 | unsigned char ircc_irq) | ||
| 2543 | { | ||
| 2544 | struct pci_dev *dev = NULL; | ||
| 2545 | unsigned short ss_vendor = 0x0000; | ||
| 2546 | unsigned short ss_device = 0x0000; | ||
| 2547 | int ret = 0; | ||
| 2548 | |||
| 2549 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
| 2550 | |||
| 2551 | while (dev != NULL) { | ||
| 2552 | struct smsc_ircc_subsystem_configuration *conf; | ||
| 2553 | |||
| 2554 | /* | ||
| 2555 | * Cache the subsystem vendor/device: some manufacturers fail to set | ||
| 2556 | * this for all components, so we save it in case there is just | ||
| 2557 | * 0x0000 0x0000 on the device we want to check. | ||
| 2558 | */ | ||
| 2559 | if (dev->subsystem_vendor != 0x0000U) { | ||
| 2560 | ss_vendor = dev->subsystem_vendor; | ||
| 2561 | ss_device = dev->subsystem_device; | ||
| 2562 | } | ||
| 2563 | conf = subsystem_configurations; | ||
| 2564 | for( ; conf->subvendor; conf++) { | ||
| 2565 | if(conf->vendor == dev->vendor && | ||
| 2566 | conf->device == dev->device && | ||
| 2567 | conf->subvendor == ss_vendor && /* Sometimes these are cached values */ | ||
| 2568 | (conf->subdevice == ss_device || conf->subdevice == 0xffff)) { | ||
| 2569 | struct smsc_ircc_subsystem_configuration tmpconf; | ||
| 2570 | |||
| 2571 | memcpy(&tmpconf, conf, sizeof(struct smsc_ircc_subsystem_configuration)); | ||
| 2572 | |||
| 2573 | /* Override the default values with anything passed in as parameter */ | ||
| 2574 | if (ircc_cfg != 0) | ||
| 2575 | tmpconf.cfg_base = ircc_cfg; | ||
| 2576 | if (ircc_fir != 0) | ||
| 2577 | tmpconf.fir_io = ircc_fir; | ||
| 2578 | if (ircc_sir != 0) | ||
| 2579 | tmpconf.sir_io = ircc_sir; | ||
| 2580 | if (ircc_dma != 0xff) | ||
| 2581 | tmpconf.fir_dma = ircc_dma; | ||
| 2582 | if (ircc_irq != 0xff) | ||
| 2583 | tmpconf.fir_irq = ircc_irq; | ||
| 2584 | |||
| 2585 | IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); | ||
| 2586 | if (conf->preconfigure) | ||
| 2587 | ret = conf->preconfigure(dev, &tmpconf); | ||
| 2588 | else | ||
| 2589 | ret = -ENODEV; | ||
| 2590 | } | ||
| 2591 | } | ||
| 2592 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
| 2593 | } | ||
| 2594 | |||
| 2595 | return ret; | ||
| 2596 | } | ||
| 2597 | #endif // CONFIG_PCI | ||
| 2598 | |||
| 2288 | /************************************************ | 2599 | /************************************************ |
| 2289 | * | 2600 | * |
| 2290 | * Transceivers specific functions | 2601 | * Transceivers specific functions |
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 75b35ad760de..66e74f740261 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
| @@ -87,6 +87,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | static struct console netconsole = { | 89 | static struct console netconsole = { |
| 90 | .name = "netcon", | ||
| 90 | .flags = CON_ENABLED | CON_PRINTBUFFER, | 91 | .flags = CON_ENABLED | CON_PRINTBUFFER, |
| 91 | .write = write_msg | 92 | .write = write_msg |
| 92 | }; | 93 | }; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0b5358072172..73e271e59c6a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -497,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | |||
| 497 | unsigned long flags; | 497 | unsigned long flags; |
| 498 | 498 | ||
| 499 | spin_lock_irqsave(&tp->indirect_lock, flags); | 499 | spin_lock_irqsave(&tp->indirect_lock, flags); |
| 500 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 500 | if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { |
| 501 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 501 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
| 502 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
| 502 | 503 | ||
| 503 | /* Always leave this as zero. */ | 504 | /* Always leave this as zero. */ |
| 504 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 505 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
| 505 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 506 | } else { |
| 506 | } | 507 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); |
| 508 | tw32_f(TG3PCI_MEM_WIN_DATA, val); | ||
| 507 | 509 | ||
| 508 | static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) | 510 | /* Always leave this as zero. */ |
| 509 | { | 511 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
| 510 | /* If no workaround is needed, write to mem space directly */ | 512 | } |
| 511 | if (tp->write32 != tg3_write_indirect_reg32) | 513 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
| 512 | tw32(NIC_SRAM_WIN_BASE + off, val); | ||
| 513 | else | ||
| 514 | tg3_write_mem(tp, off, val); | ||
| 515 | } | 514 | } |
| 516 | 515 | ||
| 517 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | 516 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) |
| @@ -519,11 +518,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | |||
| 519 | unsigned long flags; | 518 | unsigned long flags; |
| 520 | 519 | ||
| 521 | spin_lock_irqsave(&tp->indirect_lock, flags); | 520 | spin_lock_irqsave(&tp->indirect_lock, flags); |
| 522 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 521 | if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { |
| 523 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 522 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
| 523 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
| 524 | 524 | ||
| 525 | /* Always leave this as zero. */ | 525 | /* Always leave this as zero. */ |
| 526 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 526 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
| 527 | } else { | ||
| 528 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); | ||
| 529 | *val = tr32(TG3PCI_MEM_WIN_DATA); | ||
| 530 | |||
| 531 | /* Always leave this as zero. */ | ||
| 532 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); | ||
| 533 | } | ||
| 527 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 534 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
| 528 | } | 535 | } |
| 529 | 536 | ||
| @@ -1367,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
| 1367 | } | 1374 | } |
| 1368 | } | 1375 | } |
| 1369 | 1376 | ||
| 1377 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
| 1378 | |||
| 1370 | /* Finally, set the new power state. */ | 1379 | /* Finally, set the new power state. */ |
| 1371 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); | 1380 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); |
| 1372 | udelay(100); /* Delay after power state change */ | 1381 | udelay(100); /* Delay after power state change */ |
| 1373 | 1382 | ||
| 1374 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
| 1375 | |||
| 1376 | return 0; | 1383 | return 0; |
| 1377 | } | 1384 | } |
| 1378 | 1385 | ||
| @@ -5828,10 +5835,14 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
| 5828 | GRC_MODE_NO_TX_PHDR_CSUM | | 5835 | GRC_MODE_NO_TX_PHDR_CSUM | |
| 5829 | GRC_MODE_NO_RX_PHDR_CSUM); | 5836 | GRC_MODE_NO_RX_PHDR_CSUM); |
| 5830 | tp->grc_mode |= GRC_MODE_HOST_SENDBDS; | 5837 | tp->grc_mode |= GRC_MODE_HOST_SENDBDS; |
| 5831 | if (tp->tg3_flags & TG3_FLAG_NO_TX_PSEUDO_CSUM) | 5838 | |
| 5832 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; | 5839 | /* Pseudo-header checksum is done by hardware logic and not |
| 5833 | if (tp->tg3_flags & TG3_FLAG_NO_RX_PSEUDO_CSUM) | 5840 | * the offload processers, so make the chip do the pseudo- |
| 5834 | tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM; | 5841 | * header checksums on receive. For transmit it is more |
| 5842 | * convenient to do the pseudo-header checksum in software | ||
| 5843 | * as Linux does that on transmit for us in all cases. | ||
| 5844 | */ | ||
| 5845 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; | ||
| 5835 | 5846 | ||
| 5836 | tw32(GRC_MODE, | 5847 | tw32(GRC_MODE, |
| 5837 | tp->grc_mode | | 5848 | tp->grc_mode | |
| @@ -6535,11 +6546,11 @@ static void tg3_timer(unsigned long __opaque) | |||
| 6535 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { | 6546 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { |
| 6536 | u32 val; | 6547 | u32 val; |
| 6537 | 6548 | ||
| 6538 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, | 6549 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, |
| 6539 | FWCMD_NICDRV_ALIVE2); | 6550 | FWCMD_NICDRV_ALIVE2); |
| 6540 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); | 6551 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); |
| 6541 | /* 5 seconds timeout */ | 6552 | /* 5 seconds timeout */ |
| 6542 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); | 6553 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); |
| 6543 | val = tr32(GRC_RX_CPU_EVENT); | 6554 | val = tr32(GRC_RX_CPU_EVENT); |
| 6544 | val |= (1 << 14); | 6555 | val |= (1 << 14); |
| 6545 | tw32(GRC_RX_CPU_EVENT, val); | 6556 | tw32(GRC_RX_CPU_EVENT, val); |
| @@ -8034,9 +8045,13 @@ static int tg3_test_nvram(struct tg3 *tp) | |||
| 8034 | for (i = 0; i < size; i++) | 8045 | for (i = 0; i < size; i++) |
| 8035 | csum8 += buf8[i]; | 8046 | csum8 += buf8[i]; |
| 8036 | 8047 | ||
| 8037 | if (csum8 == 0) | 8048 | if (csum8 == 0) { |
| 8038 | return 0; | 8049 | err = 0; |
| 8039 | return -EIO; | 8050 | goto out; |
| 8051 | } | ||
| 8052 | |||
| 8053 | err = -EIO; | ||
| 8054 | goto out; | ||
| 8040 | } | 8055 | } |
| 8041 | 8056 | ||
| 8042 | /* Bootstrap checksum at offset 0x10 */ | 8057 | /* Bootstrap checksum at offset 0x10 */ |
| @@ -9531,8 +9546,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
| 9531 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; | 9546 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; |
| 9532 | 9547 | ||
| 9533 | /* Do not even try poking around in here on Sun parts. */ | 9548 | /* Do not even try poking around in here on Sun parts. */ |
| 9534 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) | 9549 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { |
| 9550 | /* All SUN chips are built-in LOMs. */ | ||
| 9551 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; | ||
| 9535 | return; | 9552 | return; |
| 9553 | } | ||
| 9536 | 9554 | ||
| 9537 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); | 9555 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); |
| 9538 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { | 9556 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { |
| @@ -9630,9 +9648,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
| 9630 | tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) | 9648 | tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) |
| 9631 | tp->led_ctrl = LED_CTRL_MODE_PHY_2; | 9649 | tp->led_ctrl = LED_CTRL_MODE_PHY_2; |
| 9632 | 9650 | ||
| 9633 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && | 9651 | if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) |
| 9634 | (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) && | ||
| 9635 | (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) | ||
| 9636 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; | 9652 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; |
| 9637 | 9653 | ||
| 9638 | if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { | 9654 | if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { |
| @@ -10257,6 +10273,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
| 10257 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); | 10273 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); |
| 10258 | } | 10274 | } |
| 10259 | 10275 | ||
| 10276 | if (tp->write32 == tg3_write_indirect_reg32 || | ||
| 10277 | ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && | ||
| 10278 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || | ||
| 10279 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) || | ||
| 10280 | (tp->tg3_flags2 & TG3_FLG2_SUN_570X)) | ||
| 10281 | tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; | ||
| 10282 | |||
| 10260 | /* Get eeprom hw config before calling tg3_set_power_state(). | 10283 | /* Get eeprom hw config before calling tg3_set_power_state(). |
| 10261 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be | 10284 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be |
| 10262 | * determined before calling tg3_set_power_state() so that | 10285 | * determined before calling tg3_set_power_state() so that |
| @@ -10299,15 +10322,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
| 10299 | if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) | 10322 | if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) |
| 10300 | tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; | 10323 | tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; |
| 10301 | 10324 | ||
| 10302 | /* Pseudo-header checksum is done by hardware logic and not | ||
| 10303 | * the offload processers, so make the chip do the pseudo- | ||
| 10304 | * header checksums on receive. For transmit it is more | ||
| 10305 | * convenient to do the pseudo-header checksum in software | ||
| 10306 | * as Linux does that on transmit for us in all cases. | ||
| 10307 | */ | ||
| 10308 | tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM; | ||
| 10309 | tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM; | ||
| 10310 | |||
| 10311 | /* Derive initial jumbo mode from MTU assigned in | 10325 | /* Derive initial jumbo mode from MTU assigned in |
| 10312 | * ether_setup() via the alloc_etherdev() call | 10326 | * ether_setup() via the alloc_etherdev() call |
| 10313 | */ | 10327 | */ |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index c43cc3264202..8c8b987d1250 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
| @@ -2171,8 +2171,7 @@ struct tg3 { | |||
| 2171 | #define TG3_FLAG_PCIX_MODE 0x00020000 | 2171 | #define TG3_FLAG_PCIX_MODE 0x00020000 |
| 2172 | #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 | 2172 | #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 |
| 2173 | #define TG3_FLAG_PCI_32BIT 0x00080000 | 2173 | #define TG3_FLAG_PCI_32BIT 0x00080000 |
| 2174 | #define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000 | 2174 | #define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 |
| 2175 | #define TG3_FLAG_NO_RX_PSEUDO_CSUM 0x00200000 | ||
| 2176 | #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 | 2175 | #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 |
| 2177 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 | 2176 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 |
| 2178 | #define TG3_FLAG_10_100_ONLY 0x01000000 | 2177 | #define TG3_FLAG_10_100_ONLY 0x01000000 |
