diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 254 |
1 files changed, 167 insertions, 87 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index eeefc73af7c2..504506349ac1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/interrupt.h> | 3 | #include <linux/interrupt.h> |
4 | 4 | ||
5 | #include "qlcnic.h" | 5 | #include "qlcnic.h" |
6 | #include "qlcnic_hw.h" | ||
6 | 7 | ||
7 | #include <linux/swab.h> | 8 | #include <linux/swab.h> |
8 | #include <linux/dma-mapping.h> | 9 | #include <linux/dma-mapping.h> |
@@ -13,6 +14,10 @@ | |||
13 | #include <linux/aer.h> | 14 | #include <linux/aer.h> |
14 | #include <linux/log2.h> | 15 | #include <linux/log2.h> |
15 | 16 | ||
17 | #include <linux/sysfs.h> | ||
18 | |||
19 | #define QLC_STATUS_UNSUPPORTED_CMD -2 | ||
20 | |||
16 | int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) | 21 | int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) |
17 | { | 22 | { |
18 | return -EOPNOTSUPP; | 23 | return -EOPNOTSUPP; |
@@ -40,7 +45,7 @@ static ssize_t qlcnic_store_bridged_mode(struct device *dev, | |||
40 | if (strict_strtoul(buf, 2, &new)) | 45 | if (strict_strtoul(buf, 2, &new)) |
41 | goto err_out; | 46 | goto err_out; |
42 | 47 | ||
43 | if (!adapter->nic_ops->config_bridged_mode(adapter, !!new)) | 48 | if (!qlcnic_config_bridged_mode(adapter, !!new)) |
44 | ret = len; | 49 | ret = len; |
45 | 50 | ||
46 | err_out: | 51 | err_out: |
@@ -80,9 +85,7 @@ static ssize_t qlcnic_show_diag_mode(struct device *dev, | |||
80 | struct device_attribute *attr, char *buf) | 85 | struct device_attribute *attr, char *buf) |
81 | { | 86 | { |
82 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 87 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
83 | 88 | return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED)); | |
84 | return sprintf(buf, "%d\n", | ||
85 | !!(adapter->flags & QLCNIC_DIAG_ENABLED)); | ||
86 | } | 89 | } |
87 | 90 | ||
88 | static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon, | 91 | static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon, |
@@ -111,10 +114,11 @@ static ssize_t qlcnic_store_beacon(struct device *dev, | |||
111 | const char *buf, size_t len) | 114 | const char *buf, size_t len) |
112 | { | 115 | { |
113 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 116 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
114 | int max_sds_rings = adapter->max_sds_rings; | 117 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
118 | int err, max_sds_rings = adapter->max_sds_rings; | ||
115 | u16 beacon; | 119 | u16 beacon; |
116 | u8 b_state, b_rate; | 120 | u8 b_state, b_rate; |
117 | int err; | 121 | unsigned long h_beacon; |
118 | 122 | ||
119 | if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { | 123 | if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { |
120 | dev_warn(dev, | 124 | dev_warn(dev, |
@@ -122,6 +126,41 @@ static ssize_t qlcnic_store_beacon(struct device *dev, | |||
122 | return -EOPNOTSUPP; | 126 | return -EOPNOTSUPP; |
123 | } | 127 | } |
124 | 128 | ||
129 | if (qlcnic_83xx_check(adapter) && | ||
130 | !test_bit(__QLCNIC_RESETTING, &adapter->state)) { | ||
131 | if (kstrtoul(buf, 2, &h_beacon)) | ||
132 | return -EINVAL; | ||
133 | |||
134 | if (ahw->beacon_state == h_beacon) | ||
135 | return len; | ||
136 | |||
137 | rtnl_lock(); | ||
138 | if (!ahw->beacon_state) { | ||
139 | if (test_and_set_bit(__QLCNIC_LED_ENABLE, | ||
140 | &adapter->state)) { | ||
141 | rtnl_unlock(); | ||
142 | return -EBUSY; | ||
143 | } | ||
144 | } | ||
145 | if (h_beacon) { | ||
146 | err = qlcnic_83xx_config_led(adapter, 1, h_beacon); | ||
147 | if (err) | ||
148 | goto beacon_err; | ||
149 | } else { | ||
150 | err = qlcnic_83xx_config_led(adapter, 0, !h_beacon); | ||
151 | if (err) | ||
152 | goto beacon_err; | ||
153 | } | ||
154 | /* set the current beacon state */ | ||
155 | ahw->beacon_state = h_beacon; | ||
156 | beacon_err: | ||
157 | if (!ahw->beacon_state) | ||
158 | clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); | ||
159 | |||
160 | rtnl_unlock(); | ||
161 | return len; | ||
162 | } | ||
163 | |||
125 | if (len != sizeof(u16)) | 164 | if (len != sizeof(u16)) |
126 | return QL_STATUS_INVALID_PARAM; | 165 | return QL_STATUS_INVALID_PARAM; |
127 | 166 | ||
@@ -154,11 +193,10 @@ static ssize_t qlcnic_store_beacon(struct device *dev, | |||
154 | } | 193 | } |
155 | 194 | ||
156 | err = qlcnic_config_led(adapter, b_state, b_rate); | 195 | err = qlcnic_config_led(adapter, b_state, b_rate); |
157 | 196 | if (!err) | |
158 | if (!err) { | ||
159 | err = len; | 197 | err = len; |
160 | adapter->ahw->beacon_state = b_state; | 198 | else |
161 | } | 199 | ahw->beacon_state = b_state; |
162 | 200 | ||
163 | if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) | 201 | if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) |
164 | qlcnic_diag_free_res(adapter->netdev, max_sds_rings); | 202 | qlcnic_diag_free_res(adapter->netdev, max_sds_rings); |
@@ -207,21 +245,13 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, | |||
207 | { | 245 | { |
208 | struct device *dev = container_of(kobj, struct device, kobj); | 246 | struct device *dev = container_of(kobj, struct device, kobj); |
209 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 247 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
210 | u32 data; | ||
211 | u64 qmdata; | ||
212 | int ret; | 248 | int ret; |
213 | 249 | ||
214 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | 250 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); |
215 | if (ret != 0) | 251 | if (ret != 0) |
216 | return ret; | 252 | return ret; |
253 | qlcnic_read_crb(adapter, buf, offset, size); | ||
217 | 254 | ||
218 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { | ||
219 | qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata); | ||
220 | memcpy(buf, &qmdata, size); | ||
221 | } else { | ||
222 | data = QLCRD32(adapter, offset); | ||
223 | memcpy(buf, &data, size); | ||
224 | } | ||
225 | return size; | 255 | return size; |
226 | } | 256 | } |
227 | 257 | ||
@@ -231,21 +261,13 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, | |||
231 | { | 261 | { |
232 | struct device *dev = container_of(kobj, struct device, kobj); | 262 | struct device *dev = container_of(kobj, struct device, kobj); |
233 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 263 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
234 | u32 data; | ||
235 | u64 qmdata; | ||
236 | int ret; | 264 | int ret; |
237 | 265 | ||
238 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | 266 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); |
239 | if (ret != 0) | 267 | if (ret != 0) |
240 | return ret; | 268 | return ret; |
241 | 269 | ||
242 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { | 270 | qlcnic_write_crb(adapter, buf, offset, size); |
243 | memcpy(&qmdata, buf, size); | ||
244 | qlcnic_pci_camqm_write_2M(adapter, offset, qmdata); | ||
245 | } else { | ||
246 | memcpy(&data, buf, size); | ||
247 | QLCWR32(adapter, offset, data); | ||
248 | } | ||
249 | return size; | 271 | return size; |
250 | } | 272 | } |
251 | 273 | ||
@@ -303,33 +325,44 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, | |||
303 | return size; | 325 | return size; |
304 | } | 326 | } |
305 | 327 | ||
328 | static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | ||
329 | { | ||
330 | int i; | ||
331 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { | ||
332 | if (adapter->npars[i].pci_func == pci_func) | ||
333 | return i; | ||
334 | } | ||
335 | |||
336 | return -1; | ||
337 | } | ||
338 | |||
306 | static int validate_pm_config(struct qlcnic_adapter *adapter, | 339 | static int validate_pm_config(struct qlcnic_adapter *adapter, |
307 | struct qlcnic_pm_func_cfg *pm_cfg, int count) | 340 | struct qlcnic_pm_func_cfg *pm_cfg, int count) |
308 | { | 341 | { |
309 | u8 src_pci_func, s_esw_id, d_esw_id, dest_pci_func; | 342 | u8 src_pci_func, s_esw_id, d_esw_id; |
310 | int i; | 343 | u8 dest_pci_func; |
344 | int i, src_index, dest_index; | ||
311 | 345 | ||
312 | for (i = 0; i < count; i++) { | 346 | for (i = 0; i < count; i++) { |
313 | src_pci_func = pm_cfg[i].pci_func; | 347 | src_pci_func = pm_cfg[i].pci_func; |
314 | dest_pci_func = pm_cfg[i].dest_npar; | 348 | dest_pci_func = pm_cfg[i].dest_npar; |
315 | if (src_pci_func >= QLCNIC_MAX_PCI_FUNC || | 349 | src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func); |
316 | dest_pci_func >= QLCNIC_MAX_PCI_FUNC) | ||
317 | return QL_STATUS_INVALID_PARAM; | ||
318 | 350 | ||
319 | if (adapter->npars[src_pci_func].type != QLCNIC_TYPE_NIC) | 351 | if (src_index < 0) |
320 | return QL_STATUS_INVALID_PARAM; | 352 | return QL_STATUS_INVALID_PARAM; |
321 | 353 | ||
322 | if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) | 354 | dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func); |
355 | if (dest_index < 0) | ||
323 | return QL_STATUS_INVALID_PARAM; | 356 | return QL_STATUS_INVALID_PARAM; |
324 | 357 | ||
325 | s_esw_id = adapter->npars[src_pci_func].phy_port; | 358 | s_esw_id = adapter->npars[src_index].phy_port; |
326 | d_esw_id = adapter->npars[dest_pci_func].phy_port; | 359 | d_esw_id = adapter->npars[dest_index].phy_port; |
327 | 360 | ||
328 | if (s_esw_id != d_esw_id) | 361 | if (s_esw_id != d_esw_id) |
329 | return QL_STATUS_INVALID_PARAM; | 362 | return QL_STATUS_INVALID_PARAM; |
330 | } | 363 | } |
331 | return 0; | ||
332 | 364 | ||
365 | return 0; | ||
333 | } | 366 | } |
334 | 367 | ||
335 | static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | 368 | static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, |
@@ -342,7 +375,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | |||
342 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 375 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
343 | struct qlcnic_pm_func_cfg *pm_cfg; | 376 | struct qlcnic_pm_func_cfg *pm_cfg; |
344 | u32 id, action, pci_func; | 377 | u32 id, action, pci_func; |
345 | int count, rem, i, ret; | 378 | int count, rem, i, ret, index; |
346 | 379 | ||
347 | count = size / sizeof(struct qlcnic_pm_func_cfg); | 380 | count = size / sizeof(struct qlcnic_pm_func_cfg); |
348 | rem = size % sizeof(struct qlcnic_pm_func_cfg); | 381 | rem = size % sizeof(struct qlcnic_pm_func_cfg); |
@@ -350,26 +383,32 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | |||
350 | return QL_STATUS_INVALID_PARAM; | 383 | return QL_STATUS_INVALID_PARAM; |
351 | 384 | ||
352 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; | 385 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; |
353 | |||
354 | ret = validate_pm_config(adapter, pm_cfg, count); | 386 | ret = validate_pm_config(adapter, pm_cfg, count); |
387 | |||
355 | if (ret) | 388 | if (ret) |
356 | return ret; | 389 | return ret; |
357 | for (i = 0; i < count; i++) { | 390 | for (i = 0; i < count; i++) { |
358 | pci_func = pm_cfg[i].pci_func; | 391 | pci_func = pm_cfg[i].pci_func; |
359 | action = !!pm_cfg[i].action; | 392 | action = !!pm_cfg[i].action; |
360 | id = adapter->npars[pci_func].phy_port; | 393 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
361 | ret = qlcnic_config_port_mirroring(adapter, id, action, | 394 | if (index < 0) |
362 | pci_func); | 395 | return QL_STATUS_INVALID_PARAM; |
396 | |||
397 | id = adapter->npars[index].phy_port; | ||
398 | ret = qlcnic_config_port_mirroring(adapter, id, | ||
399 | action, pci_func); | ||
363 | if (ret) | 400 | if (ret) |
364 | return ret; | 401 | return ret; |
365 | } | 402 | } |
366 | 403 | ||
367 | for (i = 0; i < count; i++) { | 404 | for (i = 0; i < count; i++) { |
368 | pci_func = pm_cfg[i].pci_func; | 405 | pci_func = pm_cfg[i].pci_func; |
369 | id = adapter->npars[pci_func].phy_port; | 406 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
370 | adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action; | 407 | id = adapter->npars[index].phy_port; |
371 | adapter->npars[pci_func].dest_npar = id; | 408 | adapter->npars[index].enable_pm = !!pm_cfg[i].action; |
409 | adapter->npars[index].dest_npar = id; | ||
372 | } | 410 | } |
411 | |||
373 | return size; | 412 | return size; |
374 | } | 413 | } |
375 | 414 | ||
@@ -383,16 +422,19 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
383 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 422 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
384 | struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; | 423 | struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; |
385 | int i; | 424 | int i; |
425 | u8 pci_func; | ||
386 | 426 | ||
387 | if (size != sizeof(pm_cfg)) | 427 | if (size != sizeof(pm_cfg)) |
388 | return QL_STATUS_INVALID_PARAM; | 428 | return QL_STATUS_INVALID_PARAM; |
389 | 429 | ||
390 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 430 | memset(&pm_cfg, 0, |
391 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | 431 | sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC); |
392 | continue; | 432 | |
393 | pm_cfg[i].action = adapter->npars[i].enable_pm; | 433 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { |
394 | pm_cfg[i].dest_npar = 0; | 434 | pci_func = adapter->npars[i].pci_func; |
395 | pm_cfg[i].pci_func = i; | 435 | pm_cfg[pci_func].action = adapter->npars[i].enable_pm; |
436 | pm_cfg[pci_func].dest_npar = 0; | ||
437 | pm_cfg[pci_func].pci_func = i; | ||
396 | } | 438 | } |
397 | memcpy(buf, &pm_cfg, size); | 439 | memcpy(buf, &pm_cfg, size); |
398 | 440 | ||
@@ -404,24 +446,33 @@ static int validate_esw_config(struct qlcnic_adapter *adapter, | |||
404 | { | 446 | { |
405 | u32 op_mode; | 447 | u32 op_mode; |
406 | u8 pci_func; | 448 | u8 pci_func; |
407 | int i; | 449 | int i, ret; |
408 | 450 | ||
409 | op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE); | 451 | if (qlcnic_82xx_check(adapter)) |
452 | op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE); | ||
453 | else | ||
454 | op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); | ||
410 | 455 | ||
411 | for (i = 0; i < count; i++) { | 456 | for (i = 0; i < count; i++) { |
412 | pci_func = esw_cfg[i].pci_func; | 457 | pci_func = esw_cfg[i].pci_func; |
413 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) | 458 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) |
414 | return QL_STATUS_INVALID_PARAM; | 459 | return QL_STATUS_INVALID_PARAM; |
415 | 460 | ||
416 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) { | 461 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) |
417 | if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) | 462 | if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0) |
418 | return QL_STATUS_INVALID_PARAM; | 463 | return QL_STATUS_INVALID_PARAM; |
419 | } | ||
420 | 464 | ||
421 | switch (esw_cfg[i].op_mode) { | 465 | switch (esw_cfg[i].op_mode) { |
422 | case QLCNIC_PORT_DEFAULTS: | 466 | case QLCNIC_PORT_DEFAULTS: |
423 | if (QLC_DEV_GET_DRV(op_mode, pci_func) != | 467 | if (qlcnic_82xx_check(adapter)) { |
424 | QLCNIC_NON_PRIV_FUNC) { | 468 | ret = QLC_DEV_GET_DRV(op_mode, pci_func); |
469 | } else { | ||
470 | ret = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode, | ||
471 | pci_func); | ||
472 | esw_cfg[i].offload_flags = 0; | ||
473 | } | ||
474 | |||
475 | if (ret != QLCNIC_NON_PRIV_FUNC) { | ||
425 | if (esw_cfg[i].mac_anti_spoof != 0) | 476 | if (esw_cfg[i].mac_anti_spoof != 0) |
426 | return QL_STATUS_INVALID_PARAM; | 477 | return QL_STATUS_INVALID_PARAM; |
427 | if (esw_cfg[i].mac_override != 1) | 478 | if (esw_cfg[i].mac_override != 1) |
@@ -444,6 +495,7 @@ static int validate_esw_config(struct qlcnic_adapter *adapter, | |||
444 | return QL_STATUS_INVALID_PARAM; | 495 | return QL_STATUS_INVALID_PARAM; |
445 | } | 496 | } |
446 | } | 497 | } |
498 | |||
447 | return 0; | 499 | return 0; |
448 | } | 500 | } |
449 | 501 | ||
@@ -458,7 +510,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
458 | struct qlcnic_esw_func_cfg *esw_cfg; | 510 | struct qlcnic_esw_func_cfg *esw_cfg; |
459 | struct qlcnic_npar_info *npar; | 511 | struct qlcnic_npar_info *npar; |
460 | int count, rem, i, ret; | 512 | int count, rem, i, ret; |
461 | u8 pci_func, op_mode = 0; | 513 | int index; |
514 | u8 op_mode = 0, pci_func; | ||
462 | 515 | ||
463 | count = size / sizeof(struct qlcnic_esw_func_cfg); | 516 | count = size / sizeof(struct qlcnic_esw_func_cfg); |
464 | rem = size % sizeof(struct qlcnic_esw_func_cfg); | 517 | rem = size % sizeof(struct qlcnic_esw_func_cfg); |
@@ -471,10 +524,9 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
471 | return ret; | 524 | return ret; |
472 | 525 | ||
473 | for (i = 0; i < count; i++) { | 526 | for (i = 0; i < count; i++) { |
474 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) { | 527 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) |
475 | if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) | 528 | if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) |
476 | return QL_STATUS_INVALID_PARAM; | 529 | return QL_STATUS_INVALID_PARAM; |
477 | } | ||
478 | 530 | ||
479 | if (adapter->ahw->pci_func != esw_cfg[i].pci_func) | 531 | if (adapter->ahw->pci_func != esw_cfg[i].pci_func) |
480 | continue; | 532 | continue; |
@@ -503,7 +555,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
503 | 555 | ||
504 | for (i = 0; i < count; i++) { | 556 | for (i = 0; i < count; i++) { |
505 | pci_func = esw_cfg[i].pci_func; | 557 | pci_func = esw_cfg[i].pci_func; |
506 | npar = &adapter->npars[pci_func]; | 558 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
559 | npar = &adapter->npars[index]; | ||
507 | switch (esw_cfg[i].op_mode) { | 560 | switch (esw_cfg[i].op_mode) { |
508 | case QLCNIC_PORT_DEFAULTS: | 561 | case QLCNIC_PORT_DEFAULTS: |
509 | npar->promisc_mode = esw_cfg[i].promisc_mode; | 562 | npar->promisc_mode = esw_cfg[i].promisc_mode; |
@@ -533,18 +586,21 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
533 | struct device *dev = container_of(kobj, struct device, kobj); | 586 | struct device *dev = container_of(kobj, struct device, kobj); |
534 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 587 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
535 | struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; | 588 | struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; |
536 | u8 i; | 589 | u8 i, pci_func; |
537 | 590 | ||
538 | if (size != sizeof(esw_cfg)) | 591 | if (size != sizeof(esw_cfg)) |
539 | return QL_STATUS_INVALID_PARAM; | 592 | return QL_STATUS_INVALID_PARAM; |
540 | 593 | ||
541 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 594 | memset(&esw_cfg, 0, |
542 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | 595 | sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC); |
543 | continue; | 596 | |
544 | esw_cfg[i].pci_func = i; | 597 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { |
545 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i])) | 598 | pci_func = adapter->npars[i].pci_func; |
599 | esw_cfg[pci_func].pci_func = pci_func; | ||
600 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) | ||
546 | return QL_STATUS_INVALID_PARAM; | 601 | return QL_STATUS_INVALID_PARAM; |
547 | } | 602 | } |
603 | |||
548 | memcpy(buf, &esw_cfg, size); | 604 | memcpy(buf, &esw_cfg, size); |
549 | 605 | ||
550 | return size; | 606 | return size; |
@@ -558,10 +614,7 @@ static int validate_npar_config(struct qlcnic_adapter *adapter, | |||
558 | 614 | ||
559 | for (i = 0; i < count; i++) { | 615 | for (i = 0; i < count; i++) { |
560 | pci_func = np_cfg[i].pci_func; | 616 | pci_func = np_cfg[i].pci_func; |
561 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) | 617 | if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0) |
562 | return QL_STATUS_INVALID_PARAM; | ||
563 | |||
564 | if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) | ||
565 | return QL_STATUS_INVALID_PARAM; | 618 | return QL_STATUS_INVALID_PARAM; |
566 | 619 | ||
567 | if (!IS_VALID_BW(np_cfg[i].min_bw) || | 620 | if (!IS_VALID_BW(np_cfg[i].min_bw) || |
@@ -581,7 +634,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
581 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 634 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
582 | struct qlcnic_info nic_info; | 635 | struct qlcnic_info nic_info; |
583 | struct qlcnic_npar_func_cfg *np_cfg; | 636 | struct qlcnic_npar_func_cfg *np_cfg; |
584 | int i, count, rem, ret; | 637 | int i, count, rem, ret, index; |
585 | u8 pci_func; | 638 | u8 pci_func; |
586 | 639 | ||
587 | count = size / sizeof(struct qlcnic_npar_func_cfg); | 640 | count = size / sizeof(struct qlcnic_npar_func_cfg); |
@@ -594,8 +647,10 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
594 | if (ret) | 647 | if (ret) |
595 | return ret; | 648 | return ret; |
596 | 649 | ||
597 | for (i = 0; i < count ; i++) { | 650 | for (i = 0; i < count; i++) { |
598 | pci_func = np_cfg[i].pci_func; | 651 | pci_func = np_cfg[i].pci_func; |
652 | |||
653 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | ||
599 | ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func); | 654 | ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func); |
600 | if (ret) | 655 | if (ret) |
601 | return ret; | 656 | return ret; |
@@ -605,12 +660,12 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
605 | ret = qlcnic_set_nic_info(adapter, &nic_info); | 660 | ret = qlcnic_set_nic_info(adapter, &nic_info); |
606 | if (ret) | 661 | if (ret) |
607 | return ret; | 662 | return ret; |
608 | adapter->npars[i].min_bw = nic_info.min_tx_bw; | 663 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
609 | adapter->npars[i].max_bw = nic_info.max_tx_bw; | 664 | adapter->npars[index].min_bw = nic_info.min_tx_bw; |
665 | adapter->npars[index].max_bw = nic_info.max_tx_bw; | ||
610 | } | 666 | } |
611 | 667 | ||
612 | return size; | 668 | return size; |
613 | |||
614 | } | 669 | } |
615 | 670 | ||
616 | static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | 671 | static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, |
@@ -628,8 +683,12 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
628 | if (size != sizeof(np_cfg)) | 683 | if (size != sizeof(np_cfg)) |
629 | return QL_STATUS_INVALID_PARAM; | 684 | return QL_STATUS_INVALID_PARAM; |
630 | 685 | ||
686 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | ||
687 | memset(&np_cfg, 0, | ||
688 | sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC); | ||
689 | |||
631 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 690 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { |
632 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | 691 | if (qlcnic_is_valid_nic_func(adapter, i) < 0) |
633 | continue; | 692 | continue; |
634 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); | 693 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); |
635 | if (ret) | 694 | if (ret) |
@@ -644,6 +703,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
644 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; | 703 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; |
645 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; | 704 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; |
646 | } | 705 | } |
706 | |||
647 | memcpy(buf, &np_cfg, size); | 707 | memcpy(buf, &np_cfg, size); |
648 | return size; | 708 | return size; |
649 | } | 709 | } |
@@ -659,6 +719,9 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, | |||
659 | struct qlcnic_esw_statistics port_stats; | 719 | struct qlcnic_esw_statistics port_stats; |
660 | int ret; | 720 | int ret; |
661 | 721 | ||
722 | if (qlcnic_83xx_check(adapter)) | ||
723 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
724 | |||
662 | if (size != sizeof(struct qlcnic_esw_statistics)) | 725 | if (size != sizeof(struct qlcnic_esw_statistics)) |
663 | return QL_STATUS_INVALID_PARAM; | 726 | return QL_STATUS_INVALID_PARAM; |
664 | 727 | ||
@@ -691,6 +754,9 @@ static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file, | |||
691 | struct qlcnic_esw_statistics esw_stats; | 754 | struct qlcnic_esw_statistics esw_stats; |
692 | int ret; | 755 | int ret; |
693 | 756 | ||
757 | if (qlcnic_83xx_check(adapter)) | ||
758 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
759 | |||
694 | if (size != sizeof(struct qlcnic_esw_statistics)) | 760 | if (size != sizeof(struct qlcnic_esw_statistics)) |
695 | return QL_STATUS_INVALID_PARAM; | 761 | return QL_STATUS_INVALID_PARAM; |
696 | 762 | ||
@@ -722,6 +788,9 @@ static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file, | |||
722 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 788 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
723 | int ret; | 789 | int ret; |
724 | 790 | ||
791 | if (qlcnic_83xx_check(adapter)) | ||
792 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
793 | |||
725 | if (offset >= QLCNIC_NIU_MAX_XG_PORTS) | 794 | if (offset >= QLCNIC_NIU_MAX_XG_PORTS) |
726 | return QL_STATUS_INVALID_PARAM; | 795 | return QL_STATUS_INVALID_PARAM; |
727 | 796 | ||
@@ -744,10 +813,14 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file, | |||
744 | char *buf, loff_t offset, | 813 | char *buf, loff_t offset, |
745 | size_t size) | 814 | size_t size) |
746 | { | 815 | { |
816 | |||
747 | struct device *dev = container_of(kobj, struct device, kobj); | 817 | struct device *dev = container_of(kobj, struct device, kobj); |
748 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 818 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
749 | int ret; | 819 | int ret; |
750 | 820 | ||
821 | if (qlcnic_83xx_check(adapter)) | ||
822 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
823 | |||
751 | if (offset >= QLCNIC_MAX_PCI_FUNC) | 824 | if (offset >= QLCNIC_MAX_PCI_FUNC) |
752 | return QL_STATUS_INVALID_PARAM; | 825 | return QL_STATUS_INVALID_PARAM; |
753 | 826 | ||
@@ -789,7 +862,10 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
789 | return ret; | 862 | return ret; |
790 | } | 863 | } |
791 | 864 | ||
792 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) { | 865 | memset(&pci_cfg, 0, |
866 | sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC); | ||
867 | |||
868 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
793 | pci_cfg[i].pci_func = pci_info[i].id; | 869 | pci_cfg[i].pci_func = pci_info[i].id; |
794 | pci_cfg[i].func_type = pci_info[i].type; | 870 | pci_cfg[i].func_type = pci_info[i].type; |
795 | pci_cfg[i].port_num = pci_info[i].default_port; | 871 | pci_cfg[i].port_num = pci_info[i].default_port; |
@@ -797,6 +873,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
797 | pci_cfg[i].max_bw = pci_info[i].tx_max_bw; | 873 | pci_cfg[i].max_bw = pci_info[i].tx_max_bw; |
798 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); | 874 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); |
799 | } | 875 | } |
876 | |||
800 | memcpy(buf, &pci_cfg, size); | 877 | memcpy(buf, &pci_cfg, size); |
801 | kfree(pci_info); | 878 | kfree(pci_info); |
802 | return size; | 879 | return size; |
@@ -897,7 +974,6 @@ void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter) | |||
897 | void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | 974 | void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) |
898 | { | 975 | { |
899 | struct device *dev = &adapter->pdev->dev; | 976 | struct device *dev = &adapter->pdev->dev; |
900 | u32 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
901 | 977 | ||
902 | if (device_create_bin_file(dev, &bin_attr_port_stats)) | 978 | if (device_create_bin_file(dev, &bin_attr_port_stats)) |
903 | dev_info(dev, "failed to create port stats sysfs entry"); | 979 | dev_info(dev, "failed to create port stats sysfs entry"); |
@@ -911,9 +987,6 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | |||
911 | if (device_create_bin_file(dev, &bin_attr_mem)) | 987 | if (device_create_bin_file(dev, &bin_attr_mem)) |
912 | dev_info(dev, "failed to create mem sysfs entry\n"); | 988 | dev_info(dev, "failed to create mem sysfs entry\n"); |
913 | 989 | ||
914 | if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD)) | ||
915 | return; | ||
916 | |||
917 | if (device_create_bin_file(dev, &bin_attr_pci_config)) | 990 | if (device_create_bin_file(dev, &bin_attr_pci_config)) |
918 | dev_info(dev, "failed to create pci config sysfs entry"); | 991 | dev_info(dev, "failed to create pci config sysfs entry"); |
919 | if (device_create_file(dev, &dev_attr_beacon)) | 992 | if (device_create_file(dev, &dev_attr_beacon)) |
@@ -936,7 +1009,6 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | |||
936 | void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) | 1009 | void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) |
937 | { | 1010 | { |
938 | struct device *dev = &adapter->pdev->dev; | 1011 | struct device *dev = &adapter->pdev->dev; |
939 | u32 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
940 | 1012 | ||
941 | device_remove_bin_file(dev, &bin_attr_port_stats); | 1013 | device_remove_bin_file(dev, &bin_attr_port_stats); |
942 | 1014 | ||
@@ -945,8 +1017,6 @@ void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) | |||
945 | device_remove_file(dev, &dev_attr_diag_mode); | 1017 | device_remove_file(dev, &dev_attr_diag_mode); |
946 | device_remove_bin_file(dev, &bin_attr_crb); | 1018 | device_remove_bin_file(dev, &bin_attr_crb); |
947 | device_remove_bin_file(dev, &bin_attr_mem); | 1019 | device_remove_bin_file(dev, &bin_attr_mem); |
948 | if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD)) | ||
949 | return; | ||
950 | device_remove_bin_file(dev, &bin_attr_pci_config); | 1020 | device_remove_bin_file(dev, &bin_attr_pci_config); |
951 | device_remove_file(dev, &dev_attr_beacon); | 1021 | device_remove_file(dev, &dev_attr_beacon); |
952 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) | 1022 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) |
@@ -968,3 +1038,13 @@ void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter) | |||
968 | { | 1038 | { |
969 | qlcnic_remove_diag_entries(adapter); | 1039 | qlcnic_remove_diag_entries(adapter); |
970 | } | 1040 | } |
1041 | |||
1042 | void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter) | ||
1043 | { | ||
1044 | qlcnic_create_diag_entries(adapter); | ||
1045 | } | ||
1046 | |||
1047 | void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter) | ||
1048 | { | ||
1049 | qlcnic_remove_diag_entries(adapter); | ||
1050 | } | ||