⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prism2.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************Etherboot -  BOOTP/TFTP Bootstrap ProgramPrism2 NIC driver for EtherbootWritten by Michael Brown of Fen Systems Ltd$Id: prism2.c,v 1.5 2003/03/18 02:45:11 ebiederm Exp $***************************************************************************//* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. *//* to get some global routines like printf */#include "etherboot.h"/* to get the interface to the body of the program */#include "nic.h"/* to get the PCI support functions, if this is a PCI NIC */#include "pci.h"/* * Hard-coded SSID * Leave blank in order to connect to any available SSID */static const char hardcoded_ssid[] = "";/* * Maximum number of info packets to wait for on a join attempt. * Some APs (including the Linksys WAP11) will send a "you are disconnected" packet * before sending the "you are connected" packet, if the card has previously been * attached to the AP. * * 2 is probably a sensible value, but YMMV. */#define MAX_JOIN_INFO_COUNT 2/* * Type of Prism2 interface to support * If not already defined, select PLX */#ifndef WLAN_HOSTIF#define WLAN_HOSTIF WLAN_PLX#endif/* * Include wlan_compat, p80211 and hfa384x header files from Linux Prism2 driver * We need to hack some defines in order to avoid compiling kernel-specific routines */#define __LINUX_WLAN__#undef __KERNEL__#define __I386__#include "wlan_compat.h"#include "p80211hdr.h"#include "hfa384x.h"#define BAP_TIMEOUT ( 5000 )/* * A few hacks to make the coding environment more Linux-like.  This makes it somewhat * quicker to convert code from the Linux Prism2 driver. */#include <errno.h>#include "timer.h"#define __le16_to_cpu(x) (x)#define __le32_to_cpu(x) (x)#define __cpu_to_le16(x) (x)#define __cpu_to_le32(x) (x)/* * PLX9052 PCI register offsets * Taken from PLX9052 datasheet available from http://www.plxtech.com/download/9052/databook/9052db-20.pdf */#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 )/* * PCMCIA CIS types * Taken from cistpl.h in pcmcia-cs */#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 )/* * Prism2 constants * Taken from prism2sta.c in linux-wlan-ng */#define COR_OFFSET      ( 0x3e0 )   /* COR attribute offset of Prism2 PC card */#define COR_VALUE       ( 0x41 )    /* Enable PC card with irq in level trigger (but interrupts disabled) *//* NIC specific static variables *//* The hfa384x_t structure is used extensively in the Linux driver but is ifdef'd out in our include since __KERNEL__ is not defined. * This is a dummy version that contains only the fields we are interested in. */typedef struct hfa384x{  UINT32 iobase;  UINT32 membase;  UINT16 lastcmd;  UINT16 status;         /* in host order */  UINT16 resp0;          /* in host order */  UINT16 resp1;          /* in host order */  UINT16 resp2;          /* in host order */  UINT8  bssid[WLAN_BSSID_LEN];} hfa384x_t;/* The global instance of the hardware (i.e. where we store iobase and membase, in the absence of anywhere better to put them */static hfa384x_t hw_global = {  0, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0}};/* * 802.11 headers in addition to those in hfa384x_tx_frame_t (LLC and SNAP) * Taken from p80211conv.h */typedef struct wlan_llc{  UINT8   dsap                            __WLAN_ATTRIB_PACK__;  UINT8   ssap                            __WLAN_ATTRIB_PACK__;  UINT8   ctl                             __WLAN_ATTRIB_PACK__;} __WLAN_ATTRIB_PACK__ wlan_llc_t;static const wlan_llc_t wlan_llc_snap = { 0xaa, 0xaa, 0x03 }; /* LLC header indicating SNAP (?) */#define WLAN_IEEE_OUI_LEN 3typedef struct wlan_snap{  UINT8   oui[WLAN_IEEE_OUI_LEN]          __WLAN_ATTRIB_PACK__;  UINT16  type                            __WLAN_ATTRIB_PACK__;} __WLAN_ATTRIB_PACK__ wlan_snap_t;typedef struct wlan_80211hdr{  wlan_llc_t llc;  wlan_snap_t snap;} wlan_80211hdr_t;/* * Function prototypes */#if (WLAN_HOSTIF == WLAN_PLX)static int prism2_find_plx ( hfa384x_t *hw, struct pci_device *p );#elif (WLAN_HOSTIF == WLAN_PCI)static int prism2_find_pci ( hfa384x_t *hw, struct pci_device *p );#endif/* * Hardware-level hfa384x functions * These are based on the ones in hfa384x.h (which are ifdef'd out since __KERNEL__ is not defined). * Basically, these functions are the result of hand-evaluating all the ifdefs and defines in the hfa384x.h versions.  *//* Retrieve the value of one of the MAC registers. */static inline UINT16 hfa384x_getreg( hfa384x_t *hw, UINT reg ){#if (WLAN_HOSTIF == WLAN_PLX)  return inw ( hw->iobase + reg );#elif (WLAN_HOSTIF == WLAN_PCI)  return readw ( hw->membase + reg );#endif}/* Set the value of one of the MAC registers. */static inline void hfa384x_setreg( hfa384x_t *hw, UINT16 val, UINT reg ){#if (WLAN_HOSTIF == WLAN_PLX)  outw ( val, hw->iobase + reg );#elif (WLAN_HOSTIF == WLAN_PCI)  writew ( val, hw->membase + reg );#endif  return;}/*  * Noswap versions * Etherboot is i386 only, so swap and noswap are the same... */static inline UINT16 hfa384x_getreg_noswap( hfa384x_t *hw, UINT reg ){  return hfa384x_getreg ( hw, reg );}static inline void hfa384x_setreg_noswap( hfa384x_t *hw, UINT16 val, UINT reg ){  hfa384x_setreg ( hw, val, reg );}/* * Low-level hfa384x functions * These are based on the ones in hfa384x.c, modified to work in the Etherboot environment. *//* * hfa384x_docmd_wait * * Waits for availability of the Command register, then * issues the given command.  Then polls the Evstat register * waiting for command completion. * Arguments: *       hw              device structure *       cmd             Command in host order *       parm0           Parameter0 in host order *       parm1           Parameter1 in host order *       parm2           Parameter2 in host order * Returns: *       0               success *       >0              command indicated error, Status and Resp0-2 are *                       in hw structure. */static int hfa384x_docmd_wait( hfa384x_t *hw, UINT16 cmd, UINT16 parm0, UINT16 parm1, UINT16 parm2){  UINT16 reg = 0;  UINT16 counter = 0;    /* wait for the busy bit to clear */	  counter = 0;  reg = hfa384x_getreg(hw, HFA384x_CMD);  while ( HFA384x_CMD_ISBUSY(reg) && (counter < 10) ) {    reg = hfa384x_getreg(hw, HFA384x_CMD);    counter++;    udelay(10);  }  if (HFA384x_CMD_ISBUSY(reg)) {    printf("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg);    return -ETIMEDOUT;  }  /* busy bit clear, write command */  hfa384x_setreg(hw, parm0, HFA384x_PARAM0);  hfa384x_setreg(hw, parm1, HFA384x_PARAM1);  hfa384x_setreg(hw, parm2, HFA384x_PARAM2);  hw->lastcmd = cmd;  hfa384x_setreg(hw, cmd, HFA384x_CMD);    /* Now wait for completion */  counter = 0;  reg = hfa384x_getreg(hw, HFA384x_EVSTAT);  /* Initialization is the problem.  It takes about     100ms. "normal" commands are typically is about     200-400 us (I've never seen less than 200).  Longer     is better so that we're not hammering the bus. */  while ( !HFA384x_EVSTAT_ISCMD(reg) && (counter < 5000)) {    reg = hfa384x_getreg(hw, HFA384x_EVSTAT);    counter++;    udelay(200);  }  if ( ! HFA384x_EVSTAT_ISCMD(reg) ) {    printf("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg);    return -ETIMEDOUT;  }  /* Read status and response */  hw->status = hfa384x_getreg(hw, HFA384x_STATUS);  hw->resp0 = hfa384x_getreg(hw, HFA384x_RESP0);  hw->resp1 = hfa384x_getreg(hw, HFA384x_RESP1);  hw->resp2 = hfa384x_getreg(hw, HFA384x_RESP2);  hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK);  return HFA384x_STATUS_RESULT_GET(hw->status);}/* * Prepare BAP for access.  Assigns FID and RID, sets offset register * and waits for BAP to become available. * * Arguments: *	hw		device structure *	id		FID or RID, destined for the select register (host order) *	offset		An _even_ offset into the buffer for the given FID/RID. * Returns:  *	0		success */static int hfa384x_prepare_bap(hfa384x_t *hw, UINT16 id, UINT16 offset){  int result = 0;  UINT16 reg;  UINT16 i;  /* Validate offset, buf, and len */  if ( (offset > HFA384x_BAP_OFFSET_MAX) || (offset % 2) ) {    result = -EINVAL;  } else {    /* Write fid/rid and offset */    hfa384x_setreg(hw, id, HFA384x_SELECT0);    udelay(10);    hfa384x_setreg(hw, offset, HFA384x_OFFSET0);    /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */    i = 0; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -