blob: 987fb6f8adc3b34a1089b9e44de928de5fba0119 [file] [log] [blame]
Jitendra Kalsaria577ae392013-02-04 12:33:07 +00001/*
2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2013 QLogic Corporation
4 *
5 * See LICENSE.qlcnic for copyright and licensing details.
6 */
7
Sony Chackoec079a02012-11-28 04:34:28 +00008#include <linux/slab.h>
9#include <linux/vmalloc.h>
10#include <linux/interrupt.h>
11
12#include "qlcnic.h"
Sony Chacko319ecf12013-01-01 03:20:22 +000013#include "qlcnic_hw.h"
Sony Chackoec079a02012-11-28 04:34:28 +000014
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
Sony Chacko319ecf12013-01-01 03:20:22 +000024#include <linux/sysfs.h>
25
26#define QLC_STATUS_UNSUPPORTED_CMD -2
27
Sony Chackoec079a02012-11-28 04:34:28 +000028int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
29{
30 return -EOPNOTSUPP;
31}
32
33int qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
34{
35 return -EOPNOTSUPP;
36}
37
Sony Chackob66e29c2012-11-28 04:34:29 +000038static ssize_t qlcnic_store_bridged_mode(struct device *dev,
39 struct device_attribute *attr,
40 const char *buf, size_t len)
Sony Chackoec079a02012-11-28 04:34:28 +000041{
42 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
43 unsigned long new;
44 int ret = -EINVAL;
45
Sony Chacko79788452012-12-04 03:33:53 +000046 if (!(adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG))
Sony Chackoec079a02012-11-28 04:34:28 +000047 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
Sony Chacko319ecf12013-01-01 03:20:22 +000055 if (!qlcnic_config_bridged_mode(adapter, !!new))
Sony Chackoec079a02012-11-28 04:34:28 +000056 ret = len;
57
58err_out:
59 return ret;
60}
61
Sony Chackob66e29c2012-11-28 04:34:29 +000062static ssize_t qlcnic_show_bridged_mode(struct device *dev,
63 struct device_attribute *attr,
64 char *buf)
Sony Chackoec079a02012-11-28 04:34:28 +000065{
66 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
67 int bridged_mode = 0;
68
Sony Chacko79788452012-12-04 03:33:53 +000069 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
Sony Chackoec079a02012-11-28 04:34:28 +000070 bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
71
72 return sprintf(buf, "%d\n", bridged_mode);
73}
74
Sony Chackob66e29c2012-11-28 04:34:29 +000075static ssize_t qlcnic_store_diag_mode(struct device *dev,
76 struct device_attribute *attr,
77 const char *buf, size_t len)
Sony Chackoec079a02012-11-28 04:34:28 +000078{
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
Sony Chackob66e29c2012-11-28 04:34:29 +000091static ssize_t qlcnic_show_diag_mode(struct device *dev,
92 struct device_attribute *attr, char *buf)
Sony Chackoec079a02012-11-28 04:34:28 +000093{
94 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chacko319ecf12013-01-01 03:20:22 +000095 return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED));
Sony Chackoec079a02012-11-28 04:34:28 +000096}
97
Sony Chackob66e29c2012-11-28 04:34:29 +000098static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon,
99 u8 *state, u8 *rate)
Sony Chackoec079a02012-11-28 04:34:28 +0000100{
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;
Sony Chackob66e29c2012-11-28 04:34:29 +0000109 } else if (*state > __QLCNIC_MAX_LED_STATE) {
Sony Chackoec079a02012-11-28 04:34:28 +0000110 return -EINVAL;
Sony Chackob66e29c2012-11-28 04:34:29 +0000111 }
Sony Chackoec079a02012-11-28 04:34:28 +0000112
113 if ((!*rate) || (*rate > __QLCNIC_MAX_LED_RATE))
114 return -EINVAL;
115
116 return 0;
117}
118
Sony Chackob66e29c2012-11-28 04:34:29 +0000119static ssize_t qlcnic_store_beacon(struct device *dev,
120 struct device_attribute *attr,
121 const char *buf, size_t len)
Sony Chackoec079a02012-11-28 04:34:28 +0000122{
123 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chacko319ecf12013-01-01 03:20:22 +0000124 struct qlcnic_hardware_context *ahw = adapter->ahw;
125 int err, max_sds_rings = adapter->max_sds_rings;
Sony Chackoec079a02012-11-28 04:34:28 +0000126 u16 beacon;
127 u8 b_state, b_rate;
Sony Chacko319ecf12013-01-01 03:20:22 +0000128 unsigned long h_beacon;
Sony Chackoec079a02012-11-28 04:34:28 +0000129
Sony Chacko79788452012-12-04 03:33:53 +0000130 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
Sony Chackob66e29c2012-11-28 04:34:29 +0000131 dev_warn(dev,
132 "LED test not supported in non privileged mode\n");
Sony Chackoec079a02012-11-28 04:34:28 +0000133 return -EOPNOTSUPP;
134 }
135
Sony Chacko319ecf12013-01-01 03:20:22 +0000136 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;
163beacon_err:
164 if (!ahw->beacon_state)
165 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
166
167 rtnl_unlock();
168 return len;
169 }
170
Sony Chackoec079a02012-11-28 04:34:28 +0000171 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);
Sony Chacko319ecf12013-01-01 03:20:22 +0000203 if (!err)
Sony Chackoec079a02012-11-28 04:34:28 +0000204 err = len;
Sony Chacko319ecf12013-01-01 03:20:22 +0000205 else
206 ahw->beacon_state = b_state;
Sony Chackoec079a02012-11-28 04:34:28 +0000207
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
Sony Chackob66e29c2012-11-28 04:34:29 +0000219static ssize_t qlcnic_show_beacon(struct device *dev,
220 struct device_attribute *attr, char *buf)
Sony Chackoec079a02012-11-28 04:34:28 +0000221{
222 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
223
224 return sprintf(buf, "%d\n", adapter->ahw->beacon_state);
225}
226
Sony Chackob66e29c2012-11-28 04:34:29 +0000227static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
228 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000229{
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,
Sony Chackob66e29c2012-11-28 04:34:29 +0000237 QLCNIC_PCI_CAMQM_END))
Sony Chackoec079a02012-11-28 04:34:28 +0000238 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
Sony Chackob66e29c2012-11-28 04:34:29 +0000249static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000252{
253 struct device *dev = container_of(kobj, struct device, kobj);
254 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chackoec079a02012-11-28 04:34:28 +0000255 int ret;
256
257 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
258 if (ret != 0)
259 return ret;
Sony Chacko319ecf12013-01-01 03:20:22 +0000260 qlcnic_read_crb(adapter, buf, offset, size);
Sony Chackoec079a02012-11-28 04:34:28 +0000261
Sony Chackoec079a02012-11-28 04:34:28 +0000262 return size;
263}
264
Sony Chackob66e29c2012-11-28 04:34:29 +0000265static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000268{
269 struct device *dev = container_of(kobj, struct device, kobj);
270 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chackoec079a02012-11-28 04:34:28 +0000271 int ret;
272
273 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
274 if (ret != 0)
275 return ret;
276
Sony Chacko319ecf12013-01-01 03:20:22 +0000277 qlcnic_write_crb(adapter, buf, offset, size);
Sony Chackoec079a02012-11-28 04:34:28 +0000278 return size;
279}
280
Sony Chackob66e29c2012-11-28 04:34:29 +0000281static int qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
282 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000283{
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
Sony Chackob66e29c2012-11-28 04:34:29 +0000293static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000296{
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
Sony Chackob66e29c2012-11-28 04:34:29 +0000314static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000317{
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
Sony Chacko319ecf12013-01-01 03:20:22 +0000335static 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
Sony Chackob66e29c2012-11-28 04:34:29 +0000346static int validate_pm_config(struct qlcnic_adapter *adapter,
347 struct qlcnic_pm_func_cfg *pm_cfg, int count)
Sony Chackoec079a02012-11-28 04:34:28 +0000348{
Sony Chacko319ecf12013-01-01 03:20:22 +0000349 u8 src_pci_func, s_esw_id, d_esw_id;
350 u8 dest_pci_func;
351 int i, src_index, dest_index;
Sony Chackoec079a02012-11-28 04:34:28 +0000352
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;
Sony Chacko319ecf12013-01-01 03:20:22 +0000356 src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func);
357
358 if (src_index < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000359 return QL_STATUS_INVALID_PARAM;
360
Sony Chacko319ecf12013-01-01 03:20:22 +0000361 dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func);
362 if (dest_index < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000363 return QL_STATUS_INVALID_PARAM;
364
Sony Chacko319ecf12013-01-01 03:20:22 +0000365 s_esw_id = adapter->npars[src_index].phy_port;
366 d_esw_id = adapter->npars[dest_index].phy_port;
Sony Chackoec079a02012-11-28 04:34:28 +0000367
368 if (s_esw_id != d_esw_id)
369 return QL_STATUS_INVALID_PARAM;
Sony Chackoec079a02012-11-28 04:34:28 +0000370 }
Sony Chackoec079a02012-11-28 04:34:28 +0000371
Sony Chacko319ecf12013-01-01 03:20:22 +0000372 return 0;
Sony Chackoec079a02012-11-28 04:34:28 +0000373}
374
Sony Chackob66e29c2012-11-28 04:34:29 +0000375static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000380{
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;
Sony Chacko319ecf12013-01-01 03:20:22 +0000385 int count, rem, i, ret, index;
Sony Chackoec079a02012-11-28 04:34:28 +0000386
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
Sony Chackob66e29c2012-11-28 04:34:29 +0000392 pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
Sony Chackoec079a02012-11-28 04:34:28 +0000393 ret = validate_pm_config(adapter, pm_cfg, count);
Sony Chacko319ecf12013-01-01 03:20:22 +0000394
Sony Chackoec079a02012-11-28 04:34:28 +0000395 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;
Sony Chacko319ecf12013-01-01 03:20:22 +0000400 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);
Sony Chackoec079a02012-11-28 04:34:28 +0000407 if (ret)
408 return ret;
409 }
410
411 for (i = 0; i < count; i++) {
412 pci_func = pm_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000413 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;
Sony Chackoec079a02012-11-28 04:34:28 +0000417 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000418
Sony Chackoec079a02012-11-28 04:34:28 +0000419 return size;
420}
421
Sony Chackob66e29c2012-11-28 04:34:29 +0000422static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000427{
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;
Sony Chacko319ecf12013-01-01 03:20:22 +0000432 u8 pci_func;
Sony Chackoec079a02012-11-28 04:34:28 +0000433
434 if (size != sizeof(pm_cfg))
435 return QL_STATUS_INVALID_PARAM;
436
Sony Chacko319ecf12013-01-01 03:20:22 +0000437 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;
Sony Chackoec079a02012-11-28 04:34:28 +0000445 }
446 memcpy(buf, &pm_cfg, size);
447
448 return size;
449}
450
Sony Chackob66e29c2012-11-28 04:34:29 +0000451static int validate_esw_config(struct qlcnic_adapter *adapter,
452 struct qlcnic_esw_func_cfg *esw_cfg, int count)
Sony Chackoec079a02012-11-28 04:34:28 +0000453{
454 u32 op_mode;
455 u8 pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000456 int i, ret;
Sony Chackoec079a02012-11-28 04:34:28 +0000457
Sony Chacko319ecf12013-01-01 03:20:22 +0000458 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);
Sony Chackoec079a02012-11-28 04:34:28 +0000462
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
Sony Chacko319ecf12013-01-01 03:20:22 +0000468 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
469 if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000470 return QL_STATUS_INVALID_PARAM;
471
472 switch (esw_cfg[i].op_mode) {
473 case QLCNIC_PORT_DEFAULTS:
Sony Chacko319ecf12013-01-01 03:20:22 +0000474 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) {
Sony Chackoec079a02012-11-28 04:34:28 +0000483 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 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000505
Sony Chackoec079a02012-11-28 04:34:28 +0000506 return 0;
507}
508
Sony Chackob66e29c2012-11-28 04:34:29 +0000509static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000514{
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;
Sony Chacko319ecf12013-01-01 03:20:22 +0000520 int index;
521 u8 op_mode = 0, pci_func;
Sony Chackoec079a02012-11-28 04:34:28 +0000522
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
Sony Chackob66e29c2012-11-28 04:34:29 +0000528 esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
Sony Chackoec079a02012-11-28 04:34:28 +0000529 ret = validate_esw_config(adapter, esw_cfg, count);
530 if (ret)
531 return ret;
532
533 for (i = 0; i < count; i++) {
Sony Chacko319ecf12013-01-01 03:20:22 +0000534 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +0000535 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
Sony Chacko79788452012-12-04 03:33:53 +0000560 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +0000561 goto out;
562
563 for (i = 0; i < count; i++) {
564 pci_func = esw_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000565 index = qlcnic_is_valid_nic_func(adapter, pci_func);
566 npar = &adapter->npars[index];
Sony Chackoec079a02012-11-28 04:34:28 +0000567 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 }
583out:
584 return size;
585}
586
Sony Chackob66e29c2012-11-28 04:34:29 +0000587static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000592{
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];
Sony Chacko319ecf12013-01-01 03:20:22 +0000596 u8 i, pci_func;
Sony Chackoec079a02012-11-28 04:34:28 +0000597
598 if (size != sizeof(esw_cfg))
599 return QL_STATUS_INVALID_PARAM;
600
Sony Chacko319ecf12013-01-01 03:20:22 +0000601 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]))
Sony Chackoec079a02012-11-28 04:34:28 +0000608 return QL_STATUS_INVALID_PARAM;
609 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000610
Sony Chackoec079a02012-11-28 04:34:28 +0000611 memcpy(buf, &esw_cfg, size);
612
613 return size;
614}
615
Sony Chackob66e29c2012-11-28 04:34:29 +0000616static int validate_npar_config(struct qlcnic_adapter *adapter,
617 struct qlcnic_npar_func_cfg *np_cfg,
618 int count)
Sony Chackoec079a02012-11-28 04:34:28 +0000619{
620 u8 pci_func, i;
621
622 for (i = 0; i < count; i++) {
623 pci_func = np_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000624 if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000625 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
Sony Chackob66e29c2012-11-28 04:34:29 +0000634static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000639{
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;
Sony Chacko319ecf12013-01-01 03:20:22 +0000644 int i, count, rem, ret, index;
Sony Chackoec079a02012-11-28 04:34:28 +0000645 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
Sony Chackob66e29c2012-11-28 04:34:29 +0000652 np_cfg = (struct qlcnic_npar_func_cfg *)buf;
Sony Chackoec079a02012-11-28 04:34:28 +0000653 ret = validate_npar_config(adapter, np_cfg, count);
654 if (ret)
655 return ret;
656
Sony Chacko319ecf12013-01-01 03:20:22 +0000657 for (i = 0; i < count; i++) {
Sony Chackoec079a02012-11-28 04:34:28 +0000658 pci_func = np_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000659
660 memset(&nic_info, 0, sizeof(struct qlcnic_info));
Sony Chackoec079a02012-11-28 04:34:28 +0000661 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;
Sony Chacko319ecf12013-01-01 03:20:22 +0000670 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;
Sony Chackoec079a02012-11-28 04:34:28 +0000673 }
674
675 return size;
Sony Chackoec079a02012-11-28 04:34:28 +0000676}
Sony Chackob66e29c2012-11-28 04:34:29 +0000677
678static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000683{
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
Sony Chacko319ecf12013-01-01 03:20:22 +0000693 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
Sony Chackob66e29c2012-11-28 04:34:29 +0000697 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
Sony Chacko319ecf12013-01-01 03:20:22 +0000698 if (qlcnic_is_valid_nic_func(adapter, i) < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000699 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;
Sony Chackob66e29c2012-11-28 04:34:29 +0000708 np_cfg[i].min_bw = nic_info.min_tx_bw;
Sony Chackoec079a02012-11-28 04:34:28 +0000709 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 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000713
Sony Chackoec079a02012-11-28 04:34:28 +0000714 memcpy(buf, &np_cfg, size);
715 return size;
716}
717
Sony Chackob66e29c2012-11-28 04:34:29 +0000718static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000723{
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
Sony Chacko319ecf12013-01-01 03:20:22 +0000729 if (qlcnic_83xx_check(adapter))
730 return QLC_STATUS_UNSUPPORTED_CMD;
731
Sony Chackoec079a02012-11-28 04:34:28 +0000732 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,
Sony Chackob66e29c2012-11-28 04:34:29 +0000740 &port_stats.rx);
Sony Chackoec079a02012-11-28 04:34:28 +0000741 if (ret)
742 return ret;
743
744 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
Sony Chackob66e29c2012-11-28 04:34:29 +0000745 &port_stats.tx);
Sony Chackoec079a02012-11-28 04:34:28 +0000746 if (ret)
747 return ret;
748
749 memcpy(buf, &port_stats, size);
750 return size;
751}
752
Sony Chackob66e29c2012-11-28 04:34:29 +0000753static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000758{
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
Sony Chacko319ecf12013-01-01 03:20:22 +0000764 if (qlcnic_83xx_check(adapter))
765 return QLC_STATUS_UNSUPPORTED_CMD;
766
Sony Chackoec079a02012-11-28 04:34:28 +0000767 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,
Sony Chackob66e29c2012-11-28 04:34:29 +0000775 &esw_stats.rx);
Sony Chackoec079a02012-11-28 04:34:28 +0000776 if (ret)
777 return ret;
778
779 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
Sony Chackob66e29c2012-11-28 04:34:29 +0000780 &esw_stats.tx);
Sony Chackoec079a02012-11-28 04:34:28 +0000781 if (ret)
782 return ret;
783
784 memcpy(buf, &esw_stats, size);
785 return size;
786}
787
Sony Chackob66e29c2012-11-28 04:34:29 +0000788static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000793{
794 struct device *dev = container_of(kobj, struct device, kobj);
795 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
796 int ret;
797
Sony Chacko319ecf12013-01-01 03:20:22 +0000798 if (qlcnic_83xx_check(adapter))
799 return QLC_STATUS_UNSUPPORTED_CMD;
800
Sony Chackoec079a02012-11-28 04:34:28 +0000801 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,
Sony Chackob66e29c2012-11-28 04:34:29 +0000805 QLCNIC_QUERY_RX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000806 if (ret)
807 return ret;
808
809 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
Sony Chackob66e29c2012-11-28 04:34:29 +0000810 QLCNIC_QUERY_TX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000811 if (ret)
812 return ret;
813
814 return size;
815}
816
Sony Chackob66e29c2012-11-28 04:34:29 +0000817static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000822{
Sony Chacko319ecf12013-01-01 03:20:22 +0000823
Sony Chackoec079a02012-11-28 04:34:28 +0000824 struct device *dev = container_of(kobj, struct device, kobj);
825 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
826 int ret;
827
Sony Chacko319ecf12013-01-01 03:20:22 +0000828 if (qlcnic_83xx_check(adapter))
829 return QLC_STATUS_UNSUPPORTED_CMD;
830
Sony Chackoec079a02012-11-28 04:34:28 +0000831 if (offset >= QLCNIC_MAX_PCI_FUNC)
832 return QL_STATUS_INVALID_PARAM;
833
834 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
Sony Chackob66e29c2012-11-28 04:34:29 +0000835 QLCNIC_QUERY_RX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000836 if (ret)
837 return ret;
838
839 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
Sony Chackob66e29c2012-11-28 04:34:29 +0000840 QLCNIC_QUERY_TX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000841 if (ret)
842 return ret;
843
844 return size;
845}
846
Sony Chackob66e29c2012-11-28 04:34:29 +0000847static 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)
Sony Chackoec079a02012-11-28 04:34:28 +0000852{
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
Sony Chacko319ecf12013-01-01 03:20:22 +0000872 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++) {
Sony Chackoec079a02012-11-28 04:34:28 +0000876 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 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000883
Sony Chackoec079a02012-11-28 04:34:28 +0000884 memcpy(buf, &pci_cfg, size);
885 kfree(pci_info);
886 return size;
887}
888
889static 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
895static 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
901static 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
907static 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
914static 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
921static 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
928static 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
935static 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
942static 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
949static 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
956static 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
963void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
964{
965 struct device *dev = &adapter->pdev->dev;
966
Sony Chacko79788452012-12-04 03:33:53 +0000967 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
Sony Chackoec079a02012-11-28 04:34:28 +0000968 if (device_create_file(dev, &dev_attr_bridged_mode))
969 dev_warn(dev,
Sony Chackob66e29c2012-11-28 04:34:29 +0000970 "failed to create bridged_mode sysfs entry\n");
Sony Chackoec079a02012-11-28 04:34:28 +0000971}
972
973void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
974{
975 struct device *dev = &adapter->pdev->dev;
976
Sony Chacko79788452012-12-04 03:33:53 +0000977 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
Sony Chackoec079a02012-11-28 04:34:28 +0000978 device_remove_file(dev, &dev_attr_bridged_mode);
979}
980
981void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
982{
983 struct device *dev = &adapter->pdev->dev;
Sony Chackoec079a02012-11-28 04:34:28 +0000984
985 if (device_create_bin_file(dev, &bin_attr_port_stats))
986 dev_info(dev, "failed to create port stats sysfs entry");
987
Sony Chacko79788452012-12-04 03:33:53 +0000988 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +0000989 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
Sony Chackoec079a02012-11-28 04:34:28 +0000997 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");
Sony Chacko79788452012-12-04 03:33:53 +00001006 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +00001007 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
1016void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
1017{
1018 struct device *dev = &adapter->pdev->dev;
Sony Chackoec079a02012-11-28 04:34:28 +00001019
1020 device_remove_bin_file(dev, &bin_attr_port_stats);
1021
Sony Chacko79788452012-12-04 03:33:53 +00001022 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +00001023 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);
Sony Chackoec079a02012-11-28 04:34:28 +00001027 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);
Sony Chacko79788452012-12-04 03:33:53 +00001032 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +00001033 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}
Sony Chacko7e2cf4f2013-01-01 03:20:17 +00001038
1039void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter)
1040{
1041 qlcnic_create_diag_entries(adapter);
1042}
1043
1044void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
1045{
1046 qlcnic_remove_diag_entries(adapter);
1047}
Sony Chacko319ecf12013-01-01 03:20:22 +00001048
1049void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
1050{
1051 qlcnic_create_diag_entries(adapter);
1052}
1053
1054void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
1055{
1056 qlcnic_remove_diag_entries(adapter);
1057}