From owner-p4-projects@FreeBSD.ORG Tue Jul 29 16:19:35 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id ECF3B1065675; Tue, 29 Jul 2008 16:19:34 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B0F3E106564A for ; Tue, 29 Jul 2008 16:19:34 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 9D45A8FC15 for ; Tue, 29 Jul 2008 16:19:34 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m6TGJYQp041741 for ; Tue, 29 Jul 2008 16:19:34 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6TGJYed041739 for perforce@freebsd.org; Tue, 29 Jul 2008 16:19:34 GMT (envelope-from sam@freebsd.org) Date: Tue, 29 Jul 2008 16:19:34 GMT Message-Id: <200807291619.m6TGJYed041739@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 146210 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jul 2008 16:19:35 -0000 http://perforce.freebsd.org/chv.cgi?CH=146210 Change 146210 by sam@sam_ebb on 2008/07/29 16:19:17 Change callback api to allocate driver resources for a crypto key: o de-const the key parameter so drivers can muck with the flags o on callback failure don't automatically try to setup s/w crypto; instead the driver must now mark the key entry for s/w crypto and the caller will re-attach the cipher module o update drivers to match new api This change is experimental. It permits drivers more control over fallback to s/w crypto (e.g. based on a limited number of h/w key slots). Affected files ... .. //depot/projects/vap/sys/dev/ath/if_ath.c#88 edit .. //depot/projects/vap/sys/dev/mwl/if_mwl.c#12 edit .. //depot/projects/vap/sys/net80211/ieee80211_crypto.c#19 edit .. //depot/projects/vap/sys/net80211/ieee80211_var.h#48 edit Differences ... ==== //depot/projects/vap/sys/dev/ath/if_ath.c#88 (text+ko) ==== @@ -135,7 +135,7 @@ static int ath_keyset(struct ath_softc *, const struct ieee80211_key *, struct ieee80211_node *); static int ath_key_alloc(struct ieee80211vap *, - const struct ieee80211_key *, + struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); static int ath_key_delete(struct ieee80211vap *, const struct ieee80211_key *); @@ -2397,7 +2397,7 @@ * 64 entries. */ static int -ath_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k, +ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; ==== //depot/projects/vap/sys/dev/mwl/if_mwl.c#12 (text+ko) ==== @@ -117,7 +117,7 @@ static void mwl_chanswitch_proc(void *, int); static void mwl_bawatchdog_proc(void *, int); static int mwl_key_alloc(struct ieee80211vap *, - const struct ieee80211_key *, + struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); static int mwl_key_delete(struct ieee80211vap *, const struct ieee80211_key *); @@ -1884,11 +1884,11 @@ /* * Allocate a key cache slot for a unicast key. The - * firmware handles key allocation so we just return - * whatever is needed to keep the net80211 layer happy. + * firmware handles key allocation and every station is + * guaranteed key space so we are always successful. */ static int -mwl_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k, +mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; @@ -1905,8 +1905,7 @@ *keyix = *rxkeyix = k - vap->iv_nw_keys; } else { /* - * Firmware handles key allocation; just set this to - * something so the upper layers are happy. + * Firmware handles key allocation. */ *keyix = *rxkeyix = 0; } ==== //depot/projects/vap/sys/net80211/ieee80211_crypto.c#19 (text+ko) ==== @@ -59,7 +59,7 @@ * Default "null" key management routines. */ static int -null_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k, +null_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { if (!(&vap->iv_nw_keys[0] <= k && @@ -116,7 +116,7 @@ */ static __inline int dev_key_alloc(struct ieee80211vap *vap, - const struct ieee80211_key *key, + struct ieee80211_key *key, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { return vap->iv_key_alloc(vap, key, keyix, rxkeyix); @@ -335,15 +335,11 @@ * whether or not it needs to do the cipher work. */ if (key->wk_cipher != cip || key->wk_flags != flags) { -again: /* * Fillin the flags so cipher modules can see s/w * crypto requirements and potentially allocate * different state and/or attach different method * pointers. - * - * XXX this is not right when s/w crypto fallback - * fails and we try to restore previous state. */ key->wk_flags = flags; keyctx = cip->ic_attach(vap, key); @@ -375,31 +371,39 @@ if ((key->wk_flags & IEEE80211_KEY_DEVKEY) == 0) { if (!dev_key_alloc(vap, key, &keyix, &rxkeyix)) { /* - * Driver has no room; fallback to doing crypto - * in the host. We change the flags and start the - * procedure over. If we get back here then there's - * no hope and we bail. Note that this can leave - * the key in a inconsistent state if the caller - * continues to use it. + * Unable to setup driver state. */ - if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { - vap->iv_stats.is_crypto_swfallback++; - IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, - "%s: no h/w resources for cipher %s, " - "falling back to s/w\n", __func__, - cip->ic_name); - oflags = key->wk_flags; - flags |= IEEE80211_KEY_SWCRYPT; - if (cipher == IEEE80211_CIPHER_TKIP) - flags |= IEEE80211_KEY_SWMIC; - goto again; - } vap->iv_stats.is_crypto_keyfail++; IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: unable to setup cipher %s\n", __func__, cip->ic_name); return 0; } + if (key->wk_flags != flags) { + /* + * Driver overrode flags we setup; typically because + * resources were unavailable to handle _this_ key. + * Re-attach the cipher context to allow cipher + * modules to handle differing requirements. + */ + IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, + "%s: driver override for cipher %s, flags " + "0x%x -> 0x%x\n", __func__, cip->ic_name, + oflags, key->wk_flags); + keyctx = cip->ic_attach(vap, key); + if (keyctx == NULL) { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, + "%s: unable to attach cipher %s with " + "flags 0x%x\n", __func__, cip->ic_name, + key->wk_flags); + key->wk_flags = oflags; /* restore old flags */ + vap->iv_stats.is_crypto_attachfail++; + return 0; + } + cipher_detach(key); + key->wk_cipher = cip; /* XXX refcnt? */ + key->wk_private = keyctx; + } key->wk_keyix = keyix; key->wk_rxkeyix = rxkeyix; key->wk_flags |= IEEE80211_KEY_DEVKEY; ==== //depot/projects/vap/sys/net80211/ieee80211_var.h#48 (text+ko) ==== @@ -370,7 +370,7 @@ ieee80211_keyix iv_def_txkey; /* default/group tx key index */ struct ieee80211_key iv_nw_keys[IEEE80211_WEP_NKID]; int (*iv_key_alloc)(struct ieee80211vap *, - const struct ieee80211_key *, + struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); int (*iv_key_delete)(struct ieee80211vap *, const struct ieee80211_key *);