--- a/br2684ctl.c +++ b/br2684ctl.c @@ -10,6 +10,10 @@ #include #include #include +#ifndef BR2684_FLAG_ROUTED +#warning "Kernel missing routed support for br2684" +#define BR2684_FLAG_ROUTED (1<<16) /* payload is routed, not bridged */ +#endif /* Written by Marcell GAL to make use of the */ /* ioctls defined in the br2684... kernel patch */ @@ -28,26 +32,35 @@ #define LOG_OPTION LOG_PERROR|LOG_PID #define LOG_FACILITY LOG_LOCAL2 +struct br2684_params { + int itfnum; + int encap; + int sndbuf; + int payload; + char *astr; /* temporary */ + struct atm_qos reqqos; +}; + int lastsock, lastitf; -void fatal(const char *str, int i) +void fatal(const char *str, int err) { - syslog (LOG_ERR,"Fatal: %s",str); + syslog (LOG_ERR,"Fatal: %s; %s", str, strerror(err)); exit(-2); }; void exitFunc(void) { - syslog (LOG_NOTICE,"Daemon terminated\n"); + syslog (LOG_NOTICE,"Daemon terminated"); } void int_signal(int dummy) { - syslog (LOG_INFO,"Killed by a signal\n"); + syslog (LOG_INFO,"Killed by a signal"); exit(0); } @@ -58,7 +71,7 @@ int create_pidfile(int num) if (num < 0) return -1; - snprintf(name, 20, "/var/run/nas%d.pid", num); + snprintf(name, 32, "/var/run/br2684ctl-nas%d.pid", num); pidfile = fopen(name, "w"); if (pidfile == NULL) return -1; fprintf(pidfile, "%d", getpid()); @@ -67,9 +80,9 @@ int create_pidfile(int num) return 0; } -int create_br(char *nstr) +int create_br(int itfnum, int payload) { - int num, err; + int err; if(lastsock<0) { lastsock = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); @@ -78,31 +91,36 @@ int create_br(char *nstr) syslog(LOG_ERR, "socket creation failed: %s",strerror(errno)); } else { /* create the device with ioctl: */ - num=atoi(nstr); - if( num>=0 && num<1234567890){ + if( itfnum>=0 && itfnum<1234567890){ struct atm_newif_br2684 ni; ni.backend_num = ATM_BACKEND_BR2684; ni.media = BR2684_MEDIA_ETHERNET; +#ifdef BR2684_FLAG_ROUTED + if (payload == 0) + ni.media |= BR2684_FLAG_ROUTED; +#endif ni.mtu = 1500; - sprintf(ni.ifname, "nas%d", num); + sprintf(ni.ifname, "nas%d", itfnum); err=ioctl (lastsock, ATM_NEWBACKENDIF, &ni); if (err == 0) - syslog(LOG_NOTICE, "Interface \"%s\" created sucessfully\n",ni.ifname); + syslog(LOG_NOTICE, "Interface \"%s\" created sucessfully",ni.ifname); else - syslog(LOG_INFO, "Interface \"%s\" could not be created, reason: %s\n", + syslog(LOG_INFO, "Interface \"%s\" could not be created, reason: %s", ni.ifname, strerror(errno)); - lastitf=num; /* even if we didn't create, because existed, assign_vcc wil want to know it! */ + lastitf=itfnum; /* even if we didn't create, because existed, + assign_vcc wil want to know it! */ } else { - syslog(LOG_ERR,"err: strange interface number %d", num ); + syslog(LOG_ERR,"err: strange interface number %d", itfnum ); } } return 0; } -int assign_vcc(char *astr, int encap, int bufsize, struct atm_qos qos) +int assign_vcc(char *astr, int encap, int payload, + int bufsize, struct atm_qos qos) { int err; struct sockaddr_atmpvc addr; @@ -112,21 +130,17 @@ int assign_vcc(char *astr, int encap, in memset(&addr, 0, sizeof(addr)); err=text2atm(astr,(struct sockaddr *)(&addr), sizeof(addr), T2A_PVC); if (err!=0) - syslog(LOG_ERR,"Could not parse ATM parameters (error=%d)\n",err); + syslog(LOG_ERR,"Could not parse ATM parameters (error=%d)",err); -#if 0 - addr.sap_family = AF_ATMPVC; - addr.sap_addr.itf = itf; - addr.sap_addr.vpi = 0; - addr.sap_addr.vci = vci; -#endif - syslog(LOG_NOTICE,"Communicating over ATM %d.%d.%d, encapsulation: %s\n", addr.sap_addr.itf, + syslog(LOG_NOTICE,"Communicating over ATM %d.%d.%d, encapsulation: %s", + addr.sap_addr.itf, addr.sap_addr.vpi, addr.sap_addr.vci, encap?"VC mux":"LLC"); if ((fd = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5)) < 0) - syslog(LOG_ERR,"failed to create socket %d, reason: %s", errno,strerror(errno)); + syslog(LOG_ERR,"failed to create socket %d, reason: %s", + errno,strerror(errno)); if (qos.aal == 0) { qos.aal = ATM_AAL5; @@ -137,7 +151,7 @@ int assign_vcc(char *astr, int encap, in } if ( (err=setsockopt(fd,SOL_SOCKET,SO_SNDBUF, &bufsize ,sizeof(bufsize))) ) - syslog(LOG_ERR,"setsockopt SO_SNDBUF: (%d) %s\n",err, strerror(err)); + syslog(LOG_ERR,"setsockopt SO_SNDBUF: (%d) %s",err, strerror(err)); if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) syslog(LOG_ERR,"setsockopt SO_ATMQOS %d", errno); @@ -145,7 +159,7 @@ int assign_vcc(char *astr, int encap, in err = connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_atmpvc)); if (err < 0) - fatal("failed to connect on socket", err); + fatal("failed to connect on socket", errno); /* attach the vcc to device: */ @@ -169,10 +183,30 @@ int assign_vcc(char *astr, int encap, in return fd ; } +void start_interface(struct br2684_params* params) +{ + if (params->astr==NULL) { + syslog(LOG_ERR, "Required ATM parameters not specified."); + exit(1); + } + + create_br(params->itfnum, params->payload); + assign_vcc(params->astr, params->encap, params->payload, params->sndbuf, + params->reqqos); +} + void usage(char *s) { - printf("usage: %s [-b] [[-c number] [-e 0|1] [-s sndbuf] [-q qos] [-a [itf.]vpi.vci]*]*\n", s); + printf("usage: %s [-b] [[-c number] [-e 0|1] [-s sndbuf] [-q qos] [-p 0|1] " + "[-a [itf.]vpi.vci]*]*\n" + " -b = run in background (daemonize)\n" + " -c = use interface nas\n" + " -e 0|1 = encapsulation (0=LLC, 1=VC Mux)\n" + " -p 0|1 = payload type (0=routed,1=bridged)\n" + " -s = set sndbuf (send buffer) size (default 8192)\n" + " -a [itf.]vpi.vci = ATM interface no, VPI, VCI\n", + s); exit(1); } @@ -180,47 +214,63 @@ void usage(char *s) int main (int argc, char **argv) { - int c, background=0, encap=0, sndbuf=8192; - struct atm_qos reqqos; - int itfnum; + int c, background=0; + + struct br2684_params params; + params.itfnum=-1; + params.encap=0; + params.sndbuf=8192; + params.payload=1; + params.astr=NULL; + memset(¶ms.reqqos, 0, sizeof(params.reqqos)); + lastsock=-1; lastitf=0; /* st qos to 0 */ - memset(&reqqos, 0, sizeof(reqqos)); openlog (LOG_NAME,LOG_OPTION,LOG_FACILITY); if (argc>1) - while ((c = getopt(argc, argv,"q:a:bc:e:s:?h")) !=EOF) + while ((c = getopt(argc, argv,"q:a:bc:e:s:p:?h")) !=EOF) switch (c) { case 'q': printf ("optarg : %s",optarg); - if (text2qos(optarg,&reqqos,0)) fprintf(stderr,"QOS parameter invalid\n"); + if (text2qos(optarg,¶ms.reqqos,0)) + fprintf(stderr,"QOS parameter invalid\n"); break; case 'a': - assign_vcc(optarg, encap, sndbuf, reqqos); + params.astr=optarg; break; case 'b': background=1; break; case 'c': - create_br(optarg); - itfnum = atoi(optarg); + /* temporary, to make it work with multiple interfaces: */ + if (params.itfnum>=0) start_interface(¶ms); + params.itfnum= atoi(optarg); break; case 'e': - encap=(atoi(optarg)); - if(encap<0){ - syslog (LOG_ERR, "invalid encapsulation: %s:\n",optarg); - encap=0; + params.encap=(atoi(optarg)); + if(params.encap<0){ + syslog (LOG_ERR, "invalid encapsulation: %s:",optarg); + params.encap=0; } break; case 's': - sndbuf=(atoi(optarg)); - if(sndbuf<0){ - syslog(LOG_ERR, "Invalid sndbuf: %s, using size of 8192 instead\n",optarg); - sndbuf=8192; + params.sndbuf=(atoi(optarg)); + if(params.sndbuf<0){ + syslog(LOG_ERR, "Invalid sndbuf: %s, using size of 8192 instead", + optarg); + params.sndbuf=8192; } break; + case 'p': /* payload type: routed (0) or bridged (1) */ +#ifdef BR2684_FLAG_ROUTED + params.payload = atoi(optarg); + break; +#else + syslog(LOG_ERR, "payload option not supported."); +#endif case '?': case 'h': default: @@ -231,6 +281,8 @@ int main (int argc, char **argv) if (argc != optind) usage(argv[0]); + start_interface(¶ms); + if(lastsock>=0) close(lastsock); if (background) { @@ -268,11 +320,11 @@ int main (int argc, char **argv) } - create_pidfile(itfnum); + create_pidfile(params.itfnum); signal(SIGINT, int_signal); signal(SIGTERM, int_signal); - syslog (LOG_INFO, "RFC 1483/2684 bridge daemon started\n"); + syslog (LOG_INFO, "RFC 1483/2684 bridge daemon started"); atexit (exitFunc); while (1) pause(); /* to keep the sockets... */ >151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
Index: linux-2.6.21gum/drivers/net/smc911x.c
===================================================================
--- linux-2.6.21gum.orig/drivers/net/smc911x.c
+++ linux-2.6.21gum/drivers/net/smc911x.c
@@ -76,6 +76,7 @@ static const char version[] =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <linux/irq.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -303,14 +304,14 @@ static void smc911x_reset(struct net_dev
 	SMC_SET_AFC_CFG(lp->afc_cfg);
 
 
-	/* Set to LED outputs */
-	SMC_SET_GPIO_CFG(0x70070000);
+	/* Set to LED outputs and configure EEPROM pins as GP outputs */
+	SMC_SET_GPIO_CFG(GPIO_CFG_LED1_EN_ | GPIO_CFG_LED2_EN_ | 1 << 20);
 
 	/*
-	 * Deassert IRQ for 1*10us for edge type interrupts
+	 * Deassert IRQ for 22*10us for edge type interrupts
 	 * and drive IRQ pin push-pull
 	 */
-	SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
+	SMC_SET_IRQ_CFG( (22 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
 
 	/* clear anything saved */
 	if (lp->pending_tx_skb != NULL) {
@@ -413,7 +414,7 @@ static inline void smc911x_drop_pkt(stru
 	if (fifo_count <= 4) {
 		/* Manually dump the packet data */
 		while (fifo_count--)
-			SMC_GET_RX_FIFO();
+			(void)SMC_GET_RX_FIFO();
 	} else	 {
 		/* Fast forward through the bad packet */
 		SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_);
@@ -900,6 +901,7 @@ static void smc911x_phy_powerdown(struct
 	unsigned long ioaddr = dev->base_addr;
 	unsigned int bmcr;
 
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
 	/* Enter Link Disable state */
 	SMC_GET_PHY_BMCR(phy, bmcr);
 	bmcr |= BMCR_PDOWN;
@@ -925,6 +927,7 @@ static void smc911x_phy_check_media(stru
 
 	if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
 		/* duplex state has changed */
+		DBG(SMC_DEBUG_MISC, "%s: duplex state has changed\n", dev->name);
 		SMC_GET_PHY_BMCR(phyaddr, bmcr);
 		SMC_GET_MAC_CR(cr);
 		if (lp->mii.full_duplex) {
@@ -960,6 +963,7 @@ static void smc911x_phy_configure(struct
 	int my_phy_caps; /* My PHY capabilities */
 	int my_ad_caps; /* My Advertised capabilities */
 	int status;
+	int bmcr;
 	unsigned long flags;
 
 	DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
@@ -1033,9 +1037,12 @@ static void smc911x_phy_configure(struct
 
 	DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps);
 	DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps);
+	DBG(SMC_DEBUG_MISC, "%s: phy advertised readback caps=0x%04x\n", dev->name, status);
 
 	/* Restart auto-negotiation process in order to advertise my caps */
-	SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART);
+	SMC_GET_PHY_BMCR(phyaddr, bmcr);
+	bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
+	SMC_SET_PHY_BMCR(phyaddr, bmcr);
 
 	smc911x_phy_check_media(dev, 1);
 
@@ -1888,6 +1895,39 @@ static int __init smc911x_findirq(unsign
 	return probe_irq_off(cookie);
 }
 
+static inline unsigned int is_gumstix_oui(u8 *addr)
+{
+	return (addr[0] == 0x00 && addr[1] == 0x15 && addr[2] == 0xC9);
+}
+
+/**
+ * gen_serial_ether_addr - Generate software assigned Ethernet address
+ * based on the system_serial number
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Generate an Ethernet address (MAC) that is not multicast
+ * and has the local assigned bit set, keyed on the system_serial
+ */
+static inline void gen_serial_ether_addr(u8 *addr)
+{
+	static u8 ether_serial_digit = 0;
+	addr [0] = system_serial_high >> 8;
+	addr [1] = system_serial_high;
+	addr [2] = system_serial_low >> 24;
+	addr [3] = system_serial_low >> 16;
+	addr [4] = system_serial_low >> 8;
+	addr [5] = (system_serial_low & 0xc0) |	/* top bits are from system serial */
+		(1 << 4) |			/* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */
+		((ether_serial_digit++) & 0x0f);	/* 15 possible interfaces of each type */
+
+	if(!is_gumstix_oui(addr))
+	{
+		addr [0] &= 0xfe;		/* clear multicast bit */
+		addr [0] |= 0x02;		/* set local assignment bit (IEEE802) */
+	}
+}
+
+
 /*
  * Function: smc911x_probe(unsigned long ioaddr)
  *
@@ -2116,15 +2156,13 @@ static int __init smc911x_probe(struct n
 #endif
 		printk("\n");
 		if (!is_valid_ether_addr(dev->dev_addr)) {
-			printk("%s: Invalid ethernet MAC address. Please "
-					"set using ifconfig\n", dev->name);
-		} else {
-			/* Print the Ethernet address */
-			printk("%s: Ethernet addr: ", dev->name);
-			for (i = 0; i < 5; i++)
-				printk("%2.2x:", dev->dev_addr[i]);
-			printk("%2.2x\n", dev->dev_addr[5]);
+			gen_serial_ether_addr(dev->dev_addr);
 		}
+		/* Print the Ethernet address */
+		printk("%s: Ethernet addr: ", dev->name);
+		for (i = 0; i < 5; i++)
+			printk("%2.2x:", dev->dev_addr[i]);
+		printk("%2.2x\n", dev->dev_addr[5]);
 
 		if (lp->phy_type == 0) {
 			PRINTK("%s: No PHY found\n", dev->name);
@@ -2300,8 +2338,15 @@ static struct platform_driver smc911x_dr
 	},
 };
 
+#ifdef CONFIG_ARCH_GUMSTIX
+extern void gumstix_smc911x_load(void);
+#endif
+
 static int __init smc911x_init(void)
 {
+#ifdef CONFIG_ARCH_GUMSTIX
+	gumstix_smc911x_load();
+#endif
 	return platform_driver_register(&smc911x_driver);
 }
 
Index: linux-2.6.21gum/drivers/net/gumstix-smc911x.c
===================================================================
--- /dev/null
+++ linux-2.6.21gum/drivers/net/gumstix-smc911x.c
@@ -0,0 +1,148 @@
+/*
+ *  Gumstix SMC911x chip intialization driver
+ *
+ *  Author:     Craig Hughes
+ *  Created:    December 9, 2004
+ *  Copyright:  (C) 2004 Craig Hughes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/delay.h>
+
+#include <asm/arch/gumstix.h>
+
+#define SMC_DEBUG               9
+#include <asm/io.h>
+#include "smc911x.h"
+
+static struct resource gumstix_smc911x0_resources[] = {
+	[0] = {
+		.name	= "smc911x-regs",
+		.start  = PXA_CS1_PHYS,
+		.end    = PXA_CS1_PHYS + 0x000fffff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = GUMSTIX_ETH0_IRQ,
+		.end    = GUMSTIX_ETH0_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource gumstix_smc911x1_resources[] = {
+	[0] = {
+		.name	= "smc911x-regs",
+		.start	= PXA_CS2_PHYS,
+		.end	= PXA_CS2_PHYS + 0x000fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= GUMSTIX_ETH1_IRQ,
+		.end	= GUMSTIX_ETH1_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device gumstix_smc911x0_device = {
+	.name           = "smc911x",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(gumstix_smc911x0_resources),
+	.resource       = gumstix_smc911x0_resources,
+};
+
+static struct platform_device gumstix_smc911x1_device = {
+	.name           = "smc911x",
+	.id             = 1,
+	.num_resources  = ARRAY_SIZE(gumstix_smc911x1_resources),
+	.resource       = gumstix_smc911x1_resources,
+};
+
+static struct platform_device *smc911x_devices[] = {
+	&gumstix_smc911x0_device,
+	&gumstix_smc911x1_device,
+};
+
+/* First we're going to test if there's a 2nd SMC911x, and if not, then we'll free up those resources and the GPIO lines
+ * that it would otherwise use.  We have no choice but to probe by doing:
+ * Set nCS2 to CS2 mode
+ * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset)
+ * Read from the memory space to check for the sentinel sequence identifying a likely SMC911x device
+ */
+int __init gumstix_smc911x_init(void)
+{
+	unsigned int val, num_devices=ARRAY_SIZE(smc911x_devices);
+	void *ioaddr;
+
+	/* Set up nPWE */
+	pxa_gpio_mode(GPIO49_nPWE_MD);
+
+	pxa_gpio_mode(GPIO78_nCS_2_MD);
+	// If either if statement fails, then we'll drop out and turn_off_eth1,
+	// if both succeed, then we'll skip that and just proceed with 2 cards
+	if(request_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT, "smc911x probe"))
+	{
+		ioaddr = ioremap(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT);
+		val = SMC_GET_PN();
+		iounmap(ioaddr);
+		release_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT);
+		if (CHIP_9115 == val ||
+			CHIP_9116 == val ||
+			CHIP_9117 == val ||
+			CHIP_9118 == val ) {
+			goto proceed;
+		}
+	}
+
+turn_off_eth1:
+	// This is apparently not an SMC911x
+	// So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode
+	num_devices--;
+	smc911x_devices[1] = NULL;
+	pxa_gpio_mode(78 | GPIO_IN);
+	
+proceed:
+	pxa_gpio_mode(GPIO15_nCS_1_MD);
+
+	if(smc911x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD);
+	pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD);
+
+	if(smc911x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
+	GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
+	msleep(500); // Hold RESET for at least 200µ
+
+	if(smc911x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
+	GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
+	msleep(50);
+
+	return platform_add_devices(smc911x_devices, num_devices);
+}
+
+void __exit gumstix_smc911x_exit(void)
+{
+	if(smc911x_devices[1] != NULL) platform_device_unregister(&gumstix_smc911x1_device);
+	platform_device_unregister(&gumstix_smc911x0_device);
+}
+
+void gumstix_smc911x_load(void) {}
+EXPORT_SYMBOL(gumstix_smc911x_load);
+
+module_init(gumstix_smc911x_init);
+module_exit(gumstix_smc911x_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Craig Hughes <craig@gumstix.com>");
+MODULE_DESCRIPTION("Gumstix board SMC911x chip initialization driver");
+MODULE_VERSION("1:0.1");
Index: linux-2.6.21gum/drivers/net/Kconfig
===================================================================
--- linux-2.6.21gum.orig/drivers/net/Kconfig
+++ linux-2.6.21gum/drivers/net/Kconfig
@@ -897,6 +897,13 @@ config SMC911X
 	  called smc911x.  If you want to compile it as a module, say M 
 	  here and read <file:Documentation/modules.txt>
 
+config SMC911X_GUMSTIX
+	tristate
+	default m if SMC911X=m
+	default y if SMC911X=y
+	depends on SMC911X && ARCH_GUMSTIX
+
+
 config NET_VENDOR_RACAL
 	bool "Racal-Interlan (Micom) NI cards"
 	depends on NET_ETHERNET && ISA
Index: linux-2.6.21gum/drivers/net/Makefile
===================================================================
--- linux-2.6.21gum.orig/drivers/net/Makefile
+++ linux-2.6.21gum/drivers/net/Makefile
@@ -201,6 +201,7 @@ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
 obj-$(CONFIG_MACB) += macb.o
 
 obj-$(CONFIG_SMC91X_GUMSTIX) += gumstix-smc91x.o
+obj-$(CONFIG_SMC911X_GUMSTIX) += gumstix-smc911x.o
 obj-$(CONFIG_ARM) += arm/
 obj-$(CONFIG_DEV_APPLETALK) += appletalk/
 obj-$(CONFIG_TR) += tokenring/
Index: linux-2.6.21gum/include/asm-arm/arch-pxa/gumstix.h
===================================================================
--- linux-2.6.21gum.orig/include/asm-arm/arch-pxa/gumstix.h
+++ linux-2.6.21gum/include/asm-arm/arch-pxa/gumstix.h
@@ -52,7 +52,7 @@
 #define GPIO_GUMSTIX_ETH0_RST		80
 #define GPIO_GUMSTIX_ETH0		36
 #else
-#define GPIO_GUMSTIX_ETH0_RST		32
+#define GPIO_GUMSTIX_ETH0_RST		107
 #define GPIO_GUMSTIX_ETH0		99
 #endif
 #define GPIO_GUMSTIX_ETH1_RST		52
Index: linux-2.6.21gum/drivers/net/smc911x.h
===================================================================
--- linux-2.6.21gum.orig/drivers/net/smc911x.h
+++ linux-2.6.21gum/drivers/net/smc911x.h
@@ -33,7 +33,9 @@
  * Use the DMA feature on PXA chips
  */
 #ifdef CONFIG_ARCH_PXA
+#if !defined( CONFIG_SMC911X_GUMSTIX ) && !defined( CONFIG_SMC911X_GUMSTIX_MODULE )
   #define SMC_USE_PXA_DMA	1
+#endif
   #define SMC_USE_16BIT		0
   #define SMC_USE_32BIT		1
 #endif
@@ -46,13 +48,13 @@
 #if	SMC_USE_16BIT
 #define SMC_inb(a, r)			 readb((a) + (r))
 #define SMC_inw(a, r)			 readw((a) + (r))
-#define SMC_inl(a, r)			 ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16))
+#define SMC_inl(a, r)			 ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw((a)+2, r)<<16))
 #define SMC_outb(v, a, r)		 writeb(v, (a) + (r))
 #define SMC_outw(v, a, r)		 writew(v, (a) + (r))
 #define SMC_outl(v, a, r) 			 \
 	do{					 \
-		 writel(v & 0xFFFF, (a) + (r));	 \
-		 writel(v >> 16, (a) + (r) + 2); \
+		 writel((v) & 0xFFFF, (a) + (r));	 \
+		 writel((v) >> 16, (a) + (r) + 2); \
 	 } while (0)
 #define SMC_insl(a, r, p, l)	 readsw((short*)((a) + (r)), p, l*2)
 #define SMC_outsl(a, r, p, l)	 writesw((short*)((a) + (r)), p, l*2)