diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-drv.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-drv.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index ff570027e9dd..c3728163be46 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -322,6 +322,41 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces, pieces->img[type].sec[sec].offset = offset; } +static int iwl_store_cscheme(struct iwl_fw *fw, const u8 *data, const u32 len) +{ + int i, j; + struct iwl_fw_cscheme_list *l = (struct iwl_fw_cscheme_list *)data; + struct iwl_fw_cipher_scheme *fwcs; + struct ieee80211_cipher_scheme *cs; + u32 cipher; + + if (len < sizeof(*l) || + len < sizeof(l->size) + l->size * sizeof(l->cs[0])) + return -EINVAL; + + for (i = 0, j = 0; i < IWL_UCODE_MAX_CS && i < l->size; i++) { + fwcs = &l->cs[j]; + cipher = le32_to_cpu(fwcs->cipher); + + /* we skip schemes with zero cipher suite selector */ + if (!cipher) + continue; + + cs = &fw->cs[j++]; + cs->cipher = cipher; + cs->iftype = BIT(NL80211_IFTYPE_STATION); + cs->hdr_len = fwcs->hdr_len; + cs->pn_len = fwcs->pn_len; + cs->pn_off = fwcs->pn_off; + cs->key_idx_off = fwcs->key_idx_off; + cs->key_idx_mask = fwcs->key_idx_mask; + cs->key_idx_shift = fwcs->key_idx_shift; + cs->mic_len = fwcs->mic_len; + } + + return 0; +} + /* * Gets uCode section from tlv. */ @@ -729,6 +764,10 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -EINVAL; } break; + case IWL_UCODE_TLV_CSCHEME: + if (iwl_store_cscheme(&drv->fw, tlv_data, tlv_len)) + goto invalid_tlv_len; + break; default: IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); break; |