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