prism2.c File Reference

#include <etherboot.h>
#include <nic.h>
#include <gpxe/pci.h>
#include <gpxe/ethernet.h>
#include "wlan_compat.h"
#include "p80211hdr.h"
#include "hfa384x.h"
#include <errno.h>

Go to the source code of this file.

Data Structures

struct  hfa384x
struct  wlan_llc
struct  wlan_snap
struct  wlan_80211hdr

Defines

#define MAX_JOIN_INFO_COUNT   2
#define WLAN_HOSTIF   WLAN_PLX
#define __LINUX_WLAN__
#define __I386__
#define BAP_TIMEOUT   ( 5000 )
#define __le16_to_cpu(x)   (x)
#define __le32_to_cpu(x)   (x)
#define __cpu_to_le16(x)   (x)
#define __cpu_to_le32(x)   (x)
#define hfa384x2host_16(n)   (__le16_to_cpu((UINT16)(n)))
#define hfa384x2host_32(n)   (__le32_to_cpu((UINT32)(n)))
#define host2hfa384x_16(n)   (__cpu_to_le16((UINT16)(n)))
#define host2hfa384x_32(n)   (__cpu_to_le32((UINT32)(n)))
#define PLX_LOCAL_CONFIG_REGISTER_BASE   ( PCI_BASE_ADDRESS_1 )
#define PLX_LOCAL_ADDRESS_SPACE_0_BASE   ( PCI_BASE_ADDRESS_2 )
#define PLX_LOCAL_ADDRESS_SPACE_1_BASE   ( PCI_BASE_ADDRESS_3 )
#define PLX_LOCAL_ADDRESS_SPACE_2_BASE   ( PCI_BASE_ADDRESS_4 )
#define PLX_LOCAL_ADDRESS_SPACE_3_BASE   ( PCI_BASE_ADDRESS_5 )
#define PRISM2_PLX_ATTR_MEM_BASE   ( PLX_LOCAL_ADDRESS_SPACE_0_BASE )
#define PRISM2_PLX_IO_BASE   ( PLX_LOCAL_ADDRESS_SPACE_1_BASE )
#define PRISM2_PCI_MEM_BASE   ( PCI_BASE_ADDRESS_0 )
#define CISTPL_VERS_1   ( 0x15 )
#define CISTPL_END   ( 0xff )
#define CIS_STEP   ( 2 )
#define CISTPL_HEADER_LEN   ( 2 * CIS_STEP )
#define CISTPL_LEN_OFF   ( 1 * CIS_STEP )
#define CISTPL_VERS_1_STR_OFF   ( 4 * CIS_STEP )
#define COR_OFFSET   ( 0x3e0 )
#define COR_VALUE   ( 0x41 )
#define WLAN_IEEE_OUI_LEN   3

Typedefs

