[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Airport



On Fri, Jun 30, 2000 at 03:25:59AM -0500, Josh wrote:
> I have a G3 Powerbook (wallstreet) and a WaveLan Turbo card.  It seems
> that there is a way to make this work with the Airport from what I can
> see in archives, but it looks complicated.  Are there any explicit
> instructions anywhere?
Yep.  Check out:
http://www.roelle.com/wvlanPPC/index.html

The instructions are good, but if you're using pcmcia-cs 3.1.16, the patch
doesn't apply cleanly.  I'll attach a patch against 3.1.16 for ppc support.
It seems to be working fine for me, but I'm not making any guarantees :)

NOTE: this patch includes the pmac patch and the patch for the wvlan driver
to work on ppc, so don't apply EITHER of the patches on the web site -- use
this instead.

Good luck,

-- 
Josh
6B21489A | GnuPG ID/Fingerprint | huber@mclx.com |
61F0 6138 BE7B FEBF A223  E9D1 BFE1 2065 6B21 489A
diff -urN pcmcia-cs-3.1.16/SUPPORTED.CARDS pcmcia-cs-3.1.16-patched/SUPPORTED.CARDS
--- pcmcia-cs-3.1.16/SUPPORTED.CARDS	Wed Jun  7 14:17:22 2000
+++ pcmcia-cs-3.1.16-patched/SUPPORTED.CARDS	Thu Jun 22 20:37:05 2000
@@ -265,7 +265,7 @@
 	AT&T / NCR / Lucent WaveLAN version 2.0
 	DEC RoamAbout/DS
 
-	[wvlan_cs driver] [x86,axp]
+	[wvlan_cs driver] [x86,axp,ppc]
 	Lucent WaveLAN/IEEE 802.11(b)
 	Melco WLI-PCM-L11
 	NCR WaveLAN/IEEE 802.11
diff -urN pcmcia-cs-3.1.16/clients/3c575_cb.c pcmcia-cs-3.1.16-patched/clients/3c575_cb.c
--- pcmcia-cs-3.1.16/clients/3c575_cb.c	Wed May 31 14:32:18 2000
+++ pcmcia-cs-3.1.16-patched/clients/3c575_cb.c	Thu Jun 22 20:22:52 2000
@@ -1403,7 +1403,7 @@
 		/* queue will be restarted at the DMADone interrupt. */
 	} else {
 		/* ... and the packet rounded to a doubleword. */
-		outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+		outsl_ns(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 		dev_free_skb(skb);
 		if (inw(ioaddr + TxFree) > 1536) {
 			netif_start_queue(dev);
@@ -1658,7 +1658,7 @@
 					while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
 						;
 				} else {
-					insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
+					insl_ns(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
 						 (pkt_len + 3) >> 2);
 				}
 				outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
diff -urN pcmcia-cs-3.1.16/etc/config pcmcia-cs-3.1.16-patched/etc/config
--- pcmcia-cs-3.1.16/etc/config	Mon Jun  5 19:29:58 2000
+++ pcmcia-cs-3.1.16-patched/etc/config	Thu Jun 22 20:22:52 2000
@@ -40,7 +40,7 @@
   class "ftl" module "ftl_cs"
 
 device "serial_cs"
-  class "serial" module "serial_cs"
+  class "serial" module "misc/serial", "serial_cs"
 
 device "parport_cs"
   class "parport" module "parport_cs"
diff -urN pcmcia-cs-3.1.16/etc/config.opts pcmcia-cs-3.1.16-patched/etc/config.opts
--- pcmcia-cs-3.1.16/etc/config.opts	Tue Jun  6 17:01:50 2000
+++ pcmcia-cs-3.1.16-patched/etc/config.opts	Thu Jun 22 20:22:52 2000
@@ -5,9 +5,8 @@
 
 # System resources available for PCMCIA devices
 
-include port 0x100-0x4ff, port 0x800-0x8ff, port 0xc00-0xcff
-include memory 0xc0000-0xfffff
-include memory 0xa0000000-0xa0ffffff, memory 0x60000000-0x60ffffff
+include port 0x0-0xfff
+include memory 0x90000000-0x90ffffff, memory 0xa0000000-0xa0ffffff            
 
 # High port numbers do not always work...
 # include port 0x1000-0x17ff
@@ -17,12 +16,6 @@
 
 # Resources we should not use, even if they appear to be available
 
-# First built-in serial port
-exclude irq 4
-# Second built-in serial port
-#exclude irq 3
-# First built-in parallel port
-exclude irq 7
 
 #----------------------------------------------------------------------
 
diff -urN pcmcia-cs-3.1.16/modules/cs.c pcmcia-cs-3.1.16-patched/modules/cs.c
--- pcmcia-cs-3.1.16/modules/cs.c	Wed May 10 15:26:32 2000
+++ pcmcia-cs-3.1.16-patched/modules/cs.c	Thu Jun 22 20:22:52 2000
@@ -439,6 +439,10 @@
     /* Blank out the socket state */
     s->state &= SOCKET_PRESENT|SOCKET_SETUP_PENDING;
     init_socket(s);
+#ifdef __powerpc__
+    s->socket.flags |= SS_EJECTION;
+    s->ss_entry(s->sock, SS_SetSocket, &s->socket);
+#endif
     s->irq.AssignedIRQ = s->irq.Config = 0;
     s->lock_count = 0;
     s->cis_used = 0;
diff -urN pcmcia-cs-3.1.16/modules/i82365.c pcmcia-cs-3.1.16-patched/modules/i82365.c
--- pcmcia-cs-3.1.16/modules/i82365.c	Fri Jun  9 18:14:25 2000
+++ pcmcia-cs-3.1.16-patched/modules/i82365.c	Thu Jun 22 21:08:02 2000
@@ -56,6 +56,13 @@
 #include <asm/bitops.h>
 #include <asm/segment.h>
 #include <asm/system.h>
+
+#ifdef __powerpc__
+#include <asm/prom.h>
+#include <asm/adb.h>
+#include <asm/pmu.h>
+#endif
+
 #endif
 
 #include <pcmcia/version.h>
@@ -189,6 +196,10 @@
     u_char		pci_lat, cb_lat, sub_bus, cache;
     u_int		cb_phys;
     char		*cb_virt;
+#ifdef __powerpc__
+    int			pmu_socket;
+    struct adb_request	pmu_req;
+#endif
 #endif
     union {
 	cirrus_state_t		cirrus;
@@ -484,6 +495,7 @@
 	}
 #endif
     }
+#if 0
     if (s->type != IS_VT83C469) {
 	if (setup_time >= 0)
 	    p->timer[0] = p->timer[3] = setup_time;
@@ -502,6 +514,7 @@
 	sprintf(buf, " [%d/%d/%d] [%d/%d/%d]", p->timer[0], p->timer[1],
 		p->timer[2], p->timer[3], p->timer[4], p->timer[5]);
     }
+#endif
     return mask;
 }
 
