]> Pileus Git - ~andy/linux/blob - drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
qlcnic: create file qlcnic_sysfs.c for sysfs routines
[~andy/linux] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_sysfs.c
1 #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
18 int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
19 {
20         return -EOPNOTSUPP;
21 }
22
23 int qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
24 {
25         return -EOPNOTSUPP;
26 }
27
28 static ssize_t
29 qlcnic_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
48 err_out:
49         return ret;
50 }
51
52 static ssize_t
53 qlcnic_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
65 static ssize_t
66 qlcnic_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
81 static ssize_t
82 qlcnic_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
91 static int
92 qlcnic_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
112 static ssize_t
113 qlcnic_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
177 static ssize_t
178 qlcnic_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
186 static int
187 qlcnic_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
209 static ssize_t
210 qlcnic_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
234 static ssize_t
235 qlcnic_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
259 static int
260 qlcnic_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
272 static ssize_t
273 qlcnic_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
294 static ssize_t
295 qlcnic_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
316 static int
317 validate_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
349 static ssize_t
350 qlcnic_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
388 static ssize_t
389 qlcnic_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
412 static int
413 validate_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
460 static ssize_t
461 qlcnic_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         }
530 out:
531         return size;
532 }
533
534 static ssize_t
535 qlcnic_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
558 static int
559 validate_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
579 static ssize_t
580 qlcnic_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 }
618 static ssize_t
619 qlcnic_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
651 static ssize_t
652 qlcnic_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
681 static ssize_t
682 qlcnic_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
711 static ssize_t
712 qlcnic_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
735 static ssize_t
736 qlcnic_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
760 static ssize_t
761 qlcnic_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
796 static 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
802 static 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
808 static 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
814 static 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
821 static 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
828 static 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
835 static 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
842 static 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
849 static 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
856 static 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
863 static 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
870 void 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
880 void 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
888 void 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
927 void 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 }