typedef struct hfa384x hfa384x_t
typedef struct wlan_llc wlan_llc_t
typedef struct wlan_snap wlan_snap_t
typedef struct wlan_80211hdr wlan_80211hdr_t

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static UINT16 hfa384x_getreg (hfa384x_t *hw, UINT reg)
static void hfa384x_setreg (hfa384x_t *hw, UINT16 val, UINT reg)
static UINT16 hfa384x_getreg_noswap (hfa384x_t *hw, UINT reg)
static void hfa384x_setreg_noswap (hfa384x_t *hw, UINT16 val, UINT reg)
static int hfa384x_docmd_wait (hfa384x_t *hw, UINT16 cmd, UINT16 parm0, UINT16 parm1, UINT16 parm2)
static int hfa384x_prepare_bap (hfa384x_t *hw, UINT16 id, UINT16 offset)
static int hfa384x_copy_from_bap (hfa384x_t *hw, UINT16 id, UINT16 offset, void *buf, UINT len)
static int hfa384x_copy_to_bap (hfa384x_t *hw, UINT16 id, UINT16 offset, void *buf, UINT len)
static int hfa384x_cmd_access (hfa384x_t *hw, UINT16 write, UINT16 rid)
static int hfa384x_drvr_getconfig (hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
static int hfa384x_drvr_setconfig (hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
static int hfa384x_drvr_setconfig16 (hfa384x_t *hw, UINT16 rid, UINT16 *val)
static int hfa384x_wait_for_event (hfa384x_t *hw, UINT16 event_mask, UINT16 event_ack, int wait, int timeout, const char *descr)
static int prism2_poll (struct nic *nic, int retrieve)
static void prism2_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
static void prism2_disable (struct nic *nic __unused)
static void prism2_irq (struct nic *nic __unused, irq_action_t action __unused)
static int prism2_probe (struct nic *nic, hfa384x_t *hw)

Variables

static const char hardcoded_ssid [] = ""
static hfa384x_t hw_global
static const wlan_llc_t wlan_llc_snap = { 0xaa, 0xaa, 0x03 }
static struct nic_operations prism2_operations


Define Documentation

#define MAX_JOIN_INFO_COUNT   2

Definition at line 39 of file prism2.c.

Referenced by prism2_probe().

#define WLAN_HOSTIF   WLAN_PLX

Definition at line 46 of file prism2.c.

#define __LINUX_WLAN__

Definition at line 54 of file prism2.c.

#define __I386__

Definition at line 56 of file prism2.c.

#define BAP_TIMEOUT   ( 5000 )

Definition at line 60 of file prism2.c.

Referenced by hfa384x_prepare_bap().

#define __le16_to_cpu (  )     (x)

Definition at line 67 of file prism2.c.

#define __le32_to_cpu (  )     (x)

Definition at line 68 of file prism2.c.

#define __cpu_to_le16 (  )     (x)

Definition at line 69 of file prism2.c.

#define __cpu_to_le32 (  )     (x)

Definition at line 70 of file prism2.c.

#define hfa384x2host_16 (  )     (__le16_to_cpu((UINT16)(n)))

Definition at line 72 of file prism2.c.

Referenced by hfa384x_drvr_getconfig(), prism2_poll(), and prism2_probe().

#define hfa384x2host_32 (  )     (__le32_to_cpu((UINT32)(n)))

Definition at line 73 of file prism2.c.

Referenced by prism2_poll().

#define host2hfa384x_16 (  )     (__cpu_to_le16((UINT16)(n)))

Definition at line 74 of file prism2.c.

Referenced by hfa384x_drvr_setconfig(), hfa384x_drvr_setconfig16(), and prism2_transmit().

#define host2hfa384x_32 (  )     (__cpu_to_le32((UINT32)(n)))

Definition at line 75 of file prism2.c.

#define PLX_LOCAL_CONFIG_REGISTER_BASE   ( PCI_BASE_ADDRESS_1 )

Definition at line 82 of file prism2.c.

Referenced by prism2_find_plx().

#define PLX_LOCAL_ADDRESS_SPACE_0_BASE   ( PCI_BASE_ADDRESS_2 )

Definition at line 83 of file prism2.c.

#define PLX_LOCAL_ADDRESS_SPACE_1_BASE   ( PCI_BASE_ADDRESS_3 )

Definition at line 84 of file prism2.c.

#define PLX_LOCAL_ADDRESS_SPACE_2_BASE   ( PCI_BASE_ADDRESS_4 )

Definition at line 85 of file prism2.c.

#define PLX_LOCAL_ADDRESS_SPACE_3_BASE   ( PCI_BASE_ADDRESS_5 )

Definition at line 86 of file prism2.c.

#define PRISM2_PLX_ATTR_MEM_BASE   ( PLX_LOCAL_ADDRESS_SPACE_0_BASE )

Definition at line 88 of file prism2.c.

Referenced by prism2_find_plx().

#define PRISM2_PLX_IO_BASE   ( PLX_LOCAL_ADDRESS_SPACE_1_BASE )

Definition at line 89 of file prism2.c.

Referenced by prism2_find_plx().

#define PRISM2_PCI_MEM_BASE   ( PCI_BASE_ADDRESS_0 )

Definition at line 91 of file prism2.c.

#define CISTPL_VERS_1   ( 0x15 )

Definition at line 98 of file prism2.c.

Referenced by prism2_find_plx().

#define CISTPL_END   ( 0xff )

Definition at line 99 of file prism2.c.

Referenced by prism2_find_plx().

#define CIS_STEP   ( 2 )

Definition at line 101 of file prism2.c.

Referenced by prism2_find_plx().

#define CISTPL_HEADER_LEN   ( 2 * CIS_STEP )

Definition at line 102 of file prism2.c.

Referenced by prism2_find_plx().

#define CISTPL_LEN_OFF   ( 1 * CIS_STEP )

Definition at line 103 of file prism2.c.

Referenced by prism2_find_plx().

#define CISTPL_VERS_1_STR_OFF   ( 4 * CIS_STEP )

Definition at line 104 of file prism2.c.

Referenced by prism2_find_plx().

#define COR_OFFSET   ( 0x3e0 )

Definition at line 111 of file prism2.c.

Referenced by prism2_find_plx().

#define COR_VALUE   ( 0x41 )

Definition at line 112 of file prism2.c.

Referenced by prism2_find_plx().

#define WLAN_IEEE_OUI_LEN   3

Definition at line 151 of file prism2.c.


Typedef Documentation

typedef struct hfa384x hfa384x_t

typedef struct wlan_llc wlan_llc_t

typedef struct wlan_snap wlan_snap_t


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static UINT16 hfa384x_getreg ( hfa384x_t hw,
UINT  reg 
) [inline, static]

Definition at line 175 of file prism2.c.

References inw, hfa384x::iobase, hfa384x::membase, and readw.

Referenced by hfa384x_docmd_wait(), hfa384x_getreg_noswap(), hfa384x_prepare_bap(), hfa384x_wait_for_event(), prism2_poll(), prism2_probe(), and prism2_transmit().

00176 {
00177 #if (WLAN_HOSTIF == WLAN_PLX)
00178   return inw ( hw->iobase + reg );
00179 #elif (WLAN_HOSTIF == WLAN_PCI)
00180   return readw ( hw->membase + reg );
00181 #endif
00182 }

static void hfa384x_setreg ( hfa384x_t hw,
UINT16  val,
UINT  reg 
) [inline, static]

Definition at line 185 of file prism2.c.

References hfa384x::iobase, hfa384x::membase, outw, and writew.

Referenced by hfa384x_docmd_wait(), hfa384x_prepare_bap(), hfa384x_setreg_noswap(), hfa384x_wait_for_event(), prism2_poll(), and prism2_probe().

00186 {
00187 #if (WLAN_HOSTIF == WLAN_PLX)
00188   outw ( val, hw->iobase + reg );
00189 #elif (WLAN_HOSTIF == WLAN_PCI)
00190   writew ( val, hw->membase + reg );
00191 #endif
00192   return;
00193 }

static UINT16 hfa384x_getreg_noswap ( hfa384x_t hw,
UINT  reg 
) [inline, static]

Definition at line 199 of file prism2.c.

References hfa384x_getreg().

Referenced by hfa384x_copy_from_bap(), and hfa384x_copy_to_bap().

00200 {
00201   return hfa384x_getreg ( hw, reg );
00202 }

static void hfa384x_setreg_noswap ( hfa384x_t hw,
UINT16  val,
UINT  reg 
) [inline, static]

Definition at line 203 of file prism2.c.

References hfa384x_setreg().

Referenced by hfa384x_copy_to_bap().

00204 {
00205   hfa384x_setreg ( hw, val, reg );
00206 }

static int hfa384x_docmd_wait ( hfa384x_t hw,
UINT16  cmd,
UINT16  parm0,
UINT16  parm1,
UINT16  parm2 
) [static]

Definition at line 230 of file prism2.c.

References ETIMEDOUT, HFA384x_CMD, HFA384x_CMD_ISBUSY, HFA384x_EVACK, HFA384x_EVACK_CMD, HFA384x_EVSTAT, HFA384x_EVSTAT_ISCMD, hfa384x_getreg(), HFA384x_PARAM0, HFA384x_PARAM1, HFA384x_PARAM2, HFA384x_RESP0, HFA384x_RESP1, HFA384x_RESP2, hfa384x_setreg(), HFA384x_STATUS, HFA384x_STATUS_RESULT_GET, hfa384x::lastcmd, printf(), hfa384x::resp0, hfa384x::resp1, hfa384x::resp2, hfa384x::status, and udelay().

Referenced by hfa384x_cmd_access(), prism2_probe(), and prism2_transmit().

00231 {
00232   UINT16 reg = 0;
00233   UINT16 counter = 0;
00234   
00235   /* wait for the busy bit to clear */  
00236   counter = 0;
00237   reg = hfa384x_getreg(hw, HFA384x_CMD);
00238   while ( HFA384x_CMD_ISBUSY(reg) && (counter < 10) ) {
00239     reg = hfa384x_getreg(hw, HFA384x_CMD);
00240     counter++;
00241     udelay(10);
00242   }
00243   if (HFA384x_CMD_ISBUSY(reg)) {
00244     printf("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg);
00245     return -ETIMEDOUT;
00246   }
00247 
00248   /* busy bit clear, write command */
00249   hfa384x_setreg(hw, parm0, HFA384x_PARAM0);
00250   hfa384x_setreg(hw, parm1, HFA384x_PARAM1);
00251   hfa384x_setreg(hw, parm2, HFA384x_PARAM2);
00252   hw->lastcmd = cmd;
00253   hfa384x_setreg(hw, cmd, HFA384x_CMD);
00254   
00255   /* Now wait for completion */
00256   counter = 0;
00257   reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00258   /* Initialization is the problem.  It takes about
00259      100ms. "normal" commands are typically is about
00260      200-400 us (I've never seen less than 200).  Longer
00261      is better so that we're not hammering the bus. */
00262   while ( !HFA384x_EVSTAT_ISCMD(reg) && (counter < 5000)) {
00263     reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00264     counter++;
00265     udelay(200);
00266   }
00267   if ( ! HFA384x_EVSTAT_ISCMD(reg) ) {
00268     printf("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg);
00269     return -ETIMEDOUT;
00270   }
00271 
00272   /* Read status and response */
00273   hw->status = hfa384x_getreg(hw, HFA384x_STATUS);
00274   hw->resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
00275   hw->resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
00276   hw->resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
00277   hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK);
00278   return HFA384x_STATUS_RESULT_GET(hw->status);
00279 }

static int hfa384x_prepare_bap ( hfa384x_t hw,
UINT16  id,
UINT16  offset 
) [static]

Definition at line 292 of file prism2.c.

References BAP_TIMEOUT, EINVAL, HFA384x_BAP_OFFSET_MAX, hfa384x_getreg(), HFA384x_OFFSET0, HFA384x_OFFSET_ISBUSY, HFA384x_OFFSET_ISERR, HFA384x_SELECT0, hfa384x_setreg(), and udelay().

Referenced by hfa384x_copy_from_bap(), and hfa384x_copy_to_bap().

00293 {
00294   int result = 0;
00295   UINT16 reg;
00296   UINT16 i;
00297 
00298   /* Validate offset, buf, and len */
00299   if ( (offset > HFA384x_BAP_OFFSET_MAX) || (offset % 2) ) {
00300     result = -EINVAL;
00301   } else {
00302     /* Write fid/rid and offset */
00303     hfa384x_setreg(hw, id, HFA384x_SELECT0);
00304     udelay(10);
00305     hfa384x_setreg(hw, offset, HFA384x_OFFSET0);
00306     /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */
00307     i = 0; 
00308     do {
00309       reg = hfa384x_getreg(hw, HFA384x_OFFSET0);
00310       if ( i > 0 ) udelay(2);
00311       i++;
00312     } while ( i < BAP_TIMEOUT && HFA384x_OFFSET_ISBUSY(reg));
00313     if ( i >= BAP_TIMEOUT ) {
00314       /* failure */
00315       result = reg;
00316     } else if ( HFA384x_OFFSET_ISERR(reg) ){
00317       /* failure */
00318       result = reg;
00319     }
00320   }
00321   return result;
00322 }

static int hfa384x_copy_from_bap ( hfa384x_t hw,
UINT16  id,
UINT16  offset,
void *  buf,
UINT  len 
) [static]

Definition at line 336 of file prism2.c.

References HFA384x_DATA0, hfa384x_getreg_noswap(), hfa384x_prepare_bap(), and printf().

Referenced by hfa384x_drvr_getconfig(), prism2_poll(), prism2_probe(), and prism2_transmit().

00338 {
00339   int result = 0;
00340   UINT8 *d = (UINT8*)buf;
00341   UINT16 i;
00342   UINT16 reg = 0;
00343   
00344   /* Prepare BAP */
00345   result = hfa384x_prepare_bap ( hw, id, offset );
00346   if ( result == 0 ) {
00347     /* Read even(len) buf contents from data reg */
00348     for ( i = 0; i < (len & 0xfffe); i+=2 ) {
00349       *(UINT16*)(&(d[i])) = hfa384x_getreg_noswap(hw, HFA384x_DATA0);
00350     }
00351     /* If len odd, handle last byte */
00352     if ( len % 2 ){
00353       reg = hfa384x_getreg_noswap(hw, HFA384x_DATA0);
00354       d[len-1] = ((UINT8*)(&reg))[0];
00355     }
00356   }
00357   if (result) {
00358     printf ( "copy_from_bap(%#hx, %#hx, %d) failed, result=%#hx\n", id, offset, len, result);
00359   }
00360   return result;
00361 }

static int hfa384x_copy_to_bap ( hfa384x_t hw,
UINT16  id,
UINT16  offset,
void *  buf,
UINT  len 
) [static]

Definition at line 375 of file prism2.c.

References HFA384x_DATA0, hfa384x_getreg_noswap(), hfa384x_prepare_bap(), hfa384x_setreg_noswap(), and printf().

Referenced by hfa384x_drvr_setconfig(), and prism2_transmit().

00377 {
00378   int result = 0;
00379   UINT8 *d = (UINT8*)buf;
00380   UINT16 i;
00381   UINT16 savereg;
00382 
00383   /* Prepare BAP */
00384   result = hfa384x_prepare_bap ( hw, id, offset );
00385   if ( result == 0 ) {
00386     /* Write even(len) buf contents to data reg */
00387     for ( i = 0; i < (len & 0xfffe); i+=2 ) {
00388       hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), HFA384x_DATA0);
00389     }
00390     /* If len odd, handle last byte */
00391     if ( len % 2 ){
00392       savereg = hfa384x_getreg_noswap(hw, HFA384x_DATA0);
00393       result = hfa384x_prepare_bap ( hw, id, offset + (len & 0xfffe) );
00394       if ( result == 0 ) {
00395         ((UINT8*)(&savereg))[0] = d[len-1];
00396         hfa384x_setreg_noswap(hw, savereg, HFA384x_DATA0);
00397       }
00398     }
00399   }
00400   if (result) {
00401     printf ( "copy_to_bap(%#hx, %#hx, %d) failed, result=%#hx\n", id, offset, len, result);
00402   }
00403   return result;
00404 }

static int hfa384x_cmd_access ( hfa384x_t hw,
UINT16  write,
UINT16  rid 
) [inline, static]

static int hfa384x_drvr_getconfig ( hfa384x_t hw,
UINT16  rid,
void *  buf,
UINT16  len 
) [static]

Definition at line 437 of file prism2.c.

References hfa384x2host_16, hfa384x_cmd_access(), hfa384x_copy_from_bap(), printf(), and hfa384x_record::reclen.

Referenced by prism2_probe().

00438 {
00439   int result = 0;
00440   hfa384x_rec_t rec;
00441 
00442   /* Request read of RID */
00443   result = hfa384x_cmd_access( hw, 0, rid);
00444   if ( result ) {
00445     printf("Call to hfa384x_cmd_access failed\n");
00446     return -1;
00447   }
00448   /* Copy out record length */
00449   result = hfa384x_copy_from_bap( hw, rid, 0, &rec, sizeof(rec));
00450   if ( result ) {
00451     return -1;
00452   }
00453   /* Validate the record length */
00454   if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) {  /* note body len calculation in bytes */
00455     printf ( "RID len mismatch, rid=%#hx hlen=%d fwlen=%d\n", rid, len, (hfa384x2host_16(rec.reclen)-1)*2);
00456     return -1;
00457   }
00458   /* Copy out record data */
00459   result = hfa384x_copy_from_bap( hw, rid, sizeof(rec), buf, len);
00460   return result;
00461 }