@@ -1524,6 +1537,32 @@
 	}
 #endif
     }
+#ifdef __powerpc__
+    /* work out the mapping to PMU socket number */
+    {
+	struct device_node *np;
+	for (i = 0; i < ns; ++i) {
+	    s[i].pmu_socket = 0;
+	    s[i].pmu_req.complete = 1;
+	}
+	for (np = find_type_devices("pccard"); np != NULL; np = np->next) {
+	    int *reg = (int *) get_property(np, "reg", NULL);
+	    int *ps = (int *) get_property(np, "AAPL,pmu-socket-number", NULL);
+	    int bus, devfn;
+	    if (reg == NULL || ps == NULL)
+		continue;
+	    bus = (reg[0] >> 16) & 0xff;
+	    devfn = (reg[0] >> 8) & 0xff;
+	    for (i = 0; i < ns; ++i) {
+		if (s[i].bus == bus && s[i].devfn == devfn) {
+		    s[i].pmu_socket = *ps;
+		    DEBUG(2, ("socket %d is pmu socket %d\n", i, *ps));
+		    break;
+		}
+	    }
+	}
+    }
+#endif
 
 } /* add_pcic */
 
@@ -2084,7 +2123,13 @@
 	cb_writel(s, CB_SOCKET_EVENT, -1);
     }
 #endif
-
+#ifdef __powerpc__
+	if (state->flags & SS_EJECTION) {
+		if (s->pmu_socket != 0 && s->pmu_req.complete)
+			pmu_request(&s->pmu_req, NULL, 2, PMU_PCEJECT, s->pmu_socket);
+		state->flags &= ~SS_EJECTION;
+	}
+#endif
     return 0;
 } /* i365_set_socket */
 
