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 *) <v.id[1], name, l);
+#ifdef __powerpc__ // (roelle): no reswapping needed later, we did a memcopy before
+ SwapBytesBlock( <v.id[1], l+1); // make sure odd length gets treated right
+#endif
rc = hcf_put_info(ifbp, (LTVP) <v);
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( <v.id[1], l+1); // make shure odd length gets treated right
+#endif
memcpy(name, (char *) <v.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 *) <v.id[1], name, l);
+#ifdef __powerpc__ // (roelle): no reswapping needed later, we did a memcopy before
+ SwapBytesBlock( <v.id[1], l+1); // make sure odd length gets treated right
+#endif
rc = hcf_put_info(ifbp, (LTVP) <v);
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( <v.id[1], l+1); // make sure odd length gets treated right
+#endif
memcpy(name, (char *) <v.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) <v);
brnum = ltv.id[0];
+#ifdef __powerpc__
+ SwapBytesBlock( <v.id[1], brnum+1); // make shure odd length gets treated right
+#endif
memcpy(brlist, (char *) <v.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) <v);
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) <v);
+#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:
pgpgRSORBD5Hz.pgp
Description: PGP signature