Added a whole bunch of stuff for download. Also added code to prism2mgmt.c

to be able to turn monitor mode OFF.
This commit is contained in:
mark 2000-01-31 20:05:16 +00:00
parent 333e2cb4db
commit bb4230aec9
7 changed files with 1540 additions and 76 deletions

View File

@ -298,6 +298,10 @@ void print_all_pdrs(pda_t *pda);
int str2macaddr( UINT8 *a, char *s );
int s3datarec_compare(const void *p1, const void *p2);
int mkpda_crc( pda_t *pda);
int pda_write(pda_t *pda);
int plugimage( imgchunk_t *fchunk, UINT nfchunks,
s3plugrec_t* s3plug, UINT ns3plug, pda_t *pda,
char *fname);
/*================================================================*/
/* Function Definitions */
@ -491,7 +495,7 @@ int main ( int argc, char **argv )
printf( "Card PDA prior to file generated "
"modifications:\n");
}
} else { /* read pda from file */
} else if ( opt_newpda ){ /* read pda from file */
pda_changed = 1;
read_filepda(&pda, newpdafname);
if (opt_status && opt_addpdrcnt) {
@ -525,11 +529,10 @@ int main ( int argc, char **argv )
exit(0);
}
#if 0
if ( !opt_debug && !opt_nowrite && pda_changed) { /* write the PDA */
pda_write(&pda);
}
#endif
/*-----------------------------------------------------*/
/* Read the flash files */
if ( opt_flashloadcnt ) {
@ -537,8 +540,8 @@ int main ( int argc, char **argv )
/* Read the S3 file */
result = read_srecfile(ffname[i]);
if ( result ) {
fprintf(stderr,
"Failed to read %s, exiting.\n",
fprintf(stderr, APPNAME
": Failed to read %s, exiting.\n",
ffname[i]);
exit(1);
}
@ -552,12 +555,22 @@ int main ( int argc, char **argv )
/* Make the image chunks */
result = mkimage(fchunk, &nfchunks);
#if 0
/* Do any plugging */
for ( i = 0; i < ns3plug; i++) {
plugimage(fchunk, &da, s3plug[i]);
result = plugimage(fchunk, nfchunks, s3plug, ns3plug,
&pda, ffname[i]);
if ( result ) {
fprintf(stderr, APPNAME
": Failed to plug data for %s, exiting.\n",
ffname[i]);
exit(1);
}
#if 0
/* Insert any CRCs */
crcimage(fchunk, nfchunks, s3crc, ns3crc);
#endif
/* Write the image */
if ( opt_debug || !opt_nowrite ) continue;
/* do the write */
@ -576,30 +589,90 @@ int main ( int argc, char **argv )
}
}
/*-----------------------------------------------------*/
/* Start loading */
if ( opt_newpda || opt_flashloadcnt ) {
/* Send aux enable BEGIN message */
/* Send flash d/l BEGIN message */
}
if ( pda_changed ) { /* load a new PDA, if necessary */
/* Program the PDA */
}
if ( opt_flashloadcnt ) { /* load the flash chunks */
/* For each chunk */
/* program chunk */
}
if ( opt_newpda || opt_flashloadcnt ) {
/* Send flash d/l END message */
/* Will result flashed code rebooting. */
}
printf(APPNAME": finished.\n");
return result;
}
/*----------------------------------------------------------------
* plugimage
*
* Plugs the given image using the given plug records from the given
* PDA and filename.
*
* Arguments:
* fchunk Array of image chunks
* nfchunks Number of image chunks
* s3plug Array of plug records
* ns3plug Number of plug records
* pda Current pda data
* fname File the image data was read from
*
* Returns:
* 0 success
* ~0 failure
----------------------------------------------------------------*/
int plugimage( imgchunk_t *fchunk, UINT nfchunks,
s3plugrec_t* s3plug, UINT ns3plug, pda_t *pda,
char *fname)
{
int result = 0;
int i; /* plug index */
int j; /* index of PDR or -1 if fname plug */
int c; /* chunk index */
UINT32 pstart;
UINT32 pend;
UINT32 cstart;
UINT32 cend;
UINT32 chunkoff;
/* for each plug record */
for ( i = 0; i < ns3plug; i++) {
pstart = s3plug[i].addr;
pend = s3plug[i].addr + s3plug[i].len;
/* find the matching PDR (or filename) */
if ( s3plug[i].itemcode != 0xffffffffUL ) { /* not filename */
for ( j = 0; j < pda->nrec; j++) {
if ( s3plug[i].itemcode ==
hfa384x2host_16(pda->rec[j]->code) ) break;
}
} else {
j = -1;
}
if ( j >= pda->nrec && j != -1 ) { /* if no matching PDR, fail */
fprintf(stderr, APPNAME
": failed to find PDR for plugrec 0x%04lx, exiting.\n",
s3plug[i].itemcode);
return 1;
}
/* Validate plug address against chunk data and identify chunk */
for ( c = 0; c < nfchunks; c++) {
cstart = fchunk[c].addr;
cend = fchunk[c].addr + fchunk[c].len;
if ( pstart >= cstart && pend <= cend ) break;
}
if ( c >= nfchunks ) {
fprintf(stderr, APPNAME
": failed to find image chunk for "
"plugrec 0x%04lx, exiting.\n",
s3plug[i].itemcode);
return 1;
}
/* Plug data */
chunkoff = pstart - cstart;
if ( j == -1 ) {
} else {
}
}
return result;
}
/*----------------------------------------------------------------
* do_ioctl
*
@ -626,7 +699,7 @@ int do_ioctl( p80211msg_t *msg )
fd = socket(AF_INET, SOCK_STREAM, 0);
if ( fd == -1 ) {
result = errno;
perror("wlanctl");
perror(APPNAME);
} else {
req.len = msg->msglen;
req.data = msg;
@ -834,6 +907,115 @@ int mkpdrlist( pda_t *pda)
}
/*----------------------------------------------------------------
* pda_write
*
* Builds a message containing the PDA in the given pda structure
* and sends it to the device driver. The driver will (hopefully)
* write the pda to the card flash.
*
* Arguments:
* pda structure containing the PDA we wish to write to
* the card.
*
* Returns:
* 0 success
* ~0 failure
----------------------------------------------------------------*/
int pda_write(pda_t *pda)
{
int result = 0;
p80211msg_p2req_flashdl_state_t statemsg;
p80211msg_p2req_flashdl_write_t writemsg;
/* Initialize the messages */
memset(&statemsg, 0, sizeof(statemsg));
strcpy(statemsg.devname, devname);
statemsg.msgcode = DIDmsg_p2req_flashdl_state;
statemsg.msglen = sizeof(statemsg);
statemsg.enable.did = DIDmsg_p2req_flashdl_state_enable;
statemsg.resultcode.did = DIDmsg_p2req_flashdl_state_resultcode;
statemsg.enable.status = P80211ENUM_msgitem_status_data_ok;
statemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
statemsg.enable.len = sizeof(UINT32);
statemsg.resultcode.len = sizeof(UINT32);
memset(&writemsg, 0, sizeof(writemsg));
strcpy(writemsg.devname, devname);
writemsg.msgcode = DIDmsg_p2req_flashdl_write;
writemsg.msglen = sizeof(writemsg);
writemsg.addr.did = DIDmsg_p2req_flashdl_write_addr;
writemsg.len.did = DIDmsg_p2req_flashdl_write_len;
writemsg.data.did = DIDmsg_p2req_flashdl_write_data;
writemsg.resultcode.did = DIDmsg_p2req_flashdl_write_resultcode;
writemsg.addr.status = P80211ENUM_msgitem_status_data_ok;
writemsg.len.status = P80211ENUM_msgitem_status_data_ok;
writemsg.data.status = P80211ENUM_msgitem_status_data_ok;
writemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
writemsg.addr.len = sizeof(UINT32);
writemsg.len.len = sizeof(UINT32);
writemsg.data.len = 1024;
writemsg.resultcode.len = sizeof(UINT32);
/* Send flashdl_state(enable) */
if (opt_verbose) printf("Sending dlflash_state(enable) message.\n");
statemsg.enable.data = P80211ENUM_truth_true;
result = do_ioctl((p80211msg_t*)&statemsg);
if ( result ) {
fprintf(stderr,APPNAME
": pda_write()->do_ioctl() failed w/ result=%d, "
"aborting pda download\n", result);
return result;
}
if ( statemsg.resultcode.data != P80211ENUM_resultcode_success ) {
fprintf(stderr,APPNAME
": pda_write()->flashdl_state msg indicates failure, "
"w/ resultcode=%ld, aborting pda download.\n",
statemsg.resultcode.data);
return 1;
}
/* Send flashdl_write(pda) */
if (opt_verbose) printf("Sending dlflash_write message.\n");
writemsg.addr.data = HFA384x_PDA_BASE;
writemsg.len.data = (((UINT8*)(pda->rec[pda->nrec - 1])) - pda->buf + 6);
memcpy(writemsg.data.data, pda->buf, writemsg.len.data);
result = do_ioctl((p80211msg_t*)&writemsg);
if ( result ) {
fprintf(stderr,APPNAME
": pda_write()->do_ioctl() failed w/ result=%d, "
"aborting pda download\n", result);
return result;
}
if ( writemsg.resultcode.data != P80211ENUM_resultcode_success ) {
fprintf(stderr,APPNAME
": pda_write()->flashdl_write msg indicates failure, "
"w/ resultcode=%ld, aborting pda download.\n",
writemsg.resultcode.data);
return 1;
}
/* Send flashdl_state(disable) */
if (opt_verbose) printf("Sending dlflash_state(disable) message.\n");
statemsg.enable.data = P80211ENUM_truth_false;
result = do_ioctl((p80211msg_t*)&statemsg);
if ( result ) {
fprintf(stderr,APPNAME
": pda_write()->do_ioctl() failed w/ result=%d, "
"aborting pda download\n", result);
return result;
}
if ( statemsg.resultcode.data != P80211ENUM_resultcode_success ) {
fprintf(stderr,APPNAME
": pda_write()->flashdl_state msg indicates failure, "
"w/ resultcode=%ld, aborting pda download.\n",
statemsg.resultcode.data);
return 1;
}
return result;
}
/*----------------------------------------------------------------
* print_all_pdrs
*

View File

@ -73,6 +73,13 @@
#define HFA384x_PDA_BASE (0x003f0000)
#define HFA384x_PDA_BOGUS_BASE (0x00390000)
/*--- Driver Download states -----------------------*/
#define HFA384x_DLSTATE_DISABLED 0
#define HFA384x_DLSTATE_RAMENABLED 1
#define HFA384x_DLSTATE_FLASHENABLED 2
#define HFA384x_DLSTATE_FLASHWRITTEN 3
#define HFA384x_DLSTATE_FLASHWRITEPENDING 4
/*--- Register I/O offsets --------------------------*/
#define HFA384x_CMD_OFF (0x00)
#define HFA384x_PARAM0_OFF (0x02)
@ -172,7 +179,9 @@
#define HFA384x_CMDCODE_DOWNLD 0x22
/*--- Debugging Commands -----------------------------*/
#define HFA384x_CMDCODE_MONITOR_ON (0x38)
#define HFA384x_CMDCODE_MONITOR (0x38)
#define HFA384x_MONITOR_ENABLE (0x0b)
#define HFA384x_MONITOR_DISABLE (0x0f)
/*--- Result Codes --------------------------*/
#define HFA384x_SUCCESS (0x00)
@ -186,10 +195,10 @@
MODE 2: Enable non-volatile memory programming
MODE 3: Program non-volatile memory section
--------------------------------------------------*/
#define HFA384x_PROGMODE_MODE0 (0x00)
#define HFA384x_PROGMODE_MODE1 (0x01)
#define HFA384x_PROGMODE_MODE2 (0x02)
#define HFA384x_PROGMODE_MODE3 (0x03)
#define HFA384x_PROGMODE_DISABLE (0x00)
#define HFA384x_PROGMODE_RAM (0x01)
#define HFA384x_PROGMODE_NV (0x02)
#define HFA384x_PROGMODE_NVWRITE (0x03)
/*--- AUX register enable --------------------------*/
#define HFA384x_AUXPW0 (0xfe01)
@ -929,14 +938,12 @@ typedef struct hfa384x_MaxLoadTime
} hfa384x_MaxLoadTime_t;
/*-- Information Record: DownLoadBuffer --*/
typedef struct hfa384x_DownLoadBuffer
typedef struct hfa384x_downloadbuffer
{
UINT16 reclen __WLAN_ATTRIB_PACK__;
UINT16 rid __WLAN_ATTRIB_PACK__;
UINT16 DownLoadBufferPage __WLAN_ATTRIB_PACK__;
UINT16 DownLoadBufferOffset __WLAN_ATTRIB_PACK__;
UINT16 DownLoadBufferLength __WLAN_ATTRIB_PACK__;
} hfa384x_DownLoadBuffer_t;
UINT16 page __WLAN_ATTRIB_PACK__;
UINT16 offset __WLAN_ATTRIB_PACK__;
UINT16 len __WLAN_ATTRIB_PACK__;
} hfa384x_downloadbuffer_t;
/*-- Information Record: PRIIdentity --*/
typedef struct hfa384x_PRIIdentity
@ -1835,6 +1842,11 @@ typedef struct hfa384x
/* context, should be set and cleared */
/* in int handler */
/* Download support */
UINT dlstate;
hfa384x_downloadbuffer_t bufinfo;
UINT16 dltimeout;
/* Command support */
spinlock_t cmdlock;
UINT16 lastcmd;
@ -1853,15 +1865,15 @@ typedef struct hfa384x
void hfa384x_inithw( hfa384x_t *hw, UINT irq, UINT iobase);
int hfa384x_cmd_initialize(hfa384x_t *hw);
int hfa384x_cmd_enable(hfa384x_t *hw, UINT8 macport);
int hfa384x_cmd_disable(hfa384x_t *hw, UINT8 macport);
int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport);
int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport);
int hfa384x_cmd_diagnose(hfa384x_t *hw);
int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len);
int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 fid);
int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid);
int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid);
int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid);
int hfa384x_cmd_monitor(hfa384x_t *hw);
int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable);
int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr,
UINT16 highaddr, UINT16 codelen);
int hfa384x_cmd_aux_enable(hfa384x_t *hw);
@ -1883,6 +1895,12 @@ int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len);
int hfa384x_drvr_setconfig16(hfa384x_t *hw, UINT16 rid, UINT16 *val);
int hfa384x_drvr_setconfig32(hfa384x_t *hw, UINT16 rid, UINT32 *val);
int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len);
int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr);
int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
int hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len);
int hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
int hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len);
int hfa384x_docmd_wait( hfa384x_t *hw, UINT16 cmd, UINT16 parm0, UINT16 parm1, UINT16 parm2);

