aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h37
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c136
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c12
5 files changed, 38 insertions, 162 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index f8d7e88234e4..0e94d8b91956 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -278,38 +278,7 @@ enum {
278 NVM_ACCESS_TARGET_EEPROM = 2, 278 NVM_ACCESS_TARGET_EEPROM = 2,
279}; 279};
280 280
281/** 281/* Section types for NVM_ACCESS_CMD */
282 * struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM.
283 * @op_code: 0 - read, 1 - write.
284 * @target: NVM_ACCESS_TARGET_*. should be 0 for read.
285 * @cache_refresh: 0 - None, 1- NVM.
286 * @offset: offset in the nvm data.
287 * @length: of the chunk.
288 * @data: empty on read, the NVM chunk on write
289 */
290struct iwl_nvm_access_cmd_ver1 {
291 u8 op_code;
292 u8 target;
293 u8 cache_refresh;
294 u8 reserved;
295 __le16 offset;
296 __le16 length;
297 u8 data[];
298} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */
299
300/**
301 * struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD
302 * @offset: the offset in the nvm data
303 * @length: of the chunk
304 * @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write
305 */
306struct iwl_nvm_access_resp_ver1 {
307 __le16 offset;
308 __le16 length;
309 u8 data[];
310} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */
311
312/* Section types for NVM_ACCESS_CMD version 2 */
313enum { 282enum {
314 NVM_SECTION_TYPE_HW = 0, 283 NVM_SECTION_TYPE_HW = 0,
315 NVM_SECTION_TYPE_SW, 284 NVM_SECTION_TYPE_SW,
@@ -330,7 +299,7 @@ enum {
330 * @length: in bytes, to read/write 299 * @length: in bytes, to read/write
331 * @data: if write operation, the data to write. On read its empty 300 * @data: if write operation, the data to write. On read its empty
332 */ 301 */
333struct iwl_nvm_access_cmd_ver2 { 302struct iwl_nvm_access_cmd {
334 u8 op_code; 303 u8 op_code;
335 u8 target; 304 u8 target;
336 __le16 type; 305 __le16 type;
@@ -347,7 +316,7 @@ struct iwl_nvm_access_cmd_ver2 {
347 * @status: 0 for success, fail otherwise 316 * @status: 0 for success, fail otherwise
348 * @data: if read operation, the data returned. Empty on write. 317 * @data: if read operation, the data returned. Empty on write.
349 */ 318 */
350struct iwl_nvm_access_resp_ver2 { 319struct iwl_nvm_access_resp {
351 __le16 offset; 320 __le16 offset;
352 __le16 length; 321 __le16 length;
353 __le16 type; 322 __le16 type;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 1006b3204e7b..d43e2a57d354 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -330,12 +330,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
330 if (ret) 330 if (ret)
331 goto error; 331 goto error;
332 332
333 /* WkP doesn't have all calibrations, need to set default values */ 333 /* need to set default values */
334 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 334 ret = iwl_set_default_calibrations(mvm);
335 ret = iwl_set_default_calibrations(mvm); 335 if (ret)
336 if (ret) 336 goto error;
337 goto error;
338 }
339 337
340 /* 338 /*
341 * Send phy configurations command to init uCode 339 * Send phy configurations command to init uCode
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 203eb85e03d3..d022e44e83a1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -281,10 +281,7 @@ struct iwl_mvm {
281 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; 281 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
282 282
283 struct iwl_nvm_data *nvm_data; 283 struct iwl_nvm_data *nvm_data;
284 /* eeprom blob for debugfs/testmode */ 284 /* NVM sections */
285 u8 *eeprom_blob;
286 size_t eeprom_blob_size;
287 /* NVM sections for 7000 family */
288 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS]; 285 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
289 286
290 /* EEPROM MAC addresses */ 287 /* EEPROM MAC addresses */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 93e3d0f174cc..b8ec02f89acc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -77,26 +77,8 @@ static const int nvm_to_read[] = {
77/* Default NVM size to read */ 77/* Default NVM size to read */
78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); 78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
79 79
80/* used to simplify the shared operations on NCM_ACCESS_CMD versions */ 80static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd,
81union iwl_nvm_access_cmd { 81 u16 offset, u16 length, u16 section)
82 struct iwl_nvm_access_cmd_ver1 ver1;
83 struct iwl_nvm_access_cmd_ver2 ver2;
84};
85union iwl_nvm_access_resp {
86 struct iwl_nvm_access_resp_ver1 ver1;
87 struct iwl_nvm_access_resp_ver2 ver2;
88};
89
90static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd,
91 u16 offset, u16 length)
92{
93 cmd->offset = cpu_to_le16(offset);
94 cmd->length = cpu_to_le16(length);
95 cmd->cache_refresh = 1;
96}
97
98static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
99 u16 offset, u16 length, u16 section)
100{ 82{
101 cmd->offset = cpu_to_le16(offset); 83 cmd->offset = cpu_to_le16(offset);
102 cmd->length = cpu_to_le16(length); 84 cmd->length = cpu_to_le16(length);
@@ -106,8 +88,8 @@ static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
106static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, 88static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
107 u16 offset, u16 length, u8 *data) 89 u16 offset, u16 length, u8 *data)
108{ 90{
109 union iwl_nvm_access_cmd nvm_access_cmd; 91 struct iwl_nvm_access_cmd nvm_access_cmd = {};
110 union iwl_nvm_access_resp *nvm_resp; 92 struct iwl_nvm_access_resp *nvm_resp;
111 struct iwl_rx_packet *pkt; 93 struct iwl_rx_packet *pkt;
112 struct iwl_host_cmd cmd = { 94 struct iwl_host_cmd cmd = {
113 .id = NVM_ACCESS_CMD, 95 .id = NVM_ACCESS_CMD,
@@ -117,18 +99,8 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
117 int ret, bytes_read, offset_read; 99 int ret, bytes_read, offset_read;
118 u8 *resp_data; 100 u8 *resp_data;
119 101
120 memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd)); 102 iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
121 103 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
122 /* TODO: not sure family should be the decider, maybe FW version? */
123 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
124 iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2),
125 offset, length, section);
126 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2);
127 } else {
128 iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1),
129 offset, length);
130 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1);
131 }
132 104
133 ret = iwl_mvm_send_cmd(mvm, &cmd); 105 ret = iwl_mvm_send_cmd(mvm, &cmd);
134 if (ret) 106 if (ret)
@@ -144,17 +116,10 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
144 116
145 /* Extract NVM response */ 117 /* Extract NVM response */
146 nvm_resp = (void *)pkt->data; 118 nvm_resp = (void *)pkt->data;
147 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 119 ret = le16_to_cpu(nvm_resp->status);
148 ret = le16_to_cpu(nvm_resp->ver2.status); 120 bytes_read = le16_to_cpu(nvm_resp->length);
149 bytes_read = le16_to_cpu(nvm_resp->ver2.length); 121 offset_read = le16_to_cpu(nvm_resp->offset);
150 offset_read = le16_to_cpu(nvm_resp->ver2.offset); 122 resp_data = nvm_resp->data;
151 resp_data = nvm_resp->ver2.data;
152 } else {
153 ret = le16_to_cpu(nvm_resp->ver1.length) <= 0;
154 bytes_read = le16_to_cpu(nvm_resp->ver1.length);
155 offset_read = le16_to_cpu(nvm_resp->ver1.offset);
156 resp_data = nvm_resp->ver1.data;
157 }
158 if (ret) { 123 if (ret) {
159 IWL_ERR(mvm, 124 IWL_ERR(mvm,
160 "NVM access command failed with status %d (device: %s)\n", 125 "NVM access command failed with status %d (device: %s)\n",
@@ -194,17 +159,10 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
194{ 159{
195 u16 length, offset = 0; 160 u16 length, offset = 0;
196 int ret; 161 int ret;
197 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
198 162
199 /* Set nvm section read length */ 163 /* Set nvm section read length */
200 length = IWL_NVM_DEFAULT_CHUNK_SIZE; 164 length = IWL_NVM_DEFAULT_CHUNK_SIZE;
201 165
202 /*
203 * if length is greater than EEPROM size, truncate it because uCode
204 * doesn't check it by itself, and exit the loop when reached.
205 */
206 if (old_eeprom && length > mvm->cfg->base_params->eeprom_size)
207 length = mvm->cfg->base_params->eeprom_size;
208 ret = length; 166 ret = length;
209 167
210 /* Read the NVM until exhausted (reading less than requested) */ 168 /* Read the NVM until exhausted (reading less than requested) */
@@ -217,8 +175,6 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
217 return ret; 175 return ret;
218 } 176 }
219 offset += ret; 177 offset += ret;
220 if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size)
221 break;
222 } 178 }
223 179
224 IWL_INFO(mvm, "NVM section %d read completed\n", section); 180 IWL_INFO(mvm, "NVM section %d read completed\n", section);
@@ -252,63 +208,31 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
252 int ret, i, section; 208 int ret, i, section;
253 u8 *nvm_buffer, *temp; 209 u8 *nvm_buffer, *temp;
254 210
255 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 211 /* TODO: find correct NVM max size for a section */
256 /* TODO: find correct NVM max size for a section */ 212 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
257 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 213 GFP_KERNEL);
258 GFP_KERNEL); 214 if (!nvm_buffer)
259 if (!nvm_buffer) 215 return -ENOMEM;
260 return -ENOMEM; 216 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
261 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 217 section = nvm_to_read[i];
262 section = nvm_to_read[i]; 218 /* we override the constness for initial read */
263 /* we override the constness for initial read */ 219 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
264 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
265 if (ret < 0)
266 break;
267 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
268 if (!temp) {
269 ret = -ENOMEM;
270 break;
271 }
272 mvm->nvm_sections[section].data = temp;
273 mvm->nvm_sections[section].length = ret;
274 }
275 kfree(nvm_buffer);
276 if (ret < 0) 220 if (ret < 0)
277 return ret; 221 break;
278 } else { 222 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
279 /* allocate eeprom */ 223 if (!temp) {
280 mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size; 224 ret = -ENOMEM;
281 IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n", 225 break;
282 mvm->eeprom_blob_size);
283 mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL);
284 if (!mvm->eeprom_blob)
285 return -ENOMEM;
286
287 ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob);
288 if (ret != mvm->eeprom_blob_size) {
289 IWL_ERR(mvm, "Read partial NVM %d/%zd\n",
290 ret, mvm->eeprom_blob_size);
291 kfree(mvm->eeprom_blob);
292 mvm->eeprom_blob = NULL;
293 return -EINVAL;
294 } 226 }
227 mvm->nvm_sections[section].data = temp;
228 mvm->nvm_sections[section].length = ret;
295 } 229 }
230 kfree(nvm_buffer);
231 if (ret < 0)
232 return ret;
296 233
297 ret = 0; 234 ret = 0;
298 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) 235 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
299 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
300 else
301 mvm->nvm_data =
302 iwl_parse_eeprom_data(mvm->trans->dev,
303 mvm->cfg,
304 mvm->eeprom_blob,
305 mvm->eeprom_blob_size);
306
307 if (!mvm->nvm_data) {
308 kfree(mvm->eeprom_blob);
309 mvm->eeprom_blob = NULL;
310 ret = -ENOMEM;
311 }
312 236
313 return ret; 237 return ret;
314} 238}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 828bdddd07e9..b490426294cc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -319,16 +319,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
319 }; 319 };
320 int err, scan_size; 320 int err, scan_size;
321 321
322 switch (cfg->device_family) {
323 case IWL_DEVICE_FAMILY_6030:
324 case IWL_DEVICE_FAMILY_6005:
325 case IWL_DEVICE_FAMILY_7000:
326 break;
327 default:
328 IWL_ERR(trans, "Trying to load mvm on an unsupported device\n");
329 return NULL;
330 }
331
332 /******************************** 322 /********************************
333 * 1. Allocating and configuring HW data 323 * 1. Allocating and configuring HW data
334 ********************************/ 324 ********************************/
@@ -444,7 +434,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
444 out_free: 434 out_free:
445 iwl_phy_db_free(mvm->phy_db); 435 iwl_phy_db_free(mvm->phy_db);
446 kfree(mvm->scan_cmd); 436 kfree(mvm->scan_cmd);
447 kfree(mvm->eeprom_blob);
448 iwl_trans_stop_hw(trans, true); 437 iwl_trans_stop_hw(trans, true);
449 ieee80211_free_hw(mvm->hw); 438 ieee80211_free_hw(mvm->hw);
450 return NULL; 439 return NULL;
@@ -466,7 +455,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
466 iwl_phy_db_free(mvm->phy_db); 455 iwl_phy_db_free(mvm->phy_db);
467 mvm->phy_db = NULL; 456 mvm->phy_db = NULL;
468 457
469 kfree(mvm->eeprom_blob);
470 iwl_free_nvm_data(mvm->nvm_data); 458 iwl_free_nvm_data(mvm->nvm_data);
471 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++) 459 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
472 kfree(mvm->nvm_sections[i].data); 460 kfree(mvm->nvm_sections[i].data);