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