aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
diff options
context:
space:
mode:
authorSucheta Chakraborty <sucheta.chakraborty@qlogic.com>2013-08-23 13:38:26 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-27 15:21:14 -0400
commitfb859ed6916faeae6b44027d2e0738836a11e8c1 (patch)
tree400c0a70c692e8f6ea78ee9635ad21a57ff6ec86 /drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
parent14d385b9905920cc0136721316c185c45ee6e26c (diff)
qlcnic: dcb: Get DCB parameters from the adapter.
o Populate driver data structures with local, operational, and peer DCB parameters. Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
index 121e492f2f87..e43866f20bbb 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
@@ -5,9 +5,14 @@
5 * See LICENSE.qlcnic for copyright and licensing details. 5 * See LICENSE.qlcnic for copyright and licensing details.
6 */ 6 */
7 7
8#include <linux/types.h>
8#include "qlcnic.h" 9#include "qlcnic.h"
9 10
11#define QLC_DCB_NUM_PARAM 3
12
13#define QLC_DCB_FW_VER 0x2
10#define QLC_DCB_MAX_TC 0x8 14#define QLC_DCB_MAX_TC 0x8
15#define QLC_DCB_MAX_APP 0x8
11 16
12#define QLC_DCB_TSA_SUPPORT(V) (V & 0x1) 17#define QLC_DCB_TSA_SUPPORT(V) (V & 0x1)
13#define QLC_DCB_ETS_SUPPORT(V) ((V >> 1) & 0x1) 18#define QLC_DCB_ETS_SUPPORT(V) ((V >> 1) & 0x1)
@@ -15,6 +20,29 @@
15#define QLC_DCB_MAX_NUM_TC(V) ((V >> 20) & 0xf) 20#define QLC_DCB_MAX_NUM_TC(V) ((V >> 20) & 0xf)
16#define QLC_DCB_MAX_NUM_ETS_TC(V) ((V >> 24) & 0xf) 21#define QLC_DCB_MAX_NUM_ETS_TC(V) ((V >> 24) & 0xf)
17#define QLC_DCB_MAX_NUM_PFC_TC(V) ((V >> 28) & 0xf) 22#define QLC_DCB_MAX_NUM_PFC_TC(V) ((V >> 28) & 0xf)
23#define QLC_DCB_GET_TC_PRIO(X, P) ((X >> (P * 3)) & 0x7)
24#define QLC_DCB_GET_PGID_PRIO(X, P) ((X >> (P * 8)) & 0xff)
25#define QLC_DCB_GET_BWPER_PG(X, P) ((X >> (P * 8)) & 0xff)
26#define QLC_DCB_GET_TSA_PG(X, P) ((X >> (P * 8)) & 0xff)
27#define QLC_DCB_GET_PFC_PRIO(X, P) (((X >> 24) >> P) & 0x1)
28#define QLC_DCB_GET_PROTO_ID_APP(X) ((X >> 8) & 0xffff)
29#define QLC_DCB_GET_SELECTOR_APP(X) (X & 0xff)
30
31#define QLC_DCB_LOCAL_PARAM_FWID 0x3
32#define QLC_DCB_OPER_PARAM_FWID 0x1
33#define QLC_DCB_PEER_PARAM_FWID 0x2
34
35#define QLC_83XX_DCB_GET_NUMAPP(X) ((X >> 2) & 0xf)
36#define QLC_83XX_DCB_TSA_VALID(X) (X & 0x1)
37#define QLC_83XX_DCB_PFC_VALID(X) ((X >> 1) & 0x1)
38#define QLC_83XX_DCB_GET_PRIOMAP_APP(X) (X >> 24)
39
40#define QLC_82XX_DCB_GET_NUMAPP(X) ((X >> 12) & 0xf)
41#define QLC_82XX_DCB_TSA_VALID(X) ((X >> 4) & 0x1)
42#define QLC_82XX_DCB_PFC_VALID(X) ((X >> 5) & 0x1)
43#define QLC_82XX_DCB_GET_PRIOVAL_APP(X) ((X >> 24) & 0x7)
44#define QLC_82XX_DCB_GET_PRIOMAP_APP(X) (1 << X)
45#define QLC_82XX_DCB_PRIO_TC_MAP (0x76543210)
18 46
19static void __qlcnic_dcb_free(struct qlcnic_adapter *); 47static void __qlcnic_dcb_free(struct qlcnic_adapter *);
20static int __qlcnic_dcb_attach(struct qlcnic_adapter *); 48static int __qlcnic_dcb_attach(struct qlcnic_adapter *);
@@ -22,8 +50,12 @@ static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *, char *);
22static void __qlcnic_dcb_get_info(struct qlcnic_adapter *); 50static void __qlcnic_dcb_get_info(struct qlcnic_adapter *);
23 51
24static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *); 52static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *);
53static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
54static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
25 55
26static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *); 56static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *);
57static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
58static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
27 59
28struct qlcnic_dcb_capability { 60struct qlcnic_dcb_capability {
29 bool tsa_capability; 61 bool tsa_capability;
@@ -34,6 +66,28 @@ struct qlcnic_dcb_capability {
34 u8 dcb_capability; 66 u8 dcb_capability;
35}; 67};
36 68
69struct qlcnic_dcb_param {
70 u32 hdr_prio_pfc_map[2];
71 u32 prio_pg_map[2];
72 u32 pg_bw_map[2];
73 u32 pg_tsa_map[2];
74 u32 app[QLC_DCB_MAX_APP];
75};
76
77struct qlcnic_dcb_mbx_params {
78 /* 1st local, 2nd operational 3rd remote */
79 struct qlcnic_dcb_param type[3];
80 u32 prio_tc_map;
81};
82
83struct qlcnic_82xx_dcb_param_mbx_le {
84 __le32 hdr_prio_pfc_map[2];
85 __le32 prio_pg_map[2];
86 __le32 pg_bw_map[2];
87 __le32 pg_tsa_map[2];
88 __le32 app[QLC_DCB_MAX_APP];
89};
90
37struct qlcnic_dcb_cfg { 91struct qlcnic_dcb_cfg {
38 struct qlcnic_dcb_capability capability; 92 struct qlcnic_dcb_capability capability;
39 u32 version; 93 u32 version;
@@ -46,6 +100,8 @@ static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = {
46 .get_info = __qlcnic_dcb_get_info, 100 .get_info = __qlcnic_dcb_get_info,
47 101
48 .get_hw_capability = qlcnic_83xx_dcb_get_hw_capability, 102 .get_hw_capability = qlcnic_83xx_dcb_get_hw_capability,
103 .query_cee_param = qlcnic_83xx_dcb_query_cee_param,
104 .get_cee_cfg = qlcnic_83xx_dcb_get_cee_cfg,
49}; 105};
50 106
51static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = { 107static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
@@ -55,8 +111,18 @@ static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
55 .get_info = __qlcnic_dcb_get_info, 111 .get_info = __qlcnic_dcb_get_info,
56 112
57 .get_hw_capability = qlcnic_82xx_dcb_get_hw_capability, 113 .get_hw_capability = qlcnic_82xx_dcb_get_hw_capability,
114 .query_cee_param = qlcnic_82xx_dcb_query_cee_param,
115 .get_cee_cfg = qlcnic_82xx_dcb_get_cee_cfg,
58}; 116};
59 117
118static u8 qlcnic_dcb_get_num_app(struct qlcnic_adapter *adapter, u32 val)
119{
120 if (qlcnic_82xx_check(adapter))
121 return QLC_82XX_DCB_GET_NUMAPP(val);
122 else
123 return QLC_83XX_DCB_GET_NUMAPP(val);
124}
125
60void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter) 126void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
61{ 127{
62 if (qlcnic_82xx_check(adapter)) 128 if (qlcnic_82xx_check(adapter))
@@ -88,6 +154,8 @@ static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
88 154
89 kfree(dcb->cfg); 155 kfree(dcb->cfg);
90 dcb->cfg = NULL; 156 dcb->cfg = NULL;
157 kfree(dcb->param);
158 dcb->param = NULL;
91 kfree(dcb); 159 kfree(dcb);
92 adapter->dcb = NULL; 160 adapter->dcb = NULL;
93} 161}
@@ -95,19 +163,32 @@ static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
95static void __qlcnic_dcb_get_info(struct qlcnic_adapter *adapter) 163static void __qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
96{ 164{
97 qlcnic_dcb_get_hw_capability(adapter); 165 qlcnic_dcb_get_hw_capability(adapter);
166 qlcnic_dcb_get_cee_cfg(adapter);
98} 167}
99 168
100static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter) 169static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
101{ 170{
102 struct qlcnic_dcb *dcb = adapter->dcb; 171 struct qlcnic_dcb *dcb = adapter->dcb;
172 int err = 0;
103 173
104 dcb->cfg = kzalloc(sizeof(struct qlcnic_dcb_cfg), GFP_ATOMIC); 174 dcb->cfg = kzalloc(sizeof(struct qlcnic_dcb_cfg), GFP_ATOMIC);
105 if (!dcb->cfg) 175 if (!dcb->cfg)
106 return -ENOMEM; 176 return -ENOMEM;
107 177
178 dcb->param = kzalloc(sizeof(struct qlcnic_dcb_mbx_params), GFP_ATOMIC);
179 if (!dcb->param) {
180 err = -ENOMEM;
181 goto out_free_cfg;
182 }
183
108 qlcnic_dcb_get_info(adapter); 184 qlcnic_dcb_get_info(adapter);
109 185
110 return 0; 186 return 0;
187out_free_cfg:
188 kfree(dcb->cfg);
189 dcb->cfg = NULL;
190
191 return err;
111} 192}
112 193
113static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter, 194static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
@@ -189,6 +270,104 @@ static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
189 return err; 270 return err;
190} 271}
191 272
273static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
274 char *buf, u8 type)
275{
276 u16 size = sizeof(struct qlcnic_82xx_dcb_param_mbx_le);
277 struct qlcnic_82xx_dcb_param_mbx_le *prsp_le;
278 struct device *dev = &adapter->pdev->dev;
279 dma_addr_t cardrsp_phys_addr;
280 struct qlcnic_dcb_param rsp;
281 struct qlcnic_cmd_args cmd;
282 u64 phys_addr;
283 void *addr;
284 int err, i;
285
286 switch (type) {
287 case QLC_DCB_LOCAL_PARAM_FWID:
288 case QLC_DCB_OPER_PARAM_FWID:
289 case QLC_DCB_PEER_PARAM_FWID:
290 break;
291 default:
292 dev_err(dev, "Invalid parameter type %d\n", type);
293 return -EINVAL;
294 }
295
296 addr = dma_alloc_coherent(&adapter->pdev->dev, size, &cardrsp_phys_addr,
297 GFP_KERNEL);
298 if (addr == NULL)
299 return -ENOMEM;
300
301 prsp_le = addr;
302
303 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_PARAM);
304 if (err)
305 goto out_free_rsp;
306
307 phys_addr = cardrsp_phys_addr;
308 cmd.req.arg[1] = size | (type << 16);
309 cmd.req.arg[2] = MSD(phys_addr);
310 cmd.req.arg[3] = LSD(phys_addr);
311
312 err = qlcnic_issue_cmd(adapter, &cmd);
313 if (err) {
314 dev_err(dev, "Failed to query DCBX parameter, err %d\n", err);
315 goto out;
316 }
317
318 memset(&rsp, 0, sizeof(struct qlcnic_dcb_param));
319 rsp.hdr_prio_pfc_map[0] = le32_to_cpu(prsp_le->hdr_prio_pfc_map[0]);
320 rsp.hdr_prio_pfc_map[1] = le32_to_cpu(prsp_le->hdr_prio_pfc_map[1]);
321 rsp.prio_pg_map[0] = le32_to_cpu(prsp_le->prio_pg_map[0]);
322 rsp.prio_pg_map[1] = le32_to_cpu(prsp_le->prio_pg_map[1]);
323 rsp.pg_bw_map[0] = le32_to_cpu(prsp_le->pg_bw_map[0]);
324 rsp.pg_bw_map[1] = le32_to_cpu(prsp_le->pg_bw_map[1]);
325 rsp.pg_tsa_map[0] = le32_to_cpu(prsp_le->pg_tsa_map[0]);
326 rsp.pg_tsa_map[1] = le32_to_cpu(prsp_le->pg_tsa_map[1]);
327
328 for (i = 0; i < QLC_DCB_MAX_APP; i++)
329 rsp.app[i] = le32_to_cpu(prsp_le->app[i]);
330
331 if (buf)
332 memcpy(buf, &rsp, size);
333out:
334 qlcnic_free_mbx_args(&cmd);
335
336out_free_rsp:
337 dma_free_coherent(&adapter->pdev->dev, size, addr, cardrsp_phys_addr);
338
339 return err;
340}
341
342static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
343{
344 struct qlcnic_dcb_mbx_params *mbx;
345 int err;
346
347 mbx = adapter->dcb->param;
348 if (!mbx)
349 return 0;
350
351 err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[0],
352 QLC_DCB_LOCAL_PARAM_FWID);
353 if (err)
354 return err;
355
356 err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[1],
357 QLC_DCB_OPER_PARAM_FWID);
358 if (err)
359 return err;
360
361 err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[2],
362 QLC_DCB_PEER_PARAM_FWID);
363 if (err)
364 return err;
365
366 mbx->prio_tc_map = QLC_82XX_DCB_PRIO_TC_MAP;
367
368 return err;
369}
370
192static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter) 371static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
193{ 372{
194 struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability; 373 struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
@@ -211,3 +390,72 @@ static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
211 390
212 return err; 391 return err;
213} 392}
393
394static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
395 char *buf, u8 idx)
396{
397 struct qlcnic_dcb_mbx_params mbx_out;
398 int err, i, j, k, max_app, size;
399 struct qlcnic_dcb_param *each;
400 struct qlcnic_cmd_args cmd;
401 u32 val;
402 char *p;
403
404 size = 0;
405 memset(&mbx_out, 0, sizeof(struct qlcnic_dcb_mbx_params));
406 memset(buf, 0, sizeof(struct qlcnic_dcb_mbx_params));
407
408 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_PARAM);
409 if (err)
410 return err;
411
412 cmd.req.arg[0] |= QLC_DCB_FW_VER << 29;
413 err = qlcnic_issue_cmd(adapter, &cmd);
414 if (err) {
415 dev_err(&adapter->pdev->dev,
416 "Failed to query DCBX param, err %d\n", err);
417 goto out;
418 }
419
420 mbx_out.prio_tc_map = cmd.rsp.arg[1];
421 p = memcpy(buf, &mbx_out, sizeof(u32));
422 k = 2;
423 p += sizeof(u32);
424
425 for (j = 0; j < QLC_DCB_NUM_PARAM; j++) {
426 each = &mbx_out.type[j];
427
428 each->hdr_prio_pfc_map[0] = cmd.rsp.arg[k++];
429 each->hdr_prio_pfc_map[1] = cmd.rsp.arg[k++];
430 each->prio_pg_map[0] = cmd.rsp.arg[k++];
431 each->prio_pg_map[1] = cmd.rsp.arg[k++];
432 each->pg_bw_map[0] = cmd.rsp.arg[k++];
433 each->pg_bw_map[1] = cmd.rsp.arg[k++];
434 each->pg_tsa_map[0] = cmd.rsp.arg[k++];
435 each->pg_tsa_map[1] = cmd.rsp.arg[k++];
436 val = each->hdr_prio_pfc_map[0];
437
438 max_app = qlcnic_dcb_get_num_app(adapter, val);
439 for (i = 0; i < max_app; i++)
440 each->app[i] = cmd.rsp.arg[i + k];
441
442 size = 16 * sizeof(u32);
443 memcpy(p, &each->hdr_prio_pfc_map[0], size);
444 p += size;
445 if (j == 0)
446 k = 18;
447 else
448 k = 34;
449 }
450out:
451 qlcnic_free_mbx_args(&cmd);
452
453 return err;
454}
455
456static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
457{
458 struct qlcnic_dcb *dcb = adapter->dcb;
459
460 return qlcnic_dcb_query_cee_param(adapter, (char *)dcb->param, 0);
461}