summaryrefslogtreecommitdiffstats
path: root/sys/dev/ray/if_ray.c
diff options
context:
space:
mode:
authordmlb <dmlb@FreeBSD.org>2000-03-05 14:39:23 +0000
committerdmlb <dmlb@FreeBSD.org>2000-03-05 14:39:23 +0000
commit0d622116584a7772ae48f8032fe2e6ee479ec853 (patch)
tree491d85917de83e573aae857f6156eb6456743472 /sys/dev/ray/if_ray.c
parenta5aaf32a4704d1ab5e2b9a344d1b0d8f4f8b3a4b (diff)
downloadFreeBSD-src-0d622116584a7772ae48f8032fe2e6ee479ec853.zip
FreeBSD-src-0d622116584a7772ae48f8032fe2e6ee479ec853.tar.gz
Moved a lot of my inline comments to head of code and documented
card configuration hassles. Added a TODO list so I don't forget to finish stuff. Tidyed up a lot of XXX. Tidy'd and documented debugging - all DPRINTF have a debug level associated. RAY_DEBUG = 1, will log packet errors. #if protect common memory hacking Don't rely on pccardd for common memory settings. Added a simple transmit mode - reasonable performance but not great. Will do a version of the NetBSD chained buffers soon. Yup we have two way transmisson! Fix a stupid bug in the common memory code - the ioctl call was hidden behind a debug test!
Diffstat (limited to 'sys/dev/ray/if_ray.c')
-rw-r--r--sys/dev/ray/if_ray.c1151
1 files changed, 773 insertions, 378 deletions
diff --git a/sys/dev/ray/if_ray.c b/sys/dev/ray/if_ray.c
index 8c826ee..3439186 100644
--- a/sys/dev/ray/if_ray.c
+++ b/sys/dev/ray/if_ray.c
@@ -28,21 +28,150 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_ray.c,v 1.4 2000/02/27 19:52:29 dmlb Exp $
+ * $Id: if_ray.c,v 1.5 2000/03/03 17:07:42 dmlb Exp $
*
*/
+/*
+ *
+ * Card configuration
+ * ==================
+ *
+ * This card is unusual in that it uses both common and attribute
+ * memory whilst working. The -stable versions of FreeBSD have a real
+ * problem managing and setting up the correct memory maps. This
+ * driver should reset the memory maps correctly under PAO and non-PAO
+ * -stable systems. Work is in hand to fix these problems for -current.
+ *
+ * So, if you want to use this driver make sure that
+ * options RAY_NEED_CM_FIXUP
+ * options RAY_NEED_CM_REMAPPING
+ * are in your kernel configuration file.
+ *
+ * The first fixes the brain deadness of pccardd (where it reads the
+ * CIS for common memory, sets it all up and then throws it all away
+ * assuming the card is an ed driver...).
+ *
+ * The second option ensures that common memory is remapped whenever
+ * we are going to access it (we can't just do it once, as something
+ * like pccardd may have read the attribute memory and pccard.c
+ * doesn't re-map the last active window - it remaps the last
+ * non-active window...).
+ *
+ *
+ * Ad-hoc and infra-structure modes
+ * ================================
+ *
+ * At present only the ad-hoc mode is being worked on.
+ *
+ * Apart from just writing the code for infrastructure mode I have a
+ * few concerns about both the Linux and NetBSD drivers in this area.
+ * They don't seem to differentiate between the MAC address of the AP
+ * and the BSS_ID of the network. I presume this is handled when
+ * joining a managed n/w and the network parameters are updated, but
+ * I'm not sure. How does this interact with ARP? For mobility we want
+ * to be able to move around without worrying about which AP we are
+ * actually talking to - we should always talk to the BSS_ID.
+ *
+ * The Linux driver also seems to have the capability to act as an AP.
+ * I wonder what facilities the "AP" can provide within a driver? We can
+ * probably use the BRIDGE code to form an ESS but I don't think
+ * power saving etc. is easy.
+ *
+ *
+ * Packet translation/encapsulation
+ * ================================
+ *
+ * Currently we only support the Webgear encapsulation
+ * 802.11 header <net/if_ieee80211.h>struct ieee80211_header
+ * 802.3 header <net/ethernet.h>struct ether_header
+ * 802.2 LLC header
+ * 802.2 SNAP header
+ *
+ * We should support whatever packet types the following drivers have
+ * if_wi.c FreeBSD, RFC1042
+ * if_ray.c NetBSD Webgear, RFC1042
+ * rayctl.c Linux Webgear, RFC1042
+ * also whatever we can divine from the NDC Access points and Kanda's boxes.
+ *
+ * Most drivers appear to have a RFC1042 translation. The incoming packet is
+ * 802.11 header <net/if_ieee80211.h>struct ieee80211_header
+ * 802.2 LLC header
+ * 802.2 SNAP header
+ *
+ * This is translated to
+ * 802.3 header <net/ethernet.h>struct ether_header
+ * 802.2 LLC header
+ * 802.2 SNAP header
+ *
+ * Linux seems to look at the SNAP org_code and do some translations
+ * for IPX and APPLEARP on that. This just may be how Linux does IPX
+ * and NETATALK. Need to see how FreeBSD does these.
+ *
+ * Translation should be selected via if_media stuff or link types.
+ */
+
+/*
+ * TODO
+ *
+ * _stop
+ * _reset
+ * havenet checking
+ * unload
+ * shutdown
+ *
+ * TX bpf
+ * RX bpf
+ * promisoius
+ * multicast
+ * ifp->if_hdr length
+ *
+ * apm
+ *
+ * more commands
+ * ioctls - translation, BSS_ID, countrycode
+ * faster TX routine
+ * more translations
+ * infrastructure mode
+ * differeniate between parameters set in attach and init
+ * start_join_done needs a restart in download_done
+ * spinning in ray_issue_cmd
+ *
+ * command tracking - really needed? if not remove SCP_ stuff
+ * will simplify ray_issue_cmd away
+ */
+
#define XXX 0
#define XXX_TRACKING 0
+#define XXX_INFRA 0
+#define XXX_MCASTPROM 0
/*
* XXX build options - move to LINT
*/
-#define RAY_DEBUG 100 /* Big numbers get more verbose */
+
+/*
+ * RAY_DEBUG settings
+ *
+ * 2 Recoverable error's
+ * 6 Subroutine entry
+ * 11 Startup CM dump
+ * 15 State transitions for start/join
+ * 21 CCS info
+ * 31 IOCTL calls
+ * 51 MBUFs dumped/packet types reported
+ */
+#define RAY_DEBUG 6
+
#define RAY_CCS_TIMEOUT (hz/2) /* Timeout for CCS commands - only used for downloading startup parameters */
+
#define RAY_NEED_STARTJOIN_TIMO 0 /* Might be needed with build 4 */
#define RAY_SJ_TIMEOUT (90*hz) /* Timeout for failing STARTJOIN commands - only used with RAY_NEED_STARTJOIN_TIMO */
+
+#define RAY_NEED_CM_FIXUP 1 /* Needed until pccardd hacks for ed drivers are removed (pccardd forces 16bit memory and 0x4000 size) THIS IS A DANGEROUS THING TO USE IF YOU USE OTHER MEMORY MAPPED PCCARDS */
+
#define RAY_NEED_CM_REMAPPING 1 /* Needed until pccard maps more than one memory area */
+
#define RAY_DUMP_CM_ON_GIFMEDIA 1 /* Dump some common memory when the SIOCGIFMEDIA ioctl is issued - a nasty hack for debugging and will be placed by an ioctl and control program */
/*
* XXX build options - move to LINT
@@ -57,6 +186,9 @@
#if RAY_DEBUG > 0
+/* XXX This macro assumes that common memory is mapped into kernel space and
+ * XXX does not indirect through SRAM macros - it should
+ */
#define RAY_DHEX8(p, l) do { if (RAY_DEBUG > 10) { \
u_int8_t *i; \
for (i = p; i < (u_int8_t *)(p+l); i += 8) \
@@ -64,7 +196,7 @@
(unsigned long)i, (unsigned char *)i, " "); \
} } while (0)
-#define RAY_DPRINTF(x) do { if (RAY_DEBUG) { \
+#define RAY_DPRINTFN(l, x) do { if (RAY_DEBUG > l) { \
printf x ; \
} } while (0)
@@ -81,12 +213,12 @@
} } while (0)
#else
-#define RAY_HEX8(p, l)
-#define RAY_DPRINTF(x)
+#define RAY_DHEX8(p, l)
+#define RAY_DPRINTFN(l,x)
#define RAY_DNET_DUMP(sc, s)
#endif /* RAY_DEBUG > 0 */
-#if RAY_DEBUG > 10
+#if RAY_DEBUG > 50
#define RAY_DMBUF_DUMP(sc, m, s) ray_dump_mbuf((sc), (m), (s))
#else
#define RAY_DMBUF_DUMP(sc, m, s)
@@ -160,20 +292,23 @@ struct ray_softc {
struct callout_handle \
sj_timerh; /* Handle for start_join timer */
#endif /* RAY_NEED_STARTJOIN_TIMO */
+ struct callout_handle \
+ start_timerh; /* Handle for start timer */
char *card_type; /* Card model name */
char *vendor; /* Card manufacturer */
int unit; /* Unit number */
u_char gone; /* 1 = Card bailed out */
- int irq; /* Assigned IRQ */
caddr_t maddr; /* Shared RAM Address */
- int msize; /* Shared RAM Size */
+ int flags; /* Start up flags */
int translation; /* Packet translation types */
- /* XXX these can go when attribute reading is fixed */
+
+#if (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP)
int slotnum; /* Slot number */
struct mem_desc md; /* Map info for common memory */
+#endif /* (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP) */
struct ray_ecf_startup_v5 \
sc_ecf_startup; /* Startup info from card */
@@ -210,8 +345,9 @@ static struct ray_softc ray_softc[NRAY];
#define sc_ssid sc_cnet_2.p_ssid
#define sc_priv_start sc_cnet_2.p_privacy_must_start
#define sc_priv_join sc_cnet_2.p_privacy_can_join
-/*XXX add to debug macro too */
+/* Remember to add to the debug macro and ioctl*/
+/* XXX might not need these */
/* Commands -- priority given to LSB */
#define SCP_FIRST 0x0001
#define SCP_UPDATESUBCMD 0x0001
@@ -233,7 +369,11 @@ static struct ray_softc ray_softc[NRAY];
#define SCP_TIMOCHECK_CMD_MASK \
(SCP_UPD_UPDATEPARAMS | SCP_UPD_STARTUP | SCP_UPD_MCAST | \
SCP_UPD_PROMISC)
-/* Translation types */
+/*XXX might not need these */
+
+/*
+ * Translation types
+ */
/* XXX maybe better as part of the if structure? */
#define SC_TRANSLATE_WEBGEAR 0
@@ -278,13 +418,16 @@ static u_int8_t ray_free_ccs __P((struct ray_softc *sc, size_t ccs));
static int ray_issue_cmd __P((struct ray_softc *sc, size_t ccs, u_int track));
static void ray_rcs_intr __P((struct ray_softc *sc, size_t ccs));
static void ray_rx __P((struct ray_softc *sc, size_t rcs));
+static void ray_start_done __P((struct ray_softc *sc, size_t ccs, u_int8_t status));
+static void ray_start_timo __P((void *xsc));
+static size_t ray_start_wrhdr __P((struct ray_softc *sc, struct ether_header *eh, size_t bufp));
static void ray_start_join_done __P((struct ray_softc *sc, size_t ccs, u_int8_t status));
#if RAY_NEED_STARTJOIN_TIMO
static void ray_start_join_timo __P((void *xsc));
#endif /* RAY_NEED_STARTJOIN_TIMO */
-#if RAY_DEBUG > 10
+#if RAY_DEBUG > 50
static void ray_dump_mbuf __P((struct ray_softc *sc, struct mbuf *m, char *s));
-#endif /* RAY_DEBUG > 10 */
+#endif /* RAY_DEBUG > 50 */
/*
* Indirections for reading/writing shared memory - from NetBSD/if_ray.c
@@ -335,6 +478,11 @@ static void ray_dump_mbuf __P((struct ray_softc *sc, struct mbuf *m, char *s));
#ifndef RAY_CCS_TIMEOUT
#define RAY_CCS_TIMEOUT (hz / 2)
#endif
+#ifndef RAY_START_TIMEOUT
+#define RAY_START_TIMEOUT (hz / 2)
+#endif
+#define RAY_CCS_FREE(sc, ccs) \
+ SRAM_WRITE_FIELD_1((sc), (ccs), ray_cmd, c_status, RAY_CCS_STATUS_FREE)
#define RAY_ECF_READY(sc) (!(ray_read_reg(sc, RAY_ECFIR) & RAY_ECFIR_IRQ))
#define RAY_ECF_START_CMD(sc) ray_attr_write((sc), RAY_ECFIR, RAY_ECFIR_IRQ)
#define RAY_HCS_CLEAR_INTR(sc) ray_attr_write((sc), RAY_HCSIR, 0)
@@ -352,13 +500,13 @@ static int ray_attr_write __P((struct ray_softc *sc, off_t offset, u_int8_t byte
static int ray_attr_read __P((struct ray_softc *sc, off_t offset, u_int8_t *buf, int size));
static u_int8_t ray_read_reg __P((struct ray_softc *sc, off_t reg));
-#if RAY_NEED_CM_REMAPPING
+#if (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP)
static void ray_attr_getmap __P((struct ray_softc *sc));
static void ray_attr_cm __P((struct ray_softc *sc));
#define RAY_MAP_CM(sc) ray_attr_cm(sc)
#else
#define RAY_MAP_CM(sc)
-#endif /* RAY_NEED_CM_REMAPPING */
+#endif /* (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP) */
/*
* PCCard initialise.
@@ -368,36 +516,58 @@ ray_pccard_init (dev_p)
struct pccard_devinfo *dev_p;
{
struct ray_softc *sc;
- u_int32_t irq;
- int j;
+ int doRemap;
- RAY_DPRINTF(("ray%d: PCCard probe\n", dev_p->isahd.id_unit));
+ RAY_DPRINTFN(5, ("ray%d: PCCard probe\n", dev_p->isahd.id_unit));
if (dev_p->isahd.id_unit >= NRAY)
return(ENODEV);
sc = &ray_softc[dev_p->isahd.id_unit];
- sc->gone = 0;
- sc->unit = dev_p->isahd.id_unit;
- sc->slotnum = dev_p->slt->slotnum;
- /* Get IRQ - encoded as a bitmask. */
- irq = dev_p->isahd.id_irq;
- for (j = 0; j < 32; j++) {
- if (irq & 0x1)
- break;
- irq >>= 1;
+#if (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP)
+ sc->slotnum = dev_p->slt->slotnum;
+ ray_attr_getmap(sc);
+ RAY_DPRINTFN(1, ("ray%d: Memory window flags 0x%02x, start %p, size 0x%x, card address 0x%lx\n", sc->unit, sc->md.flags, sc->md.start, sc->md.size, sc->md.card));
+#endif /* (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP) */
+
+#if RAY_NEED_CM_FIXUP
+ doRemap = 0;
+ if (sc->md.flags != MDF_ACTIVE) {
+ printf("ray%d: Fixing up CM flags from 0x%x to 0x40\n",
+ sc->unit, sc->md.flags);
+ doRemap = 1;
+ sc->md.flags = MDF_ACTIVE;
}
- sc->irq = j;
- sc->maddr = dev_p->isahd.id_maddr;
- sc->msize = dev_p->isahd.id_msize;
+ if (sc->md.size != 0xc000) {
+ printf("ray%d: Fixing up CM size from 0x%x to 0xc000\n",
+ sc->unit, sc->md.size);
+ doRemap = 1;
+ sc->md.size = 0xc000;
+ dev_p->isahd.id_msize = sc->md.size;
+ }
+ if (sc->md.card != 0) {
+ printf("ray%d: Fixing up CM card address from 0x%lx to 0x0\n",
+ sc->unit, sc->md.card);
+ doRemap = 1;
+ sc->md.card = 0;
+ }
+ if (doRemap)
+ ray_attr_cm(sc);
+#endif /* RAY_NEED_CM_FIXUP */
- printf("ray%d: <Raylink/IEEE 802.11> maddr 0x%lx msize 0x%x irq %d on isa (PC-Card slot %d)\n",
- sc->unit, (unsigned long)sc->maddr, sc->msize, sc->irq, sc->slotnum);
+ sc->gone = 0;
+ sc->unit = dev_p->isahd.id_unit;
+ sc->maddr = dev_p->isahd.id_maddr;
+ sc->flags = dev_p->isahd.id_flags;
-#if RAY_NEED_CM_REMAPPING
- ray_attr_getmap(sc);
-#endif /* RAY_NEED_CM_REMAPPING */
+ printf("ray%d: <Raylink/IEEE 802.11> maddr 0x%lx msize 0x%x irq %d flags 0x%x on isa (PC-Card slot %d)\n",
+ sc->unit,
+ (unsigned long)sc->maddr,
+ dev_p->isahd.id_msize,
+ ffs(dev_p->isahd.id_irq) - 1,
+ sc->flags,
+ sc->slotnum);
if (ray_attach(&dev_p->isahd))
return(ENXIO);
@@ -415,7 +585,7 @@ ray_pccard_unload (dev_p)
struct ray_softc *sc;
struct ifnet *ifp;
- RAY_DPRINTF(("ray%d: PCCard unload\n", dev_p->isahd.id_unit));
+ RAY_DPRINTFN(5, ("ray%d: PCCard unload\n", dev_p->isahd.id_unit));
sc = &ray_softc[dev_p->isahd.id_unit];
@@ -424,6 +594,7 @@ ray_pccard_unload (dev_p)
return;
}
+/* XXX shouldn't we call _stop? */
/* Cleardown interface */
ifp = &sc->arpcom.ac_if;
ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
@@ -439,17 +610,18 @@ ray_pccard_unload (dev_p)
/*
* PCCard interrupt.
*/
-/* XXX return 1 if we take interrupt, 0 otherwise */
static int
ray_pccard_intr (dev_p)
struct pccard_devinfo *dev_p;
{
struct ray_softc *sc;
+ struct ifnet *ifp;
int ccsi, handled;
- RAY_DPRINTF(("ray%d: PCCard intr\n", dev_p->isahd.id_unit));
+ RAY_DPRINTFN(5, ("ray%d: PCCard intr\n", dev_p->isahd.id_unit));
sc = &ray_softc[dev_p->isahd.id_unit];
+ ifp = &sc->arpcom.ac_if;
RAY_MAP_CM(sc);
if (sc->gone) {
@@ -476,25 +648,16 @@ ray_pccard_intr (dev_p)
else
printf("ray%d: ray_intr bad ccs index %d\n", sc->unit, ccsi);
-#if XXX
- ccs_done and rcs_intr return function pointers - why dont
- they just do it themselves? its not as if each command only
- requires a single function call - things like start_join_net
- call a couple on the way...
- if (rcmd)
- (*rcmd)(sc);
-#endif
-
}
if (handled)
RAY_HCS_CLEAR_INTR(sc);
- RAY_DPRINTF(("ray%d: interrupt %s handled\n",
+ RAY_DPRINTFN(10, ("ray%d: interrupt %s handled\n",
sc->unit, handled?"was":"not"));
/* Send any packets lying around */
- if (!(sc->sc_if.if_flags & IFF_OACTIVE) && (ifp->if_snd.ifq_head != NULL))
+ if (!(ifp->if_flags & IFF_OACTIVE) && (ifp->if_snd.ifq_head != NULL))
ray_start(ifp);
return(handled);
@@ -508,7 +671,7 @@ ray_probe (dev_p)
struct isa_device *dev_p;
{
- RAY_DPRINTF(("ray%d: ISA probe\n", dev_p->id_unit));
+ RAY_DPRINTFN(5, ("ray%d: ISA probe\n", dev_p->id_unit));
return(0);
}
@@ -525,7 +688,7 @@ ray_attach (dev_p)
struct ifnet *ifp;
char ifname[IFNAMSIZ];
- RAY_DPRINTF(("ray%d: ISA/PCCard attach\n", dev_p->id_unit));
+ RAY_DPRINTFN(5, ("ray%d: ISA/PCCard attach\n", dev_p->id_unit));
sc = &ray_softc[dev_p->id_unit];
RAY_MAP_CM(sc);
@@ -602,7 +765,7 @@ ray_attach (dev_p)
* Do not update these in ray_init's parameter setup
*/
#if XXX
- see the ray_init section for stuff to move here
+ see the ray_init section for stuff to move
#endif
/*
@@ -619,7 +782,7 @@ ray_attach (dev_p)
#if XXX
ifp->if_hdr = ...; make this big enough to hold the .11 and .3 headers
#endif
- ifp->if_baudrate = 1000000; /* XXX Is this baud or bps ;-) */
+ ifp->if_baudrate = 1000000; /* Is this baud or bps ;-) */
ifp->if_output = ether_output;
ifp->if_start = ray_start;
@@ -639,6 +802,7 @@ ray_attach (dev_p)
#if RAY_NEED_STARTJOIN_TIMO
callout_handle_init(&sc->sj_timerh);
#endif /* RAY_NEED_STARTJOIN_TIMO */
+ callout_handle_init(&sc->start_timerh);
if_attach(ifp);
ether_ifattach(ifp);
#if NBPFILTER > 0
@@ -657,45 +821,228 @@ ray_attach (dev_p)
/*
* Network start.
*
- *XXX from if_xe
- * Start output on interface. We make two assumptions here:
- * 1) that the current priority is set to splimp _before_ this code
+ * Start sending a packet.
+ *
+ * We make two assumptions here:
+ * 1) That the current priority is set to splimp _before_ this code
* is called *and* is returned to the appropriate priority after
* return
- * 2) that the IFF_OACTIVE flag is checked before this code is called
+ * 2) That the IFF_OACTIVE flag is checked before this code is called
* (i.e. that the output part of the interface is idle)
- *XXX from if_xe so maybe we can ignore? see start_join_net_done
*/
static void
ray_start (ifp)
register struct ifnet *ifp;
{
struct ray_softc *sc;
- struct mbuf *m;
+ struct mbuf *m0, *m;
+ struct ether_header *eh;
+ size_t ccs, bufp;
+ int i, pktlen, len;
+ u_int8_t status;
- RAY_DPRINTF(("ray%d: Network start\n", ifp->if_unit));
-/* XXX mark output queue full so the kernel waits */
-ifp->if_flags |= IFF_OACTIVE;
-return;
-/* XXX mark output queue full so the kernel waits */
+ RAY_DPRINTFN(5, ("ray%d: Network start\n", ifp->if_unit));
sc = ifp->if_softc;
RAY_MAP_CM(sc);
+ /*
+ * Some simple checks first
+ */
if (sc->gone) {
printf("ray%d: unloaded before start!\n", sc->unit);
return;
}
-
if ((ifp->if_flags & IFF_RUNNING) == 0 || !sc->sc_havenet)
return;
+ if (!RAY_ECF_READY(sc)) {
+ sc->start_timerh = timeout(ray_start_timo, sc, RAY_START_TIMEOUT);
+ return;
+ } else
+ untimeout(ray_start_timo, sc, sc->start_timerh);
- /* We only deal with one packet at a time */
-/* XXX is this actually true? I don't think so there are 16 ccs */
- if (ifp->if_flags & IFF_OACTIVE)
+ /*
+ * Simple one packet at a time TX routine - probably appaling performance
+ * and we certainly chew CPU. However bing to windows boxes shows
+ * a reliance on the far end too:
+ *
+ * Libretto 50CT (75MHz Pentium) with FreeBSD-3.1 to
+ * Nonname box Windows 95C (133MHz AMD 5x86) 996109bps
+ * AST J30 Windows 95A (100MHz Pentium) 1307791bps
+ *
+ * Flow is
+ * get a ccs
+ * build the packet
+ * set IFF_OACTIVE
+ * interrupt the card to send the packet
+ * exit
+ *
+ * wait for interrupt telling us the packet has been sent
+ * clear IFF_OACTIVE
+ * get called by the interrupt routine if any packets left
+ */
+
+ /*
+ * Find a free ccs; if none available wave good bye and exit.
+ *
+ * We find a ccs before we process the mbuf so that we are sure it
+ * is worthwhile processing the packet. All errors in the mbuf
+ * processing are either errors in the mbuf or gross configuration
+ * errors and the packet wouldn't get through anyway.
+ *
+ * Don't forget to clear the ccs on errors.
+ */
+ i = RAY_CCS_TX_FIRST;
+ do {
+ status = SRAM_READ_FIELD_1(sc, RAY_CCS_ADDRESS(i), ray_cmd, c_status);
+ if (status == RAY_CCS_STATUS_FREE)
+ break;
+ i++;
+ } while (i <= RAY_CCS_TX_LAST);
+ if (i > RAY_CCS_TX_LAST) {
+ ifp->if_flags |= IFF_OACTIVE;
+ return;
+ }
+ RAY_DPRINTFN(20, ("ray%d: ray_start using ccs 0x%02x\n", sc->unit, i));
+
+ /*
+ * Reserve and fill the ccs - must do the length later.
+ *
+ * Even though build 4 and build 5 have different fields all these
+ * are common apart from tx_rate. This will be overwritten later if
+ * needed.
+ */
+ ccs = RAY_CCS_ADDRESS(i);
+ bufp = RAY_TX_BASE + i * RAY_TX_BUF_SIZE;
+ bufp += sc->sc_tibsize;
+ SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_status, RAY_CCS_STATUS_BUSY);
+ SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_cmd, RAY_CMD_TX_REQ);
+ SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_link, RAY_CCS_LINK_NULL);
+ SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_bufp, bufp);
+ SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_tx_rate, sc->sc_def_txrate);
+ SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_apm_mode, 0);
+ SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_antenna, 0);
+ bufp += sizeof(struct ray_tx_phy_header);
+
+ /*
+ * Get the mbuf and process it - we have to remember to free the
+ * ccs if there are any errors
+ */
+ IF_DEQUEUE(&ifp->if_snd, m0);
+ if (m0 == NULL) {
+ RAY_CCS_FREE(sc, ccs);
+ return;
+ }
+
+ for (pktlen = 0, m = m0; m != NULL; m = m->m_next) {
+ pktlen += m->m_len;
+ }
+ if (pktlen > ETHER_MAX_LEN - ETHER_CRC_LEN) {
+ RAY_DPRINTFN(1, ("ray%d: mbuf too long %d\n", sc->unit, pktlen));
+ RAY_CCS_FREE(sc, ccs);
+ ifp->if_oerrors++;
+ m_freem(m0);
+ return;
+ }
+
+ /*
+ * Translation - capability as described earlier
+ *
+ * Each case must write the 802.11 header using ray_start_wrhdr,
+ * passing a pointer to the ethernet header in and getting a new
+ * tc buffer pointer. Next remove/modify/addto the 802.3 and 802.2
+ * headers as needed.
+ *
+ * We've pulled up the mbuf for you.
+ */
+ if (m0->m_len < sizeof(struct ether_header))
+ m = m_pullup(m, sizeof(struct ether_header));
+ if (m0 == NULL) {
+ RAY_DPRINTFN(1, ("ray%d: ray_start could not pullup ether\n", sc->unit));
+ RAY_CCS_FREE(sc, ccs);
+ ifp->if_oerrors++;
+ return;
+ }
+ eh = mtod(m0, struct ether_header *);
+ switch (sc->translation) {
+
+ case SC_TRANSLATE_WEBGEAR:
+ bufp = ray_start_wrhdr(sc, eh, bufp);
+ break;
+
+ default:
+ printf("ray%d: ray_start unknown translation type 0x%x - why?\n",
+ sc->unit, sc->translation);
+ RAY_CCS_FREE(sc, ccs);
+ ifp->if_oerrors++;
+ m0 = m_free(m0);
+ return;
+
+ }
+ if (m0 == NULL) {
+ RAY_DPRINTFN(1, ("ray%d: ray_start could not translate mbuf\n", sc->unit));
+ RAY_CCS_FREE(sc, ccs);
+ ifp->if_oerrors++;
+ return;
+ }
+ pktlen = sizeof(struct ieee80211_header);
+
+ /*
+ * Copy the mbuf to the buffer in common memory
+ *
+ * We panic and don't bother wrapping as ethernet packets are 1518
+ * bytes, we checked the mbuf earlier, and our TX buffers are 2048
+ * bytes. We don't have 530 bytes of headers etc. so something
+ * must be fubar.
+ */
+ for (m = m0; m != NULL; m = m->m_next) {
+ pktlen += m->m_len;
+ if ((len = m->m_len) == 0)
+ continue;
+ if ((bufp + len) < RAY_TX_END)
+ ray_write_region(sc, bufp, mtod(m, u_int8_t *), len);
+ else
+ panic("ray%d: ray_start tx buffer overflow\n", sc->unit);
+ bufp += len;
+ }
+ RAY_DMBUF_DUMP(sc, m0, "ray_start");
+ m_free(m0);
+
+ /*
+ * Fill in a few loose ends and kick the card to send the packet
+ */
+ if (!RAY_ECF_READY(sc)) {
+ /*
+ * From NetBSD code:
+ *
+ * If this can really happen perhaps we need to save
+ * the chain and use it later. I think this might
+ * be a confused state though because we check above
+ * and don't issue any commands between.
+ */
+ printf("ray%d: ray_tx device busy\n", sc->unit);
+ RAY_CCS_FREE(sc, ccs);
+ ifp->if_oerrors++;
return;
+ }
+ SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_len, pktlen);
+ SRAM_WRITE_1(sc, RAY_SCB_CCSI, ccs);
+ ifp->if_opackets++;
+ ifp->if_flags |= IFF_OACTIVE;
+ RAY_ECF_START_CMD(sc);
#if XXX
+#if NBPFILTER > 0
+ /* XXX but the translation code dicks around with the mbuf structure sigh */
+ /* XXX and I've freed the mbuf already */
+ if (ifp->if_bpf)
+ bpf_mtap(ifp, m0);
+#endif
+#endif /* XXX */
+
+ return;
+}
+#if XXX
netbsd
driver uses a loop
@@ -715,10 +1062,7 @@ driver is simple single shot packet (with a lot of spinlocks!)
general
-why 14 CCS reserved for TX in Linux+NetBSD? Is it simply that there are
-that many ethernet+80211header packets in the TX memory space? probably
-
-the tx space is 0x7000 = 28kB, and TX buffer size is 2048? so there
+the tx space is 0x7000 = 28kB, and TX buffer size is 2048 so there
can be 14 requests at 2kB each
from this 2k we have to remove the TIB - whatever that is - for data
@@ -728,13 +1072,13 @@ netbsd:
we need to call _start after receiveing a packet to see
if any packets were queued whilst in the interrupt
- there is a potential race in obtaining ccs's for the tx, in that
+ there is a potential race in obtaining ccss for the tx, in that
we might be in _start synchronously and then an rx interrupt
occurs. the rx will call _start and steal tx ccs from underneath
the interrupted entry.
toptions
- don't call _start from rx interrupt
+ dont call _start from rx interrupt
find a safe way of locking
@@ -748,17 +1092,116 @@ netbsd:
free lsit
+ rework calling
#endif
- IF_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- return;
-
+/*
+ * TX completion routine.
+ *
+ * Clear ccs and network flags.
+ */
+static void
+ray_start_done (sc, ccs, status)
+ struct ray_softc *sc;
+ size_t ccs;
+ u_int8_t status;
+{
+ struct ifnet *ifp;
+ char *status_string[] = RAY_CCS_STATUS_STRINGS;
+
+ RAY_DPRINTFN(5, ("ray%d: ray_start_done\n", sc->unit));
+ RAY_MAP_CM(sc);
+
+ ifp = &sc->arpcom.ac_if;
+
+ if (status != RAY_CCS_STATUS_COMPLETE) {
+ printf("ray%d: ray_start tx completed but status is %s.\n",
+ sc->unit, status_string[status]);
+ ifp->if_oerrors++;
+ }
+
+ RAY_CCS_FREE(sc, ccs);
+ ifp->if_timer = 0;
+ if (ifp->if_flags & IFF_OACTIVE)
+ ifp->if_flags &= ~IFF_OACTIVE;
+
return;
}
/*
+ * Start timeout routine.
+ *
+ * Used when card was busy but we needed to send a packet.
+ */
+static void
+ray_start_timo (xsc)
+ void *xsc;
+{
+ struct ray_softc *sc = xsc;
+ struct ifnet *ifp;
+ int s;
+
+ RAY_DPRINTFN(5, ("ray%d: ray_start_timo\n", sc->unit));
+ RAY_MAP_CM(sc);
+
+ ifp = &sc->arpcom.ac_if;
+
+ if (!(ifp->if_flags & IFF_OACTIVE) && (ifp->if_snd.ifq_head != NULL)) {
+ s = splimp();
+ ray_start(ifp);
+ splx(s);
+ }
+
+ return;
+}
+
+/*
+ * Write an 802.11 header into the TX buffer and return the
+ * adjusted buffer pointer.
+ */
+static size_t
+ray_start_wrhdr (sc, eh, bufp)
+ struct ray_softc *sc;
+ struct ether_header *eh;
+ size_t bufp;
+{
+ struct ieee80211_header header;
+
+ RAY_DPRINTFN(5, ("ray%d: ray_start_wrhdr\n", sc->unit));
+ RAY_MAP_CM(sc);
+
+ bzero(&header, sizeof(struct ieee80211_header));
+
+ header.i_fc[0] = (IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA);
+ if (sc->sc_net_type == RAY_MIB_NET_TYPE_ADHOC) {
+
+ header.i_fc[1] = IEEE80211_FC1_STA_TO_STA;
+ bcopy(eh->ether_dhost, header.i_addr1, ETHER_ADDR_LEN);
+ bcopy(eh->ether_shost, header.i_addr2, ETHER_ADDR_LEN);
+ bcopy(sc->sc_bss_id, header.i_addr3, ETHER_ADDR_LEN);
+
+ } else {
+#if XXX_INFRA
+ if (sc->sc_ap_status == RAY_MIB_AP_STATUS_TERMINAL) {
+
+ header.i_fc[1] = IEEE80211_FC1_STA_TO_AP;
+ bcopy(sc->sc_bss_id, header.i_addr1, ETHER_ADDR_LEN);
+ bcopy(eh->ether_shost, header.i_addr2, ETHER_ADDR_LEN);
+ bcopy(eh->ether_dhost, header.i_addr3, ETHER_ADDR_LEN);
+
+ } else
+ panic("ray%d: ray_start can't be an AP yet\n", sc-.unit);
+#endif /* XXX_INFRA */
+ }
+
+ ray_write_region(sc, bufp, (u_int8_t *)&header,
+ sizeof(struct ieee80211_header));
+
+ return(bufp + sizeof(struct ieee80211_header));
+}
+
+/*
* Network ioctl request.
*/
static int
@@ -770,7 +1213,7 @@ ray_ioctl (ifp, command, data)
struct ray_softc *sc;
int s, error = 0;
- RAY_DPRINTF(("ray%d: Network ioctl\n", ifp->if_unit));
+ RAY_DPRINTFN(5, ("ray%d: Network ioctl\n", ifp->if_unit));
sc = ifp->if_softc;
RAY_MAP_CM(sc);
@@ -778,7 +1221,7 @@ ray_ioctl (ifp, command, data)
if (sc->gone) {
printf("ray%d: unloaded before ioctl!\n", sc->unit);
ifp->if_flags &= ~IFF_RUNNING;
- return ENXIO;
+ return(ENXIO);
}
s = splimp();
@@ -788,12 +1231,12 @@ ray_ioctl (ifp, command, data)
case SIOCSIFADDR:
case SIOCGIFADDR:
case SIOCSIFMTU:
- RAY_DPRINTF(("ray%d: ioctl SIFADDR/GIFADDR/SIFMTU\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: ioctl SIFADDR/GIFADDR/SIFMTU\n", sc->unit));
error = ether_ioctl(ifp, command, data);
break;
case SIOCSIFFLAGS:
- RAY_DPRINTF(("ray%d: for SIFFLAGS\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: for SIFFLAGS\n", sc->unit));
/*
* If the interface is marked up and stopped, then start
* it. If it is marked down and running, then stop it.
@@ -810,7 +1253,7 @@ ray_ioctl (ifp, command, data)
#if XXX
case SIOCADDMULTI:
case SIOCDELMULTI:
- RAY_DPRINTF(("ray%d: ioctl called for ADDMULTI/DELMULTI\n, sc->unit"));
+ RAY_DPRINTFN(30, ("ray%d: ioctl called for ADDMULTI/DELMULTI\n, sc->unit"));
/*
* Multicast list has (maybe) changed; set the hardware filter
* accordingly. This also serves to deal with promiscuous mode
@@ -823,31 +1266,31 @@ ray_ioctl (ifp, command, data)
break;
case SIOCGIFFLAGS:
- RAY_DPRINTF(("ray%d: ioctl called for GIFFLAGS\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: ioctl called for GIFFLAGS\n", sc->unit));
error = EINVAL;
break;
case SIOCGIFMETRIC:
- RAY_DPRINTF(("ray%d: ioctl called for GIFMETRIC\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: ioctl called for GIFMETRIC\n", sc->unit));
error = EINVAL;
break;
case SIOCGIFMTU:
- RAY_DPRINTF(("ray%d: ioctl called for GIFMTU\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: ioctl called for GIFMTU\n", sc->unit));
error = EINVAL;
break;
case SIOCGIFPHYS:
- RAY_DPRINTF(("ray%d: ioctl called for GIFPYHS\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: ioctl called for GIFPYHS\n", sc->unit));
error = EINVAL;
break;
case SIOCSIFMEDIA:
- RAY_DPRINTF(("ray%d: ioctl called for SIFMEDIA\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: ioctl called for SIFMEDIA\n", sc->unit));
error = EINVAL;
break;
case SIOCGIFMEDIA:
- RAY_DPRINTF(("ray%d: ioctl called for GIFMEDIA\n", sc->unit));
+ RAY_DPRINTFN(30, ("ray%d: ioctl called for GIFMEDIA\n", sc->unit));
#if RAY_DUMP_CM_ON_GIFMEDIA
- RAY_DPRINTF(("ray%d: RAY_SCB\n", sc->unit));
+ RAY_DPRINTFN(10, ("ray%d: RAY_SCB\n", sc->unit));
RAY_DHEX8((u_int8_t *)sc->maddr + RAY_SCB_BASE, 0x20);
- RAY_DPRINTF(("ray%d: RAY_STATUS\n", sc->unit));
+ RAY_DPRINTFN(10, ("ray%d: RAY_STATUS\n", sc->unit));
RAY_DNET_DUMP(sc, ".");
#endif /* RAY_DUMP_CM_ON_GIFMEDIA */
error = EINVAL;
@@ -857,7 +1300,7 @@ case SIOCGIFMEDIA:
error = EINVAL;
}
- (void)splx(s);
+ splx(s);
return(error);
}
@@ -868,7 +1311,7 @@ ray_watchdog (ifp)
{
struct ray_softc *sc;
- RAY_DPRINTF(("ray%d: Network watchdog\n", ifp->if_unit));
+ RAY_DPRINTFN(5, ("ray%d: Network watchdog\n", ifp->if_unit));
sc = ifp->if_softc;
RAY_MAP_CM(sc);
@@ -886,6 +1329,10 @@ ray_watchdog (ifp)
ray_stop
...
ray_init
+
+ do we only use on TX?
+ if so then we should clear OACTIVE etc.
+
*/
return;
@@ -893,6 +1340,28 @@ ray_watchdog (ifp)
/*
* Network initialisation.
+ *
+ * Start up flow is as follows.
+ * The kernel calls ray_init when the interface is assigned an address.
+ *
+ * ray_init does a bit of house keeping before calling ray_download_params.
+ *
+ * ray_download_params fills the startup parameter structure out and
+ * sends it to the card. The download command simply completes so we
+ * use schedule a timeout function call to ray_download_timo instead
+ * of spin locking. We pass the ccs in use via sc->sc_css.
+ *
+ * ray_download_timo checks the ccs for command completion and/or
+ * errors. Then it tells the card to start an adhoc network or join a
+ * managed network. This should complete via the interrupt mechanism,
+ * but the NetBSD driver includes a timeout for some buggy stuff
+ * somewhere - I've left the hooks in but don't use them. The interrupt
+ * handler passes control to ray_start_join_done - the ccs is handled
+ * by the interrupt mechanism.
+ *
+ * Once ray_start_join_done has checked the ccs and uploaded/updated
+ * the network parameters we are ready to process packets. It is then
+ * safe to call ray_start which is done by the interrupt handler.
*/
static void
ray_init (xsc)
@@ -904,7 +1373,7 @@ ray_init (xsc)
size_t ccs;
int i;
- RAY_DPRINTF(("ray%d: Network init\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: Network init\n", sc->unit));
RAY_MAP_CM(sc);
if (sc->gone) {
@@ -926,37 +1395,30 @@ ray_init (xsc)
* The second set are network parameters that are downloaded to
* the card.
*
+ * The third set are driver parameters.
+ *
* All of the variables in these sets can be updated by the card or ioctls.
*/
+#if XXX
+ see the ray_attach section for stuff to move
+#endif
sc->sc_upd_param = 0;
bzero(sc->sc_bss_id, sizeof(sc->sc_bss_id));
sc->sc_inited = 0;
sc->sc_def_txrate = 0;
sc->sc_encrypt = 0;
- sc->translation = SC_TRANSLATE_WEBGEAR;
-
-#if XXX
- these might be better in _attach so updated values are kept
- over up/down events
-
- we probably also need a few more
- countrycode
-#endif
sc->sc_net_type = RAY_MIB_NET_TYPE_DEFAULT;
- bzero(&sc->sc_ssid, sizeof(sc->sc_ssid));
+ bzero(sc->sc_ssid, sizeof(sc->sc_ssid));
strncpy(sc->sc_ssid, RAY_MIB_SSID_DEFAULT, RAY_MAXSSIDLEN);
sc->sc_priv_start = RAY_MIB_PRIVACY_MUST_START_DEFAULT;
sc->sc_priv_join = RAY_MIB_PRIVACY_CAN_JOIN_DEFAULT;
+#if XXX_MCASTPROM
+ sc->sc_promisc = !!(sc->sc_if.if_flags & (IFF_PROMISC|IFF_ALLMULTI));
+#endif /* XXX_MCASTPROM */
sc->sc_havenet = 0;
-#if XXX
-NetBSD
- sc->sc_scheduled = 0;
- sc->sc_running = 0;
- sc->sc_txfree = RAY_CCS_NTX;
- sc->sc_checkcounters = 0;
-#endif
+ sc->translation = SC_TRANSLATE_WEBGEAR;
/* Set all ccs to be free */
bzero(sc->sc_ccsinuse, sizeof(sc->sc_ccsinuse));
@@ -968,6 +1430,10 @@ NetBSD
/* Clear any pending interrupts */
RAY_HCS_CLEAR_INTR(sc);
+#if XXX
+ Not sure why I really need this - maybe best to deal with
+ this when resets are requested by me?
+#endif /* XXX */
/*
* Get startup results - the card may have been reset
*/
@@ -986,54 +1452,22 @@ NetBSD
"\007RERSERVED1"
"\008TEST_COMPLETE"
);
-#if XXX
return; /* XXX This doesn't mark the interface as down */
-#endif /* XXX */
}
/*
* Fixup tib size to be correct - on build 4 it is garbage
*/
if (sc->sc_version == RAY_ECFS_BUILD_4 && sc->sc_tibsize == 0x55)
- sc->sc_tibsize = 32;
+ sc->sc_tibsize = sizeof(struct ray_tx_tib);
/*
* We are now up and running. Next we have to download network
* configuration into the card. We are busy until download is done.
*/
ifp->if_flags |= IFF_RUNNING | IFF_OACTIVE;
-#if XXX
- /* set this now so it gets set in the download */
- sc->sc_promisc = !!(sc->sc_if.if_flags & (IFF_PROMISC|IFF_ALLMULTI));
-#endif /* XXX */
- ray_download_params(sc);
-
-#if XXX
- need to understand how the doenload finishes first
-
- Start up flow is as follows.
-
- The kernel calls ray_init when the interface is assigned an address.
-
- ray_init does a bit of house keeping before calling ray_download_params.
-
- ray_download_params fills the startup parameter structure out and
- sends it to the card. The download command simply completes so
- we use schedule a timeout function call to ray_download_timo.
- We pass the ccs in use via sc->sc_css.
- ray_download_timo checks the ccs for command completion/errors.
- Then it tells the card to start an adhoc or join a managed
- network. This should complete via the interrupt mechanism, but
- the NetBSD driver includes a timeout for some buggy stuff somewhere.
- I've left the hooks in but don't use them. The interrupt handler
- passes control to ray_start_join_done - the ccs is handled by
- the interrupt mechanism.
-
- Once ray_start_join_done has checked the ccs and
- uploaded/updated the network parameters we are ready to
- process packets. It can then call ray_start.
-#endif /* XXX */
+ ray_download_params(sc);
return;
}
@@ -1047,7 +1481,7 @@ ray_stop (sc)
{
struct ifnet *ifp;
- RAY_DPRINTF(("ray%d: Network stop\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: Network stop\n", sc->unit));
RAY_MAP_CM(sc);
if (sc->gone) {
@@ -1057,7 +1491,15 @@ ray_stop (sc)
ifp = &sc->arpcom.ac_if;
-/* XXX stuff here please to kill activity on the card and drain down transmissons */
+ /* XXX how do we clear ccs etc. properly */
+ /* XXX how do we inhibit interrupts properly */
+ /* XXX do these matter are we always restated with an _init? */
+
+ untimeout(ray_download_timo, sc, sc->timerh);
+#if RAY_NEED_STARTJOIN_TIMO
+ untimeout(ray_start_join_timo, sc, sc->sj_timerh);
+#endif /* RAY_NEED_STARTJOIN_TIMO */
+ untimeout(ray_start_timo, sc, sc->start_timerh);
/* Mark as not running */
ifp->if_flags &= ~IFF_RUNNING;
@@ -1075,58 +1517,61 @@ ray_ccs_done (sc, ccs)
{
u_int cmd, status;
- RAY_DPRINTF(("ray%d: Processing ccs %d\n", sc->unit, RAY_CCS_INDEX(ccs)));
+ RAY_DPRINTFN(5, ("ray%d: ray_ccs_done\n", sc->unit));
RAY_MAP_CM(sc);
cmd = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd);
status = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
- RAY_DPRINTF(("ray%d: ccs idx %d ccs 0x%x cmd 0x%x stat %d\n",
+ RAY_DPRINTFN(20, ("ray%d: ccs idx %d ccs 0x%x cmd 0x%x status %d\n",
sc->unit, RAY_CCS_INDEX(ccs), ccs, cmd, status));
- /* XXX should we panic on unrecognised commands or just ignore them?
- * maybe I'll macroize the printf's */
switch (cmd) {
case RAY_CMD_START_PARAMS:
printf("ray%d: ray_ccs_done got START_PARAMS - why?\n", sc->unit);
break;
case RAY_CMD_UPDATE_PARAMS:
- RAY_DPRINTF(("ray%d: ray_ccs_done got UPDATE_PARAMS\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_ccs_done got UPDATE_PARAMS\n",
+ sc->unit));
XXX;
break;
case RAY_CMD_REPORT_PARAMS:
- RAY_DPRINTF(("ray%d: ray_ccs_done got REPORT_PARAMS\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_ccs_done got REPORT_PARAMS\n",
+ sc->unit));
XXX;
break;
case RAY_CMD_UPDATE_MCAST:
- RAY_DPRINTF(("ray%d: ray_ccs_done got UPDATE_MCAST\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_ccs_done got UPDATE_MCAST\n",
+ sc->unit));
XXX;
break;
case RAY_CMD_UPDATE_APM:
- RAY_DPRINTF(("ray%d: ray_ccs_done got UPDATE_APM\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_ccs_done got UPDATE_APM\n",
+ sc->unit));
XXX;
break;
case RAY_CMD_START_NET:
case RAY_CMD_JOIN_NET:
- RAY_DPRINTF(("ray%d: ray_ccs_done got START|JOIN_NET\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_ccs_done got START|JOIN_NET\n",
+ sc->unit));
ray_start_join_done(sc, ccs, status);
break;
case RAY_CMD_START_ASSOC:
- RAY_DPRINTF(("ray%d: ray_ccs_done got START_ASSOC\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_ccs_done got START_ASSOC\n",
+ sc->unit));
sc->sc_havenet = 1; /* Should not be here but in function */
XXX;
break;
case RAY_CMD_TX_REQ:
- RAY_DPRINTF(("ray%d: ray_ccs_done got TX_REQ\n", sc->unit));
- SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE);
- if (sc->sc_if.if_flags & IFF_OACTIVE)
- sc->sc_if.if_flags &= ~IFF_OACTIVE;
+ RAY_DPRINTFN(20, ("ray%d: ray_ccs_done got TX_REQ\n",
+ sc->unit));
+ ray_start_done(sc, ccs, status);
return;
case RAY_CMD_TEST_MEM:
@@ -1166,43 +1611,42 @@ ray_rcs_intr (sc, rcs)
struct ifnet *ifp;
u_int cmd, status;
- RAY_DPRINTF(("ray%d: Processing rcs %d\n", sc->unit, RAY_CCS_INDEX(rcs)));
+ RAY_DPRINTFN(5, ("ray%d: ray_rcs_intr\n", sc->unit));
RAY_MAP_CM(sc);
ifp = &sc->arpcom.ac_if;
cmd = SRAM_READ_FIELD_1(sc, rcs, ray_cmd, c_cmd);
status = SRAM_READ_FIELD_1(sc, rcs, ray_cmd, c_status);
- RAY_DPRINTF(("ray%d: rcs idx %d rcs 0x%x cmd 0x%x stat %d\n",
+ RAY_DPRINTFN(20, ("ray%d: rcs idx %d rcs 0x%x cmd 0x%x status %d\n",
sc->unit, RAY_CCS_INDEX(rcs), rcs, cmd, status));
- /* XXX should we panic on unrecognised commands or just ignore them?
- * maybe I'll macroize the printf's */
switch (cmd) {
case RAY_ECMD_RX_DONE:
- printf("ray%d: ray_rcs_intr got RX_DONE\n", sc->unit);
+ RAY_DPRINTFN(20, ("ray%d: ray_rcs_intr got RX_DONE\n", sc->unit));
ray_rx(sc, rcs);
break;
case RAY_ECMD_REJOIN_DONE:
- RAY_DPRINTF(("ray%d: ray_rcs_intr got UPDATE_PARAMS\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_rcs_intr got UPDATE_PARAMS\n",
+ sc->unit));
XXX;
break;
case RAY_ECMD_ROAM_START:
- RAY_DPRINTF(("ray%d: ray_rcs_intr got ROAM_START\n", sc->unit));
+ RAY_DPRINTFN(20, ("ray%d: ray_rcs_intr got ROAM_START\n",
+ sc->unit));
sc->sc_havenet = 0; /* Should not be here but in function */
XXX;
break;
case RAY_ECMD_JAPAN_CALL_SIGNAL:
printf("ray%d: ray_rcs_intr got JAPAN_CALL_SIGNAL - why?\n",
- sc->unit);
+ sc->unit);
break;
default:
- printf("ray%d: ray_rcs_intr unknown command 0x%x\n",
- sc->unit, cmd);
+ printf("ray%d: ray_rcs_intr unknown command 0x%x\n", sc->unit, cmd);
break;
}
@@ -1222,20 +1666,20 @@ ray_rx (sc, rcs)
struct ieee80211_header *header;
struct ether_header *eh;
struct ifnet *ifp;
- struct mbuf *m;
+ struct mbuf *m0;
size_t pktlen, fraglen, readlen, tmplen;
size_t bufp, ebufp;
u_int8_t *dst, *src;
u_int8_t fc;
u_int first, ni, i;
- RAY_DPRINTF(("ray%d: ray_rx\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: ray_rx\n", sc->unit));
RAY_MAP_CM(sc);
- RAY_DPRINTF(("ray%d: rcs chain - using rcs 0x%x\n", sc->unit, rcs));
+ RAY_DPRINTFN(20, ("ray%d: rcs chain - using rcs 0x%x\n", sc->unit, rcs));
ifp = &sc->arpcom.ac_if;
- m = NULL;
+ m0 = NULL;
readlen = 0;
/*
@@ -1245,33 +1689,33 @@ ray_rx (sc, rcs)
first = RAY_CCS_INDEX(rcs);
pktlen = SRAM_READ_FIELD_2(sc, rcs, ray_cmd_rx, c_pktlen);
- if ((pktlen > MCLBYTES) || (pktlen < 1/*XXX should be header size*/)) {
- RAY_DPRINTF(("ray%d: ray_rx packet is too big or too small\n",
+ if ((pktlen > MCLBYTES) || (pktlen < sizeof(struct ieee80211_header))) {
+ RAY_DPRINTFN(1, ("ray%d: ray_rx packet is too big or too small\n",
sc->unit));
ifp->if_ierrors++;
goto skip_read;
}
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- RAY_DPRINTF(("ray%d: ray_rx MGETHDR failed\n", sc->unit));
+ MGETHDR(m0, M_DONTWAIT, MT_DATA);
+ if (m0 == NULL) {
+ RAY_DPRINTFN(1, ("ray%d: ray_rx MGETHDR failed\n", sc->unit));
ifp->if_ierrors++;
goto skip_read;
}
if (pktlen > MHLEN) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0) {
- RAY_DPRINTF(("ray%d: ray_rx MCLGET failed\n", sc->unit));
+ MCLGET(m0, M_DONTWAIT);
+ if ((m0->m_flags & M_EXT) == 0) {
+ RAY_DPRINTFN(1, ("ray%d: ray_rx MCLGET failed\n", sc->unit));
ifp->if_ierrors++;
- m_freem(m);
- m = 0;
+ m_freem(m0);
+ m0 = NULL;
goto skip_read;
}
}
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = pktlen;
- m->m_len = pktlen;
- dst = mtod(m, u_int8_t *);
+ m0->m_pkthdr.rcvif = ifp;
+ m0->m_pkthdr.len = pktlen;
+ m0->m_len = pktlen;
+ dst = mtod(m0, u_int8_t *);
/*
* Walk the fragment chain to build the complete packet.
@@ -1287,22 +1731,22 @@ ray_rx (sc, rcs)
ni = SRAM_READ_FIELD_1(sc, rcs, ray_cmd_rx, c_nextfrag);
bufp = SRAM_READ_FIELD_2(sc, rcs, ray_cmd_rx, c_bufp);
fraglen = SRAM_READ_FIELD_2(sc, rcs, ray_cmd_rx, c_len);
- RAY_DPRINTF(("ray%d: ray_rx frag index %d len %d bufp 0x%x ni %d\n",
+ RAY_DPRINTFN(50, ("ray%d: ray_rx frag index %d len %d bufp 0x%x ni %d\n",
sc->unit, i, fraglen, (int)bufp, ni));
if (fraglen + readlen > pktlen) {
- RAY_DPRINTF(("ray%d: ray_rx bad length current 0x%x pktlen 0x%x\n",
+ RAY_DPRINTFN(1, ("ray%d: ray_rx bad length current 0x%x pktlen 0x%x\n",
sc->unit, fraglen + readlen, pktlen));
ifp->if_ierrors++;
- m_freem(m);
- m = 0;
+ m_freem(m0);
+ m0 = NULL;
goto skip_read;
}
if ((i < RAY_RCS_FIRST) || (i > RAY_RCS_LAST)) {
printf("ray%d: ray_rx bad rcs index 0x%x\n", sc->unit, i);
ifp->if_ierrors++;
- m_freem(m);
- m = 0;
+ m_freem(m0);
+ m0 = NULL;
goto skip_read;
}
@@ -1323,152 +1767,144 @@ skip_read:
* Walk the chain again to free the rcss.
*/
i = ni = first;
-RAY_DPRINTF(("ray%d: ray_rx cleaning rcs fragments ", sc->unit));
while ((i = ni) && (i != RAY_CCS_LINK_NULL)) {
-RAY_DPRINTF(("%d ", i));
rcs = RAY_CCS_ADDRESS(i);
ni = SRAM_READ_FIELD_1(sc, rcs, ray_cmd_rx, c_nextfrag);
SRAM_WRITE_FIELD_1(sc, rcs, ray_cmd, c_status, RAY_CCS_STATUS_FREE);
}
-RAY_DPRINTF(("\n"));
- if (!m)
+ if (m0 == NULL)
return;
- RAY_DPRINTF(("ray%d: ray_rx got packet pktlen %d actual %d\n",
- sc->unit, pktlen, readlen));
- RAY_DMBUF_DUMP(sc, m, "ray_rx");
+ RAY_DMBUF_DUMP(sc, m0, "ray_rx");
/*
- * Check the 802.11 packet type and obtain the .11 src address.
+ * Check the 802.11 packet type and obtain the .11 src addresses.
*
- * XXX CTL and MGT packets will have separate functions,
- * DATA dealt with here
+ * XXX CTL and MGT packets will have separate functions, DATA with here
+ *
+ * XXX This needs some work for INFRA mode
*/
- header = mtod(m, struct ieee80211_header *);
+ header = mtod(m0, struct ieee80211_header *);
fc = header->i_fc[0];
if ((fc & IEEE80211_FC0_VERSION_MASK) != IEEE80211_FC0_VERSION_0) {
- RAY_DPRINTF(("ray%d: header not version 0 fc 0x%x\n", sc->unit, fc));
- m_freem(m);
+ RAY_DPRINTFN(1, ("ray%d: header not version 0 fc 0x%x\n", sc->unit, fc));
+ ifp->if_ierrors++;
+ m_freem(m0);
return;
}
switch (fc & IEEE80211_FC0_TYPE_MASK) {
case IEEE80211_FC0_TYPE_MGT:
- printf("ray%d: ray_rx got a .11 MGT packet - why?\n", sc->unit);
- m_freem(m);
+ printf("ray%d: ray_rx got a MGT packet - why?\n", sc->unit);
+ ifp->if_ierrors++;
+ m_freem(m0);
return;
case IEEE80211_FC0_TYPE_CTL:
- printf("ray%d: ray_rx got a .11 CTL packet - why?\n", sc->unit);
- m_freem(m);
+ printf("ray%d: ray_rx got a CTL packet - why?\n", sc->unit);
+ ifp->if_ierrors++;
+ m_freem(m0);
return;
case IEEE80211_FC0_TYPE_DATA:
- RAY_DPRINTF(("ray%d: ray_rx got a .11 DATA packet\n", sc->unit));
+ RAY_DPRINTFN(50, ("ray%d: ray_rx got a DATA packet\n", sc->unit));
break;
default:
- printf("ray%d: ray_rx got a unknown .11 packet fc0 0x%x - why?\n",
+ printf("ray%d: ray_rx got a unknown packet fc0 0x%x - why?\n",
sc->unit, fc);
- m_freem(m);
+ ifp->if_ierrors++;
+ m_freem(m0);
return;
}
fc = header->i_fc[1];
- switch (fc & IEEE80211_FC1_RCVFROM_MASK) {
+ switch (fc & IEEE80211_FC1_DS_MASK) {
- case IEEE80211_FC1_RCVFROM_TERMINAL:
+ case IEEE80211_FC1_STA_TO_STA:
src = header->i_addr2;
- RAY_DPRINTF(("ray%d: ray_rx got packet from station %6D\n",
- sc->unit, src, ":"));
+ RAY_DPRINTFN(50, ("ray%d: ray_rx packet from sta %6D\n",
+ sc->unit, src, ":"));
break;
- case IEEE80211_FC1_RCVFROM_AP:
- src = header->i_addr3;
- RAY_DPRINTF(("ray%d: ray_rx got packet from ap %6D\n",
- sc->unit, src, ":"));
+ case IEEE80211_FC1_STA_TO_AP:
+ RAY_DPRINTFN(1, ("ray%d: ray_rx packet from sta %6D to ap %6D\n",
+ sc->unit,
+ header->i_addr2, ":", header->i_addr3, ":"));
+ ifp->if_ierrors++;
+ m_freem(m0);
break;
- case IEEE80211_FC1_RCVFROM_AP2AP:
- RAY_DPRINTF(("ray%d: ray_rx saw packet between aps %6D %6D %6D\n",
- sc->unit, header->i_addr1, ":", header->i_addr2, ":",
- header->i_addr3, ":"));
- m_freem(m);
+ case IEEE80211_FC1_AP_TO_STA:
+ RAY_DPRINTFN(1, ("ray%d: ray_rx packet from ap %6D\n",
+ sc->unit,
+ header->i_addr3, ":"));
+ ifp->if_ierrors++;
+ m_freem(m0);
+ break;
+
+ case IEEE80211_FC1_AP_TO_AP:
+ RAY_DPRINTFN(1, ("ray%d: ray_rx saw packet between aps %6D %6D\n",
+ sc->unit,
+ header->i_addr1, ":", header->i_addr2, ":"));
+ ifp->if_ierrors++;
+ m_freem(m0);
return;
default:
printf("ray%d: ray_rx packet type unknown fc1 0x%x - why?\n",
- sc->unit, fc);
- m_freem(m);
+ sc->unit, fc);
+ ifp->if_ierrors++;
+ m_freem(m0);
return;
}
/*
- * XXX
- *
- * Currently only support the Webgear encapsulation
- * 802.11 header <net/if_ieee80211.h>struct ieee80211_header
- * 802.3 header <net/ethernet.h>struct ether_header
- * 802.2 LLC header
- * 802.2 SNAP header
- *
- * We should support whatever packet types the following drivers have
- * if_wi.c FreeBSD, RFC1042
- * if_ray.c NetBSD Webgear, RFC1042
- * rayctl.c Linux Webgear, RFC1042
- * also whatever we can divine from the NDC Access points and
- * Kanda's boxes.
- *
- * Most appear to have a RFC1042 translation. The incoming packet is
- * 802.11 header <net/if_ieee80211.h>struct ieee80211_header
- * 802.2 LLC header
- * 802.2 SNAP header
- *
- * This is translated to
- * 802.3 header <net/ethernet.h>struct ether_header
- * 802.2 LLC header
- * 802.2 SNAP header
- *
- * Linux seems to look at the SNAP org_code and do some translations
- * for IPX and APPLEARP on that. This just may be how Linux does IPX
- * and NETATALK. Need to see how FreeBSD does these.
+ * Translation - capability as described earlier
*
- * Translation should be selected via if_media stuff or link types.
+ * Each case must remove the 802.11 header and leave an 802.3
+ * header in the mbuf copy addresses as needed.
*/
switch (sc->translation) {
case SC_TRANSLATE_WEBGEAR:
- /* XXX error checking ? how? */
- eh = (struct ether_header *)(header + 1);
- m_adj(m, sizeof(struct ieee80211_header)+sizeof(struct ether_header));
+ /* Nice and easy - just trim the 802.11 header */
+ m_adj(m0, sizeof(struct ieee80211_header));
break;
default:
printf("ray%d: ray_rx unknown translation type 0x%x - why?\n",
sc->unit, sc->translation);
- m_freem(m);
+ ifp->if_ierrors++;
+ m_freem(m0);
return;
}
+ /*
+ * Finally, do a bit of house keeping before sending the packet
+ * up the stack.
+ */
+ ifp->if_ipackets++;
#if NBPFILTER > 0
- /* Handle BPF listeners. */
if (ifp->if_bpf)
- bpf_mtap(ifp, m);
+ bpf_mtap(ifp, m0);
#endif /* NBPFILTER */
#if XXX
if_wi.c - might be needed if we hear our own broadcasts in promiscuous mode
+but will not be if we dont see them
if ((ifp->if_flags & IFF_PROMISC) &&
(bcmp(eh->ether_shost, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) &&
(eh->ether_dhost[0] & 1) == 0)
) {
- m_freem(m);
+ m_freem(m0);
return;
}
#endif /* XXX */
-
- ether_input(ifp, eh, m);
+ eh = mtod(m0, struct ether_header *);
+ m_adj(m0, sizeof(struct ether_header));
+ ether_input(ifp, eh, m0);
return;
}
@@ -1485,14 +1921,12 @@ ray_download_params (sc)
struct ray_mib_4 ray_mib_4_default;
struct ray_mib_5 ray_mib_5_default;
- RAY_DPRINTF(("ray%d: Downloading startup parameters\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: Downloading startup parameters\n", sc->unit));
RAY_MAP_CM(sc);
- RAY_DNET_DUMP(sc, " before we download them.");
-#if XXX
-netbsd
+#if XXX_TRACKING
ray_cmd_cancel(sc, SCP_UPD_STARTUP);
-#endif /* XXX */
+#endif /* XXX_TRACKING */
#define MIB4(m) ray_mib_4_default.##m
#define MIB5(m) ray_mib_5_default.##m
@@ -1595,6 +2029,8 @@ PUT2(MIB5(mib_cw_min), RAY_MIB_CW_MIN_V5);
MIB5(mib_privacy_can_join) = sc->sc_priv_start;
MIB5(mib_basic_rate_set[0]) = sc->sc_priv_join;
+ /* XXX I don't really want to panic here but we must ensure that the
+ * XXX card is idle - maybe stop it and reset it? */
if (!RAY_ECF_READY(sc))
panic("ray%d: ray_download_params something is already happening\n",
sc->unit);
@@ -1606,20 +2042,6 @@ PUT2(MIB5(mib_cw_min), RAY_MIB_CW_MIN_V5);
ray_write_region(sc, RAY_HOST_TO_ECF_BASE,
&ray_mib_5_default, sizeof(ray_mib_5_default));
-/* XXX
- * NetBSD
- * hand expanding ray_simple_cmd
- * we dont do any of the clever timeout stuff yet (i.e. ray_cmd_ran) just
- * simple check
- *
- * if (!ray_simple_cmd(sc, RAY_CMD_START_PARAMS, SCP_UPD_STARTUP))
- * panic("ray_download_params issue");
- *
- * ray_simple_cmd ==
- * ray_alloc_ccs(sc, &ccs, cmd, track) &&
- * ray_issue_cmd(sc, ccs, track));
- *
- */
/*
* Get a free command ccs and issue the command - there is nothing
* to fill in for a START_PARAMS command. The start parameters
@@ -1634,7 +2056,7 @@ PUT2(MIB5(mib_cw_min), RAY_MIB_CW_MIN_V5);
sc->timerh = timeout(ray_download_timo, sc, RAY_CCS_TIMEOUT);
- RAY_DPRINTF(("ray%d: Download now awaiting timeout\n", sc->unit));
+ RAY_DPRINTFN(15, ("ray%d: Download now awaiting timeout\n", sc->unit));
return;
}
@@ -1652,36 +2074,32 @@ ray_download_timo (xsc)
size_t ccs;
u_int8_t status, cmd;
- RAY_DPRINTF(("ray%d: ray_download_timo\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: ray_download_timo\n", sc->unit));
RAY_MAP_CM(sc);
status = SRAM_READ_FIELD_1(sc, sc->sc_ccs, ray_cmd, c_status);
cmd = SRAM_READ_FIELD_1(sc, sc->sc_ccs, ray_cmd, c_cmd);
- RAY_DPRINTF(("ray%d: check rayidx %d ccs 0x%x cmd 0x%x stat %d\n",
+ RAY_DPRINTFN(20, ("ray%d: check rayidx %d ccs 0x%x cmd 0x%x status %d\n",
sc->unit, RAY_CCS_INDEX(sc->sc_ccs), sc->sc_ccs, cmd, status));
if ((cmd != RAY_CMD_START_PARAMS) || (status != RAY_CCS_STATUS_FREE))
printf("ray%d: Download ccs odd cmd = 0x%02x, status = 0x%02x",
sc->unit, cmd, status);
/*XXX so what do we do? reset or retry? */
- /*XXX this gets triggered when we try and re-reset the ipaddress
- * ray_init gets called */
/*
* If the card is still busy, re-schedule ourself
*/
if (status == RAY_CCS_STATUS_BUSY) {
- RAY_DPRINTF(("ray%d: ray_download_timo - still busy, see you soon\n",
+ RAY_DPRINTFN(1, ("ray%d: ray_download_timo still busy, re-schedule\n",
sc->unit));
sc->timerh = timeout(ray_download_timo, sc, RAY_CCS_TIMEOUT);
+ return;
}
/* Clear the ccs */
- ray_free_ccs(sc, sc->sc_ccs);
+ (void)ray_free_ccs(sc, sc->sc_ccs);
sc->sc_ccs = RAY_CCS_LAST + 1;
-#if XXX
-NetBSD clear IFF_OACTIVE at this point
-#endif
/*
* Grab a ccs and don't bother updating the network parameters.
* Issue the start/join command and we get interrupted back.
@@ -1704,7 +2122,8 @@ NetBSD clear IFF_OACTIVE at this point
sc->sj_timerh = timeout(ray_start_join_timo, sc, RAY_CCS_TIMEOUT);
#endif /* RAY_NEED_STARTJOIN_TIMO */
- RAY_DPRINTF(("ray%d: Start-join awaiting interrupt/timeout\n", sc->unit));
+ RAY_DPRINTFN(15, ("ray%d: Start-join awaiting interrupt/timeout\n",
+ sc->unit));
return;
}
@@ -1720,11 +2139,14 @@ ray_start_join_done (sc, ccs, status)
size_t ccs;
u_int8_t status;
{
+ struct ifnet *ifp;
u_int8_t o_net_type;
- RAY_DPRINTF(("ray%d: ray_start_join_done\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: ray_start_join_done\n", sc->unit));
RAY_MAP_CM(sc);
+ ifp = &sc->arpcom.ac_if;
+
#if RAY_NEED_STARTJOIN_TIMO
untimeout(ray_start_join_timo, sc, sc->sj_timerh);
#endif /* RAY_NEED_STARTJOIN_TIMO */
@@ -1749,7 +2171,8 @@ ray_start_join_done (sc, ccs, status)
sc->unit);
sc->sc_havenet = 0;
#if XXX
- restart ray_start_join sequence
+ if we fired the start command we successfully set the card up
+ so just restart ray_start_join sequence and dont reset the card
may need to split download_done for this
#endif
break;
@@ -1777,7 +2200,7 @@ ray_start_join_done (sc, ccs, status)
/* card is telling us to update the network parameters */
if (sc->sc_upd_param) {
- RAY_DPRINTF(("ray%d: sj_done card updating parameters - why?\n",
+ RAY_DPRINTFN(1, ("ray%d: sj_done card updating parameters - why?\n",
sc->unit));
o_net_type = sc->sc_net_type;
ray_read_region(sc, RAY_HOST_TO_ECF_BASE,
@@ -1786,34 +2209,32 @@ ray_start_join_done (sc, ccs, status)
printf("ray%d: sj_done card changing network type - why?\n",
sc->unit);
#if XXX
-restart ray_start_join sequence ?
-may need to split download_timo for this
-panic?
+ restart ray_start_join sequence
+ may need to split download_timo for this
#endif
}
}
RAY_DNET_DUMP(sc, " after start/join network completed.");
/*
- * Hurrah! The network is now active
+ * Hurrah! The network is now active.
+ *
+ * Clearing IFF_OACTIVE will ensure that the system will queue packets.
+ * Just before we return from the interrupt context we check to
+ * see if packets have been queued.
*/
#if XXX_MCASTPROM
ray_cmd_schedule(sc, SCP_UPD_MCAST|SCP_UPD_PROMISC);
#endif /* XXX_MCASTPROM */
if (SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd) == RAY_CMD_JOIN_NET)
-#if XXX
+#if XXX_INFRA
ray_start_assoc(sc);
#else
- RAY_DPRINTF(("wanted to join a NET!\n"));
-#endif /* XXX */
+ RAY_DPRINTFN(1, ("wanted to join a NET!\n"));
+#endif /* XXX_INFRA */
else {
- sc->sc_havenet = 1; /* XXX need to check havenet setting/clearing */
-#if XXX
- ray_start needs OACTIVE clear and more than splimp
- NetBSD has already cleared OACTIVE
- need to know interrupt level we enter ray_pccard_intr at
- ray_start(&sc->arpcom.ac_if);
-#endif /* XXX */
+ sc->sc_havenet = 1;
+ ifp->if_flags &= ~IFF_OACTIVE;
}
return;
@@ -1832,7 +2253,7 @@ ray_start_join_timo (xsc)
{
struct ray_softc *sc = xsc;
- RAY_DPRINTF(("ray%d: ray_start_join_timo\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: ray_start_join_timo\n", sc->unit));
RAY_MAP_CM(sc);
panic("ray%d: ray-start_join_timo occured\n", sc->unit);
@@ -1862,16 +2283,16 @@ ray_alloc_ccs (sc, ccsp, cmd, track)
size_t ccs;
u_int i;
- RAY_DPRINTF(("ray%d: ray_alloc_ccs for cmd %d\n", sc->unit, cmd));
+ RAY_DPRINTFN(5, ("ray%d: ray_alloc_ccs\n", sc->unit));
RAY_MAP_CM(sc);
-#if XXX
+#if XXX_TRACKING
/* for tracked commands, if not ready just set pending */
if (track && !RAY_ECF_READY(sc)) {
ray_cmd_schedule(sc, track);
- return (0);
+ return(0);
}
-#endif /* XXX */
+#endif /* XXX_TRACKING */
for (i = RAY_CCS_CMD_FIRST; i <= RAY_CCS_CMD_LAST; i++) {
/* probe here to make the card go */
@@ -1880,11 +2301,11 @@ ray_alloc_ccs (sc, ccsp, cmd, track)
break;
}
if (i > RAY_CCS_CMD_LAST) {
-#if XXX
+#if XXX_TRACKING
if (track)
ray_cmd_schedule(sc, track);
-#endif /* XXX */
- return (0);
+#endif /* XXX_TRACKING */
+ return(0);
}
sc->sc_ccsinuse[i] = 1;
ccs = RAY_CCS_ADDRESS(i);
@@ -1893,7 +2314,7 @@ ray_alloc_ccs (sc, ccsp, cmd, track)
SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_link, RAY_CCS_LINK_NULL);
*ccsp = ccs;
- return (1);
+ return(1);
}
/*
@@ -1905,17 +2326,19 @@ ray_free_ccs (sc, ccs)
struct ray_softc *sc;
size_t ccs;
{
- u_int8_t stat;
+ u_int8_t status;
- RAY_DPRINTF(("ray%d: free_ccs 0x%02x\n", sc->unit, RAY_CCS_INDEX(ccs)));
+ RAY_DPRINTFN(5, ("ray%d: ray_free_ccs\n", sc->unit));
RAY_MAP_CM(sc);
- stat = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
- SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd, c_status, RAY_CCS_STATUS_FREE);
+ status = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status);
+ RAY_CCS_FREE(sc, ccs);
if (ccs <= RAY_CCS_ADDRESS(RAY_CCS_LAST))
sc->sc_ccsinuse[RAY_CCS_INDEX(ccs)] = 0;
+ RAY_DPRINTFN(20, ("ray%d: ray_free_ccs freed 0x%02x\n",
+ sc->unit, RAY_CCS_INDEX(ccs)));
- return (stat);
+ return(status);
}
/*
@@ -1930,7 +2353,7 @@ ray_issue_cmd(sc, ccs, track)
{
u_int i;
- RAY_DPRINTF(("ray%d: ray_cmd_issue, track = 0x%x\n", sc->unit, track));
+ RAY_DPRINTFN(5, ("ray%d: ray_cmd_issue\n", sc->unit));
RAY_MAP_CM(sc);
/*
@@ -1941,13 +2364,17 @@ ray_issue_cmd(sc, ccs, track)
i = 0;
while (!RAY_ECF_READY(sc))
if (++i > 50) {
- ray_free_ccs(sc, ccs);
+ printf("\n");
+ (void)ray_free_ccs(sc, ccs);
#if XXX_TRACKING
if (track)
ray_cmd_schedule(sc, track);
#endif /* XXX_TRACKING */
- return (0);
- }
+ return(0);
+ } else if (i == 1)
+ printf("ray%d: ray_issue_cmd spinning", sc->unit);
+ else
+ printf(".");
SRAM_WRITE_1(sc, RAY_SCB_CCSI, RAY_CCS_INDEX(ccs));
RAY_ECF_START_CMD(sc);
@@ -1955,10 +2382,10 @@ ray_issue_cmd(sc, ccs, track)
ray_cmd_ran(sc, track);
#endif /* XXX_TRACKING */
- return (1);
+ return(1);
}
-#if RAY_DEBUG > 10
+#if RAY_DEBUG > 50
static void
ray_dump_mbuf(sc, m, s)
struct ray_softc *sc;
@@ -1988,7 +2415,7 @@ ray_dump_mbuf(sc, m, s)
if ((i - 1) % 16)
printf("%s\n", p);
}
-#endif /* RAY_DEBUG > 10 */
+#endif /* RAY_DEBUG > 50 */
/*
* Routines to read from/write to the attribute memory.
@@ -2011,15 +2438,17 @@ ray_dump_mbuf(sc, m, s)
* successive calls
*
*/
-#if RAY_NEED_CM_REMAPPING
+#if (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP)
static void
ray_attr_getmap (struct ray_softc *sc)
{
- struct ucred uc;
- struct pcred pc;
- struct proc p;
+ struct ucred uc;
+ struct pcred pc;
+ struct proc p;
+ int result;
- RAY_DPRINTF(("ray%d: attempting to get map for common memory\n", sc->unit));
+ RAY_DPRINTFN(5, ("ray%d: attempting to get map for common memory\n",
+ sc->unit));
sc->md.window = 0;
@@ -2027,9 +2456,7 @@ ray_attr_getmap (struct ray_softc *sc)
p.p_cred->pc_ucred = &uc;
p.p_cred->pc_ucred->cr_uid = 0;
- RAY_DPRINTF((" ioctl returns 0x%0x\n", cdevsw[CARD_MAJOR]->d_ioctl(makedev(CARD_MAJOR, sc->slotnum), PIOCGMEM, (caddr_t)&sc->md, 0, &p)));
-
- RAY_DPRINTF((" flags 0x%02x, start 0x%p, size 0x%08x, card address 0x%lx\n", sc->md.flags, sc->md.start, sc->md.size, sc->md.card));
+ result = cdevsw[CARD_MAJOR]->d_ioctl(makedev(CARD_MAJOR, sc->slotnum), PIOCGMEM, (caddr_t)&sc->md, 0, &p);
return;
}
@@ -2041,7 +2468,7 @@ ray_attr_cm (struct ray_softc *sc)
struct pcred pc;
struct proc p;
- RAY_DPRINTF(("ray%d: attempting to remap common memory\n", sc->unit));
+ RAY_DPRINTFN(100, ("ray%d: attempting to remap common memory\n", sc->unit));
p.p_cred = &pc;
p.p_cred->pc_ucred = &uc;
@@ -2051,7 +2478,7 @@ ray_attr_cm (struct ray_softc *sc)
return;
}
-#endif /* RAY_NEED_CM_REMAPPING */
+#endif /* (RAY_NEED_CM_REMAPPING | RAY_NEED_CM_FIXUP) */
static int
ray_attr_write (struct ray_softc *sc, off_t offset, u_int8_t byte)
@@ -2119,36 +2546,4 @@ ray_read_reg (sc, reg)
return(byte);
}
-#if XXX
-/*
- * Could be replaced by the following macro
- * RAY_ECF_READY(sc) (!(REG_READ(sc, RAY_ECFIR) & RAY_ECFIR_IRQ))
- * where reg_read is a suitable macro to read a byte in the attribute memory.
- */
-static int
-ray_ecf_ready(struct ray_softc *sc)
-{
- u_int8_t byte;
-
- ray_attr_read(sc, RAY_ECFIR, &byte, 1);
-
- return (!(byte & RAY_ECFIR_IRQ));
-}
-
-/*
- * Could be replaced by the following macro
- * RAY_HCS_INTR(sc) (REG_READ(sc, RAY_HCSIR) & RAY_HCSIR_IRQ)
- * where reg_read is a suitable macro to read a byte in the attribute memory.
- */
-static int
-ray_hcs_intr(struct ray_softc *sc)
-{
- u_int8_t byte;
-
- ray_attr_read(sc, RAY_HCSIR, &byte, 1);
-
- return (byte & RAY_HCSIR_IRQ);
-}
-#endif
-
#endif /* NRAY */
OpenPOWER on IntegriCloud