2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2013 QLogic Corporation
5 * See LICENSE.qlcnic for copyright and licensing details.
10 #define QLC_DCB_MAX_TC 0x8
12 #define QLC_DCB_TSA_SUPPORT(V) (V & 0x1)
13 #define QLC_DCB_ETS_SUPPORT(V) ((V >> 1) & 0x1)
14 #define QLC_DCB_VERSION_SUPPORT(V) ((V >> 2) & 0xf)
15 #define QLC_DCB_MAX_NUM_TC(V) ((V >> 20) & 0xf)
16 #define QLC_DCB_MAX_NUM_ETS_TC(V) ((V >> 24) & 0xf)
17 #define QLC_DCB_MAX_NUM_PFC_TC(V) ((V >> 28) & 0xf)
19 static void __qlcnic_dcb_free(struct qlcnic_adapter
*);
20 static int __qlcnic_dcb_attach(struct qlcnic_adapter
*);
21 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter
*, char *);
22 static void __qlcnic_dcb_get_info(struct qlcnic_adapter
*);
24 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter
*);
26 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter
*);
28 struct qlcnic_dcb_capability
{
37 struct qlcnic_dcb_cfg
{
38 struct qlcnic_dcb_capability capability
;
42 static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops
= {
43 .free
= __qlcnic_dcb_free
,
44 .attach
= __qlcnic_dcb_attach
,
45 .query_hw_capability
= __qlcnic_dcb_query_hw_capability
,
46 .get_info
= __qlcnic_dcb_get_info
,
48 .get_hw_capability
= qlcnic_83xx_dcb_get_hw_capability
,
51 static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops
= {
52 .free
= __qlcnic_dcb_free
,
53 .attach
= __qlcnic_dcb_attach
,
54 .query_hw_capability
= __qlcnic_dcb_query_hw_capability
,
55 .get_info
= __qlcnic_dcb_get_info
,
57 .get_hw_capability
= qlcnic_82xx_dcb_get_hw_capability
,
60 void qlcnic_set_dcb_ops(struct qlcnic_adapter
*adapter
)
62 if (qlcnic_82xx_check(adapter
))
63 adapter
->dcb
->ops
= &qlcnic_82xx_dcb_ops
;
64 else if (qlcnic_83xx_check(adapter
))
65 adapter
->dcb
->ops
= &qlcnic_83xx_dcb_ops
;
68 int __qlcnic_register_dcb(struct qlcnic_adapter
*adapter
)
70 struct qlcnic_dcb
*dcb
;
72 dcb
= kzalloc(sizeof(struct qlcnic_dcb
), GFP_ATOMIC
);
77 qlcnic_set_dcb_ops(adapter
);
82 static void __qlcnic_dcb_free(struct qlcnic_adapter
*adapter
)
84 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
95 static void __qlcnic_dcb_get_info(struct qlcnic_adapter
*adapter
)
97 qlcnic_dcb_get_hw_capability(adapter
);
100 static int __qlcnic_dcb_attach(struct qlcnic_adapter
*adapter
)
102 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
104 dcb
->cfg
= kzalloc(sizeof(struct qlcnic_dcb_cfg
), GFP_ATOMIC
);
108 qlcnic_dcb_get_info(adapter
);
113 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter
*adapter
,
116 struct qlcnic_cmd_args cmd
;
120 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_CAP
);
124 err
= qlcnic_issue_cmd(adapter
, &cmd
);
126 dev_err(&adapter
->pdev
->dev
,
127 "Failed to query DCBX capability, err %d\n", err
);
129 mbx_out
= cmd
.rsp
.arg
[1];
131 memcpy(buf
, &mbx_out
, sizeof(u32
));
134 qlcnic_free_mbx_args(&cmd
);
139 static int __qlcnic_dcb_get_capability(struct qlcnic_adapter
*adapter
, u32
*val
)
141 struct qlcnic_dcb_capability
*cap
= &adapter
->dcb
->cfg
->capability
;
145 memset(cap
, 0, sizeof(struct qlcnic_dcb_capability
));
147 err
= qlcnic_dcb_query_hw_capability(adapter
, (char *)val
);
152 if (QLC_DCB_TSA_SUPPORT(mbx_out
))
153 cap
->tsa_capability
= true;
155 if (QLC_DCB_ETS_SUPPORT(mbx_out
))
156 cap
->ets_capability
= true;
158 cap
->max_num_tc
= QLC_DCB_MAX_NUM_TC(mbx_out
);
159 cap
->max_ets_tc
= QLC_DCB_MAX_NUM_ETS_TC(mbx_out
);
160 cap
->max_pfc_tc
= QLC_DCB_MAX_NUM_PFC_TC(mbx_out
);
162 if (cap
->max_num_tc
> QLC_DCB_MAX_TC
||
163 cap
->max_ets_tc
> cap
->max_num_tc
||
164 cap
->max_pfc_tc
> cap
->max_num_tc
) {
165 dev_err(&adapter
->pdev
->dev
, "Invalid DCB configuration\n");
172 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter
*adapter
)
174 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
175 struct qlcnic_dcb_capability
*cap
;
179 err
= __qlcnic_dcb_get_capability(adapter
, &mbx_out
);
183 cap
= &cfg
->capability
;
184 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
| DCB_CAP_DCBX_LLD_MANAGED
;
186 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
187 set_bit(__QLCNIC_DCB_STATE
, &adapter
->state
);
192 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter
*adapter
)
194 struct qlcnic_dcb_capability
*cap
= &adapter
->dcb
->cfg
->capability
;
198 err
= __qlcnic_dcb_get_capability(adapter
, &mbx_out
);
203 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
;
205 cap
->dcb_capability
|= DCB_CAP_DCBX_VER_IEEE
;
206 if (cap
->dcb_capability
)
207 cap
->dcb_capability
|= DCB_CAP_DCBX_LLD_MANAGED
;
209 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
210 set_bit(__QLCNIC_DCB_STATE
, &adapter
->state
);