static int hfa384x_drvr_setconfig ( hfa384x_t hw,
UINT16  rid,
void *  buf,
UINT16  len 
) [static]

Definition at line 510 of file prism2.c.

References hfa384x_cmd_access(), hfa384x_copy_to_bap(), host2hfa384x_16, printf(), hfa384x_record::reclen, and hfa384x_record::rid.

Referenced by hfa384x_drvr_setconfig16(), and prism2_probe().

00511 {
00512   int result = 0;
00513   hfa384x_rec_t rec;
00514 
00515   rec.rid = host2hfa384x_16(rid);
00516   rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */
00517   /* write the record header */
00518   result = hfa384x_copy_to_bap( hw, rid, 0, &rec, sizeof(rec));
00519   if ( result ) {
00520     printf("Failure writing record header\n");
00521     return -1;
00522   }
00523   /* write the record data (if there is any) */
00524   if ( len > 0 ) {
00525     result = hfa384x_copy_to_bap( hw, rid, sizeof(rec), buf, len);
00526     if ( result ) {
00527       printf("Failure writing record data\n");
00528       return -1;
00529     }
00530   }
00531   /* Trigger setting of record */
00532   result = hfa384x_cmd_access( hw, 1, rid);
00533   return result;
00534 }

static int hfa384x_drvr_setconfig16 ( hfa384x_t hw,
UINT16  rid,
UINT16 val 
) [static]

