#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 MAX_JOIN_INFO_COUNT 2 |
| #define BAP_TIMEOUT ( 5000 ) |
| #define hfa384x2host_16 | ( | n | ) | (__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 | ( | n | ) | (__le32_to_cpu((UINT32)(n))) |
| #define host2hfa384x_16 | ( | n | ) | (__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 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 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 ) |
| typedef struct wlan_llc wlan_llc_t |
| typedef struct wlan_snap wlan_snap_t |
| typedef struct wlan_80211hdr wlan_80211hdr_t |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
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 }
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 }
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 }
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 }
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*)(®))[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 }
Definition at line 418 of file prism2.c.
References HFA384x_CMD_CMDCODE_SET, HFA384x_CMD_WRITE_SET, HFA384x_CMDCODE_ACCESS, and hfa384x_docmd_wait().
Referenced by hfa384x_drvr_getconfig(), and hfa384x_drvr_setconfig().
00419 { 00420 return hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) | HFA384x_CMD_WRITE_SET(write), rid, 0, 0); 00421 }
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 }
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 }
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 }
Definition at line 728 of file prism2.c.
Referenced by prism2_pci_disable(), and prism2_plx_disable().
| static void prism2_irq | ( | struct nic *nic | __unused, | |
| irq_action_t action | __unused | |||
| ) | [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 }
const char hardcoded_ssid[] = "" [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] |
struct nic_operations prism2_operations [static] |
Initial value:
{
.connect = dummy_connect,
.poll = prism2_poll,
.transmit = prism2_transmit,
.irq = prism2_irq,
}
1.5.7.1