@@ -2313,7 +2358,15 @@
     i365_get(s, I365_CSC);
     cb_writel(s, CB_SOCKET_MASK, CB_SM_CCD);
     cb_writel(s, CB_SOCKET_EVENT, -1);
-    
+
+#ifdef __powerpc__
+    if (state->flags & SS_EJECTION) {
+		if (s->pmu_socket != 0 && s->pmu_req.complete)
+			pmu_request(&s->pmu_req, NULL, 2, PMU_PCEJECT, s->pmu_socket);
+		state->flags &= ~SS_EJECTION;
+	}
+#endif	
+
     return 0;
 } /* cb_set_socket */
 
diff -urN pcmcia-cs-3.1.16/wireless/wvlan_cs.c pcmcia-cs-3.1.16-patched/wireless/wvlan_cs.c
--- pcmcia-cs-3.1.16/wireless/wvlan_cs.c	Mon Jun  5 19:00:42 2000
+++ pcmcia-cs-3.1.16-patched/wireless/wvlan_cs.c	Thu Jun 22 21:01:13 2000
@@ -4,6 +4,9 @@
  *	by Andreas Neuhaus <andy@fasta.fh-dortmund.de>
  *	http://www.fasta.fh-dortmund.de/users/andy/wvlan/
  *
+ *	Byteorder patches for LinuxPPC v0.3
+ *	by Harald Roelle <harald@roelle.com>
+ *
  *	This driver is free software; you can redistribute and/or
  *	modify it under the terms of the GNU General Public License;
  *	either version 2 of the license, or (at your option) any
@@ -234,6 +237,16 @@
 
 #include "wvlan_hcf.h"
 
+#ifdef __powerpc__
+#include <linux/byteorder/swab.h>
+inline void SwapBytesBlock( void* ptr, int len)
+{
+	int l = (len)/2;
+	while ( l--) swab16s( ((unsigned short*)ptr)++);
+}
+#endif
+				
+
 /* #define PCMCIA_DEBUG 1	// For developer only :-) */
 
 // Undefine this if you want to ignore Tx timeouts
@@ -261,7 +274,7 @@
 /********************************************************************
  * MISC
  */
-static char *version = "1.0.4";
+static char *version = "1.0.4-ppcPatch-0.3";
 static dev_info_t dev_info = "wvlan_cs";
 static dev_link_t *dev_list = NULL;
 
@@ -307,7 +320,11 @@
 #define TX_TIMEOUT ((4000*HZ)/1000)
 
 // Ethernet-II snap header
+#ifdef __powerpc__ // (roelle): store it already byte swapped for ppc, saves some cycles
+static char snap_header[] = { 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x03, 0xf8, 0x00 };
+#else
 static char snap_header[] = { 0x00, 0x00, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
+#endif
 
 // Valid MTU values (HCF_MAX_MSG (2304) is the max hardware frame size)
 #define WVLAN_MIN_MTU 256
@@ -483,6 +500,9 @@
 	if (rc)
 		return rc;
 	l = min(len, ltv.len*2);
+#ifdef __powerpc__
+	SwapBytesBlock( ltv.mac_addr, l+1);  // make sure odd length gets treated right
+#endif
 	memcpy(mac, (char *)ltv.mac_addr, l);
 	return 0;
 }
@@ -536,6 +556,9 @@
 	l = min(strlen(name), ltv.len*2);
 	ltv.id[0] = l;
 	memcpy((char *) &ltv.id[1], name, l);
+#ifdef __powerpc__ // (roelle): no reswapping needed later, we did a memcopy before
+	SwapBytesBlock( &ltv.id[1], l+1); // make sure odd length gets treated right
+#endif 
 	rc = hcf_put_info(ifbp, (LTVP) &ltv);
 	DEBUG(DEBUG_NOISY, "%s: hcf_put_info(CFG_CNF_OWN_NAME:'%s') returned 0x%x\n", dev_info, name, rc);
 	return rc;
@@ -556,6 +579,9 @@
 		l = min(len, ltv.id[0]);
 	else
 		l = min(len, ltv.len*2);	/* It's a feature */
