Changeset 1755

Show
Ignore:
Timestamp:
10/18/06 13:38:57 (2 years ago)
Author:
kelmo
Message:

Implement the ath_hal_*tkipsplit feature required to take advantage of the HAL
version 0.9.18.0 "keycaching" ability. Ported from FreeBSD ath. Closes #925

Signed-off-by: Bell Kin <bell_kin@pek.com.tw>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ath/if_ath.c

    r1754 r1755  
    347347#define KEYPRINTF(sc, ix, hk, mac) do {                         \ 
    348348        if (sc->sc_debug & ATH_DEBUG_KEYCACHE)                  \ 
    349                 ath_keyprint(__func__, ix, hk, mac);          \ 
     349                ath_keyprint(sc, __func__, ix, hk, mac);      \ 
    350350} while (0) 
    351351#else /* defined(AR_DEBUG) */ 
     
    472472        for (i = 0; i < sc->sc_keymax; i++) 
    473473                ath_hal_keyreset(ah, i); 
    474         /* 
    475          * Mark key cache slots associated with global keys 
    476          * as in use.  If we knew TKIP was not to be used we 
    477          * could leave the +32, +64, and +32+64 slots free. 
    478          * XXX only for splitmic. 
    479          */ 
    480         for (i = 0; i < IEEE80211_WEP_NKID; i++) { 
    481                 setbit(sc->sc_keymap, i); 
    482                 setbit(sc->sc_keymap, i+32); 
    483                 setbit(sc->sc_keymap, i+64); 
    484                 setbit(sc->sc_keymap, i+32+64); 
    485         } 
    486474 
    487475        /* 
     
    764752                                ic->ic_caps |= IEEE80211_C_WME_TKIPMIC; 
    765753                } 
    766   
    767                 if (ath_hal_tkipsplit(ah)) 
     754 
     755                /* 
     756                 * If the h/w supports storing tx+rx MIC keys 
     757                 * in one cache slot automatically enable use. 
     758                 */ 
     759                if (ath_hal_hastkipsplit(ah) || 
     760                    !ath_hal_settkipsplit(ah, AH_FALSE)) 
    768761                        sc->sc_splitmic = 1; 
    769762        } 
     
    772765        sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah); 
    773766#endif 
     767        /* 
     768         * Mark key cache slots associated with global keys 
     769         * as in use.  If we knew TKIP was not to be used we 
     770         * could leave the +32, +64, and +32+64 slots free. 
     771         */ 
     772        for (i = 0; i < IEEE80211_WEP_NKID; i++) { 
     773                setbit(sc->sc_keymap, i); 
     774                setbit(sc->sc_keymap, i+64); 
     775                if (sc->sc_splitmic) { 
     776                        setbit(sc->sc_keymap, i+32); 
     777                        setbit(sc->sc_keymap, i+32+64); 
     778                } 
     779        } 
    774780        /* 
    775781         * TPC support can be done either with a global cap or 
     
    28612867#ifdef AR_DEBUG 
    28622868static void 
    2863 ath_keyprint(const char *tag, u_int ix, 
     2869ath_keyprint(struct ath_softc *sc, const char *tag, u_int ix, 
    28642870        const HAL_KEYVAL *hk, const u_int8_t mac[IEEE80211_ADDR_LEN]) 
    28652871{ 
     
    28792885        printk(" mac %s", ether_sprintf(mac)); 
    28802886        if (hk->kv_type == HAL_CIPHER_TKIP) { 
    2881                 printk(" mic "); 
     2887                printk(" %s ", sc->sc_splitmic ? "mic" : "rxmic"); 
    28822888                for (i = 0; i < sizeof(hk->kv_mic); i++) 
    28832889                        printk("%02x", hk->kv_mic[i]); 
     2890#if HAL_ABI_VERSION > 0x06052200 
     2891                if (!sc->sc_splitmic) { 
     2892                        printk(" txmic "); 
     2893                        for (i = 0; i < sizeof(hk->kv_txmic); i++) 
     2894                                printk("%02x", hk->kv_txmic[i]); 
     2895                } 
     2896#endif 
    28842897        } 
    28852898        printk("\n"); 
     
    29022915        KASSERT(k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP, 
    29032916                ("got a non-TKIP key, cipher %u", k->wk_cipher->ic_cipher)); 
    2904         KASSERT(sc->sc_splitmic, ("key cache !split")); 
    29052917        if ((k->wk_flags & IEEE80211_KEY_XR) == IEEE80211_KEY_XR) { 
    2906                 /* 
    2907                  * TX key goes at first index, RX key at +32. 
    2908                  * The hal handles the MIC keys at index+64. 
    2909                  */ 
    2910                 memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_mic)); 
    2911                 KEYPRINTF(sc, k->wk_keyix, hk, zerobssid); 
    2912                 if (!ath_hal_keyset(ah, k->wk_keyix, hk, zerobssid)) 
    2913                         return 0; 
    2914  
    2915                 memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); 
    2916                 KEYPRINTF(sc, k->wk_keyix + 32, hk, mac); 
    2917                 /* XXX delete tx key on failure? */ 
    2918                 return ath_hal_keyset(ah, k->wk_keyix + 32, hk, mac); 
     2918                if (sc->sc_splitmic) { 
     2919                        /* 
     2920                         * TX key goes at first index, RX key at the rx index. 
     2921                         * The hal handles the MIC keys at index+64. 
     2922                         */ 
     2923                        memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_mic)); 
     2924                        KEYPRINTF(sc, k->wk_keyix, hk, zerobssid); 
     2925                        if (!ath_hal_keyset(ah, k->wk_keyix, hk, zerobssid)) 
     2926                                return 0; 
     2927 
     2928                        memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); 
     2929                        KEYPRINTF(sc, k->wk_keyix+32, hk, mac); 
     2930                        /* XXX delete tx key on failure? */ 
     2931                        return ath_hal_keyset(ah, k->wk_keyix+32, hk, mac); 
     2932                } else { 
     2933                        /* 
     2934                         * Room for both TX+RX MIC keys in one key cache 
     2935                         * slot, just set key at the first index; the hal 
     2936                         * will handle the reset. 
     2937                         */ 
     2938                        memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); 
     2939#if HAL_ABI_VERSION > 0x06052200 
     2940                        memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic)); 
     2941#endif 
     2942                        KEYPRINTF(sc, k->wk_keyix, hk, mac); 
     2943                        return ath_hal_keyset(ah, k->wk_keyix, hk, mac); 
     2944                } 
    29192945        } else if (k->wk_flags & IEEE80211_KEY_XR) { 
    29202946                /* 
     
    29853011 
    29863012        if (hk.kv_type == HAL_CIPHER_TKIP && 
    2987             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && 
    2988             sc->sc_splitmic) { 
     3013            (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { 
    29893014                return ath_keyset_tkip(sc, k, &hk, mac); 
    29903015        } else { 
     
    30483073 
    30493074/* 
     3075 * Allocate tx/rx key slots for TKIP.  We allocate two slots for 
     3076 * each key, one for decrypt/encrypt and the other for the MIC. 
     3077 */ 
     3078static u_int16_t 
     3079key_alloc_pair(struct ath_softc *sc) 
     3080{ 
     3081#define N(a)    (sizeof(a)/sizeof(a[0])) 
     3082        u_int i, keyix; 
     3083 
     3084        KASSERT(!sc->sc_splitmic, ("key cache split")); 
     3085        /* XXX could optimize */ 
     3086        for (i = 0; i < N(sc->sc_keymap)/4; i++) { 
     3087                u_int8_t b = sc->sc_keymap[i]; 
     3088                if (b != 0xff) { 
     3089                        /* 
     3090                         * One or more slots in this byte are free. 
     3091                         */ 
     3092                        keyix = i*NBBY; 
     3093                        while (b & 1) { 
     3094                again: 
     3095                                keyix++; 
     3096                                b >>= 1; 
     3097                        } 
     3098                        if (isset(sc->sc_keymap, keyix+64)) { 
     3099                                /* full pair unavailable */ 
     3100                                /* XXX statistic */ 
     3101                                if (keyix == (i+1)*NBBY) { 
     3102                                        /* no slots were appropriate, advance */ 
     3103                                        continue; 
     3104                                } 
     3105                                goto again; 
     3106                        } 
     3107                        setbit(sc->sc_keymap, keyix); 
     3108                        setbit(sc->sc_keymap, keyix+64); 
     3109                        DPRINTF(sc, ATH_DEBUG_KEYCACHE, 
     3110                                "%s: key pair %u,%u\n", 
     3111                                __func__, keyix, keyix+64); 
     3112                        return keyix; 
     3113                } 
     3114        } 
     3115        DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of pair space\n", __func__); 
     3116        return IEEE80211_KEYIX_NONE; 
     3117#undef N 
     3118} 
     3119 
     3120/* 
    30503121 * Allocate a single key cache slot. 
    30513122 */ 
     
    31343205                return key_alloc_single(sc); 
    31353206        else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP && 
    3136             (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic) { 
    3137                 return key_alloc_2pair(sc); 
     3207                (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { 
     3208                if (sc->sc_splitmic) 
     3209                        return key_alloc_2pair(sc); 
     3210                else 
     3211                        return key_alloc_pair(sc); 
    31383212        } else 
    31393213                return key_alloc_single(sc); 
     
    32003274                clrbit(sc->sc_keymap, keyix); 
    32013275                if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && 
    3202                     (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && 
    3203                     sc->sc_splitmic) { 
     3276                    (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { 
    32043277                        clrbit(sc->sc_keymap, keyix + 64);      /* TX key MIC */ 
    3205                         clrbit(sc->sc_keymap, keyix + 32);      /* RX key */ 
    3206                         clrbit(sc->sc_keymap, keyix + 32 + 64); /* RX key MIC */ 
     3278                        if (sc->sc_splitmic) { 
     3279                                /* +32 for RX key, +32+64 for RX key MIC */ 
     3280                                clrbit(sc->sc_keymap, keyix+32); 
     3281                                clrbit(sc->sc_keymap, keyix+32+64); 
     3282                        } 
    32073283                } 
    32083284 
  • trunk/ath/if_athvar.h

    r1753 r1755  
    895895#define ath_hal_getcountrycode(_ah, _pcc) \ 
    896896        (*(_pcc) = (_ah)->ah_countryCode) 
    897 #define        ath_hal_tkipsplit(_ah) \ 
     897#define ath_hal_hastkipsplit(_ah) \ 
    898898        (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 0, NULL) == HAL_OK) 
     899#define ath_hal_gettkipsplit(_ah) \ 
     900        (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, NULL) == HAL_OK) 
     901#define ath_hal_settkipsplit(_ah, _v) \ 
     902        ath_hal_setcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, _v, NULL) 
    899903#define ath_hal_wmetkipmic(_ah) \ 
    900904        (ath_hal_getcapability(_ah, HAL_CAP_WME_TKIPMIC, 0, NULL) == HAL_OK)