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