./service/fxp minix-sys
./service/hgfs minix-sys
./service/lance minix-sys
-./service/orinoco minix-sys
+./service/orinoco minix-sys obsolete
./service/pci minix-sys
./service/pckbd minix-sys
./service/printer minix-sys
;
};
-service orinoco
-{
- system
- PRIVCTL # 4
- UMAP # 14
- IRQCTL # 19
- DEVIO # 21
- VM_MAP # 30
- ;
- pci device 1260:3873;
- pci device 1186:1300;
- uid 0;
-};
-
service es1370
{
system
SUBDIR+= e1000
SUBDIR+= fxp
SUBDIR+= lance
-SUBDIR+= orinoco
SUBDIR+= rtl8139
SUBDIR+= rtl8169
SUBDIR+= virtio_net
+++ /dev/null
-The driver has been tested on Minix 3.1.3, svn revision 2928:
- http://derelict.cs.vu.nl/images/minix3_1_3_ide_r2928.iso.bz2
-
-
-To install the driver do:
-#sh install_script
-
-This script will patch, compile and install 2 code files in Minix:
- /usr/src/services/rs/service.c
- /usr/src/commands/dhcpd/devices.c
- (see the docs directory for more information)
-Furthermore, the script will patch 1 configuration file:
- /etc/system.conf
- (adding an entry for 'orinoco')
-and 1 script file:
- /usr/etc/rc
- (adding an entry in a for-loop to start orinoco)
-Finally, the script will copy the orinoco driver into the drivers directory,
-compile and install it.
-
-When the script completes successfully, the inet.conf file has to be adjusted
-so that Minix will use the orinoco driver. Add an entry like:
-
- eth0 orinoco 0 {default;};
-
-The last step is to set the essid and WEP key of the network in the boot
-monitor. When in the boot monitor, type:
- essid=<essid>
- wep=<WEP key>
- save
-
-The essid is the name of the wireless network
-The WEP key is a string of 13 ASCII characters, being the key of the wireless
-network. This variable shouldn't be set when the network is not WEP protected.
-If the essid is not set, the card will just try connect a network quite at random
-
-N.B.: WPA is not supported
-N.B.: WEP seems to be buggy. At my place it works, at the VU it doesnt. So if
-things don't work, try without WEP
-
+++ /dev/null
-# Makefile for the Orinoco wireless card (Prism chipset)
-PROG= orinoco
-SRCS= orinoco.c hermes.c
-
-DPADD+= ${LIBNETDRIVER} ${LIBSYS}
-LDADD+= -lnetdriver -lsys
-
-CPPFLAGS.orinoco.c+= -I${NETBSDSRCDIR}/minix
-
-.include <minix.service.mk>
+++ /dev/null
-/*
- * hermes.c
- *
- * This file contains the lower level access functions for Prism based
- * wireless cards. The file is based on hermes.c of the Linux kernel
- *
- * Adjusted to Minix by Stevens Le Blond <slblond@few.vu.nl>
- * and Michael Valkering <mjvalker@cs.vu.nl>
- */
-
-/* Original copyright notices from Linux hermes.c
- *
- * Copyright (C) 2000, David Gibson, Linuxcare Australia
- * <hermes@gibson.dropbear.id.au>
- * Copyright (C) 2001, David Gibson, IBM <hermes@gibson.dropbear.id.au>
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
-
-#include "hermes.h"
-
-/*****************************************************************************
- * milli_delay *
- * *
- * Wait msecs milli seconds *
- *****************************************************************************/
-static void milli_delay(unsigned int msecs)
-{
- micro_delay((long)msecs * 1000);
-}
-
-
-/*****************************************************************************
- * hermes_issue_cmd *
- * *
- * Issue a command to the chip. Waiting for it to complete is the caller's *
- * problem. The only thing we have to do first is to see whether we can *
- * actually write something in the CMD register: is it unbusy? *
- * Returns -EBUSY if the command register is busy, 0 on success. *
- *****************************************************************************/
-static int hermes_issue_cmd (hermes_t * hw, u16_t cmd, u16_t param0) {
- int k = HERMES_CMD_BUSY_TIMEOUT;
- u16_t reg;
-
- /* First wait for the command register to unbusy */
- reg = hermes_read_reg (hw, HERMES_CMD);
- while ((reg & HERMES_CMD_BUSY) && k) {
- k--;
- micro_delay (1);
- reg = hermes_read_reg (hw, HERMES_CMD);
- }
- /* it takes too long. Bailing out */
- if (reg & HERMES_CMD_BUSY) {
- printf("Hermes: HERMES_CMD_BUSY timeout\n");
- return -EBUSY;
- }
-
- /* write the values to the right registers */
- hermes_write_reg (hw, HERMES_PARAM2, 0);
- hermes_write_reg (hw, HERMES_PARAM1, 0);
- hermes_write_reg (hw, HERMES_PARAM0, param0);
- hermes_write_reg (hw, HERMES_CMD, cmd);
- return 0;
-}
-
-/*****************************************************************************
- * hermes_struct_init *
- * *
- * Initialize the hermes structure fields *
- *****************************************************************************/
-void hermes_struct_init (hermes_t * hw, u32_t address,
- int io_space, int reg_spacing) {
- hw->iobase = address;
- hw->io_space = io_space;
- hw->reg_spacing = reg_spacing;
- hw->inten = 0x0;
-}
-
-
-/*****************************************************************************
- * hermes_cor_reset *
- * *
- * This is the first step in initializing the card's firmware and hardware: *
- * write HERMES_PCI_COR_MASK to the Configuration Option Register *
- *****************************************************************************/
-int hermes_cor_reset (hermes_t *hw) {
- int k;
- u16_t reg;
-
- /* Assert the reset until the card notice */
- hermes_write_reg (hw, HERMES_PCI_COR, HERMES_PCI_COR_MASK);
-
- milli_delay (HERMES_PCI_COR_ONT);
-
- /* Give time for the card to recover from this hard effort */
- hermes_write_reg (hw, HERMES_PCI_COR, 0x0000);
-
- milli_delay (HERMES_PCI_COR_OFFT);
-
- /* The card is ready when it's no longer busy */
- k = HERMES_PCI_COR_BUSYT;
- reg = hermes_read_reg (hw, HERMES_CMD);
- while (k && (reg & HERMES_CMD_BUSY)) {
- k--;
- milli_delay (1);
- reg = hermes_read_reg (hw, HERMES_CMD);
- }
-
- /* Did we timeout ? */
- if (reg & HERMES_CMD_BUSY) {
- printf ("Busy timeout after resetting the COR\n");
- return -1;
- }
-
- return (0);
-}
-
-
-/*****************************************************************************
- * hermes_present *
- * *
- * Check whether we have access to the card. Does the SWSUPPORT0 contain the *
- * value we put in it earlier? *
- *****************************************************************************/
-static int hermes_present (hermes_t * hw) {
- int i = hermes_read_reg (hw, HERMES_SWSUPPORT0) == HERMES_MAGIC;
- if (!i)
- printf("Hermes: Error, card not present?\n");
- return i;
-}
-
-
-/*****************************************************************************
- * hermes_init *
- * *
- * Initialize the card *
- *****************************************************************************/
-int hermes_init (hermes_t * hw)
-{
- u32_t status, reg, resp0;
- int err = 0;
- int k;
-
- /* We don't want to be interrupted while resetting the chipset. By
- * setting the control mask for hardware interrupt generation to 0,
- * we won't be disturbed*/
- hw->inten = 0x0;
- hermes_write_reg (hw, HERMES_INTEN, 0);
-
- /* Acknowledge any pending events waiting for acknowledgement. We
- * assume there won't be any important to take care off */
- hermes_write_reg (hw, HERMES_EVACK, 0xffff);
-
- /* Normally it's a "can't happen" for the command register to
- * be busy when we go to issue a command because we are
- * serializing all commands. However we want to have some
- * chance of resetting the card even if it gets into a stupid
- * state, so we actually wait to see if the command register
- * will unbusy itself here. */
- k = HERMES_CMD_BUSY_TIMEOUT;
- reg = hermes_read_reg (hw, HERMES_CMD);
- while (k && (reg & HERMES_CMD_BUSY)) {
- if (reg == 0xffff) {
- /* Special case - the card has probably
- * been removed, so don't wait for the
- * timeout */
- printf("Hermes: Card removed?\n");
- return -ENODEV;
- }
-
- k--;
- micro_delay (1);
- reg = hermes_read_reg (hw, HERMES_CMD);
- }
-
- /* No need to explicitly handle the timeout - if we've timed
- * out hermes_issue_cmd() will probably return -EBUSY below.
- * But i check to be sure :-) */
- if (reg & HERMES_CMD_BUSY) {
- printf("Hermes: Timeout waiting for the CMD_BUSY to unset\n");
- return -EBUSY;
- }
-
- /* According to the documentation, EVSTAT may contain
- * obsolete event occurrence information. We have to acknowledge
- * it by writing EVACK. */
- reg = hermes_read_reg (hw, HERMES_EVSTAT);
- hermes_write_reg (hw, HERMES_EVACK, reg);
-
- err = hermes_issue_cmd (hw, HERMES_CMD_INIT, 0);
- if (err){
- printf("Hermes: errornr: 0x%x issueing HERMES_CMD_INIT\n",
- err);
- return err;
- }
-
- /* here we start waiting for the above command,CMD_INIT, to complete.
- * Completion is noticeable when the HERMES_EV_CMD bit in the
- * HERMES_EVSTAT register is set to 1 */
- reg = hermes_read_reg (hw, HERMES_EVSTAT);
- k = HERMES_CMD_INIT_TIMEOUT;
- while ((!(reg & HERMES_EV_CMD)) && k) {
- k--;
- micro_delay (10);
- reg = hermes_read_reg (hw, HERMES_EVSTAT);
- }
-
-
- /* the software support register 0 (there are 3) is filled with a
- * magic number. With this one can test the availability of the card */
- hermes_write_reg (hw, HERMES_SWSUPPORT0, HERMES_MAGIC);
-
- if (!hermes_present (hw)) {
- printf("Hermes: Card not present?: got mag. nr.0x%x\n",
- hermes_read_reg (hw, HERMES_SWSUPPORT0));
- }
-
- if (!(reg & HERMES_EV_CMD)) {
- printf("hermes @ %x: Timeout waiting for card to reset\n",
- hw->iobase);
- return -ETIMEDOUT;
- }
-
- status = hermes_read_reg (hw, HERMES_STATUS);
- resp0 = hermes_read_reg (hw, HERMES_RESP0);
-
- /* after having issued the command above, the completion set a bit in
- * the EVSTAT register. This has to be acknowledged, as follows */
- hermes_write_reg (hw, HERMES_EVACK, HERMES_EV_CMD);
-
- /* Was the status, the result of the issued command, ok? */
- /* The expression below should be zero. Non-zero means an error */
- if (status & HERMES_STATUS_RESULT) {
- printf("Hermes:Result of INIT_CMD wrong.error value: 0x%x\n",
- (status & HERMES_STATUS_RESULT) >> 8);
- err = -EIO;
- }
-
- return err;
-}
-
-/*****************************************************************************
- * hermes_docmd_wait *
- * *
- * Issue a command to the chip, and (busy) wait for it to complete. *
- *****************************************************************************/
-int hermes_docmd_wait (hermes_t * hw, u16_t cmd, u16_t parm0,
- hermes_response_t * resp) {
- int err;
- int k;
- u16_t reg;
- u16_t status;
-
- err = hermes_issue_cmd (hw, cmd, parm0);
- if (err) {
- printf("hermes @ %x: Error %d issuing command.\n",
- hw->iobase, err);
- return err;
- }
-
- /* Reads the Event status register. When the command has completed,
- * the fourth bit in the HERMES_EVSTAT register is a 1. We will be
- * waiting for that to happen */
- reg = hermes_read_reg (hw, HERMES_EVSTAT);
- k = HERMES_CMD_COMPL_TIMEOUT;
- while ((!(reg & HERMES_EV_CMD)) && k) {
- k--;
- micro_delay (10);
- reg = hermes_read_reg (hw, HERMES_EVSTAT);
- }
-
- /* check for a timeout: has the command still not completed? */
- if (!(reg & HERMES_EV_CMD)) {
- printf("hermes @ %x: Timeout waiting for command \
- completion.\n", hw->iobase);
- err = -ETIMEDOUT;
- return err;
- }
-
- status = hermes_read_reg (hw, HERMES_STATUS);
- /* some commands result in results residing in response registers.
- * They have to be read before the acknowledgement below.
- */
- if (resp) {
- resp->status = status;
- resp->resp0 = hermes_read_reg (hw, HERMES_RESP0);
- resp->resp1 = hermes_read_reg (hw, HERMES_RESP1);
- resp->resp2 = hermes_read_reg (hw, HERMES_RESP2);
- }
-
- /* After issueing a Command, the card expects an Acknowledgement */
- hermes_write_reg (hw, HERMES_EVACK, HERMES_EV_CMD);
-
- /* check whether there has been a valid value in the Status register.
- * the high order bits should have at least some value */
- if (status & HERMES_STATUS_RESULT) {
- printf("Hermes: EIO\n");
- err = -EIO;
- }
-
- return err;
-}
-
-
-/*****************************************************************************
- * hermes_allocate *
- * *
- * Allocate bufferspace in the card, which will be then available for *
- * writing by the host, TX buffers. The card will try to find enough memory *
- * (creating a list of 128 byte blocks) and will return a pointer to the *
- * first block. This pointer is a pointer to the frame identifier (fid), *
- * holding information and data of the buffer. The fid is like a file *
- * descriptor, a value indicating some resource *
- *****************************************************************************/
-int hermes_allocate (hermes_t * hw, u16_t size, u16_t * fid) {
- int err = 0;
- int k;
- u16_t reg;
-
- if ((size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX)) {
- printf("Hermes: Invalid size\n");
- return -EINVAL;
- }
-
- /* Issue a allocation request to the card, waiting for the command
- * to complete */
- err = hermes_docmd_wait (hw, HERMES_CMD_ALLOC, size, NULL);
- if (err) {
- printf( "Hermes: docmd_wait timeout\n");
- return err;
- }
-
- /* Read the status event register to know whether the allocation
- * succeeded. The HERMES_EV_ALLOC bit should be set */
- reg = hermes_read_reg (hw, HERMES_EVSTAT);
- k = HERMES_ALLOC_COMPL_TIMEOUT;
- while ((!(reg & HERMES_EV_ALLOC)) && k) {
- k--;
- micro_delay (10);
- reg = hermes_read_reg (hw, HERMES_EVSTAT);
- }
-
- /* tired of waiting to complete. Abort. */
- if (!(reg & HERMES_EV_ALLOC)) {
- printf("hermes @ %x:Timeout waiting for frame allocation\n",
- hw->iobase);
- return -ETIMEDOUT;
- }
-
- /* When we come here, everything has gone well. The pointer to the
- * fid is in the ALLOCFID register. This fid is later on used
- * to access this buffer */
- *fid = hermes_read_reg (hw, HERMES_ALLOCFID);
-
- /* always acknowledge the receipt of an event */
- hermes_write_reg (hw, HERMES_EVACK, HERMES_EV_ALLOC);
-
- return 0;
-}
-
-
-
-/*****************************************************************************
- * hermes_bap_seek *
- * *
- * Set up a Buffer Access Path (BAP) to read a particular chunk of data *
- * from card's internal buffer. Setting a bap register is like doing a fseek *
- * system call: setting an internal pointer to the right place in a buffer *
- *****************************************************************************/
-static int hermes_bap_seek (hermes_t * hw, int bap, u16_t id, u16_t offset) {
-
- /* There are 2 BAPs. This can be used to use the access buffers
- * concurrently: 1 for writing in the TX buffer and 1 for reading
- * a RX buffer in case of an RX interrupt.
- * The BAP consists of 2 registers, together with which one can
- * point to a single byte in the required buffer (additionally
- * there is a third register, but that one is not used in this
- * function, the data register). With the SELECT register one chooses
- * the fid, with the OFFSET register one chooses the offset in the fid
- * buffer */
- int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
- int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
- int k;
- u16_t reg;
-
- /* Check whether the offset is not too large, and whether it is a
- * number of words. Offset can't be odd */
- if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2)) {
- printf("Hermes: Offset error\n");
- return -EINVAL;
- }
-
- /* We can't write to the offset register when the busy flag is set. If
- * it is set, wait to automatically reset*/
- k = HERMES_BAP_BUSY_TIMEOUT;
- reg = hermes_read_reg (hw, oreg);
- while ((reg & HERMES_OFFSET_BUSY) && k) {
- k--;
- micro_delay (1);
- reg = hermes_read_reg (hw, oreg);
- }
-
- /* For some reason, the busy flag didn't reset automatically. Return */
- if (reg & HERMES_OFFSET_BUSY) {
- printf("Hermes: HERMES_OFFSET_BUSY still set, oreg: 0x%x\n",
- reg);
- return -ETIMEDOUT;
- }
-
- /* Now we actually set up the transfer. Write the fid in the select
- * register, and the offset in the offset register */
- hermes_write_reg (hw, sreg, id);
- hermes_write_reg (hw, oreg, offset);
-
- /* Wait for the BAP to be ready. This means that at first the
- * OFFSET_BUSY bit is set by the card once we have written the values
- * above. We wait until the card has done its internal processing and
- * unset the OFFSET_BUSY bit */
- k = HERMES_BAP_BUSY_TIMEOUT;
- reg = hermes_read_reg (hw, oreg);
- while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
- k--;
- micro_delay (1);
- reg = hermes_read_reg (hw, oreg);
- }
-
- /* Busy bit didn't reset automatically */
- if (reg & HERMES_OFFSET_BUSY) {
- printf("Hermes: Error with fid 0x%x. Err: 0x%x\n", id, reg);
- return -ETIMEDOUT;
- }
-
- /* There has gone something wrong: offset is outside the buffer
- * boundary or the fid is not correct */
- if (reg & HERMES_OFFSET_ERR) {
- printf("Hermes: Error with fid 0x%x. Err: 0x%x\n", id, reg);
- return -EIO;
- }
-
- /* If we arrive here, the buffer can be accessed through the data
- * register associated with the BAP */
- return 0;
-}
-
-
-/*****************************************************************************
- * hermes_bap_pread *
- * *
- * Read a block of data from the chip's buffer, via the BAP. len must be *
- * even. *
- *****************************************************************************/
-int hermes_bap_pread (hermes_t * hw, int bap, void *buf, unsigned len,
- u16_t id, u16_t offset) {
- /* The data register is the access point for the buffer made
- * available by setting the BAP right. Which BAP does the user
- * want to use? there are 2 of them */
- int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
- int err = 0;
-
- /* reading (and writing) data goes a word a time, so should be even */
- if ((len % 2)) {
- printf("Hermes: Error in length to be read\n");
- return -EINVAL;
- }
-
- /* Set the cards internal pointer to the right fid and to the right
- * offset */
- err = hermes_bap_seek (hw, bap, id, offset);
- if (err) {
- printf("Hermes: error hermes_bap_seek in hermes_bap_pread\n");
- return err;
- }
- /* Actually do the transfer. The length is divided by 2 because
- * transfers go a word at a time as far as the card is concerned */
- hermes_read_words (hw, dreg, buf, len / 2);
-
- return err;
-}
-
-/*****************************************************************************
- * hermes_write_words *
- * *
- * Write a sequence of words of the buffer to the card *
- *****************************************************************************/
-void hermes_write_words (hermes_t * hw, int off, const void *buf,
- unsigned count) {
- int i = 0;
-
- for (i = 0; i < count; i++) {
- hermes_write_reg (hw, off, *((u16_t *) buf + i));
- }
-}
-
-/*****************************************************************************
- * hermes_bap_pwrite *
- * *
- * Write a block of data to the chip's buffer, via the BAP. len must be even.*
- *****************************************************************************/
-int hermes_bap_pwrite (hermes_t * hw, int bap, const void *buf, unsigned len,
- u16_t id, u16_t offset) {
-
- /* This procedure is quite the same as the hermes_bap_read */
- int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
- int err = 0;
-
- if ((len % 2)) {
- printf("Hermes: Error in length to be written\n");
- return -EINVAL;
- }
-
- /* Set the cards internal pointer to the right fid and to the right
- * offset */
- err = hermes_bap_seek (hw, bap, id, offset);
- if (err) {
- printf("Hermes: hermes_bap_seek error in hermes_bap_pwrite\n");
- return err;
-
- }
-
- /* Actually do the transfer */
- hermes_write_words (hw, dreg, buf, len / 2);
-
- return err;
-}
-
-
-
-/*****************************************************************************
- * hermes_set_irqmask *
- * *
- * Which events should the card respond to with an interrupt? *
- *****************************************************************************/
-int hermes_set_irqmask (hermes_t * hw, u16_t events) {
- hw->inten = events;
- hermes_write_reg (hw, HERMES_INTEN, events);
-
- /* Compare written value with read value to check whether things
- * succeeded */
- if (hermes_read_reg (hw, HERMES_INTEN) != events) {
- printf("Hermes: error setting irqmask\n");
- return 1;
- }
-
- return (0);
-}
-
-/*****************************************************************************
- * hermes_set_irqmask *
- * *
- * Which events does the card respond to with an interrupt? *
- *****************************************************************************/
-u16_t hermes_get_irqmask (hermes_t * hw) {
- return hermes_read_reg (hw, HERMES_INTEN);
-}
-
-
-/*****************************************************************************
- * hermes_read_ltv *
- * *
- * Read a Length-Type-Value record from the card. These are configurable *
- * parameters in the cards firmware, like wepkey, essid, mac address etc. *
- * Another name for them are 'rids', Resource Identifiers. See hermes_rids.h *
- * for all available rids *
- * If length is NULL, we ignore the length read from the card, and *
- * read the entire buffer regardless. This is useful because some of *
- * the configuration records appear to have incorrect lengths in *
- * practice. *
- *****************************************************************************/
-int hermes_read_ltv (hermes_t * hw, int bap, u16_t rid, unsigned bufsize,
- u16_t * length, void *buf) {
- int err = 0;
- int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
- u16_t rlength, rtype;
- unsigned nwords;
-
- if ((bufsize % 2)) {
- printf("Hermes: error in bufsize\n");
- return -EINVAL;
- }
-
- err = hermes_docmd_wait (hw, HERMES_CMD_ACCESS, rid, NULL);
- if (err) {
- printf("Hermes: error hermes_docmd_wait in hermes_read_ltv\n");
- return err;
- }
-
- err = hermes_bap_seek (hw, bap, rid, 0);
- if (err) {
- printf("Hermes: error hermes_bap_seek in hermes_read_ltv\n");
- return err;
- }
-
- rlength = hermes_read_reg (hw, dreg);
-
- if (!rlength) {
- printf( "Hermes: Error rlength\n");
- return -ENOENT;
- }
-
- rtype = hermes_read_reg (hw, dreg);
-
- if (length)
- *length = rlength;
-
- if (rtype != rid) {
- printf("hermes @ %x: hermes_read_ltv(): rid (0x%04x)",
- hw->iobase, rid);
- printf("does not match type (0x%04x)\n", rtype);
- }
-
- if (HERMES_RECLEN_TO_BYTES (rlength) > bufsize) {
- printf("hermes @ %x: Truncating LTV record from ",
- hw->iobase);
- printf("%d to %d bytes. (rid=0x%04x, len=0x%04x)\n",
- HERMES_RECLEN_TO_BYTES (rlength), bufsize, rid,
- rlength);
- }
- nwords = MIN ((unsigned) rlength - 1, bufsize / 2);
- hermes_read_words (hw, dreg, buf, nwords);
-
- return 0;
-}
-
-
-/*****************************************************************************
- * hermes_write_ltv *
- * *
- * Write a Length-Type-Value record to the card. These are configurable *
- * parameters in the cards firmware, like wepkey, essid, mac address etc. *
- * Another name for them are 'rids', Resource Identifiers. See hermes_rids.h *
- * for all available rids *
- *****************************************************************************/
-int hermes_write_ltv (hermes_t * hw, int bap, u16_t rid,
- u16_t length, const void *value) {
- int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
- int err = 0;
- unsigned count;
-
- if (length == 0) {
- printf("Hermes: length==0 in hermes_write_ltv\n");
- return -EINVAL;
- }
-
- err = hermes_bap_seek (hw, bap, rid, 0);
- if (err) {
- printf("Hermes: error hermes_bap_seek in hermes_write_ltv\n");
- return err;
- }
-
- hermes_write_reg (hw, dreg, length);
- hermes_write_reg (hw, dreg, rid);
-
- count = length - 1;
-
- hermes_write_words (hw, dreg, value, count);
-
- err = hermes_docmd_wait (hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
- rid, NULL);
- if (err)
- printf("Hermes: error hermes_docmd_wait in hermes_write_ltv\n");
-
- return err;
-}
-
-
-/*****************************************************************************
- * hermes_write_wordrec *
- * *
- * A shorthand for hermes_write_ltv when the field is 2 bytes long *
- *****************************************************************************/
-int hermes_write_wordrec (hermes_t * hw, int bap, u16_t rid, u16_t word) {
-
- u16_t rec;
- int err;
- rec = (word);
-
- err = hermes_write_ltv (hw, bap, rid,
- HERMES_BYTES_TO_RECLEN (sizeof (rec)), &rec);
-
- if (err)
- printf("Hermes: error in write_wordrec\n");
- return err;
-}
-
-
-/*****************************************************************************
- * hermes_read_wordrec *
- * *
- * A shorthand for hermes_read_ltv when the field is 2 bytes long *
- *****************************************************************************/
-int hermes_read_wordrec (hermes_t * hw, int bap, u16_t rid, u16_t * word) {
- u16_t rec;
- int err;
-
- err = hermes_read_ltv (hw, bap, rid, sizeof (rec), NULL, &rec);
- *word = (rec);
- if (err)
- printf("Hermes: Error in read_wordrec\n");
- return err;
-}
-
-
-/*****************************************************************************
- * hermes_read_words *
- * *
- * Read a sequence of words from the card to the buffer *
- *****************************************************************************/
-void hermes_read_words (hermes_t * hw, int off, void *buf, unsigned count) {
- int i = 0;
- u16_t reg;
-
- for (i = 0; i < count; i++) {
- reg = hermes_read_reg (hw, off);
- *((u16_t *) buf + i) = (u16_t) reg;
- }
-}
-
-
-/*****************************************************************************
- * hermes_read_reg *
- * *
- * Read a value from a certain register. Currently only memory mapped *
- * registers are supported, but accessing I/O spaced registers should be *
- * quite trivial *
- *****************************************************************************/
-u16_t hermes_read_reg (const hermes_t * hw, u16_t off) {
- int v = 0;
- v = *((int *)(hw->locmem + (off << hw->reg_spacing)));
- return (u16_t) v;
-}
-
-/*****************************************************************************
- * hermes_write_reg *
- * *
- * Write a value to a certain register. Currently only memory mapped *
- * registers are supported, but accessing I/O spaced registers should be *
- * quite trivial *
- *****************************************************************************/
-void hermes_write_reg (const hermes_t * hw, u16_t off, u16_t val) {
- int v = (int) val;
- *(int *)(hw->locmem + (off << hw->reg_spacing)) = v;
-}
-
+++ /dev/null
-/*
- * hermes.h
- *
- * Constants, structures and prototypes needed for the low level access of
- * Prism cards. The hermes.h file was used as the basis of this file
- *
- * Adjusted to Minix by Stevens Le Blond <slblond@few.vu.nl>
- * and Michael Valkering <mjvalker@cs.vu.nl>
- */
-
-/* Original copyright notices from hermes.h of the Linux kernel
- *
- * Copyright (C) 2000, David Gibson, Linuxcare Australia
- * <hermes@gibson.dropbear.id.au>
- * Portions taken from hfa384x.h, Copyright (C) 1999 AbsoluteValue Systems, Inc.
- * All Rights Reserved.
- * This file distributed under the GPL, version 2.
- */
-#ifndef _HERMES_H
-#define _HERMES_H
-
-#include <minix/drivers.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-#include <net/hton.h>
-#include <stdarg.h>
-
-/*****************************************************************************
- * HERMES CONSTANTS *
- *****************************************************************************/
-#define HERMES_ALLOC_LEN_MIN (4)
-#define HERMES_ALLOC_LEN_MAX (2400)
-#define HERMES_LTV_LEN_MAX (34)
-#define HERMES_BAP_DATALEN_MAX (4096)
-#define HERMES_BAP_OFFSET_MAX (4096)
-#define HERMES_PORTID_MAX (7)
-#define HERMES_NUMPORTS_MAX (HERMES_PORTID_MAX+1)
-#define HERMES_PDR_LEN_MAX (260)
-#define HERMES_PDA_RECS_MAX (200)
-#define HERMES_PDA_LEN_MAX (1024)
-#define HERMES_SCANRESULT_MAX (35)
-#define HERMES_CHINFORESULT_MAX (8)
-#define HERMES_MAX_MULTICAST (16)
-#define HERMES_MAGIC (0x69ff)
-
-/*
- * Hermes register offsets
- */
-#define HERMES_CMD (0x00)
-#define HERMES_PARAM0 (0x02)
-#define HERMES_PARAM1 (0x04)
-#define HERMES_PARAM2 (0x06)
-#define HERMES_STATUS (0x08)
-#define HERMES_RESP0 (0x0A)
-#define HERMES_RESP1 (0x0C)
-#define HERMES_RESP2 (0x0E)
-#define HERMES_INFOFID (0x10)
-#define HERMES_RXFID (0x20)
-#define HERMES_ALLOCFID (0x22)
-#define HERMES_TXCOMPLFID (0x24)
-#define HERMES_SELECT0 (0x18)
-#define HERMES_OFFSET0 (0x1C)
-#define HERMES_DATA0 (0x36)
-#define HERMES_SELECT1 (0x1A)
-#define HERMES_OFFSET1 (0x1E)
-#define HERMES_DATA1 (0x38)
-#define HERMES_EVSTAT (0x30)
-#define HERMES_INTEN (0x32)
-#define HERMES_EVACK (0x34)
-#define HERMES_CONTROL (0x14)
-#define HERMES_SWSUPPORT0 (0x28)
-#define HERMES_SWSUPPORT1 (0x2A)
-#define HERMES_SWSUPPORT2 (0x2C)
-#define HERMES_AUXPAGE (0x3A)
-#define HERMES_AUXOFFSET (0x3C)
-#define HERMES_AUXDATA (0x3E)
-
-/*
- * CMD register bitmasks
- */
-#define HERMES_CMD_BUSY (0x8000)
-#define HERMES_CMD_AINFO (0x7f00)
-#define HERMES_CMD_MACPORT (0x0700)
-#define HERMES_CMD_RECL (0x0100)
-#define HERMES_CMD_WRITE (0x0100)
-#define HERMES_CMD_PROGMODE (0x0300)
-#define HERMES_CMD_CMDCODE (0x003f)
-
-/*
- * STATUS register bitmasks
- */
-#define HERMES_STATUS_RESULT (0x7f00)
-#define HERMES_STATUS_CMDCODE (0x003f)
-
-/*
- * OFFSET register bitmasks
- */
-#define HERMES_OFFSET_BUSY (0x8000)
-#define HERMES_OFFSET_ERR (0x4000)
-#define HERMES_OFFSET_DATAOFF (0x0ffe)
-
-/*
- * Event register bitmasks (INTEN, EVSTAT, EVACK)
- */
-#define HERMES_EV_TICK (0x8000)
-#define HERMES_EV_WTERR (0x4000)
-#define HERMES_EV_INFDROP (0x2000)
-#define HERMES_EV_INFO (0x0080)
-#define HERMES_EV_DTIM (0x0020)
-#define HERMES_EV_CMD (0x0010)
-#define HERMES_EV_ALLOC (0x0008)
-#define HERMES_EV_TXEXC (0x0004)
-#define HERMES_EV_TX (0x0002)
-#define HERMES_EV_RX (0x0001)
-
-/*
- * COR reset options
- */
-#define HERMES_PCI_COR (0x26)
-#define HERMES_PCI_COR_MASK (0x0080)
-/* It appears that the card needs quite some time to recover: */
-#define HERMES_PCI_COR_ONT (250) /* ms */
-#define HERMES_PCI_COR_OFFT (500) /* ms */
-#define HERMES_PCI_COR_BUSYT (500) /* ms */
-/*
- * Command codes
- */
-/*--- Controller Commands --------------------------*/
-#define HERMES_CMD_INIT (0x0000)
-#define HERMES_CMD_ENABLE (0x0001)
-#define HERMES_CMD_DISABLE (0x0002)
-#define HERMES_CMD_DIAG (0x0003)
-
-/*--- Buffer Mgmt Commands --------------------------*/
-#define HERMES_CMD_ALLOC (0x000A)
-#define HERMES_CMD_TX (0x000B)
-#define HERMES_CMD_CLRPRST (0x0012)
-
-/*--- Regulate Commands --------------------------*/
-#define HERMES_CMD_NOTIFY (0x0010)
-#define HERMES_CMD_INQUIRE (0x0011)
-
-/*--- Configure Commands --------------------------*/
-#define HERMES_CMD_ACCESS (0x0021)
-#define HERMES_CMD_DOWNLD (0x0022)
-
-/*--- Debugging Commands -----------------------------*/
-#define HERMES_CMD_MONITOR (0x0038)
-#define HERMES_MONITOR_ENABLE (0x000b)
-#define HERMES_MONITOR_DISABLE (0x000f)
-
-/*
- * Frame structures and constants
- */
-
-#define HERMES_DESCRIPTOR_OFFSET (0)
-#define HERMES_802_11_OFFSET (14)
-#define HERMES_802_3_OFFSET (14+32)
-#define HERMES_802_2_OFFSET (14+32+14)
-
-struct hermes_rx_descriptor
-{
- u16_t status;
- u16_t time_lefthalf;
- u16_t time_righthalf;
- u8_t silence;
- u8_t signal;
- u8_t rate;
- u8_t rxflow;
- u16_t reserved1;
- u16_t reserved2;
-};
-
-#define HERMES_RXSTAT_ERR (0x0003)
-#define HERMES_RXSTAT_BADCRC (0x0001)
-#define HERMES_RXSTAT_UNDECRYPTABLE (0x0002)
-#define HERMES_RXSTAT_MACPORT (0x0700)
-#define HERMES_RXSTAT_PCF (0x1000)
-#define HERMES_RXSTAT_MSGTYPE (0xE000)
-#define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */
-#define HERMES_RXSTAT_TUNNEL (0x4000) /* bridge-tunnel
- * encoded frame */
-#define HERMES_RXSTAT_WMP (0x6000) /* Wavelan-II
- * Management
- * Protocol frame */
-
-struct hermes_tx_descriptor
-{
- u16_t status;
- u16_t reserved1;
- u16_t reserved2;
- u16_t sw_support_lefthalf;
- u16_t sw_support_righthalf;
- u8_t retry_count;
- u8_t tx_rate;
- u16_t tx_control;
-};
-
-#define HERMES_TXSTAT_RETRYERR (0x0001)
-#define HERMES_TXSTAT_AGEDERR (0x0002)
-#define HERMES_TXSTAT_DISCON (0x0004)
-#define HERMES_TXSTAT_FORMERR (0x0008)
-
-#define HERMES_TXCTRL_TX_OK (0x0002)
-#define HERMES_TXCTRL_TX_EX (0x0004)
-#define HERMES_TXCTRL_802_11 (0x0008)
-#define HERMES_TXCTRL_ALT_RTRY (0x0020)
-
-/* Inquiry constants and data types */
-
-#define HERMES_INQ_TALLIES (0xF100)
-#define HERMES_INQ_SCAN (0xF101)
-#define HERMES_INQ_LINKSTATUS (0xF200)
-
-
-/* The tallies are retrieved, but these fields are not processed until now */
-struct hermes_tallies_frame
-{
- u16_t TxUnicastFrames;
- u16_t TxMulticastFrames;
- u16_t TxFragments;
- u16_t TxUnicastOctets;
- u16_t TxMulticastOctets;
- u16_t TxDeferredTransmissions;
- u16_t TxSingleRetryFrames;
- u16_t TxMultipleRetryFrames;
- u16_t TxRetryLimitExceeded;
- u16_t TxDiscards;
- u16_t RxUnicastFrames;
- u16_t RxMulticastFrames;
- u16_t RxFragments;
- u16_t RxUnicastOctets;
- u16_t RxMulticastOctets;
- u16_t RxFCSErrors;
- u16_t RxDiscards_NoBuffer;
- u16_t TxDiscardsWrongSA;
- u16_t RxWEPUndecryptable;
- u16_t RxMsgInMsgFragments;
- u16_t RxMsgInBadMsgFragments;
- u16_t RxDiscards_WEPICVError;
- u16_t RxDiscards_WEPExcluded;
-};
-
-#define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
-#define HERMES_LINKSTATUS_CONNECTED (0x0001)
-#define HERMES_LINKSTATUS_DISCONNECTED (0x0002)
-#define HERMES_LINKSTATUS_AP_CHANGE (0x0003)
-#define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
-#define HERMES_LINKSTATUS_AP_IN_RANGE (0x0005)
-#define HERMES_LINKSTATUS_ASSOC_FAILED (0x0006)
-
-struct hermes_linkstatus
-{
- u16_t linkstatus; /* Link status */
-};
-
-/* Timeouts. These are maximum timeouts. Most often, card wil react
- * much faster */
-#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
-#define HERMES_CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
-#define HERMES_CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
-#define HERMES_CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
-#define HERMES_ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
-
-/* WEP settings */
-#define HERMES_AUTH_OPEN (1)
-#define HERMES_AUTH_SHARED_KEY (2)
-#define HERMES_WEP_PRIVACY_INVOKED (0x0001)
-#define HERMES_WEP_EXCL_UNENCRYPTED (0x0002)
-#define HERMES_WEP_HOST_ENCRYPT (0x0010)
-#define HERMES_WEP_HOST_DECRYPT (0x0080)
-
-
-/* Basic control structure */
-typedef struct hermes
-{
- u32_t iobase;
- int io_space; /* 1 if we IO-mapped IO, 0 for memory-mapped
- * IO */
-#define HERMES_IO 1
-#define HERMES_MEM 0
- int reg_spacing;
-#define HERMES_16BIT_REGSPACING 0
-#define HERMES_32BIT_REGSPACING 1
- u16_t inten; /* Which interrupts should be enabled? */
- char *locmem;
-} hermes_t;
-
-typedef struct hermes_response
-{
- u16_t status, resp0, resp1, resp2;
-} hermes_response_t;
-
-struct hermes_idstring
-{
- u16_t len;
- u16_t val[16];
-};
-
-#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
-#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
-
-/* Function prototypes */
-u16_t hermes_read_reg(const hermes_t * hw, u16_t off);
-void hermes_write_reg(const hermes_t * hw, u16_t off, u16_t val);
-void hermes_struct_init(hermes_t * hw, u32_t address, int io_space, int
- reg_spacing);
-int hermes_init(hermes_t * hw);
-int hermes_docmd_wait(hermes_t * hw, u16_t cmd, u16_t parm0,
- hermes_response_t * resp);
-int hermes_allocate(hermes_t * hw, u16_t size, u16_t * fid);
-int hermes_bap_pread(hermes_t * hw, int bap, void *buf, unsigned len,
- u16_t id, u16_t offset);
-int hermes_bap_pwrite(hermes_t * hw, int bap, const void *buf, unsigned
- len, u16_t id, u16_t offset);
-void hermes_read_words(hermes_t * hw, int off, void *buf, unsigned
- count);
-int hermes_read_ltv(hermes_t * hw, int bap, u16_t rid, unsigned buflen,
- u16_t * length, void *buf);
-int hermes_write_ltv(hermes_t * hw, int bap, u16_t rid, u16_t length,
- const void *value);
-int hermes_set_irqmask(hermes_t * hw, u16_t events);
-u16_t hermes_get_irqmask(hermes_t * hw);
-int hermes_read_wordrec(hermes_t * hw, int bap, u16_t rid, u16_t *
- word);
-int hermes_write_wordrec(hermes_t * hw, int bap, u16_t rid, u16_t word);
-int hermes_cor_reset(hermes_t *hw);
-#endif /* _HERMES_H */
+++ /dev/null
-/* hermes_rid.h
- *
- * This file contains the RIDs (Resource IDentifiers). These are data items
- * which are configurable in the card. Most of them are not used in our driver
- * currently, as you can see there are really a lot which can be configured.
- */
-
-
-#ifndef _HERMES_RID_H
-#define _HERMES_RID_H
-
-#define HERMES_RID_CNFPORTTYPE 0xFC00
-#define HERMES_RID_CNFOWNMACADDR 0xFC01
-#define HERMES_RID_CNFDESIREDSSID 0xFC02
-#define HERMES_RID_CNFOWNCHANNEL 0xFC03
-#define HERMES_RID_CNFOWNSSID 0xFC04
-#define HERMES_RID_CNFOWNATIMWINDOW 0xFC05
-#define HERMES_RID_CNFSYSTEMSCALE 0xFC06
-#define HERMES_RID_CNFMAXDATALEN 0xFC07
-#define HERMES_RID_CNFWDSADDRESS 0xFC08
-#define HERMES_RID_CNFPMENABLED 0xFC09
-#define HERMES_RID_CNFPMEPS 0xFC0A
-#define HERMES_RID_CNFMULTICASTRECEIVE 0xFC0B
-#define HERMES_RID_CNFMAXSLEEPDURATION 0xFC0C
-#define HERMES_RID_CNFPMHOLDOVERDURATION 0xFC0D
-#define HERMES_RID_CNFOWNNAME 0xFC0E
-#define HERMES_RID_CNFOWNDTIMPERIOD 0xFC10
-#define HERMES_RID_CNFWDSADDRESS1 0xFC11
-#define HERMES_RID_CNFWDSADDRESS2 0xFC12
-#define HERMES_RID_CNFWDSADDRESS3 0xFC13
-#define HERMES_RID_CNFWDSADDRESS4 0xFC14
-#define HERMES_RID_CNFWDSADDRESS5 0xFC15
-#define HERMES_RID_CNFWDSADDRESS6 0xFC16
-#define HERMES_RID_CNFMULTICASTPMBUFFERING 0xFC17
-#define HERMES_RID_CNFWEPENABLED_AGERE 0xFC20
-#define HERMES_RID_CNFAUTHENTICATION_AGERE 0xFC21
-#define HERMES_RID_CNFMANDATORYBSSID_SYMBOL 0xFC21
-#define HERMES_RID_CNFWEPDEFAULTKEYID 0xFC23
-#define HERMES_RID_CNFDEFAULTKEY0 0xFC24
-#define HERMES_RID_CNFDEFAULTKEY1 0xFC25
-#define HERMES_RID_CNFMWOROBUST_AGERE 0xFC25
-#define HERMES_RID_CNFDEFAULTKEY2 0xFC26
-#define HERMES_RID_CNFDEFAULTKEY3 0xFC27
-#define HERMES_RID_CNFWEPFLAGS_INTERSIL 0xFC28
-#define HERMES_RID_CNFWEPKEYMAPPINGTABLE 0xFC29
-#define HERMES_RID_CNFAUTHENTICATION 0xFC2A
-#define HERMES_RID_CNFMAXASSOCSTA 0xFC2B
-#define HERMES_RID_CNFKEYLENGTH_SYMBOL 0xFC2B
-#define HERMES_RID_CNFTXCONTROL 0xFC2C
-#define HERMES_RID_CNFROAMINGMODE 0xFC2D
-#define HERMES_RID_CNFHOSTAUTHENTICATION 0xFC2E
-#define HERMES_RID_CNFRCVCRCERROR 0xFC30
-#define HERMES_RID_CNFMMLIFE 0xFC31
-#define HERMES_RID_CNFALTRETRYCOUNT 0xFC32
-#define HERMES_RID_CNFBEACONINT 0xFC33
-#define HERMES_RID_CNFAPPCFINFO 0xFC34
-#define HERMES_RID_CNFSTAPCFINFO 0xFC35
-#define HERMES_RID_CNFPRIORITYQUSAGE 0xFC37
-#define HERMES_RID_CNFTIMCTRL 0xFC40
-#define HERMES_RID_CNFTHIRTY2TALLY 0xFC42
-#define HERMES_RID_CNFENHSECURITY 0xFC43
-#define HERMES_RID_CNFGROUPADDRESSES 0xFC80
-#define HERMES_RID_CNFCREATEIBSS 0xFC81
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD 0xFC82
-#define HERMES_RID_CNFRTSTHRESHOLD 0xFC83
-#define HERMES_RID_CNFTXRATECONTROL 0xFC84
-#define HERMES_RID_CNFPROMISCUOUSMODE 0xFC85
-#define HERMES_RID_CNFBASICRATES_SYMBOL 0xFC8A
-#define HERMES_RID_CNFPREAMBLE_SYMBOL 0xFC8C
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD0 0xFC90
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD1 0xFC91
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD2 0xFC92
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD3 0xFC93
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD4 0xFC94
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD5 0xFC95
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD6 0xFC96
-#define HERMES_RID_CNFRTSTHRESHOLD0 0xFC97
-#define HERMES_RID_CNFRTSTHRESHOLD1 0xFC98
-#define HERMES_RID_CNFRTSTHRESHOLD2 0xFC99
-#define HERMES_RID_CNFRTSTHRESHOLD3 0xFC9A
-#define HERMES_RID_CNFRTSTHRESHOLD4 0xFC9B
-#define HERMES_RID_CNFRTSTHRESHOLD5 0xFC9C
-#define HERMES_RID_CNFRTSTHRESHOLD6 0xFC9D
-#define HERMES_RID_CNFHOSTSCAN_SYMBOL 0xFCAB
-#define HERMES_RID_CNFSHORTPREAMBLE 0xFCB0
-#define HERMES_RID_CNFWEPKEYS_AGERE 0xFCB0
-#define HERMES_RID_CNFEXCLUDELONGPREAMBLE 0xFCB1
-#define HERMES_RID_CNFTXKEY_AGERE 0xFCB1
-#define HERMES_RID_CNFAUTHENTICATIONRSPTO 0xFCB2
-#define HERMES_RID_CNFSCANSSID_AGERE 0xFCB2
-#define HERMES_RID_CNFBASICRATES 0xFCB3
-#define HERMES_RID_CNFSUPPORTEDRATES 0xFCB4
-#define HERMES_RID_CNFTICKTIME 0xFCE0
-#define HERMES_RID_CNFSCANREQUEST 0xFCE1
-#define HERMES_RID_CNFJOINREQUEST 0xFCE2
-#define HERMES_RID_CNFAUTHENTICATESTATION 0xFCE3
-#define HERMES_RID_CNFCHANNELINFOREQUEST 0xFCE4
-#define HERMES_RID_CNFHOSTSCAN 0xFCE5
-#define HERMES_RID_MAXLOADTIME 0xFD00
-#define HERMES_RID_DOWNLOADBUFFER 0xFD01
-#define HERMES_RID_PRIID 0xFD02
-#define HERMES_RID_PRISUPRANGE 0xFD03
-#define HERMES_RID_CFIACTRANGES 0xFD04
-#define HERMES_RID_NICSERNUM 0xFD0A
-#define HERMES_RID_NICID 0xFD0B
-#define HERMES_RID_MFISUPRANGE 0xFD0C
-#define HERMES_RID_CFISUPRANGE 0xFD0D
-#define HERMES_RID_CHANNELLIST 0xFD10
-#define HERMES_RID_REGULATORYDOMAINS 0xFD11
-#define HERMES_RID_TEMPTYPE 0xFD12
-#define HERMES_RID_CIS 0xFD13
-#define HERMES_RID_STAID 0xFD20
-#define HERMES_RID_STASUPRANGE 0xFD21
-#define HERMES_RID_MFIACTRANGES 0xFD22
-#define HERMES_RID_CFIACTRANGES2 0xFD23
-#define HERMES_RID_SECONDARYVERSION_SYMBOL 0xFD24
-#define HERMES_RID_PORTSTATUS 0xFD40
-#define HERMES_RID_CURRENTSSID 0xFD41
-#define HERMES_RID_CURRENTBSSID 0xFD42
-#define HERMES_RID_COMMSQUALITY 0xFD43
-#define HERMES_RID_CURRENTTXRATE 0xFD44
-#define HERMES_RID_CURRENTBEACONINTERVAL 0xFD45
-#define HERMES_RID_CURRENTSCALETHRESHOLDS 0xFD46
-#define HERMES_RID_PROTOCOLRSPTIME 0xFD47
-#define HERMES_RID_SHORTRETRYLIMIT 0xFD48
-#define HERMES_RID_LONGRETRYLIMIT 0xFD49
-#define HERMES_RID_MAXTRANSMITLIFETIME 0xFD4A
-#define HERMES_RID_MAXRECEIVELIFETIME 0xFD4B
-#define HERMES_RID_CFPOLLABLE 0xFD4C
-#define HERMES_RID_AUTHENTICATIONALGORITHMS 0xFD4D
-#define HERMES_RID_PRIVACYOPTIONIMPLEMENTED 0xFD4F
-#define HERMES_RID_DBMCOMMSQUALITY_INTERSIL 0xFD51
-#define HERMES_RID_CURRENTTXRATE1 0xFD80
-#define HERMES_RID_CURRENTTXRATE2 0xFD81
-#define HERMES_RID_CURRENTTXRATE3 0xFD82
-#define HERMES_RID_CURRENTTXRATE4 0xFD83
-#define HERMES_RID_CURRENTTXRATE5 0xFD84
-#define HERMES_RID_CURRENTTXRATE6 0xFD85
-#define HERMES_RID_OWNMACADDR 0xFD86
-#define HERMES_RID_SCANRESULTSTABLE 0xFD88
-#define HERMES_RID_PHYTYPE 0xFDC0
-#define HERMES_RID_CURRENTCHANNEL 0xFDC1
-#define HERMES_RID_CURRENTPOWERSTATE 0xFDC2
-#define HERMES_RID_CCAMODE 0xFDC3
-#define HERMES_RID_SUPPORTEDDATARATES 0xFDC6
-#define HERMES_RID_BUILDSEQ 0xFFFE
-#define HERMES_RID_FWID 0xFFFF
-
-#endif
+++ /dev/null
-/*
- * orinoco.c
- *
- * This file contains a wireless device driver for Prism based wireless
- * cards.
- *
- * Created by Stevens Le Blond <slblond@few.vu.nl>
- * and Michael Valkering <mjvalker@cs.vu.nl>
- *
- */
-
-#include <minix/drivers.h>
-#include <minix/netdriver.h>
-#include <machine/pci.h>
-#include <machine/vmparam.h>
-#include <sys/mman.h>
-
-#define VERBOSE 1 /* display message during init */
-
-#include "assert.h"
-#include "hermes.h"
-#include "hermes_rid.h"
-#include "orinoco.h"
-
-#define OR_M_ENABLED 1
-#define OR_M_DISABLED 0
-#define OR_F_EMPTY 0
-#define OR_F_MULTI 1
-#define OR_F_BROAD (1<<1)
-#define OR_F_ENABLED (1<<2)
-#define OR_F_PROMISC (1<<3)
-#define OR_F_READING (1<<4)
-#define OR_F_SEND_AVAIL (1<<5)
-#define OR_F_PACK_SENT (1<<6)
-#define OR_F_PACK_RECV (1<<7)
-#define ORINOCO_INTEN ( HERMES_EV_RX | HERMES_EV_ALLOC |\
- HERMES_EV_WTERR | HERMES_EV_TXEXC|\
- HERMES_EV_INFO | HERMES_EV_INFDROP|\
- HERMES_EV_TX)
-
-#define NO_FID (-1)
-#define ETH_ALEN 6
-#define USER_BAP 0
-#define IRQ_BAP 1
-#define ETH_HLEN 14
-
-static t_or or_state;
-
-struct ethhdr {
- u8_t h_dest[ETH_ALEN];
- u8_t h_src[ETH_ALEN];
- u16_t h_proto;
-};
-
-struct header_struct {
- /* 802.3 */
- u8_t dest[ETH_ALEN];
- u8_t src[ETH_ALEN];
- u16_t len;
- /* 802.2 */
- u8_t dsap;
- u8_t ssap;
- u8_t ctrl;
- /* SNAP */
- u8_t oui[3];
- u16_t ethertype;
-};
-
-#define RUP_EVEN(x) (((x) + 1) & (~1))
-
-u8_t encaps_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-#define ENCAPS_OVERHEAD (sizeof (encaps_hdr) + 2)
-
-/********************************************************************
- * Data tables *
- ********************************************************************/
-
-/* The frequency of each channel in MHz */
-static const long channel_frequency[] = {
- 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-
-#define NUM_CHANNELS (sizeof(channel_frequency) / sizeof(channel_frequency[0]))
-
-/* This tables gives the actual meanings of the bitrate IDs returned by the
- * firmware. Not used yet */
-struct {
- int bitrate; /* in 100s of kilobits */
- int automatic;
- u16_t txratectrl;
-} bitrate_table[] =
-{
- {110, 1, 15}, /* Entry 0 is the default */
- {10, 0, 1},
- {10, 1, 1},
- {20, 0, 2},
- {20, 1, 3},
- {55, 0, 4},
- {55, 1, 7},
- {110, 0, 8},};
-
-#define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
-
-static void or_other(const message *m_ptr, int ipc_status);
-static void or_stop(void);
-static int or_probe(t_or *, unsigned int skip);
-static void or_ev_info(t_or *);
-static int or_init(unsigned int instance, ether_addr_t *addr);
-static void or_init_struct(t_or *, unsigned int);
-static void or_init_hw(t_or *, ether_addr_t *);
-static void or_check_ints(t_or *);
-static void or_writerids(hermes_t *, t_or *);
-static void or_readrids(hermes_t *, t_or *, ether_addr_t *);
-static u32_t or_get_bar(int devind, t_or * orp);
-static void or_stat(eth_stat_t *stat);
-static void print_linkstatus(t_or * orp, u16_t status);
-static ssize_t or_recv(struct netdriver_data *data, size_t max);
-static int or_get_recvd_packet(t_or *orp, u16_t rxfid, u8_t *databuf);
-static void or_reset(void);
-static void or_alarm(clock_t stamp);
-static int or_send(struct netdriver_data *data, size_t size);
-static void setup_wepkey(t_or *orp, char *wepkey0);
-static void or_intr(unsigned int mask);
-static void or_handler(t_or *orp);
-static void or_dump(void);
-
-static const struct netdriver or_table = {
- .ndr_init = or_init,
- .ndr_stop = or_stop,
- .ndr_recv = or_recv,
- .ndr_send = or_send,
- .ndr_stat = or_stat,
- .ndr_intr = or_intr,
- .ndr_alarm = or_alarm,
- .ndr_other = or_other
-};
-
-/*****************************************************************************
- * main *
- * *
- * *
- * The main function of the driver, receiving and processing messages *
- *****************************************************************************/
-int main(int argc, char *argv[])
-{
- env_setargs(argc, argv);
-
- netdriver_task(&or_table);
-
- return 0;
-}
-
-/*****************************************************************************
- * or_other *
- * *
- * *
- * Process miscellaneous messages *
- *****************************************************************************/
-static void or_other(const message *m_ptr, int ipc_status)
-{
- if (is_ipc_notify(ipc_status) && m_ptr->m_source == TTY_PROC_NR)
- or_dump();
-}
-
-/*****************************************************************************
- * or_stop *
- * *
- * Stop the card *
- *****************************************************************************/
-static void or_stop(void)
-{
- t_or *orp;
-
- orp = &or_state;
-
- /* TODO: send a signal to the card to shut it down */
-}
-
-/*****************************************************************************
- * or_intr *
- * *
- * Process the interrupts which the card generated *
- *****************************************************************************/
-static void or_intr(unsigned int __unused mask)
-{
- t_or *orp;
- int s;
-
- orp = &or_state;
-
- /* Run interrupt handler at driver level. */
- or_handler(orp);
-
- /* Reenable interrupts for this hook. */
- if ((s=sys_irqenable(&orp->or_hook_id)) != OK)
- printf("orinoco: error, couldn't enable interrupts: %d\n", s);
-
- /* Perform tasks based on the flagged conditions. */
- or_check_ints(orp);
-}
-
-/*****************************************************************************
- * or_reset *
- * *
- * Sometime the card gets screwed, behaving erratically. Solution: reset the *
- * card. This is actually largely redoing the initialization *
- *****************************************************************************/
-static void or_reset(void)
-{
- static clock_t last_reset, now;
- t_or *orp;
- int i, r;
-
- if (OK != (r = getticks(&now)))
- panic("orinoco: getuptime() failed: %d", r);
-
- if(now - last_reset < sys_hz() * 10) {
- printf("Resetting card too often. Going to reset driver\n");
- exit(1);
- }
-
- last_reset = now;
-
- orp = &or_state;
-
- orp->or_need_reset = FALSE;
- or_init_hw(orp, NULL);
-
- orp->rx_last = orp->rx_first = 0;
- for(i = 0; i < NR_RX_BUFS; i++) {
- orp->rx_length[0] = 0;
- }
-
- if (orp->or_tx.ret_busy)
- orp->or_tx_busy--;
- orp->or_tx.ret_busy = FALSE;
- orp->or_send_int = TRUE;
-}
-
-/*****************************************************************************
- * or_dump *
- * *
- * Dump interesting information about the card on F-key pressed. *
- * Not implemented yet *
- *****************************************************************************/
-static void or_dump(void)
-{
- t_or *orp;
- int sfkeys;
-
- orp = &or_state;
-
- if(OK != fkey_events(NULL, &sfkeys)) {
- printf("Contacting the TTY failed\n");
- }
-
- if(bit_isset(sfkeys, 11)) {
- print_linkstatus(orp, orp->last_linkstatus);
- }
-}
-
-/*****************************************************************************
- * or_init *
- * *
- * The main initialization function, called at startup. *
- *****************************************************************************/
-static int or_init(unsigned int instance, ether_addr_t *addr)
-{
- int fkeys, sfkeys, r;
- t_or *orp;
-
- orp = &or_state;
-
- /* Initialize the orp structure */
- or_init_struct(orp, instance);
-
- /* Try to find out where the card is in the pci bus */
- if (!or_probe(orp, instance))
- return ENXIO;
-
- /* initialize card, hardware/firmware */
- or_init_hw(orp, addr);
-
- /* Use a synchronous alarm instead of a watchdog timer. */
- sys_setalarm(sys_hz(), 0);
-
- /* Observe some function key for debug dumps. */
- fkeys = sfkeys = 0; bit_set(sfkeys, 11);
- if ((r=fkey_map(&fkeys, &sfkeys)) != OK)
- printf("Warning: orinoco couldn't observe F-key(s): %d\n",r);
-
- return OK;
-}
-
-/*****************************************************************************
- * or_probe *
- * *
- * Try to find the card based on information provided by pci and get irq and *
- * bar *
- *****************************************************************************/
-static int or_probe(t_or * orp, unsigned int skip)
-{
- u8_t ilr;
- u32_t bar;
- char *dname;
- u16_t vid, did;
- int r, devind;
-
- pci_init();
-
- /* Start looking from the beginning */
- r = pci_first_dev(&devind, &vid, &did);
- if (r == 0)
- return FALSE;
-
- /* Skip as many instances as requested */
- while (skip--) {
- r = pci_next_dev(&devind, &vid, &did);
- if (!r)
- return FALSE;
- }
-
- /* Get the name as advertised by pci */
- dname = pci_dev_name(vid, did);
- if (!dname)
- dname = "unknown device";
- printf("%s: %s (%04x/%04x) at %s\n",
- orp->or_name, dname, vid, did, pci_slot_name(devind));
-
- pci_reserve(devind);
-
- /* Get the irq */
- ilr = pci_attr_r8(devind, PCI_ILR);
- orp->or_irq = ilr;
-
- /* Map registers into memory */
- bar = or_get_bar(devind, orp);
-
- orp->hw.locmem = vm_map_phys(SELF, (void *)bar, PAGE_SIZE);
- if (orp->hw.locmem == MAP_FAILED)
- panic("or_probe: vm_map_phys failed");
-
- return TRUE;
-}
-
-/*****************************************************************************
- * or_get_bar *
- * *
- * Get the base address from pci (from Base Address Register) and find out *
- * whether the card is memory mapped or in I/O space. Currently, only *
- * memmory mapped is supported. *
- *****************************************************************************/
-static u32_t or_get_bar(int devind, t_or * orp)
-{
- u32_t bar;
- int is_iospace;
- hermes_t *hw = &(orp->hw);
-
- /* bit 1 off the PCI_BAR register indicates whether the cards registers
- * are mapped in io-space or shared memory */
- is_iospace = pci_attr_r32(devind, PCI_BAR) & 1;
-
- if (is_iospace) {
- /* read where the base address is in I/O space */
- bar = pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
-
- if ((bar & 0x3ff) >= 0x100 - 32 || bar < 0x400)
- panic("base address isn't properly configured");
-
- /* In I/O space registers are 2 bytes wide, without any spacing
- * in between */
- hermes_struct_init (hw, bar, is_iospace,
- HERMES_16BIT_REGSPACING);
-
-#if VERBOSE
- printf ("%s: using I/O space address 0x%x, IRQ %d\n",
- orp->or_name, bar, orp->or_irq);
-#endif
-
- panic("Not implemented yet");
- /* Although we are able to find the desired bar and irq for an
- * I/O spaced card, we haven't implemented the right register
- * accessing functions. This wouldn't be difficult, but we were
- * not able to test them. Therefore, give an alert here */
-
- return bar;
- } else {
- /* read where the base address is in shared memory */
- bar = pci_attr_r32(devind, PCI_BAR) & 0xfffffff0;
- /* maybe some checking whether the address is legal... */
-
- /* Memory mapped registers are 2 bytes wide, aligned on 4
- * bytes */
- hermes_struct_init (hw, bar, is_iospace,
- HERMES_32BIT_REGSPACING);
-
-#if VERBOSE
- printf ("%s: using shared memory address", orp->or_name);
- printf (" 0x%x, IRQ %d\n", bar, orp->or_irq);
-#endif
-
- return bar;
-
- }
-}
-
-/*****************************************************************************
- * or_init_struct *
- * *
- * Set the orinoco structure to default values *
- *****************************************************************************/
-static void or_init_struct(t_or * orp, unsigned int instance)
-{
- int i;
-
- memset(orp, 0, sizeof(*orp));
-
- strlcpy(orp->or_name, OR_NAME, sizeof(orp->or_name));
- orp->or_name[sizeof(OR_NAME) - 2] = instance + '0';
-
- orp->or_link_up = -1;
-
- orp->or_tx.or_txfid = NO_FID;
-
- for(i = 0; i < NR_RX_BUFS; i++) {
- orp->rxfid[i] = NO_FID;
- orp->rx_length[i] = 0;
- }
-
- /* Keep an administration in the driver whether the internal
- buffer is in use. That's what ret_busy is for */
- orp->or_tx.ret_busy = FALSE;
- orp->or_tx_busy = 0;
-
- orp->or_nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
-}
-
-/*****************************************************************************
- * or_init_hw *
- * *
- * Initialize hardware and prepare for intercepting the interrupts. At the *
- * end, the card is up and running. May be called multiple times. *
- *****************************************************************************/
-static void or_init_hw(t_or * orp, ether_addr_t * addr)
-{
-#if VERBOSE
- int i;
-#endif
- int err, s;
- hermes_t *hw = &(orp->hw);
- static int first_time = TRUE;
-
- /* first step in starting the card */
- if (hermes_cor_reset(hw) != 0) {
- printf ("%s: Failed to start the card\n", orp->or_name);
- }
-
- /* here begins the real things, yeah! ;) */
- if ((err = hermes_init (hw)) != 0) {
- printf ("error value of hermes_init(): %d\n", err);
- }
-
- if (first_time) {
- /* Get the MAC address (which is a data item in the card)*/
- or_readrids(hw, orp, addr);
- }
-
- /* Write a few rids to the card, e.g. WEP key*/
- or_writerids (hw, orp);
-
-#if VERBOSE
- printf ("%s: Ethernet address ", orp->or_name);
- for (i = 0; i < 6; i++)
- printf("%x%c", addr->ea_addr[i], i < 5 ? ':' : '\n');
-#endif
-
- /* Prepare internal TX buffer in the card */
- err = hermes_allocate (hw,
- orp->or_nicbuf_size,
- &(orp->or_tx.or_txfid));
-
- if (err)
- printf ("%s:Error %d allocating Tx buffer\n",
- orp->or_name, err);
-
- /* Establish event handle */
- if(first_time) {
- orp->or_hook_id = orp->or_irq;
- if ((s=sys_irqsetpolicy(orp->or_irq, 0,
- &orp->or_hook_id)) != OK)
- printf("orinoco: couldn't set IRQ policy: %d\n", s);
-
- if ((s=sys_irqenable(&orp->or_hook_id)) != OK)
- printf("orinoco: couldn't enable interrupts: %d\n", s);
- first_time = FALSE;
- }
-
- /* Tell the card which events should raise an interrupt to the OS */
- hermes_set_irqmask (hw, ORINOCO_INTEN);
-
- /* Enable operation */
- err = hermes_docmd_wait (hw, HERMES_CMD_ENABLE, 0, NULL);
- if (err)
- printf("%s: Error %d enabling MAC port\n", orp->or_name, err);
-}
-
-/*****************************************************************************
- * or_readrids *
- * *
- * Read some default rids from the card. A rid (resource identifier) *
- * is a data item in the firmware, some configuration variable. *
- * In our case, we are mostly interested in the MAC address for now *
- *****************************************************************************/
-static void or_readrids(hermes_t * hw, t_or * orp, ether_addr_t * addr)
-{
- int err;
-
- assert(addr != NULL);
-
- /* Read the MAC address */
- err = hermes_read_ltv (hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
- ETH_ALEN, NULL, addr);
- if (err)
- printf("%s: failed to read MAC address!\n", orp->or_name);
-}
-
-/*****************************************************************************
- * or_writerids *
- * *
- * Write some default rids to the card. A rid (resource identifier) *
- * is a data item in the firmware, some configuration variable, e.g. WEP key *
- *****************************************************************************/
-static void or_writerids(hermes_t * hw, t_or * orp)
-{
- int err;
- struct hermes_idstring idbuf;
- static char essid[IW_ESSID_MAX_SIZE + 1];
- static char wepkey0[LARGE_KEY_LENGTH + 1];
-
- /* Set the MAC port */
- err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE, 1);
- if (err) {
- printf ("%s: Error %d setting port type\n", orp->or_name, err);
- return;
- }
-
- if (OK != env_get_param("essid", essid, sizeof(essid))) {
- essid[0] = 0;
- }
-
- if(strlen(essid) == 0) {
- printf("%s: no essid provided in boot monitor!\n",
- orp->or_name);
- printf("Hope you'll connect to the right network... \n");
- }
-
- /* Set the desired ESSID */
- idbuf.len = strlen (essid);
- memcpy (&idbuf.val, essid, sizeof (idbuf.val));
-
- err = hermes_write_ltv (hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
- HERMES_BYTES_TO_RECLEN (strlen (essid) + 2),
- &idbuf);
- if (err) {
- printf ("%s: Error %d setting DESIREDSSID\n",
- orp->or_name, err);
- return;
- }
-
- if (OK != env_get_param("wep", wepkey0, sizeof(wepkey0))) {
- wepkey0[0] = 0;
- }
-
- switch(strlen(wepkey0)) {
- case 0:
- /* No key found in monitor, using no encryption */
- break;
- case LARGE_KEY_LENGTH:
- setup_wepkey(orp, wepkey0);
- break;
- default:
- printf("Invalid key provided. Has to be 13 chars\n");
- break;
- }
-}
-
-/*****************************************************************************
- * setup_wepkey *
- * *
- * If a wepkey is provided in the boot monitor, set the necessary rids so *
- * that the card will decrypt received data and encrypt data to send by *
- * by default with this key. *
- * It appears that there is a severe bug in setting up WEP. If the driver *
- * doesnt function properly, please turn WEP off. *
- *****************************************************************************/
-static void setup_wepkey(t_or *orp, char *wepkey0)
-{
- int default_key = 0, err = 0;
- hermes_t *hw = &(orp->hw);
-
- err = hermes_write_wordrec (hw, USER_BAP,
- HERMES_RID_CNFWEPDEFAULTKEYID,
- default_key);
- if (err)
- printf ("%s: Error %d setting the default WEP-key entry\n",
- orp->or_name, err);
-
- err = hermes_write_ltv (hw, USER_BAP,
- HERMES_RID_CNFDEFAULTKEY0,
- HERMES_BYTES_TO_RECLEN(LARGE_KEY_LENGTH),
- wepkey0);
- if (err)
- printf ("%s: Error %d setting the WEP-key0\n",
- orp->or_name, err);
-
- err = hermes_write_wordrec (hw, USER_BAP,
- HERMES_RID_CNFAUTHENTICATION,
- HERMES_AUTH_OPEN);
- if (err)
- printf ("%s: Error %d setting the authentication flag\n",
- orp->or_name, err);
-
- err = hermes_write_wordrec (hw, USER_BAP,
- HERMES_RID_CNFWEPFLAGS_INTERSIL,
- HERMES_WEP_PRIVACY_INVOKED);
- if (err)
- printf ("%s: Error %d setting the master wep setting flag\n",
- orp->or_name, err);
-
-}
-
-/*****************************************************************************
- * or_handler *
- * *
- * The handler which is called when the card generated an interrupt. Events *
- * like EV_INFO and EV_RX have to be handled before an acknowledgement for *
- * the event is returned to the card. See also the documentation *
- *****************************************************************************/
-static void or_handler(t_or *orp)
-{
- int length;
- u16_t evstat, events, fid;
- hermes_t *hw = &(orp->hw);
-
-beginning:
- /* Retrieve which kind of event happened */
- evstat = hermes_read_reg (hw, HERMES_EVSTAT);
- events = evstat;
-
- /* There are plenty of events possible. The more interesting events
- are actually implemented. Whether the following events actually
- raise an interrupt depends on the value of ORINOCO_INTEN. For more
- information about the events, see the specification in pdf */
-
- /* Occurs at each tick of the auxiliary time */
- if (events & HERMES_EV_TICK) {
- events &= ~HERMES_EV_TICK;
- }
- /* Occurs when a wait time-out error is detected */
- if (events & HERMES_EV_WTERR) {
- events &= ~HERMES_EV_WTERR;
- }
-
- /* Occurs when an info frame is dropped because there is not enough
- buffer space available */
- if (events & HERMES_EV_INFDROP) {
- events &= ~(HERMES_EV_INFDROP);
- }
-
- /* This AP-only event will be asserted at the beacon interval prior to
- the DTIM interval */
- if (events & HERMES_EV_DTIM) {
- events &= ~(HERMES_EV_DTIM);
- }
-
- /* Occurs when a command execution is completed */
- if (events & HERMES_EV_CMD) {
- events &= ~(HERMES_EV_CMD);
- }
-
- /* Occurs when the asynchronous transmission process is unsuccessfully
- completed */
- if (events & HERMES_EV_TXEXC) {
- /* What buffer generated the event? Represented by an fid */
- fid = hermes_read_reg(hw, HERMES_TXCOMPLFID);
- if(fid == 0xFFFF) {
- /* Illegal fid found */
- printf("unexpected txexc_fid interrupted\n");
- }
-
- if (orp->or_tx.ret_busy)
- orp->or_tx_busy--;
- orp->or_tx.ret_busy = FALSE;
-
- orp->or_send_int = TRUE;
- orp->or_got_int = TRUE;
-
- /* To detect illegal fids */
- hermes_write_reg(hw, HERMES_TXCOMPLFID, 0xFFFF);
- events &= ~(HERMES_EV_TXEXC);
- /* We don't do anything else yet.
- * Could be used for statistics */
- }
-
- /* Occurs when the asynchronous transmission process is successfully
- completed */
- if (events & HERMES_EV_TX) {
- events &= ~(HERMES_EV_TX);
- /* Which buffer was sent, represented by an fid */
- fid = hermes_read_reg (hw, HERMES_TXCOMPLFID);
- if(fid == 0xFFFF) {
- /* Illegal fid found */
- printf("unexpected tx_fid interrupted\n");
- }
-
- if (orp->or_tx.ret_busy)
- orp->or_tx_busy--;
- orp->or_tx.ret_busy = FALSE;
-
- orp->or_send_int = TRUE;
- orp->or_got_int = TRUE;
- orp->or_tx_alive = TRUE;
-
- /* To detect illegal fids */
- hermes_write_reg(hw, HERMES_TXCOMPLFID, 0xFFFF);
- /* We don't do anything else when such event happens */
- }
-
- /* Occurs when an info frame is available in the card */
- if (events & HERMES_EV_INFO) {
- events &= ~(HERMES_EV_INFO);
- /* Process the information, inside the handler (!) */
- or_ev_info(orp);
- }
-
- /* Occurs when a TX buffer is available again for usage */
- if (events & HERMES_EV_ALLOC) {
- /* Which frame is now marked as free? */
- fid = hermes_read_reg (hw, HERMES_ALLOCFID);
- if (fid == 0xFFFF){
- /* An illegal frame identifier is found. Ignore */
- printf("Allocate event on unexpected fid\n");
- goto next;
- }
-
- /* To be able to detect illegal fids */
- hermes_write_reg(hw, HERMES_ALLOCFID, 0xFFFF);
-
- events &= ~(HERMES_EV_ALLOC);
- }
-
- /* Occurs when a frame is received */
- if (events & HERMES_EV_RX) {
- events &= ~(HERMES_EV_RX);
-
- /* If the last buffer is still filled with data, then we don't
- * have any buffers available to store the data */
- if(orp->rx_length[orp->rx_last] != 0) {
- /* indeed, we are going to overwrite information
- * in a buffer
- */
- }
-
- /* Which buffer is storing the data (represented by a fid) */
- orp->rxfid[orp->rx_last]
- = hermes_read_reg (hw, HERMES_RXFID);
-
- /* Get the packet from the card and store it in
- * orp->rx_buf[orp->rx_last]. The length is returned by this
- * function
- */
- length = or_get_recvd_packet(orp, orp->rxfid[orp->rx_last],
- (orp->rx_buf[orp->rx_last]));
-
- if(length < 0) {
- /* Error happened. */
- printf("length < 0\n");
- goto next;
- } else {
- orp->rx_length[orp->rx_last] = length;
- }
-
- /* The next buffer will be used the next time, circularly */
- orp->rx_last++;
- orp->rx_last %= NR_RX_BUFS;
-
- orp->or_got_int = TRUE;
- }
-next:
- if (events) {
- printf("Unknown event: 0x%x\n", events);
- }
-
- /* Acknowledge to the card that the events have been processed. After
- * this the card will assume we have processed any buffer which were in
- * use for this event. */
- hermes_write_reg (hw, HERMES_EVACK, evstat);
-
- evstat = hermes_read_reg (hw, HERMES_EVSTAT);
- if(evstat != 0 && !(evstat & HERMES_EV_TICK)) {
- goto beginning;
- }
-}
-
-/*****************************************************************************
- * or_alarm *
- * *
- * Will be called regularly to see whether the driver has crashed. If that *
- * condition is detected, reset the driver and card *
- *****************************************************************************/
-static void or_alarm(clock_t __unused stamp)
-{
- t_or *orp;
-
- /* Use a synchronous alarm instead of a watchdog timer. */
- sys_setalarm(sys_hz(), 0);
-
- orp = &or_state;
-
- if (orp->or_tx_busy == 0) {
- /* Assume that an idle system is alive */
- orp->or_tx_alive= TRUE;
- return;
- }
-
- if (orp->connected == 0) {
- orp->or_tx_alive= TRUE;
- return;
- }
- if (orp->or_tx_alive) {
- orp->or_tx_alive= FALSE;
- return;
- }
-
- printf("or_alarm: resetting card\n");
-
- orp->or_need_reset= TRUE;
- orp->or_got_int= TRUE;
- or_check_ints(orp);
-}
-
-/*****************************************************************************
- * or_send *
- * *
- * Send a packet, if possible *
- *****************************************************************************/
-static int or_send(struct netdriver_data *data, size_t size)
-{
- size_t p, data_len, data_off;
- int err;
- struct ethhdr *eh;
- t_or *orp;
- hermes_t *hw;
- struct hermes_tx_descriptor desc;
- struct header_struct hdr;
- u16_t txfid;
-
- /* We need space for the max packet size itself, plus an ethernet
- * header, plus 2 bytes so we can align the IP header on a
- * 32bit boundary, plus 1 byte so we can read in odd length
- * packets from the card, which has an IO granularity of 16
- * bits */
- static u8_t databuf[IEEE802_11_DATA_LEN + ETH_HLEN + 2 + 1];
-
- orp = &or_state;
- hw = &(orp->hw);
-
- /* Switch off interrupts. The card is accessable via 2 BAPs, one for
- * reading and one for writing. In theory these BAPs should be
- * independent, but in practice, the are not. By switching off the
- * interrupts of the card, the chances of one interfering with the
- * other should be less
- */
- /* ..except that this is not happening at all here. */
-
- txfid = orp->or_tx.or_txfid;
-
- if (orp->or_tx.ret_busy || orp->connected == 0) {
- /* there is no buffer in the card available */
- return SUSPEND;
- }
-
- /* Copy the data to be sent from the vector to the databuf */
- netdriver_copyin(data, 0, databuf, size);
-
- /* Zero out the rest of the buffer */
- memset(&databuf[size], 0, sizeof(databuf) - size);
-
- memset(&desc, 0, sizeof(desc));
- /* Reclaim the tx buffer once the data is sent (OK), or it is clear
- * that transmission failed (EX). Reclaiming means that we can reuse
- * the buffer again for transmission
- */
- desc.tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
- /* Actually, this reclaim bit is the only thing which needs to be set
- * in the descriptor
- */
- err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
- if (err) {
- printf("hermes_bap_pwrite() descriptor error:resetting card\n");
- /* When this happens, the card is quite confused: it will not
- * recover. Reset it
- */
- or_reset();
- return OK; /* pretend the packet was sent anyway.. */
- }
-
- eh = (struct ethhdr *) databuf;
- /* Encapsulate Ethernet-II frames */
- if (ntohs(eh->h_proto) > 1500) {
- /* Ethernet-II frame */
- data_len = size - ETH_HLEN;
- data_off = HERMES_802_3_OFFSET + sizeof (hdr);
-
- /* 802.3 header */
- memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
- memcpy(hdr.src, eh->h_src, ETH_ALEN);
- hdr.len = htons(data_len + ENCAPS_OVERHEAD);
-
- /* 802.2 header */
- memcpy(&hdr.dsap, &encaps_hdr, sizeof (encaps_hdr));
- hdr.ethertype = eh->h_proto;
-
- err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
- txfid, HERMES_802_3_OFFSET);
- if (err) {
- printf("%s: Error %d writing packet header to BAP\n",
- orp->or_name, err);
- return OK; /* pretend the packet was sent anyway.. */
- }
-
- p = ETH_HLEN;
- } else {
- /* IEEE 802.3 frame */
- data_len = size + ETH_HLEN;
- data_off = HERMES_802_3_OFFSET;
- p = 0;
- }
-
- /* Round up for odd length packets */
- err = hermes_bap_pwrite(hw, USER_BAP, (void *) &(databuf[p]),
- RUP_EVEN(data_len), txfid, data_off);
- if (err) {
- printf("hermes_bap_pwrite(data): error %d\n", err);
- return OK; /* pretend the packet was sent anyway.. */
- }
-
- /* this should be before the docmd_wait. Cause otherwise the bit can
- * be cleared in the handler (if irq's not off) before it is set
- * and then 1 reset (ret_busy=false) is lost
- */
- orp->or_tx.ret_busy = TRUE;
- orp->or_tx_busy++;
-
- /* Send the packet which was constructed in txfid */
- err = hermes_docmd_wait (hw, HERMES_CMD_TX | HERMES_CMD_RECL,
- txfid, NULL);
- if (err) {
- printf("hermes_docmd_wait(TX|RECL): error %d\n", err);
- /* Mark the buffer as available again */
- orp->or_tx.ret_busy = FALSE;
- orp->or_tx_busy--;
- return OK; /* pretend the packet was sent anyway.. */
- }
-
- return OK;
-}
-
-/*****************************************************************************
- * or_ev_info *
- * *
- * Process information which comes in from the card *
- *****************************************************************************/
-static void or_ev_info(t_or * orp)
-{
- struct hermes_tallies_frame tallies;
- struct hermes_linkstatus linkstatus;
- u16_t newstatus;
- u16_t infofid;
- int err, len, type;
- hermes_t *hw = &orp->hw;
-
- struct {
- u16_t len;
- u16_t type;
- } info;
-
- infofid = hermes_read_reg (hw, HERMES_INFOFID);
- err = hermes_bap_pread (hw, IRQ_BAP, &info, sizeof (info), infofid,
- 0);
- if (err) {
- printf ("%s: error %d reading info frame.\n", orp->or_name,
- err);
- return;
- }
-
- len = HERMES_RECLEN_TO_BYTES (info.len);
- type = info.type;
-
- switch (type) {
- case HERMES_INQ_TALLIES:
- if (len > sizeof(tallies)) {
- printf("%s: Tallies frame too long ", orp->or_name);
- printf("(%d bytes)\n", len);
- len = sizeof (tallies);
- }
- hermes_read_words(hw, HERMES_DATA1, (void *)&tallies, len / 2);
- /* TODO: do something with the tallies structure */
- break;
-
- case HERMES_INQ_LINKSTATUS:
- if (len != sizeof(linkstatus)) {
- printf("%s: Unexpected size for linkstatus ",
- orp->or_name);
- printf("frame (%d bytes)\n", len);
- }
-
- hermes_read_words(hw, HERMES_DATA1, (void *)&linkstatus,
- len / 2);
- newstatus = linkstatus.linkstatus;
-
- if ((newstatus == HERMES_LINKSTATUS_CONNECTED)
- || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
- || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE)) {
- orp->connected = 1;
- orp->or_send_int = TRUE;
- orp->or_got_int = TRUE;
- }
- else if ((newstatus == HERMES_LINKSTATUS_NOT_CONNECTED)
- || (newstatus == HERMES_LINKSTATUS_DISCONNECTED)
- || (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE)
- || (newstatus == HERMES_LINKSTATUS_ASSOC_FAILED)) {
- orp->connected = 0;
- }
-
- if (newstatus != orp->last_linkstatus)
- print_linkstatus(orp, newstatus);
-
- orp->last_linkstatus = newstatus;
-
- break;
- default:
- printf("%s:Unknown information frame received (type %04x).\n",
- orp->or_name, type);
- break;
- }
-}
-
-/*****************************************************************************
- * or_print_linkstatus *
- * *
- * Process information which comes in from the card *
- *****************************************************************************/
-static void print_linkstatus(t_or * orp, u16_t status)
-{
- int err;
- u16_t d;
- char *s;
- hermes_t *hw = &(orp->hw);
-
- switch (status) {
- case HERMES_LINKSTATUS_NOT_CONNECTED:
- s = "Not Connected";
- break;
- case HERMES_LINKSTATUS_CONNECTED:
- s = "Connected";
- break;
- case HERMES_LINKSTATUS_DISCONNECTED:
- s = "Disconnected";
- break;
- case HERMES_LINKSTATUS_AP_CHANGE:
- s = "AP Changed";
- break;
- case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
- s = "AP Out of Range";
- break;
- case HERMES_LINKSTATUS_AP_IN_RANGE:
- s = "AP In Range";
- break;
- case HERMES_LINKSTATUS_ASSOC_FAILED:
- s = "Association Failed";
- break;
- default:
- s = "UNKNOWN";
- }
-
- printf("%s: link status: %s, ", orp->or_name, s);
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &d);
- if (err) {
- printf("error %d\n", err);
- return;
- }
- printf("channel: %d, freq: %ld MHz\n", d, (channel_frequency[d-1]));
-}
-
-/*****************************************************************************
- * or_check_ints *
- * *
- * Process events which have been postponed in the interrupt handler *
- *****************************************************************************/
-static void or_check_ints(t_or * orp)
-{
- if (!orp->or_got_int)
- return;
- orp->or_got_int = FALSE;
-
- if (orp->or_need_reset)
- or_reset();
-
- if (orp->rx_first != orp->rx_last)
- netdriver_recv();
-
- if (orp->or_send_int)
- netdriver_send();
-}
-
-/*****************************************************************************
- * is_ethersnap *
- * *
- * is there an LLC and SNAP header in the ethernet packet? The inet task *
- * isn't very interested in it... *
- *****************************************************************************/
-static int is_ethersnap(struct header_struct *hdr)
-{
- /* We de-encapsulate all packets which, a) have SNAP headers
- * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
- * and where b) the OUI of the SNAP header is 00:00:00 or
- * 00:00:f8 - we need both because different APs appear to use
- * different OUIs for some reason */
- return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0)
- && ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );
-}
-
-/*****************************************************************************
- * or_recv *
- * *
- * Receive a packet, if one is available *
- *****************************************************************************/
-static ssize_t or_recv(struct netdriver_data *data, size_t max)
-{
- t_or *orp;
- u8_t *databuf;
- size_t length;
-
- orp = &or_state;
-
- if (orp->rx_first == orp->rx_last)
- return SUSPEND;
-
- /* store the pointer to this data in databuf */
- databuf = &(orp->rx_buf[orp->rx_first][0]);
- length = orp->rx_length[orp->rx_first];
-
- orp->rxfid[orp->rx_first] = NO_FID;
- orp->rx_length[orp->rx_first] = 0;
-
- /* Next time, the next buffer with data will be retrieved */
- orp->rx_first++;
- orp->rx_first %= NR_RX_BUFS;
-
- if (length > max)
- length = max;
-
- netdriver_copyout(data, 0, databuf, length);
-
- orp->or_stat.ets_packetR++;
-
- return length;
-}
-
-/*****************************************************************************
- * or_get_recvd_packet *
- * *
- * The card has received data. Retrieve the data from the card and put it *
- * in a buffer in the driver (in the orp structure) *
- *****************************************************************************/
-static int or_get_recvd_packet(t_or *orp, u16_t rxfid, u8_t *databuf)
-{
- struct hermes_rx_descriptor desc;
- hermes_t *hw;
- struct header_struct hdr;
- int err, length, offset;
- u16_t status;
-
- memset(databuf, 0, IEEE802_11_FRAME_LEN);
-
- hw = &(orp->hw);
-
- /* Read the data from the buffer in the card which holds the data.
- * First get the descriptor which will tell us whether the packet is
- * healthy*/
- err = hermes_bap_pread (hw, IRQ_BAP, &desc, sizeof (desc), rxfid, 0);
- if (err) {
- printf("Orinoco: error %d reading Rx descriptor. "
- "Frame dropped\n", err);
- orp->or_stat.ets_recvErr++;
- return -1;
- }
-
- status = desc.status;
-
- if (status & HERMES_RXSTAT_ERR) {
- if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
- printf("Error reading Orinoco Rx descriptor.Dropped");
- } else {
- orp->or_stat.ets_CRCerr++;
- printf("Orinoco: Bad CRC on Rx. Frame dropped\n");
- }
- orp->or_stat.ets_recvErr++;
- return -1;
- }
-
- /* For now we ignore the 802.11 header completely, assuming
- that the card's firmware has handled anything vital. The only
- thing we want to know is the length of the received data */
- err = hermes_bap_pread (hw, IRQ_BAP, &hdr, sizeof (hdr),
- rxfid, HERMES_802_3_OFFSET);
-
- if (err) {
- printf("Orinoco: error %d reading frame header. "
- "Frame dropped\n", err);
- orp->or_stat.ets_recvErr++;
- return -1;
- }
-
- length = ntohs (hdr.len);
-
- /* Sanity checks */
- if (length < 3) {
- /* No for even an 802.2 LLC header */
- printf("Orinoco: error in frame length: length = %d\n",
- length);
- /* orp->or_stat.ets_recvErr++; */
- return -1;
- }
-
- if (length > IEEE802_11_DATA_LEN) {
- printf("Orinoco: Oversized frame received (%d bytes)\n",
- length);
- orp->or_stat.ets_recvErr++;
- return -1;
- }
-
- length += sizeof (struct ethhdr);
- offset = HERMES_802_3_OFFSET;
-
- /* Read the interesting parts of the data to the drivers memory. This
- * would be everything from the 802.3 layer and up */
- err = hermes_bap_pread (hw,
- IRQ_BAP, (void *) databuf, RUP_EVEN (length),
- rxfid, offset);
-
- if (err) {
- printf("Orinoco: error doing hermes_bap_pread()\n");
- orp->or_stat.ets_recvErr++;
- return -1;
- }
-
- /* Some types of firmware give us the SNAP and OUI headers. Remove
- * these.
- */
- if (is_ethersnap(&hdr)) {
- length -= 8;
-
- memcpy(databuf + ETH_ALEN * 2,
- databuf + sizeof(struct header_struct) - 2,
- length - ETH_ALEN * 2);
- }
-
- if(length<60) length=60;
-
- return length;
-}
-
-/*****************************************************************************
- * or_stat *
- * *
- * Return the statistics structure. The statistics aren't updated until now, *
- * so this won't return much interesting yet. *
- *****************************************************************************/
-static void or_stat(eth_stat_t *stat)
-{
- memcpy(stat, &or_state.or_stat, sizeof(*stat));
-}
+++ /dev/null
-/*
- * orinoco.h
- *
- * This file contains the most important structure for the driver: t_or
- * and some configurable definitions
- *
- * Created by Stevens Le Blond <slblond@few.vu.nl>
- * and Michael Valkering <mjvalker@cs.vu.nl>
- */
-
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-
-#define NR_RX_BUFS 32
-
-#define LARGE_KEY_LENGTH 13
-#define IW_ESSID_MAX_SIZE 32
-#define IOVEC_NR 16
-#define OR_NAME "orinoco#n"
-
-#define IEEE802_11_HLEN 30
-#define IEEE802_11_DATA_LEN (2304)
-#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN + 3)
-
-typedef struct s_or
-{
- int or_irq;
- int or_hook_id;
- int or_link_up;
- int or_got_int;
- int or_tx_alive;
- int or_send_int;
- int or_need_reset;
- int or_report_link;
-
- /* Events */
- int connected;
- int last_linkstatus;
-
- /* Rx */
- phys_bytes or_rx_buf;
- u16_t rxfid[NR_RX_BUFS];
- int rx_length[NR_RX_BUFS];
- u8_t rx_buf[NR_RX_BUFS][IEEE802_11_FRAME_LEN];
- int rx_first;
- int rx_last;
- int rx_current;
-
- /* Tx */
- u16_t or_nicbuf_size;
- int or_tx_head;
- int or_tx_tail;
- int or_tx_busy;
-
- struct
- {
- int ret_busy;
- u16_t or_txfid;
- } or_tx;
-
- eth_stat_t or_stat;
- char or_name[sizeof(OR_NAME)];
- hermes_t hw;
-} t_or;
{ .label = "fxp", .policy_str = "restart" },
{ .label = "lance", .policy_str = "restart" },
{ .label = "lan8710a", .policy_str = "restart" },
- { .label = "orinoco", .policy_str = "restart" },
{ .label = "rtl8139", .policy_str = "restart" },
{ .label = "rtl8169", .policy_str = "restart" },
{ .label = "uds", .policy_str = "reset" },