Definition at line 547 of file prism2.c.

References hfa384x_drvr_setconfig(), and host2hfa384x_16.

Referenced by prism2_probe().

00548 {
00549   UINT16 value;
00550   value = host2hfa384x_16(*val);
00551   return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(UINT16));
00552 }

static int hfa384x_wait_for_event ( hfa384x_t hw,
UINT16  event_mask,
UINT16  event_ack,
int  wait,
int  timeout,
const char *  descr 
) [static]

Definition at line 579 of file prism2.c.

References HFA384x_EVACK, HFA384x_EVSTAT, hfa384x_getreg(), hfa384x_setreg(), printf(), and udelay().

Referenced by prism2_probe(), and prism2_transmit().

00580 {
00581   UINT16 reg;
00582   int count = 0;
00583   
00584   do {
00585     reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00586     if ( count > 0 ) udelay(wait);
00587     count++;
00588   } while ( !(reg & event_mask) && count < timeout);
00589   if ( count >= timeout ) {
00590     printf("hfa384x: Timed out waiting for %s\n", descr);
00591     return 0; /* Return failure */
00592   }
00593   /* Acknowledge all events that we were waiting on */
00594   hfa384x_setreg(hw, reg & ( event_mask | event_ack ), HFA384x_EVACK);
00595   return reg;
00596 }