View File

@ -119,6 +119,8 @@ extern int prism2_debug;
/*--- Function Declarations -----------------------------------*/
/*=============================================================*/
int prism2sta_initmac(wlandevice_t *wlandev);
int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
@ -132,6 +134,13 @@ int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
/*---------------------------------------------------------------
* conversion functions going between wlan message data types and

View File

@ -466,6 +466,378 @@ failed:
}
/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_enable
*
* Begins the ram download state. Checks to see that we're not
* already in a download state and that a port isn't enabled.
* Sets the download state and calls cmd_download with the
* ENABLE_VOLATILE subcommand and the exeaddr argument.
*
* Arguments:
* hw device structure
* exeaddr the card execution address that will be
* jumped to when ramdl_disable() is called
* (host order).
*
* Returns:
* 0 success
* >0 f/w reported error - f/w status code
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr)
{
int result = 0;
UINT16 lowaddr;
UINT16 hiaddr;
int i;
DBFENTER;
/* Check that a port isn't active */
for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
if ( hw->port_enabled[i] ) return -EINVAL;
}
/* Check that we're not already in a download state */
if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
return -EINVAL;
}
/* Enable the aux port */
if ( (result = hfa384x_cmd_aux_enable(hw)) ) {
return result;
}
/* Call the download(1,addr) function */
lowaddr = (UINT16)(exeaddr & 0x0000ffff);
lowaddr = host2hfa384x_16(lowaddr);
hiaddr = (UINT16)(exeaddr >> 16);
hiaddr = host2hfa384x_16(hiaddr);
result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
lowaddr, hiaddr, 0);
if ( result == 0) {
/* Set the download state */
hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
} else {
/* Disable the aux port */
hfa384x_cmd_aux_disable(hw);
}
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_disable
*
* Ends the ram download state.
*
* Arguments:
* hw device structure
*
* Returns:
* 0 success
* >0 f/w reported error - f/w status code
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
{
DBFENTER;
/* Check that we're already in the download state */
if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
return -EINVAL;
}
/* There isn't much we can do at this point, so I don't */
/* bother w/ the return value */
hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
hw->dlstate = HFA384x_DLSTATE_DISABLED;
/* Disable the aux port */
hfa384x_cmd_aux_disable(hw);
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_write
*
* Performs a RAM download of a chunk of data. First checks to see
* that we're in the RAM download state, then uses the aux functions
* to 1) copy the data, 2) readback and compare. The download
* state is unaffected. When all data has been written using
* this function, call drvr_ramdl_disable() to end the download state
* and restart the MAC.
*
* Arguments:
* hw device structure
* daddr Card address to write to. (host order)
* buf Ptr to data to write.
* len Length of data (host order).
*
* Returns:
* 0 success
* >0 f/w reported error - f/w status code
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
{
int result = 0;
UINT8 *verbuf;
DBFENTER;
/* Check that we're in the ram download state */
if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
return -EINVAL;
}
WLAN_LOG_INFO2("Writing %ld bytes to ram @0x%06lx\n", len, daddr);
/* Copy the data via the aux port */
hfa384x_copy_to_aux(hw, daddr, buf, len);
/* Create a buffer for the verify */
verbuf = kmalloc(len, GFP_KERNEL);
if (verbuf == NULL ) return 1;
/* Read back and compare */
hfa384x_copy_from_aux(hw, daddr, verbuf, len);
if ( memcmp(buf, verbuf, len) ) {
result = -EINVAL;
}
kfree_s(verbuf, len);
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_enable
*
* Begins the flash download state. Checks to see that we're not
* already in a download state and that a port isn't enabled.
* Sets the download state and retrieves the flash download
* buffer location, buffer size, and timeout length.
*
* Arguments:
* hw device structure
*
* Returns:
* 0 success
* >0 f/w reported error - f/w status code
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
{
int result = 0;
int i;
DBFENTER;
/* Check that a port isn't active */
for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
if ( hw->port_enabled[i] ) return -EINVAL;
}
/* Check that we're not already in a download state */
if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
return -EINVAL;
}
/* Retrieve the buffer loc&size and timeout */
if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
&(hw->bufinfo), sizeof(hw->bufinfo))) ) {
return result;
}
hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.offset);
if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
&(hw->dltimeout))) ) {
return result;
}
hw->dltimeout = hfa384x2host_16(hw->dltimeout);
/* Enable the aux port */
if ( (result = hfa384x_cmd_aux_enable(hw)) ) {
return result;
}
hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_disable
*
* Ends the flash download state. Note that this will cause the MAC
* firmware to restart.
*
* Arguments:
* hw device structure
*
* Returns:
* 0 success
* >0 f/w reported error - f/w status code
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
{
DBFENTER;
/* Check that we're already in the download state */
if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
return -EINVAL;
}
/* There isn't much we can do at this point, so I don't */
/* bother w/ the return value */
hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
hw->dlstate = HFA384x_DLSTATE_DISABLED;
/* Disable the aux port */
hfa384x_cmd_aux_disable(hw);
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_write
*
* Performs a FLASH download of a chunk of data. First checks to see
* that we're in the FLASH download state, then sets the download
* mode, uses the aux functions to 1) copy the data to the flash
* buffer, 2) sets the download 'write flash' mode, 3) readback and
* compare. Lather rinse, repeat as many times an necessary to get
* all the given data into flash.
* When all data has been written using this function (possibly
* repeatedly), call drvr_flashdl_disable() to end the download state
* and restart the MAC.
*
* Arguments:
* hw device structure
* daddr Card address to write to. (host order)
* buf Ptr to data to write.
* len Length of data (host order).
*
* Returns:
* 0 success
* >0 f/w reported error - f/w status code
* <0 driver reported error
*
* Side effects:
*
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
{
int result = 0;
UINT8 *verbuf;
UINT32 dlbufaddr;
UINT32 currlen;
UINT32 currdaddr;
UINT16 destlo;
UINT16 desthi;
int nwrites;
int i;
DBFENTER;
/* Check that we're in the flash download state */
if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
return -EINVAL;
}
/* Figure out how many times to to the flash prog */
nwrites = len / hw->bufinfo.len;
nwrites += (len % hw->bufinfo.len) ? 1 : 0;
/* For convenience */
dlbufaddr = (hw->bufinfo.page << 7) | hw->bufinfo.offset;
verbuf = kmalloc(hw->bufinfo.len, GFP_KERNEL);
if ( verbuf == NULL ) {
WLAN_LOG_ERROR0("Failed to allocate flash verify buffer\n");
return 1;
}
/* For each */
for ( i = 0; i < nwrites; i++) {
/* Get the dest address and len */
currlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
hw->bufinfo.len :
(len - (hw->bufinfo.len * i));
currdaddr = daddr + (hw->bufinfo.len * i);
destlo = currdaddr & 0x0000ffff;
desthi = currdaddr >> 16;
WLAN_LOG_INFO2("Writing %ld bytes to flash @0x%06lx\n", currlen, currdaddr);
/* Set the download mode */
result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
destlo, desthi, currlen);
if ( result ) {
WLAN_LOG_ERROR3("download(NV,lo=%x,hi=%x,len=%lx) cmd failed. Aborting d/l\n",
destlo, desthi, currlen);
kfree_s(verbuf, len);
return result;
}
/* copy the data to the flash buffer */
hfa384x_copy_to_aux(hw, dlbufaddr,
buf+(hw->bufinfo.len*i), currlen);
/* set the download 'write flash' mode */
result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0);
if ( result ) {
WLAN_LOG_ERROR3("download(NVWRITE,lo=%x,hi=%x,len=%lx) cmd failed. Aborting d/l\n",
destlo, desthi, currlen);
kfree_s(verbuf, len);
return result;
}
/* readback and compare, if fail...bail */
hfa384x_copy_from_aux(hw, currdaddr, verbuf, currlen);
if ( memcmp(buf+(hw->bufinfo.len*i), verbuf, currlen) ) {
kfree_s(verbuf, hw->bufinfo.len);
return -EINVAL;
}
}
/* Leave the firmware in the 'post-prog' mode. flashdl_disable will */
/* actually disable programming mode. Remember, that will cause the */
/* the firmware to effectively reset itself. */
DBFEXIT;
return result;
}
/*----------------------------------------------------------------
* hfa384x_cmd_initialize
*
@ -524,7 +896,7 @@ int hfa384x_cmd_initialize(hfa384x_t *hw)
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_cmd_enable(hfa384x_t *hw, UINT8 macport)
int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport)
{
int result = 0;
UINT16 cmd;
@ -557,7 +929,7 @@ int hfa384x_cmd_enable(hfa384x_t *hw, UINT8 macport)
*
* Arguments:
* hw device structure
* macport MAC port number
* macport MAC port number (host order)
*
* Returns:
* 0 success
@ -569,7 +941,7 @@ int hfa384x_cmd_enable(hfa384x_t *hw, UINT8 macport)
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_cmd_disable(hfa384x_t *hw, UINT8 macport)
int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport)
{
int result = 0;
UINT16 cmd;
@ -651,7 +1023,7 @@ int hfa384x_cmd_diagnose(hfa384x_t *hw)
* Arguments:
* hw device structure
* len allocation length, must be an even value
* in the range [4-2400].
* in the range [4-2400]. (host order)
*
* Returns:
* 0 success
@ -696,8 +1068,10 @@ int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len)
* hw device structure
* reclaim [0|1] indicates whether the given FID will
* be handed back (via Alloc event) for reuse.
* (host order)
* fid FID of buffer containing the frame that was
* previously copied to MAC memory via the bap.
* (host order)
*
* Returns:
* 0 success
@ -739,8 +1113,10 @@ int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 fid)
* hw device structure
* reclaim [0|1] indicates whether the given FID will
* be handed back (via Alloc event) for reuse.
* (host order)
* fid FID of buffer containing the frame that was
* previously copied to MAC memory via the bap.
* (host order)
*
* Returns:
* 0 success
@ -777,7 +1153,7 @@ int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid)
*
* Arguments:
* hw device structure
* fid FID of the info frame requested.
* fid FID of the info frame requested. (host order)
*
* Returns:
* 0 success
@ -814,8 +1190,8 @@ int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid)
* Arguments:
* hw device structure
* write [0|1] copy the record buffer to the given
* configuration record.
* rid RID of the record to read/write
* configuration record. (host order)
* rid RID of the record to read/write. (host order)
*
* Returns:
* 0 success
@ -852,13 +1228,13 @@ int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid)
* MPDUs are passed to the host with MAC Port = 7, with a
* receive status of good, FCS error, or undecryptable. Passing
* certain MPDUs is a violation of the 802.11 standard, but useful
* for a debugging tool."
*
* TODO: We don't yet know if it's possible to turn it off w/o a reset
* TODO: Will the MAC still operate as a STA or AP in this mode?
* for a debugging tool." Normal communication is not possible
* while monitor mode is enabled.
*
* Arguments:
* hw device structure
* enable a code (0x0b|0x0f) that enables/disables
* monitor mode. (host order)
*
* Returns:
* 0 success
@ -870,13 +1246,13 @@ int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid)
* Call context:
* process thread
----------------------------------------------------------------*/
int hfa384x_cmd_monitor(hfa384x_t *hw)
int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable)
{
int result = 0;
UINT16 cmd;
DBFENTER;
cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR_ON) |
HFA384x_CMD_AINFO_SET(0x0b);
cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
HFA384x_CMD_AINFO_SET(enable);
result = hfa384x_docmd_wait(hw, cmd, 0, 0, 0);
DBFEXIT;
@ -898,16 +1274,18 @@ int hfa384x_cmd_monitor(hfa384x_t *hw)
* 1 - Enable volatile mem programming
* 2 - Enable non-volatile mem programming
* 3 - Program non-volatile section from NV download
* buffer.
* buffer.
* (host order)
* lowaddr
* highaddr for mode 1, sets the high & low order bits of
* highaddr For mode 1, sets the high & low order bits of
* the "destination address". This address will be
* the execution start address when download is
* subsequently disabled.
* for mode 2, sets the high & low order bits of
* For mode 2, sets the high & low order bits of
* the destination in NV ram.
* for modes 0 & 3, should be zero
* codelen length of the data to write in mode 2, zero otherwise
* For modes 0 & 3, should be zero. (host order)
* codelen Length of the data to write in mode 2,
* zero otherwise. (host order)
*
* Returns:
* 0 success
@ -1041,7 +1419,7 @@ int hfa384x_cmd_aux_disable(hfa384x_t *hw)
if (hw->auxen) hw->auxen--;
if (hw->auxen) return 0;
/* Set the aux enable in the Control register */
/* Clear the aux enable in the Control register */
outw(0, HFA384x_PARAM0(hw->iobase));
outw(0, HFA384x_PARAM1(hw->iobase));
outw(0, HFA384x_PARAM2(hw->iobase));
@ -1473,7 +1851,13 @@ int hfa384x_docmd_wait( hfa384x_t *hw, UINT16 cmd, UINT16 parm0, UINT16 parm1, U
outw(host2hfa384x_16(cmd), HFA384x_CMD(hw->iobase));
/* Now wait for completion */
timeout = jiffies + 1*HZ;
if ( (HFA384x_CMD_CMDCODE_GET(hw->lastcmd) ==
HFA384x_CMDCODE_DOWNLD) ) {
/* dltimeout is in ms */
timeout = jiffies + (hw->dltimeout * 1000)*HZ;
} else {
timeout = jiffies + 1*HZ;
}
reg = inw(HFA384x_EVSTAT(hw->iobase));
while ( !HFA384x_EVSTAT_ISCMD(hfa384x2host_16(reg)) &&
time_before(jiffies,timeout) ){

View File

@ -1077,14 +1077,6 @@ int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp)
p80211msg_dot11req_associate_t *msg = msgp;
DBFENTER;
printk(KERN_DEBUG"offset(msg->peerstaaddress)=%d\n", ((UINT8*)&(msg->peerstaaddress)) - ((UINT8*)msg));
printk(KERN_DEBUG"offset(msg->associatefailuretimeout)=%d\n", ((UINT8*)&(msg->associatefailuretimeout)) - ((UINT8*)msg));
printk(KERN_DEBUG"offset(msg->cfpollable)=%d\n", ((UINT8*)&(msg->cfpollable)) - ((UINT8*)msg));
printk(KERN_DEBUG"offset(msg->cfpollreq)=%d\n", ((UINT8*)&(msg->cfpollreq)) - ((UINT8*)msg));
printk(KERN_DEBUG"offset(msg->privacy)=%d\n", ((UINT8*)&(msg->privacy)) - ((UINT8*)msg));
printk(KERN_DEBUG"offset(msg->listeninterval)=%d\n", ((UINT8*)&(msg->listeninterval)) - ((UINT8*)msg));
printk(KERN_DEBUG"offset(msg->resultcode)=%d\n", ((UINT8*)&(msg->resultcode)) - ((UINT8*)msg));
/* Set the PortType */
port_type = 1;
hfa384x_drvr_setconfig16(hw, 0xfc00, &port_type); /* ESS port */
@ -1101,7 +1093,7 @@ printk(KERN_DEBUG"offset(msg->resultcode)=%d\n", ((UINT8*)&(msg->resultcode)) -
/* Enable the Port */
hfa384x_cmd_enable(hw, 0);
/* Set the resultcode */
msg->resultcode.status = 0;
msg->resultcode.data = P80211ENUM_resultcode_success;
@ -1258,6 +1250,362 @@ int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
}
/*----------------------------------------------------------------
* prism2mgmt_auxport_state
*
* Enables/Disables the card's auxiliary port. Should be called
* before and after a sequence of auxport_read()/auxport_write()
* calls.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp)
{
prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv;
hfa384x_t *hw = priv->hw;
p80211msg_p2req_auxport_state_t *msg = msgp;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
if (msg->enable.data == P80211ENUM_truth_true) {
if ( hfa384x_cmd_aux_enable(hw) ) {
msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
} else {
hfa384x_cmd_aux_disable(hw);
msg->resultcode.data = P80211ENUM_resultcode_success;
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_auxport_read
*
* Copies data from the card using the auxport. The auxport must
* have previously been enabled. Note: this is not the way to
* do downloads, see the [ram|flash]dl functions.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp)
{
prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv;
hfa384x_t *hw = priv->hw;
p80211msg_p2req_auxport_read_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8* buf;
UINT32 maxlen = sizeof(msg->data.data);
DBFENTER;
if ( hw->auxen ) {
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( len <= maxlen ) { /* max read/write size */
hfa384x_copy_from_aux(hw, addr, buf, len);
} else {
WLAN_LOG_DEBUG0(1,"Attempt to read > maxlen from auxport.\n");
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
} else {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->data.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_auxport_write
*
* Copies data to the card using the auxport. The auxport must
* have previously been enabled. Note: this is not the way to
* do downloads, see the [ram|flash]dl functions.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp)
{
prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv;
hfa384x_t *hw = priv->hw;
p80211msg_p2req_auxport_write_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8* buf;
UINT32 maxlen = sizeof(msg->data.data);
DBFENTER;
if ( hw->auxen ) {
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( len <= maxlen ) { /* max read/write size */
hfa384x_copy_to_aux(hw, addr, buf, len);
} else {
WLAN_LOG_DEBUG0(1,"Attempt to write > maxlen from auxport.\n");
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
} else {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->data.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_ramdl_state
*
* Establishes the beginning/end of a card RAM download session.
*
* It is expected that the ramdl_write() function will be called
* one or more times between the 'enable' and 'disable' calls to
* this function.
*
* Note: This function should not be called when a mac comm port
* is active.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
{
prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv;
hfa384x_t *hw = priv->hw;
p80211msg_p2req_ramdl_state_t *msg = msgp;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
if ( msg->enable.data == P80211ENUM_truth_true ) {
if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) {
msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
} else {
hfa384x_drvr_ramdl_disable(hw);
msg->resultcode.data = P80211ENUM_resultcode_success;
/*TODO: Reset everything....the MAC just restarted */
udelay(1000);
prism2sta_initmac(wlandev);
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_ramdl_write
*
* Writes a buffer to the card RAM using the download state. This
* is for writing code to card RAM. To just read or write raw data
* use the aux functions.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
{
prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv;
hfa384x_t *hw = priv->hw;
p80211msg_p2req_ramdl_write_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8 *buf;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* first validate the length */
if ( msg->len.data > sizeof(msg->data.data) ) {
msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
return 0;
}
/* call the hfa384x function to do the write */
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_flashdl_state
*
* Establishes the beginning/end of a card Flash download session.
*
* It is expected that the flashdl_write() function will be called
* one or more times between the 'enable' and 'disable' calls to
* this function.
*
* Note: This function should not be called when a mac comm port
* is active.
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
{
prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv;
hfa384x_t *hw = priv->hw;
p80211msg_p2req_flashdl_state_t *msg = msgp;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
if ( msg->enable.data == P80211ENUM_truth_true ) {
if ( hfa384x_drvr_flashdl_enable(hw) ) {
msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
} else {
hfa384x_drvr_flashdl_disable(hw);
msg->resultcode.data = P80211ENUM_resultcode_success;
/*TODO: Reset everything....the MAC just restarted */
udelay(1000);
prism2sta_initmac(wlandev);
}
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_flashdl_write
*
*
*
* Arguments:
* wlandev wlan device structure
* msgp ptr to msg buffer
*
* Returns:
* 0 success and done
* <0 success, but we're waiting for something to finish.
* >0 an error occurred while handling the message.
* Side effects:
*
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
{
prism2sta_priv_t *priv = (prism2sta_priv_t*)wlandev->priv;
hfa384x_t *hw = priv->hw;
p80211msg_p2req_flashdl_write_t *msg = msgp;
UINT32 addr;
UINT32 len;
UINT8 *buf;
DBFENTER;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* first validate the length */
if ( msg->len.data > sizeof(msg->data.data) ) {
msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
return 0;
}
/* call the hfa384x function to do the write */
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) {
msg->resultcode.data = P80211ENUM_resultcode_refused;
}
msg->resultcode.data = P80211ENUM_resultcode_success;
DBFEXIT;
return 0;
}
/*----------------------------------------------------------------
* prism2mgmt_wlansniff
*
@ -1290,6 +1638,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
case P80211ENUM_truth_false:
WLAN_LOG_NOTICE0("wlansniff: Don't know how to disable monitor mode");
/* Set the priv structure to discard monitor frames */
hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
priv->sniffing = 0;
msg->resultcode.data = P80211ENUM_resultcode_success;
msg->resultcode.status = 0; /* TODO: Establish data_set constant */
@ -1298,7 +1647,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* Set the priv structure to expect monitor frames */
priv->sniffing = 1;
/* Issue the HFA384x monitor command */
hfa384x_cmd_monitor(hw); /* assume success, don't know if it _can_ fail */
hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
msg->resultcode.data = P80211ENUM_resultcode_success;
msg->resultcode.status = 0; /* TODO: Establish data_set constant */
break;