+#ifdef __powerpc__
+	SwapBytesBlock( &ltv.id[1], l+1); // make shure odd length gets treated right
+#endif
 	memcpy(name, (char *) &ltv.id[1], l);
 	name[l] = 0;
 	DEBUG(DEBUG_NOISY, "%s: hcf_get_info(CFG_CNF_OWN_NAME):'%s'\n", dev_info, name);
@@ -575,6 +601,9 @@
 	l = min(strlen(name), ltv.len*2);
 	ltv.id[0] = l;
 	memcpy((char *) &ltv.id[1], name, l);
+#ifdef __powerpc__ // (roelle): no reswapping needed later, we did a memcopy before
+	SwapBytesBlock( &ltv.id[1], l+1); // make sure odd length gets treated right
+#endif
 	rc = hcf_put_info(ifbp, (LTVP) &ltv);
 	DEBUG(DEBUG_NOISY, "%s: hcf_put_info(CFG_CNF_OWN/DESIRED_SSID:'%s') returned 0x%x\n", dev_info, name, rc);
 	return rc;
@@ -600,6 +629,9 @@
 	if (ltv.id[0])
 	{
 		l = min(len, ltv.id[0]);
+#ifdef __powerpc__
+		SwapBytesBlock( &ltv.id[1], l+1); // make sure odd length gets treated right
+#endif
 		memcpy(name, (char *) &ltv.id[1], l);
 	}
 	else
@@ -621,6 +653,9 @@
 	if (rc)
 		return rc;
 	l = min(len, ltv.len*2);
+#ifdef __powerpc__
+	SwapBytesBlock( ltv.mac_addr, l+1); // make sure odd length gets treated right
+#endif
 	memcpy(mac, (char *)ltv.mac_addr, l);
 	return 0;
 }
@@ -725,6 +760,9 @@
 	ltv.typ = CFG_SUPPORTED_DATA_RATES;
 	rc = hcf_get_info(ifbp, (LTVP) &ltv);
 	brnum = ltv.id[0];
+#ifdef __powerpc__
+	SwapBytesBlock( &ltv.id[1], brnum+1); // make shure odd length gets treated right
+#endif
 	memcpy(brlist, (char *) &ltv.id[1], brnum);
 	DEBUG(DEBUG_NOISY, "%s: hcf_get_info(CFG_CHANNEL_LIST):0x%x returned 0x%x\n", dev_info, brnum, rc);
 	return rc ? 0 : brnum;
@@ -1276,16 +1314,17 @@
 					// Or maybe I just got it wrong?
 					brate = rate_list[wvrate];
 #else
-					brate = 2 * wvrate;
+					wrq->u.bitrate.value = wvrate * 1000 * 1000;
+					//brate = 2 * wvrate;
 					// Mandatory kludge!
-					if (wvrate == 6)
-						brate = 11;
+					//if (wvrate == 6)
+					//	brate = 11;
 #endif
 				}
-				else
+				else {
 					wrq->u.bitrate.fixed = 1;
-
-				wrq->u.bitrate.value = brate * 500000;
+					wrq->u.bitrate.value = brate * 500000;
+				}
 			}
 			break;
 
@@ -1316,6 +1355,9 @@
 			wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
 #endif /* WIRELESS_EXT > 8 */
 			wrq->u.rts.fixed = 1;
+#if WIRELESS_EXT > 8
+			wrq->u.frag.disabled = (wrq->u.frag.value == 2347) ? 1 : 0;
+#endif
 			break;
 
 		// Set the desired fragmentation threshold
@@ -1345,6 +1387,9 @@
 			wrq->u.frag.disabled = (wrq->u.frag.value == 2346);
 #endif /* WIRELESS_EXT > 8 */
 			wrq->u.frag.fixed = 1;
+#if WIRELESS_EXT > 8
+			wrq->u.frag.disabled = (wrq->u.frag.value == 2346) ? 1 : 0;
+#endif
 			break;
 
 		// Set the desired AP density
@@ -1564,7 +1609,8 @@
 				//	1.6 Mb/s for the 2 Mb/s card
 				//	~5 Mb/s for the 11 Mb/s card
 				// Jean II
-				range.throughput = 1.6 * 1024 * 1024;
+				//range.throughput = 1.6 * 1024 * 1024;
+				range.throughput = 6.0 * 1024 * 1024;
 				range.min_nwid = 0x0000;
 				range.max_nwid = 0x0000;
 				range.num_channels = 14;