static int prism2_poll ( struct nic nic,
int  retrieve 
) [static]

Definition at line 601 of file prism2.c.

References hfa384x_rx_frame::data_len, ETH_HLEN, hfa384x2host_16, hfa384x2host_32, hfa384x_copy_from_bap(), HFA384x_EVACK, HFA384x_EVACK_RX_SET, HFA384x_EVSTAT, HFA384x_EVSTAT_ISRX, hfa384x_getreg(), HFA384x_RX_DATA_OFF, HFA384x_RXFID, hfa384x_setreg(), nic::packet, nic::packetlen, hfa384x_rx_frame::status, and hfa384x_rx_frame::time.

00602 {
00603   UINT16 reg;
00604   UINT16 rxfid;
00605   UINT16 result;
00606   hfa384x_rx_frame_t rxdesc;
00607   hfa384x_t *hw = &hw_global;
00608   
00609   /* Check for received packet */
00610   reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00611   if ( ! HFA384x_EVSTAT_ISRX(reg) ) {
00612     /* No packet received - return 0 */
00613     return 0;
00614   }
00615 
00616   if ( ! retrieve ) return 1;
00617 
00618   /* Acknowledge RX event */
00619   hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1), HFA384x_EVACK);
00620   /* Get RX FID */  
00621   rxfid = hfa384x_getreg(hw, HFA384x_RXFID);
00622   /* Get the descriptor (including headers) */
00623   result = hfa384x_copy_from_bap(hw, rxfid, 0, &rxdesc, sizeof(rxdesc));
00624   if ( result ) {
00625     return 0; /* fail */
00626   }
00627   /* Byte order convert once up front. */
00628   rxdesc.status = hfa384x2host_16(rxdesc.status);
00629   rxdesc.time = hfa384x2host_32(rxdesc.time);
00630   rxdesc.data_len = hfa384x2host_16(rxdesc.data_len);
00631 
00632   /* Fill in nic->packetlen */
00633   nic->packetlen = rxdesc.data_len;
00634   if ( nic->packetlen > 0 ) {
00635     /* Fill in nic->packet */
00636     /*
00637      * NOTE: Packets as received have an 8-byte header (LLC+SNAP(?)) terminating with the packet type.
00638      * Etherboot expects a 14-byte header terminating with the packet type (it ignores the rest of the
00639      * header), so we use a quick hack to achieve this.
00640      */
00641     result = hfa384x_copy_from_bap(hw, rxfid, HFA384x_RX_DATA_OFF,
00642                                    nic->packet + ETH_HLEN - sizeof(wlan_80211hdr_t), nic->packetlen);
00643     if ( result ) {
00644       return 0; /* fail */
00645     }
00646   }
00647   return 1; /* Packet successfully received */
00648 }

