1 /*
2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2013 QLogic Corporation
4 *
5 * See LICENSE.qlcnic for copyright and licensing details.
6 */
7
8 #include <linux/slab.h>
9 #include <linux/vmalloc.h>
10 #include <linux/interrupt.h>
11
12 #include "qlcnic.h"
13 #include "qlcnic_hw.h"
14
15 #include <linux/swab.h>
16 #include <linux/dma-mapping.h>
17 #include <net/ip.h>
18 #include <linux/ipv6.h>
19 #include <linux/inetdevice.h>
20 #include <linux/sysfs.h>
21 #include <linux/aer.h>
22 #include <linux/log2.h>
23
24 #define QLC_STATUS_UNSUPPORTED_CMD -2
25
qlcnicvf_config_bridged_mode(struct qlcnic_adapter * adapter,u32 enable)26 int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
27 {
28 return -EOPNOTSUPP;
29 }
30
qlcnicvf_config_led(struct qlcnic_adapter * adapter,u32 state,u32 rate)31 int qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
32 {
33 return -EOPNOTSUPP;
34 }
35
qlcnic_store_bridged_mode(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)36 static ssize_t qlcnic_store_bridged_mode(struct device *dev,
37 struct device_attribute *attr,
38 const char *buf, size_t len)
39 {
40 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
41 unsigned long new;
42 int ret = -EINVAL;
43
44 if (!(adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG))
45 goto err_out;
46
47 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
48 goto err_out;
49
50 if (strict_strtoul(buf, 2, &new))
51 goto err_out;
52
53 if (!qlcnic_config_bridged_mode(adapter, !!new))
54 ret = len;
55
56 err_out:
57 return ret;
58 }
59
qlcnic_show_bridged_mode(struct device * dev,struct device_attribute * attr,char * buf)60 static ssize_t qlcnic_show_bridged_mode(struct device *dev,
61 struct device_attribute *attr,
62 char *buf)
63 {
64 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
65 int bridged_mode = 0;
66
67 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
68 bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
69
70 return sprintf(buf, "%d\n", bridged_mode);
71 }
72
qlcnic_store_diag_mode(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)73 static ssize_t qlcnic_store_diag_mode(struct device *dev,
74 struct device_attribute *attr,
75 const char *buf, size_t len)
76 {
77 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
78 unsigned long new;
79
80 if (strict_strtoul(buf, 2, &new))
81 return -EINVAL;
82
83 if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
84 adapter->flags ^= QLCNIC_DIAG_ENABLED;
85
86 return len;
87 }
88
qlcnic_show_diag_mode(struct device * dev,struct device_attribute * attr,char * buf)89 static ssize_t qlcnic_show_diag_mode(struct device *dev,
90 struct device_attribute *attr, char *buf)
91 {
92 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
93 return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED));
94 }
95
qlcnic_validate_beacon(struct qlcnic_adapter * adapter,u16 beacon,u8 * state,u8 * rate)96 static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon,
97 u8 *state, u8 *rate)
98 {
99 *rate = LSB(beacon);
100 *state = MSB(beacon);
101
102 QLCDB(adapter, DRV, "rate %x state %x\n", *rate, *state);
103
104 if (!*state) {
105 *rate = __QLCNIC_MAX_LED_RATE;
106 return 0;
107 } else if (*state > __QLCNIC_MAX_LED_STATE) {
108 return -EINVAL;
109 }
110
111 if ((!*rate) || (*rate > __QLCNIC_MAX_LED_RATE))
112 return -EINVAL;
113
114 return 0;
115 }
116
qlcnic_store_beacon(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)117 static ssize_t qlcnic_store_beacon(struct device *dev,
118 struct device_attribute *attr,
119 const char *buf, size_t len)
120 {
121 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
122 struct qlcnic_hardware_context *ahw = adapter->ahw;
123 int err, max_sds_rings = adapter->max_sds_rings;
124 u16 beacon;
125 u8 b_state, b_rate;
126 unsigned long h_beacon;
127
128 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
129 dev_warn(dev,
130 "LED test not supported in non privileged mode\n");
131 return -EOPNOTSUPP;
132 }
133
134 if (qlcnic_83xx_check(adapter) &&
135 !test_bit(__QLCNIC_RESETTING, &adapter->state)) {
136 if (kstrtoul(buf, 2, &h_beacon))
137 return -EINVAL;
138
139 if (ahw->beacon_state == h_beacon)
140 return len;
141
142 rtnl_lock();
143 if (!ahw->beacon_state) {
144 if (test_and_set_bit(__QLCNIC_LED_ENABLE,
145 &adapter->state)) {
146 rtnl_unlock();
147 return -EBUSY;
148 }
149 }
150 if (h_beacon) {
151 err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
152 if (err)
153 goto beacon_err;
154 } else {
155 err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
156 if (err)
157 goto beacon_err;
158 }
159 /* set the current beacon state */
160 ahw->beacon_state = h_beacon;
161 beacon_err:
162 if (!ahw->beacon_state)
163 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
164
165 rtnl_unlock();
166 return len;
167 }
168
169 if (len != sizeof(u16))
170 return QL_STATUS_INVALID_PARAM;
171
172 memcpy(&beacon, buf, sizeof(u16));
173 err = qlcnic_validate_beacon(adapter, beacon, &b_state, &b_rate);
174 if (err)
175 return err;
176
177 if (adapter->ahw->beacon_state == b_state)
178 return len;
179
180 rtnl_lock();
181
182 if (!adapter->ahw->beacon_state)
183 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
184 rtnl_unlock();
185 return -EBUSY;
186 }
187
188 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
189 err = -EIO;
190 goto out;
191 }
192
193 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
194 err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST);
195 if (err)
196 goto out;
197 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
198 }
199
200 err = qlcnic_config_led(adapter, b_state, b_rate);
201 if (!err) {
202 err = len;
203 ahw->beacon_state = b_state;
204 }
205
206 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
207 qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
208
209 out:
210 if (!adapter->ahw->beacon_state)
211 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
212 rtnl_unlock();
213
214 return err;
215 }
216
qlcnic_show_beacon(struct device * dev,struct device_attribute * attr,char * buf)217 static ssize_t qlcnic_show_beacon(struct device *dev,
218 struct device_attribute *attr, char *buf)
219 {
220 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
221
222 return sprintf(buf, "%d\n", adapter->ahw->beacon_state);
223 }
224
qlcnic_sysfs_validate_crb(struct qlcnic_adapter * adapter,loff_t offset,size_t size)225 static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
226 loff_t offset, size_t size)
227 {
228 size_t crb_size = 4;
229
230 if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
231 return -EIO;
232
233 if (offset < QLCNIC_PCI_CRBSPACE) {
234 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
235 QLCNIC_PCI_CAMQM_END))
236 crb_size = 8;
237 else
238 return -EINVAL;
239 }
240
241 if ((size != crb_size) || (offset & (crb_size-1)))
242 return -EINVAL;
243
244 return 0;
245 }
246
qlcnic_sysfs_read_crb(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)247 static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
248 struct bin_attribute *attr, char *buf,
249 loff_t offset, size_t size)
250 {
251 struct device *dev = container_of(kobj, struct device, kobj);
252 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
253 int ret;
254
255 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
256 if (ret != 0)
257 return ret;
258 qlcnic_read_crb(adapter, buf, offset, size);
259
260 return size;
261 }
262
qlcnic_sysfs_write_crb(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)263 static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
264 struct bin_attribute *attr, char *buf,
265 loff_t offset, size_t size)
266 {
267 struct device *dev = container_of(kobj, struct device, kobj);
268 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
269 int ret;
270
271 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
272 if (ret != 0)
273 return ret;
274
275 qlcnic_write_crb(adapter, buf, offset, size);
276 return size;
277 }
278
qlcnic_sysfs_validate_mem(struct qlcnic_adapter * adapter,loff_t offset,size_t size)279 static int qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
280 loff_t offset, size_t size)
281 {
282 if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
283 return -EIO;
284
285 if ((size != 8) || (offset & 0x7))
286 return -EIO;
287
288 return 0;
289 }
290
qlcnic_sysfs_read_mem(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)291 static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
292 struct bin_attribute *attr, char *buf,
293 loff_t offset, size_t size)
294 {
295 struct device *dev = container_of(kobj, struct device, kobj);
296 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
297 u64 data;
298 int ret;
299
300 ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
301 if (ret != 0)
302 return ret;
303
304 if (qlcnic_pci_mem_read_2M(adapter, offset, &data))
305 return -EIO;
306
307 memcpy(buf, &data, size);
308
309 return size;
310 }
311
qlcnic_sysfs_write_mem(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)312 static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
313 struct bin_attribute *attr, char *buf,
314 loff_t offset, size_t size)
315 {
316 struct device *dev = container_of(kobj, struct device, kobj);
317 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
318 u64 data;
319 int ret;
320
321 ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
322 if (ret != 0)
323 return ret;
324
325 memcpy(&data, buf, size);
326
327 if (qlcnic_pci_mem_write_2M(adapter, offset, data))
328 return -EIO;
329
330 return size;
331 }
332
qlcnic_is_valid_nic_func(struct qlcnic_adapter * adapter,u8 pci_func)333 static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
334 {
335 int i;
336 for (i = 0; i < adapter->ahw->act_pci_func; i++) {
337 if (adapter->npars[i].pci_func == pci_func)
338 return i;
339 }
340
341 return -1;
342 }
343
validate_pm_config(struct qlcnic_adapter * adapter,struct qlcnic_pm_func_cfg * pm_cfg,int count)344 static int validate_pm_config(struct qlcnic_adapter *adapter,
345 struct qlcnic_pm_func_cfg *pm_cfg, int count)
346 {
347 u8 src_pci_func, s_esw_id, d_esw_id;
348 u8 dest_pci_func;
349 int i, src_index, dest_index;
350
351 for (i = 0; i < count; i++) {
352 src_pci_func = pm_cfg[i].pci_func;
353 dest_pci_func = pm_cfg[i].dest_npar;
354 src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func);
355
356 if (src_index < 0)
357 return QL_STATUS_INVALID_PARAM;
358
359 dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func);
360 if (dest_index < 0)
361 return QL_STATUS_INVALID_PARAM;
362
363 s_esw_id = adapter->npars[src_index].phy_port;
364 d_esw_id = adapter->npars[dest_index].phy_port;
365
366 if (s_esw_id != d_esw_id)
367 return QL_STATUS_INVALID_PARAM;
368 }
369
370 return 0;
371 }
372
qlcnic_sysfs_write_pm_config(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)373 static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
374 struct kobject *kobj,
375 struct bin_attribute *attr,
376 char *buf, loff_t offset,
377 size_t size)
378 {
379 struct device *dev = container_of(kobj, struct device, kobj);
380 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
381 struct qlcnic_pm_func_cfg *pm_cfg;
382 u32 id, action, pci_func;
383 int count, rem, i, ret, index;
384
385 count = size / sizeof(struct qlcnic_pm_func_cfg);
386 rem = size % sizeof(struct qlcnic_pm_func_cfg);
387 if (rem)
388 return QL_STATUS_INVALID_PARAM;
389
390 pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
391 ret = validate_pm_config(adapter, pm_cfg, count);
392
393 if (ret)
394 return ret;
395 for (i = 0; i < count; i++) {
396 pci_func = pm_cfg[i].pci_func;
397 action = !!pm_cfg[i].action;
398 index = qlcnic_is_valid_nic_func(adapter, pci_func);
399 if (index < 0)
400 return QL_STATUS_INVALID_PARAM;
401
402 id = adapter->npars[index].phy_port;
403 ret = qlcnic_config_port_mirroring(adapter, id,
404 action, pci_func);
405 if (ret)
406 return ret;
407 }
408
409 for (i = 0; i < count; i++) {
410 pci_func = pm_cfg[i].pci_func;
411 index = qlcnic_is_valid_nic_func(adapter, pci_func);
412 id = adapter->npars[index].phy_port;
413 adapter->npars[index].enable_pm = !!pm_cfg[i].action;
414 adapter->npars[index].dest_npar = id;
415 }
416
417 return size;
418 }
419
qlcnic_sysfs_read_pm_config(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)420 static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
421 struct kobject *kobj,
422 struct bin_attribute *attr,
423 char *buf, loff_t offset,
424 size_t size)
425 {
426 struct device *dev = container_of(kobj, struct device, kobj);
427 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
428 struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC];
429 int i;
430 u8 pci_func;
431
432 if (size != sizeof(pm_cfg))
433 return QL_STATUS_INVALID_PARAM;
434
435 memset(&pm_cfg, 0,
436 sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC);
437
438 for (i = 0; i < adapter->ahw->act_pci_func; i++) {
439 pci_func = adapter->npars[i].pci_func;
440 pm_cfg[pci_func].action = adapter->npars[i].enable_pm;
441 pm_cfg[pci_func].dest_npar = 0;
442 pm_cfg[pci_func].pci_func = i;
443 }
444 memcpy(buf, &pm_cfg, size);
445
446 return size;
447 }
448
validate_esw_config(struct qlcnic_adapter * adapter,struct qlcnic_esw_func_cfg * esw_cfg,int count)449 static int validate_esw_config(struct qlcnic_adapter *adapter,
450 struct qlcnic_esw_func_cfg *esw_cfg, int count)
451 {
452 u32 op_mode;
453 u8 pci_func;
454 int i, ret;
455
456 if (qlcnic_82xx_check(adapter))
457 op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
458 else
459 op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
460
461 for (i = 0; i < count; i++) {
462 pci_func = esw_cfg[i].pci_func;
463 if (pci_func >= QLCNIC_MAX_PCI_FUNC)
464 return QL_STATUS_INVALID_PARAM;
465
466 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
467 if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
468 return QL_STATUS_INVALID_PARAM;
469
470 switch (esw_cfg[i].op_mode) {
471 case QLCNIC_PORT_DEFAULTS:
472 if (qlcnic_82xx_check(adapter)) {
473 ret = QLC_DEV_GET_DRV(op_mode, pci_func);
474 } else {
475 ret = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
476 pci_func);
477 esw_cfg[i].offload_flags = 0;
478 }
479
480 if (ret != QLCNIC_NON_PRIV_FUNC) {
481 if (esw_cfg[i].mac_anti_spoof != 0)
482 return QL_STATUS_INVALID_PARAM;
483 if (esw_cfg[i].mac_override != 1)
484 return QL_STATUS_INVALID_PARAM;
485 if (esw_cfg[i].promisc_mode != 1)
486 return QL_STATUS_INVALID_PARAM;
487 }
488 break;
489 case QLCNIC_ADD_VLAN:
490 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
491 return QL_STATUS_INVALID_PARAM;
492 if (!esw_cfg[i].op_type)
493 return QL_STATUS_INVALID_PARAM;
494 break;
495 case QLCNIC_DEL_VLAN:
496 if (!esw_cfg[i].op_type)
497 return QL_STATUS_INVALID_PARAM;
498 break;
499 default:
500 return QL_STATUS_INVALID_PARAM;
501 }
502 }
503
504 return 0;
505 }
506
qlcnic_sysfs_write_esw_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)507 static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
508 struct kobject *kobj,
509 struct bin_attribute *attr,
510 char *buf, loff_t offset,
511 size_t size)
512 {
513 struct device *dev = container_of(kobj, struct device, kobj);
514 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
515 struct qlcnic_esw_func_cfg *esw_cfg;
516 struct qlcnic_npar_info *npar;
517 int count, rem, i, ret;
518 int index;
519 u8 op_mode = 0, pci_func;
520
521 count = size / sizeof(struct qlcnic_esw_func_cfg);
522 rem = size % sizeof(struct qlcnic_esw_func_cfg);
523 if (rem)
524 return QL_STATUS_INVALID_PARAM;
525
526 esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
527 ret = validate_esw_config(adapter, esw_cfg, count);
528 if (ret)
529 return ret;
530
531 for (i = 0; i < count; i++) {
532 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
533 if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
534 return QL_STATUS_INVALID_PARAM;
535
536 if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
537 continue;
538
539 op_mode = esw_cfg[i].op_mode;
540 qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
541 esw_cfg[i].op_mode = op_mode;
542 esw_cfg[i].pci_func = adapter->ahw->pci_func;
543
544 switch (esw_cfg[i].op_mode) {
545 case QLCNIC_PORT_DEFAULTS:
546 qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
547 rtnl_lock();
548 qlcnic_set_netdev_features(adapter, &esw_cfg[i]);
549 rtnl_unlock();
550 break;
551 case QLCNIC_ADD_VLAN:
552 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
553 break;
554 case QLCNIC_DEL_VLAN:
555 esw_cfg[i].vlan_id = 0;
556 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
557 break;
558 }
559 }
560
561 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
562 goto out;
563
564 for (i = 0; i < count; i++) {
565 pci_func = esw_cfg[i].pci_func;
566 index = qlcnic_is_valid_nic_func(adapter, pci_func);
567 npar = &adapter->npars[index];
568 switch (esw_cfg[i].op_mode) {
569 case QLCNIC_PORT_DEFAULTS:
570 npar->promisc_mode = esw_cfg[i].promisc_mode;
571 npar->mac_override = esw_cfg[i].mac_override;
572 npar->offload_flags = esw_cfg[i].offload_flags;
573 npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
574 npar->discard_tagged = esw_cfg[i].discard_tagged;
575 break;
576 case QLCNIC_ADD_VLAN:
577 npar->pvid = esw_cfg[i].vlan_id;
578 break;
579 case QLCNIC_DEL_VLAN:
580 npar->pvid = 0;
581 break;
582 }
583 }
584 out:
585 return size;
586 }
587
qlcnic_sysfs_read_esw_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)588 static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
589 struct kobject *kobj,
590 struct bin_attribute *attr,
591 char *buf, loff_t offset,
592 size_t size)
593 {
594 struct device *dev = container_of(kobj, struct device, kobj);
595 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
596 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
597 u8 i, pci_func;
598
599 if (size != sizeof(esw_cfg))
600 return QL_STATUS_INVALID_PARAM;
601
602 memset(&esw_cfg, 0,
603 sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC);
604
605 for (i = 0; i < adapter->ahw->act_pci_func; i++) {
606 pci_func = adapter->npars[i].pci_func;
607 esw_cfg[pci_func].pci_func = pci_func;
608 if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
609 return QL_STATUS_INVALID_PARAM;
610 }
611
612 memcpy(buf, &esw_cfg, size);
613
614 return size;
615 }
616
validate_npar_config(struct qlcnic_adapter * adapter,struct qlcnic_npar_func_cfg * np_cfg,int count)617 static int validate_npar_config(struct qlcnic_adapter *adapter,
618 struct qlcnic_npar_func_cfg *np_cfg,
619 int count)
620 {
621 u8 pci_func, i;
622
623 for (i = 0; i < count; i++) {
624 pci_func = np_cfg[i].pci_func;
625 if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
626 return QL_STATUS_INVALID_PARAM;
627
628 if (!IS_VALID_BW(np_cfg[i].min_bw) ||
629 !IS_VALID_BW(np_cfg[i].max_bw))
630 return QL_STATUS_INVALID_PARAM;
631 }
632 return 0;
633 }
634
qlcnic_sysfs_write_npar_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)635 static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
636 struct kobject *kobj,
637 struct bin_attribute *attr,
638 char *buf, loff_t offset,
639 size_t size)
640 {
641 struct device *dev = container_of(kobj, struct device, kobj);
642 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
643 struct qlcnic_info nic_info;
644 struct qlcnic_npar_func_cfg *np_cfg;
645 int i, count, rem, ret, index;
646 u8 pci_func;
647
648 count = size / sizeof(struct qlcnic_npar_func_cfg);
649 rem = size % sizeof(struct qlcnic_npar_func_cfg);
650 if (rem)
651 return QL_STATUS_INVALID_PARAM;
652
653 np_cfg = (struct qlcnic_npar_func_cfg *)buf;
654 ret = validate_npar_config(adapter, np_cfg, count);
655 if (ret)
656 return ret;
657
658 for (i = 0; i < count; i++) {
659 pci_func = np_cfg[i].pci_func;
660
661 memset(&nic_info, 0, sizeof(struct qlcnic_info));
662 ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
663 if (ret)
664 return ret;
665 nic_info.pci_func = pci_func;
666 nic_info.min_tx_bw = np_cfg[i].min_bw;
667 nic_info.max_tx_bw = np_cfg[i].max_bw;
668 ret = qlcnic_set_nic_info(adapter, &nic_info);
669 if (ret)
670 return ret;
671 index = qlcnic_is_valid_nic_func(adapter, pci_func);
672 adapter->npars[index].min_bw = nic_info.min_tx_bw;
673 adapter->npars[index].max_bw = nic_info.max_tx_bw;
674 }
675
676 return size;
677 }
678
qlcnic_sysfs_read_npar_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)679 static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
680 struct kobject *kobj,
681 struct bin_attribute *attr,
682 char *buf, loff_t offset,
683 size_t size)
684 {
685 struct device *dev = container_of(kobj, struct device, kobj);
686 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
687 struct qlcnic_info nic_info;
688 struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC];
689 int i, ret;
690
691 if (size != sizeof(np_cfg))
692 return QL_STATUS_INVALID_PARAM;
693
694 memset(&nic_info, 0, sizeof(struct qlcnic_info));
695 memset(&np_cfg, 0,
696 sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC);
697
698 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
699 if (qlcnic_is_valid_nic_func(adapter, i) < 0)
700 continue;
701 ret = qlcnic_get_nic_info(adapter, &nic_info, i);
702 if (ret)
703 return ret;
704
705 np_cfg[i].pci_func = i;
706 np_cfg[i].op_mode = (u8)nic_info.op_mode;
707 np_cfg[i].port_num = nic_info.phys_port;
708 np_cfg[i].fw_capab = nic_info.capabilities;
709 np_cfg[i].min_bw = nic_info.min_tx_bw;
710 np_cfg[i].max_bw = nic_info.max_tx_bw;
711 np_cfg[i].max_tx_queues = nic_info.max_tx_ques;
712 np_cfg[i].max_rx_queues = nic_info.max_rx_ques;
713 }
714
715 memcpy(buf, &np_cfg, size);
716 return size;
717 }
718
qlcnic_sysfs_get_port_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)719 static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
720 struct kobject *kobj,
721 struct bin_attribute *attr,
722 char *buf, loff_t offset,
723 size_t size)
724 {
725 struct device *dev = container_of(kobj, struct device, kobj);
726 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
727 struct qlcnic_esw_statistics port_stats;
728 int ret;
729
730 if (qlcnic_83xx_check(adapter))
731 return QLC_STATUS_UNSUPPORTED_CMD;
732
733 if (size != sizeof(struct qlcnic_esw_statistics))
734 return QL_STATUS_INVALID_PARAM;
735
736 if (offset >= QLCNIC_MAX_PCI_FUNC)
737 return QL_STATUS_INVALID_PARAM;
738
739 memset(&port_stats, 0, size);
740 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
741 &port_stats.rx);
742 if (ret)
743 return ret;
744
745 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
746 &port_stats.tx);
747 if (ret)
748 return ret;
749
750 memcpy(buf, &port_stats, size);
751 return size;
752 }
753
qlcnic_sysfs_get_esw_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)754 static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
755 struct kobject *kobj,
756 struct bin_attribute *attr,
757 char *buf, loff_t offset,
758 size_t size)
759 {
760 struct device *dev = container_of(kobj, struct device, kobj);
761 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
762 struct qlcnic_esw_statistics esw_stats;
763 int ret;
764
765 if (qlcnic_83xx_check(adapter))
766 return QLC_STATUS_UNSUPPORTED_CMD;
767
768 if (size != sizeof(struct qlcnic_esw_statistics))
769 return QL_STATUS_INVALID_PARAM;
770
771 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
772 return QL_STATUS_INVALID_PARAM;
773
774 memset(&esw_stats, 0, size);
775 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
776 &esw_stats.rx);
777 if (ret)
778 return ret;
779
780 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
781 &esw_stats.tx);
782 if (ret)
783 return ret;
784
785 memcpy(buf, &esw_stats, size);
786 return size;
787 }
788
qlcnic_sysfs_clear_esw_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)789 static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
790 struct kobject *kobj,
791 struct bin_attribute *attr,
792 char *buf, loff_t offset,
793 size_t size)
794 {
795 struct device *dev = container_of(kobj, struct device, kobj);
796 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
797 int ret;
798
799 if (qlcnic_83xx_check(adapter))
800 return QLC_STATUS_UNSUPPORTED_CMD;
801
802 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
803 return QL_STATUS_INVALID_PARAM;
804
805 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
806 QLCNIC_QUERY_RX_COUNTER);
807 if (ret)
808 return ret;
809
810 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
811 QLCNIC_QUERY_TX_COUNTER);
812 if (ret)
813 return ret;
814
815 return size;
816 }
817
qlcnic_sysfs_clear_port_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)818 static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
819 struct kobject *kobj,
820 struct bin_attribute *attr,
821 char *buf, loff_t offset,
822 size_t size)
823 {
824
825 struct device *dev = container_of(kobj, struct device, kobj);
826 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
827 int ret;
828
829 if (qlcnic_83xx_check(adapter))
830 return QLC_STATUS_UNSUPPORTED_CMD;
831
832 if (offset >= QLCNIC_MAX_PCI_FUNC)
833 return QL_STATUS_INVALID_PARAM;
834
835 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
836 QLCNIC_QUERY_RX_COUNTER);
837 if (ret)
838 return ret;
839
840 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
841 QLCNIC_QUERY_TX_COUNTER);
842 if (ret)
843 return ret;
844
845 return size;
846 }
847
qlcnic_sysfs_read_pci_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)848 static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
849 struct kobject *kobj,
850 struct bin_attribute *attr,
851 char *buf, loff_t offset,
852 size_t size)
853 {
854 struct device *dev = container_of(kobj, struct device, kobj);
855 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
856 struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC];
857 struct qlcnic_pci_info *pci_info;
858 int i, ret;
859
860 if (size != sizeof(pci_cfg))
861 return QL_STATUS_INVALID_PARAM;
862
863 pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
864 if (!pci_info)
865 return -ENOMEM;
866
867 ret = qlcnic_get_pci_info(adapter, pci_info);
868 if (ret) {
869 kfree(pci_info);
870 return ret;
871 }
872
873 memset(&pci_cfg, 0,
874 sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC);
875
876 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
877 pci_cfg[i].pci_func = pci_info[i].id;
878 pci_cfg[i].func_type = pci_info[i].type;
879 pci_cfg[i].port_num = pci_info[i].default_port;
880 pci_cfg[i].min_bw = pci_info[i].tx_min_bw;
881 pci_cfg[i].max_bw = pci_info[i].tx_max_bw;
882 memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
883 }
884
885 memcpy(buf, &pci_cfg, size);
886 kfree(pci_info);
887 return size;
888 }
889
qlcnic_83xx_sysfs_flash_read_handler(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)890 static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
891 struct kobject *kobj,
892 struct bin_attribute *attr,
893 char *buf, loff_t offset,
894 size_t size)
895 {
896 unsigned char *p_read_buf;
897 int ret, count;
898 struct device *dev = container_of(kobj, struct device, kobj);
899 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
900
901 if (!size)
902 return QL_STATUS_INVALID_PARAM;
903 if (!buf)
904 return QL_STATUS_INVALID_PARAM;
905
906 count = size / sizeof(u32);
907
908 if (size % sizeof(u32))
909 count++;
910
911 p_read_buf = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
912 if (!p_read_buf)
913 return -ENOMEM;
914 if (qlcnic_83xx_lock_flash(adapter) != 0) {
915 kfree(p_read_buf);
916 return -EIO;
917 }
918
919 ret = qlcnic_83xx_lockless_flash_read32(adapter, offset, p_read_buf,
920 count);
921
922 if (ret) {
923 qlcnic_83xx_unlock_flash(adapter);
924 kfree(p_read_buf);
925 return ret;
926 }
927
928 qlcnic_83xx_unlock_flash(adapter);
929 memcpy(buf, p_read_buf, size);
930 kfree(p_read_buf);
931
932 return size;
933 }
934
qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter * adapter,char * buf,loff_t offset,size_t size)935 static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter,
936 char *buf, loff_t offset,
937 size_t size)
938 {
939 int i, ret, count;
940 unsigned char *p_cache, *p_src;
941
942 p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
943 if (!p_cache)
944 return -ENOMEM;
945
946 memcpy(p_cache, buf, size);
947 p_src = p_cache;
948 count = size / sizeof(u32);
949
950 if (qlcnic_83xx_lock_flash(adapter) != 0) {
951 kfree(p_cache);
952 return -EIO;
953 }
954
955 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
956 ret = qlcnic_83xx_enable_flash_write(adapter);
957 if (ret) {
958 kfree(p_cache);
959 qlcnic_83xx_unlock_flash(adapter);
960 return -EIO;
961 }
962 }
963
964 for (i = 0; i < count / QLC_83XX_FLASH_WRITE_MAX; i++) {
965 ret = qlcnic_83xx_flash_bulk_write(adapter, offset,
966 (u32 *)p_src,
967 QLC_83XX_FLASH_WRITE_MAX);
968
969 if (ret) {
970 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
971 ret = qlcnic_83xx_disable_flash_write(adapter);
972 if (ret) {
973 kfree(p_cache);
974 qlcnic_83xx_unlock_flash(adapter);
975 return -EIO;
976 }
977 }
978
979 kfree(p_cache);
980 qlcnic_83xx_unlock_flash(adapter);
981 return -EIO;
982 }
983
984 p_src = p_src + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
985 offset = offset + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
986 }
987
988 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
989 ret = qlcnic_83xx_disable_flash_write(adapter);
990 if (ret) {
991 kfree(p_cache);
992 qlcnic_83xx_unlock_flash(adapter);
993 return -EIO;
994 }
995 }
996
997 kfree(p_cache);
998 qlcnic_83xx_unlock_flash(adapter);
999
1000 return 0;
1001 }
1002
qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter * adapter,char * buf,loff_t offset,size_t size)1003 static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter,
1004 char *buf, loff_t offset, size_t size)
1005 {
1006 int i, ret, count;
1007 unsigned char *p_cache, *p_src;
1008
1009 p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
1010 if (!p_cache)
1011 return -ENOMEM;
1012
1013 memcpy(p_cache, buf, size);
1014 p_src = p_cache;
1015 count = size / sizeof(u32);
1016
1017 if (qlcnic_83xx_lock_flash(adapter) != 0) {
1018 kfree(p_cache);
1019 return -EIO;
1020 }
1021
1022 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1023 ret = qlcnic_83xx_enable_flash_write(adapter);
1024 if (ret) {
1025 kfree(p_cache);
1026 qlcnic_83xx_unlock_flash(adapter);
1027 return -EIO;
1028 }
1029 }
1030
1031 for (i = 0; i < count; i++) {
1032 ret = qlcnic_83xx_flash_write32(adapter, offset, (u32 *)p_src);
1033 if (ret) {
1034 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1035 ret = qlcnic_83xx_disable_flash_write(adapter);
1036 if (ret) {
1037 kfree(p_cache);
1038 qlcnic_83xx_unlock_flash(adapter);
1039 return -EIO;
1040 }
1041 }
1042 kfree(p_cache);
1043 qlcnic_83xx_unlock_flash(adapter);
1044 return -EIO;
1045 }
1046
1047 p_src = p_src + sizeof(u32);
1048 offset = offset + sizeof(u32);
1049 }
1050
1051 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1052 ret = qlcnic_83xx_disable_flash_write(adapter);
1053 if (ret) {
1054 kfree(p_cache);
1055 qlcnic_83xx_unlock_flash(adapter);
1056 return -EIO;
1057 }
1058 }
1059
1060 kfree(p_cache);
1061 qlcnic_83xx_unlock_flash(adapter);
1062
1063 return 0;
1064 }
1065
qlcnic_83xx_sysfs_flash_write_handler(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)1066 static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
1067 struct kobject *kobj,
1068 struct bin_attribute *attr,
1069 char *buf, loff_t offset,
1070 size_t size)
1071 {
1072 int ret;
1073 static int flash_mode;
1074 unsigned long data;
1075 struct device *dev = container_of(kobj, struct device, kobj);
1076 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
1077
1078 if (!buf)
1079 return QL_STATUS_INVALID_PARAM;
1080
1081 ret = kstrtoul(buf, 16, &data);
1082
1083 switch (data) {
1084 case QLC_83XX_FLASH_SECTOR_ERASE_CMD:
1085 flash_mode = QLC_83XX_ERASE_MODE;
1086 ret = qlcnic_83xx_erase_flash_sector(adapter, offset);
1087 if (ret) {
1088 dev_err(&adapter->pdev->dev,
1089 "%s failed at %d\n", __func__, __LINE__);
1090 return -EIO;
1091 }
1092 break;
1093
1094 case QLC_83XX_FLASH_BULK_WRITE_CMD:
1095 flash_mode = QLC_83XX_BULK_WRITE_MODE;
1096 break;
1097
1098 case QLC_83XX_FLASH_WRITE_CMD:
1099 flash_mode = QLC_83XX_WRITE_MODE;
1100 break;
1101 default:
1102 if (flash_mode == QLC_83XX_BULK_WRITE_MODE) {
1103 ret = qlcnic_83xx_sysfs_flash_bulk_write(adapter, buf,
1104 offset, size);
1105 if (ret) {
1106 dev_err(&adapter->pdev->dev,
1107 "%s failed at %d\n",
1108 __func__, __LINE__);
1109 return -EIO;
1110 }
1111 }
1112
1113 if (flash_mode == QLC_83XX_WRITE_MODE) {
1114 ret = qlcnic_83xx_sysfs_flash_write(adapter, buf,
1115 offset, size);
1116 if (ret) {
1117 dev_err(&adapter->pdev->dev,
1118 "%s failed at %d\n", __func__,
1119 __LINE__);
1120 return -EIO;
1121 }
1122 }
1123 }
1124
1125 return size;
1126 }
1127
1128 static struct device_attribute dev_attr_bridged_mode = {
1129 .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
1130 .show = qlcnic_show_bridged_mode,
1131 .store = qlcnic_store_bridged_mode,
1132 };
1133
1134 static struct device_attribute dev_attr_diag_mode = {
1135 .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
1136 .show = qlcnic_show_diag_mode,
1137 .store = qlcnic_store_diag_mode,
1138 };
1139
1140 static struct device_attribute dev_attr_beacon = {
1141 .attr = {.name = "beacon", .mode = (S_IRUGO | S_IWUSR)},
1142 .show = qlcnic_show_beacon,
1143 .store = qlcnic_store_beacon,
1144 };
1145
1146 static struct bin_attribute bin_attr_crb = {
1147 .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
1148 .size = 0,
1149 .read = qlcnic_sysfs_read_crb,
1150 .write = qlcnic_sysfs_write_crb,
1151 };
1152
1153 static struct bin_attribute bin_attr_mem = {
1154 .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
1155 .size = 0,
1156 .read = qlcnic_sysfs_read_mem,
1157 .write = qlcnic_sysfs_write_mem,
1158 };
1159
1160 static struct bin_attribute bin_attr_npar_config = {
1161 .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)},
1162 .size = 0,
1163 .read = qlcnic_sysfs_read_npar_config,
1164 .write = qlcnic_sysfs_write_npar_config,
1165 };
1166
1167 static struct bin_attribute bin_attr_pci_config = {
1168 .attr = {.name = "pci_config", .mode = (S_IRUGO | S_IWUSR)},
1169 .size = 0,
1170 .read = qlcnic_sysfs_read_pci_config,
1171 .write = NULL,
1172 };
1173
1174 static struct bin_attribute bin_attr_port_stats = {
1175 .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
1176 .size = 0,
1177 .read = qlcnic_sysfs_get_port_stats,
1178 .write = qlcnic_sysfs_clear_port_stats,
1179 };
1180
1181 static struct bin_attribute bin_attr_esw_stats = {
1182 .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
1183 .size = 0,
1184 .read = qlcnic_sysfs_get_esw_stats,
1185 .write = qlcnic_sysfs_clear_esw_stats,
1186 };
1187
1188 static struct bin_attribute bin_attr_esw_config = {
1189 .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
1190 .size = 0,
1191 .read = qlcnic_sysfs_read_esw_config,
1192 .write = qlcnic_sysfs_write_esw_config,
1193 };
1194
1195 static struct bin_attribute bin_attr_pm_config = {
1196 .attr = {.name = "pm_config", .mode = (S_IRUGO | S_IWUSR)},
1197 .size = 0,
1198 .read = qlcnic_sysfs_read_pm_config,
1199 .write = qlcnic_sysfs_write_pm_config,
1200 };
1201
1202 static struct bin_attribute bin_attr_flash = {
1203 .attr = {.name = "flash", .mode = (S_IRUGO | S_IWUSR)},
1204 .size = 0,
1205 .read = qlcnic_83xx_sysfs_flash_read_handler,
1206 .write = qlcnic_83xx_sysfs_flash_write_handler,
1207 };
1208
qlcnic_create_sysfs_entries(struct qlcnic_adapter * adapter)1209 void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
1210 {
1211 struct device *dev = &adapter->pdev->dev;
1212
1213 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
1214 if (device_create_file(dev, &dev_attr_bridged_mode))
1215 dev_warn(dev,
1216 "failed to create bridged_mode sysfs entry\n");
1217 }
1218
qlcnic_remove_sysfs_entries(struct qlcnic_adapter * adapter)1219 void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
1220 {
1221 struct device *dev = &adapter->pdev->dev;
1222
1223 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
1224 device_remove_file(dev, &dev_attr_bridged_mode);
1225 }
1226
qlcnic_create_diag_entries(struct qlcnic_adapter * adapter)1227 void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
1228 {
1229 struct device *dev = &adapter->pdev->dev;
1230
1231 if (device_create_bin_file(dev, &bin_attr_port_stats))
1232 dev_info(dev, "failed to create port stats sysfs entry");
1233
1234 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
1235 return;
1236 if (device_create_file(dev, &dev_attr_diag_mode))
1237 dev_info(dev, "failed to create diag_mode sysfs entry\n");
1238 if (device_create_bin_file(dev, &bin_attr_crb))
1239 dev_info(dev, "failed to create crb sysfs entry\n");
1240 if (device_create_bin_file(dev, &bin_attr_mem))
1241 dev_info(dev, "failed to create mem sysfs entry\n");
1242
1243 if (device_create_bin_file(dev, &bin_attr_pci_config))
1244 dev_info(dev, "failed to create pci config sysfs entry");
1245 if (device_create_file(dev, &dev_attr_beacon))
1246 dev_info(dev, "failed to create beacon sysfs entry");
1247
1248 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1249 return;
1250 if (device_create_bin_file(dev, &bin_attr_esw_config))
1251 dev_info(dev, "failed to create esw config sysfs entry");
1252 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
1253 return;
1254 if (device_create_bin_file(dev, &bin_attr_npar_config))
1255 dev_info(dev, "failed to create npar config sysfs entry");
1256 if (device_create_bin_file(dev, &bin_attr_pm_config))
1257 dev_info(dev, "failed to create pm config sysfs entry");
1258 if (device_create_bin_file(dev, &bin_attr_esw_stats))
1259 dev_info(dev, "failed to create eswitch stats sysfs entry");
1260 }
1261
qlcnic_remove_diag_entries(struct qlcnic_adapter * adapter)1262 void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
1263 {
1264 struct device *dev = &adapter->pdev->dev;
1265
1266 device_remove_bin_file(dev, &bin_attr_port_stats);
1267
1268 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
1269 return;
1270 device_remove_file(dev, &dev_attr_diag_mode);
1271 device_remove_bin_file(dev, &bin_attr_crb);
1272 device_remove_bin_file(dev, &bin_attr_mem);
1273 device_remove_bin_file(dev, &bin_attr_pci_config);
1274 device_remove_file(dev, &dev_attr_beacon);
1275 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1276 return;
1277 device_remove_bin_file(dev, &bin_attr_esw_config);
1278 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
1279 return;
1280 device_remove_bin_file(dev, &bin_attr_npar_config);
1281 device_remove_bin_file(dev, &bin_attr_pm_config);
1282 device_remove_bin_file(dev, &bin_attr_esw_stats);
1283 }
1284
qlcnic_82xx_add_sysfs(struct qlcnic_adapter * adapter)1285 void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter)
1286 {
1287 qlcnic_create_diag_entries(adapter);
1288 }
1289
qlcnic_82xx_remove_sysfs(struct qlcnic_adapter * adapter)1290 void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
1291 {
1292 qlcnic_remove_diag_entries(adapter);
1293 }
1294
qlcnic_83xx_add_sysfs(struct qlcnic_adapter * adapter)1295 void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
1296 {
1297 struct device *dev = &adapter->pdev->dev;
1298
1299 qlcnic_create_diag_entries(adapter);
1300
1301 if (sysfs_create_bin_file(&dev->kobj, &bin_attr_flash))
1302 dev_info(dev, "failed to create flash sysfs entry\n");
1303 }
1304
qlcnic_83xx_remove_sysfs(struct qlcnic_adapter * adapter)1305 void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
1306 {
1307 struct device *dev = &adapter->pdev->dev;
1308
1309 qlcnic_remove_diag_entries(adapter);
1310 sysfs_remove_bin_file(&dev->kobj, &bin_attr_flash);
1311 }
1312