Merge tag 'leds-for-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anasz...
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / chelsio / cxgb4 / cxgb4_dcb.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Copyright (C) 2013-2014 Chelsio Communications.  All rights reserved.
4  *
5  *  Written by Anish Bhatt (anish@chelsio.com)
6  *             Casey Leedom (leedom@chelsio.com)
7  */
8
9 #include "cxgb4.h"
10
11 /* DCBx version control
12  */
13 const char * const dcb_ver_array[] = {
14         "Unknown",
15         "DCBx-CIN",
16         "DCBx-CEE 1.01",
17         "DCBx-IEEE",
18         "", "", "",
19         "Auto Negotiated"
20 };
21
22 static inline bool cxgb4_dcb_state_synced(enum cxgb4_dcb_state state)
23 {
24         if (state == CXGB4_DCB_STATE_FW_ALLSYNCED ||
25             state == CXGB4_DCB_STATE_HOST)
26                 return true;
27         else
28                 return false;
29 }
30
31 /* Initialize a port's Data Center Bridging state.
32  */
33 void cxgb4_dcb_state_init(struct net_device *dev)
34 {
35         struct port_info *pi = netdev2pinfo(dev);
36         struct port_dcb_info *dcb = &pi->dcb;
37         int version_temp = dcb->dcb_version;
38
39         memset(dcb, 0, sizeof(struct port_dcb_info));
40         dcb->state = CXGB4_DCB_STATE_START;
41         if (version_temp)
42                 dcb->dcb_version = version_temp;
43
44         netdev_dbg(dev, "%s: Initializing DCB state for port[%d]\n",
45                     __func__, pi->port_id);
46 }
47
48 void cxgb4_dcb_version_init(struct net_device *dev)
49 {
50         struct port_info *pi = netdev2pinfo(dev);
51         struct port_dcb_info *dcb = &pi->dcb;
52
53         /* Any writes here are only done on kernels that exlicitly need
54          * a specific version, say < 2.6.38 which only support CEE
55          */
56         dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
57 }
58
59 static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
60 {
61         struct port_info *pi = netdev2pinfo(dev);
62         struct adapter *adap = pi->adapter;
63         struct port_dcb_info *dcb = &pi->dcb;
64         struct dcb_app app;
65         int i, err;
66
67         /* zero priority implies remove */
68         app.priority = 0;
69
70         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
71                 /* Check if app list is exhausted */
72                 if (!dcb->app_priority[i].protocolid)
73                         break;
74
75                 app.protocol = dcb->app_priority[i].protocolid;
76
77                 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
78                         app.priority = dcb->app_priority[i].user_prio_map;
79                         app.selector = dcb->app_priority[i].sel_field + 1;
80                         err = dcb_ieee_delapp(dev, &app);
81                 } else {
82                         app.selector = !!(dcb->app_priority[i].sel_field);
83                         err = dcb_setapp(dev, &app);
84                 }
85
86                 if (err) {
87                         dev_err(adap->pdev_dev,
88                                 "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
89                                 dcb_ver_array[dcb->dcb_version], app.selector,
90                                 app.protocol, -err);
91                         break;
92                 }
93         }
94 }
95
96 /* Reset a port's Data Center Bridging state.  Typically used after a
97  * Link Down event.
98  */
99 void cxgb4_dcb_reset(struct net_device *dev)
100 {
101         cxgb4_dcb_cleanup_apps(dev);
102         cxgb4_dcb_state_init(dev);
103 }
104
105 /* update the dcb port support, if version is IEEE then set it to
106  * FW_PORT_DCB_VER_IEEE and if DCB_CAP_DCBX_VER_CEE is already set then
107  * clear that. and if it is set to CEE then set dcb supported to
108  * DCB_CAP_DCBX_VER_CEE & if DCB_CAP_DCBX_VER_IEEE is set, clear it
109  */
110 static inline void cxgb4_dcb_update_support(struct port_dcb_info *dcb)
111 {
112         if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
113                 if (dcb->supported & DCB_CAP_DCBX_VER_CEE)
114                         dcb->supported &= ~DCB_CAP_DCBX_VER_CEE;
115                 dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
116         } else if (dcb->dcb_version == FW_PORT_DCB_VER_CEE1D01) {
117                 if (dcb->supported & DCB_CAP_DCBX_VER_IEEE)
118                         dcb->supported &= ~DCB_CAP_DCBX_VER_IEEE;
119                 dcb->supported |= DCB_CAP_DCBX_VER_CEE;
120         }
121 }
122
123 /* Finite State machine for Data Center Bridging.
124  */
125 void cxgb4_dcb_state_fsm(struct net_device *dev,
126                          enum cxgb4_dcb_state_input transition_to)
127 {
128         struct port_info *pi = netdev2pinfo(dev);
129         struct port_dcb_info *dcb = &pi->dcb;
130         struct adapter *adap = pi->adapter;
131         enum cxgb4_dcb_state current_state = dcb->state;
132
133         netdev_dbg(dev, "%s: State change from %d to %d for %s\n",
134                     __func__, dcb->state, transition_to, dev->name);
135
136         switch (current_state) {
137         case CXGB4_DCB_STATE_START: {
138                 switch (transition_to) {
139                 case CXGB4_DCB_INPUT_FW_DISABLED: {
140                         /* we're going to use Host DCB */
141                         dcb->state = CXGB4_DCB_STATE_HOST;
142                         dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
143                         break;
144                 }
145
146                 case CXGB4_DCB_INPUT_FW_ENABLED: {
147                         /* we're going to use Firmware DCB */
148                         dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
149                         dcb->supported = DCB_CAP_DCBX_LLD_MANAGED;
150                         if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE)
151                                 dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
152                         else
153                                 dcb->supported |= DCB_CAP_DCBX_VER_CEE;
154                         break;
155                 }
156
157                 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
158                         /* expected transition */
159                         break;
160                 }
161
162                 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
163                         dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
164                         break;
165                 }
166
167                 default:
168                         goto bad_state_input;
169                 }
170                 break;
171         }
172
173         case CXGB4_DCB_STATE_FW_INCOMPLETE: {
174                 if (transition_to != CXGB4_DCB_INPUT_FW_DISABLED) {
175                         /* during this CXGB4_DCB_STATE_FW_INCOMPLETE state,
176                          * check if the dcb version is changed (there can be
177                          * mismatch in default config & the negotiated switch
178                          * configuration at FW, so update the dcb support
179                          * accordingly.
180                          */
181                         cxgb4_dcb_update_support(dcb);
182                 }
183                 switch (transition_to) {
184                 case CXGB4_DCB_INPUT_FW_ENABLED: {
185                         /* we're alreaady in firmware DCB mode */
186                         break;
187                 }
188
189                 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
190                         /* we're already incomplete */
191                         break;
192                 }
193
194                 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
195                         dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
196                         dcb->enabled = 1;
197                         linkwatch_fire_event(dev);
198                         break;
199                 }
200
201                 default:
202                         goto bad_state_input;
203                 }
204                 break;
205         }
206
207         case CXGB4_DCB_STATE_FW_ALLSYNCED: {
208                 switch (transition_to) {
209                 case CXGB4_DCB_INPUT_FW_ENABLED: {
210                         /* we're alreaady in firmware DCB mode */
211                         break;
212                 }
213
214                 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
215                         /* We were successfully running with firmware DCB but
216                          * now it's telling us that it's in an "incomplete
217                          * state.  We need to reset back to a ground state
218                          * of incomplete.
219                          */
220                         cxgb4_dcb_reset(dev);
221                         dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
222                         dcb->supported = CXGB4_DCBX_FW_SUPPORT;
223                         linkwatch_fire_event(dev);
224                         break;
225                 }
226
227                 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
228                         /* we're already all sync'ed
229                          * this is only applicable for IEEE or
230                          * when another VI already completed negotiaton
231                          */
232                         dcb->enabled = 1;
233                         linkwatch_fire_event(dev);
234                         break;
235                 }
236
237                 default:
238                         goto bad_state_input;
239                 }
240                 break;
241         }
242
243         case CXGB4_DCB_STATE_HOST: {
244                 switch (transition_to) {
245                 case CXGB4_DCB_INPUT_FW_DISABLED: {
246                         /* we're alreaady in Host DCB mode */
247                         break;
248                 }
249
250                 default:
251                         goto bad_state_input;
252                 }
253                 break;
254         }
255
256         default:
257                 goto bad_state_transition;
258         }
259         return;
260
261 bad_state_input:
262         dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
263                 transition_to);
264         return;
265
266 bad_state_transition:
267         dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
268                 current_state, transition_to);
269 }
270
271 /* Handle a DCB/DCBX update message from the firmware.
272  */
273 void cxgb4_dcb_handle_fw_update(struct adapter *adap,
274                                 const struct fw_port_cmd *pcmd)
275 {
276         const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
277         int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid));
278         struct net_device *dev = adap->port[adap->chan_map[port]];
279         struct port_info *pi = netdev_priv(dev);
280         struct port_dcb_info *dcb = &pi->dcb;
281         int dcb_type = pcmd->u.dcb.pgid.type;
282         int dcb_running_version;
283
284         /* Handle Firmware DCB Control messages separately since they drive
285          * our state machine.
286          */
287         if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) {
288                 enum cxgb4_dcb_state_input input =
289                         ((pcmd->u.dcb.control.all_syncd_pkd &
290                           FW_PORT_CMD_ALL_SYNCD_F)
291                          ? CXGB4_DCB_INPUT_FW_ALLSYNCED
292                          : CXGB4_DCB_INPUT_FW_INCOMPLETE);
293
294                 if (dcb->dcb_version != FW_PORT_DCB_VER_UNKNOWN) {
295                         dcb_running_version = FW_PORT_CMD_DCB_VERSION_G(
296                                 be16_to_cpu(
297                                 pcmd->u.dcb.control.dcb_version_to_app_state));
298                         if (dcb_running_version == FW_PORT_DCB_VER_CEE1D01 ||
299                             dcb_running_version == FW_PORT_DCB_VER_IEEE) {
300                                 dcb->dcb_version = dcb_running_version;
301                                 dev_warn(adap->pdev_dev, "Interface %s is running %s\n",
302                                          dev->name,
303                                          dcb_ver_array[dcb->dcb_version]);
304                         } else {
305                                 dev_warn(adap->pdev_dev,
306                                          "Something screwed up, requested firmware for %s, but firmware returned %s instead\n",
307                                          dcb_ver_array[dcb->dcb_version],
308                                          dcb_ver_array[dcb_running_version]);
309                                 dcb->dcb_version = FW_PORT_DCB_VER_UNKNOWN;
310                         }
311                 }
312
313                 cxgb4_dcb_state_fsm(dev, input);
314                 return;
315         }
316
317         /* It's weird, and almost certainly an error, to get Firmware DCB
318          * messages when we either haven't been told whether we're going to be
319          * doing Host or Firmware DCB; and even worse when we've been told
320          * that we're doing Host DCB!
321          */
322         if (dcb->state == CXGB4_DCB_STATE_START ||
323             dcb->state == CXGB4_DCB_STATE_HOST) {
324                 dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n",
325                         dcb->state);
326                 return;
327         }
328
329         /* Now handle the general Firmware DCB update messages ...
330          */
331         switch (dcb_type) {
332         case FW_PORT_DCB_TYPE_PGID:
333                 dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid);
334                 dcb->msgs |= CXGB4_DCB_FW_PGID;
335                 break;
336
337         case FW_PORT_DCB_TYPE_PGRATE:
338                 dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported;
339                 memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate,
340                        sizeof(dcb->pgrate));
341                 memcpy(dcb->tsa, &fwdcb->pgrate.tsa,
342                        sizeof(dcb->tsa));
343                 dcb->msgs |= CXGB4_DCB_FW_PGRATE;
344                 if (dcb->msgs & CXGB4_DCB_FW_PGID)
345                         IEEE_FAUX_SYNC(dev, dcb);
346                 break;
347
348         case FW_PORT_DCB_TYPE_PRIORATE:
349                 memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate,
350                        sizeof(dcb->priorate));
351                 dcb->msgs |= CXGB4_DCB_FW_PRIORATE;
352                 break;
353
354         case FW_PORT_DCB_TYPE_PFC:
355                 dcb->pfcen = fwdcb->pfc.pfcen;
356                 dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs;
357                 dcb->msgs |= CXGB4_DCB_FW_PFC;
358                 IEEE_FAUX_SYNC(dev, dcb);
359                 break;
360
361         case FW_PORT_DCB_TYPE_APP_ID: {
362                 const struct fw_port_app_priority *fwap = &fwdcb->app_priority;
363                 int idx = fwap->idx;
364                 struct app_priority *ap = &dcb->app_priority[idx];
365
366                 struct dcb_app app = {
367                         .protocol = be16_to_cpu(fwap->protocolid),
368                 };
369                 int err;
370
371                 /* Convert from firmware format to relevant format
372                  * when using app selector
373                  */
374                 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
375                         app.selector = (fwap->sel_field + 1);
376                         app.priority = ffs(fwap->user_prio_map) - 1;
377                         err = dcb_ieee_setapp(dev, &app);
378                         IEEE_FAUX_SYNC(dev, dcb);
379                 } else {
380                         /* Default is CEE */
381                         app.selector = !!(fwap->sel_field);
382                         app.priority = fwap->user_prio_map;
383                         err = dcb_setapp(dev, &app);
384                 }
385
386                 if (err)
387                         dev_err(adap->pdev_dev,
388                                 "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
389                                 app.selector, app.protocol, app.priority, -err);
390
391                 ap->user_prio_map = fwap->user_prio_map;
392                 ap->sel_field = fwap->sel_field;
393                 ap->protocolid = be16_to_cpu(fwap->protocolid);
394                 dcb->msgs |= CXGB4_DCB_FW_APP_ID;
395                 break;
396         }
397
398         default:
399                 dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n",
400                         dcb_type);
401                 break;
402         }
403 }
404
405 /* Data Center Bridging netlink operations.
406  */
407
408
409 /* Get current DCB enabled/disabled state.
410  */
411 static u8 cxgb4_getstate(struct net_device *dev)
412 {
413         struct port_info *pi = netdev2pinfo(dev);
414
415         return pi->dcb.enabled;
416 }
417
418 /* Set DCB enabled/disabled.
419  */
420 static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
421 {
422         struct port_info *pi = netdev2pinfo(dev);
423
424         /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
425         if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
426                 pi->dcb.enabled = enabled;
427                 return 0;
428         }
429
430         /* Firmware doesn't provide any mechanism to control the DCB state.
431          */
432         if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
433                 return 1;
434
435         return 0;
436 }
437
438 static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
439                              u8 *prio_type, u8 *pgid, u8 *bw_per,
440                              u8 *up_tc_map, int local)
441 {
442         struct fw_port_cmd pcmd;
443         struct port_info *pi = netdev2pinfo(dev);
444         struct adapter *adap = pi->adapter;
445         int err;
446
447         *prio_type = *pgid = *bw_per = *up_tc_map = 0;
448
449         if (local)
450                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
451         else
452                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
453
454         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
455         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
456         if (err != FW_PORT_DCB_CFG_SUCCESS) {
457                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
458                 return;
459         }
460         *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
461
462         if (local)
463                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
464         else
465                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
466         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
467         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
468         if (err != FW_PORT_DCB_CFG_SUCCESS) {
469                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
470                         -err);
471                 return;
472         }
473
474         *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
475         *up_tc_map = (1 << tc);
476
477         /* prio_type is link strict */
478         if (*pgid != 0xF)
479                 *prio_type = 0x2;
480 }
481
482 static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
483                                 u8 *prio_type, u8 *pgid, u8 *bw_per,
484                                 u8 *up_tc_map)
485 {
486         /* tc 0 is written at MSB position */
487         return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
488                                 up_tc_map, 1);
489 }
490
491
492 static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
493                                 u8 *prio_type, u8 *pgid, u8 *bw_per,
494                                 u8 *up_tc_map)
495 {
496         /* tc 0 is written at MSB position */
497         return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
498                                 up_tc_map, 0);
499 }
500
501 static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
502                                 u8 prio_type, u8 pgid, u8 bw_per,
503                                 u8 up_tc_map)
504 {
505         struct fw_port_cmd pcmd;
506         struct port_info *pi = netdev2pinfo(dev);
507         struct adapter *adap = pi->adapter;
508         int fw_tc = 7 - tc;
509         u32 _pgid;
510         int err;
511
512         if (pgid == DCB_ATTR_VALUE_UNDEFINED)
513                 return;
514         if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
515                 return;
516
517         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
518         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
519
520         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
521         if (err != FW_PORT_DCB_CFG_SUCCESS) {
522                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
523                 return;
524         }
525
526         _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
527         _pgid &= ~(0xF << (fw_tc * 4));
528         _pgid |= pgid << (fw_tc * 4);
529         pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
530
531         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
532
533         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
534         if (err != FW_PORT_DCB_CFG_SUCCESS) {
535                 dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
536                         -err);
537                 return;
538         }
539
540         memset(&pcmd, 0, sizeof(struct fw_port_cmd));
541
542         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
543         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
544
545         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
546         if (err != FW_PORT_DCB_CFG_SUCCESS) {
547                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
548                         -err);
549                 return;
550         }
551
552         pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
553
554         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
555         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
556                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
557
558         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
559         if (err != FW_PORT_DCB_CFG_SUCCESS)
560                 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
561                         -err);
562 }
563
564 static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
565                               int local)
566 {
567         struct fw_port_cmd pcmd;
568         struct port_info *pi = netdev2pinfo(dev);
569         struct adapter *adap = pi->adapter;
570         int err;
571
572         if (local)
573                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
574         else
575                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
576
577         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
578         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
579         if (err != FW_PORT_DCB_CFG_SUCCESS) {
580                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
581                         -err);
582                 return;
583         }
584
585         *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
586 }
587
588 static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
589 {
590         return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
591 }
592
593 static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
594 {
595         return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
596 }
597
598 static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
599                                  u8 bw_per)
600 {
601         struct fw_port_cmd pcmd;
602         struct port_info *pi = netdev2pinfo(dev);
603         struct adapter *adap = pi->adapter;
604         int err;
605
606         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
607         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
608
609         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
610         if (err != FW_PORT_DCB_CFG_SUCCESS) {
611                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
612                         -err);
613                 return;
614         }
615
616         pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
617
618         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
619         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
620                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
621
622         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
623
624         if (err != FW_PORT_DCB_CFG_SUCCESS)
625                 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
626                         -err);
627 }
628
629 /* Return whether the specified Traffic Class Priority has Priority Pause
630  * Frames enabled.
631  */
632 static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
633 {
634         struct port_info *pi = netdev2pinfo(dev);
635         struct port_dcb_info *dcb = &pi->dcb;
636
637         if (!cxgb4_dcb_state_synced(dcb->state) ||
638             priority >= CXGB4_MAX_PRIORITY)
639                 *pfccfg = 0;
640         else
641                 *pfccfg = (pi->dcb.pfcen >> (7 - priority)) & 1;
642 }
643
644 /* Enable/disable Priority Pause Frames for the specified Traffic Class
645  * Priority.
646  */
647 static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
648 {
649         struct fw_port_cmd pcmd;
650         struct port_info *pi = netdev2pinfo(dev);
651         struct adapter *adap = pi->adapter;
652         int err;
653
654         if (!cxgb4_dcb_state_synced(pi->dcb.state) ||
655             priority >= CXGB4_MAX_PRIORITY)
656                 return;
657
658         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
659         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
660                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
661
662         pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
663         pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
664
665         if (pfccfg)
666                 pcmd.u.dcb.pfc.pfcen |= (1 << (7 - priority));
667         else
668                 pcmd.u.dcb.pfc.pfcen &= (~(1 << (7 - priority)));
669
670         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
671         if (err != FW_PORT_DCB_CFG_SUCCESS) {
672                 dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
673                 return;
674         }
675
676         pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
677 }
678
679 static u8 cxgb4_setall(struct net_device *dev)
680 {
681         return 0;
682 }
683
684 /* Return DCB capabilities.
685  */
686 static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
687 {
688         struct port_info *pi = netdev2pinfo(dev);
689
690         switch (cap_id) {
691         case DCB_CAP_ATTR_PG:
692         case DCB_CAP_ATTR_PFC:
693                 *caps = true;
694                 break;
695
696         case DCB_CAP_ATTR_PG_TCS:
697                 /* 8 priorities for PG represented by bitmap */
698                 *caps = 0x80;
699                 break;
700
701         case DCB_CAP_ATTR_PFC_TCS:
702                 /* 8 priorities for PFC represented by bitmap */
703                 *caps = 0x80;
704                 break;
705
706         case DCB_CAP_ATTR_GSP:
707                 *caps = true;
708                 break;
709
710         case DCB_CAP_ATTR_UP2TC:
711         case DCB_CAP_ATTR_BCN:
712                 *caps = false;
713                 break;
714
715         case DCB_CAP_ATTR_DCBX:
716                 *caps = pi->dcb.supported;
717                 break;
718
719         default:
720                 *caps = false;
721         }
722
723         return 0;
724 }
725
726 /* Return the number of Traffic Classes for the indicated Traffic Class ID.
727  */
728 static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
729 {
730         struct port_info *pi = netdev2pinfo(dev);
731
732         switch (tcs_id) {
733         case DCB_NUMTCS_ATTR_PG:
734                 if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
735                         *num = pi->dcb.pg_num_tcs_supported;
736                 else
737                         *num = 0x8;
738                 break;
739
740         case DCB_NUMTCS_ATTR_PFC:
741                 *num = 0x8;
742                 break;
743
744         default:
745                 return -EINVAL;
746         }
747
748         return 0;
749 }
750
751 /* Set the number of Traffic Classes supported for the indicated Traffic Class
752  * ID.
753  */
754 static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
755 {
756         /* Setting the number of Traffic Classes isn't supported.
757          */
758         return -ENOSYS;
759 }
760
761 /* Return whether Priority Flow Control is enabled.  */
762 static u8 cxgb4_getpfcstate(struct net_device *dev)
763 {
764         struct port_info *pi = netdev2pinfo(dev);
765
766         if (!cxgb4_dcb_state_synced(pi->dcb.state))
767                 return false;
768
769         return pi->dcb.pfcen != 0;
770 }
771
772 /* Enable/disable Priority Flow Control. */
773 static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
774 {
775         /* We can't enable/disable Priority Flow Control but we also can't
776          * return an error ...
777          */
778 }
779
780 /* Return the Application User Priority Map associated with the specified
781  * Application ID.
782  */
783 static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
784                           int peer)
785 {
786         struct port_info *pi = netdev2pinfo(dev);
787         struct adapter *adap = pi->adapter;
788         int i;
789
790         if (!cxgb4_dcb_state_synced(pi->dcb.state))
791                 return 0;
792
793         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
794                 struct fw_port_cmd pcmd;
795                 int err;
796
797                 if (peer)
798                         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
799                 else
800                         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
801
802                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
803                 pcmd.u.dcb.app_priority.idx = i;
804
805                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
806                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
807                         dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
808                                 -err);
809                         return err;
810                 }
811                 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
812                         if (pcmd.u.dcb.app_priority.sel_field == app_idtype)
813                                 return pcmd.u.dcb.app_priority.user_prio_map;
814
815                 /* exhausted app list */
816                 if (!pcmd.u.dcb.app_priority.protocolid)
817                         break;
818         }
819
820         return -EEXIST;
821 }
822
823 /* Return the Application User Priority Map associated with the specified
824  * Application ID.
825  */
826 static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
827 {
828         /* Convert app_idtype to firmware format before querying */
829         return __cxgb4_getapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
830                               app_idtype : 3, app_id, 0);
831 }
832
833 /* Write a new Application User Priority Map for the specified Application ID
834  */
835 static int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
836                           u8 app_prio)
837 {
838         struct fw_port_cmd pcmd;
839         struct port_info *pi = netdev2pinfo(dev);
840         struct adapter *adap = pi->adapter;
841         int i, err;
842
843
844         if (!cxgb4_dcb_state_synced(pi->dcb.state))
845                 return -EINVAL;
846
847         /* DCB info gets thrown away on link up */
848         if (!netif_carrier_ok(dev))
849                 return -ENOLINK;
850
851         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
852                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
853                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
854                 pcmd.u.dcb.app_priority.idx = i;
855                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
856
857                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
858                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
859                                 -err);
860                         return err;
861                 }
862                 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
863                         /* overwrite existing app table */
864                         pcmd.u.dcb.app_priority.protocolid = 0;
865                         break;
866                 }
867                 /* find first empty slot */
868                 if (!pcmd.u.dcb.app_priority.protocolid)
869                         break;
870         }
871
872         if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
873                 /* no empty slots available */
874                 dev_err(adap->pdev_dev, "DCB app table full\n");
875                 return -EBUSY;
876         }
877
878         /* write out new app table entry */
879         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
880         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
881                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
882
883         pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
884         pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
885         pcmd.u.dcb.app_priority.sel_field = app_idtype;
886         pcmd.u.dcb.app_priority.user_prio_map = app_prio;
887         pcmd.u.dcb.app_priority.idx = i;
888
889         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
890         if (err != FW_PORT_DCB_CFG_SUCCESS) {
891                 dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
892                         -err);
893                 return err;
894         }
895
896         return 0;
897 }
898
899 /* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */
900 static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
901                         u8 app_prio)
902 {
903         int ret;
904         struct dcb_app app = {
905                 .selector = app_idtype,
906                 .protocol = app_id,
907                 .priority = app_prio,
908         };
909
910         if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
911             app_idtype != DCB_APP_IDTYPE_PORTNUM)
912                 return -EINVAL;
913
914         /* Convert app_idtype to a format that firmware understands */
915         ret = __cxgb4_setapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
916                               app_idtype : 3, app_id, app_prio);
917         if (ret)
918                 return ret;
919
920         return dcb_setapp(dev, &app);
921 }
922
923 /* Return whether IEEE Data Center Bridging has been negotiated.
924  */
925 static inline int
926 cxgb4_ieee_negotiation_complete(struct net_device *dev,
927                                 enum cxgb4_dcb_fw_msgs dcb_subtype)
928 {
929         struct port_info *pi = netdev2pinfo(dev);
930         struct port_dcb_info *dcb = &pi->dcb;
931
932         if (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED)
933                 if (dcb_subtype && !(dcb->msgs & dcb_subtype))
934                         return 0;
935
936         return (cxgb4_dcb_state_synced(dcb->state) &&
937                 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
938 }
939
940 static int cxgb4_ieee_read_ets(struct net_device *dev, struct ieee_ets *ets,
941                                int local)
942 {
943         struct port_info *pi = netdev2pinfo(dev);
944         struct port_dcb_info *dcb = &pi->dcb;
945         struct adapter *adap = pi->adapter;
946         uint32_t tc_info;
947         struct fw_port_cmd pcmd;
948         int i, bwg, err;
949
950         if (!(dcb->msgs & (CXGB4_DCB_FW_PGID | CXGB4_DCB_FW_PGRATE)))
951                 return 0;
952
953         ets->ets_cap =  dcb->pg_num_tcs_supported;
954
955         if (local) {
956                 ets->willing = 1;
957                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
958         } else {
959                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
960         }
961
962         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
963         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
964         if (err != FW_PORT_DCB_CFG_SUCCESS) {
965                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
966                 return err;
967         }
968
969         tc_info = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
970
971         if (local)
972                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
973         else
974                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
975
976         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
977         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
978         if (err != FW_PORT_DCB_CFG_SUCCESS) {
979                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
980                         -err);
981                 return err;
982         }
983
984         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
985                 bwg = (tc_info >> ((7 - i) * 4)) & 0xF;
986                 ets->prio_tc[i] = bwg;
987                 ets->tc_tx_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
988                 ets->tc_rx_bw[i] = ets->tc_tx_bw[i];
989                 ets->tc_tsa[i] = pcmd.u.dcb.pgrate.tsa[i];
990         }
991
992         return 0;
993 }
994
995 static int cxgb4_ieee_get_ets(struct net_device *dev, struct ieee_ets *ets)
996 {
997         return cxgb4_ieee_read_ets(dev, ets, 1);
998 }
999
1000 /* We reuse this for peer PFC as well, as we can't have it enabled one way */
1001 static int cxgb4_ieee_get_pfc(struct net_device *dev, struct ieee_pfc *pfc)
1002 {
1003         struct port_info *pi = netdev2pinfo(dev);
1004         struct port_dcb_info *dcb = &pi->dcb;
1005
1006         memset(pfc, 0, sizeof(struct ieee_pfc));
1007
1008         if (!(dcb->msgs & CXGB4_DCB_FW_PFC))
1009                 return 0;
1010
1011         pfc->pfc_cap = dcb->pfc_num_tcs_supported;
1012         pfc->pfc_en = bitswap_1(dcb->pfcen);
1013
1014         return 0;
1015 }
1016
1017 static int cxgb4_ieee_peer_ets(struct net_device *dev, struct ieee_ets *ets)
1018 {
1019         return cxgb4_ieee_read_ets(dev, ets, 0);
1020 }
1021
1022 /* Fill in the Application User Priority Map associated with the
1023  * specified Application.
1024  * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1025  */
1026 static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
1027 {
1028         int prio;
1029
1030         if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1031                 return -EINVAL;
1032         if (!(app->selector && app->protocol))
1033                 return -EINVAL;
1034
1035         /* Try querying firmware first, use firmware format */
1036         prio = __cxgb4_getapp(dev, app->selector - 1, app->protocol, 0);
1037
1038         if (prio < 0)
1039                 prio = dcb_ieee_getapp_mask(dev, app);
1040
1041         app->priority = ffs(prio) - 1;
1042         return 0;
1043 }
1044
1045 /* Write a new Application User Priority Map for the specified Application ID.
1046  * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1047  */
1048 static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
1049 {
1050         int ret;
1051
1052         if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1053                 return -EINVAL;
1054         if (!(app->selector && app->protocol))
1055                 return -EINVAL;
1056
1057         if (!(app->selector > IEEE_8021QAZ_APP_SEL_ETHERTYPE  &&
1058               app->selector < IEEE_8021QAZ_APP_SEL_ANY))
1059                 return -EINVAL;
1060
1061         /* change selector to a format that firmware understands */
1062         ret = __cxgb4_setapp(dev, app->selector - 1, app->protocol,
1063                              (1 << app->priority));
1064         if (ret)
1065                 return ret;
1066
1067         return dcb_ieee_setapp(dev, app);
1068 }
1069
1070 /* Return our DCBX parameters.
1071  */
1072 static u8 cxgb4_getdcbx(struct net_device *dev)
1073 {
1074         struct port_info *pi = netdev2pinfo(dev);
1075
1076         /* This is already set by cxgb4_set_dcb_caps, so just return it */
1077         return pi->dcb.supported;
1078 }
1079
1080 /* Set our DCBX parameters.
1081  */
1082 static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
1083 {
1084         struct port_info *pi = netdev2pinfo(dev);
1085
1086         /* Filter out requests which exceed our capabilities.
1087          */
1088         if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
1089             != dcb_request)
1090                 return 1;
1091
1092         /* Can't enable DCB if we haven't successfully negotiated it.
1093          */
1094         if (!cxgb4_dcb_state_synced(pi->dcb.state))
1095                 return 1;
1096
1097         /* There's currently no mechanism to allow for the firmware DCBX
1098          * negotiation to be changed from the Host Driver.  If the caller
1099          * requests exactly the same parameters that we already have then
1100          * we'll allow them to be successfully "set" ...
1101          */
1102         if (dcb_request != pi->dcb.supported)
1103                 return 1;
1104
1105         pi->dcb.supported = dcb_request;
1106         return 0;
1107 }
1108
1109 static int cxgb4_getpeer_app(struct net_device *dev,
1110                              struct dcb_peer_app_info *info, u16 *app_count)
1111 {
1112         struct fw_port_cmd pcmd;
1113         struct port_info *pi = netdev2pinfo(dev);
1114         struct adapter *adap = pi->adapter;
1115         int i, err = 0;
1116
1117         if (!cxgb4_dcb_state_synced(pi->dcb.state))
1118                 return 1;
1119
1120         info->willing = 0;
1121         info->error = 0;
1122
1123         *app_count = 0;
1124         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1125                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1126                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1127                 pcmd.u.dcb.app_priority.idx = *app_count;
1128                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1129
1130                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1131                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1132                                 -err);
1133                         return err;
1134                 }
1135
1136                 /* find first empty slot */
1137                 if (!pcmd.u.dcb.app_priority.protocolid)
1138                         break;
1139         }
1140         *app_count = i;
1141         return err;
1142 }
1143
1144 static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
1145 {
1146         struct fw_port_cmd pcmd;
1147         struct port_info *pi = netdev2pinfo(dev);
1148         struct adapter *adap = pi->adapter;
1149         int i, err = 0;
1150
1151         if (!cxgb4_dcb_state_synced(pi->dcb.state))
1152                 return 1;
1153
1154         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1155                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1156                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1157                 pcmd.u.dcb.app_priority.idx = i;
1158                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1159
1160                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1161                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1162                                 -err);
1163                         return err;
1164                 }
1165
1166                 /* find first empty slot */
1167                 if (!pcmd.u.dcb.app_priority.protocolid)
1168                         break;
1169
1170                 table[i].selector = (pcmd.u.dcb.app_priority.sel_field + 1);
1171                 table[i].protocol =
1172                         be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
1173                 table[i].priority =
1174                         ffs(pcmd.u.dcb.app_priority.user_prio_map) - 1;
1175         }
1176         return err;
1177 }
1178
1179 /* Return Priority Group information.
1180  */
1181 static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
1182 {
1183         struct fw_port_cmd pcmd;
1184         struct port_info *pi = netdev2pinfo(dev);
1185         struct adapter *adap = pi->adapter;
1186         u32 pgid;
1187         int i, err;
1188
1189         /* We're always "willing" -- the Switch Fabric always dictates the
1190          * DCBX parameters to us.
1191          */
1192         pg->willing = true;
1193
1194         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1195         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
1196         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1197         if (err != FW_PORT_DCB_CFG_SUCCESS) {
1198                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
1199                 return err;
1200         }
1201         pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
1202
1203         for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1204                 pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF;
1205
1206         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1207         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
1208         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1209         if (err != FW_PORT_DCB_CFG_SUCCESS) {
1210                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
1211                         -err);
1212                 return err;
1213         }
1214
1215         for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1216                 pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
1217
1218         pg->tcs_supported = pcmd.u.dcb.pgrate.num_tcs_supported;
1219
1220         return 0;
1221 }
1222
1223 /* Return Priority Flow Control information.
1224  */
1225 static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
1226 {
1227         struct port_info *pi = netdev2pinfo(dev);
1228
1229         cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
1230
1231         /* Firmware sends this to us in a formwat that is a bit flipped version
1232          * of spec, correct it before we send it to host. This is taken care of
1233          * by bit shifting in other uses of pfcen
1234          */
1235         pfc->pfc_en = bitswap_1(pi->dcb.pfcen);
1236
1237         pfc->tcs_supported = pi->dcb.pfc_num_tcs_supported;
1238
1239         return 0;
1240 }
1241
1242 const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
1243         .ieee_getets            = cxgb4_ieee_get_ets,
1244         .ieee_getpfc            = cxgb4_ieee_get_pfc,
1245         .ieee_getapp            = cxgb4_ieee_getapp,
1246         .ieee_setapp            = cxgb4_ieee_setapp,
1247         .ieee_peer_getets       = cxgb4_ieee_peer_ets,
1248         .ieee_peer_getpfc       = cxgb4_ieee_get_pfc,
1249
1250         /* CEE std */
1251         .getstate               = cxgb4_getstate,
1252         .setstate               = cxgb4_setstate,
1253         .getpgtccfgtx           = cxgb4_getpgtccfg_tx,
1254         .getpgbwgcfgtx          = cxgb4_getpgbwgcfg_tx,
1255         .getpgtccfgrx           = cxgb4_getpgtccfg_rx,
1256         .getpgbwgcfgrx          = cxgb4_getpgbwgcfg_rx,
1257         .setpgtccfgtx           = cxgb4_setpgtccfg_tx,
1258         .setpgbwgcfgtx          = cxgb4_setpgbwgcfg_tx,
1259         .setpfccfg              = cxgb4_setpfccfg,
1260         .getpfccfg              = cxgb4_getpfccfg,
1261         .setall                 = cxgb4_setall,
1262         .getcap                 = cxgb4_getcap,
1263         .getnumtcs              = cxgb4_getnumtcs,
1264         .setnumtcs              = cxgb4_setnumtcs,
1265         .getpfcstate            = cxgb4_getpfcstate,
1266         .setpfcstate            = cxgb4_setpfcstate,
1267         .getapp                 = cxgb4_getapp,
1268         .setapp                 = cxgb4_setapp,
1269
1270         /* DCBX configuration */
1271         .getdcbx                = cxgb4_getdcbx,
1272         .setdcbx                = cxgb4_setdcbx,
1273
1274         /* peer apps */
1275         .peer_getappinfo        = cxgb4_getpeer_app,
1276         .peer_getapptable       = cxgb4_getpeerapp_tbl,
1277
1278         /* CEE peer */
1279         .cee_peer_getpg         = cxgb4_cee_peer_getpg,
1280         .cee_peer_getpfc        = cxgb4_cee_peer_getpfc,
1281 };