static void prism2_transmit ( struct nic nic,
const char *  d,
unsigned int  t,
unsigned int  s,
const char *  p 
) [static]

Definition at line 653 of file prism2.c.

References hfa384x_tx_frame::address1, hfa384x_tx_frame::address2, hfa384x_tx_frame::address3, hfa384x::bssid, hfa384x_tx_frame::data_len, hfa384x_tx_frame::frame_control, HFA384x_ALLOCFID, HFA384x_CMD_CMDCODE_SET, HFA384x_CMDCODE_ALLOC, HFA384x_CMDCODE_TX, hfa384x_copy_from_bap(), hfa384x_copy_to_bap(), hfa384x_docmd_wait(), HFA384x_DRVR_TXBUF_MAX, HFA384x_EVACK_INFO, HFA384x_EVSTAT_ALLOC, HFA384x_EVSTAT_ISTXEXC, HFA384x_EVSTAT_TX, HFA384x_EVSTAT_TXEXC, hfa384x_getreg(), HFA384x_TX_MACPORT_SET, HFA384x_TX_STRUCTYPE_SET, HFA384x_TX_TXEX_SET, HFA384x_TX_TXOK_SET, HFA384x_TXCOMPLFID, HFA384x_TXSTATUS_ISACKERR, HFA384x_TXSTATUS_ISAGEDERR, HFA384x_TXSTATUS_ISDISCON, HFA384x_TXSTATUS_ISFORMERR, HFA384x_TXSTATUS_ISRETRYERR, hfa384x_wait_for_event(), host2hfa384x_16, host2ieee16, htons, memcpy, memset(), nic::node_addr, printf(), wlan_80211hdr::snap, hfa384x_tx_frame::tx_control, wlan_snap::type, WLAN_ADDR_LEN, WLAN_FSTYPE_DATAONLY, WLAN_FTYPE_DATA, WLAN_SET_FC_FSTYPE, WLAN_SET_FC_FTYPE, and WLAN_SET_FC_TODS.

00659 {
00660   hfa384x_t *hw = &hw_global;
00661   hfa384x_tx_frame_t txdesc;
00662   wlan_80211hdr_t p80211hdr = { wlan_llc_snap, {{0,0,0},0} };
00663   UINT16 fid;
00664   UINT16 status;
00665   int result;
00666 
00667   // Request FID allocation
00668   result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC), HFA384x_DRVR_TXBUF_MAX, 0, 0);
00669   if (result != 0) {
00670     printf("hfa384x: Tx FID allocate command failed: Aborting transmit..\n");
00671     return;
00672   }
00673   if ( !hfa384x_wait_for_event(hw, HFA384x_EVSTAT_ALLOC, HFA384x_EVACK_INFO, 10, 50, "Tx FID to be allocated\n" ) ) return;
00674   fid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
00675 
00676   /* Build Tx frame structure */
00677   memset(&txdesc, 0, sizeof(txdesc));
00678   txdesc.tx_control = host2hfa384x_16( HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | 
00679                                        HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1) );
00680   txdesc.frame_control =  host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
00681                                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY) |
00682                                        WLAN_SET_FC_TODS(1) );
00683   memcpy(txdesc.address1, hw->bssid, WLAN_ADDR_LEN);
00684   memcpy(txdesc.address2, nic->node_addr, WLAN_ADDR_LEN);
00685   memcpy(txdesc.address3, d, WLAN_ADDR_LEN);
00686   txdesc.data_len = host2hfa384x_16( sizeof(txdesc) + sizeof(p80211hdr) + s );
00687   /* Set up SNAP header */
00688   /* Let OUI default to RFC1042 (0x000000) */
00689   p80211hdr.snap.type = htons(t);
00690   
00691   /* Copy txdesc, p80211hdr and payload parts to FID */
00692   result = hfa384x_copy_to_bap(hw, fid, 0, &txdesc, sizeof(txdesc));
00693   if ( result ) return; /* fail */
00694   result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc), &p80211hdr, sizeof(p80211hdr) );
00695   if ( result ) return; /* fail */
00696   result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc) + sizeof(p80211hdr), (UINT8*)p, s );
00697   if ( result ) return; /* fail */
00698 
00699   /* Issue Tx command */
00700   result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX), fid, 0, 0);
00701   if ( result != 0 ) {
00702     printf("hfa384x: Transmit failed with result %#hx.\n", result);
00703     return;
00704   }
00705   
00706   /* Wait for transmit completion (or exception) */
00707   result = hfa384x_wait_for_event(hw, HFA384x_EVSTAT_TXEXC | HFA384x_EVSTAT_TX, HFA384x_EVACK_INFO,
00708                                   200, 500, "Tx to complete\n" );
00709   if ( !result ) return; /* timeout failure */
00710   if ( HFA384x_EVSTAT_ISTXEXC(result) ) {
00711     fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
00712     printf ( "Tx exception occurred with fid %#hx\n", fid );
00713     result = hfa384x_copy_from_bap(hw, fid, 0, &status, sizeof(status));
00714     if ( result ) return; /* fail */
00715     printf("hfa384x: Tx error occurred (status %#hx):\n", status);
00716     if ( HFA384x_TXSTATUS_ISACKERR(status) ) { printf(" ...acknowledgement error\n"); }
00717     if ( HFA384x_TXSTATUS_ISFORMERR(status) ) { printf(" ...format error\n"); }
00718     if ( HFA384x_TXSTATUS_ISDISCON(status) ) { printf(" ...disconnected error\n"); }
00719     if ( HFA384x_TXSTATUS_ISAGEDERR(status) ) { printf(" ...AGED error\n"); }
00720     if ( HFA384x_TXSTATUS_ISRETRYERR(status) ) { printf(" ...retry error\n"); }
00721     return; /* fail */
00722   }
00723 }

