+static ssize_t key_tx_spec_write(struct file *file, const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_key *key = file->private_data;
+ u64 pn;
+ int ret;
+
+ switch (key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ return -EINVAL;
+ case WLAN_CIPHER_SUITE_TKIP:
+ /* not supported yet */
+ return -EOPNOTSUPP;
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ ret = kstrtou64_from_user(userbuf, count, 16, &pn);
+ if (ret)
+ return ret;
+ /* PN is a 48-bit counter */
+ if (pn >= (1ULL << 48))
+ return -ERANGE;
+ atomic64_set(&key->conf.tx_pn, pn);
+ return count;
+ default:
+ return 0;
+ }
+}
+