Author: wmb Date: 2009-05-13 00:53:43 +0200 (Wed, 13 May 2009) New Revision: 1179
Added: dev/libertas.fth dev/mmc/sdhci/mv8686/ dev/mmc/sdhci/mv8686/build/ dev/mmc/sdhci/mv8686/common.fth dev/mmc/sdhci/mv8686/fw8686.fth dev/mmc/sdhci/mv8686/mv8686.bth dev/mmc/sdhci/mv8686/mv8686.fth dev/mmc/sdhci/mv8686/queue.fth dev/mmc/sdhci/mv8686/sdio.fth dev/mmc/sdhci/sdhci2.bth Modified: dev/mmc/sdhci/sdhci.fth dev/mmc/sdhci/sdmmc.fth dev/mmc/sdhci/selftest.fth dev/usb2/device/wlan/common.fth dev/usb2/device/wlan/fw8388.fth dev/usb2/device/wlan/usb8388.bth dev/usb2/device/wlan/usb8388.fth dev/usb2/device/wlan/wlan.fth Log: SD and Libertas - Big rearrangement of Marvel Wireless driver and of the SDHCI driver to support the wireless on both USB and SD, while sharing as much code as possible.
Added: dev/libertas.fth =================================================================== --- dev/libertas.fth (rev 0) +++ dev/libertas.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,1720 @@ +purpose: Marvel "Libertas" wireless network driver common code +\ See license at end of file + +headers +hex + +\ **************** WPA and WPA2 are not functional yet ****************** + +\ ======================================================================= +\ Usage: +\ +\ Before probe-pci, reset-wlan. +\ Before using the driver, set wlan-* environment variables. +\ ======================================================================= + +\ Interface to /supplicant support package +0 value supplicant-ih +: $call-supplicant ( ...$ -- ... ) supplicant-ih $call-method ; +: do-associate ( -- flag ) " do-associate" $call-supplicant ; +: process-eapol ( adr len -- ) " process-eapol" $call-supplicant ; +: .scan ( adr -- ) " .scan" $call-supplicant ; + +defer load-all-fw ( -- error? ) ' false to load-all-fw +defer ?process-eapol ['] 2drop to ?process-eapol + +0 value outbuf +d# 2048 value /outbuf \ Power of 2 larger than max-frame-size + \ Override as necessary + +d# 2048 value /inbuf \ Power of 2 larger than max-frame-size + \ Override as necessary + +: init-buf ( -- ) + outbuf 0= if /outbuf dma-alloc to outbuf then +; +: free-buf ( -- ) + outbuf if outbuf /outbuf dma-free 0 to outbuf then +; + +\ ======================================================================= +\ Driver variables +\ ======================================================================= + +\ driver-state bit definitions +0000 constant ds-not-ready \ Initial state +0001 constant ds-ready \ Firmware has been downloaded +0010 constant ds-connected-mask \ Associated or joined +0010 constant ds-associated +8000 constant ds-disconnected \ Disconnected + +ds-not-ready value driver-state + +: set-driver-state ( bit-mask -- ) driver-state or to driver-state ; +: reset-driver-state ( bit-mask -- ) invert driver-state and to driver-state ; + +\ bss-type values +1 constant bss-type-managed +2 constant bss-type-adhoc +bss-type-managed value bss-type + +\ WPA/WPA2 keys +0 value ktype \ Key type +0 value ctype-g \ Group (multicast) cipher type +0 value ctype-p \ Pairwise (unicast) cipher type + +\ ktype values +0 constant kt-wep +1 constant kt-wpa +2 constant kt-wpa2 +h# ff constant kt-none + +\ ctype-x values +0 constant ct-none +1 constant ct-tkip +2 constant ct-aes + +\ WEP keys +1 constant TYPE_WEP_40_BIT +2 constant TYPE_WEP_104_BIT + +0 value wep-idx +d# 13 buffer: wep1 0 constant /wep1 +d# 13 buffer: wep2 0 constant /wep2 +d# 13 buffer: wep3 0 constant /wep3 +d# 13 buffer: wep4 0 constant /wep4 +: wep1$ ( -- $ ) wep1 /wep1 ; +: wep2$ ( -- $ ) wep2 /wep2 ; +: wep3$ ( -- $ ) wep3 /wep3 ; +: wep4$ ( -- $ ) wep4 /wep4 ; + +/mac-adr buffer: target-mac +: target-mac$ ( -- $ ) target-mac /mac-adr ; + +0 value #mc-adr \ Actual number of set multicast addresses +d# 32 dup constant #max-mc-adr \ Maximum number of multicast addresses +/mac-adr * dup constant /mc-adrs + buffer: mc-adrs \ Buffer of multicast addresses + +d# 256 buffer: ssid +0 value /ssid +: ssid$ ( -- $ ) ssid /ssid ; + +0 value channel + +d# 80 buffer: wpa-ie \ WPA IE saved for EAPOL phases +0 value /wpa-ie + +external +: wpa-ie$ ( -- adr len ) wpa-ie /wpa-ie ; +headers + +\ Data rates +d# 14 constant #rates +create supported-rates 82 c, 84 c, 8b c, 96 c, 0c c, 12 c, 18 c, 24 c, + 30 c, 48 c, 60 c, 6c c, 00 c, 00 c, +#rates buffer: common-rates + +external +: supported-rates$ ( -- adr len ) supported-rates #rates ; +: set-common-rates ( adr len -- ) + common-rates #rates erase + #rates min common-rates swap move +; +headers + +\ Miscellaneous +0 value preamble \ 0=long, 2=short, 4=auto +0 value auth-mode \ 0: open; 1: shared key; 2: EAP +h# 401 value cap \ Capabilities +3 instance value mac-ctrl \ MAC control + +external +: set-preamble ( preamble -- ) to preamble ; +: set-cap ( cap -- ) to cap ; +: set-auth-mode ( amode -- ) to auth-mode ; +headers + +: marvel-link-up? ( -- flag ) driver-state ds-ready > ; + +' marvel-link-up? to link-up? + +\ ========================================================================= +\ Firmware Command +\ ========================================================================= + +struct + /fw-transport + + 2 field >fw-cmd \ Start of command header + 2 field >fw-len + 2 field >fw-seq + 2 field >fw-result +dup constant /fw-cmd +dup 4 - constant /fw-cmd-hdr \ Command header len (less /fw-transport) + 0 field >fw-data \ Command payload starts here +drop + +: outbuf-out ( -- error? ) + outbuf dup >fw-len le-w@ /fw-transport + cmd-out +; + + +0 constant ACTION_GET +1 constant ACTION_SET +2 constant ACTION_ADD +3 constant ACTION_HALT +4 constant ACTION_REMOVE +8 constant ACTION_USE_DEFAULT + +-1 value fw-seq + +: fw-seq++ ( -- seq ) fw-seq 1+ dup to fw-seq ; + +d# 30 constant resp-wait-tiny +d# 1,000 constant resp-wait-short +d# 10,000 constant resp-wait-long +resp-wait-short instance value resp-wait + +/inbuf instance buffer: respbuf +0 instance value /respbuf + +\ ========================================================================= +\ Transmit Packet Descriptor +\ ========================================================================= + +struct + /fw-transport + + 4 field >tx-stat + 4 field >tx-ctrl + 4 field >tx-offset + 2 field >tx-len + 6 field >tx-mac + 1 field >tx-priority + 1 field >tx-pwr + 1 field >tx-delay \ in 2ms + 1+ + 1+ \ tx-mesh must be 0 + 1+ \ tx-mesh must be 0 + 1 field >tx-mesh-ttl + 1+ \ Just for alignment + 0 field >tx-pkt +constant /tx-hdr + +0 constant tx-ctrl \ Tx rates, etc + +\ The Libertas FW is currently abusing the WDS flag to mean "send on the mesh". +\ At some point a separate mesh flag might be defined ... +h# 20000 constant TX_WDS + +: mesh-on? ( -- flag ) tx-ctrl TX_WDS and 0<> ; + +: wrap-msg ( adr len -- adr' len' ) + outbuf /tx-hdr erase ( adr len ) + over outbuf >tx-mac /mac-adr move ( adr len ) + dup outbuf >tx-len le-w! ( adr len ) + tuck outbuf >tx-pkt swap move ( len ) + + /tx-hdr 4 - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-ctrl field + tx-ctrl outbuf >tx-ctrl le-l! ( len ) + + mesh-on? if 1 outbuf >tx-mesh-ttl c! then ( len ) + + outbuf swap /tx-hdr + ( adr' len' ) +; + +\ ========================================================================= +\ Receive Packet Descriptor +\ ========================================================================= + +true instance value got-data? +0 instance value /data +0 instance value data + +\ Receive packet descriptor +struct + /fw-transport + + 2 field >rx-stat + 1 field >rx-snr + 1 field >rx-ctrl + 2 field >rx-len + 1 field >rx-nf + 1 field >rx-rate + 4 field >rx-offset + 1 field >rx-type + 3 + + 1 field >rx-priority + 3 + +\ dup constant /rx-desc +\ 6 field >rx-dst-mac +\ 6 field >rx-src-mac +\ 0 field >rx-data-no-snap +\ 2 field >rx-pkt-len \ pkt len from >rx-snap-hdr +\ 6 field >rx-snap-hdr +\ 0 field >rx-data +d# 22 + \ Size of an Ethernet header with SNAP +constant /rx-min + +\ >rx-stat constants +1 constant rx-stat-ok +2 constant rx-stat-multicast + +: snap-header " "(aa aa 03 00 00 00)" ; + +: rx-rate$ ( -- adr len ) " 1 25.5 11 ? 6 9 12 18 24 36 48 54 ? ? ?" ; +: .rx-rate ( rate -- ) h# f and 3 * rx-rate$ drop + 3 type ; + +: .rx-desc ( adr -- ) + debug? 0= if drop exit then + ?cr + ." Rx status: " dup >rx-stat le-w@ u. cr + ." Rx offset: " dup >rx-offset le-l@ u. cr + ." Rx len: " dup >rx-len le-w@ u. cr + ." Rx SNR: " dup >rx-snr c@ .d ." dB" cr + ." Rx noise floor: -" dup >rx-nf c@ .d ." dBm" cr + ." Rx rate: " dup >rx-rate c@ .rx-rate ." Mbps" cr + ." Rx priority: " dup >rx-priority c@ u. cr + drop +; + +: unwrap-pkt ( adr len -- data-adr data-len ) + /rx-min < if drop 0 0 then \ Invalid packet: too small + + \ Go to the payload, skipping the descriptor header + dup dup >rx-offset le-l@ + la1+ ( adr data-adr ) + swap >rx-len le-w@ ( data-adr data-len ) + + \ Remove snap header by moving the MAC addresses up + \ That's faster than moving the contents down + over d# 14 + snap-header comp 0= if ( data-adr data-len ) + over dup 8 + d# 12 move ( data-adr data-len ) + 8 /string ( adr' len' ) + then +; + +: process-data ( adr len -- ) + 2dup vdump ( adr len ) + over .rx-desc ( adr len ) + + over >rx-stat le-w@ rx-stat-ok <> if 2drop exit then + + unwrap-pkt to /data to data ( ) + + true to got-data? \ do-process-eapol may unset this + + \ Check the Ethernet type field for EAPOL messages + data d# 12 + be-w@ h# 888e = if \ Pass EAPOL messages to supplicant + data /data ?process-eapol + then +; + +: do-process-eapol ( adr len -- ) false to got-data? process-eapol ; + +\ ========================================================================= +\ Generic commands & responses +\ ========================================================================= + +0 value x \ Temporary variables to assist command creation +0 value /x + +: set-fw-data-x ( -- ) outbuf >fw-data to x /fw-cmd-hdr to /x ; +: 'x ( -- adr ) x /x + ; +: +x ( n -- ) /x + to /x ; +: +x$ ( $ -- ) 'x swap dup +x move ; +: +xl ( n -- ) 'x le-l! /l +x ; +: +xw ( n -- ) 'x le-w! /w +x ; +: +xb ( n -- ) 'x c! /c +x ; +: +xbl ( n -- ) 'x be-l! /l +x ; +: +xerase ( n -- ) 'x over erase +x ; + +: .cmd ( cmd -- ) + debug? 0= if drop exit then + ?cr + case + 0003 of ." CMD_GET_HW_SPEC" endof + 0005 of ." CMD_802_11_RESET" endof + 0006 of ." CMD_802_11_SCAN" endof + 000b of ." CMD_802_11_GET_LOG" endof + 0010 of ." CMD_MAC_MULTICAST_ADR" endof + 0011 of ." CMD_802_11_AUTHENTICATE" endof + 0013 of ." CMD_802_11_SET_WEP" endof + 0016 of ." CMD_802_11_SNMP_MIB" endof + 0019 of ." CMD_MAC_REG_ACCESS" endof + 001a of ." CMD_BBP_REG_ACCESS" endof + 001b of ." CMD_RF_REG_ACCESS" endof + 001c of ." CMD_802_11_RADIO_CONTROL" endof + 001d of ." CMD_802_11_RF_CHANNEL" endof + 001e of ." CMD_802_11_TX_POWER" endof + 001f of ." CMD_802_11_RSSI" endof + 0020 of ." CMD_802_11_RF_ANTENNA" endof + 0021 of ." CMD_802_11_PS_MODE" endof + 0022 of ." CMD_802_11_DATA_RATE" endof + 0024 of ." CMD_802_11_DEAUTHENTICATE" endof + 0026 of ." CMD_802_11_DISASSOCIATE" endof + 0028 of ." CMD_MAC_CONTROL" endof + 002b of ." CMD_802_11_AD_HOC_START" endof + 002c of ." CMD_802_11_AD_HOC_JOIN" endof + 002f of ." CMD_802_11_ENABLE_RSN" endof + 003e of ." CMD_802_11_DEEP_SLEEP" endof + 0040 of ." CMD_802_11_AD_HOC_STOP" endof + 0043 of ." CMD_802_11_HOST_SLEEP_CFG" endof + 0044 of ." CMD_802_11_WAKEUP_CONFIRM" endof + 004c of ." CMD_802_11_RGN_CODE" endof + 004d of ." CMD_802_11_MAC_ADDR" endof + 0050 of ." CMD_802_11_ASSOCIATE" endof + 0058 of ." CMD_802_11_BAND_CONFIG" endof + 0059 of ." CMD_EEPROM_ACCESS" endof + 005a of ." CMD_GSPI_BUS_CONFIG" endof + 005b of ." CMD_802_11D_DOMAIN_INFO" endof + 005c of ." CMD_WMM_ACK_POLICY" endof + 005e of ." CMD_802_11_KEY_MATERIAL" endof + 005f of ." CMD_802_11H_TPC_INFO" endof + 0060 of ." CMD_802_11H_TPC_ADAPT_REQ" endof + 0061 of ." CMD_802_11H_CHAN_SW_ANN" endof + 0062 of ." CMD_802_11H_MEASUREMENT_REQUEST" endof + 0063 of ." CMD_802_11H_GET_MEASUREMENT_REPORT" endof + 0066 of ." CMD_802_11_SLEEP_PARAMS" endof + 0068 of ." CMD_802_11_SLEEP_PERIOD" endof + 0069 of ." CMD_802_11_BCA_CONFIG_TIMESHARE" endof + 006b of ." CMD_802_11_BG_SCAN_CONFIG" endof + 006c of ." CMD_802_11_BG_SCAN_QUERY" endof + 006d of ." CMD_802_11_CAL_DATA_EXT" endof + 0071 of ." CMD_WMM_GET_STATUS" endof + 0072 of ." CMD_802_11_TPC_CFG" endof + 0073 of ." CMD_802_11_PA_CFG" endof + 0074 of ." CMD_802_11_FW_WAKE_METHOD" endof + 0075 of ." CMD_802_11_SUBSCRIBE_EVENT" endof + 0076 of ." CMD_802_11_RATE_ADAPT_RATESET" endof + 007f of ." CMD_TX_RATE_QUERY" endof + ( default ) ." Unknown command: " dup u. + endcase + cr +; + +\ Use prepare-cmd when the length is well known in advance +\ or longer than the outgoing argument fields +: prepare-cmd ( len cmd -- ) + dup .cmd ( len cmd ) + resp-wait-short to resp-wait ( len cmd ) + outbuf /outbuf erase ( len cmd ) + outbuf /fw-transport + to x 0 to /x ( len cmd ) + ( len cmd ) +xw \ fw-cmd ( len ) + /fw-cmd-hdr + +xw \ fw-len ( ) + fw-seq++ +xw \ fw-seq ( ) + 0 +xw \ fw-result ( ) +; + +\ Use start-cmd when determining the length in advance is tricky +: start-cmd ( cmd -- ) 0 swap prepare-cmd ; \ Will set actual len later +: finish-cmd ( -- ) /x outbuf >fw-len le-w! ; \ Set len field + +true value got-response? +true value got-indicator? + +: process-disconnect ( -- ) ds-disconnected set-driver-state ; +: process-wakeup ( -- ) ; +: process-sleep ( -- ) ; +: process-pmic-failure ( -- ) ; +: process-gmic-failure ( -- ) ; + +: .event ?cr ." Event: " type cr ; +0 instance value last-event +: process-ind ( adr len -- ) + drop + true to got-indicator? + 4 + le-l@ dup to last-event + case + h# 00 of " Tx PPA Free" .event endof \ n + h# 01 of " Tx DMA Done" .event endof \ n + h# 02 of " Link Loss with scan" .event process-disconnect endof + h# 03 of " Link Loss no scan" .event process-disconnect endof + h# 04 of " Link Sensed" .event endof + h# 05 of " CMD Finished" .event endof + h# 06 of " MIB Changed" .event endof + h# 07 of " Init Done" .event endof + h# 08 of " Deauthenticated" .event process-disconnect endof + h# 09 of " Disassociated" .event process-disconnect endof + h# 0a of " Awake" .event process-wakeup endof + h# 0b of " Sleep" .event process-wakeup endof + h# 0d of " Multicast MIC error" .event process-gmic-failure endof + h# 0e of " Unicast MIC error" .event process-pmic-failure endof + h# 0e of " WM awake" .event endof \ n + h# 11 of " HWAC - adhoc BCN lost" .event endof + h# 19 of " RSSI low" .event endof + h# 1a of " SNR low" .event endof + h# 1b of " Max fail" .event endof + h# 1c of " RSSI high" .event endof + h# 1d of " SNR high" .event endof + h# 23 of endof \ Suppress this; the user doesn't need to see it + \ h# 23 of ." Mesh auto-started" endof + h# 30 of endof \ Handle this silently +\ h# 30 of " Firmware ready" .event endof + ( default ) ." Unknown " dup u. + endcase +; + +: process-request ( adr len -- ) + 2dup vdump ( adr len ) + to /respbuf ( adr ) + respbuf /respbuf move ( ) + true to got-response? ( ) +; + +: process-rx ( adr len -- ) + over packet-type case + \ Encoding must agree with packet-type + 0 of process-request endof \ Response & request + 1 of process-data endof \ Data + 2 of process-ind endof \ Indication + ( default ) >r vdump r> + endcase +; + +: check-for-rx ( -- ) + got-packet? if ( error | buf len 0 ) + 0= if process-rx then ( ) + recycle-packet ( ) + then ( ) +; + +\ -1 error, 0 okay, 1 retry +: wait-cmd-resp ( -- -1|0|1 ) + false to got-response? + resp-wait 0 do + check-for-rx + got-response? if leave then + 1 ms + loop + got-response? if + respbuf >fw-result le-w@ case + 0 of 0 endof \ No error + 4 of 1 endof \ Busy, so retry + ( default ) ." Result = " dup u. cr dup + endcase + else +\ ." Timeout or error" cr + true + then +; +: wait-event ( -- true | event false ) + false to got-indicator? + d# 1000 0 do + check-for-rx + got-indicator? if last-event false unloop exit then + 1 ms + loop + true +; +: outbuf-wait ( -- error? ) + outbuf-out ?dup if exit then + wait-cmd-resp +; + + +\ ========================================================================= +\ Dumps +\ ========================================================================= + +: .fw-cap ( cap -- ) + ." 802.11" + dup h# 400 and if ." a" then + dup h# 100 and if ." b" then + dup h# 200 and if ." g" then ." ;" + dup h# 1 and if ." WPA;" then + dup h# 2 and if ." PS;" then + dup h# 8 and if ." EEPROM does not exit;" then + dup h# 30 and case + h# 00 of ." TX antanna 0;" endof + h# 10 of ." TX antenna 1;" endof + ( default ) ." TX diversity; " + endcase + h# c0 and case + h# 00 of ." RX antenna 0;" endof + h# 40 of ." RX antenna 1;" endof + ( default ) ." RX diversity;" + endcase +; + +: .log ( adr -- ) + dup >fw-len le-w@ /fw-cmd-hdr = if drop exit then + ." Multicast txed: " dup >fw-data le-l@ u. cr + ." Failed: " dup >fw-data 4 + le-l@ u. cr + ." Retry: " dup >fw-data 8 + le-l@ u. cr + ." Multiple retry: " dup >fw-data h# c + le-l@ u. cr + ." Duplicate frame rxed: " dup >fw-data h# 10 + le-l@ u. cr + ." Successful RTS: " dup >fw-data h# 14 + le-l@ u. cr + ." Failed RTS: " dup >fw-data h# 18 + le-l@ u. cr + ." Failed ACK: " dup >fw-data h# 1c + le-l@ u. cr + ." Fragment rxed: " dup >fw-data h# 20 + le-l@ u. cr + ." Multicast rxed: " dup >fw-data h# 24 + le-l@ u. cr + ." FCS error: " dup >fw-data h# 28 + le-l@ u. cr + ." Frame txed: " dup >fw-data h# 2c + le-l@ u. cr + ." WEP undecryptable: " dup >fw-data h# 30 + le-l@ u. cr + drop +; + + +\ ========================================================================= +\ Reset +\ ========================================================================= + +: reset-wlan ( -- ) " wlan-reset" evaluate ; + +: marvel-get-hw-spec ( -- true | adr false ) + d# 38 h# 03 ( CMD_GET_HW_SPEC ) prepare-cmd + outbuf-out ?dup if true exit then + resp-wait-tiny to resp-wait + wait-cmd-resp if true exit then + + respbuf >fw-data false +; + +\ The purpose of this is to work around a problem that I don't fully understand. +\ For some reason, when you reopen the device without re-downloading the +\ firmware, the first command silently fails - you don't get a response. +\ This is a "throwaway" command to handle that case without a long timeout +\ or a warning message. + +: nonce-cmd ( -- ) marvel-get-hw-spec 0= if drop then ; + +\ ========================================================================= +\ MAC address +\ ========================================================================= + +: marvel-get-mac-address ( -- ) + 8 h# 4d ( CMD_802_11_MAC_ADDRESS ) prepare-cmd + ACTION_GET +xw + outbuf-wait if ." marvel-get-mac-address failed" cr exit then + respbuf >fw-data 2 + mac-adr$ move +; + +: marvel-set-mac-address ( -- ) + 8 h# 4d ( CMD_802_11_MAC_ADDRESS ) prepare-cmd + ACTION_SET +xw + mac-adr$ +x$ + outbuf-wait if exit then +; + +: marvel-get-mc-address ( -- ) + 4 /mc-adrs + h# 10 ( CMD_MAC_MULTICAST_ADR ) prepare-cmd + ACTION_GET +xw + outbuf-wait if exit then + respbuf >fw-data 2 + le-w@ to #mc-adr + respbuf >fw-data 4 + mc-adrs #mc-adr /mac-adr * move +; + +: marvel-set-mc-address ( adr len -- ) + 4 /mc-adrs + h# 10 ( CMD_MAC_MULTICAST_ADR ) prepare-cmd + ACTION_SET +xw + dup /mac-adr / dup +xw \ Number of multicast addresses + to #mc-adr + ( adr len ) 2dup +x$ \ Multicast addresses + mc-adrs swap move + outbuf-wait if exit then +; + +\ ========================================================================= +\ Register access +\ ========================================================================= + +: reg-access@ ( reg cmd -- n ) + 8 swap prepare-cmd + ACTION_GET +xw + ( reg ) +xw + outbuf-wait if 0 exit then + respbuf >fw-data 4 + le-l@ +; + +: bbp-reg@ ( reg -- n ) + 1a ( CMD_BBP_REG_ACCESS ) reg-access@ h# ff and +; +: rf-reg@ ( reg -- n ) + 1b ( CMD_RF_REG_ACCESS ) reg-access@ h# ff and +; +: mac-reg@ ( reg -- n ) + 19 ( CMD_MAC_REG_ACCESS ) reg-access@ +; +: eeprom-l@ ( idx -- n ) + a 59 ( CMD_EEPROM_ACCESS ) prepare-cmd + ACTION_GET +xw + ( idx ) +xw + 4 +xw + outbuf-wait if 0 exit then + respbuf >fw-data 6 + le-l@ +; + +\ ========================================================================= +\ Miscellaneous control settings +\ ========================================================================= + +: set-radio-control ( -- ) + 4 h# 1c ( CMD_802_11_RADIO_CONTROL ) prepare-cmd + ACTION_SET +xw + preamble 1 or +xw \ Preamble, RF on + outbuf-wait if exit then +; + +: (set-bss-type) ( bsstype -- ok? ) + 6 d# 128 + h# 16 ( CMD_802_11_SNMP_MIB ) prepare-cmd + ACTION_SET +xw + 0 +xw \ Object = desiredBSSType + 1 +xw \ Size of object + ( bssType ) +xb + outbuf-wait 0= +; + +external +: set-bss-type ( bssType -- ok? ) dup to bss-type (set-bss-type) ; +headers + +: (set-mac-control) ( -- error? ) + 4 h# 28 ( CMD_MAC_CONTROL ) prepare-cmd + mac-ctrl +xw \ WEP type, WMM, protection, multicast, promiscous, WEP, tx, rx + outbuf-wait +; + +: set-mac-control ( -- error? ) + (set-mac-control) if + (set-mac-control) drop + then +; + +: set-domain-info ( adr len -- ) + dup 6 + h# 5b ( CMD_802_11D_DOMAIN_INFO ) prepare-cmd + ACTION_SET +xw + 7 +xw \ Type = MrvlIETypes_DomainParam_t + ( len ) dup +xw \ Length of payload + ( adr len ) +x$ \ Country IE + outbuf-wait if exit then +; + +: enable-11d ( -- ) + 6 d# 128 + h# 16 ( CMD_802_11_SNMP_MIB ) prepare-cmd + ACTION_SET +xw + 9 +xw \ Object = enable 11D + 2 +xw \ Size of object + 1 +xw \ Enable 11D + outbuf-wait if exit then +; + +external +: enforce-protection ( -- ) + mac-ctrl h# 400 or to mac-ctrl \ Enforce protection + set-mac-control +; + +: disable-protection ( -- ) + mac-ctrl h# 400 invert and to mac-ctrl + set-mac-control +; + +: set-key-type ( ctp ctg ktype -- ) to ktype to ctype-g to ctype-p ; + +: set-country-info ( adr len -- ) \ IEEE country IE + set-domain-info + enable-11d +; + +: enable-promiscuous ( -- ) + mac-ctrl h# 80 or to mac-ctrl + set-mac-control +; +: disable-promiscuous ( -- ) + mac-ctrl h# 80 invert and to mac-ctrl + set-mac-control +; + +: enable-multicast ( -- ) + mac-ctrl h# 20 or to mac-ctrl + set-mac-control +; +: disable-multicast ( -- ) + mac-ctrl h# 20 invert and to mac-ctrl + set-mac-control +; +: set-multicast ( adr len -- ) marvel-set-mc-address enable-multicast ; + +: mac-off ( -- ) + 0 to mac-ctrl set-mac-control 3 to mac-ctrl +; +headers + +\ ========================================================================= +\ Scan +\ ========================================================================= + +1 constant #probes + +d# 14 constant #channels + +[ifdef] notdef +struct + 2 field >type-id + 2 field >/payload +dup constant /marvel-IE-hdr + 2 field >probes +constant /probes-IE + +struct + 1 field >radio-type + 1 field >channel# + 1 field >scan-type + 2 field >min-scan-time + 2 field >max-scan-time +constant /chan-list + +struct + /marvel-IE-hdr + + #channels /chan-list * field >chan-list +constant /chan-list-IE + +struct + /marvel-IE-hdr + + d# 34 field >ssid +constant /ssid-IE + +struct + 1 field >bss-type + 6 field >bss-id + /chan-list-IE field >chan-list-IE + /probes-IE field >probes-IE +constant /cmd_802_11_scan +[then] + +1 constant BSS_INDEPENDENT +2 constant BSS_INFRASTRUCTURE +3 constant BSS_ANY + +\ OUI values (big-endian) +h# 0050.f201 constant wpa-tag \ WPA tag +h# 0050.f202 constant moui-tkip \ WPA cipher suite TKIP +h# 0050.f204 constant moui-aes \ WPA cipher suite AES +h# 000f.ac02 constant oui-tkip \ WPA2 cipher suite TKIP +h# 000f.ac04 constant oui-aes \ WPA2 cipher suite AES +h# 000f.ac02 constant aoui \ WPA2 authentication suite +h# 0050.f202 constant amoui \ WPA authentication suite + + +d# 34 instance buffer: scan-ssid + +0 value scan-type +: active-scan ( -- ) 0 to scan-type ; +: passive-scan ( -- ) 1 to scan-type ; + +[ifdef] notdef +: make-chan-list-param ( adr -- ) + #channels 0 do + dup i /chan-list * + + 0 over >radio-type c! + i 1+ over >channel# c! + scan-type over >scan-type c! + d# 100 over >min-scan-time le-w! + d# 100 swap >max-scan-time le-w! + loop drop +; + +: (oldscan) ( -- error? | adr len 0 ) + /cmd_802_11_scan scan-ssid c@ if + /marvel-IE-hdr + scan-ssid c@ + + then + 6 ( CMD_802_11_SCAN ) prepare-cmd ( ) + resp-wait-long to resp-wait ( ) + BSS_ANY outbuf >fw-data tuck >bss-type c! ( 'fw-data ) + + dup >chan-list-IE ( 'fw-data 'chan-list ) + h# 101 over >type-id le-w! ( 'fw-data 'chan-list ) + #channels /chan-list * over >/payload le-w! ( 'fw-data 'chan-list ) + >chan-list make-chan-list-param ( 'fw-data ) + + dup >probes-IE ( 'fw-data 'probes ) + h# 102 over >type-id le-w! ( 'fw-data 'probes ) + 2 over >/payload le-w! ( 'fw-data 'probes ) + #probes swap >probes le-w! ( 'fw-data ) + + scan-ssid c@ if ( 'fw-data ) + \ Attach an SSID TLV to filter the result + /cmd_802_11_scan + ( 'ssid ) + h# 000 over >type-id le-w! ( 'ssid ) + scan-ssid c@ over >/payload le-w! ( 'ssid ) + scan-ssid count rot /marvel-IE-hdr + swap move ( ) + else ( 'fw-data ) + drop + then ( ) + + outbuf-wait ( error? ) + dup 0= if ( error? ) + respbuf /respbuf /fw-cmd /string rot ( adr len 0 ) + then +; +[then] + +h# 7ffe instance value channel-mask + +: +chan-list-tlv ( -- ) + h# 101 +xw + 0 +xw 'x >r ( r: 'payload ) + #channels 1+ 1 do + 1 i lshift channel-mask and if + 0 +xb \ Radio type + i +xb \ Channel # + scan-type +xb \ Scan type - 0:active or 1:passive + d# 100 +xw \ Min scan time + d# 100 +xw \ Max scan time + then + loop + 'x r@ - r> 2- le-w! +; + +: +probes-tlv ( -- ) + h# 102 +xw \ Probes TLV + 2 +xw \ length + #probes +xw \ #probes +; + +: +ssid-tlv ( -- ) + scan-ssid c@ if + 0 +xw \ SSID TLV + scan-ssid c@ +xw \ length + scan-ssid count +x$ + then +; + +: (scan) ( -- error? | adr len 0 ) + 6 ( CMD_802_11_SCAN ) start-cmd + resp-wait-long to resp-wait + + BSS_ANY +xb + 6 +xerase \ BSS ID + + +chan-list-tlv + +probes-tlv + +ssid-tlv + + finish-cmd outbuf-wait dup 0= if ( error? ) + respbuf /respbuf /fw-cmd /string rot ( adr len 0 ) + then +; + + +external +: set-channel-mask ( n -- ) + h# 7ffe and to channel-mask +; + +\ Ask the device to look for the indicated SSID. +: set-ssid ( adr len -- ) + \ This is an optimization for NAND update over the mesh. + \ It prevents listening stations, of which there can be many, + \ from transmitting when they come on-line. + 2dup " olpc-mesh" $= if passive-scan then + + h# 32 min scan-ssid pack drop +; + +: scan ( adr len -- actual ) +\ (scan) + begin (scan) dup 1 = while drop d# 1000 ms repeat \ Retry while busy + if 2drop 0 exit then ( adr len scan-adr scan-len ) + rot min >r ( adr scan-adr r: len ) + swap r@ move ( r: len ) + r> +; +headers + +\ ========================================================================= +\ WEP +\ ========================================================================= + +: set-wep-type ( len -- ) + ?dup if + 5 = if TYPE_WEP_40_BIT 8 else TYPE_WEP_104_BIT h# 8008 then + mac-ctrl or to mac-ctrl \ WEPxx on + else + 0 + then + +xb +; + +external +: (set-wep) ( wep4$ wep3$ wep2$ wep1$ idx -- ok? ) + d# 72 h# 13 ( CMD_802_11_SET_WEP ) prepare-cmd + ACTION_ADD +xw + ( idx ) +xw \ TxKeyIndex + dup set-wep-type + 2 pick set-wep-type + 4 pick set-wep-type + 6 pick set-wep-type + 4 0 do + ?dup if x /x + swap move else drop then + d# 16 /x + to /x + loop + outbuf-wait 0= +; +: set-wep ( wep4$ wep3$ wep2$ wep1$ idx -- ok? ) + to wep-idx + dup to /wep1 wep1 swap move + dup to /wep2 wep2 swap move + dup to /wep3 wep3 swap move + dup to /wep4 wep4 swap move + true +; +: ?set-wep ( -- ) + ktype kt-wep = if + wep4$ wep3$ wep2$ wep1$ wep-idx (set-wep) drop + then +; + +: disable-wep ( -- ok? ) + mac-ctrl h# 8008 invert and to mac-ctrl \ Disable WEP + d# 72 h# 13 ( CMD_802_11_SET_WEP ) prepare-cmd + ACTION_REMOVE +xw + 0 +xw \ TxKeyIndex + outbuf-wait 0= +; +headers + +\ ========================================================================= +\ WPA and WPA2 +\ ========================================================================= + +: set-rsn ( enable? -- ok? ) + 4 h# 2f ( CMD_802_11_ENABLE_RSN ) prepare-cmd + ACTION_SET +xw + ( enable? ) +xw \ 1: enable; 0: disable + outbuf-wait 0= +; + +external +: enable-rsn ( -- ok? ) 1 set-rsn ; +: disable-rsn ( -- ok? ) 0 set-rsn ; +headers + +: set-key-material ( key$ kinfo ct -- ) + h# 5e ( CMD_802_11_KEY_MATERIAL ) start-cmd + ACTION_SET +xw + h# 100 +xw \ Key param IE type + 2 pick 6 + +xw \ IE payload length + ( ct ) +xw \ Cipher type + ( kinfo ) +xw \ Key info + dup +xw \ Key length + ( key$ ) +x$ \ key$ + finish-cmd outbuf-wait if exit then +; + +external +: set-gtk ( gtk$ -- ) 5 ctype-g set-key-material ; +: set-ptk ( ptk$ -- ) 6 ctype-p set-key-material ; +headers + +\ ======================================================================= +\ Adhoc join +\ ======================================================================= + +0 value atim + +: save-associate-params ( ch ssid$ target-mac$ -- ch ssid$ target-mac ) + over target-mac$ move + 2over dup to /ssid + ssid swap move + 4 pick to channel +; + +: (join) ( ch ssid$ target-mac$ -- ok? ) + save-associate-params + h# 2c ( CMD_802_11_AD_HOC_JOIN ) start-cmd + resp-wait-long to resp-wait + + ( target-mac$ ) +x$ \ Peer MAC address + ( ssid$ ) tuck +x$ \ SSID + ( ssid-len ) d# 32 swap - +x \ 32 bytes of SSID + bss-type-adhoc +xb \ BSS type + d# 100 +xw \ Beacon period + 1 +xb \ DTIM period + + 8 +x \ 8 bytes of time stamp + 8 +x \ 8 bytes of local time + + \ DS param set + 3 +xb \ Elem ID = DS param set + 1 +xb \ Length + ( channel ) +xb \ Channel + 4 +x \ Reserved bytes + + \ IBSS param set + 6 +xb \ Elem ID = IBSS param set + 2 +xb \ Length + atim +xw \ ATIM window + 4 +x \ Reserved bytes + + cap +xw \ Capability info: ESS, short slot, WEP + + \ XXX 14 bytes for 802.11g, 8 bytes for 802.11b + common-rates #rates +x$ \ Common supported data rates + d# 255 +xw \ Association timeout + 0 +xw \ Probe delay time + + finish-cmd outbuf-wait if ." Failed to join adhoc network" cr false exit then + true +; + +external +: set-atim-window ( n -- ) d# 50 min to atim ; +headers + +\ ========================================================================= +\ Authenticate +\ ========================================================================= + +: authenticate ( target-mac$ -- ) + dup 1+ h# 11 ( CMD_802_11_AUTHENTICATE ) prepare-cmd + ( target-mac$ ) +x$ \ Peer MAC address + auth-mode +xb \ Authentication mode + outbuf-wait if exit then +; + +: deauthenticate ( mac$ -- ) + dup 2+ h# 24 ( CMD_802_11_DEAUTHENTICATE ) prepare-cmd + ( mac$ ) +x$ \ AP MAC address + 3 +xw \ Reason code: station is leaving + outbuf-wait if exit then + ds-disconnected set-driver-state +; + +\ Mesh + +: mesh-access! ( value cmd -- ) + h# 82 h# 9b ( CMD_MESH_ACCESS ) prepare-cmd ( value cmd ) + +xw +xl ( ) + + outbuf-wait if exit then +; +: mesh-access@ ( cmd -- value ) + h# 82 h# 9b ( CMD_MESH_ACCESS ) prepare-cmd ( value cmd ) + +xw ( ) + + outbuf-wait if -1 exit then + respbuf >fw-data wa1+ le-l@ +; + +: mesh-config-set ( adr len type channel action -- error? ) + h# 88 h# a3 ( CMD_MESH_CONFIG ) prepare-cmd ( adr len type channel action ) + +xw +xw +xw ( adr len ) + dup +xw +x$ ( ) + + outbuf-wait +; +: mesh-config-get ( -- true | buf false ) + h# 88 h# a3 ( CMD_MESH_CONFIG ) prepare-cmd ( ) + 3 +xw 0 +xw 5 +xw ( ) + + outbuf-wait if true exit then + respbuf >fw-data false +; +: (mesh-start) ( channel tlv -- error? ) + " "(dd 0e 00 50 43 04 00 00 00 00 00 04)mesh" ( channel tlv adr len ) + 2swap swap 1 ( adr len tlv channel action ) \ 1 is CMD_ACT_MESH_CONFIG_START + mesh-config-set +; + +: mesh-stop ( -- error? ) + mesh-on? if + " " 0 0 0 mesh-config-set ( error? ) + tx-ctrl TX_WDS invert and to tx-ctrl ( error? ) + ds-associated reset-driver-state ( error? ) + else + false ( error? ) + then +; + +: mesh-start ( channel -- error? ) + \ h# 223 (0x100 + 291) is an old value + \ h# 125 (0x100 + 37) is an "official" value that doesn't work + dup h# 223 (mesh-start) if ( channel ) + \ Retry once + h# 223 (mesh-start) ( error? ) + else + drop false ( error? ) + then + + dup 0= if ( error? ) + tx-ctrl TX_WDS or to tx-ctrl ( error? ) + ds-associated set-driver-state ( error? ) + then ( error? ) +; + +instance variable mesh-param +: mesh-set-bootflag ( bootflag -- error? ) + mesh-param le-l! mesh-param 4 1 0 3 mesh-config-set +; +: mesh-set-boottime ( boottime -- error? ) + mesh-param le-w! mesh-param 2 2 0 3 mesh-config-set +; +: mesh-set-def-channel ( boottime -- error? ) + mesh-param le-w! mesh-param 2 3 0 3 mesh-config-set +; +: mesh-set-ie ( adr len -- error? ) 4 0 3 mesh-config-set ; +: mesh-set-ttl ( ttl -- ) 2 mesh-access! ; +: mesh-get-ttl ( -- ttl ) 1 mesh-access@ ; +: mesh-set-bcast ( index -- ) 8 mesh-access! ; +: mesh-get-bcast ( -- index ) 9 mesh-access@ ; + +[ifdef] notdef +: mesh-set-anycast ( mask -- ) 5 mesh-access! ; +: mesh-get-anycast ( -- mask ) 4 mesh-access@ ; + +: mesh-set-rreq-delay ( n -- ) d# 10 mesh-access! ; +: mesh-get-rreq-delay ( -- n ) d# 11 mesh-access@ ; + +: mesh-set-route-exp ( n -- ) d# 12 mesh-access! ; +: mesh-get-route-exp ( -- n ) d# 13 mesh-access@ ; + +: mesh-set-autostart ( n -- ) d# 14 mesh-access! ; +: mesh-get-autostart ( -- n ) d# 15 mesh-access@ ; + +: mesh-set-prb-rsp-retry-limit ( n -- ) d# 17 mesh-access! ; +[then] + +\ ========================================================================= +\ Associate/disassociate +\ ========================================================================= + +0 value assoc-id + +\ The source IE is in the Marvel format: id and len are 2 bytes long. +\ The destination IE is in the 802.11 format: id and len are 1 byte long. +: save-wpa-ie ( boffset eoffset -- ) + over - 2 - to /wpa-ie \ Less extra bytes + x + dup c@ wpa-ie c! \ Copy IE id + 2 + dup c@ wpa-ie 1+ c! \ Copy len + 2 + wpa-ie /wpa-ie 2 /string move \ Copy body of IE +; + +: moui ( ct -- ) ct-tkip = if moui-tkip else moui-aes then ; +: oui ( ct -- ) ct-tkip = if oui-tkip else oui-aes then ; + +: (associate) ( ch ssid$ target-mac$ -- ok? ) + save-associate-params + + h# 50 ( CMD_802_11_ASSOCIATE ) start-cmd + resp-wait-long to resp-wait + + ( target-mac$ ) +x$ \ Peer MAC address + cap +xw \ Capability info: ESS, short slot, WEP + d# 10 +xw \ Listen interval + d# 100 +xw \ Beacon period + 1 +xb \ DTIM period + + \ SSID + 0 +xw \ element ID = SSID + dup +xw \ len + ( ssid$ ) +x$ \ SSID + + \ DS param + 3 +xw \ element ID = DS param set + 1 +xw \ len + ( ch ) +xb \ channel + + \ CF param + 4 +xw \ element ID = CF param set + 0 +xw \ len + + \ Common supported rates + 1 +xw \ element ID = rates + #rates +xw \ len + common-rates #rates +x$ \ common supported data rates + + \ RSN (WPA2) + ktype kt-wpa2 = if + /x \ Save beginning offset + d# 48 +xw \ element ID = RSN + d# 20 +xw \ len + 1 +xw \ version + ctype-g oui +xbl \ group cipher suite + 1 +xw \ count of pairwise cipher suite + ctype-p oui +xbl \ pairwise cipher suite + 1 +xw \ count of authentication suite + aoui +xbl \ authentication suite + h# 28 +xw \ RSN capabilities + /x save-wpa-ie \ Save IE in wpa-ie + then + + \ WPA param + ktype kt-wpa = if + /x \ Save beginning offset + d# 221 +xw \ element ID = WPA + d# 24 +xw \ len + wpa-tag +xbl \ WPA-specific tag + 1 +xw \ version + ctype-g moui +xbl \ group cipher suite + 1 +xw \ count of pairwise cipher suite + ctype-p moui +xbl \ pairwise cipher suite + 1 +xw \ count of authentication suite + amoui +xbl \ authentication suite + ctype-p ct-tkip = if h# 2a else h# 28 then + ( cap ) +xw \ WPA capabilities + /x save-wpa-ie \ Save IE in wpa-ie + then + + \ XXX power (optional) + \ XXX supported channels set (802.11h only) + \ XXX pass thru IEs (optional) + + finish-cmd outbuf-wait if false exit then + + respbuf >fw-data 2 + le-w@ ?dup if \ This is the IEEE Status Code + ." Failed to associate: " u. cr + false + else + respbuf >fw-data 4 + le-w@ to assoc-id + ds-disconnected ds-connected-mask or reset-driver-state + true + then +; + +external +instance defer mesh-default-modes +' noop to mesh-default-modes +: nandcast-mesh-modes ( -- ) + 1 mesh-set-ttl + d# 12 mesh-set-bcast +; +' nandcast-mesh-modes to mesh-default-modes + +: associate ( ch ssid$ target-mac$ -- ok? ) + 2over " olpc-mesh" $= if ( ch ssid$ target-mac$ ) + 2drop 2drop mesh-start 0= ( ok? ) + dup if mesh-default-modes then + exit + then + ?set-wep \ Set WEP keys again, if ktype is WEP + set-mac-control + 2dup authenticate + bss-type bss-type-managed = if (associate) else (join) then +; +headers + +: do-associate ( -- ok? ) + do-associate dup if + ds-disconnected reset-driver-state + ds-associated set-driver-state + then +; + +: ?reassociate ( -- ) + driver-state ds-disconnected and if do-associate drop then +; +' ?reassociate to start-nic + +: disassociate ( mac$ -- ) + dup 2+ h# 26 ( CMD_802_11_DISASSOCIATE ) prepare-cmd + ( mac$ ) +x$ \ AP MAC address + 3 +xw \ Reason code: station is leaving + outbuf-wait if exit then + ds-disconnected set-driver-state +; + + +\ ======================================================================= +\ Miscellaneous +\ ======================================================================= + +: get-rf-channel ( -- ) + d# 40 h# 1d ( CMD_802_11_RF_CHANNEL ) prepare-cmd + ACTION_GET +xw + outbuf-wait if exit then + ." Current channel = " respbuf >fw-data 2 + le-w@ .d cr +; + +: get-beacon ( -- interval enabled? ) + 6 h# b0 ( CMD_802_11_BEACON_CTRL ) prepare-cmd + ACTION_GET +xw + outbuf-wait if exit then + respbuf >fw-data dup 2 wa+ le-w@ swap wa1+ le-w@ +; + +: set-beacon ( interval enabled? -- ) + 6 h# b0 ( CMD_802_11_BEACON_CTRL ) prepare-cmd + ACTION_SET +xw ( interval enabled? ) + +xw +xw + outbuf-wait drop +; + + +: get-log ( -- ) + 0 h# b ( CMD_802_11_GET_LOG ) prepare-cmd + outbuf-wait if exit then + respbuf .log +; + +: get-rssi ( -- ) + 2 h# 1f ( CMD_802_11_RSSI ) prepare-cmd + 8 +xw \ Value used for exp averaging + outbuf-wait drop + \ XXX What to do with the result? +; + +: .hw-spec ( -- ) + marvel-get-hw-spec if + ." marvel-get-hw-spec command failed" cr + else + ." HW interface version: " dup le-w@ u. cr + ." HW version: " dup 2 + le-w@ u. cr + ." Max multicast addr: " dup 6 + le-w@ .d cr + ." MAC address: " dup 8 + .enaddr cr + ." Region code: " dup d# 14 + le-w@ u. cr + ." # antenna: " dup d# 16 + le-w@ .d cr + ." FW release: " dup d# 18 + le-l@ u. cr + ." FW capability:" d# 34 + le-l@ .fw-cap cr + then +; + +: set-data-rate ( rate-code -- ) + #rates 4 + h# 22 ( CMD_802_11_DATA_RATE ) prepare-cmd + + 1 ( CMD_ACT_SET_TX_FIX_RATE ) +xw + 0 +xw \ reserved field + ( rate-code ) +xb + + outbuf-wait drop +; +: auto-data-rate ( -- ) + #rates 4 + h# 22 ( CMD_802_11_DATA_RATE ) prepare-cmd + + 0 ( CMD_ACT_SET_TX_FIX_RATE ) +xw + 0 +xw \ reserved field + + outbuf-wait drop +; + + +: get-data-rates ( -- ) + #rates 4 + h# 22 ( CMD_802_11_DATA_RATE ) prepare-cmd + 2 ( HostCmd_ACT_GET_TX_RATE ) +xw + outbuf-wait drop +; + +2 constant gpio-pin +d# 20 constant wake-gap +1 constant wake-on-broadcast +2 constant wake-on-unicast +4 constant wake-on-mac-event +-1 constant remove-wakeup + +\ LED_GPIO_CTRL + +: host-sleep-activate ( -- ) + 0 h# 45 ( CMD_802_11_HOST_SLEEP_ACTIVATE ) prepare-cmd + outbuf-wait drop +; + +: host-sleep-config ( conditions -- ) + >r + 6 h# 43 ( CMD_802_11_HOST_SLEEP_CFG ) prepare-cmd +\ ACTION_SET +xw + + r> +xl + gpio-pin +xb + wake-gap +xb + + outbuf-wait drop +; + +: unicast-wakeup ( -- ) wake-on-unicast host-sleep-config ; +: broadcast-wakeup ( -- ) wake-on-unicast wake-on-broadcast or host-sleep-config ; +: sleep ( -- ) host-sleep-activate ; + +[ifdef] notdef + CMD_ACT_MESH_... + 1 GET_TTL 2 SET_TTL 3 GET_STATS 4 GET_ANYCAST 5 SET_ANYCAST + 6 SET_LINK_COSTS 7 GET_LINK_COSTS 8 SET_BCAST_RATE 9 GET_BCAST_RATE +10 SET_RREQ_DELAY 11 GET_RREQ_DELAY 12 SET_ROUTE_EXP 13 GET_ROUTE_EXP +14 SET_AUTOSTART_ENABLED 15 GET_AUTOSTART_ENABLED 16 not used +17 SET_PRB_RSP_RETRY_LIMIT + +CMD_TYPE_MESH_ +1 SET_BOOTFLAG 2 SET_BOOTTIME 3 SET_DEF_CHANNEL 4 SET_MESH_IE +5 GET_DEFAULTS 6 GET_MESH_IE /* GET_DEFAULTS is superset of GET_MESHIE */ + +CMD_ACT_MESH_CONFIG_.. 0 STOP 1 START 2 SET 3 GET + +struct cmd_ds_mesh_config { + struct cmd_header hdr; + __le16 action; __le16 channel; __le16 type; __le16 length; + u8 data[128]; /* last position reserved */ +} +struct mrvl_meshie_val { + uint8_t oui[P80211_OUI_LEN]; + uint8_t type; + uint8_t subtype; + uint8_t version; + uint8_t active_protocol_id; + uint8_t active_metric_id; + uint8_t mesh_capability; + uint8_t mesh_id_len; + uint8_t mesh_id[IW_ESSID_MAX_SIZE]; 32 +} +struct ieee80211_info_element { + u8 id; u8 len; u8 data[0]; +} +struct mrvl_meshie { + struct ieee80211_info_element hdr; + struct mrvl_meshie_val val; +} + memset(&cmd, 0, sizeof(cmd)); + cmd.channel = cpu_to_le16(chan); + ie = (struct mrvl_meshie *)cmd.data; + + switch (action) { + case CMD_ACT_MESH_CONFIG_START: +0.b 221 ie->hdr.id = MFIE_TYPE_GENERIC; +2.b h# 00 ie->val.oui[0] = 0x00; +3.b h# 50 ie->val.oui[1] = 0x50; +4.b h# 43 ie->val.oui[2] = 0x43; +5.b 4 ie->val.type = MARVELL_MESH_IE_TYPE; +6.b 0 ie->val.subtype = MARVELL_MESH_IE_SUBTYPE; +7.b 0 ie->val.version = MARVELL_MESH_IE_VERSION; +8.b 0 ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP; +9.b 0 ie->val.active_metric_id = MARVELL_MESH_METRIC_ID; +10.b 0 ie->val.mesh_capability = MARVELL_MESH_CAPABILITY; +11.b ssid_len ie->val.mesh_id_len = priv->mesh_ssid_len; +12 memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len); +1 10+ssid_len ie->hdr.len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + priv->mesh_ssid_len; + + 42 (32+10) cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val)); + +config_start: action is 1 (...CONFIG_START), type = mesh_tlv which is either h# 100 d# 291 + or h# 100 d# 37 + +[then] + +[ifdef] notdef +create mesh_start_cmd + \ MFIE_TYPE_GENERIC ielen (10 + sizeof("mesh")) + d# 221 c, d# 14 c, + + \ OUI.................... type subtyp vers proto metric cap + h# 00 c, h# 50 c, h# 43 c, 4 c, 0 c, 0 c, 0 c, 0 c, 0 c, + + \ ssidlen ssid (set@12) + d# 04 c, here 4 allot " mesh" rot swap move +here mesh_start_cmd - constant /mesh_start_cmd +[then] + +[ifdef] wlan-wackup \ This is test code that only works with a special debug version of the Libertas firmware +: autostart ( -- ) + h# 700000 h# 5 mesh-access! +; +[then] + +hex +headers + +" wlan" device-name +" wireless-network" device-type + +variable opencount 0 opencount ! + +headers + +: ?make-mac-address-property ( -- ) + driver-state ds-ready < if exit then + " mac-address" get-my-property if + mac-adr$ encode-bytes " local-mac-address" property + mac-address encode-bytes " mac-address" property + else + 2drop + then +; +: set-frame-size ( -- ) + " max-frame-size" get-my-property if ( ) + max-frame-size encode-int " max-frame-size" property + else ( prop$ ) + 2drop + then +; + +: init-net ( -- ) + marvel-get-mac-address + ?make-mac-address-property +; + +: ?load-fw ( -- error? ) + driver-state ds-not-ready = if + load-all-fw if + ." Failed to download firmware" cr + true exit + then + ds-ready to driver-state + then + init-net + false +; + +false instance value use-promiscuous? + +external + +\ Set to true to force open the driver without association. +\ Designed for use by application to update the Marvel firmware only. +\ Normal operation should have force-open? be false. +false instance value force-open? + +: parse-args ( $ -- ) + false to use-promiscuous? + begin ?dup while + ascii , left-parse-string + 2dup " debug" $= if debug-on then + 2dup " promiscuous" $= if true to use-promiscuous? then + " force" $= if true to force-open? then + repeat drop +; + +: open ( -- ok? ) + my-args parse-args + set-parent-channel + opencount @ 0= if + init-buf + /inbuf /outbuf setup-bus-io if free-buf false exit then + ?load-fw if release-bus-resources free-buf false exit then + my-args " supplicant" $open-package to supplicant-ih + supplicant-ih 0= if release-bus-resources free-buf false exit then + nonce-cmd + force-open? 0= if + link-up? 0= if + ['] 2drop to ?process-eapol + do-associate 0= if free-buf false exit then + ds-disconnected reset-driver-state + ds-associated set-driver-state + ['] do-process-eapol to ?process-eapol + then + start-nic + then + then + force-open? 0= if + use-promiscuous? if enable-promiscuous else disable-promiscuous then + then + opencount @ 1+ opencount ! + true +; + +: close ( -- ) + opencount @ 1- 0 max opencount ! + opencount @ 0= if + disable-multicast + mesh-stop drop + link-up? if target-mac$ deauthenticate then + ['] 2drop to ?process-eapol + stop-nic + mac-off + supplicant-ih ?dup if close-package 0 to supplicant-ih then + release-bus-resources + then +; + +\ Read and write ethernet messages regardless of the associate state. +\ Used by the /supplicant support package to perform key handshaking. +: write-force ( adr len -- actual ) + tuck ( actual adr len ) + wrap-msg ( actual adr' len' ) + data-out ( actual ) +; + +: read-force ( adr len -- actual ) + got-packet? 0= if ( adr len ) + 2drop -2 exit + then ( adr len [ error | buf actual 0 ] ) + + if \ receive error ( adr len ) + recycle-packet ( adr len ) + 2drop -1 exit + then ( adr len buf actual ) + + false to got-data? ( adr len buf actual ) + process-rx ( adr len ) + recycle-packet ( adr len ) + + got-data? if ( adr len ) + /data min tuck data -rot move ( actual ) + else ( adr len ) + 2drop -2 \ No data + then ( actual ) + +; + +\ Normal read and write methods. +: write ( adr len -- actual ) + link-up? 0= if 2drop 0 exit then \ Not associated yet. + ?reassociate \ In case if the connection is dropped + write-force +; +: read ( adr len -- actual ) + \ If a good receive packet is ready, copy it out and return actual length + \ If a bad packet came in, discard it and return -1 + \ If no packet is currently available, return -2 + + link-up? 0= if 2drop 0 exit then \ Not associated yet. + ?reassociate \ In case if the connection is dropped + read-force +; + +: load ( adr -- len ) + link-up? 0= if drop 0 exit then \ Not associated yet. + + " obp-tftp" find-package if ( adr phandle ) + my-args rot open-package ( adr ihandle|0 ) + else ( adr ) + 0 ( adr 0 ) + then ( adr ihandle|0 ) + + dup 0= if ." Can't open obp-tftp support package" stop-nic abort then + ( adr ihandle ) + + >r + " load" r@ $call-method ( len ) + r> close-package +; + +: reset ( -- flag ) reset-nic ; + +: (scan-wifi) ( -- error? ) + true to force-open? + open + false to force-open? + 0= if ." Can't open Marvell wireless" cr true close exit then + + (scan) if + ." Failed to scan" true cr + else ( adr len ) + drop .scan false + then + + close +; + +: scan-wifi ( -- ) (scan-wifi) drop ; + +: selftest ( -- error? ) (scan-wifi) ; + +headers + + +\ LICENSE_BEGIN +\ Copyright (c) 2007 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Added: dev/mmc/sdhci/mv8686/common.fth =================================================================== --- dev/mmc/sdhci/mv8686/common.fth (rev 0) +++ dev/mmc/sdhci/mv8686/common.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,113 @@ +purpose: Common ethernet driver stuff +\ See license at end of file + +hex +headers + +false instance value debug? + +: debug-on ( -- ) true to debug? ; + +: dma-alloc ( size -- virt ) " dma-alloc" $call-parent ; +: dma-free ( virt size -- ) " dma-free" $call-parent ; + +: usec ( us -- ) " us" evaluate ; + +: 4drop ( n1 n2 n3 n4 -- ) 2drop 2drop ; + +\ Little endian operations +: le-w@ ( a -- w ) dup c@ swap ca1+ c@ bwjoin ; +: le-w! ( w a -- ) >r wbsplit r@ ca1+ c! r> c! ; +: le-l@ ( a -- l ) >r r@ c@ r@ 1+ c@ r@ 2+ c@ r> 3 + c@ bljoin ; +: le-l! ( l a -- ) >r lbsplit r@ 3 + c! r@ 2+ c! r@ 1+ c! r> c! ; + +\ String comparision +: $= ( adr0 len0 adr1 len1 -- equal? ) + 2 pick <> if 3drop false exit then ( adr0 len0 adr1 ) + swap comp 0= +; +: /string ( adr len cnt -- adr+n len-n ) tuck - -rot + swap ; + +create mac-adr 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, +6 constant /mac-adr +: mac-adr$ ( -- adr len ) mac-adr /mac-adr ; + +: null$ ( -- adr len ) " " ; + +\ Big endian operations +: be-w@ ( a -- w ) dup ca1+ c@ swap c@ bwjoin ; +: be-w! ( w a -- ) >r wbsplit r@ c! r> ca1+ c! ; +: be-l@ ( a -- l ) dup wa1+ be-w@ swap be-w@ wljoin ; +: be-l! ( l a -- ) >r lwsplit r@ be-w! r> wa1+ be-w! ; + +\ Dumps +: .2 ( n -- ) <# u# u# u#> type ; +: .enaddr ( adr -- ) + base @ >r d# 16 base ! ( adr len ) ( R: base ) + 5 0 do dup c@ .2 1+ ." :" loop c@ .2 + r> base ! ( ) +; +: 3u.r ( n -- ) <# bl hold u# u#s u#> type ; +: cdump ( adr len -- ) + base @ >r d# 16 base ! ( adr len ) ( R: base ) + bounds ?do i c@ 3u.r loop ( ) ( R: base ) + r> base ! ( ) +; +: ?cr ( -- ) " ??cr" evaluate ; +: vdump ( adr len -- ) debug? if " dump" evaluate else 2drop then ; +: vldump ( adr len -- ) debug? if " ldump" evaluate else 2drop then ; +: vtype ( adr len -- ) debug? if type cr else 2drop then ; + + +defer link-up? ( -- up? ) ' true to link-up? +defer reset-nic ( -- ) ' noop to reset-nic +defer start-nic ( -- ) ' noop to start-nic +defer stop-nic ( -- ) ' noop to stop-nic + +external +defer get-mac-address ( -- adr len ) ' mac-adr$ to get-mac-address +headers + +: max-frame-size ( -- size ) d# 1514 ; + +: property-or-abort ( name$ -- n ) + 2dup get-my-property if ( name$ ) + ." Can't find property " type cr stop-nic abort + then ( name$ value$ ) + 2swap 2drop decode-int nip nip ( n ) +; + +: find-fw ( $ -- adr len ) + over " rom:" comp if + " boot-read" evaluate \ Not a dropin + " loaded" evaluate + else + 4 - swap 4 + swap " find-drop-in" evaluate 0= if null$ then + then +; + +headers + +\ LICENSE_BEGIN +\ Copyright (c) 2006 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Added: dev/mmc/sdhci/mv8686/fw8686.fth =================================================================== --- dev/mmc/sdhci/mv8686/fw8686.fth (rev 0) +++ dev/mmc/sdhci/mv8686/fw8686.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,143 @@ +purpose: Marvel 8686 firmware loader +\ See license at end of file + + +\ ======================================================================= +\ Firmware download data structures +\ ======================================================================= + +h# fedc constant FIRMWARE_READY + +fw-blksz 2 * 4 - constant /fw-tx + + +\ ========================================================================= +\ Firmware Download +\ ========================================================================= + +0 value dn-idx +0 value fw-len +0 value fw-adr +0 value fw-tx-len +0 value dn-retry + +: fw-dn-blksz ( -- blksz ) + h# 10 1 sdio-reg@ + h# 11 1 sdio-reg@ bwjoin +; +: wait-for-fw-dn-blksz ( -- blksz ) + \ Wait for the first non-zero value + d# 5000 0 do fw-dn-blksz dup ?leave drop loop + dup 0= if ." Failed to get firmware download block size" cr then +; + +: fw-download-ok? ( -- flag ) + false d# 100 0 do + sdio-scratch@ FIRMWARE_READY = if drop true leave then + d# 10 ms + loop +; + +: (download-fw) ( adr len tx-size -- error? ) + to fw-tx-len + to fw-len to fw-adr + 0 to dn-idx 0 to dn-retry + begin + fw-len dn-idx - fw-tx-len min ( len ) + fw-adr dn-idx + outbuf 2 pick move ( len ) + outbuf over sdio-fw! <> if + 4 3 1 sdio-reg! \ FN1 CFG = write iomem fail + then + sdio-poll-dl-ready 0= if true exit then + fw-dn-blksz ?dup 0= if true exit then + dup 1 and if + dn-retry 1+ dup to dn-retry + 2 > if ." Retry fail" cr true exit then + else + 0 to dn-retry + dn-idx fw-tx-len + to dn-idx + then + 1 invert and to fw-tx-len + dn-idx fw-len >= until + false +; + +: fw-image-ok? ( adr len -- flag ) 2drop true ; + +: download-fw ( adr len -- error? ) + 2dup fw-image-ok? 0= if ." Bad WLAN firmware image" cr true exit then + + wait-for-fw-dn-blksz + ?dup 0= if ." Failed to get firmware download block size" cr 2drop true exit then + + sdio-poll-dl-ready 0= if ." Helper not ready" cr 3drop true exit then + 1 invert and (download-fw) if true exit then + + fw-download-ok? 0= if true exit then + + 3 4 1 sdio-reg! \ Enable host interrupt mask + false +; + +: (download-helper) ( adr len -- error? ) + to fw-len to fw-adr + 0 to dn-idx + begin + sdio-poll-dl-ready 0= if true exit then + fw-len dn-idx - /fw-tx min ( len ) + dup outbuf le-l! ( len ) + fw-adr dn-idx + outbuf 4 + 2 pick move ( len ) + dn-idx over + to dn-idx ( len ) + outbuf swap 4 + sdio-fw! drop ( ) + dn-idx fw-len >= until + \ Write last EOF data + outbuf fw-blksz erase + outbuf fw-blksz sdio-fw! drop + false +; + +: download-helper ( adr len -- error? ) + sdio-scratch@ FIRMWARE_READY = if " Firmware downloaded" vtype 2drop true exit then + 2dup fw-image-ok? 0= if ." Bad WLAN helper image" cr true exit then + (download-helper) +; + +: load-8686-fw ( -- error? ) + wlan-helper find-fw dup if ( adr len ) + download-helper if true exit then + else ( adr len ) + 2drop ( ) + then ( ) + + wlan-fw find-fw dup if ( adr len ) + download-fw ( error? ) + else ( adr len ) + 2drop false ( error? ) + then ( error? ) +; +' load-8686-fw to load-all-fw + + +\ LICENSE_BEGIN +\ Copyright (c) 2007 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Added: dev/mmc/sdhci/mv8686/mv8686.bth =================================================================== --- dev/mmc/sdhci/mv8686/mv8686.bth (rev 0) +++ dev/mmc/sdhci/mv8686/mv8686.bth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,48 @@ +purpose: Marvel SDIO 8686 wireless ethernet driver loader +\ See license at end of file + +command: &tokenize &this +build-now + +silent on + +begin-tokenizing mv8686.fc + +FCode-version2 + +fload ${BP}/dev/mmc/sdhci/mv8686/common.fth \ Ethernet common variables and routines +fload ${BP}/dev/mmc/sdhci/mv8686/queue.fth \ Receive queue management +fload ${BP}/dev/mmc/sdhci/mv8686/sdio.fth \ SDIO interface routines +fload ${BP}/dev/mmc/sdhci/mv8686/mv8686.fth \ SDIO I/O interface for Marvell 8686 +fload ${BP}/dev/libertas.fth \ Marvell "Libertas" common code +fload ${BP}/dev/mmc/sdhci/mv8686/fw8686.fth \ Marvell firmware download for SDIO +\ fload ${BP}/dev/mmc/sdhci/mv8686/wlan.fth \ External interface methods + +end0 + +end-tokenizing + + +\ LICENSE_BEGIN +\ Copyright (c) 2007 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Added: dev/mmc/sdhci/mv8686/mv8686.fth =================================================================== --- dev/mmc/sdhci/mv8686/mv8686.fth (rev 0) +++ dev/mmc/sdhci/mv8686/mv8686.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,114 @@ +purpose: Transport interface for Marvel 8686 wireless ethernet driver +\ See license at end of file + +headers +hex + +\ ======================================================================= +\ Wireless environment variables +\ wlan-fw e.g., rom:mv8686.bin, disk:\mv8686.bin +\ wlan-helper e.g., rom:mvhelper.bin, disk:\mvhelper.bin +\ ======================================================================= + +: wlan-fw ( -- $ ) + " wlan-fw" " $getenv" evaluate if " rom:sd8686.bin" then +; +: wlan-helper ( -- $ ) + " wlan-helper" " $getenv" evaluate if " rom:helper_sd.bin" then +; + +\ >fw-type constants +0 constant CMD_TYPE_DATA +1 constant CMD_TYPE_CMD +3 constant CMD_TYPE_EVENT + +struct +2 field >fw-plen +2 field >fw-type +constant /fw-transport + +: packet-type ( adr -- type ) + >fw-type le-w@ case + CMD_TYPE_CMD of 0 endof + CMD_TYPE_DATA of 1 endof + CMD_TYPE_EVENT of 2 endof + endcase +; + +: cmd-out ( adr len -- error? ) + read-poll + 2dup swap >fw-plen le-w! ( len ) + CMD_TYPE_CMD 2 pick >fw-type le-w! ( len ) + + 2dup vdump ( adr len ) + packet-out ( error? ) +; + +: data-out ( adr len -- ) + read-poll + 2dup swap >fw-plen le-w! ( adr len ) + CMD_TYPE_DATA 2 pick >fw-type le-w! ( adr len ) + packet-out-async +; + +: got-packet? ( -- false | error true | buf len 0 true ) + read-poll ( ) + + get-queued? if ( buf len ) + 0 true ( buf len 0 true ) + else ( ) + false ( false ) + then +; +: recycle-packet ( -- ) recycle-queued ; + +0 value rca \ Relative card address + +: set-parent-channel ( -- ) rca my-unit set-address ; + +: release-bus-resources ( -- ) drain-queue detach-card ; + +0 value card-attached? + +: ?attach-card ( -- ok? ) + card-attached? if true exit then + attach-card dup to card-attached? ( ok? ) +; + +: make-my-properties ( -- ) + get-address dup to rca + encode-int " assigned-address" property +; + +: setup-bus-io ( /inbuf /outbuf -- error? ) + 2drop + init-queue + ?attach-card 0= if ." Fail to attach card" cr true exit then + make-my-properties + init-device + false +; + +\ LICENSE_BEGIN +\ Copyright (c) 2009 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Added: dev/mmc/sdhci/mv8686/queue.fth =================================================================== --- dev/mmc/sdhci/mv8686/queue.fth (rev 0) +++ dev/mmc/sdhci/mv8686/queue.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,85 @@ +\ See license at end of file +purpose: Packet queue routines + +\ Maintain a linked list of packets that were received while transmitting. + +\ Since the firmware mostly uses request/response protocols, the expected +\ queue length is either 0 or 1. However, since the queue is stored as a +\ linked list with dynamically allocated and freed entries, it costs very +\ little to make the maximum size rather large. + +d# 32 constant max#queued \ Toss old packets after this number + +variable rx-queue +0 value #queued + +struct \ Queue entry +/n field >link +/n field >length + 0 field >data +constant /q-header + +: init-queue ( -- ) 0 to #queued 0 rx-queue ! ; + +\ Do not execute this is #queued is 0 +: deque-oldest ( -- handle ) + 0 rx-queue ( prev this ) + begin dup >link @ dup while ( prev this next ) + rot drop ( prev' this' ) + repeat ( prev-handle oldest-handle 0 ) + rot >link ! ( oldest-handle ) + #queued 1- to #queued +; + +: release-buffer ( handle -- ) dup >length @ /q-header + dma-free ; + +: drain-queue ( -- ) + #queued 0 ?do deque-oldest release-buffer loop +; + +: new-buffer ( packet-length -- handle adr len ) + #queued max#queued >= if deque-oldest release-buffer then + + dup /q-header + dma-alloc ( packet-length handle ) + 2dup >length ! ( packet-length handle ) + dup >data rot ( handle adr len ) +; + +: enque-buffer ( handle -- ) + rx-queue @ over >link ! rx-queue ! + #queued 1+ to #queued +; + +0 instance value loaned-handle + +: get-queued? ( -- false | adr len true ) + #queued 0= if false exit then + deque-oldest to loaned-handle ( ) + loaned-handle >data loaned-handle >length @ ( adr len ) + true +; +: recycle-queued ( -- ) loaned-handle release-buffer ; + +\ LICENSE_BEGIN +\ Copyright (c) 2006 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Added: dev/mmc/sdhci/mv8686/sdio.fth =================================================================== --- dev/mmc/sdhci/mv8686/sdio.fth (rev 0) +++ dev/mmc/sdhci/mv8686/sdio.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,140 @@ +purpose: SDIO interface +\ See license at end of file + +hex +headers + +0 value ioport +d# 320 constant blksz \ Block size for data tx/rx +d# 32 constant fw-blksz + +: roundup-blksz ( n -- n' ) blksz 1- + blksz / blksz * ; + +: set-address ( rca slot -- ) " set-address" $call-parent ; +: get-address ( -- rca ) " get-address" $call-parent ; +: attach-card ( -- ok? ) " attach-sdio-card" $call-parent ; +: detach-card ( -- ) " detach-sdio-card" $call-parent ; + +\ The following are CMD52 (SDIO) variants +\ Flags: 80:CRC_ERROR 40:ILLEGAL_COMMAND 30:IO_STATE (see spec) +\ 08:ERROR 04:reserved 02:INVALID_FUNCTION# 01:OUT_OF_RANGE + +h# cf constant SDIO_FLAG_MASK + +: .io-state ( flags & 30 -- ) + case + h# 00 of ." card disabled; " endof + h# 10 of ." CMD state; " endof + h# 20 of ." data transfer; " endof + h# 30 of ." reserved; " endof + endcase +; +: .sdio-flags ( flags -- ) + dup SDIO_FLAG_MASK and 0= if drop exit then + ." IO_RW_DIRECT response = " + dup h# 80 and if ." CRC error; " then + dup h# 40 and if ." illegal command; " then + dup h# 30 and .io-state + dup h# 08 and if ." error; " then + dup h# 02 and if ." invalid function; " then + dup h# 01 and if ." argument out of range" then + cr +; + +: sdio-reg@ ( reg# function# -- value ) + " io-b@" $call-parent .sdio-flags +; + +: sdio-reg! ( value reg# function# -- ) + " io-b!" $call-parent .sdio-flags +; + +: sdio-reg!@ ( value reg# function# -- value' ) + " io-b!@" $call-parent .sdio-flags +; + +: sdio-scratch@ ( -- value ) + h# 34 1 sdio-reg@ ( lo ) + h# 35 1 sdio-reg@ ( lo hi ) + bwjoin ( value ) +; + +: sdio-poll-dl-ready ( -- ready? ) + false d# 100 0 do + h# 20 1 sdio-reg@ \ card status register + h# 9 tuck and = if drop true leave then + d# 100 usec + loop + dup 0= if ." sdio-poll-dl-ready failed" cr then +; + +: sdio-blocks@ ( adr len -- actual ) + >r >r + ioport 1 true r> r> blksz true " r/w-ioblocks" $call-parent ( actual ) +; + +: sdio-blocks! ( adr len -- actual ) + >r >r ioport 1 true r> r> blksz false " r/w-ioblocks" $call-parent +; + +: packet-out ( adr len -- error? ) tuck sdio-blocks! <> ; +: packet-out-async ( adr len -- ) sdio-blocks! drop ; + +: sdio-fw! ( adr len -- actual ) + >r >r ioport 1 true r> r> fw-blksz false " r/w-ioblocks" $call-parent +; + +: rx-ready? ( -- len ) + 5 1 sdio-reg@ \ Read interrupt status reg + dup 0= if exit then + dup invert 3 and 5 1 sdio-reg! \ Clear UP_LD bit + 1 and if + sdio-scratch@ \ Read payload length + else + 0 + then +; + +: read-poll ( -- ) + begin rx-ready? ?dup while ( len ) + new-buffer ( handle adr len ) + sdio-blocks@ drop ( handle ) + enque-buffer ( ) + repeat +; + +: init-device ( -- ) + 3 0 do i 1 sdio-reg@ loop \ Read the IO port + 0 bljoin to ioport + + 7 0 sdio-reg@ h# 20 or 7 0 sdio-reg! \ Enable async interrupt mode + + 2 2 0 sdio-reg! \ Enable IO function + 3 4 0 sdio-reg! \ Enable interrupts +; + +headers + +\ LICENSE_BEGIN +\ Copyright (c) 2006 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Modified: dev/mmc/sdhci/sdhci.fth =================================================================== --- dev/mmc/sdhci/sdhci.fth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/mmc/sdhci/sdhci.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -12,7 +12,7 @@ \ begin-select /pci/pci11ab,4101
" sd" device-name -0 " #address-cells" integer-property +1 " #address-cells" integer-property 0 " #size-cells" integer-property
" sdhci" " compatible" string-property @@ -20,6 +20,8 @@ h# 100 value /regs \ Standard size of SDHCI register block 1 value #slots
+0 instance value rca + : phys+ encode-phys encode+ ; : i+ encode-int encode+ ;
@@ -32,7 +34,7 @@ then
h# 40 my-space + " config-b@" $call-parent ( slot_info ) - 4 rshift 7 and 1+ ( #slots ) + 4 rshift 7 and 1+ dup to #slots ( #slots ) 0 ?do 0 0 h# 0100.0010 i 4 * + my-space + phys+ 0 i+ /regs i+ \ Operational regs for slot N loop @@ -43,7 +45,8 @@
0 value debug?
-0 value chip +0 instance value slot +0 instance value chip
h# 200 constant /block \ 512 bytes
@@ -52,17 +55,24 @@
: map-regs ( -- ) chip if exit then - 0 0 h# 0200.0010 my-space + /regs " map-in" $call-parent + 0 0 h# 0200.0010 slot 1- 4 * + my-space + /regs " map-in" $call-parent to chip 6 4 my-w! ; : unmap-regs ( -- ) chip 0= if exit then - 0 4 my-w! +\ 0 4 my-w! chip /regs " map-out" $call-parent 0 to chip ;
+external +: set-address ( rca slot -- ) to slot to rca map-regs ; +: get-address ( -- rca ) rca ; +: decode-unit ( addr len -- lun ) push-hex $number if 0 then pop-base ; +: encode-unit ( lun -- adr len ) push-hex (u.) pop-base ; +headers + : cl! ( l adr -- ) chip + rl! ; : cl@ ( adr -- l ) chip + rl@ ; : cw! ( w adr -- ) chip + rw! ; @@ -94,6 +104,7 @@ h# 7fff h# 60 cw! \ Disable internal pull-up/down on DATA3 then ; + \ Some Marvell-specific stuff : enable-sd-int ( -- ) h# 300c cl@ h# 8000.0002 or h# 300c cl! @@ -145,10 +156,23 @@ present-state@ h# 40000 and h# 40000 = ;
+: ?via-quirk ( -- ) + \ This is a workaround for an odd problem with the Via Vx855 chip. + \ You have to tell it to use 1.8 V, otherwise when you tell it + \ it to use 3.3V, it will use 1.8 V instead! You only have to + \ do this 1.8V thing once after power-up to fix it until the + \ next power cycle. The "fix" survives resets; it takes a power + \ cycle to break it again. + + my-space " config-l@" $call-parent h# 95d01106 = if h# 0a h# 29 cb! then +; + : card-power-on ( -- ) \ Card power on does not work if a removal interrupt is pending h# c0 isr! \ Clear any pending insert/remove events
+ ?via-quirk + \ The 200.0000 bit is set if 3.0V is supported. If it is, \ use it (value c for reg 29), otherwise use 3.3V (value e). \ For now we don't handle the 1.8V possibility. @@ -221,6 +245,8 @@ 0 instance value dma-vadr 0 instance value dma-padr 0 instance value dma-len +0 instance value io-block-len +0 instance value io-#blocks
: (dma-setup) ( adr #bytes block-size -- ) h# 7000 or 4 cw! ( adr #bytes ) \ Block size register @@ -240,6 +266,11 @@ dma-vadr dma-padr dma-len " dma-map-out" $call-parent ;
+: iodma-setup ( adr len -- ) + io-#blocks 6 cw! ( adr len ) \ Set block count + io-block-len (dma-setup) ( ) +; + : decode-esr ( esr -- ) dup h# 8000 and if ." Vendor8, " then dup h# 4000 and if ." Vendor4, " then @@ -333,6 +364,7 @@ \ Response types: \ R1: mirrored command and status \ R3: OCR register +\ R5: 8-bit flags, 8-bit data (for CMD52) \ R6: RCA \ R2: 136 bits (CID (cmd 2 or 9) or CSD (cmd 10)) \ R7: 136 bits (Interface condition, for CMD8) @@ -356,7 +388,6 @@
0 value scratch-buf
-0 instance value rca d# 16 instance buffer: cid
external @@ -467,9 +498,9 @@
: io-send-op-cond ( voltage-range -- ocr ) h# 050a 0 cmd response ; \ CMD5 R4 (SDIO)
-: >io-arg ( reg# function# -- arg ) 7 and d# 28 lshift or ; +: >io-arg ( reg# function# -- arg ) 7 and d# 28 lshift swap 9 lshift or ;
-\ The following are CMD52 (SDIO) variants +\ The following are CMD52 (SDIO R5) variants \ Flags: 80:CRC_ERROR 40:ILLEGAL_COMMAND 30:IO_STATE (see spec) \ 08:ERROR 04:reserved 02:INVALID_FUNCTION# 01:OUT_OF_RANGE : io-b@ ( reg# function# -- value flags ) @@ -489,37 +520,44 @@ \ These commands - io-{read,write}-{bytes,blocks} will need to be \ enclosed in a method like r/w-blocks, in order to set up the DMA hardware.
-0 instance value io-block-len +: write-blksz ( blksz function# -- ) + over to io-block-len ( blksz function# ) + h# 100 * h# 11 + ( blksz reg# ) + swap wbsplit rot tuck ( blksz.lo reg# blksz.hi reg# ) + 0 io-b! drop ( blksz.lo reg# ) + 1- 0 io-b! drop ( ) +;
\ In FIFO mode, the address inside the card does not autoincrement \ during the transfer. -: >io-xarg ( reg# function# fifo-mode? -- arg ) +: >io-xarg ( reg# function# inc? -- arg ) >r >io-arg r> 0= if h# 0400.0000 or then ;
\ Set up memory address in caller -: io-read-bytes ( len reg# function# fifo? -- flags ) \ 1 <= len <= 512 - >io-xarg ( len arg ) - swap h# 1ff and or ( arg' ) \ Byte count +: io-read-bytes ( reg# function# inc? len -- flags ) \ 1 <= len <= 512 + >r ( reg# function# inc? r: len ) + >io-xarg ( arg r: len ) + r> h# 1ff and or ( arg' ) \ Byte count h# 353a h# 13 cmd ( ) ; -: io-read-blocks ( adr len reg# function# fifo? -- flags ) - >io-xarg h# 0800.0000 or ( len arg ) - swap io-block-len / or ( arg' ) \ Block count - h# 353a h# 37 cmd ( ) +: io-read-blocks ( reg# function# inc? -- flags ) + >io-xarg h# 0800.0000 or ( arg ) + io-#blocks or ( arg' ) \ Block count + h# 353a h# 33 cmd ( ) ; -: io-write-bytes ( len reg# function# fifo? -- flags ) - >io-xarg h# 8000.0000 or ( len arg ) - swap h# 1ff and or ( arg' ) \ Byte count +: io-write-bytes ( reg# function# inc? len -- flags ) + >r ( reg# function# inc? r: len ) + >io-xarg h# 8000.0000 or ( arg r: len ) + r> h# 1ff and or ( arg' ) \ Byte count h# 353a h# 03 cmd ; -: io-write-blocks ( len reg# function# fifo? -- flags ) - >io-xarg h# 8800.0000 or ( len arg ) - swap io-block-len / or ( arg' ) \ Block count - h# 353a h# 27 cmd +: io-write-blocks ( reg# function# inc? -- flags ) + >io-xarg h# 8800.0000 or ( arg ) + io-#blocks or ( arg' ) \ Block count + h# 353a h# 23 cmd ;
- 9 instance value address-shift h# 8010.0000 value oc-mode \ Voltage settings, etc.
@@ -660,9 +698,26 @@ false ;
+\ -1 means error, 1 means retry +: power-up-sdio-card ( -- false | retry? true ) + intstat-on + card-power-off d# 20 ms + card-power-on d# 40 ms \ This delay is just a guess (20 was barely too slow for a Via board) + card-inserted? 0= if card-power-off intstat-off false true exit then + card-clock-slow d# 10 ms \ This delay is just a guess + reset-card \ Cmd 0 + false +; + +: set-sdio-voltage ( -- ) + 0 io-send-op-cond \ Cmd 5: get card voltage + h# ff.ffff and io-send-op-cond drop \ Cmd 5: set card voltage +; + external
: attach-card ( -- okay? ) + setup-host power-up-card if ( retry? ) \ The first try at powering up failed. if ( ) @@ -688,7 +743,7 @@
card-clock-25
- get-csd \ Cmd 9 - Get card-specific data +\ get-csd \ Cmd 9 - Get card-specific data
select-card \ Cmd 7 - Select
@@ -700,6 +755,42 @@ true ;
+: detach-card ( -- ) + card-clock-off + card-power-off +; + +: attach-sdio-card ( -- okay? ) + setup-host + power-up-sdio-card if ( retry? ) + \ The first try at powering up failed. + if ( ) + \ The card was detected, but didn't go to "powered up" state. + \ Sometimes that can be fixed by power cycling, so we retry + power-up-sdio-card if ( retry? ) + if ." SD card did not power up" cr then + false exit + then + \ The second attempt to power up the card worked + else + \ The card was not detected, so we give up + false exit + then + then + + set-sdio-voltage + get-rca \ Cmd 3 (SD) - Get relative card address + card-clock-25 + select-card \ Cmd 7 - Select + set-timeout + 4-bit + 22 7 0 io-b! \ Cmd 52 - Set 4-bit bus width and ECSI bit + h# cf and 0= +; + +: detach-sdio-card ( -- ) +; + : dma-alloc ( size -- vadr ) " dma-alloc" $call-parent ; : dma-free ( vadr size -- ) " dma-free" $call-parent ;
@@ -720,11 +811,28 @@ intstat-off ;
+: r/w-ioblocks ( reg# function# inc? addr len blksz in? -- actual ) + 2 pick 0= if 2drop 2drop 2drop drop 0 exit then \ Prevents hangs + intstat-on + >r ( reg# function# inc? addr len blksz r: in? ) + 2dup tuck 1- + swap / to io-#blocks ( reg# function# inc? addr len blksz r: in? ) + 4 pick write-blksz ( reg# function# inc? addr len r: in? ) + iodma-setup ( reg# function# inc? r: in? ) + wait-write-done + r> if ( reg# function# inc? ) + io-read-blocks + else + io-write-blocks ( true to writing? ) + then + 2 wait + dma-release + dma-len +\ intstat-off +; + 0 value open-count : open ( -- ) open-count 0= if - map-regs - setup-host d# 64 " dma-alloc" $call-parent to scratch-buf then open-count 1+ to open-count @@ -736,14 +844,13 @@ intstat-on wait-write-done scratch-buf d# 64 " dma-free" $call-parent - card-clock-off - card-power-off - unmap-regs then + unmap-regs open-count 1- 0 max to open-count ;
: init ( -- ) + 0 1 set-address map-regs vendor-modes unmap-regs
Added: dev/mmc/sdhci/sdhci2.bth =================================================================== --- dev/mmc/sdhci/sdhci2.bth (rev 0) +++ dev/mmc/sdhci/sdhci2.bth 2009-05-12 22:53:43 UTC (rev 1179) @@ -0,0 +1,29 @@ +purpose: Load file for SDHCI (Secure Digital Host Controller Interface) + +command: &tokenize &this +build-now + +silent on + +begin-tokenizing sdhci2.fc + +FCode-version2 +fload ${BP}/dev/mmc/sdhci/sdhci.fth + +init + +new-device + 1 encode-int " reg" property + " sdmmc" " $load-driver" eval drop +finish-device + +new-device + 2 encode-int " reg" property + " mv8686" " $load-driver" eval drop +finish-device + + +fload ${BP}/dev/mmc/sdhci/selftest.fth +end0 + +end-tokenizing
Modified: dev/mmc/sdhci/sdmmc.fth =================================================================== --- dev/mmc/sdhci/sdmmc.fth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/mmc/sdhci/sdmmc.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -35,6 +35,7 @@ : dma-free ( vadr size -- ) " dma-free" $call-parent ;
: open ( -- ) + 0 my-unit " set-address" $call-parent " attach-card" $call-parent 0= if false exit then
" " " deblocker" $open-package ?dup if @@ -56,6 +57,7 @@ ;
: close ( -- ) + " detach-card" $call-parent label-package close-package deblocker close-package ;
Modified: dev/mmc/sdhci/selftest.fth =================================================================== --- dev/mmc/sdhci/selftest.fth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/mmc/sdhci/selftest.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -35,6 +35,7 @@ external : selftest ( -- error? ) open 0= if ." Open /sd failed" cr true exit then + 0 1 set-address attach-card 0= if ." No card inserted" cr close false exit then alloc-test-bufs ['] (selftest) catch if true then
Modified: dev/usb2/device/wlan/common.fth =================================================================== --- dev/usb2/device/wlan/common.fth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/usb2/device/wlan/common.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -4,15 +4,6 @@ hex headers
-\ Interface to /supplicant support package -0 value supplicant-ih -: $call-supplicant ( ...$ -- ... ) supplicant-ih $call-method ; -: do-associate ( -- flag ) " do-associate" $call-supplicant ; -: process-eapol ( adr len -- ) " process-eapol" $call-supplicant ; -: .scan ( adr -- ) " .scan" $call-supplicant ; - -defer ?process-eapol ['] 2drop to ?process-eapol - \ String comparision : $= ( adr0 len0 adr1 len1 -- equal? ) 2 pick <> if 3drop false exit then ( adr0 len0 adr1 ) @@ -51,9 +42,6 @@ : vtype ( adr len -- ) debug? if type cr else 2drop then ;
-defer init-nic ( -- ) ' noop to init-nic -defer wrap-msg ( adr len -- adr' len' ) ' noop to wrap-msg -defer unwrap-msg ( adr len -- adr' len' ) ' noop to unwrap-msg defer link-up? ( -- up? ) ' true to link-up? defer reset-nic ( -- ) ' noop to reset-nic defer start-nic ( -- ) ' noop to start-nic @@ -65,23 +53,6 @@
: max-frame-size ( -- size ) d# 1514 ;
-0 value vid -0 value pid - -0 value outbuf -d# 2048 value /outbuf \ Power of 2 larger than max-frame-size - \ Override as necessary - -d# 2048 value /inbuf \ Power of 2 larger than max-frame-size - \ Override as necessary - -: init-buf ( -- ) - outbuf 0= if /outbuf dma-alloc to outbuf then -; -: free-buf ( -- ) - outbuf if outbuf /outbuf dma-free 0 to outbuf then -; - : property-or-abort ( name$ -- n ) 2dup get-my-property if ( name$ ) ." Can't find property " type cr stop-nic abort @@ -89,18 +60,15 @@ 2swap 2drop decode-int nip nip ( n ) ;
-: init ( -- ) - init - " vendor-id" property-or-abort to vid - " device-id" property-or-abort to pid +: find-fw ( $ -- adr len ) + over " rom:" comp if + " boot-read" evaluate \ Not a dropin + " loaded" evaluate + else + 4 - swap 4 + swap " find-drop-in" evaluate 0= if null$ then + then ;
-: bulk-out ( adr len pipe -- error? ) - drop - " send-out" $call-parent ( qtd ) - " wait-out" $call-parent ( error? ) -; - headers
\ LICENSE_BEGIN
Modified: dev/usb2/device/wlan/fw8388.fth =================================================================== --- dev/usb2/device/wlan/fw8388.fth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/usb2/device/wlan/fw8388.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -1,7 +1,6 @@ purpose: Marvel USB 8388 firmware loader \ See license at end of file
- \ ======================================================================= \ Firmware download data structures \ ======================================================================= @@ -32,7 +31,7 @@ 0 constant boot-ack-ok \ Download ok 1 constant boot-ack-fail \ Download failed
-\ Bulk out transfer: USB image download +\ USB image download request structure struct 4 field >dl-cmd \ Download command 4 field >dl-ba \ Address in the device @@ -74,23 +73,22 @@ " Bad command status length" vtype false exit then ( adr ) - dup >boot-magic le-l@ boot-magic <> if ( adr ) - drop ( ) - " Bad signature" vtype ( ) - false exit - then ( adr ) - >cmd-status c@ boot-ack-ok = ( ok? ) + >boot-magic le-l@ case ( ) + 0 of false exit endof \ BOOT_CMD_RESP_FAIL + 1 of true exit endof \ BOOT_CMD_RESP_OK + 2 of false exit endof \ BOOT_CMD_RESP_NOT_SUPPORTED + endcase ;
: wait-cmd-fw-dl-ack ( -- acked? ) d# 100 0 do ( ) - bulk-in-ready? if ( error | buf len 0 ) + got-packet? if ( error | buf len 0 ) if ( ) false ( acked? ) else ( buf len ) cmd-fw-dl-ok? ( acked? ) then ( acked? ) - restart-bulk-in ( acked? ) + recycle-packet ( acked? ) unloop exit then ( ) 1 ms ( ) @@ -104,7 +102,7 @@ cmd-fw-dl outbuf >boot-cmd c!
5 0 do - outbuf /boot-cmd bulk-out-pipe bulk-out drop + outbuf /boot-cmd packet-out drop wait-cmd-fw-dl-ack if leave then loop ; @@ -118,9 +116,9 @@
: wait-fw-dl-ack ( -- ) d# 500 0 do ( ) - bulk-in-ready? if ( error | buf len 0 ) + got-packet? if ( error | buf len 0 ) 0= if process-dl-resp then ( ) - restart-bulk-in ( ) + recycle-packet ( ) leave then ( ) 1 ms ( ) @@ -134,7 +132,7 @@ dl-seq outbuf >dl-seq le-l! \ Add sequence number to outbuf dup /dl-header + outbuf >dl-data 2 pick >dl-len le-l@ dup >r move \ Move payload to outbuf - outbuf r@ /dl-header + 4 + bulk-out-pipe bulk-out drop + outbuf r@ /dl-header + 4 + packet-out drop \ Send command wait-fw-dl-ack \ Wait for ACK r> + /dl-header + \ Advance pointer @@ -170,18 +168,21 @@ ." Unexpected event while waiting for firmware-started" cr then ; -: download-fw ( adr len -- ) - driver-state ds-not-ready <> if " Firmware downloaded" vtype 2drop exit then - 2dup fw-image-ok? 0= if ." Bad WLAN firmware image" cr exit then +: download-fw ( adr len -- error? ) + 2dup fw-image-ok? 0= if ." Bad WLAN firmware image" cr true exit then download-fw-init (download-fw)
wait-fw + false +;
- ds-ready to driver-state - marvel-get-mac-address +: load-8388-fw ( -- error? ) + wlan-fw find-fw ( adr len ) + dup if download-fw else 2drop true then ;
+' load-8388-fw to load-all-fw
\ LICENSE_BEGIN \ Copyright (c) 2007 FirmWorks
Modified: dev/usb2/device/wlan/usb8388.bth =================================================================== --- dev/usb2/device/wlan/usb8388.bth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/usb2/device/wlan/usb8388.bth 2009-05-12 22:53:43 UTC (rev 1179) @@ -12,9 +12,10 @@
fload ${BP}/dev/usb2/device/common.fth \ USB device driver common routines fload ${BP}/dev/usb2/device/wlan/common.fth \ Ethernet common variables and routines -fload ${BP}/dev/usb2/device/wlan/usb8388.fth \ Marvel USB 8388 driver -fload ${BP}/dev/usb2/device/wlan/fw8388.fth \ Marvel firmware download -fload ${BP}/dev/usb2/device/wlan/wlan.fth \ USB wireless ethernet driver +fload ${BP}/dev/usb2/device/wlan/usb8388.fth \ USB I/O interface for Marvell 8388 +fload ${BP}/dev/libertas.fth \ Marvell "Libertas" common code +\ fload ${BP}/dev/usb2/device/wlan/wlan.fth \ External interface methods +fload ${BP}/dev/usb2/device/wlan/fw8388.fth \ Marvell firmware download for USB
end0
Modified: dev/usb2/device/wlan/usb8388.fth =================================================================== --- dev/usb2/device/wlan/usb8388.fth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/usb2/device/wlan/usb8388.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -1,19 +1,20 @@ -purpose: Marvel USB 8388 wireless ethernet driver +purpose: USB transport interface for Marvel USB 8388 wireless ethernet driver \ See license at end of file
headers hex
-\ **************** WPA and WPA2 are not functional yet ****************** +\ Used by cmd-out below and also by firmware download routine +: packet-out ( adr len -- error? ) + " send-out" $call-parent ( qtd ) + " wait-out" $call-parent ( error? ) +; +: packet-out-async ( adr len -- ) + " send-out" $call-parent ( qtd ) + drop +;
\ ======================================================================= -\ Usage: -\ -\ Before probe-pci, reset-wlan. -\ Before using the driver, set wlan-* environment variables. -\ ======================================================================= - -\ ======================================================================= \ Wireless environment variables \ wlan-fw e.g., rom:usb8388.bin, disk:\usb8388.bin \ ======================================================================= @@ -22,1506 +23,69 @@ " wlan-fw" " $getenv" evaluate if " rom:usb8388.bin" then ;
-\ ======================================================================= -\ Driver variables -\ ======================================================================= - -\ driver-state bit definitions -0000 constant ds-not-ready \ Initial state -0001 constant ds-ready \ Firmware has been downloaded -0010 constant ds-connected-mask \ Associated or joined -0010 constant ds-associated -8000 constant ds-disconnected \ Disconnected - -ds-not-ready value driver-state - -: set-driver-state ( bit-mask -- ) driver-state or to driver-state ; -: reset-driver-state ( bit-mask -- ) invert driver-state and to driver-state ; - -\ bss-type values -1 constant bss-type-managed -2 constant bss-type-adhoc -bss-type-managed value bss-type - -\ WPA/WPA2 keys -0 value ktype \ Key type -0 value ctype-g \ Group (multicast) cipher type -0 value ctype-p \ Pairwise (unicast) cipher type - -\ ktype values -0 constant kt-wep -1 constant kt-wpa -2 constant kt-wpa2 -h# ff constant kt-none - -\ ctype-x values -0 constant ct-none -1 constant ct-tkip -2 constant ct-aes - -\ WEP keys -1 constant TYPE_WEP_40_BIT -2 constant TYPE_WEP_104_BIT - -0 value wep-idx -d# 13 buffer: wep1 0 constant /wep1 -d# 13 buffer: wep2 0 constant /wep2 -d# 13 buffer: wep3 0 constant /wep3 -d# 13 buffer: wep4 0 constant /wep4 -: wep1$ ( -- $ ) wep1 /wep1 ; -: wep2$ ( -- $ ) wep2 /wep2 ; -: wep3$ ( -- $ ) wep3 /wep3 ; -: wep4$ ( -- $ ) wep4 /wep4 ; - -/mac-adr buffer: target-mac -: target-mac$ ( -- $ ) target-mac /mac-adr ; - -0 value #mc-adr \ Actual number of set multicast addresses -d# 32 dup constant #max-mc-adr \ Maximum number of multicast addresses -/mac-adr * dup constant /mc-adrs - buffer: mc-adrs \ Buffer of multicast addresses - -d# 256 buffer: ssid -0 value /ssid -: ssid$ ( -- $ ) ssid /ssid ; - -0 value channel - -d# 80 buffer: wpa-ie \ WPA IE saved for EAPOL phases -0 value /wpa-ie - -external -: wpa-ie$ ( -- adr len ) wpa-ie /wpa-ie ; -headers - -\ Data rates -d# 14 constant #rates -create supported-rates 82 c, 84 c, 8b c, 96 c, 0c c, 12 c, 18 c, 24 c, - 30 c, 48 c, 60 c, 6c c, 00 c, 00 c, -#rates buffer: common-rates - -external -: supported-rates$ ( -- adr len ) supported-rates #rates ; -: set-common-rates ( adr len -- ) - common-rates #rates erase - #rates min common-rates swap move -; -headers - -\ Miscellaneous -0 value preamble \ 0=long, 2=short, 4=auto -0 value auth-mode \ 0: open; 1: shared key; 2: EAP -h# 401 value cap \ Capabilities -3 instance value mac-ctrl \ MAC control - -external -: set-preamble ( preamble -- ) to preamble ; -: set-cap ( cap -- ) to cap ; -: set-auth-mode ( amode -- ) to auth-mode ; -headers - -: marvel-link-up? ( -- flag ) driver-state ds-ready > ; - -' marvel-link-up? to link-up? - -\ ========================================================================= -\ Firmware Command -\ ========================================================================= - struct - 4 field >fw-req \ Command request type - 2 field >fw-cmd \ Start of command header - 2 field >fw-len - 2 field >fw-seq - 2 field >fw-result -dup constant /fw-cmd -dup 4 - constant /fw-cmd-hdr \ Command header len (less >fw-req) - 0 field >fw-data \ Command payload starts here -drop +4 field >fw-transport +constant /fw-transport
-\ >fw-req constants -h# f00d.face constant CMD_TYPE_REQUEST -h# bead.c0de constant CMD_TYPE_DATA -h# beef.face constant CMD_TYPE_INDICATION +\ >fw-transport constants for USB/8388 +h# f00d.face constant TYPE_USB_REQUEST +h# bead.c0de constant TYPE_USB_DATA +h# beef.face constant TYPE_USB_INDICATION
-0 constant ACTION_GET -1 constant ACTION_SET -2 constant ACTION_ADD -3 constant ACTION_HALT -4 constant ACTION_REMOVE -8 constant ACTION_USE_DEFAULT - --1 value fw-seq - -: fw-seq++ ( -- seq ) fw-seq 1+ dup to fw-seq ; - -d# 30 constant resp-wait-tiny -d# 1,000 constant resp-wait-short -d# 10,000 constant resp-wait-long -resp-wait-short instance value resp-wait - -/inbuf instance buffer: respbuf -0 instance value /respbuf - -\ ========================================================================= -\ Transmit Packet Descriptor -\ ========================================================================= - -struct - 4 + \ >fw-req - 4 field >tx-stat - 4 field >tx-ctrl - 4 field >tx-offset - 2 field >tx-len - 6 field >tx-mac - 1 field >tx-priority - 1 field >tx-pwr - 1 field >tx-delay \ in 2ms - 1+ - 1+ \ tx-mesh must be 0 - 1+ \ tx-mesh must be 0 - 1 field >tx-mesh-ttl - 1+ \ Just for alignment - 0 field >tx-pkt -constant /tx-hdr - -0 constant tx-ctrl \ Tx rates, etc - -\ The Libertas FW is currently abusing the WDS flag to mean "send on the mesh". -\ At some point a separate mesh flag might be defined ... -h# 20000 constant TX_WDS - -: mesh-on? ( -- flag ) tx-ctrl TX_WDS and 0<> ; - -: wrap-pkt ( adr len -- adr' len' ) - outbuf /tx-hdr erase ( adr len ) - over outbuf >tx-mac /mac-adr move ( adr len ) - dup outbuf >tx-len le-w! ( adr len ) - tuck outbuf >tx-pkt swap move ( len ) - - CMD_TYPE_DATA outbuf >fw-req le-l! ( len ) - /tx-hdr 4 - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-ctrl field - tx-ctrl outbuf >tx-ctrl le-l! ( len ) - - mesh-on? if 1 outbuf >tx-mesh-ttl c! then ( len ) - - outbuf swap /tx-hdr + ( adr' len' ) +: cmd-out ( adr len -- error? ) + TYPE_USB_REQUEST 2 pick >fw-transport le-l! ( adr len ) + 2dup vdump ( adr len ) + packet-out ( error? ) ; -' wrap-pkt to wrap-msg
-\ ========================================================================= -\ Receive Packet Descriptor -\ ========================================================================= - -true instance value got-data? -0 instance value /data -0 instance value data - -\ Receive packet descriptor -struct - 4 + \ >fw-req - 2 field >rx-stat - 1 field >rx-snr - 1 field >rx-ctrl - 2 field >rx-len - 1 field >rx-nf - 1 field >rx-rate - 4 field >rx-offset - 4 + - 1 field >rx-priority - 3 + -\ dup constant /rx-desc -\ 6 field >rx-dst-mac -\ 6 field >rx-src-mac -\ 0 field >rx-data-no-snap -\ 2 field >rx-pkt-len \ pkt len from >rx-snap-hdr -\ 6 field >rx-snap-hdr -\ 0 field >rx-data -d# 22 + \ Size of an Ethernet header with SNAP -constant /rx-min - -\ >rx-stat constants -1 constant rx-stat-ok -2 constant rx-stat-multicast - -: snap-header " "(aa aa 03 00 00 00)" ; - -: rx-rate$ ( -- adr len ) " 1 25.5 11 ? 6 9 12 18 24 36 48 54 ? ? ?" ; -: .rx-rate ( rate -- ) h# f and 3 * rx-rate$ drop + 3 type ; - -: .rx-desc ( adr -- ) - debug? 0= if drop exit then - ?cr - ." Rx status: " dup >rx-stat le-w@ u. cr - ." Rx offset: " dup >rx-offset le-l@ u. cr - ." Rx len: " dup >rx-len le-w@ u. cr - ." Rx SNR: " dup >rx-snr c@ .d ." dB" cr - ." Rx noise floor: -" dup >rx-nf c@ .d ." dBm" cr - ." Rx rate: " dup >rx-rate c@ .rx-rate ." Mbps" cr - ." Rx priority: " dup >rx-priority c@ u. cr - drop +: data-out ( adr len -- ) + TYPE_USB_DATA 2 pick >fw-transport le-l! ( adr len ) + packet-out-async ;
-: unwrap-pkt ( adr len -- data-adr data-len ) - /rx-min < if drop 0 0 then \ Invalid packet: too small - - \ Go to the payload, skipping the descriptor header - dup dup >rx-offset le-l@ + la1+ ( adr data-adr ) - swap >rx-len le-w@ ( data-adr data-len ) - - \ Remove snap header by moving the MAC addresses up - \ That's faster than moving the contents down - over d# 14 + snap-header comp 0= if ( data-adr data-len ) - over dup 8 + d# 12 move ( data-adr data-len ) - 8 /string ( adr' len' ) - then -; - -: process-data ( adr len -- ) - 2dup vdump ( adr len ) - over .rx-desc ( adr len ) - - over >rx-stat le-w@ rx-stat-ok <> if 2drop exit then - - unwrap-pkt to /data to data ( ) - - true to got-data? \ do-process-eapol may unset this - - \ Check the Ethernet type field for EAPOL messages - data d# 12 + be-w@ h# 888e = if \ Pass EAPOL messages to supplicant - data /data ?process-eapol - then -; - -: do-process-eapol ( adr len -- ) false to got-data? process-eapol ; - -\ ========================================================================= -\ Generic commands & responses -\ ========================================================================= - -0 value x \ Temporary variables to assist command creation -0 value /x - -: set-fw-data-x ( -- ) outbuf >fw-data to x 0 to /x ; -: 'x ( -- adr ) x /x + ; -: +x ( n -- ) /x + to /x ; -: +x$ ( $ -- ) 'x swap dup +x move ; -: +xl ( n -- ) 'x le-l! /l +x ; -: +xw ( n -- ) 'x le-w! /w +x ; -: +xb ( n -- ) 'x c! /c +x ; -: +xbl ( n -- ) 'x be-l! /l +x ; -: +xerase ( n -- ) 'x over erase +x ; - -: outbuf-bulk-out ( dlen -- error? ) - /fw-cmd + outbuf swap ( adr len ) - 2dup vdump bulk-out-pipe ( adr len ) - bulk-out ( error? ) -; - -: .cmd ( cmd -- ) - debug? 0= if drop exit then - ?cr - case - 0003 of ." CMD_GET_HW_SPEC" endof - 0005 of ." CMD_802_11_RESET" endof - 0006 of ." CMD_802_11_SCAN" endof - 000b of ." CMD_802_11_GET_LOG" endof - 0010 of ." CMD_MAC_MULTICAST_ADR" endof - 0011 of ." CMD_802_11_AUTHENTICATE" endof - 0013 of ." CMD_802_11_SET_WEP" endof - 0016 of ." CMD_802_11_SNMP_MIB" endof - 0019 of ." CMD_MAC_REG_ACCESS" endof - 001a of ." CMD_BBP_REG_ACCESS" endof - 001b of ." CMD_RF_REG_ACCESS" endof - 001c of ." CMD_802_11_RADIO_CONTROL" endof - 001d of ." CMD_802_11_RF_CHANNEL" endof - 001e of ." CMD_802_11_TX_POWER" endof - 001f of ." CMD_802_11_RSSI" endof - 0020 of ." CMD_802_11_RF_ANTENNA" endof - 0021 of ." CMD_802_11_PS_MODE" endof - 0022 of ." CMD_802_11_DATA_RATE" endof - 0024 of ." CMD_802_11_DEAUTHENTICATE" endof - 0026 of ." CMD_802_11_DISASSOCIATE" endof - 0028 of ." CMD_MAC_CONTROL" endof - 002b of ." CMD_802_11_AD_HOC_START" endof - 002c of ." CMD_802_11_AD_HOC_JOIN" endof - 002f of ." CMD_802_11_ENABLE_RSN" endof - 003e of ." CMD_802_11_DEEP_SLEEP" endof - 0040 of ." CMD_802_11_AD_HOC_STOP" endof - 0043 of ." CMD_802_11_HOST_SLEEP_CFG" endof - 0044 of ." CMD_802_11_WAKEUP_CONFIRM" endof - 004c of ." CMD_802_11_RGN_CODE" endof - 004d of ." CMD_802_11_MAC_ADDR" endof - 0050 of ." CMD_802_11_ASSOCIATE" endof - 0058 of ." CMD_802_11_BAND_CONFIG" endof - 0059 of ." CMD_EEPROM_ACCESS" endof - 005a of ." CMD_GSPI_BUS_CONFIG" endof - 005b of ." CMD_802_11D_DOMAIN_INFO" endof - 005c of ." CMD_WMM_ACK_POLICY" endof - 005e of ." CMD_802_11_KEY_MATERIAL" endof - 005f of ." CMD_802_11H_TPC_INFO" endof - 0060 of ." CMD_802_11H_TPC_ADAPT_REQ" endof - 0061 of ." CMD_802_11H_CHAN_SW_ANN" endof - 0062 of ." CMD_802_11H_MEASUREMENT_REQUEST" endof - 0063 of ." CMD_802_11H_GET_MEASUREMENT_REPORT" endof - 0066 of ." CMD_802_11_SLEEP_PARAMS" endof - 0068 of ." CMD_802_11_SLEEP_PERIOD" endof - 0069 of ." CMD_802_11_BCA_CONFIG_TIMESHARE" endof - 006b of ." CMD_802_11_BG_SCAN_CONFIG" endof - 006c of ." CMD_802_11_BG_SCAN_QUERY" endof - 006d of ." CMD_802_11_CAL_DATA_EXT" endof - 0071 of ." CMD_WMM_GET_STATUS" endof - 0072 of ." CMD_802_11_TPC_CFG" endof - 0073 of ." CMD_802_11_PA_CFG" endof - 0074 of ." CMD_802_11_FW_WAKE_METHOD" endof - 0075 of ." CMD_802_11_SUBSCRIBE_EVENT" endof - 0076 of ." CMD_802_11_RATE_ADAPT_RATESET" endof - 007f of ." CMD_TX_RATE_QUERY" endof - ( default ) ." Unknown command: " dup u. +\ Translate the USB/8388 type codes into more abstract codes, which +\ happen to be the codes used by the 8686 +: packet-type ( adr -- type ) + >fw-transport le-l@ case + TYPE_USB_REQUEST of 0 endof + TYPE_USB_DATA of 1 endof + TYPE_USB_INDICATION of 2 endof endcase - cr ;
-: prepare-cmd ( len cmd -- ) - dup .cmd - resp-wait-short to resp-wait - outbuf 2 pick /fw-cmd + erase ( len cmd ) - CMD_TYPE_REQUEST outbuf >fw-req le-l! ( len cmd ) - ( cmd ) outbuf >fw-cmd le-w! ( len ) - ( len ) /fw-cmd-hdr + outbuf >fw-len le-w! ( ) - fw-seq++ outbuf >fw-seq le-w! ( ) - 0 outbuf >fw-result le-w! ( ) - set-fw-data-x ( ) -; -: start-cmd ( cmd -- ) - dup .cmd - resp-wait-short to resp-wait - outbuf to x 0 to /x - CMD_TYPE_REQUEST +xl ( cmd ) - ( cmd ) +xw ( ) - 0 +xw ( ) \ Set len later - fw-seq++ +xw ( ) - 0 +xw ( ) -; -: finish-cmd ( -- len ) - /x 4 - outbuf 6 + le-w! \ Set len field - /x -; +: got-packet? ( -- false | error true | buf len 0 true ) bulk-in-ready? ; +: recycle-packet ( -- ) restart-bulk-in ;
-true value got-response? -true value got-indicator? +: end-out-ring ( -- ) " end-out-ring" $call-parent ;
-: process-disconnect ( -- ) ds-disconnected set-driver-state ; -: process-wakeup ( -- ) ; -: process-sleep ( -- ) ; -: process-pmic-failure ( -- ) ; -: process-gmic-failure ( -- ) ; +: set-parent-channel ( -- ) device set-target ;
-: .event ?cr ." Event: " type cr ; -0 instance value last-event -: process-ind ( adr len -- ) - drop - true to got-indicator? - 4 + le-l@ dup to last-event - case - h# 00 of " Tx PPA Free" .event endof \ n - h# 01 of " Tx DMA Done" .event endof \ n - h# 02 of " Link Loss with scan" .event process-disconnect endof - h# 03 of " Link Loss no scan" .event process-disconnect endof - h# 04 of " Link Sensed" .event endof - h# 05 of " CMD Finished" .event endof - h# 06 of " MIB Changed" .event endof - h# 07 of " Init Done" .event endof - h# 08 of " Deauthenticated" .event process-disconnect endof - h# 09 of " Disassociated" .event process-disconnect endof - h# 0a of " Awake" .event process-wakeup endof - h# 0b of " Sleep" .event process-wakeup endof - h# 0d of " Multicast MIC error" .event process-gmic-failure endof - h# 0e of " Unicast MIC error" .event process-pmic-failure endof - h# 0e of " WM awake" .event endof \ n - h# 11 of " HWAC - adhoc BCN lost" .event endof - h# 19 of " RSSI low" .event endof - h# 1a of " SNR low" .event endof - h# 1b of " Max fail" .event endof - h# 1c of " RSSI high" .event endof - h# 1d of " SNR high" .event endof - h# 23 of endof \ Suppress this; the user doesn't need to see it - \ h# 23 of ." Mesh auto-started" endof - h# 30 of endof \ Handle this silently -\ h# 30 of " Firmware ready" .event endof - ( default ) ." Unknown " dup u. - endcase +: setup-bus-io ( /inbuf /outbuf -- error? ) + 4 bulk-out-pipe " begin-out-ring" $call-parent ( /inbuf ) + h# 40 bulk-in-pipe " begin-in-ring" $call-parent + false ;
-: process-request ( adr len -- ) - 2dup vdump ( adr len ) - to /respbuf ( adr ) - respbuf /respbuf move ( ) - true to got-response? ( ) -; +: release-bus-resources ( -- ) end-bulk-in end-out-ring ;
-: process-rx ( adr len -- ) - over >fw-req le-l@ case - CMD_TYPE_REQUEST of process-request endof \ Response & request - CMD_TYPE_DATA of process-data endof \ Data - CMD_TYPE_INDICATION of process-ind endof \ Indication - ( default ) >r vdump r> - endcase -;
-: check-for-rx ( -- ) - bulk-in-ready? if ( error | buf len 0 ) - 0= if process-rx then ( ) - restart-bulk-in ( ) - then ( ) -; +0 value vid +0 value pid
-\ : xcheck-for-rx ( -- ) -\ bulk-in? if ( actual ) -\ drop restart-bulk-in exit \ USB error -\ else ( actual ) -\ ?dup if ( actual ) -\ inbuf respbuf rot dup to /respbuf move -\ restart-bulk-in -\ respbuf /respbuf process-rx -\ then -\ then -\ ; - -\ -1 error, 0 okay, 1 retry -: wait-cmd-resp ( -- -1|0|1 ) - false to got-response? - resp-wait 0 do - check-for-rx - got-response? if leave then - 1 ms - loop - got-response? if - respbuf >fw-result le-w@ case - 0 of 0 endof \ No error - 4 of 1 endof \ Busy, so retry - ( default ) ." Result = " dup u. cr dup - endcase - else -\ ." Timeout or USB error" cr - true +: init ( -- ) + init + " vendor-id" property-or-abort to vid + " device-id" property-or-abort to pid + set-parent-channel + configuration set-config if + ." Failed to set USB configuration for wireless" cr then ; -: wait-event ( -- true | event false ) - false to got-indicator? - d# 1000 0 do - check-for-rx - got-indicator? if last-event false unloop exit then - 1 ms - loop - true -; -: outbuf-wait ( len -- error? ) - outbuf-bulk-out ?dup if exit then - wait-cmd-resp -;
+init
-\ ========================================================================= -\ Dumps -\ ========================================================================= - -: .fw-cap ( cap -- ) - ." 802.11" - dup h# 400 and if ." a" then - dup h# 100 and if ." b" then - dup h# 200 and if ." g" then ." ;" - dup h# 1 and if ." WPA;" then - dup h# 2 and if ." PS;" then - dup h# 8 and if ." EEPROM does not exit;" then - dup h# 30 and case - h# 00 of ." TX antanna 0;" endof - h# 10 of ." TX antenna 1;" endof - ( default ) ." TX diversity; " - endcase - h# c0 and case - h# 00 of ." RX antenna 0;" endof - h# 40 of ." RX antenna 1;" endof - ( default ) ." RX diversity;" - endcase -; - -: .log ( adr -- ) - dup >fw-len le-w@ /fw-cmd-hdr = if drop exit then - ." Multicast txed: " dup >fw-data le-l@ u. cr - ." Failed: " dup >fw-data 4 + le-l@ u. cr - ." Retry: " dup >fw-data 8 + le-l@ u. cr - ." Multiple retry: " dup >fw-data h# c + le-l@ u. cr - ." Duplicate frame rxed: " dup >fw-data h# 10 + le-l@ u. cr - ." Successful RTS: " dup >fw-data h# 14 + le-l@ u. cr - ." Failed RTS: " dup >fw-data h# 18 + le-l@ u. cr - ." Failed ACK: " dup >fw-data h# 1c + le-l@ u. cr - ." Fragment rxed: " dup >fw-data h# 20 + le-l@ u. cr - ." Multicast rxed: " dup >fw-data h# 24 + le-l@ u. cr - ." FCS error: " dup >fw-data h# 28 + le-l@ u. cr - ." Frame txed: " dup >fw-data h# 2c + le-l@ u. cr - ." WEP undecryptable: " dup >fw-data h# 30 + le-l@ u. cr - drop -; - - -\ ========================================================================= -\ Reset -\ ========================================================================= - -: reset-wlan ( -- ) " wlan-reset" evaluate ; - -: marvel-get-hw-spec ( -- true | adr false ) - d# 38 h# 03 ( CMD_GET_HW_SPEC ) prepare-cmd - d# 38 outbuf-bulk-out ?dup if true exit then - resp-wait-tiny to resp-wait - wait-cmd-resp if true exit then - - respbuf >fw-data false -; - -\ The purpose of this is to work around a problem that I don't fully understand. -\ For some reason, when you reopen the device without re-downloading the -\ firmware, the first command silently fails - you don't get a response. -\ This is a "throwaway" command to handle that case without a long timeout -\ or a warning message. - -: nonce-cmd ( -- ) marvel-get-hw-spec 0= if drop then ; - -\ ========================================================================= -\ MAC address -\ ========================================================================= - -: marvel-get-mac-address ( -- ) - 8 h# 4d ( CMD_802_11_MAC_ADDRESS ) prepare-cmd - ACTION_GET +xw - 8 outbuf-wait if ." marvel-get-mac-address failed" cr exit then - respbuf >fw-data 2 + mac-adr$ move -; - -: marvel-set-mac-address ( -- ) - 8 h# 4d ( CMD_802_11_MAC_ADDRESS ) prepare-cmd - ACTION_SET +xw - mac-adr$ +x$ - 8 outbuf-wait if exit then -; - -: marvel-get-mc-address ( -- ) - 4 /mc-adrs + h# 10 ( CMD_MAC_MULTICAST_ADR ) prepare-cmd - ACTION_GET +xw - 4 /mc-adrs + outbuf-wait if exit then - respbuf >fw-data 2 + le-w@ to #mc-adr - respbuf >fw-data 4 + mc-adrs #mc-adr /mac-adr * move -; - -: marvel-set-mc-address ( adr len -- ) - 4 /mc-adrs + h# 10 ( CMD_MAC_MULTICAST_ADR ) prepare-cmd - ACTION_SET +xw - dup /mac-adr / dup +xw \ Number of multicast addresses - to #mc-adr - ( adr len ) 2dup +x$ \ Multicast addresses - mc-adrs swap move - 4 /mc-adrs + outbuf-wait if exit then -; - -\ ========================================================================= -\ Register access -\ ========================================================================= - -: reg-access@ ( reg cmd -- n ) - 8 swap prepare-cmd - ACTION_GET +xw - ( reg ) +xw - 8 outbuf-wait if 0 exit then - respbuf >fw-data 4 + le-l@ -; - -: bbp-reg@ ( reg -- n ) - 1a ( CMD_BBP_REG_ACCESS ) reg-access@ h# ff and -; -: rf-reg@ ( reg -- n ) - 1b ( CMD_RF_REG_ACCESS ) reg-access@ h# ff and -; -: mac-reg@ ( reg -- n ) - 19 ( CMD_MAC_REG_ACCESS ) reg-access@ -; -: eeprom-l@ ( idx -- n ) - a 59 ( CMD_EEPROM_ACCESS ) prepare-cmd - ACTION_GET +xw - ( idx ) +xw - 4 +xw - a outbuf-wait if 0 exit then - respbuf >fw-data 6 + le-l@ -; - -\ ========================================================================= -\ Miscellaneous control settings -\ ========================================================================= - -: set-radio-control ( -- ) - 4 h# 1c ( CMD_802_11_RADIO_CONTROL ) prepare-cmd - ACTION_SET +xw - preamble 1 or +xw \ Preamble, RF on - 4 outbuf-wait if exit then -; - -: (set-bss-type) ( bsstype -- ok? ) - 6 d# 128 + h# 16 ( CMD_802_11_SNMP_MIB ) prepare-cmd - ACTION_SET +xw - 0 +xw \ Object = desiredBSSType - 1 +xw \ Size of object - ( bssType ) +xb - 6 d# 128 + outbuf-wait 0= -; - -external -: set-bss-type ( bssType -- ok? ) dup to bss-type (set-bss-type) ; -headers - -: (set-mac-control) ( -- error? ) - 4 h# 28 ( CMD_MAC_CONTROL ) prepare-cmd - mac-ctrl +xw \ WEP type, WMM, protection, multicast, promiscous, WEP, tx, rx - 4 outbuf-wait -; - -: set-mac-control ( -- error? ) - (set-mac-control) if - (set-mac-control) drop - then -; - -: set-domain-info ( adr len -- ) - dup 6 + h# 5b ( CMD_802_11D_DOMAIN_INFO ) prepare-cmd - ACTION_SET +xw - 7 +xw \ Type = MrvlIETypes_DomainParam_t - ( len ) dup +xw \ Length of payload - ( adr len ) tuck +x$ \ Country IE - ( len ) 6 + outbuf-wait if exit then -; - -: enable-11d ( -- ) - 6 d# 128 + h# 16 ( CMD_802_11_SNMP_MIB ) prepare-cmd - ACTION_SET +xw - 9 +xw \ Object = enable 11D - 2 +xw \ Size of object - 1 +xw \ Enable 11D - 6 d# 128 + outbuf-wait if exit then -; - -external -: enforce-protection ( -- ) - mac-ctrl h# 400 or to mac-ctrl \ Enforce protection - set-mac-control -; - -: disable-protection ( -- ) - mac-ctrl h# 400 invert and to mac-ctrl - set-mac-control -; - -: set-key-type ( ctp ctg ktype -- ) to ktype to ctype-g to ctype-p ; - -: set-country-info ( adr len -- ) \ IEEE country IE - set-domain-info - enable-11d -; - -: enable-promiscuous ( -- ) - mac-ctrl h# 80 or to mac-ctrl - set-mac-control -; -: disable-promiscuous ( -- ) - mac-ctrl h# 80 invert and to mac-ctrl - set-mac-control -; - -: enable-multicast ( -- ) - mac-ctrl h# 20 or to mac-ctrl - set-mac-control -; -: disable-multicast ( -- ) - mac-ctrl h# 20 invert and to mac-ctrl - set-mac-control -; -: set-multicast ( adr len -- ) marvel-set-mc-address enable-multicast ; - -: mac-off ( -- ) - 0 to mac-ctrl set-mac-control 3 to mac-ctrl -; -headers - -\ ========================================================================= -\ Scan -\ ========================================================================= - -1 constant #probes - -d# 14 constant #channels - -[ifdef] notdef -struct - 2 field >type-id - 2 field >/payload -dup constant /marvel-IE-hdr - 2 field >probes -constant /probes-IE - -struct - 1 field >radio-type - 1 field >channel# - 1 field >scan-type - 2 field >min-scan-time - 2 field >max-scan-time -constant /chan-list - -struct - /marvel-IE-hdr + - #channels /chan-list * field >chan-list -constant /chan-list-IE - -struct - /marvel-IE-hdr + - d# 34 field >ssid -constant /ssid-IE - -struct - 1 field >bss-type - 6 field >bss-id - /chan-list-IE field >chan-list-IE - /probes-IE field >probes-IE -constant /cmd_802_11_scan -[then] - -1 constant BSS_INDEPENDENT -2 constant BSS_INFRASTRUCTURE -3 constant BSS_ANY - -\ OUI values (big-endian) -h# 0050.f201 constant wpa-tag \ WPA tag -h# 0050.f202 constant moui-tkip \ WPA cipher suite TKIP -h# 0050.f204 constant moui-aes \ WPA cipher suite AES -h# 000f.ac02 constant oui-tkip \ WPA2 cipher suite TKIP -h# 000f.ac04 constant oui-aes \ WPA2 cipher suite AES -h# 000f.ac02 constant aoui \ WPA2 authentication suite -h# 0050.f202 constant amoui \ WPA authentication suite - - -d# 34 instance buffer: scan-ssid - -0 value scan-type -: active-scan ( -- ) 0 to scan-type ; -: passive-scan ( -- ) 1 to scan-type ; - -[ifdef] notdef -: make-chan-list-param ( adr -- ) - #channels 0 do - dup i /chan-list * + - 0 over >radio-type c! - i 1+ over >channel# c! - scan-type over >scan-type c! - d# 100 over >min-scan-time le-w! - d# 100 swap >max-scan-time le-w! - loop drop -; - -: (oldscan) ( -- error? | adr len 0 ) - /cmd_802_11_scan scan-ssid c@ if - /marvel-IE-hdr + scan-ssid c@ + - then - 6 ( CMD_802_11_SCAN ) prepare-cmd ( ) - resp-wait-long to resp-wait ( ) - BSS_ANY outbuf >fw-data tuck >bss-type c! ( 'fw-data ) - - dup >chan-list-IE ( 'fw-data 'chan-list ) - h# 101 over >type-id le-w! ( 'fw-data 'chan-list ) - #channels /chan-list * over >/payload le-w! ( 'fw-data 'chan-list ) - >chan-list make-chan-list-param ( 'fw-data ) - - dup >probes-IE ( 'fw-data 'probes ) - h# 102 over >type-id le-w! ( 'fw-data 'probes ) - 2 over >/payload le-w! ( 'fw-data 'probes ) - #probes swap >probes le-w! ( 'fw-data ) - - scan-ssid c@ if ( 'fw-data ) - \ Attach an SSID TLV to filter the result - /cmd_802_11_scan + ( 'ssid ) - h# 000 over >type-id le-w! ( 'ssid ) - scan-ssid c@ over >/payload le-w! ( 'ssid ) - scan-ssid count rot /marvel-IE-hdr + swap move ( ) - /cmd_802_11_scan /marvel-IE-hdr scan-ssid c@ + + ( cmdlen ) - else ( 'fw-data ) - drop - /cmd_802_11_scan ( cmdlen ) - then ( cmdlen ) - - outbuf-wait ( error? ) - dup 0= if ( error? ) - respbuf /respbuf /fw-cmd /string rot ( adr len 0 ) - then -; -[then] - -h# 7ffe instance value channel-mask - -: +chan-list-tlv ( -- ) - h# 101 +xw - 0 +xw 'x >r ( r: 'payload ) - #channels 1+ 1 do - 1 i lshift channel-mask and if - 0 +xb \ Radio type - i +xb \ Channel # - scan-type +xb \ Scan type - 0:active or 1:passive - d# 100 +xw \ Min scan time - d# 100 +xw \ Max scan time - then - loop - 'x r@ - r> 2- le-w! -; - -: +probes-tlv ( -- ) - h# 102 +xw \ Probes TLV - 2 +xw \ length - #probes +xw \ #probes -; - -: +ssid-tlv ( -- ) - scan-ssid c@ if - 0 +xw \ SSID TLV - scan-ssid c@ +xw \ length - scan-ssid count +x$ - then -; - -: (scan) ( -- error? | adr len 0 ) - 6 ( CMD_802_11_SCAN ) start-cmd - resp-wait-long to resp-wait - - BSS_ANY +xb - 6 +xerase \ BSS ID - - +chan-list-tlv - +probes-tlv - +ssid-tlv - - finish-cmd outbuf-wait ( error? ) - dup 0= if ( error? ) - respbuf /respbuf /fw-cmd /string rot ( adr len 0 ) - then -; - - -external -: set-channel-mask ( n -- ) - h# 7ffe and to channel-mask -; - -\ Ask the device to look for the indicated SSID. -: set-ssid ( adr len -- ) - \ This is an optimization for NAND update over the mesh. - \ It prevents listening stations, of which there can be many, - \ from transmitting when they come on-line. - 2dup " olpc-mesh" $= if passive-scan then - - h# 32 min scan-ssid pack drop -; - -: scan ( adr len -- actual ) - begin (scan) dup 1 = while drop d# 1000 ms repeat \ Retry while busy - if 2drop 0 exit then ( adr len scan-adr scan-len ) - rot min >r ( adr scan-adr r: len ) - swap r@ move ( r: len ) - r> -; -headers - -\ ========================================================================= -\ WEP -\ ========================================================================= - -: set-wep-type ( len -- ) - ?dup if - 5 = if TYPE_WEP_40_BIT 8 else TYPE_WEP_104_BIT h# 8008 then - mac-ctrl or to mac-ctrl \ WEPxx on - else - 0 - then - +xb -; - -external -: (set-wep) ( wep4$ wep3$ wep2$ wep1$ idx -- ok? ) - d# 72 h# 13 ( CMD_802_11_SET_WEP ) prepare-cmd - ACTION_ADD +xw - ( idx ) +xw \ TxKeyIndex - dup set-wep-type - 2 pick set-wep-type - 4 pick set-wep-type - 6 pick set-wep-type - 4 0 do - ?dup if x /x + swap move else drop then - d# 16 /x + to /x - loop - d# 72 outbuf-wait 0= -; -: set-wep ( wep4$ wep3$ wep2$ wep1$ idx -- ok? ) - to wep-idx - dup to /wep1 wep1 swap move - dup to /wep2 wep2 swap move - dup to /wep3 wep3 swap move - dup to /wep4 wep4 swap move - true -; -: ?set-wep ( -- ) - ktype kt-wep = if - wep4$ wep3$ wep2$ wep1$ wep-idx (set-wep) drop - then -; - -: disable-wep ( -- ok? ) - mac-ctrl h# 8008 invert and to mac-ctrl \ Disable WEP - d# 72 h# 13 ( CMD_802_11_SET_WEP ) prepare-cmd - ACTION_REMOVE +xw - 0 +xw \ TxKeyIndex - d# 72 outbuf-wait 0= -; -headers - -\ ========================================================================= -\ WPA and WPA2 -\ ========================================================================= - -: set-rsn ( enable? -- ok? ) - 4 h# 2f ( CMD_802_11_ENABLE_RSN ) prepare-cmd - ACTION_SET +xw - ( enable? ) +xw \ 1: enable; 0: disable - 4 outbuf-wait 0= -; - -external -: enable-rsn ( -- ok? ) 1 set-rsn ; -: disable-rsn ( -- ok? ) 0 set-rsn ; -headers - -: set-key-material ( key$ kinfo ct -- ) - /outbuf h# 5e ( CMD_802_11_KEY_MATERIAL ) prepare-cmd - ACTION_SET +xw - h# 100 +xw \ Key param IE type - 2 pick 6 + +xw \ IE payload length - ( ct ) +xw \ Cipher type - ( kinfo ) +xw \ Key info - dup +xw \ Key length - ( key$ ) +x$ \ key$ - /x dup /fw-cmd-hdr + outbuf >fw-len le-w! \ Finally set the length - outbuf-wait if exit then -; - -external -: set-gtk ( gtk$ -- ) 5 ctype-g set-key-material ; -: set-ptk ( ptk$ -- ) 6 ctype-p set-key-material ; -headers - -\ ======================================================================= -\ Adhoc join -\ ======================================================================= - -0 value atim - -: save-associate-params ( ch ssid$ target-mac$ -- ch ssid$ target-mac ) - over target-mac$ move - 2over dup to /ssid - ssid swap move - 4 pick to channel -; - -: (join) ( ch ssid$ target-mac$ -- ok? ) - save-associate-params - /outbuf h# 2c ( CMD_802_11_AD_HOC_JOIN ) prepare-cmd - resp-wait-long to resp-wait - - ( target-mac$ ) +x$ \ Peer MAC address - ( ssid$ ) tuck +x$ \ SSID - ( ssid-len ) d# 32 swap - +x \ 32 bytes of SSID - bss-type-adhoc +xb \ BSS type - d# 100 +xw \ Beacon period - 1 +xb \ DTIM period - - 8 +x \ 8 bytes of time stamp - 8 +x \ 8 bytes of local time - - \ DS param set - 3 +xb \ Elem ID = DS param set - 1 +xb \ Length - ( channel ) +xb \ Channel - 4 +x \ Reserved bytes - - \ IBSS param set - 6 +xb \ Elem ID = IBSS param set - 2 +xb \ Length - atim +xw \ ATIM window - 4 +x \ Reserved bytes - - cap +xw \ Capability info: ESS, short slot, WEP - - \ XXX 14 bytes for 802.11g, 8 bytes for 802.11b - common-rates #rates +x$ \ Common supported data rates - d# 255 +xw \ Association timeout - 0 +xw \ Probe delay time - - /x dup /fw-cmd-hdr + outbuf >fw-len le-w! \ Finally set the length - outbuf-wait if ." Failed to join adhoc network" cr false exit then - true -; - -external -: set-atim-window ( n -- ) d# 50 min to atim ; -headers - -\ ========================================================================= -\ Authenticate -\ ========================================================================= - -: authenticate ( target-mac$ -- ) - 7 h# 11 ( CMD_802_11_AUTHENTICATE ) prepare-cmd - ( target-mac$ ) +x$ \ Peer MAC address - auth-mode +xb \ Authentication mode - 7 outbuf-wait if exit then -; - -: deauthenticate ( mac$ -- ) - 8 h# 24 ( CMD_802_11_DEAUTHENTICATE ) prepare-cmd - ( mac$ ) +x$ \ AP MAC address - 3 +xw \ Reason code: station is leaving - 8 outbuf-wait if exit then - ds-disconnected set-driver-state -; - -\ Mesh - -: mesh-access! ( value cmd -- ) - h# 82 h# 9b ( CMD_MESH_ACCESS ) prepare-cmd ( value cmd ) - +xw +xl ( ) - - h# 82 outbuf-wait if exit then -; -: mesh-access@ ( cmd -- value ) - h# 82 h# 9b ( CMD_MESH_ACCESS ) prepare-cmd ( value cmd ) - +xw ( ) - - h# 82 outbuf-wait if -1 exit then - respbuf >fw-data wa1+ le-l@ -; - -: mesh-config-set ( adr len type channel action -- error? ) - h# 88 h# a3 ( CMD_MESH_CONFIG ) prepare-cmd ( adr len type channel action ) - +xw +xw +xw ( adr len ) - dup +xw +x$ ( ) - - h# 88 outbuf-wait -; -: mesh-config-get ( -- true | buf false ) - h# 88 h# a3 ( CMD_MESH_CONFIG ) prepare-cmd ( ) - 3 +xw 0 +xw 5 +xw ( ) - - h# 88 outbuf-wait if true exit then - respbuf >fw-data false -; -: (mesh-start) ( channel tlv -- error? ) - " "(dd 0e 00 50 43 04 00 00 00 00 00 04)mesh" ( channel tlv adr len ) - 2swap swap 1 ( adr len tlv channel action ) \ 1 is CMD_ACT_MESH_CONFIG_START - mesh-config-set -; - -: mesh-stop ( -- error? ) - mesh-on? if - " " 0 0 0 mesh-config-set ( error? ) - tx-ctrl TX_WDS invert and to tx-ctrl ( error? ) - ds-associated reset-driver-state ( error? ) - else - false ( error? ) - then -; - -: mesh-start ( channel -- error? ) - \ h# 223 (0x100 + 291) is an old value - \ h# 125 (0x100 + 37) is an "official" value that doesn't work - dup h# 223 (mesh-start) if ( channel ) - \ Retry once - h# 223 (mesh-start) ( error? ) - else - drop false ( error? ) - then - - dup 0= if ( error? ) - tx-ctrl TX_WDS or to tx-ctrl ( error? ) - ds-associated set-driver-state ( error? ) - then ( error? ) -; - -instance variable mesh-param -: mesh-set-bootflag ( bootflag -- error? ) - mesh-param le-l! mesh-param 4 1 0 3 mesh-config-set -; -: mesh-set-boottime ( boottime -- error? ) - mesh-param le-w! mesh-param 2 2 0 3 mesh-config-set -; -: mesh-set-def-channel ( boottime -- error? ) - mesh-param le-w! mesh-param 2 3 0 3 mesh-config-set -; -: mesh-set-ie ( adr len -- error? ) 4 0 3 mesh-config-set ; -: mesh-set-ttl ( ttl -- ) 2 mesh-access! ; -: mesh-get-ttl ( -- ttl ) 1 mesh-access@ ; -: mesh-set-bcast ( index -- ) 8 mesh-access! ; -: mesh-get-bcast ( -- index ) 9 mesh-access@ ; - -[ifdef] notdef -: mesh-set-anycast ( mask -- ) 5 mesh-access! ; -: mesh-get-anycast ( -- mask ) 4 mesh-access@ ; - -: mesh-set-rreq-delay ( n -- ) d# 10 mesh-access! ; -: mesh-get-rreq-delay ( -- n ) d# 11 mesh-access@ ; - -: mesh-set-route-exp ( n -- ) d# 12 mesh-access! ; -: mesh-get-route-exp ( -- n ) d# 13 mesh-access@ ; - -: mesh-set-autostart ( n -- ) d# 14 mesh-access! ; -: mesh-get-autostart ( -- n ) d# 15 mesh-access@ ; - -: mesh-set-prb-rsp-retry-limit ( n -- ) d# 17 mesh-access! ; -[then] - -\ ========================================================================= -\ Associate/disassociate -\ ========================================================================= - -0 value assoc-id - -\ The source IE is in the Marvel format: id and len are 2 bytes long. -\ The destination IE is in the 802.11 format: id and len are 1 byte long. -: save-wpa-ie ( boffset eoffset -- ) - over - 2 - to /wpa-ie \ Less extra bytes - x + dup c@ wpa-ie c! \ Copy IE id - 2 + dup c@ wpa-ie 1+ c! \ Copy len - 2 + wpa-ie /wpa-ie 2 /string move \ Copy body of IE -; - -: moui ( ct -- ) ct-tkip = if moui-tkip else moui-aes then ; -: oui ( ct -- ) ct-tkip = if oui-tkip else oui-aes then ; - -: (associate) ( ch ssid$ target-mac$ -- ok? ) - save-associate-params - - /outbuf h# 50 ( CMD_802_11_ASSOCIATE ) prepare-cmd - resp-wait-long to resp-wait - - ( target-mac$ ) +x$ \ Peer MAC address - cap +xw \ Capability info: ESS, short slot, WEP - d# 10 +xw \ Listen interval - d# 100 +xw \ Beacon period - 1 +xb \ DTIM period - - \ SSID - 0 +xw \ element ID = SSID - dup +xw \ len - ( ssid$ ) +x$ \ SSID - - \ DS param - 3 +xw \ element ID = DS param set - 1 +xw \ len - ( ch ) +xb \ channel - - \ CF param - 4 +xw \ element ID = CF param set - 0 +xw \ len - - \ Common supported rates - 1 +xw \ element ID = rates - #rates +xw \ len - common-rates #rates +x$ \ common supported data rates - - \ RSN (WPA2) - ktype kt-wpa2 = if - /x \ Save beginning offset - d# 48 +xw \ element ID = RSN - d# 20 +xw \ len - 1 +xw \ version - ctype-g oui +xbl \ group cipher suite - 1 +xw \ count of pairwise cipher suite - ctype-p oui +xbl \ pairwise cipher suite - 1 +xw \ count of authentication suite - aoui +xbl \ authentication suite - h# 28 +xw \ RSN capabilities - /x save-wpa-ie \ Save IE in wpa-ie - then - - \ WPA param - ktype kt-wpa = if - /x \ Save beginning offset - d# 221 +xw \ element ID = WPA - d# 24 +xw \ len - wpa-tag +xbl \ WPA-specific tag - 1 +xw \ version - ctype-g moui +xbl \ group cipher suite - 1 +xw \ count of pairwise cipher suite - ctype-p moui +xbl \ pairwise cipher suite - 1 +xw \ count of authentication suite - amoui +xbl \ authentication suite - ctype-p ct-tkip = if h# 2a else h# 28 then - ( cap ) +xw \ WPA capabilities - /x save-wpa-ie \ Save IE in wpa-ie - then - - \ XXX power (optional) - \ XXX supported channels set (802.11h only) - \ XXX pass thru IEs (optional) - - /x dup /fw-cmd-hdr + outbuf >fw-len le-w! \ Finally set the length - outbuf-wait if false exit then - - respbuf >fw-data 2 + le-w@ ?dup if \ This is the IEEE Status Code - ." Failed to associate: " u. cr - false - else - respbuf >fw-data 4 + le-w@ to assoc-id - ds-disconnected ds-connected-mask or reset-driver-state - true - then -; - -external -instance defer mesh-default-modes -' noop to mesh-default-modes -: nandcast-mesh-modes ( -- ) - 1 mesh-set-ttl - d# 12 mesh-set-bcast -; -' nandcast-mesh-modes to mesh-default-modes - -: associate ( ch ssid$ target-mac$ -- ok? ) - 2over " olpc-mesh" $= if ( ch ssid$ target-mac$ ) - 2drop 2drop mesh-start 0= ( ok? ) - dup if mesh-default-modes then - exit - then - ?set-wep \ Set WEP keys again, if ktype is WEP - set-mac-control - 2dup authenticate - bss-type bss-type-managed = if (associate) else (join) then -; -headers - -: do-associate ( -- ok? ) - do-associate dup if - ds-disconnected reset-driver-state - ds-associated set-driver-state - then -; - -: ?reassociate ( -- ) - driver-state ds-disconnected and if do-associate drop then -; -' ?reassociate to start-nic - -: disassociate ( mac$ -- ) - 8 h# 26 ( CMD_802_11_DISASSOCIATE ) prepare-cmd - ( mac$ ) +x$ \ AP MAC address - 3 +xw \ Reason code: station is leaving - 8 outbuf-wait if exit then - ds-disconnected set-driver-state -; - - -\ ======================================================================= -\ Miscellaneous -\ ======================================================================= - -: get-rf-channel ( -- ) - d# 40 h# 1d ( CMD_802_11_RF_CHANNEL ) prepare-cmd - ACTION_GET +xw - d# 40 outbuf-wait if exit then - ." Current channel = " respbuf >fw-data 2 + le-w@ .d cr -; - -: get-beacon ( -- interval enabled? ) - 6 h# b0 ( CMD_802_11_BEACON_CTRL ) prepare-cmd - ACTION_GET +xw - 6 outbuf-wait if exit then - respbuf >fw-data dup 2 wa+ le-w@ swap wa1+ le-w@ -; - -: set-beacon ( interval enabled? -- ) - 6 h# b0 ( CMD_802_11_BEACON_CTRL ) prepare-cmd - ACTION_SET +xw ( interval enabled? ) - +xw +xw - 6 outbuf-wait drop -; - - -: get-log ( -- ) - 0 h# b ( CMD_802_11_GET_LOG ) prepare-cmd - 0 outbuf-wait if exit then - respbuf .log -; - -: get-rssi ( -- ) - 2 h# 1f ( CMD_802_11_RSSI ) prepare-cmd - 8 +xw \ Value used for exp averaging - 2 outbuf-wait drop - \ XXX What to do with the result? -; - -: .hw-spec ( -- ) - marvel-get-hw-spec if - ." marvel-get-hw-spec command failed" cr - else - ." HW interface version: " dup le-w@ u. cr - ." HW version: " dup 2 + le-w@ u. cr - ." Max multicast addr: " dup 6 + le-w@ .d cr - ." MAC address: " dup 8 + .enaddr cr - ." Region code: " dup d# 14 + le-w@ u. cr - ." # antenna: " dup d# 16 + le-w@ .d cr - ." FW release: " dup d# 18 + le-l@ u. cr - ." FW capability:" d# 34 + le-l@ .fw-cap cr - then -; - -: set-data-rate ( rate-code -- ) - #rates 4 + h# 22 ( CMD_802_11_DATA_RATE ) prepare-cmd - - 1 ( CMD_ACT_SET_TX_FIX_RATE ) +xw - 0 +xw \ reserved field - ( rate-code ) +xb - - #rates 4 + outbuf-wait drop -; -: auto-data-rate ( -- ) - #rates 4 + h# 22 ( CMD_802_11_DATA_RATE ) prepare-cmd - - 0 ( CMD_ACT_SET_TX_FIX_RATE ) +xw - 0 +xw \ reserved field - - #rates 4 + outbuf-wait drop -; - - -: get-data-rates ( -- ) - #rates 4 + h# 22 ( CMD_802_11_DATA_RATE ) prepare-cmd - 2 ( HostCmd_ACT_GET_TX_RATE ) +xw - #rates 4 + outbuf-wait drop -; - -2 constant gpio-pin -d# 20 constant wake-gap -1 constant wake-on-broadcast -2 constant wake-on-unicast -4 constant wake-on-mac-event --1 constant remove-wakeup - -\ LED_GPIO_CTRL - -: host-sleep-activate ( -- ) - 0 h# 45 ( CMD_802_11_HOST_SLEEP_ACTIVATE ) prepare-cmd - 0 outbuf-wait drop -; - -: host-sleep-config ( conditions -- ) - >r - 6 h# 43 ( CMD_802_11_HOST_SLEEP_CFG ) prepare-cmd -\ ACTION_SET +xw - - r> +xl - gpio-pin +xb - wake-gap +xb - - 6 outbuf-wait drop -; - -: unicast-wakeup ( -- ) wake-on-unicast host-sleep-config ; -: broadcast-wakeup ( -- ) wake-on-unicast wake-on-broadcast or host-sleep-config ; -: sleep ( -- ) host-sleep-activate ; - -[ifdef] notdef - CMD_ACT_MESH_... - 1 GET_TTL 2 SET_TTL 3 GET_STATS 4 GET_ANYCAST 5 SET_ANYCAST - 6 SET_LINK_COSTS 7 GET_LINK_COSTS 8 SET_BCAST_RATE 9 GET_BCAST_RATE -10 SET_RREQ_DELAY 11 GET_RREQ_DELAY 12 SET_ROUTE_EXP 13 GET_ROUTE_EXP -14 SET_AUTOSTART_ENABLED 15 GET_AUTOSTART_ENABLED 16 not used -17 SET_PRB_RSP_RETRY_LIMIT - -CMD_TYPE_MESH_ -1 SET_BOOTFLAG 2 SET_BOOTTIME 3 SET_DEF_CHANNEL 4 SET_MESH_IE -5 GET_DEFAULTS 6 GET_MESH_IE /* GET_DEFAULTS is superset of GET_MESHIE */ - -CMD_ACT_MESH_CONFIG_.. 0 STOP 1 START 2 SET 3 GET - -struct cmd_ds_mesh_config { - struct cmd_header hdr; - __le16 action; __le16 channel; __le16 type; __le16 length; - u8 data[128]; /* last position reserved */ -} -struct mrvl_meshie_val { - uint8_t oui[P80211_OUI_LEN]; - uint8_t type; - uint8_t subtype; - uint8_t version; - uint8_t active_protocol_id; - uint8_t active_metric_id; - uint8_t mesh_capability; - uint8_t mesh_id_len; - uint8_t mesh_id[IW_ESSID_MAX_SIZE]; 32 -} -struct ieee80211_info_element { - u8 id; u8 len; u8 data[0]; -} -struct mrvl_meshie { - struct ieee80211_info_element hdr; - struct mrvl_meshie_val val; -} - memset(&cmd, 0, sizeof(cmd)); - cmd.channel = cpu_to_le16(chan); - ie = (struct mrvl_meshie *)cmd.data; - - switch (action) { - case CMD_ACT_MESH_CONFIG_START: -0.b 221 ie->hdr.id = MFIE_TYPE_GENERIC; -2.b h# 00 ie->val.oui[0] = 0x00; -3.b h# 50 ie->val.oui[1] = 0x50; -4.b h# 43 ie->val.oui[2] = 0x43; -5.b 4 ie->val.type = MARVELL_MESH_IE_TYPE; -6.b 0 ie->val.subtype = MARVELL_MESH_IE_SUBTYPE; -7.b 0 ie->val.version = MARVELL_MESH_IE_VERSION; -8.b 0 ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP; -9.b 0 ie->val.active_metric_id = MARVELL_MESH_METRIC_ID; -10.b 0 ie->val.mesh_capability = MARVELL_MESH_CAPABILITY; -11.b ssid_len ie->val.mesh_id_len = priv->mesh_ssid_len; -12 memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len); -1 10+ssid_len ie->hdr.len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + priv->mesh_ssid_len; - - 42 (32+10) cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val)); - -config_start: action is 1 (...CONFIG_START), type = mesh_tlv which is either h# 100 d# 291 + or h# 100 d# 37 + -[then] - -[ifdef] notdef -create mesh_start_cmd - \ MFIE_TYPE_GENERIC ielen (10 + sizeof("mesh")) - d# 221 c, d# 14 c, - - \ OUI.................... type subtyp vers proto metric cap - h# 00 c, h# 50 c, h# 43 c, 4 c, 0 c, 0 c, 0 c, 0 c, 0 c, - - \ ssidlen ssid (set@12) - d# 04 c, here 4 allot " mesh" rot swap move -here mesh_start_cmd - constant /mesh_start_cmd -[then] - -[ifdef] wlan-wackup \ This is test code that only works with a special debug version of the Libertas firmware -: autostart ( -- ) - h# 700000 h# 5 mesh-access! -; -[then] - \ LICENSE_BEGIN -\ Copyright (c) 2007 FirmWorks +\ Copyright (c) 2009 FirmWorks \ \ Permission is hereby granted, free of charge, to any person obtaining \ a copy of this software and associated documentation files (the
Modified: dev/usb2/device/wlan/wlan.fth =================================================================== --- dev/usb2/device/wlan/wlan.fth 2009-05-12 22:48:24 UTC (rev 1178) +++ dev/usb2/device/wlan/wlan.fth 2009-05-12 22:53:43 UTC (rev 1179) @@ -29,33 +29,24 @@ ;
: init-net ( -- ) + marvel-get-mac-address ?make-mac-address-property ;
-: load-fw ( $ -- adr len ) - over " rom:" comp if - " boot-read" evaluate \ Not a dropin - " loaded" evaluate - else - 4 - swap 4 + swap " find-drop-in" evaluate 0= if null$ then - then -; -: ?load-fw ( -- ok? ) +: ?load-fw ( -- error? ) driver-state ds-not-ready = if - wlan-fw load-fw ?dup if download-fw else drop then - driver-state ds-not-ready = if + load-all-fw if ." Failed to download firmware" cr - false exit + true exit then + ds-ready to driver-state then init-net - true + false ;
false instance value use-promiscuous?
-: end-out-ring ( -- ) " end-out-ring" $call-parent ; - external
\ Set to true to force open the driver without association. @@ -75,14 +66,13 @@
: open ( -- ok? ) my-args parse-args - device set-target + set-parent-channel opencount @ 0= if init-buf - /outbuf 4 bulk-out-pipe " begin-out-ring" $call-parent - /inbuf h# 40 bulk-in-pipe " begin-in-ring" $call-parent - ?load-fw 0= if end-bulk-in end-out-ring free-buf false exit then + /inbuf /outbuf setup-bus-io if free-buf false exit then + ?load-fw if release-bus-resources free-buf false exit then my-args " supplicant" $open-package to supplicant-ih - supplicant-ih 0= if end-bulk-in end-out-ring free-buf false exit then + supplicant-ih 0= if release-bus-resources free-buf false exit then nonce-cmd force-open? 0= if link-up? 0= if @@ -111,31 +101,32 @@ ['] 2drop to ?process-eapol stop-nic mac-off - end-bulk-in - end-out-ring - free-buf supplicant-ih ?dup if close-package 0 to supplicant-ih then + release-bus-resources then ;
\ Read and write ethernet messages regardless of the associate state. \ Used by the /supplicant support package to perform key handshaking. : write-force ( adr len -- actual ) - tuck wrap-msg ( actual adr' len' ) - " send-out" $call-parent drop ( actual ) + tuck ( actual adr len ) + wrap-msg ( actual adr' len' ) + data-out ( actual ) ; + : read-force ( adr len -- actual ) - bulk-in-ready? 0= if ( adr len ) + got-packet? 0= if ( adr len ) 2drop -2 exit then ( adr len [ error | buf actual 0 ] )
- if ( adr len ) - restart-bulk-in ( adr len ) + if \ receive error ( adr len ) + recycle-packet ( adr len ) 2drop -1 exit then ( adr len buf actual )
false to got-data? ( adr len buf actual ) process-rx ( adr len ) + recycle-packet ( adr len )
got-data? if ( adr len ) /data min tuck data -rot move ( actual ) @@ -143,7 +134,6 @@ 2drop -2 \ No data then ( actual )
- restart-bulk-in ;
\ Normal read and write methods. @@ -185,7 +175,7 @@ true to force-open? open false to force-open? - 0= if ." Can't open USB8388 wireless" cr true close exit then + 0= if ." Can't open Marvell wireless" cr true close exit then
(scan) if ." Failed to scan" true cr @@ -202,14 +192,6 @@
headers
-: init ( -- ) - init - device set-target - configuration set-config if ." Failed to set ethernet configuration" cr then -; - -init - \ LICENSE_BEGIN \ Copyright (c) 2007 FirmWorks \