static void prism2_disable ( struct nic *nic  __unused  )  [static]

Definition at line 728 of file prism2.c.

Referenced by prism2_pci_disable(), and prism2_plx_disable().

00728                                                         {
00729   /* put the card in its initial state */
00730 }

static void prism2_irq ( struct nic *nic  __unused,
irq_action_t action  __unused 
) [static]

Definition at line 735 of file prism2.c.

References DISABLE, ENABLE, and FORCE.

00736 {
00737   switch ( action ) {
00738   case DISABLE :
00739     break;
00740   case ENABLE :
00741     break;
00742   case FORCE :
00743     break;
00744   }
00745 }

static int prism2_probe ( struct nic nic,
hfa384x_t hw 
) [static]

Definition at line 761 of file prism2.c.

References hfa384x::bssid, DBG, eth_ntoa(), hfa384x_InfFrame::framelen, hardcoded_ssid, hfa384x2host_16, HFA384x_CMD_CMDCODE_SET, HFA384x_CMD_MACPORT_SET, HFA384x_CMDCODE_ENABLE, HFA384x_CMDCODE_INIT, HFA384x_CNFAUTHENTICATION_OPENSYSTEM, hfa384x_copy_from_bap(), hfa384x_docmd_wait(), hfa384x_drvr_getconfig(), hfa384x_drvr_setconfig(), hfa384x_drvr_setconfig16(), HFA384x_EVACK, HFA384x_EVSTAT_INFO, hfa384x_getreg(), HFA384x_INFOFID, HFA384x_INTEN, HFA384x_IT_LINKSTATUS, HFA384x_LINK_CONNECTED, HFA384x_RID_CNFAUTHENTICATION, HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, HFA384x_RID_CNFMAXDATALEN, HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, HFA384x_RID_CNFPORTTYPE, HFA384x_RID_CURRENTBSSID, HFA384x_RID_TXRATECNTL, hfa384x_setreg(), hfa384x_wait_for_event(), hfa384x_InfFrame::info, hfa384x_InfFrame::infotype, nic::irqno, hfa384x_LinkStatus::linkstatus, hfa384x_infodata::linkstatus, MAX_JOIN_INFO_COUNT, memset(), nic::nic_op, nic::node_addr, printf(), WLAN_BSSID_LEN, and WLAN_DATA_MAXLEN.

Referenced by prism2_pci_probe(), and prism2_plx_probe().

