blob: e2bad8b6020cca6b8d8b1222b1198508e6bd6760 [file] [log] [blame]
Sony Chackoec079a02012-11-28 04:34:28 +00001#include <linux/slab.h>
2#include <linux/vmalloc.h>
3#include <linux/interrupt.h>
4
5#include "qlcnic.h"
6
7#include <linux/swab.h>
8#include <linux/dma-mapping.h>
9#include <net/ip.h>
10#include <linux/ipv6.h>
11#include <linux/inetdevice.h>
12#include <linux/sysfs.h>
13#include <linux/aer.h>
14#include <linux/log2.h>
15
16#include <linux/sysfs.h>
17
18int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
19{
20 return -EOPNOTSUPP;
21}
22
23int qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
24{
25 return -EOPNOTSUPP;
26}
27
28static ssize_t
29qlcnic_store_bridged_mode(struct device *dev,
30 struct device_attribute *attr, const char *buf, size_t len)
31{
32 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
33 unsigned long new;
34 int ret = -EINVAL;
35
36 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG))
37 goto err_out;
38
39 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
40 goto err_out;
41
42 if (strict_strtoul(buf, 2, &new))
43 goto err_out;
44
45 if (!adapter->nic_ops->config_bridged_mode(adapter, !!new))
46 ret = len;
47
48err_out:
49 return ret;
50}
51
52static ssize_t
53qlcnic_show_bridged_mode(struct device *dev,
54 struct device_attribute *attr, char *buf)
55{
56 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
57 int bridged_mode = 0;
58
59 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
60 bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
61
62 return sprintf(buf, "%d\n", bridged_mode);
63}
64
65static ssize_t
66qlcnic_store_diag_mode(struct device *dev,
67 struct device_attribute *attr, const char *buf, size_t len)
68{
69 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
70 unsigned long new;
71
72 if (strict_strtoul(buf, 2, &new))
73 return -EINVAL;
74
75 if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
76 adapter->flags ^= QLCNIC_DIAG_ENABLED;
77
78 return len;
79}
80
81static ssize_t
82qlcnic_show_diag_mode(struct device *dev,
83 struct device_attribute *attr, char *buf)
84{
85 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
86
87 return sprintf(buf, "%d\n",
88 !!(adapter->flags & QLCNIC_DIAG_ENABLED));
89}
90
91static int
92qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon, u8 *state,
93 u8 *rate)
94{
95 *rate = LSB(beacon);
96 *state = MSB(beacon);
97
98 QLCDB(adapter, DRV, "rate %x state %x\n", *rate, *state);
99
100 if (!*state) {
101 *rate = __QLCNIC_MAX_LED_RATE;
102 return 0;
103 } else if (*state > __QLCNIC_MAX_LED_STATE)
104 return -EINVAL;
105
106 if ((!*rate) || (*rate > __QLCNIC_MAX_LED_RATE))
107 return -EINVAL;
108
109 return 0;
110}
111
112static ssize_t
113qlcnic_store_beacon(struct device *dev,
114 struct device_attribute *attr, const char *buf, size_t len)
115{
116 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
117 int max_sds_rings = adapter->max_sds_rings;
118 u16 beacon;
119 u8 b_state, b_rate;
120 int err;
121
122 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
123 dev_warn(dev, "LED test not supported for non "
124 "privilege function\n");
125 return -EOPNOTSUPP;
126 }
127
128 if (len != sizeof(u16))
129 return QL_STATUS_INVALID_PARAM;
130
131 memcpy(&beacon, buf, sizeof(u16));
132 err = qlcnic_validate_beacon(adapter, beacon, &b_state, &b_rate);
133 if (err)
134 return err;
135
136 if (adapter->ahw->beacon_state == b_state)
137 return len;
138
139 rtnl_lock();
140
141 if (!adapter->ahw->beacon_state)
142 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
143 rtnl_unlock();
144 return -EBUSY;
145 }
146
147 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
148 err = -EIO;
149 goto out;
150 }
151
152 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
153 err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST);
154 if (err)
155 goto out;
156 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
157 }
158
159 err = qlcnic_config_led(adapter, b_state, b_rate);
160
161 if (!err) {
162 err = len;
163 adapter->ahw->beacon_state = b_state;
164 }
165
166 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
167 qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
168
169 out:
170 if (!adapter->ahw->beacon_state)
171 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
172 rtnl_unlock();
173
174 return err;
175}
176
177static ssize_t
178qlcnic_show_beacon(struct device *dev,
179 struct device_attribute *attr, char *buf)
180{
181 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
182
183 return sprintf(buf, "%d\n", adapter->ahw->beacon_state);
184}
185
186static int
187qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
188 loff_t offset, size_t size)
189{
190 size_t crb_size = 4;
191
192 if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
193 return -EIO;
194
195 if (offset < QLCNIC_PCI_CRBSPACE) {
196 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
197 QLCNIC_PCI_CAMQM_END))
198 crb_size = 8;
199 else
200 return -EINVAL;
201 }
202
203 if ((size != crb_size) || (offset & (crb_size-1)))
204 return -EINVAL;
205
206 return 0;
207}
208
209static ssize_t
210qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
211 struct bin_attribute *attr,
212 char *buf, loff_t offset, size_t size)
213{
214 struct device *dev = container_of(kobj, struct device, kobj);
215 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
216 u32 data;
217 u64 qmdata;
218 int ret;
219
220 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
221 if (ret != 0)
222 return ret;
223
224 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
225 qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata);
226 memcpy(buf, &qmdata, size);
227 } else {
228 data = QLCRD32(adapter, offset);
229 memcpy(buf, &data, size);
230 }
231 return size;
232}
233
234static ssize_t
235qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
236 struct bin_attribute *attr,
237 char *buf, loff_t offset, size_t size)
238{
239 struct device *dev = container_of(kobj, struct device, kobj);
240 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
241 u32 data;
242 u64 qmdata;
243 int ret;
244
245 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
246 if (ret != 0)
247 return ret;
248
249 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
250 memcpy(&qmdata, buf, size);
251 qlcnic_pci_camqm_write_2M(adapter, offset, qmdata);
252 } else {
253 memcpy(&data, buf, size);
254 QLCWR32(adapter, offset, data);
255 }
256 return size;
257}
258
259static int
260qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
261 loff_t offset, size_t size)
262{
263 if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
264 return -EIO;
265
266 if ((size != 8) || (offset & 0x7))
267 return -EIO;
268
269 return 0;
270}
271
272static ssize_t
273qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
274 struct bin_attribute *attr,
275 char *buf, loff_t offset, size_t size)
276{
277 struct device *dev = container_of(kobj, struct device, kobj);
278 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
279 u64 data;
280 int ret;
281
282 ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
283 if (ret != 0)
284 return ret;
285
286 if (qlcnic_pci_mem_read_2M(adapter, offset, &data))
287 return -EIO;
288
289 memcpy(buf, &data, size);
290
291 return size;
292}
293
294static ssize_t
295qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
296 struct bin_attribute *attr,
297 char *buf, loff_t offset, size_t size)
298{
299 struct device *dev = container_of(kobj, struct device, kobj);
300 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
301 u64 data;
302 int ret;
303
304 ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
305 if (ret != 0)
306 return ret;
307
308 memcpy(&data, buf, size);
309
310 if (qlcnic_pci_mem_write_2M(adapter, offset, data))
311 return -EIO;
312
313 return size;
314}
315
316static int
317validate_pm_config(struct qlcnic_adapter *adapter,
318 struct qlcnic_pm_func_cfg *pm_cfg, int count)
319{
320
321 u8 src_pci_func, s_esw_id, d_esw_id;
322 u8 dest_pci_func;
323 int i;
324
325 for (i = 0; i < count; i++) {
326 src_pci_func = pm_cfg[i].pci_func;
327 dest_pci_func = pm_cfg[i].dest_npar;
328 if (src_pci_func >= QLCNIC_MAX_PCI_FUNC
329 || dest_pci_func >= QLCNIC_MAX_PCI_FUNC)
330 return QL_STATUS_INVALID_PARAM;
331
332 if (adapter->npars[src_pci_func].type != QLCNIC_TYPE_NIC)
333 return QL_STATUS_INVALID_PARAM;
334
335 if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC)
336 return QL_STATUS_INVALID_PARAM;
337
338 s_esw_id = adapter->npars[src_pci_func].phy_port;
339 d_esw_id = adapter->npars[dest_pci_func].phy_port;
340
341 if (s_esw_id != d_esw_id)
342 return QL_STATUS_INVALID_PARAM;
343
344 }
345 return 0;
346
347}
348
349static ssize_t
350qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
351 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
352{
353 struct device *dev = container_of(kobj, struct device, kobj);
354 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
355 struct qlcnic_pm_func_cfg *pm_cfg;
356 u32 id, action, pci_func;
357 int count, rem, i, ret;
358
359 count = size / sizeof(struct qlcnic_pm_func_cfg);
360 rem = size % sizeof(struct qlcnic_pm_func_cfg);
361 if (rem)
362 return QL_STATUS_INVALID_PARAM;
363
364 pm_cfg = (struct qlcnic_pm_func_cfg *) buf;
365
366 ret = validate_pm_config(adapter, pm_cfg, count);
367 if (ret)
368 return ret;
369 for (i = 0; i < count; i++) {
370 pci_func = pm_cfg[i].pci_func;
371 action = !!pm_cfg[i].action;
372 id = adapter->npars[pci_func].phy_port;
373 ret = qlcnic_config_port_mirroring(adapter, id,
374 action, pci_func);
375 if (ret)
376 return ret;
377 }
378
379 for (i = 0; i < count; i++) {
380 pci_func = pm_cfg[i].pci_func;
381 id = adapter->npars[pci_func].phy_port;
382 adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action;
383 adapter->npars[pci_func].dest_npar = id;
384 }
385 return size;
386}
387
388static ssize_t
389qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj,
390 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
391{
392 struct device *dev = container_of(kobj, struct device, kobj);
393 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
394 struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC];
395 int i;
396
397 if (size != sizeof(pm_cfg))
398 return QL_STATUS_INVALID_PARAM;
399
400 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
401 if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
402 continue;
403 pm_cfg[i].action = adapter->npars[i].enable_pm;
404 pm_cfg[i].dest_npar = 0;
405 pm_cfg[i].pci_func = i;
406 }
407 memcpy(buf, &pm_cfg, size);
408
409 return size;
410}
411
412static int
413validate_esw_config(struct qlcnic_adapter *adapter,
414 struct qlcnic_esw_func_cfg *esw_cfg, int count)
415{
416 u32 op_mode;
417 u8 pci_func;
418 int i;
419
420 op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
421
422 for (i = 0; i < count; i++) {
423 pci_func = esw_cfg[i].pci_func;
424 if (pci_func >= QLCNIC_MAX_PCI_FUNC)
425 return QL_STATUS_INVALID_PARAM;
426
427 if (adapter->op_mode == QLCNIC_MGMT_FUNC)
428 if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
429 return QL_STATUS_INVALID_PARAM;
430
431 switch (esw_cfg[i].op_mode) {
432 case QLCNIC_PORT_DEFAULTS:
433 if (QLC_DEV_GET_DRV(op_mode, pci_func) !=
434 QLCNIC_NON_PRIV_FUNC) {
435 if (esw_cfg[i].mac_anti_spoof != 0)
436 return QL_STATUS_INVALID_PARAM;
437 if (esw_cfg[i].mac_override != 1)
438 return QL_STATUS_INVALID_PARAM;
439 if (esw_cfg[i].promisc_mode != 1)
440 return QL_STATUS_INVALID_PARAM;
441 }
442 break;
443 case QLCNIC_ADD_VLAN:
444 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
445 return QL_STATUS_INVALID_PARAM;
446 if (!esw_cfg[i].op_type)
447 return QL_STATUS_INVALID_PARAM;
448 break;
449 case QLCNIC_DEL_VLAN:
450 if (!esw_cfg[i].op_type)
451 return QL_STATUS_INVALID_PARAM;
452 break;
453 default:
454 return QL_STATUS_INVALID_PARAM;
455 }
456 }
457 return 0;
458}
459
460static ssize_t
461qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
462 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
463{
464 struct device *dev = container_of(kobj, struct device, kobj);
465 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
466 struct qlcnic_esw_func_cfg *esw_cfg;
467 struct qlcnic_npar_info *npar;
468 int count, rem, i, ret;
469 u8 pci_func, op_mode = 0;
470
471 count = size / sizeof(struct qlcnic_esw_func_cfg);
472 rem = size % sizeof(struct qlcnic_esw_func_cfg);
473 if (rem)
474 return QL_STATUS_INVALID_PARAM;
475
476 esw_cfg = (struct qlcnic_esw_func_cfg *) buf;
477 ret = validate_esw_config(adapter, esw_cfg, count);
478 if (ret)
479 return ret;
480
481 for (i = 0; i < count; i++) {
482 if (adapter->op_mode == QLCNIC_MGMT_FUNC)
483 if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
484 return QL_STATUS_INVALID_PARAM;
485
486 if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
487 continue;
488
489 op_mode = esw_cfg[i].op_mode;
490 qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
491 esw_cfg[i].op_mode = op_mode;
492 esw_cfg[i].pci_func = adapter->ahw->pci_func;
493
494 switch (esw_cfg[i].op_mode) {
495 case QLCNIC_PORT_DEFAULTS:
496 qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
497 break;
498 case QLCNIC_ADD_VLAN:
499 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
500 break;
501 case QLCNIC_DEL_VLAN:
502 esw_cfg[i].vlan_id = 0;
503 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
504 break;
505 }
506 }
507
508 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
509 goto out;
510
511 for (i = 0; i < count; i++) {
512 pci_func = esw_cfg[i].pci_func;
513 npar = &adapter->npars[pci_func];
514 switch (esw_cfg[i].op_mode) {
515 case QLCNIC_PORT_DEFAULTS:
516 npar->promisc_mode = esw_cfg[i].promisc_mode;
517 npar->mac_override = esw_cfg[i].mac_override;
518 npar->offload_flags = esw_cfg[i].offload_flags;
519 npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
520 npar->discard_tagged = esw_cfg[i].discard_tagged;
521 break;
522 case QLCNIC_ADD_VLAN:
523 npar->pvid = esw_cfg[i].vlan_id;
524 break;
525 case QLCNIC_DEL_VLAN:
526 npar->pvid = 0;
527 break;
528 }
529 }
530out:
531 return size;
532}
533
534static ssize_t
535qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
536 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
537{
538 struct device *dev = container_of(kobj, struct device, kobj);
539 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
540 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
541 u8 i;
542
543 if (size != sizeof(esw_cfg))
544 return QL_STATUS_INVALID_PARAM;
545
546 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
547 if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
548 continue;
549 esw_cfg[i].pci_func = i;
550 if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]))
551 return QL_STATUS_INVALID_PARAM;
552 }
553 memcpy(buf, &esw_cfg, size);
554
555 return size;
556}
557
558static int
559validate_npar_config(struct qlcnic_adapter *adapter,
560 struct qlcnic_npar_func_cfg *np_cfg, int count)
561{
562 u8 pci_func, i;
563
564 for (i = 0; i < count; i++) {
565 pci_func = np_cfg[i].pci_func;
566 if (pci_func >= QLCNIC_MAX_PCI_FUNC)
567 return QL_STATUS_INVALID_PARAM;
568
569 if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
570 return QL_STATUS_INVALID_PARAM;
571
572 if (!IS_VALID_BW(np_cfg[i].min_bw) ||
573 !IS_VALID_BW(np_cfg[i].max_bw))
574 return QL_STATUS_INVALID_PARAM;
575 }
576 return 0;
577}
578
579static ssize_t
580qlcnic_sysfs_write_npar_config(struct file *file, struct kobject *kobj,
581 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
582{
583 struct device *dev = container_of(kobj, struct device, kobj);
584 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
585 struct qlcnic_info nic_info;
586 struct qlcnic_npar_func_cfg *np_cfg;
587 int i, count, rem, ret;
588 u8 pci_func;
589
590 count = size / sizeof(struct qlcnic_npar_func_cfg);
591 rem = size % sizeof(struct qlcnic_npar_func_cfg);
592 if (rem)
593 return QL_STATUS_INVALID_PARAM;
594
595 np_cfg = (struct qlcnic_npar_func_cfg *) buf;
596 ret = validate_npar_config(adapter, np_cfg, count);
597 if (ret)
598 return ret;
599
600 for (i = 0; i < count ; i++) {
601 pci_func = np_cfg[i].pci_func;
602 ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
603 if (ret)
604 return ret;
605 nic_info.pci_func = pci_func;
606 nic_info.min_tx_bw = np_cfg[i].min_bw;
607 nic_info.max_tx_bw = np_cfg[i].max_bw;
608 ret = qlcnic_set_nic_info(adapter, &nic_info);
609 if (ret)
610 return ret;
611 adapter->npars[i].min_bw = nic_info.min_tx_bw;
612 adapter->npars[i].max_bw = nic_info.max_tx_bw;
613 }
614
615 return size;
616
617}
618static ssize_t
619qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj,
620 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
621{
622 struct device *dev = container_of(kobj, struct device, kobj);
623 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
624 struct qlcnic_info nic_info;
625 struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC];
626 int i, ret;
627
628 if (size != sizeof(np_cfg))
629 return QL_STATUS_INVALID_PARAM;
630
631 for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) {
632 if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
633 continue;
634 ret = qlcnic_get_nic_info(adapter, &nic_info, i);
635 if (ret)
636 return ret;
637
638 np_cfg[i].pci_func = i;
639 np_cfg[i].op_mode = (u8)nic_info.op_mode;
640 np_cfg[i].port_num = nic_info.phys_port;
641 np_cfg[i].fw_capab = nic_info.capabilities;
642 np_cfg[i].min_bw = nic_info.min_tx_bw ;
643 np_cfg[i].max_bw = nic_info.max_tx_bw;
644 np_cfg[i].max_tx_queues = nic_info.max_tx_ques;
645 np_cfg[i].max_rx_queues = nic_info.max_rx_ques;
646 }
647 memcpy(buf, &np_cfg, size);
648 return size;
649}
650
651static ssize_t
652qlcnic_sysfs_get_port_stats(struct file *file, struct kobject *kobj,
653 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
654{
655 struct device *dev = container_of(kobj, struct device, kobj);
656 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
657 struct qlcnic_esw_statistics port_stats;
658 int ret;
659
660 if (size != sizeof(struct qlcnic_esw_statistics))
661 return QL_STATUS_INVALID_PARAM;
662
663 if (offset >= QLCNIC_MAX_PCI_FUNC)
664 return QL_STATUS_INVALID_PARAM;
665
666 memset(&port_stats, 0, size);
667 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
668 &port_stats.rx);
669 if (ret)
670 return ret;
671
672 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
673 &port_stats.tx);
674 if (ret)
675 return ret;
676
677 memcpy(buf, &port_stats, size);
678 return size;
679}
680
681static ssize_t
682qlcnic_sysfs_get_esw_stats(struct file *file, struct kobject *kobj,
683 struct bin_attribute *attr, char *buf, loff_t offset, 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_esw_statistics esw_stats;
688 int ret;
689
690 if (size != sizeof(struct qlcnic_esw_statistics))
691 return QL_STATUS_INVALID_PARAM;
692
693 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
694 return QL_STATUS_INVALID_PARAM;
695
696 memset(&esw_stats, 0, size);
697 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
698 &esw_stats.rx);
699 if (ret)
700 return ret;
701
702 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
703 &esw_stats.tx);
704 if (ret)
705 return ret;
706
707 memcpy(buf, &esw_stats, size);
708 return size;
709}
710
711static ssize_t
712qlcnic_sysfs_clear_esw_stats(struct file *file, struct kobject *kobj,
713 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
714{
715 struct device *dev = container_of(kobj, struct device, kobj);
716 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
717 int ret;
718
719 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
720 return QL_STATUS_INVALID_PARAM;
721
722 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
723 QLCNIC_QUERY_RX_COUNTER);
724 if (ret)
725 return ret;
726
727 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
728 QLCNIC_QUERY_TX_COUNTER);
729 if (ret)
730 return ret;
731
732 return size;
733}
734
735static ssize_t
736qlcnic_sysfs_clear_port_stats(struct file *file, struct kobject *kobj,
737 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
738{
739
740 struct device *dev = container_of(kobj, struct device, kobj);
741 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
742 int ret;
743
744 if (offset >= QLCNIC_MAX_PCI_FUNC)
745 return QL_STATUS_INVALID_PARAM;
746
747 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
748 QLCNIC_QUERY_RX_COUNTER);
749 if (ret)
750 return ret;
751
752 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
753 QLCNIC_QUERY_TX_COUNTER);
754 if (ret)
755 return ret;
756
757 return size;
758}
759
760static ssize_t
761qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj,
762 struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
763{
764 struct device *dev = container_of(kobj, struct device, kobj);
765 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
766 struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC];
767 struct qlcnic_pci_info *pci_info;
768 int i, ret;
769
770 if (size != sizeof(pci_cfg))
771 return QL_STATUS_INVALID_PARAM;
772
773 pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
774 if (!pci_info)
775 return -ENOMEM;
776
777 ret = qlcnic_get_pci_info(adapter, pci_info);
778 if (ret) {
779 kfree(pci_info);
780 return ret;
781 }
782
783 for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) {
784 pci_cfg[i].pci_func = pci_info[i].id;
785 pci_cfg[i].func_type = pci_info[i].type;
786 pci_cfg[i].port_num = pci_info[i].default_port;
787 pci_cfg[i].min_bw = pci_info[i].tx_min_bw;
788 pci_cfg[i].max_bw = pci_info[i].tx_max_bw;
789 memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
790 }
791 memcpy(buf, &pci_cfg, size);
792 kfree(pci_info);
793 return size;
794}
795
796static struct device_attribute dev_attr_bridged_mode = {
797 .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
798 .show = qlcnic_show_bridged_mode,
799 .store = qlcnic_store_bridged_mode,
800};
801
802static struct device_attribute dev_attr_diag_mode = {
803 .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
804 .show = qlcnic_show_diag_mode,
805 .store = qlcnic_store_diag_mode,
806};
807
808static struct device_attribute dev_attr_beacon = {
809 .attr = {.name = "beacon", .mode = (S_IRUGO | S_IWUSR)},
810 .show = qlcnic_show_beacon,
811 .store = qlcnic_store_beacon,
812};
813
814static struct bin_attribute bin_attr_crb = {
815 .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
816 .size = 0,
817 .read = qlcnic_sysfs_read_crb,
818 .write = qlcnic_sysfs_write_crb,
819};
820
821static struct bin_attribute bin_attr_mem = {
822 .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
823 .size = 0,
824 .read = qlcnic_sysfs_read_mem,
825 .write = qlcnic_sysfs_write_mem,
826};
827
828static struct bin_attribute bin_attr_npar_config = {
829 .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)},
830 .size = 0,
831 .read = qlcnic_sysfs_read_npar_config,
832 .write = qlcnic_sysfs_write_npar_config,
833};
834
835static struct bin_attribute bin_attr_pci_config = {
836 .attr = {.name = "pci_config", .mode = (S_IRUGO | S_IWUSR)},
837 .size = 0,
838 .read = qlcnic_sysfs_read_pci_config,
839 .write = NULL,
840};
841
842static struct bin_attribute bin_attr_port_stats = {
843 .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
844 .size = 0,
845 .read = qlcnic_sysfs_get_port_stats,
846 .write = qlcnic_sysfs_clear_port_stats,
847};
848
849static struct bin_attribute bin_attr_esw_stats = {
850 .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
851 .size = 0,
852 .read = qlcnic_sysfs_get_esw_stats,
853 .write = qlcnic_sysfs_clear_esw_stats,
854};
855
856static struct bin_attribute bin_attr_esw_config = {
857 .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
858 .size = 0,
859 .read = qlcnic_sysfs_read_esw_config,
860 .write = qlcnic_sysfs_write_esw_config,
861};
862
863static struct bin_attribute bin_attr_pm_config = {
864 .attr = {.name = "pm_config", .mode = (S_IRUGO | S_IWUSR)},
865 .size = 0,
866 .read = qlcnic_sysfs_read_pm_config,
867 .write = qlcnic_sysfs_write_pm_config,
868};
869
870void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
871{
872 struct device *dev = &adapter->pdev->dev;
873
874 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
875 if (device_create_file(dev, &dev_attr_bridged_mode))
876 dev_warn(dev,
877 "failed to create bridged_mode sysfs entry\n");
878}
879
880void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
881{
882 struct device *dev = &adapter->pdev->dev;
883
884 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)
885 device_remove_file(dev, &dev_attr_bridged_mode);
886}
887
888void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
889{
890 struct device *dev = &adapter->pdev->dev;
891 u32 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
892
893 if (device_create_bin_file(dev, &bin_attr_port_stats))
894 dev_info(dev, "failed to create port stats sysfs entry");
895
896 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
897 return;
898 if (device_create_file(dev, &dev_attr_diag_mode))
899 dev_info(dev, "failed to create diag_mode sysfs entry\n");
900 if (device_create_bin_file(dev, &bin_attr_crb))
901 dev_info(dev, "failed to create crb sysfs entry\n");
902 if (device_create_bin_file(dev, &bin_attr_mem))
903 dev_info(dev, "failed to create mem sysfs entry\n");
904
905 if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD))
906 return;
907
908 if (device_create_bin_file(dev, &bin_attr_pci_config))
909 dev_info(dev, "failed to create pci config sysfs entry");
910 if (device_create_file(dev, &dev_attr_beacon))
911 dev_info(dev, "failed to create beacon sysfs entry");
912
913 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
914 return;
915 if (device_create_bin_file(dev, &bin_attr_esw_config))
916 dev_info(dev, "failed to create esw config sysfs entry");
917 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
918 return;
919 if (device_create_bin_file(dev, &bin_attr_npar_config))
920 dev_info(dev, "failed to create npar config sysfs entry");
921 if (device_create_bin_file(dev, &bin_attr_pm_config))
922 dev_info(dev, "failed to create pm config sysfs entry");
923 if (device_create_bin_file(dev, &bin_attr_esw_stats))
924 dev_info(dev, "failed to create eswitch stats sysfs entry");
925}
926
927void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
928{
929 struct device *dev = &adapter->pdev->dev;
930 u32 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
931
932 device_remove_bin_file(dev, &bin_attr_port_stats);
933
934 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
935 return;
936 device_remove_file(dev, &dev_attr_diag_mode);
937 device_remove_bin_file(dev, &bin_attr_crb);
938 device_remove_bin_file(dev, &bin_attr_mem);
939 if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD))
940 return;
941 device_remove_bin_file(dev, &bin_attr_pci_config);
942 device_remove_file(dev, &dev_attr_beacon);
943 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
944 return;
945 device_remove_bin_file(dev, &bin_attr_esw_config);
946 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
947 return;
948 device_remove_bin_file(dev, &bin_attr_npar_config);
949 device_remove_bin_file(dev, &bin_attr_pm_config);
950 device_remove_bin_file(dev, &bin_attr_esw_stats);
951}