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