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