diff options
author | dmlb <dmlb@FreeBSD.org> | 2001-05-17 22:23:49 +0000 |
---|---|---|
committer | dmlb <dmlb@FreeBSD.org> | 2001-05-17 22:23:49 +0000 |
commit | fff1e2f2427f31a994f85981b3a8b32a23f746c5 (patch) | |
tree | 12c36442b450208c8c5948a440b0db89ba681ad5 /sys/dev/ray | |
parent | fbaf605e32cb99697d53090d26bd612fd736f484 (diff) | |
download | FreeBSD-src-fff1e2f2427f31a994f85981b3a8b32a23f746c5.zip FreeBSD-src-fff1e2f2427f31a994f85981b3a8b32a23f746c5.tar.gz |
Primary purpose of this commit is to enable support for the Aviator
Pro and Raylink cards with version 5 firmware. Only infra-structure
mode has been tested. Specific changes for this feature are:
o Add RFC1042 encapsulation of IP datagrams
o Add authentication and association
o Decode of the beacon (although not used)
Other changes have been made:
o Pass command completion status to *_done (in place for
adding proper error recovery)
o Move a couple of state variables into the current
network parameters structure. This is in prep. for
dealing with roaming.
MFC after: 1 week
Diffstat (limited to 'sys/dev/ray')
-rw-r--r-- | sys/dev/ray/if_ray.c | 787 | ||||
-rw-r--r-- | sys/dev/ray/if_raydbg.h | 13 | ||||
-rw-r--r-- | sys/dev/ray/if_raymib.h | 155 | ||||
-rw-r--r-- | sys/dev/ray/if_rayvar.h | 60 |
4 files changed, 715 insertions, 300 deletions
diff --git a/sys/dev/ray/if_ray.c b/sys/dev/ray/if_ray.c index fe3af87..0b5822e 100644 --- a/sys/dev/ray/if_ray.c +++ b/sys/dev/ray/if_ray.c @@ -82,10 +82,9 @@ * Ad-hoc and infra-structure modes * ================================ * - * At present only the ad-hoc mode is tested. - * - * I have received an AP from Raylink and will be working on - * infrastructure mode. + * The driver supports ad-hoc mode for V4 firmware and infrastructure + * mode for V5 firmware. V5 firmware in ad-hoc mode is untested and should + * work. * * The Linux driver also seems to have the capability to act as an AP. * I wonder what facilities the "AP" can provide within a driver? We can @@ -93,36 +92,25 @@ * power saving etc. is easy. * * - * Packet framing/encapsulation - * ================================ + * Packet framing/encapsulation/translation + * ======================================== * - * Currently we only support the Webgear encapsulation + * Currently we support the Webgear encapsulation: * 802.11 header <net/if_ieee80211.h>struct ieee80211_frame * 802.3 header <net/ethernet.h>struct ether_header - * 802.2 LLC header - * 802.2 SNAP header + * IP/ARP payload * - * We should support whatever packet types the following drivers have - * if_wi.c FreeBSD, RFC1042 - * if_ray.c NetBSD Webgear, RFC1042 - * rayctl.c Linux Webgear, RFC1042 - * also whatever we can divine from the NDC Access points and Kanda's boxes. - * - * Most drivers appear to have a RFC1042 framing. The incoming packet is + * and RFC1042 encapsulation of IP datagrams (translation): * 802.11 header <net/if_ieee80211.h>struct ieee80211_frame * 802.2 LLC header * 802.2 SNAP header + * 802.3 Ethertype + * IP/ARP payload * - * This is translated to - * 802.3 header <net/ethernet.h>struct ether_header - * 802.2 LLC header - * 802.2 SNAP header - * - * Linux seems to look at the SNAP org_code and do some framings - * for IPX and APPLEARP on that. This just may be how Linux does IPX - * and NETATALK. Need to see how FreeBSD does these. - * - * Translation should be selected via if_media stuff or link types. + * Framing should be selected via if_media stuff or link types but + * is currently hardcoded to: + * V4 encapsulation + * V5 translation * * * Authentication @@ -141,23 +129,34 @@ */ /* + * ***check all XXX_INFRA code - reassoc not done well at all! * ***watchdog to catch screwed up removals? * ***error handling of RAY_COM_RUNQ * ***error handling of ECF command completions * ***can't seem to create a n/w that Win95 wants to see. - * ***need decent association code + * ***remove panic in ray_com_ecf by re-quing or timeout + * ***use new ioctl stuff - probably need to change RAY_COM_FCHKRUNNING things? + * consider user doing: + * ifconfig ray0 192.168.200.38 -bssid "freed" + * ifconfig ray0 192.168.200.38 -bssid "fred" + * here the second one would be missed in this code + * check that v5 needs timeouts on ecf commands * write up driver structure in comments above * UPDATE_PARAMS seems to return via an interrupt - maybe the timeout * is needed for wrong values? - * havenet needs checking again * proper setting of mib_hop_seq_len with country code for v4 firmware * best done with raycontrol? - * more translations - * might be able to autodetect them - * spinning in ray_com_ecf * countrycode setting is broken I think * userupdate should trap and do via startjoin etc. * fragmentation when rx level drops? + * v5 might not need download + * defaults are as documented apart from hop_seq_length + * settings are sane for ad-hoc not infra + * + * driver state + * most state is implied by the sequence of commands in the runq + * but in fact any of the rx and tx path that uses variables + * in the sc_c are potentially going to get screwed? * * infra mode stuff * proper handling of the basic rate set - see the manual @@ -166,6 +165,8 @@ * need to consider WEP * acting as ap - should be able to get working from the manual * need to finish RAY_ECMD_REJOIN_DONE + * finish authenitcation code, it doesn't handle errors/timeouts/ + * REJOIN etc. * * ray_nw_param * promisc in here too? - done @@ -205,6 +206,7 @@ #define XXX_ACTING_AP 0 #define XXX_INFRA 0 #define RAY_DEBUG ( \ + /* RAY_DBG_AUTH | */ \ /* RAY_DBG_SUBR | */ \ /* RAY_DBG_BOOTPARAM | */ \ /* RAY_DBG_STARTJOIN | */ \ @@ -212,7 +214,7 @@ /* RAY_DBG_IOCTL | */ \ /* RAY_DBG_MBUF | */ \ /* RAY_DBG_RX | */ \ - /* RAY_DBG_CM | */ \ + /* RAY_DBG_CM | */ \ /* RAY_DBG_COM | */ \ /* RAY_DBG_STOP | */ \ /* RAY_DBG_CTL | */ \ @@ -259,6 +261,7 @@ #include <net/if_arp.h> #include <net/if_dl.h> #include <net/if_ieee80211.h> +#include <net/if_llc.h> #include <machine/limits.h> @@ -292,26 +295,29 @@ static int ray_detach (device_t); static void ray_init (void *xsc); static int ray_init_user (struct ray_softc *sc); static void ray_init_assoc (struct ray_softc *sc, struct ray_comq_entry *com); -static void ray_init_assoc_done (struct ray_softc *sc, size_t ccs); +static void ray_init_assoc_done (struct ray_softc *sc, u_int8_t status, size_t ccs); +static void ray_init_auth (struct ray_softc *sc, struct ray_comq_entry *com); +static int ray_init_auth_send (struct ray_softc *sc, u_int8_t *dst, int sequence); +static void ray_init_auth_done (struct ray_softc *sc, u_int8_t status); static void ray_init_download (struct ray_softc *sc, struct ray_comq_entry *com); -static void ray_init_download_done (struct ray_softc *sc, size_t ccs); +static void ray_init_download_done (struct ray_softc *sc, u_int8_t status, size_t ccs); static void ray_init_download_v4 (struct ray_softc *sc, struct ray_comq_entry *com); static void ray_init_download_v5 (struct ray_softc *sc, struct ray_comq_entry *com); static void ray_init_mcast (struct ray_softc *sc, struct ray_comq_entry *com); static void ray_init_sj (struct ray_softc *sc, struct ray_comq_entry *com); -static void ray_init_sj_done (struct ray_softc *sc, size_t ccs); +static void ray_init_sj_done (struct ray_softc *sc, u_int8_t status, size_t ccs); static void ray_intr (void *xsc); static void ray_intr_ccs (struct ray_softc *sc, u_int8_t cmd, u_int8_t status, size_t ccs); static void ray_intr_rcs (struct ray_softc *sc, u_int8_t cmd, size_t ccs); static void ray_intr_updt_errcntrs (struct ray_softc *sc); static int ray_ioctl (struct ifnet *ifp, u_long command, caddr_t data); static void ray_mcast (struct ray_softc *sc, struct ray_comq_entry *com); -static void ray_mcast_done (struct ray_softc *sc, size_t ccs); +static void ray_mcast_done (struct ray_softc *sc, u_int8_t status, size_t ccs); static int ray_mcast_user (struct ray_softc *sc); static int ray_probe (device_t); static void ray_promisc (struct ray_softc *sc, struct ray_comq_entry *com); static void ray_repparams (struct ray_softc *sc, struct ray_comq_entry *com); -static void ray_repparams_done (struct ray_softc *sc, size_t ccs); +static void ray_repparams_done (struct ray_softc *sc, u_int8_t status, size_t ccs); static int ray_repparams_user (struct ray_softc *sc, struct ray_param_req *pr); static int ray_repstats_user (struct ray_softc *sc, struct ray_stats_req *sr); static int ray_res_alloc_am (struct ray_softc *sc); @@ -323,16 +329,18 @@ static void ray_rx_ctl (struct ray_softc *sc, struct mbuf *m0); static void ray_rx_data (struct ray_softc *sc, struct mbuf *m0, u_int8_t siglev, u_int8_t antenna); static void ray_rx_mgt (struct ray_softc *sc, struct mbuf *m0); static void ray_rx_mgt_auth (struct ray_softc *sc, struct mbuf *m0); +static void ray_rx_mgt_beacon (struct ray_softc *sc, struct mbuf *m0); +static void ray_rx_mgt_info (struct ray_softc *sc, struct mbuf *m0, struct ieee80211_information *elements); static void ray_rx_update_cache (struct ray_softc *sc, u_int8_t *src, u_int8_t siglev, u_int8_t antenna); static void ray_stop (struct ray_softc *sc, struct ray_comq_entry *com); static int ray_stop_user (struct ray_softc *sc); static void ray_tx (struct ifnet *ifp); -static void ray_tx_done (struct ray_softc *sc, size_t ccs); +static void ray_tx_done (struct ray_softc *sc, u_int8_t status, size_t ccs); static void ray_tx_timo (void *xsc); static int ray_tx_send (struct ray_softc *sc, size_t ccs, int pktlen, u_int8_t *dst); static size_t ray_tx_wrhdr (struct ray_softc *sc, size_t bufp, u_int8_t type, u_int8_t fc1, u_int8_t *addr1, u_int8_t *addr2, u_int8_t *addr3); static void ray_upparams (struct ray_softc *sc, struct ray_comq_entry *com); -static void ray_upparams_done (struct ray_softc *sc, size_t ccs); +static void ray_upparams_done (struct ray_softc *sc, u_int8_t status, size_t ccs); static int ray_upparams_user (struct ray_softc *sc, struct ray_param_req *pr); static void ray_watchdog (struct ifnet *ifp); static u_int8_t ray_tx_best_antenna (struct ray_softc *sc, u_int8_t *dst); @@ -583,7 +591,7 @@ ray_detach(device_t dev) * then clean the runq. */ sc->sc_gone = 1; - sc->sc_havenet = 0; + sc->sc_c.np_havenet = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -762,7 +770,7 @@ ray_init(void *xsc) static int ray_init_user(struct ray_softc *sc) { - struct ray_comq_entry *com[5]; + struct ray_comq_entry *com[6]; int error, ncom; RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); @@ -773,14 +781,21 @@ ray_init_user(struct ray_softc *sc) * init_download - download the network to the card * init_mcast - reset multicast list * init_sj - find or start a BSS + * init_auth - authenticate with a ESSID if needed * init_assoc - associate with a ESSID if needed * - * They are only actually executed if the card is not running + * They are only actually executed if the card is not running. + * We may enter this routine from a simple change of IP + * address and do not need to get the card to do these things. + * However, we cannot perform the check here as there may be + * commands in the runq that change the IFF_RUNNING state of + * the interface. */ ncom = 0; com[ncom++] = RAY_COM_MALLOC(ray_init_download, RAY_COM_FCHKRUNNING); com[ncom++] = RAY_COM_MALLOC(ray_init_mcast, RAY_COM_FCHKRUNNING); com[ncom++] = RAY_COM_MALLOC(ray_init_sj, RAY_COM_FCHKRUNNING); + com[ncom++] = RAY_COM_MALLOC(ray_init_auth, RAY_COM_FCHKRUNNING); com[ncom++] = RAY_COM_MALLOC(ray_init_assoc, RAY_COM_FCHKRUNNING); /* @@ -811,14 +826,8 @@ ray_init_download(struct ray_softc *sc, struct ray_comq_entry *com) RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); - /* - * If card already running we don't need to download. - */ - if ((com->c_flags & RAY_COM_FCHKRUNNING) && - (ifp->if_flags & IFF_RUNNING)) { - ray_com_runq_done(sc); - return; - } + /* If the card already running we might not need to download */ + RAY_COM_CHKRUNNING(sc, com, ifp); /* * Reset instance variables @@ -842,16 +851,22 @@ ray_init_download(struct ray_softc *sc, struct ray_comq_entry *com) sc->sc_d.np_def_txrate = RAY_MIB_BASIC_RATE_SET_DEFAULT; sc->sc_d.np_encrypt = 0; - sc->sc_d.np_net_type = RAY_MIB_NET_TYPE_DEFAULT; bzero(sc->sc_d.np_ssid, IEEE80211_NWID_LEN); - strncpy(sc->sc_d.np_ssid, RAY_MIB_SSID_DEFAULT, IEEE80211_NWID_LEN); + if (sc->sc_version == RAY_ECFS_BUILD_4) { + sc->sc_d.np_net_type = RAY_MIB_NET_TYPE_V4; + strncpy(sc->sc_d.np_ssid, RAY_MIB_SSID_V4, IEEE80211_NWID_LEN); + sc->sc_d.np_ap_status = RAY_MIB_AP_STATUS_V4; + sc->sc_d.np_framing = RAY_FRAMING_ENCAPSULATION; + } else { + sc->sc_d.np_net_type = RAY_MIB_NET_TYPE_V5; + strncpy(sc->sc_d.np_ssid, RAY_MIB_SSID_V5, IEEE80211_NWID_LEN); + sc->sc_d.np_ap_status = RAY_MIB_AP_STATUS_V5; + sc->sc_d.np_framing = RAY_FRAMING_TRANSLATION; + } sc->sc_d.np_priv_start = RAY_MIB_PRIVACY_MUST_START_DEFAULT; sc->sc_d.np_priv_join = RAY_MIB_PRIVACY_CAN_JOIN_DEFAULT; - sc->sc_d.np_ap_status = RAY_MIB_AP_STATUS_DEFAULT; sc->sc_d.np_promisc = !!(ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)); - sc->framing = SC_FRAMING_WEBGEAR; - /* XXX this is a hack whilst I transition the code. The instance * XXX variables above should be set somewhere else. This is needed for * XXX start_join */ @@ -890,37 +905,37 @@ ray_init_download_v4(struct ray_softc *sc, struct ray_comq_entry *com) MIB4(mib_net_type) = com->c_desired.np_net_type; MIB4(mib_ap_status) = com->c_desired.np_ap_status; bcopy(com->c_desired.np_ssid, MIB4(mib_ssid), IEEE80211_NWID_LEN); - MIB4(mib_scan_mode) = RAY_MIB_SCAN_MODE_DEFAULT; - MIB4(mib_apm_mode) = RAY_MIB_APM_MODE_DEFAULT; + MIB4(mib_scan_mode) = RAY_MIB_SCAN_MODE_V4; + MIB4(mib_apm_mode) = RAY_MIB_APM_MODE_V4; bcopy(sc->sc_station_addr, MIB4(mib_mac_addr), ETHER_ADDR_LEN); - PUT2(MIB4(mib_frag_thresh), RAY_MIB_FRAG_THRESH_DEFAULT); + PUT2(MIB4(mib_frag_thresh), RAY_MIB_FRAG_THRESH_V4); PUT2(MIB4(mib_dwell_time), RAY_MIB_DWELL_TIME_V4); PUT2(MIB4(mib_beacon_period), RAY_MIB_BEACON_PERIOD_V4); - MIB4(mib_dtim_interval) = RAY_MIB_DTIM_INTERVAL_DEFAULT; - MIB4(mib_max_retry) = RAY_MIB_MAX_RETRY_DEFAULT; - MIB4(mib_ack_timo) = RAY_MIB_ACK_TIMO_DEFAULT; - MIB4(mib_sifs) = RAY_MIB_SIFS_DEFAULT; - MIB4(mib_difs) = RAY_MIB_DIFS_DEFAULT; + MIB4(mib_dtim_interval) = RAY_MIB_DTIM_INTERVAL_V4; + MIB4(mib_max_retry) = RAY_MIB_MAX_RETRY_V4; + MIB4(mib_ack_timo) = RAY_MIB_ACK_TIMO_V4; + MIB4(mib_sifs) = RAY_MIB_SIFS_V4; + MIB4(mib_difs) = RAY_MIB_DIFS_V4; MIB4(mib_pifs) = RAY_MIB_PIFS_V4; - PUT2(MIB4(mib_rts_thresh), RAY_MIB_RTS_THRESH_DEFAULT); + PUT2(MIB4(mib_rts_thresh), RAY_MIB_RTS_THRESH_V4); PUT2(MIB4(mib_scan_dwell), RAY_MIB_SCAN_DWELL_V4); PUT2(MIB4(mib_scan_max_dwell), RAY_MIB_SCAN_MAX_DWELL_V4); - MIB4(mib_assoc_timo) = RAY_MIB_ASSOC_TIMO_DEFAULT; - MIB4(mib_adhoc_scan_cycle) = RAY_MIB_ADHOC_SCAN_CYCLE_DEFAULT; - MIB4(mib_infra_scan_cycle) = RAY_MIB_INFRA_SCAN_CYCLE_DEFAULT; + MIB4(mib_assoc_timo) = RAY_MIB_ASSOC_TIMO_V4; + MIB4(mib_adhoc_scan_cycle) = RAY_MIB_ADHOC_SCAN_CYCLE_V4; + MIB4(mib_infra_scan_cycle) = RAY_MIB_INFRA_SCAN_CYCLE_V4; MIB4(mib_infra_super_scan_cycle) - = RAY_MIB_INFRA_SUPER_SCAN_CYCLE_DEFAULT; + = RAY_MIB_INFRA_SUPER_SCAN_CYCLE_V4; MIB4(mib_promisc) = com->c_desired.np_promisc; - PUT2(MIB4(mib_uniq_word), RAY_MIB_UNIQ_WORD_DEFAULT); + PUT2(MIB4(mib_uniq_word), RAY_MIB_UNIQ_WORD_V4); MIB4(mib_slot_time) = RAY_MIB_SLOT_TIME_V4; - MIB4(mib_roam_low_snr_thresh) = RAY_MIB_ROAM_LOW_SNR_THRESH_DEFAULT; - MIB4(mib_low_snr_count) = RAY_MIB_LOW_SNR_COUNT_DEFAULT; + MIB4(mib_roam_low_snr_thresh) = RAY_MIB_ROAM_LOW_SNR_THRESH_V4; + MIB4(mib_low_snr_count) = RAY_MIB_LOW_SNR_COUNT_V4; MIB4(mib_infra_missed_beacon_count) - = RAY_MIB_INFRA_MISSED_BEACON_COUNT_DEFAULT; + = RAY_MIB_INFRA_MISSED_BEACON_COUNT_V4; MIB4(mib_adhoc_missed_beacon_count) - = RAY_MIB_ADHOC_MISSED_BEACON_COUNT_DEFAULT; - MIB4(mib_country_code) = RAY_MIB_COUNTRY_CODE_DEFAULT; - MIB4(mib_hop_seq) = RAY_MIB_HOP_SEQ_DEFAULT; + = RAY_MIB_ADHOC_MISSED_BEACON_COUNT_V4; + MIB4(mib_country_code) = RAY_MIB_COUNTRY_CODE_V4; + MIB4(mib_hop_seq) = RAY_MIB_HOP_SEQ_V4; MIB4(mib_hop_seq_len) = RAY_MIB_HOP_SEQ_LEN_V4; MIB4(mib_cw_max) = RAY_MIB_CW_MAX_V4; MIB4(mib_cw_min) = RAY_MIB_CW_MIN_V4; @@ -930,8 +945,8 @@ ray_init_download_v4(struct ray_softc *sc, struct ray_comq_entry *com) MIB4(mib_busy_thresh_offset) = RAY_MIB_BUSY_THRESH_OFFSET_DEFAULT; MIB4(mib_sync_thresh) = RAY_MIB_SYNC_THRESH_DEFAULT; MIB4(mib_test_mode) = RAY_MIB_TEST_MODE_DEFAULT; - MIB4(mib_test_min_chan) = RAY_MIB_TEST_MIN_CHAN_DEFAULT; - MIB4(mib_test_max_chan) = RAY_MIB_TEST_MAX_CHAN_DEFAULT; + MIB4(mib_test_min_chan) = RAY_MIB_TEST_MIN_CHAN_DEFAULT; + MIB4(mib_test_max_chan) = RAY_MIB_TEST_MAX_CHAN_DEFAULT; #undef MIB4 SRAM_WRITE_REGION(sc, RAY_HOST_TO_ECF_BASE, @@ -953,37 +968,37 @@ ray_init_download_v5(struct ray_softc *sc, struct ray_comq_entry *com) MIB5(mib_net_type) = com->c_desired.np_net_type; MIB5(mib_ap_status) = com->c_desired.np_ap_status; bcopy(com->c_desired.np_ssid, MIB5(mib_ssid), IEEE80211_NWID_LEN); - MIB5(mib_scan_mode) = RAY_MIB_SCAN_MODE_DEFAULT; - MIB5(mib_apm_mode) = RAY_MIB_APM_MODE_DEFAULT; + MIB5(mib_scan_mode) = RAY_MIB_SCAN_MODE_V5; + MIB5(mib_apm_mode) = RAY_MIB_APM_MODE_V5; bcopy(sc->sc_station_addr, MIB5(mib_mac_addr), ETHER_ADDR_LEN); - PUT2(MIB5(mib_frag_thresh), RAY_MIB_FRAG_THRESH_DEFAULT); + PUT2(MIB5(mib_frag_thresh), RAY_MIB_FRAG_THRESH_V5); PUT2(MIB5(mib_dwell_time), RAY_MIB_DWELL_TIME_V5); PUT2(MIB5(mib_beacon_period), RAY_MIB_BEACON_PERIOD_V5); - MIB5(mib_dtim_interval) = RAY_MIB_DTIM_INTERVAL_DEFAULT; - MIB5(mib_max_retry) = RAY_MIB_MAX_RETRY_DEFAULT; - MIB5(mib_ack_timo) = RAY_MIB_ACK_TIMO_DEFAULT; - MIB5(mib_sifs) = RAY_MIB_SIFS_DEFAULT; - MIB5(mib_difs) = RAY_MIB_DIFS_DEFAULT; + MIB5(mib_dtim_interval) = RAY_MIB_DTIM_INTERVAL_V5; + MIB5(mib_max_retry) = RAY_MIB_MAX_RETRY_V5; + MIB5(mib_ack_timo) = RAY_MIB_ACK_TIMO_V5; + MIB5(mib_sifs) = RAY_MIB_SIFS_V5; + MIB5(mib_difs) = RAY_MIB_DIFS_V5; MIB5(mib_pifs) = RAY_MIB_PIFS_V5; - PUT2(MIB5(mib_rts_thresh), RAY_MIB_RTS_THRESH_DEFAULT); + PUT2(MIB5(mib_rts_thresh), RAY_MIB_RTS_THRESH_V5); PUT2(MIB5(mib_scan_dwell), RAY_MIB_SCAN_DWELL_V5); PUT2(MIB5(mib_scan_max_dwell), RAY_MIB_SCAN_MAX_DWELL_V5); - MIB5(mib_assoc_timo) = RAY_MIB_ASSOC_TIMO_DEFAULT; - MIB5(mib_adhoc_scan_cycle) = RAY_MIB_ADHOC_SCAN_CYCLE_DEFAULT; - MIB5(mib_infra_scan_cycle) = RAY_MIB_INFRA_SCAN_CYCLE_DEFAULT; + MIB5(mib_assoc_timo) = RAY_MIB_ASSOC_TIMO_V5; + MIB5(mib_adhoc_scan_cycle) = RAY_MIB_ADHOC_SCAN_CYCLE_V5; + MIB5(mib_infra_scan_cycle) = RAY_MIB_INFRA_SCAN_CYCLE_V5; MIB5(mib_infra_super_scan_cycle) - = RAY_MIB_INFRA_SUPER_SCAN_CYCLE_DEFAULT; + = RAY_MIB_INFRA_SUPER_SCAN_CYCLE_V5; MIB5(mib_promisc) = com->c_desired.np_promisc; - PUT2(MIB5(mib_uniq_word), RAY_MIB_UNIQ_WORD_DEFAULT); + PUT2(MIB5(mib_uniq_word), RAY_MIB_UNIQ_WORD_V5); MIB5(mib_slot_time) = RAY_MIB_SLOT_TIME_V5; - MIB5(mib_roam_low_snr_thresh) = RAY_MIB_ROAM_LOW_SNR_THRESH_DEFAULT; - MIB5(mib_low_snr_count) = RAY_MIB_LOW_SNR_COUNT_DEFAULT; + MIB5(mib_roam_low_snr_thresh) = RAY_MIB_ROAM_LOW_SNR_THRESH_V5; + MIB5(mib_low_snr_count) = RAY_MIB_LOW_SNR_COUNT_V5; MIB5(mib_infra_missed_beacon_count) - = RAY_MIB_INFRA_MISSED_BEACON_COUNT_DEFAULT; + = RAY_MIB_INFRA_MISSED_BEACON_COUNT_V5; MIB5(mib_adhoc_missed_beacon_count) - = RAY_MIB_ADHOC_MISSED_BEACON_COUNT_DEFAULT; - MIB5(mib_country_code) = RAY_MIB_COUNTRY_CODE_DEFAULT; - MIB5(mib_hop_seq) = RAY_MIB_HOP_SEQ_DEFAULT; + = RAY_MIB_ADHOC_MISSED_BEACON_COUNT_V5; + MIB5(mib_country_code) = RAY_MIB_COUNTRY_CODE_V5; + MIB5(mib_hop_seq) = RAY_MIB_HOP_SEQ_V5; MIB5(mib_hop_seq_len) = RAY_MIB_HOP_SEQ_LEN_V5; PUT2(MIB5(mib_cw_max), RAY_MIB_CW_MAX_V5); PUT2(MIB5(mib_cw_min), RAY_MIB_CW_MIN_V5); @@ -993,8 +1008,8 @@ ray_init_download_v5(struct ray_softc *sc, struct ray_comq_entry *com) MIB5(mib_busy_thresh_offset) = RAY_MIB_BUSY_THRESH_OFFSET_DEFAULT; MIB5(mib_sync_thresh) = RAY_MIB_SYNC_THRESH_DEFAULT; MIB5(mib_test_mode) = RAY_MIB_TEST_MODE_DEFAULT; - MIB5(mib_test_min_chan) = RAY_MIB_TEST_MIN_CHAN_DEFAULT; - MIB5(mib_test_max_chan) = RAY_MIB_TEST_MAX_CHAN_DEFAULT; + MIB5(mib_test_min_chan) = RAY_MIB_TEST_MIN_CHAN_DEFAULT; + MIB5(mib_test_max_chan) = RAY_MIB_TEST_MAX_CHAN_DEFAULT; MIB5(mib_allow_probe_resp) = RAY_MIB_ALLOW_PROBE_RESP_DEFAULT; MIB5(mib_privacy_must_start) = com->c_desired.np_priv_start; MIB5(mib_privacy_can_join) = com->c_desired.np_priv_join; @@ -1010,11 +1025,13 @@ ray_init_download_v5(struct ray_softc *sc, struct ray_comq_entry *com) * Download completion routine */ static void -ray_init_download_done(struct ray_softc *sc, size_t ccs) +ray_init_download_done(struct ray_softc *sc, u_int8_t status, size_t ccs) { RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); RAY_COM_CHECK(sc, ccs); + RAY_CCSERR(sc, status, if_oerrors); /* XXX error counter */ + ray_com_ecf_done(sc); } @@ -1029,14 +1046,8 @@ ray_init_mcast(struct ray_softc *sc, struct ray_comq_entry *com) RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); RAY_MAP_CM(sc); - /* - * If card is already running we don't need to reset the list - */ - if ((com->c_flags & RAY_COM_FCHKRUNNING) && - (ifp->if_flags & IFF_RUNNING)) { - ray_com_runq_done(sc); - return; - } + /* If the card already running we might not need to reset the list */ + RAY_COM_CHKRUNNING(sc, com, ifp); /* * Kick the card @@ -1060,16 +1071,15 @@ ray_init_sj(struct ray_softc *sc, struct ray_comq_entry *com) RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); RAY_MAP_CM(sc); + /* If the card already running we might not need to start the n/w */ + RAY_COM_CHKRUNNING(sc, com, ifp); + /* - * If card already running we don't need to start the n/w. + * Set up the right start or join command and determine + * whether we should tell the card about a change in operating + * parameters. */ - if ((com->c_flags & RAY_COM_FCHKRUNNING) && - (ifp->if_flags & IFF_RUNNING)) { - ray_com_runq_done(sc); - return; - } - - sc->sc_havenet = 0; + sc->sc_c.np_havenet = 0; if (sc->sc_d.np_net_type == RAY_MIB_NET_TYPE_ADHOC) ray_ccs_fill(sc, com->c_ccs, RAY_CMD_START_NET); else @@ -1107,7 +1117,7 @@ ray_init_sj(struct ray_softc *sc, struct ray_comq_entry *com) * Complete start command or intermediate step in assoc command */ static void -ray_init_sj_done(struct ray_softc *sc, size_t ccs) +ray_init_sj_done(struct ray_softc *sc, u_int8_t status, size_t ccs) { struct ifnet *ifp = &sc->arpcom.ac_if; @@ -1115,12 +1125,16 @@ ray_init_sj_done(struct ray_softc *sc, size_t ccs) RAY_MAP_CM(sc); RAY_COM_CHECK(sc, ccs); + RAY_CCSERR(sc, status, if_oerrors); /* XXX error counter */ + /* * Read back network parameters that the ECF sets */ SRAM_READ_REGION(sc, ccs, &sc->sc_c.p_1, sizeof(struct ray_cmd_net)); - /* Adjust values for buggy build 4 */ + /* Adjust values for buggy firmware */ + if (sc->sc_c.np_inited == 0x55) + sc->sc_c.np_inited = 0; if (sc->sc_c.np_def_txrate == 0x55) sc->sc_c.np_def_txrate = sc->sc_d.np_def_txrate; if (sc->sc_c.np_encrypt == 0x55) @@ -1144,7 +1158,8 @@ ray_init_sj_done(struct ray_softc *sc, size_t ccs) * we check to see if packets have been queued. */ if (SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_cmd) == RAY_CMD_START_NET) { - sc->sc_havenet = 1; + sc->sc_c.np_havenet = 1; + sc->sc_c.np_framing = sc->sc_d.np_framing; ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; } @@ -1153,28 +1168,121 @@ ray_init_sj_done(struct ray_softc *sc, size_t ccs) } /* - * Runq entry to starting an association with an access point + * Runq entry to authenticate with an access point or another station */ static void -ray_init_assoc(struct ray_softc *sc, struct ray_comq_entry *com) +ray_init_auth(struct ray_softc *sc, struct ray_comq_entry *com) { struct ifnet *ifp = &sc->arpcom.ac_if; - RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); + RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN | RAY_DBG_AUTH, ""); + + /* If card already running we might not need to authenticate */ + RAY_COM_CHKRUNNING(sc, com, ifp); /* - * Don't do anything if we are not in a managed network + * XXX Don't do anything if we are not in a managed network + * + * XXX V4 adhoc does not need this, V5 adhoc unknown */ if (sc->sc_c.np_net_type != RAY_MIB_NET_TYPE_INFRA) { ray_com_runq_done(sc); return; } +/* + * XXX_AUTH need to think of run queue when doing auths from request i.e. would + * XXX_AUTH need to have auth at top of runq? + * XXX_AUTH ditto for sending any auth response packets...what about timeouts? + */ + + /* + * Kick the card + */ +/* XXX_AUTH check exit status and retry or fail as we can't associate without this */ + ray_init_auth_send(sc, sc->sc_c.np_bss_id, IEEE80211_AUTH_OPEN_REQUEST); +} + +/* + * Build and send an authentication packet + * + * If an error occurs, returns 1 else returns 0. + */ +static int +ray_init_auth_send(struct ray_softc *sc, u_int8_t *dst, int sequence) +{ + size_t ccs, bufp; + int pktlen = 0; + + RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN | RAY_DBG_AUTH, ""); + + /* Get a control block */ + if (ray_ccs_tx(sc, &ccs, &bufp)) { + RAY_RECERR(sc, "could not obtain a ccs"); + return (1); + } + + /* Fill the header in */ + bufp = ray_tx_wrhdr(sc, bufp, + IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH, + IEEE80211_FC1_DIR_NODS, + dst, + sc->arpcom.ac_enaddr, + sc->sc_c.np_bss_id); + + /* Add algorithm number */ + SRAM_WRITE_1(sc, bufp + pktlen++, IEEE80211_AUTH_ALG_OPEN); + SRAM_WRITE_1(sc, bufp + pktlen++, 0); + + /* Add sequence number */ + SRAM_WRITE_1(sc, bufp + pktlen++, sequence); + SRAM_WRITE_1(sc, bufp + pktlen++, 0); + + /* Add status code */ + SRAM_WRITE_1(sc, bufp + pktlen++, 0); + SRAM_WRITE_1(sc, bufp + pktlen++, 0); + pktlen += sizeof(struct ieee80211_frame); + + return (ray_tx_send(sc, ccs, pktlen, dst)); +} + +/* + * Complete authentication runq + */ +static void +ray_init_auth_done(struct ray_softc *sc, u_int8_t status) +{ + RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN | RAY_DBG_AUTH, ""); + + if (status != IEEE80211_STATUS_SUCCESS) + RAY_RECERR(sc, "authentication failed with status %d", status); +/* + * XXX_AUTH retry? if not just recall ray_init_auth_send and dont clear runq? + * XXX_AUTH association requires that authenitcation is successful + * XXX_AUTH before we associate, and the runq is the only way to halt the + * XXX_AUTH progress of associate. + * XXX_AUTH In this case I might not need the RAY_AUTH_NEEDED state + */ + ray_com_runq_done(sc); +} + +/* + * Runq entry to starting an association with an access point + */ +static void +ray_init_assoc(struct ray_softc *sc, struct ray_comq_entry *com) +{ + struct ifnet *ifp = &sc->arpcom.ac_if; + + RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); + + /* If the card already running we might not need to associate */ + RAY_COM_CHKRUNNING(sc, com, ifp); + /* - * If card already running we don't need to associate. + * Don't do anything if we are not in a managed network */ - if ((com->c_flags & RAY_COM_FCHKRUNNING) && - (ifp->if_flags & IFF_RUNNING)) { + if (sc->sc_c.np_net_type != RAY_MIB_NET_TYPE_INFRA) { ray_com_runq_done(sc); return; } @@ -1190,13 +1298,15 @@ ray_init_assoc(struct ray_softc *sc, struct ray_comq_entry *com) * Complete association */ static void -ray_init_assoc_done(struct ray_softc *sc, size_t ccs) +ray_init_assoc_done(struct ray_softc *sc, u_int8_t status, size_t ccs) { struct ifnet *ifp = &sc->arpcom.ac_if; RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); RAY_COM_CHECK(sc, ccs); + RAY_CCSERR(sc, status, if_oerrors); /* XXX error counter */ + /* * Hurrah! The network is now active. * @@ -1204,7 +1314,8 @@ ray_init_assoc_done(struct ray_softc *sc, size_t ccs) * packets. Just before we return from the interrupt context * we check to see if packets have been queued. */ - sc->sc_havenet = 1; + sc->sc_c.np_havenet = 1; + sc->sc_c.np_framing = sc->sc_d.np_framing; ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -1321,6 +1432,7 @@ ray_tx(struct ifnet *ifp) struct ray_softc *sc = ifp->if_softc; struct mbuf *m0, *m; struct ether_header *eh; + struct llc *llc; size_t ccs, bufp; int pktlen, len; @@ -1336,15 +1448,18 @@ ray_tx(struct ifnet *ifp) RAY_RECERR(sc, "cannot transmit - not running"); return; } - if (!sc->sc_havenet) { + if (!sc->sc_c.np_havenet) { RAY_RECERR(sc, "cannot transmit - no network"); return; } if (!RAY_ECF_READY(sc)) { /* Can't assume that the ECF is busy because of this driver */ - RAY_RECERR(sc, "cannot transmit - ECF busy"); - sc->tx_timerh = timeout(ray_tx_timo, sc, RAY_TX_TIMEOUT); - return; + if ((sc->tx_timerh.callout == NULL) || + (!callout_active(sc->tx_timerh.callout))) { + sc->tx_timerh = + timeout(ray_tx_timo, sc, RAY_TX_TIMEOUT); + return; + } } else untimeout(ray_tx_timo, sc, sc->tx_timerh); @@ -1361,14 +1476,13 @@ ray_tx(struct ifnet *ifp) /* * Get the mbuf and process it - we have to remember to free the - * ccs if there are any errors + * ccs if there are any errors. */ IF_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) { RAY_CCS_FREE(sc, ccs); return; } - eh = mtod(m0, struct ether_header *); pktlen = m0->m_pkthdr.len; if (pktlen > ETHER_MAX_LEN - ETHER_CRC_LEN) { @@ -1379,8 +1493,17 @@ ray_tx(struct ifnet *ifp) return; } + m0 = m_pullup(m0, sizeof(struct ether_header)); + if (m0 == NULL) { + RAY_RECERR(sc, "could not pullup ether"); + RAY_CCS_FREE(sc, ccs); + ifp->if_oerrors++; + return; + } + eh = mtod(m0, struct ether_header *); + /* - * Write the header according to network type etc. + * Write the 802.11 header according to network type etc. */ if (sc->sc_c.np_net_type == RAY_MIB_NET_TYPE_ADHOC) bufp = ray_tx_wrhdr(sc, bufp, @@ -1406,29 +1529,39 @@ ray_tx(struct ifnet *ifp) eh->ether_shost); /* - * Translation - capability as described earlier - * - * Remove/modify/addto the 802.3 and 802.2 headers as needed. - * - * We've pulled up the mbuf for you. + * Framing * + * Add to the mbuf. */ - if (m0->m_len < sizeof(struct ether_header)) - m0 = m_pullup(m0, sizeof(struct ether_header)); - if (m0 == NULL) { - RAY_RECERR(sc, "could not pullup ether"); - RAY_CCS_FREE(sc, ccs); - ifp->if_oerrors++; - return; - } - switch (sc->framing) { + switch (sc->sc_c.np_framing) { - case SC_FRAMING_WEBGEAR: + case RAY_FRAMING_ENCAPSULATION: /* Nice and easy - nothing! (just add an 802.11 header) */ break; + case RAY_FRAMING_TRANSLATION: + /* + * Drop the first address in the ethernet header and + * write an LLC and SNAP header over the second. + */ + m_adj(m0, ETHER_ADDR_LEN); + if (m0 == NULL) { + RAY_RECERR(sc, "could not get space for 802.2 header"); + RAY_CCS_FREE(sc, ccs); + ifp->if_oerrors++; + return; + } + llc = mtod(m0, struct llc *); + llc->llc_dsap = LLC_SNAP_LSAP; + llc->llc_ssap = LLC_SNAP_LSAP; + llc->llc_control = LLC_UI; + llc->llc_un.type_snap.org_code[0] = 0; + llc->llc_un.type_snap.org_code[1] = 0; + llc->llc_un.type_snap.org_code[2] = 0; + break; + default: - RAY_RECERR(sc, "unknown framing type %d", sc->framing); + RAY_RECERR(sc, "unknown framing type %d", sc->sc_c.np_framing); RAY_CCS_FREE(sc, ccs); ifp->if_oerrors++; m_freem(m0); @@ -1441,6 +1574,7 @@ ray_tx(struct ifnet *ifp) ifp->if_oerrors++; return; } + RAY_MBUF_DUMP(sc, RAY_DBG_TX, m0, "framed packet"); /* * Copy the mbuf to the buffer in common memory @@ -1531,13 +1665,13 @@ ray_tx_wrhdr(struct ray_softc *sc, size_t bufp, u_int8_t type, u_int8_t fc1, u_i static int ray_tx_send(struct ray_softc *sc, size_t ccs, int pktlen, u_int8_t *dst) { - int i = 0; + int i = 0; RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_TX, ""); RAY_MAP_CM(sc); while (!RAY_ECF_READY(sc)) { - DELAY(RAY_ECF_SPIN_DELAY); + DELAY(RAY_ECF_SPIN_DELAY); if (++i > RAY_ECF_SPIN_TRIES) { RAY_RECERR(sc, "ECF busy, dropping packet"); RAY_CCS_FREE(sc, ccs); @@ -1546,7 +1680,7 @@ ray_tx_send(struct ray_softc *sc, size_t ccs, int pktlen, u_int8_t *dst) } if (i != 0) RAY_RECERR(sc, "spun %d times", i); - + SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_len, pktlen); SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_antenna, ray_tx_best_antenna(sc, dst)); @@ -1599,20 +1733,13 @@ found: * Transmit now complete so clear ccs and network flags. */ static void -ray_tx_done(struct ray_softc *sc, size_t ccs) +ray_tx_done(struct ray_softc *sc, u_int8_t status, size_t ccs) { struct ifnet *ifp = &sc->arpcom.ac_if; - char *ss[] = RAY_CCS_STATUS_STRINGS; - u_int8_t status; RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_TX, ""); - RAY_MAP_CM(sc); - status = SRAM_READ_FIELD_1(sc, ccs, ray_cmd, c_status); - if (status != RAY_CCS_STATUS_COMPLETE) { - RAY_RECERR(sc, "tx completed but status is %s", ss[status]); - ifp->if_oerrors++; - } + RAY_CCSERR(sc, status, if_oerrors); RAY_CCS_FREE(sc, ccs); ifp->if_timer = 0; @@ -1784,7 +1911,9 @@ ray_rx_data(struct ray_softc *sc, struct mbuf *m0, u_int8_t siglev, u_int8_t ant struct ifnet *ifp = &sc->arpcom.ac_if; struct ieee80211_frame *header = mtod(m0, struct ieee80211_frame *); struct ether_header *eh; - u_int8_t *sa, *da, *ra, *ta; + struct llc *llc; + u_int8_t *sa = NULL, *da = NULL, *ra = NULL, *ta = NULL; + int trim = 0; RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_RX, ""); @@ -1819,37 +1948,47 @@ ray_rx_data(struct ray_softc *sc, struct mbuf *m0, u_int8_t siglev, u_int8_t ant } /* - * Obtain the .11 addresses. Packets may come via APs so the - * MAC addresses of the source/destination may be different - * from the node that actually sent us the packet. + * Parse the To DS and From DS fields to determine the length + * of the 802.11 header for use later on. + * + * Additionally, furtle out the right destination and + * source MAC addresses for the packet. Packets may come via + * APs so the MAC addresses of the immediate node may be + * different from the node that actually sent us the packet. + * + * da destination address of final recipient + * sa source address of orginator + * ra receiver address of immediate recipient + * ta transmitter address of immediate orginator * - * XXX At present this information is unused, although it is - * XXX available for translation routines to use. + * Address matching is performed on da or sa with the AP or + * BSSID in ra and ta. */ + RAY_MBUF_DUMP(sc, RAY_DBG_RX, m0, "(1) packet before framing"); switch (header->i_fc[1] & IEEE80211_FC1_DIR_MASK) { case IEEE80211_FC1_DIR_NODS: - da = header->i_addr1; - sa = header->i_addr2; - ra = ta = NULL; + da = ra = header->i_addr1; + sa = ta = header->i_addr2; + trim = sizeof(struct ieee80211_frame); RAY_DPRINTF(sc, RAY_DBG_RX, "from %6D to %6D", sa, ":", da, ":"); break; case IEEE80211_FC1_DIR_FROMDS: - da = header->i_addr1; + da = ra = header->i_addr1; ta = header->i_addr2; sa = header->i_addr3; - ra = NULL; + trim = sizeof(struct ieee80211_frame); RAY_DPRINTF(sc, RAY_DBG_RX, "ap %6D from %6D to %6D", ta, ":", sa, ":", da, ":"); break; case IEEE80211_FC1_DIR_TODS: ra = header->i_addr1; - sa = header->i_addr2; + sa = ta = header->i_addr2; da = header->i_addr3; - ta = NULL; + trim = sizeof(struct ieee80211_frame); RAY_DPRINTF(sc, RAY_DBG_RX, "from %6D to %6D ap %6D", sa, ":", da, ":", ra, ":"); break; @@ -1859,36 +1998,85 @@ ray_rx_data(struct ray_softc *sc, struct mbuf *m0, u_int8_t siglev, u_int8_t ant ta = header->i_addr2; da = header->i_addr3; sa = (u_int8_t *)header+1; + trim = sizeof(struct ieee80211_frame) + ETHER_ADDR_LEN; RAY_DPRINTF(sc, RAY_DBG_RX, "from %6D to %6D ap %6D to %6D", sa, ":", da, ":", ta, ":", ra, ":"); break; } /* - * Translation - capability as described earlier + * Framing * - * Each case must remove the 802.11 header and leave an 802.3 - * header in the mbuf copy addresses as needed. + * Each case must leave an Ethernet header and adjust trim. */ - RAY_MBUF_DUMP(sc, RAY_DBG_RX, m0, "DATA packet before framing"); - switch (sc->framing) { + switch (sc->sc_c.np_framing) { - case SC_FRAMING_WEBGEAR: - /* Nice and easy - just trim the 802.11 header */ - m_adj(m0, sizeof(struct ieee80211_frame)); + case RAY_FRAMING_ENCAPSULATION: + /* A NOP as the Ethernet header is in the packet */ + break; + + case RAY_FRAMING_TRANSLATION: + /* Check that we have an LLC and SNAP sequence */ + llc = (struct llc *)((u_int8_t *)header + trim); + if (llc->llc_dsap == LLC_SNAP_LSAP && + llc->llc_ssap == LLC_SNAP_LSAP && + llc->llc_control == LLC_UI && + llc->llc_un.type_snap.org_code[0] == 0 && + llc->llc_un.type_snap.org_code[1] == 0 && + llc->llc_un.type_snap.org_code[2] == 0) { + /* + * This is not magic. RFC1042 header is 8 + * bytes, with the last two bytes being the + * ether type. So all we need is another + * ETHER_ADDR_LEN bytes to write the + * destination into. + */ + trim -= ETHER_ADDR_LEN; + eh = (struct ether_header *)((u_int8_t *)header + trim); + + /* + * Copy carefully to avoid mashing the MAC + * addresses. The address layout in the .11 header + * does make sense, honest, but it is a pain. + * + * NODS da sa no risk + * FROMDS da ta sa sa then da + * DSTODS ra ta da sa sa then da + * TODS ra sa da da then sa + */ + if (sa > da) { + /* Copy sa first */ + bcopy(sa, eh->ether_shost, ETHER_ADDR_LEN); + bcopy(da, eh->ether_dhost, ETHER_ADDR_LEN); + } else { + /* Copy da first */ + bcopy(da, eh->ether_dhost, ETHER_ADDR_LEN); + bcopy(sa, eh->ether_shost, ETHER_ADDR_LEN); + } + + } else { + + /* Assume RAY_FRAMING_ENCAPSULATION */ + RAY_RECERR(sc, + "got encapsulated packet but in translation mode"); + + } break; default: - RAY_RECERR(sc, "unknown framing type %d", sc->framing); + RAY_RECERR(sc, "unknown framing type %d", sc->sc_c.np_framing); ifp->if_ierrors++; m_freem(m0); return; } + RAY_MBUF_DUMP(sc, RAY_DBG_RX, m0, "(2) packet after framing"); /* * Finally, do a bit of house keeping before sending the packet * up the stack. */ + m_adj(m0, trim); + RAY_MBUF_DUMP(sc, RAY_DBG_RX, m0, "(3) packet after trimming"); ifp->if_ipackets++; ray_rx_update_cache(sc, header->i_addr2, siglev, antenna); eh = mtod(m0, struct ether_header *); @@ -1944,6 +2132,7 @@ ray_rx_mgt(struct ray_softc *sc, struct mbuf *m0) case IEEE80211_FC0_SUBTYPE_BEACON: RAY_DPRINTF(sc, RAY_DBG_MGT, "BEACON MGT packet"); + ray_rx_mgt_beacon(sc, m0); break; case IEEE80211_FC0_SUBTYPE_AUTH: @@ -1996,71 +2185,160 @@ ray_rx_mgt(struct ray_softc *sc, struct mbuf *m0) } /* - * Deal with AUTH management packet types + * Deal with BEACON management packet types + * XXX furtle anything interesting out + * XXX Note that there are rules governing what beacons to read + * XXX see 8802 S7.2.3, S11.1.2.3 + * XXX is this actually useful? */ static void -ray_rx_mgt_auth(struct ray_softc *sc, struct mbuf *m0) +ray_rx_mgt_beacon(struct ray_softc *sc, struct mbuf *m0) { struct ieee80211_frame *header = mtod(m0, struct ieee80211_frame *); - ieee80211_mgt_auth_t auth = (u_int8_t *)(header+1); - size_t ccs, bufp; - int pktlen; + ieee80211_mgt_beacon_t beacon = (u_int8_t *)(header+1); + struct ieee80211_information elements; + + u_int64_t *timestamp; RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_MGT, ""); - RAY_MAP_CM(sc); - switch (IEEE80211_AUTH_ALGORITHM(auth)) { - - case IEEE80211_AUTH_ALG_OPEN: - RAY_RECERR(sc, "open system authentication request"); - if (IEEE80211_AUTH_TRANSACTION(auth) == 1) { + timestamp = (u_int64_t *)beacon; - /* XXX see sys/dev/awi/awk.c:awi_{recv|send}_auth */ +RAY_DPRINTF(sc, RAY_DBG_MGT, "timestamp\t0x%x", *timestamp); +RAY_DPRINTF(sc, RAY_DBG_MGT, "interval\t\t0x%x", IEEE80211_BEACON_INTERVAL(beacon)); +RAY_DPRINTF(sc, RAY_DBG_MGT, "capability\t0x%x", IEEE80211_BEACON_CAPABILITY(beacon)); - /* - * Send authentication response if possible. If - * we are out of CCSs we don't to anything, the - * other end will try again. - */ - if (ray_ccs_tx(sc, &ccs, &bufp)) { - return; - } -RAY_DPRINTF(sc, RAY_DBG_MGT, "bufp %x", bufp); + ray_rx_mgt_info(sc, m0, &elements); - bufp = ray_tx_wrhdr(sc, bufp, - IEEE80211_FC0_TYPE_MGT | - IEEE80211_FC0_SUBTYPE_AUTH, - IEEE80211_FC1_DIR_NODS, - header->i_addr2, - header->i_addr1, - header->i_addr3); +} - for (pktlen = 0; pktlen < 6; pktlen++) - SRAM_WRITE_1(sc, bufp+pktlen, 0); - pktlen += sizeof(struct ieee80211_frame); - SRAM_WRITE_1(sc, bufp+2, 2); +static void +ray_rx_mgt_info(struct ray_softc *sc, struct mbuf *m0, struct ieee80211_information *elements) +{ + struct ifnet *ifp = &sc->arpcom.ac_if; + struct ieee80211_frame *header = mtod(m0, struct ieee80211_frame *); + ieee80211_mgt_beacon_t beacon = (u_int8_t *)(header+1); + ieee80211_mgt_beacon_t bp, be; + int len; -RAY_DPRINTF(sc, RAY_DBG_MGT, "dump start %x", bufp-pktlen+6); -RAY_DHEX8(sc, RAY_DBG_MGT, bufp-pktlen+6, pktlen, "AUTH MGT response to Open System request"); - (void)ray_tx_send(sc, ccs, pktlen, header->i_addr2); + RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_MGT, ""); - } else if (IEEE80211_AUTH_TRANSACTION(auth) == 2) { + bp = beacon + 12; + be = mtod(m0, u_int8_t *) + m0->m_len; + + while (bp < be) { + len = *(bp + 1); + RAY_DPRINTF(sc, RAY_DBG_MGT, "id 0x%02x length %d", *bp, len); - /* - * XXX probably need a lot more than this - * XXX like initiating an auth sequence - */ - if (IEEE80211_AUTH_STATUS(auth) != - IEEE80211_STATUS_SUCCESS) - RAY_RECERR(sc, - "authentication failed with status %d", - IEEE80211_AUTH_STATUS(auth)); + switch (*bp) { + + case IEEE80211_ELEMID_SSID: + if (len > IEEE80211_NWID_LEN) { + RAY_RECERR(sc, "bad SSD length: %d from %6D", + len, header->i_addr2, ":"); + } + strncpy(elements->ssid, bp + 2, len); + elements->ssid[len] = 0; + RAY_DPRINTF(sc, RAY_DBG_MGT, + "beacon ssid %s", elements->ssid); + break; + + case IEEE80211_ELEMID_RATES: + RAY_DPRINTF(sc, RAY_DBG_MGT, "rates"); + break; + + case IEEE80211_ELEMID_FHPARMS: + elements->fh.dwell = bp[2] + (bp[3] << 8); + elements->fh.set = bp[4]; + elements->fh.pattern = bp[5]; + elements->fh.index = bp[6]; + RAY_DPRINTF(sc, RAY_DBG_MGT, + "fhparams dwell\t0x%04x", elements->fh.dwell); + RAY_DPRINTF(sc, RAY_DBG_MGT, + "fhparams set\t0x%02x", elements->fh.set); + RAY_DPRINTF(sc, RAY_DBG_MGT, + "fhparams pattern\t0x%02x", elements->fh.pattern); + RAY_DPRINTF(sc, RAY_DBG_MGT, + "fhparams index\t0x%02x", elements->fh.index); + break; + + case IEEE80211_ELEMID_DSPARMS: + RAY_RECERR(sc, "got direct sequence params!"); + break; + case IEEE80211_ELEMID_CFPARMS: + RAY_DPRINTF(sc, RAY_DBG_MGT, "cfparams"); + break; + + case IEEE80211_ELEMID_TIM: + elements->tim.count = bp[2]; + elements->tim.period = bp[3]; + elements->tim.bitctl = bp[4]; + RAY_DPRINTF(sc, RAY_DBG_MGT, + "tim count\t0x%02x", elements->tim.count); + RAY_DPRINTF(sc, RAY_DBG_MGT, + "tim period\t0x%02x", elements->tim.period); + RAY_DPRINTF(sc, RAY_DBG_MGT, + "tim bitctl\t0x%02x", elements->tim.bitctl); +#if RAY_DEBUG & RAY_DBG_MGT + { + int i; + for (i = 5; i < len + 1; i++) + RAY_DPRINTF(sc, RAY_DBG_MGT, + "tim pvt[%03d]\t0x%02x", i-5, bp[i]); + } +#endif (RAY_DEBUG & RAY_DBG_MGT) + break; + + case IEEE80211_ELEMID_IBSSPARMS: + elements->ibss.atim = bp[2] + (bp[3] << 8); + RAY_DPRINTF(sc, RAY_DBG_MGT, + "ibssparams atim\t0x%02x", elements->ibss.atim); + break; + + case IEEE80211_ELEMID_CHALLENGE: + RAY_DPRINTF(sc, RAY_DBG_MGT, "challenge"); + break; + + default: + RAY_RECERR(sc, "reserved MGT element id 0x%x", *bp); + ifp->if_ierrors++;break; } + bp += bp[1] + 2; + } +} + +/* + * Deal with AUTH management packet types + */ +static void +ray_rx_mgt_auth(struct ray_softc *sc, struct mbuf *m0) +{ + struct ieee80211_frame *header = mtod(m0, struct ieee80211_frame *); + ieee80211_mgt_auth_t auth = (u_int8_t *)(header+1); + + RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_AUTH, ""); + + switch (IEEE80211_AUTH_ALGORITHM(auth)) { + + case IEEE80211_AUTH_ALG_OPEN: + RAY_DPRINTF(sc, RAY_DBG_AUTH, + "open system authentication sequence number %d", + IEEE80211_AUTH_TRANSACTION(auth)); + if (IEEE80211_AUTH_TRANSACTION(auth) == + IEEE80211_AUTH_OPEN_REQUEST) { + +/* XXX_AUTH use ray_init_auth_send */ + + } else if (IEEE80211_AUTH_TRANSACTION(auth) == + IEEE80211_AUTH_OPEN_RESPONSE) + ray_init_auth_done(sc, IEEE80211_AUTH_STATUS(auth)); break; case IEEE80211_AUTH_ALG_SHARED: - RAY_RECERR(sc, "shared key authentication request"); + RAY_RECERR(sc, + "shared key authentication sequence number %d", + IEEE80211_AUTH_TRANSACTION(auth)); break; default: @@ -2268,38 +2546,38 @@ ray_intr_ccs(struct ray_softc *sc, u_int8_t cmd, u_int8_t status, size_t ccs) case RAY_CMD_DOWNLOAD_PARAMS: RAY_DPRINTF(sc, RAY_DBG_COM, "START_PARAMS"); - ray_init_download_done(sc, ccs); + ray_init_download_done(sc, status, ccs); break; case RAY_CMD_UPDATE_PARAMS: RAY_DPRINTF(sc, RAY_DBG_COM, "UPDATE_PARAMS"); - ray_upparams_done(sc, ccs); + ray_upparams_done(sc, status, ccs); break; case RAY_CMD_REPORT_PARAMS: RAY_DPRINTF(sc, RAY_DBG_COM, "REPORT_PARAMS"); - ray_repparams_done(sc, ccs); + ray_repparams_done(sc, status, ccs); break; case RAY_CMD_UPDATE_MCAST: RAY_DPRINTF(sc, RAY_DBG_COM, "UPDATE_MCAST"); - ray_mcast_done(sc, ccs); + ray_mcast_done(sc, status, ccs); break; case RAY_CMD_START_NET: case RAY_CMD_JOIN_NET: RAY_DPRINTF(sc, RAY_DBG_COM, "START|JOIN_NET"); - ray_init_sj_done(sc, ccs); + ray_init_sj_done(sc, status, ccs); break; case RAY_CMD_TX_REQ: RAY_DPRINTF(sc, RAY_DBG_COM, "TX_REQ"); - ray_tx_done(sc, ccs); + ray_tx_done(sc, status, ccs); break; case RAY_CMD_START_ASSOC: RAY_DPRINTF(sc, RAY_DBG_COM, "START_ASSOC"); - ray_init_assoc_done(sc, ccs); + ray_init_assoc_done(sc, status, ccs); break; case RAY_CMD_UPDATE_APM: @@ -2345,12 +2623,12 @@ ray_intr_rcs(struct ray_softc *sc, u_int8_t cmd, size_t rcs) case RAY_ECMD_REJOIN_DONE: RAY_DPRINTF(sc, RAY_DBG_RX, "REJOIN_DONE"); - sc->sc_havenet = 1; /* XXX Should not be here but in function */ + sc->sc_c.np_havenet = 1; /* XXX Should not be here but in function */ break; case RAY_ECMD_ROAM_START: RAY_DPRINTF(sc, RAY_DBG_RX, "ROAM_START"); - sc->sc_havenet = 0; /* XXX Should not be here but in function */ + sc->sc_c.np_havenet = 0; /* XXX Should not be here but in function */ break; case RAY_ECMD_JAPAN_CALL_SIGNAL: @@ -2461,11 +2739,13 @@ ray_mcast(struct ray_softc *sc, struct ray_comq_entry *com) * Complete the multicast filter list update */ static void -ray_mcast_done(struct ray_softc *sc, size_t ccs) +ray_mcast_done(struct ray_softc *sc, u_int8_t status, size_t ccs) { - RAY_DPRINTF(sc, RAY_DBG_SUBR, ""); + RAY_DPRINTF(sc, RAY_DBG_SUBR | RAY_DBG_STARTJOIN, ""); RAY_COM_CHECK(sc, ccs); + RAY_CCSERR(sc, status, if_oerrors); /* XXX error counter */ + ray_com_ecf_done(sc); } @@ -2597,6 +2877,12 @@ ray_repparams_user(struct ray_softc *sc, struct ray_param_req *pr) case RAY_MIB_DES_PROMISC: *pr->r_data = sc->sc_d.np_promisc; break; + case RAY_MIB_CUR_FRAMING: + *pr->r_data = sc->sc_c.np_framing; + break; + case RAY_MIB_DES_FRAMING: + *pr->r_data = sc->sc_d.np_framing; + break; default: return (EINVAL); @@ -2653,7 +2939,7 @@ ray_repparams(struct ray_softc *sc, struct ray_comq_entry *com) * Complete the parameter reporting */ static void -ray_repparams_done(struct ray_softc *sc, size_t ccs) +ray_repparams_done(struct ray_softc *sc, u_int8_t status, size_t ccs) { struct ray_comq_entry *com; @@ -2661,6 +2947,8 @@ ray_repparams_done(struct ray_softc *sc, size_t ccs) RAY_MAP_CM(sc); RAY_COM_CHECK(sc, ccs); + RAY_CCSERR(sc, status, if_oerrors); /* XXX error counter */ + com = TAILQ_FIRST(&sc->sc_comq); com->c_pr->r_failcause = SRAM_READ_FIELD_1(sc, ccs, ray_cmd_report, c_failcause); @@ -2697,7 +2985,7 @@ ray_repstats_user(struct ray_softc *sc, struct ray_stats_req *sr) static int ray_upparams_user(struct ray_softc *sc, struct ray_param_req *pr) { - struct ray_comq_entry *com[3]; + struct ray_comq_entry *com[4]; int error, ncom, todo; #define RAY_UPP_SJ 0x1 #define RAY_UPP_PARAMS 0x2 @@ -2771,6 +3059,7 @@ ray_upparams_user(struct ray_softc *sc, struct ray_param_req *pr) } if (todo & RAY_UPP_SJ) { com[ncom++] = RAY_COM_MALLOC(ray_init_sj, 0); + com[ncom++] = RAY_COM_MALLOC(ray_init_auth, 0); com[ncom++] = RAY_COM_MALLOC(ray_init_assoc, 0); } @@ -2815,7 +3104,7 @@ ray_upparams(struct ray_softc *sc, struct ray_comq_entry *com) * Complete the parameter update, note that promisc finishes up here too */ static void -ray_upparams_done(struct ray_softc *sc, size_t ccs) +ray_upparams_done(struct ray_softc *sc, u_int8_t status, size_t ccs) { struct ray_comq_entry *com; @@ -2823,6 +3112,8 @@ ray_upparams_done(struct ray_softc *sc, size_t ccs) RAY_MAP_CM(sc); RAY_COM_CHECK(sc, ccs); + RAY_CCSERR(sc, status, if_oerrors); /* XXX error counter */ + com = TAILQ_FIRST(&sc->sc_comq); switch (SRAM_READ_FIELD_1(sc, ccs, ray_cmd_update, c_paramid)) { @@ -3038,7 +3329,7 @@ ray_com_ecf(struct ray_softc *sc, struct ray_comq_entry *com) RAY_MAP_CM(sc); while (!RAY_ECF_READY(sc)) { - DELAY(RAY_ECF_SPIN_DELAY); + DELAY(RAY_ECF_SPIN_DELAY); if (++i > RAY_ECF_SPIN_TRIES) RAY_PANIC(sc, "spun too long"); } @@ -3288,7 +3579,7 @@ ray_ccs_tx(struct ray_softc *sc, size_t *ccsp, size_t *bufpp) SRAM_WRITE_FIELD_2(sc, ccs, ray_cmd_tx, c_bufp, bufp); SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_tx_rate, sc->sc_c.np_def_txrate); - SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_apm_mode, 0); /* XXX_APM */ + SRAM_WRITE_FIELD_1(sc, ccs, ray_cmd_tx, c_apm_mode, 0); bufp += sizeof(struct ray_tx_phy_header); *ccsp = ccs; @@ -3344,7 +3635,7 @@ ray_res_alloc_am(struct ray_softc *sc) #if RAY_DEBUG & (RAY_DBG_CM | RAY_DBG_BOOTPARAM) { - u_long flags; + u_long flags; u_int32_t offset; CARD_GET_RES_FLAGS(device_get_parent(sc->dev), sc->dev, SYS_RES_MEMORY, sc->am_rid, &flags); diff --git a/sys/dev/ray/if_raydbg.h b/sys/dev/ray/if_raydbg.h index 7dc255d..965a180 100644 --- a/sys/dev/ray/if_raydbg.h +++ b/sys/dev/ray/if_raydbg.h @@ -39,7 +39,7 @@ /* * RAY_DEBUG settings * - * RECERR Recoverable error's, deprecated use RAY_RECERR macro + * AUTH Authentication * SUBR Subroutine entry * BOOTPARAM Startup CM dump * STARTJOIN State transitions for start/join @@ -55,7 +55,7 @@ * TX TX routine info * DCOM dump comq entries */ -#define RAY_DBG_RECERR 0x0001 +#define RAY_DBG_AUTH 0x0001 #define RAY_DBG_SUBR 0x0002 #define RAY_DBG_BOOTPARAM 0x0004 #define RAY_DBG_STARTJOIN 0x0008 @@ -131,12 +131,17 @@ * These override macros defined in if_ray.c to turn them into * debugging ones. */ -#if RAY_DEBUG & RAY_DBG_COM +#if RAY_DEBUG +#define RAY_RECERR(sc, fmt, args...) do { \ + device_printf((sc)->dev, "%s(%d) " fmt "\n", \ + __FUNCTION__ , __LINE__ , ##args); \ +} while (0) +#endif /* RAY_DEBUG */ +#if RAY_DEBUG & RAY_DBG_COM #define RAY_COM_CHECK(sc, com) do { if (RAY_DEBUG & RAY_DBG_COM) { \ ray_com_ecf_check((sc), (com), __FUNCTION__ ); \ } } while (0) - #endif /* RAY_DEBUG & RAY_DBG_COM */ #if RAY_DEBUG & RAY_DBG_MBUF diff --git a/sys/dev/ray/if_raymib.h b/sys/dev/ray/if_raymib.h index 7729786..8657715 100644 --- a/sys/dev/ray/if_raymib.h +++ b/sys/dev/ray/if_raymib.h @@ -220,9 +220,11 @@ struct ray_mib_5 { #define RAY_MIB_CUR_PROMISC 64 #define RAY_MIB_DES_AP_STATUS 65 #define RAY_MIB_DES_PROMISC 66 +#define RAY_MIB_CUR_FRAMING 67 +#define RAY_MIB_DES_FRAMING 68 #define RAY_MIB_LASTUSER 45 -#define RAY_MIB_MAX 66 +#define RAY_MIB_MAX 68 /* * Strings for the MIB @@ -294,7 +296,9 @@ struct ray_mib_5 { "Current AP_STATUS", \ "Current PROMISC", \ "Desired AP_STATUS", \ - "Desired PROMISC" \ + "Desired PROMISC", \ + "Current FRAMING", \ + "Desired FRAMING" \ } #define RAY_MIB_HELP_STRINGS { \ @@ -364,7 +368,9 @@ struct ray_mib_5 { "Current AP_STATUS", \ "Current PROMISC", \ "Desired AP_STATUS", \ - "Desired PROMISC" \ + "Desired PROMISC", \ + "Current FRAMING", \ + "Desired FRAMING" \ } /* @@ -447,7 +453,9 @@ struct ray_mib_5 { {RAY_V4|RAY_V5, 1, 1}, /* RAY_MIB_CUR_AP_STATUS */ \ {RAY_V4|RAY_V5, 1, 1}, /* RAY_MIB_CUR_PROMISC */ \ {RAY_V4|RAY_V5, 1, 1}, /* RAY_MIB_DES_AP_STATUS */ \ -{RAY_V4|RAY_V5, 1, 1} /* RAY_MIB_DES_PROMISC */ \ +{RAY_V4|RAY_V5, 1, 1}, /* RAY_MIB_DES_PROMISC */ \ +{RAY_V4|RAY_V5, 1, 1}, /* RAY_MIB_CUR_FRAMING */ \ +{RAY_V4|RAY_V5, 1, 1} /* RAY_MIB_DES_FRAMING */ \ } /* @@ -480,8 +488,11 @@ struct ray_mib_5 { * 17 June, 1998 */ -/* XXX Obtained by raycontrol _before_ downloading - * # /sys/dev/ray/raycontrol/raycontrol -i ray0 +/* Obtained by raycontrol _before_ downloading + * + * WebGear Aviator + * + * # raycontrol -i ray0 * Firmware version 4 * Network type 0x01 0 Ad hoc, 1 Infrastructure * AP status 0x00 0 Station, 1 Access Point @@ -525,7 +536,56 @@ struct ray_mib_5 { * TEST_MODE 0x00 TEST_MODE * TEST_MIN_CHAN 0x02 TEST_MIN_CHAN * TEST_MAX_CHAN 0x02 TEST_MAX_CHAN -*/ + * + * Raylink + * Firmware version 5 + * Network type 0x01 0 Ad hoc, 1 Infrastructure + * AP status 0x00 0 Station, 1 Access Point + * SSID ESSID1 + * Scan mode 0x01 0 Passive, 1 Active + * APM mode 0x00 0 Off, 1 On + * MAC address 00:00:8f:a8:17:06 + * Fragmentation threshold 0x7fff Bytes + * Dwell time 0x0080 DWELL_TIME + * Beacon period 0x0100 BEACON_PERIOD + * DTIM_INTERVAL 0x01 DTIM_INTERVAL + * MAX_RETRY 0x1f MAX_RETRY + * ACK_TIMO 0x86 ACK_TIMO + * SIFS 0x1c SIFS + * DIFS 0x82 DIFS + * PIFS 0x4e PIFS + * RTS_THRESH 0x7fff RTS_THRESH + * SCAN_DWELL 0x04e2 SCAN_DWELL + * SCAN_MAX_DWELL 0x38a4 SCAN_MAX_DWELL + * ASSOC_TIMO 0x05 ASSOC_TIMO + * ADHOC_SCAN_CYCLE 0x08 ADHOC_SCAN_CYCLE + * INFRA_SCAN_CYCLE 0x02 INFRA_SCAN_CYCLE + * INFRA_SUPER_SCAN_CYCLE 0x08 INFRA_SUPER_SCAN_CYCLE + * PROMISC 0x00 PROMISC + * UNIQ_WORD 0x0cbd UNIQ_WORD + * SLOT_TIME 0x32 SLOT_TIME + * ROAM_LOW_SNR_THRESH 0xff ROAM_LOW_SNR_THRESH + * LOW_SNR_COUNT 0xff LOW_SNR_COUNT + * INFRA_MISSED_BEACON_COUNT 0x02 INFRA_MISSED_BEACON_COUNT + * ADHOC_MISSED_BEACON_COUNT 0xff ADHOC_MISSED_BEACON_COUNT + * COUNTRY_CODE 0x01 COUNTRY_CODE + * HOP_SEQ 0x0b HOP_SEQ + * HOP_SEQ_LEN 0x55 HOP_SEQ_LEN + * CW_MAX 0x003f CW_MAX + * CW_MIN 0x000f CW_MIN + * NOISE_FILTER_GAIN 0x04 NOISE_FILTER_GAIN + * NOISE_LIMIT_OFFSET 0x08 NOISE_LIMIT_OFFSET + * RSSI_THRESH_OFFSET 0x28 RSSI_THRESH_OFFSET + * BUSY_THRESH_OFFSET 0x28 BUSY_THRESH_OFFSET + * SYNC_THRESH 0x07 SYNC_THRESH + * TEST_MODE 0x00 TEST_MODE + * TEST_MIN_CHAN 0x02 TEST_MIN_CHAN + * TEST_MAX_CHAN 0x02 TEST_MAX_CHAN + * ALLOW_PROBE_RESP 0x00 ALLOW_PROBE_RESP + * PRIVACY_MUST_START 0x00 PRIVACY_MUST_START + * PRIVACY_CAN_JOIN 0x00 PRIVACY_CAN_JOIN + * BASIC_RATE_SET 0x02 BASIC_RATE_SET + */ /* * mib_net_type @@ -533,11 +593,13 @@ struct ray_mib_5 { * DOC 0x01 - Defines network type for Start and Join * - Network commands. * - * Symb 0x00 - Adhoc is safer and I ain't got an AP + * As the V4 cards don't do infra we have to use adhoc. For V5 cards + * we follow standard FreeBSD practise and use infrastructure mode. */ #define RAY_MIB_NET_TYPE_ADHOC 0x00 #define RAY_MIB_NET_TYPE_INFRA 0x01 -#define RAY_MIB_NET_TYPE_DEFAULT RAY_MIB_NET_TYPE_ADHOC +#define RAY_MIB_NET_TYPE_V4 RAY_MIB_NET_TYPE_ADHOC +#define RAY_MIB_NET_TYPE_V5 RAY_MIB_NET_TYPE_INFRA /* * mib_ap_status @@ -547,7 +609,8 @@ struct ray_mib_5 { */ #define RAY_MIB_AP_STATUS_TERMINAL 0x00 #define RAY_MIB_AP_STATUS_AP 0x01 -#define RAY_MIB_AP_STATUS_DEFAULT RAY_MIB_AP_STATUS_TERMINAL +#define RAY_MIB_AP_STATUS_V4 RAY_MIB_AP_STATUS_TERMINAL +#define RAY_MIB_AP_STATUS_V5 RAY_MIB_AP_STATUS_TERMINAL /* * mib_ssid @@ -560,8 +623,9 @@ struct ray_mib_5 { * Symb - windows setting comes from the Aviator software v1.1 */ #define RAY_MIB_SSID_WINDOWS "NETWORK_NAME" -#define RAY_MIB_SSID_NOT_WINDOWS "WIRELESS_NETWORK" -#define RAY_MIB_SSID_DEFAULT RAY_MIB_SSID_WINDOWS +#define RAY_MIB_SSID_RAYLINK "ESSID1" +#define RAY_MIB_SSID_V4 RAY_MIB_SSID_WINDOWS +#define RAY_MIB_SSID_V5 RAY_MIB_SSID_RAYLINK /* * mib_scan_mode @@ -572,7 +636,8 @@ struct ray_mib_5 { */ #define RAY_MIB_SCAN_MODE_PASSIVE 0x00 #define RAY_MIB_SCAN_MODE_ACTIVE 0x01 -#define RAY_MIB_SCAN_MODE_DEFAULT RAY_MIB_SCAN_MODE_ACTIVE +#define RAY_MIB_SCAN_MODE_V4 RAY_MIB_SCAN_MODE_ACTIVE +#define RAY_MIB_SCAN_MODE_V5 RAY_MIB_SCAN_MODE_ACTIVE /* * mib_apm_mode @@ -584,7 +649,8 @@ struct ray_mib_5 { */ #define RAY_MIB_APM_MODE_NONE 0x00 #define RAY_MIB_APM_MODE_POWERSAVE 0x01 -#define RAY_MIB_APM_MODE_DEFAULT RAY_MIB_APM_MODE_NONE +#define RAY_MIB_APM_MODE_V4 RAY_MIB_APM_MODE_NONE +#define RAY_MIB_APM_MODE_V5 RAY_MIB_APM_MODE_NONE /* * mib_mac_addr @@ -609,7 +675,8 @@ struct ray_mib_5 { #define RAY_MIB_FRAG_THRESH_MINIMUM 0 #define RAY_MIB_FRAG_THRESH_MAXIMUM 2346 #define RAY_MIB_FRAG_THRESH_DISABLE 0x7fff -#define RAY_MIB_FRAG_THRESH_DEFAULT RAY_MIB_FRAG_THRESH_DISABLE +#define RAY_MIB_FRAG_THRESH_V4 RAY_MIB_FRAG_THRESH_DISABLE +#define RAY_MIB_FRAG_THRESH_V5 RAY_MIB_FRAG_THRESH_DISABLE /* * mib_dwell_time @@ -664,7 +731,7 @@ struct ray_mib_5 { #define RAY_MIB_BEACON_PERIOD_MINIMUM 1 #define RAY_MIB_BEACON_PERIOD_MAXIMUM 0xffff #define RAY_MIB_BEACON_PERIOD_V4 0x0001 -#define RAY_MIB_BEACON_PERIOD_V5 RAY_MIB_DWELL_TIME_V5 +#define RAY_MIB_BEACON_PERIOD_V5 (2*RAY_MIB_DWELL_TIME_V5) /* * mib_dtim_interval @@ -680,7 +747,8 @@ struct ray_mib_5 { */ #define RAY_MIB_DTIM_INTERVAL_MINIMUM 1 #define RAY_MIB_DTIM_INTERVAL_MAXIMUM 255 -#define RAY_MIB_DTIM_INTERVAL_DEFAULT 0x01 +#define RAY_MIB_DTIM_INTERVAL_V4 0x01 +#define RAY_MIB_DTIM_INTERVAL_V5 0x01 /* * mib_max_retry @@ -696,7 +764,8 @@ struct ray_mib_5 { */ #define RAY_MIB_MAX_RETRY_MINIMUM 0 #define RAY_MIB_MAX_RETRY_MAXIMUM 255 -#define RAY_MIB_MAX_RETRY_DEFAULT 0x07 +#define RAY_MIB_MAX_RETRY_V4 0x07 +#define RAY_MIB_MAX_RETRY_V5 0x1f /* * mib_ack_timo @@ -714,7 +783,8 @@ struct ray_mib_5 { */ #define RAY_MIB_ACK_TIMO_MINIMUM 0 #define RAY_MIB_ACK_TIMO_MAXIMUM 255 -#define RAY_MIB_ACK_TIMO_DEFAULT 0xa3 +#define RAY_MIB_ACK_TIMO_V4 0xa3 +#define RAY_MIB_ACK_TIMO_V5 0x86 /* * mib_sifs @@ -729,7 +799,8 @@ struct ray_mib_5 { */ #define RAY_MIB_SIFS_MINIMUM 28 #define RAY_MIB_SIFS_MAXIMUM 62 -#define RAY_MIB_SIFS_DEFAULT 0x1d +#define RAY_MIB_SIFS_V4 0x1d +#define RAY_MIB_SIFS_V5 0x1c /* * mib_difs @@ -738,7 +809,8 @@ struct ray_mib_5 { */ #define RAY_MIB_DIFS_MINIMUM 130 #define RAY_MIB_DIFS_MAXIMUM 255 -#define RAY_MIB_DIFS_DEFAULT 0x82 +#define RAY_MIB_DIFS_V4 0x82 +#define RAY_MIB_DIFS_V5 0x82 /* * mib_pifs @@ -766,7 +838,8 @@ struct ray_mib_5 { #define RAY_MIB_RTS_THRESH_MINIMUM 0 #define RAY_MIB_RTS_THRESH_MAXIMUM 2346 #define RAY_MIB_RTS_THRESH_DISABLE 0x7fff -#define RAY_MIB_RTS_THRESH_DEFAULT RAY_MIB_RTS_THRESH_DISABLE +#define RAY_MIB_RTS_THRESH_V4 RAY_MIB_RTS_THRESH_DISABLE +#define RAY_MIB_RTS_THRESH_V5 RAY_MIB_RTS_THRESH_DISABLE /* * mib_scan_dwell @@ -815,7 +888,8 @@ struct ray_mib_5 { */ #define RAY_MIB_ASSOC_TIMO_MINIMUM 0 #define RAY_MIB_ASSOC_TIMO_MAXIMUM 255 -#define RAY_MIB_ASSOC_TIMO_DEFAULT 0x05 +#define RAY_MIB_ASSOC_TIMO_V4 0x05 +#define RAY_MIB_ASSOC_TIMO_V5 0x05 /* * mib_adhoc_scan_cycle @@ -827,7 +901,8 @@ struct ray_mib_5 { */ #define RAY_MIB_ADHOC_SCAN_CYCLE_MINIMUM 1 #define RAY_MIB_ADHOC_SCAN_CYCLE_MAXIMUM 255 -#define RAY_MIB_ADHOC_SCAN_CYCLE_DEFAULT 0x08 +#define RAY_MIB_ADHOC_SCAN_CYCLE_V4 0x08 +#define RAY_MIB_ADHOC_SCAN_CYCLE_V5 0x08 /* * mib_infra_scan_cycle @@ -839,7 +914,8 @@ struct ray_mib_5 { */ #define RAY_MIB_INFRA_SCAN_CYCLE_MINIMUM 1 #define RAY_MIB_INFRA_SCAN_CYCLE_MAXIMUM 255 -#define RAY_MIB_INFRA_SCAN_CYCLE_DEFAULT 0x02 +#define RAY_MIB_INFRA_SCAN_CYCLE_V4 0x02 +#define RAY_MIB_INFRA_SCAN_CYCLE_V5 0x02 /* * mib_infra_super_scan_cycle @@ -850,7 +926,8 @@ struct ray_mib_5 { */ #define RAY_MIB_INFRA_SUPER_SCAN_CYCLE_MINIMUM 1 #define RAY_MIB_INFRA_SUPER_SCAN_CYCLE_MAXIMUM 255 -#define RAY_MIB_INFRA_SUPER_SCAN_CYCLE_DEFAULT 0x08 +#define RAY_MIB_INFRA_SUPER_SCAN_CYCLE_V4 0x08 +#define RAY_MIB_INFRA_SUPER_SCAN_CYCLE_V5 0x08 /* * mib_promisc @@ -860,7 +937,8 @@ struct ray_mib_5 { */ #define RAY_MIB_PROMISC_DISABLED 0 #define RAY_MIB_PROMISC_ENABLED 1 -#define RAY_MIB_PROMISC_DEFAULT 0x00 +#define RAY_MIB_PROMISC_V4 0x00 +#define RAY_MIB_PROMISC_V5 0x00 /* * mib_uniq_word @@ -870,7 +948,8 @@ struct ray_mib_5 { */ #define RAY_MIB_UNIQ_WORD_MINIMUM 0 #define RAY_MIB_UNIQ_WORD_MAXIMUM 0xffff -#define RAY_MIB_UNIQ_WORD_DEFAULT 0x0cbd +#define RAY_MIB_UNIQ_WORD_V4 0x0cbd +#define RAY_MIB_UNIQ_WORD_V5 0x0cbd /* * mib_slot_time @@ -908,7 +987,8 @@ struct ray_mib_5 { #define RAY_MIB_ROAM_LOW_SNR_THRESH_MINIMUM 0 #define RAY_MIB_ROAM_LOW_SNR_THRESH_MAXIMUM 255 #define RAY_MIB_ROAM_LOW_SNR_THRESH_DISABLED 0xff -#define RAY_MIB_ROAM_LOW_SNR_THRESH_DEFAULT RAY_MIB_ROAM_LOW_SNR_THRESH_DISABLED +#define RAY_MIB_ROAM_LOW_SNR_THRESH_V4 RAY_MIB_ROAM_LOW_SNR_THRESH_DISABLED +#define RAY_MIB_ROAM_LOW_SNR_THRESH_V5 RAY_MIB_ROAM_LOW_SNR_THRESH_DISABLED /* * mib_low_snr_count @@ -929,7 +1009,8 @@ struct ray_mib_5 { #define RAY_MIB_LOW_SNR_COUNT_MINIMUM 0 #define RAY_MIB_LOW_SNR_COUNT_MAXIMUM 255 #define RAY_MIB_LOW_SNR_COUNT_DISABLED 0xff -#define RAY_MIB_LOW_SNR_COUNT_DEFAULT RAY_MIB_LOW_SNR_COUNT_DISABLED +#define RAY_MIB_LOW_SNR_COUNT_V4 RAY_MIB_LOW_SNR_COUNT_DISABLED +#define RAY_MIB_LOW_SNR_COUNT_V5 RAY_MIB_LOW_SNR_COUNT_DISABLED /* * mib_infra_missed_beacon_count @@ -947,7 +1028,8 @@ struct ray_mib_5 { */ #define RAY_MIB_INFRA_MISSED_BEACON_COUNT_MINIMUM 0 #define RAY_MIB_INFRA_MISSED_BEACON_COUNT_MAXIMUM 255 -#define RAY_MIB_INFRA_MISSED_BEACON_COUNT_DEFAULT 0x05 +#define RAY_MIB_INFRA_MISSED_BEACON_COUNT_V4 0x05 +#define RAY_MIB_INFRA_MISSED_BEACON_COUNT_V5 0x02 /* * mib_adhoc_missed_beacon_count @@ -960,7 +1042,8 @@ struct ray_mib_5 { #define RAY_MIB_ADHOC_MISSED_BEACON_COUNT_MINIMUM 0 #define RAY_MIB_ADHOC_MISSED_BEACON_COUNT_MAXIMUM 255 #define RAY_MIB_ADHOC_MISSED_BEACON_COUNT_DISABLED 0xff -#define RAY_MIB_ADHOC_MISSED_BEACON_COUNT_DEFAULT RAY_MIB_ADHOC_MISSED_BEACON_COUNT_DISABLED +#define RAY_MIB_ADHOC_MISSED_BEACON_COUNT_V4 RAY_MIB_ADHOC_MISSED_BEACON_COUNT_DISABLED +#define RAY_MIB_ADHOC_MISSED_BEACON_COUNT_V5 RAY_MIB_ADHOC_MISSED_BEACON_COUNT_DISABLED /* * mib_country_code @@ -982,7 +1065,8 @@ struct ray_mib_5 { #define RAY_MIB_COUNTRY_CODE_ISRAEL 0x07 #define RAY_MIB_COUNTRY_CODE_AUSTRALIA 0x08 #define RAY_MIB_COUNTRY_CODE_JAPAN_TEST 0x09 -#define RAY_MIB_COUNTRY_CODE_DEFAULT RAY_MIB_COUNTRY_CODE_USA +#define RAY_MIB_COUNTRY_CODE_V4 RAY_MIB_COUNTRY_CODE_USA +#define RAY_MIB_COUNTRY_CODE_V5 RAY_MIB_COUNTRY_CODE_USA /* * mib_hop_seq @@ -994,7 +1078,8 @@ struct ray_mib_5 { */ #define RAY_MIB_HOP_SEQ_MINIMUM 6 #define RAY_MIB_HOP_SEQ_MAXIMUM 72 -#define RAY_MIB_HOP_SEQ_DEFAULT 0x0b +#define RAY_MIB_HOP_SEQ_V4 0x0b +#define RAY_MIB_HOP_SEQ_V5 0x04 /* * mib_hop_seq_len @@ -1009,8 +1094,6 @@ struct ray_mib_5 { #define RAY_MIB_HOP_SEQ_LEN_V4 0x4e #define RAY_MIB_HOP_SEQ_LEN_V5 0x4f -/* XXX need to update these to the spec. XXX */ - /* * All from here down are the same in Linux/NetBSD and seem to be sane. */ diff --git a/sys/dev/ray/if_rayvar.h b/sys/dev/ray/if_rayvar.h index cc8561c..a5a09b5 100644 --- a/sys/dev/ray/if_rayvar.h +++ b/sys/dev/ray/if_rayvar.h @@ -33,7 +33,7 @@ */ /* - * Network parameters, used twice in sotfc to store what we want and what + * Network parameters, used twice in softc to store what we want and what * we have. * * The current parameters are ONLY valid in a function called from the runq @@ -44,7 +44,10 @@ struct ray_nw_param { struct ray_net_params \ p_2; u_int8_t np_ap_status; - int np_promisc; + int np_promisc; /* Promiscious mode status */ + int np_framing; /* Packet framing types */ + int np_auth; /* Authentication status */ + int np_havenet; /* True if we have a network */ }; #define np_upd_param p_1.c_upd_param #define np_bss_id p_1.c_bss_id @@ -80,10 +83,9 @@ struct ray_softc { struct resource* irq_res; /* Resource for irq */ void * irq_handle; /* Handle for irq handler */ + u_int8_t sc_ccsinuse[64];/* ccss' in use -- not for tx */ u_char sc_gone; /* 1 = Card bailed out */ - int framing; /* Packet framing types */ - struct ray_ecf_startup_v5 sc_ecf_startup; /* Startup info from card */ @@ -92,8 +94,6 @@ struct ray_softc { struct ray_nw_param sc_c; /* current network params */ struct ray_nw_param sc_d; /* desired network params */ - int sc_havenet; /* true if we have a network */ - u_int8_t sc_ccsinuse[64];/* ccss' in use -- not for tx */ int sc_checkcounters; u_int64_t sc_rxoverflow; /* Number of rx overflows */ @@ -128,12 +128,6 @@ struct ray_comq_entry { }; /* - * Framing types - */ -/* XXX maybe better as part of the if structure? */ -#define SC_FRAMING_WEBGEAR 0 - -/* * Macro's and constants */ static int mib_info[RAY_MIB_MAX+1][3] = RAY_MIB_INFO; @@ -183,6 +177,17 @@ static int mib_info[RAY_MIB_MAX+1][3] = RAY_MIB_INFO; #define SRAM_WRITE_FIELD_N(sc, off, s, f, p, n) \ SRAM_WRITE_REGION((sc), (off) + offsetof(struct s, f), (p), (n)) +/* Framing types */ +/* XXX maybe better as part of the if structure? */ +#define RAY_FRAMING_ENCAPSULATION 0 +#define RAY_FRAMING_TRANSLATION 1 + +/* Authentication states */ +#define RAY_AUTH_UNAUTH 0 +#define RAY_AUTH_WAITING 1 +#define RAY_AUTH_AUTH 2 +#define RAY_AUTH_NEEDED 3 + /* Flags for runq entries */ #define RAY_COM_FWOK 0x0001 /* Wakeup on completion */ #define RAY_COM_FRUNNING 0x0002 /* This one running */ @@ -263,6 +268,24 @@ static int mib_info[RAY_MIB_MAX+1][3] = RAY_MIB_INFO; RAY_PRINTF(sc, "got error from runq 0x%x", (error)); \ } while (0) +/* + * There are a number of entry points into the ray_init_xxx routines. + * These can be classed into two types: a) those that happen as a result + * of a change to the cards operating parameters (e.g. BSSID change), and + * b) those that happen as a result of a change to the interface parameters + * (e.g. a change to the IP address). The second set of entries need not + * send a command to the card when the card is IFF_RUNNING. The + * RAY_COM_FCHKRUNNING flags indicates when the RUNNING flag should be + * checked, and this macro does the necessary check and command abort. + */ +#define RAY_COM_CHKRUNNING(sc, com, ifp) do { \ + if (((com)->c_flags & RAY_COM_FCHKRUNNING) && \ + ((ifp)->if_flags & IFF_RUNNING)) { \ + ray_com_runq_done(sc); \ + return; \ +} } while (0) + + #define RAY_COM_INIT(com, function, flags) \ ray_com_init((com), (function), (flags), __STRING(function)); @@ -284,6 +307,19 @@ static int mib_info[RAY_MIB_MAX+1][3] = RAY_MIB_INFO; } } while (0) #endif /* RAY_RECERR */ +/* XXX this should be in CCSERR but don't work - probably need to use ##ifp->(iferrcounter)++; \*/ +#ifndef RAY_CCSERR +#define RAY_CCSERR(sc, status, iferrcounter) do { \ + struct ifnet *ifp = &(sc)->arpcom.ac_if; \ + char *ss[] = RAY_CCS_STATUS_STRINGS; \ + if ((status) != RAY_CCS_STATUS_COMPLETE) { \ + if (ifp->if_flags & IFF_DEBUG) { \ + device_printf((sc)->dev, \ + "%s(%d) ECF command completed with status %s\n", \ + __FUNCTION__ , __LINE__ , ss[(status)]); \ +} } } while (0) +#endif /* RAY_CCSERR */ + #ifndef RAY_MAP_CM #define RAY_MAP_CM(sc) #endif /* RAY_MAP_CM */ |