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