00761                                                            {
00762   int result;
00763   UINT16 tmp16 = 0;
00764   UINT16 infofid;
00765   hfa384x_InfFrame_t inf;
00766   char ssid[HFA384x_RID_CNFDESIREDSSID_LEN];
00767   int info_count = 0;
00768 
00769   nic->irqno  = 0;
00770 
00771   /* Initialize card */
00772   result = hfa384x_docmd_wait(hw, HFA384x_CMDCODE_INIT, 0,0,0); /* Send initialize command */
00773   if ( result ) printf ( "Initialize command returned %#hx\n", result );
00774   hfa384x_setreg(hw, 0, HFA384x_INTEN); /* Disable interrupts */
00775   hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); /* Acknowledge any spurious events */
00776 
00777   DBG ( "MAC address %s\n", eth_ntoa ( nic->node_addr ) );
00778 
00779   /* Retrieve MAC address (and fill out nic->node_addr) */
00780   hfa384x_drvr_getconfig ( hw, HFA384x_RID_CNFOWNMACADDR, nic->node_addr, HFA384x_RID_CNFOWNMACADDR_LEN );
00781 
00782   /* Prepare card for autojoin */
00783   /* This procedure is reverse-engineered from a register-level trace of the Linux driver's join process */
00784   tmp16 = WLAN_DATA_MAXLEN; /* Set maximum data length */
00785   result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, &tmp16);
00786   if ( result ) printf ( "Set Max Data Length command returned %#hx\n", result );
00787   tmp16 = 0x000f; /* Set transmit rate(?) */
00788   result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, &tmp16);
00789   if ( result ) printf ( "Set Transmit Rate command returned %#hx\n", result );
00790   tmp16 = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; /* Set authentication type to OpenSystem */
00791   result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, &tmp16);
00792   if ( result ) printf ( "Set Authentication Type command returned %#hx\n", result );
00793   /* Set SSID */
00794   memset(ssid, 0, HFA384x_RID_CNFDESIREDSSID_LEN);
00795   for ( tmp16=0; tmp16<sizeof(hardcoded_ssid); tmp16++ ) { ssid[2+tmp16] = hardcoded_ssid[tmp16]; }
00796   ssid[0] = sizeof(hardcoded_ssid) - 1; /* Ignore terminating zero */
00797   result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, ssid, HFA384x_RID_CNFDESIREDSSID_LEN); /* Set the SSID */
00798   if ( result ) printf ( "Set SSID command returned %#hx\n", result );
00799   tmp16 = 1; /* Set port type to ESS port */
00800   result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, &tmp16);
00801   if ( result ) printf ( "Set port type command returned %#hx\n", result );
00802   /* Enable card */
00803   result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | HFA384x_CMD_MACPORT_SET(0), 0,0,0);
00804   if ( result ) printf ( "Enable command returned %#hx\n", result );
00805 
00806   do {
00807     /* Increment info_count, abort if too many attempts.
00808      * See comment next to definition of MAX_JOIN_INFO_COUNT for explanation.
00809      */
00810     info_count++;
00811     if ( info_count > MAX_JOIN_INFO_COUNT ) {
00812       printf ( "Too many failed attempts - aborting\n" );
00813       return 0;
00814     }
00815 
00816     /* Wait for info frame to indicate link status */
00817     if ( sizeof(hardcoded_ssid) == 1 ) {
00818       /* Empty SSID => join to any SSID */
00819       printf ( "Attempting to autojoin to any available access point (attempt %d)...", info_count );
00820     } else {
00821       printf ( "Attempting to autojoin to SSID %s (attempt %d)...", &ssid[2], info_count );
00822     }
00823     
00824     if ( !hfa384x_wait_for_event(hw, HFA384x_EVSTAT_INFO, 0, 1000, 2000, "Info event" ) ) return 0;
00825     printf("done\n");
00826     infofid = hfa384x_getreg(hw, HFA384x_INFOFID);
00827     /* Retrieve the length */
00828     result = hfa384x_copy_from_bap( hw, infofid, 0, &inf.framelen, sizeof(UINT16));
00829     if ( result ) return 0; /* fail */
00830     inf.framelen = hfa384x2host_16(inf.framelen);
00831     /* Retrieve the rest */
00832     result = hfa384x_copy_from_bap( hw, infofid, sizeof(UINT16),
00833                                     &(inf.infotype), inf.framelen * sizeof(UINT16));
00834     if ( result ) return 0; /* fail */
00835     if ( inf.infotype != HFA384x_IT_LINKSTATUS ) {
00836       /* Not a Link Status info frame: die */
00837       printf ( "Unexpected info frame type %#hx (not LinkStatus type)\n", inf.infotype );
00838       return 0;
00839     }
00840     inf.info.linkstatus.linkstatus = hfa384x2host_16(inf.info.linkstatus.linkstatus);
00841     if ( inf.info.linkstatus.linkstatus != HFA384x_LINK_CONNECTED ) {
00842       /* Link not connected - retry */
00843       printf ( "Link not connected (status %#hx)\n", inf.info.linkstatus.linkstatus );
00844     }
00845   } while ( inf.info.linkstatus.linkstatus != HFA384x_LINK_CONNECTED );
00846     
00847   /* Retrieve BSSID and print Connected message */
00848   result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CURRENTBSSID, hw->bssid, WLAN_BSSID_LEN);
00849 
00850   DBG ( "Link connected (BSSID %s - ", eth_ntoa ( hw->bssid ) );
00851   DBG ( " MAC address %s)\n", eth_ntoa (nic->node_addr ) );
00852   
00853   /* point to NIC specific routines */
00854   nic->nic_op   = &prism2_operations;
00855   return 1;
00856 }


Variable Documentation

const char hardcoded_ssid[] = "" [static]

Definition at line 28 of file prism2.c.

Referenced by prism2_probe().

hfa384x_t hw_global [static]

Initial value:

 {
  0, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0}
}

Definition at line 133 of file prism2.c.

Referenced by prism2_pci_probe(), and prism2_plx_probe().

const wlan_llc_t wlan_llc_snap = { 0xaa, 0xaa, 0x03 } [static]

Definition at line 149 of file prism2.c.

Initial value:

 {
        .connect        = dummy_connect,
        .poll           = prism2_poll,
        .transmit       = prism2_transmit,
        .irq            = prism2_irq,
}

Definition at line 750 of file prism2.c.


Generated on Tue Apr 6 20:01:37 2010 for gPXE by  doxygen 1.5.7.1