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