@@ -1758,6 +1804,9 @@
 				int typ = *((int *) wrq->u.name);
 				ltv.len = 18;
 				ltv.typ = typ;
+				//
+				// NOTE: NO BYTE SWAPPING FOR POWERPC HERE!
+				//
 				rc = hcf_get_info(&local->ifb, (LTVP) &ltv);
 				if (rc)
 					printk(KERN_DEBUG "%s: hcf_get_info(0x%x) returned error 0x%x\n", dev_info, typ, rc);
@@ -1808,6 +1857,10 @@
 		ltv.len = 4;
 		ltv.typ = CFG_COMMS_QUALITY;
 		rc = hcf_get_info(&local->ifb, (LTVP) &ltv);
+#ifdef __powerpc__
+		//(roelle). I don't get it, why HERE no byte swapping is needed
+		//SwapBytesBlock( &(ltv.signal_lvl), 4);
+#endif
 		DEBUG(DEBUG_NOISY, "%s: hcf_get_info(CFG_COMMS_QUALITY) returned 0x%x\n", dev_info, rc);
 		local->wstats.qual.qual = max(min(ltv.coms_qual, 0x8b-0x2f), 0);
 		local->wstats.qual.level = max(min(ltv.signal_lvl, 0x8a), 0x2f) - 0x95;
@@ -2071,15 +2124,34 @@
 	// HCF-light doesn't support that.
 	if (p[13] + (p[12] << 8) > 1500)
 	{
+#ifdef __powerpc__
+		SwapBytesBlock( p, len);
+#endif
 		hcf_put_data(&local->ifb, p, 12, 0);
 		len += sizeof(snap_header);
+#ifdef __powerpc__
+		snap_header[0] = (len-0x0e) & 0xff;
+		snap_header[1] = (char)((len-0x0e) >> 8);
+#else
 		snap_header[1] = (len-0x0e) & 0xff;
 		snap_header[0] = (char)((len-0x0e) >> 8);
+#endif
 		hcf_put_data(&local->ifb, snap_header, sizeof(snap_header), 0);
 		hcf_put_data(&local->ifb, p+12, len-12-sizeof(snap_header), 0);
 	}
 	else
+	{
+#ifdef __powerpc__
+		SwapBytesBlock( p, len);
+#endif
 		hcf_put_data(&local->ifb, p, len, 0);
+	}
+#ifdef __powerpc__ 
+	// (roelle): I dont't know if the data is needed later, so to be safe, swap it back.
+	//
+	//           Andreas: Your opinion?
+	SwapBytesBlock( p, len);
+#endif
 
 	// Send packet
 	rc = hcf_send(&local->ifb, 0);
@@ -2130,10 +2202,18 @@
 	{
 		hcf_get_data(&local->ifb, 0, p, 12);
 		hcf_get_data(&local->ifb, 12+sizeof(snap_header), p+12, len-12-sizeof(snap_header));
+#ifdef __powerpc__
+		SwapBytesBlock( p, len-sizeof(snap_header));
+#endif
 		skb_trim(skb, len-sizeof(snap_header));
 	}
 	else
+	{
 		hcf_get_data(&local->ifb, 0, p, len);
+#ifdef __powerpc__
+		SwapBytesBlock( p, len);
+#endif  
+	}
 
 	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
@@ -2177,6 +2257,7 @@
 #if defined(HISTOGRAM)
 		// We can't be clever...
 		rc = hcf_get_data(&local->ifb, HFS_Q_INFO, stats, 2);
+		SwapBytesBlock(stats, 2);
 		DEBUG(DEBUG_NOISY, "%s: hcf_get_data(HFS_Q_INFO) returned 0x%x\n", dev_info, rc);
 #else // Therefore WIRELESS_SPY only !!!
 		memset(&stats, 0, sizeof(stats));
@@ -2185,6 +2266,9 @@
 			if (!memcmp(srcaddr, local->spy_address[i], MAC_ADDR_SIZE))
 			{
 				rc = hcf_get_data(&local->ifb, HFS_Q_INFO, stats, 2);
+#ifdef __powerpc__
+				SwapBytesBlock( stats, 2);
+#endif
 				break;
 			}
 #endif

Attachment: pgpN39lMDwJGx.pgp
Description: PGP signature


Reply to: