cxgb4 : Fix bug in DCB app deletion
[cascardo/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 = 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         /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
390         if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
391                 pi->dcb.enabled = enabled;
392                 return 0;
393         }
394
395         /* Firmware doesn't provide any mechanism to control the DCB state.
396          */
397         if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
398                 return 1;
399
400         return 0;
401 }
402
403 static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
404                              u8 *prio_type, u8 *pgid, u8 *bw_per,
405                              u8 *up_tc_map, int local)
406 {
407         struct fw_port_cmd pcmd;
408         struct port_info *pi = netdev2pinfo(dev);
409         struct adapter *adap = pi->adapter;
410         int err;
411
412         *prio_type = *pgid = *bw_per = *up_tc_map = 0;
413
414         if (local)
415                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
416         else
417                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
418
419         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
420         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
421         if (err != FW_PORT_DCB_CFG_SUCCESS) {
422                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
423                 return;
424         }
425         *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
426
427         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
428         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
429         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
430         if (err != FW_PORT_DCB_CFG_SUCCESS) {
431                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
432                         -err);
433                 return;
434         }
435
436         *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
437         *up_tc_map = (1 << tc);
438
439         /* prio_type is link strict */
440         *prio_type = 0x2;
441 }
442
443 static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
444                                 u8 *prio_type, u8 *pgid, u8 *bw_per,
445                                 u8 *up_tc_map)
446 {
447         return cxgb4_getpgtccfg(dev, tc, prio_type, pgid, bw_per, up_tc_map, 1);
448 }
449
450
451 static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
452                                 u8 *prio_type, u8 *pgid, u8 *bw_per,
453                                 u8 *up_tc_map)
454 {
455         return cxgb4_getpgtccfg(dev, tc, prio_type, pgid, bw_per, up_tc_map, 0);
456 }
457
458 static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
459                                 u8 prio_type, u8 pgid, u8 bw_per,
460                                 u8 up_tc_map)
461 {
462         struct fw_port_cmd pcmd;
463         struct port_info *pi = netdev2pinfo(dev);
464         struct adapter *adap = pi->adapter;
465         u32 _pgid;
466         int err;
467
468         if (pgid == DCB_ATTR_VALUE_UNDEFINED)
469                 return;
470         if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
471                 return;
472
473         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
474         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
475
476         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
477         if (err != FW_PORT_DCB_CFG_SUCCESS) {
478                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
479                 return;
480         }
481
482         _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
483         _pgid &= ~(0xF << (tc * 4));
484         _pgid |= pgid << (tc * 4);
485         pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
486
487         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
488
489         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
490         if (err != FW_PORT_DCB_CFG_SUCCESS) {
491                 dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
492                         -err);
493                 return;
494         }
495
496         memset(&pcmd, 0, sizeof(struct fw_port_cmd));
497
498         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
499         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
500
501         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
502         if (err != FW_PORT_DCB_CFG_SUCCESS) {
503                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
504                         -err);
505                 return;
506         }
507
508         pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
509
510         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
511         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
512                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
513
514         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
515         if (err != FW_PORT_DCB_CFG_SUCCESS)
516                 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
517                         -err);
518 }
519
520 static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
521                               int local)
522 {
523         struct fw_port_cmd pcmd;
524         struct port_info *pi = netdev2pinfo(dev);
525         struct adapter *adap = pi->adapter;
526         int err;
527
528         if (local)
529                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
530         else
531                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
532
533         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
534         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
535         if (err != FW_PORT_DCB_CFG_SUCCESS) {
536                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
537                         -err);
538                 return;
539         }
540
541         *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
542 }
543
544 static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
545 {
546         return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
547 }
548
549 static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
550 {
551         return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
552 }
553
554 static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
555                                  u8 bw_per)
556 {
557         struct fw_port_cmd pcmd;
558         struct port_info *pi = netdev2pinfo(dev);
559         struct adapter *adap = pi->adapter;
560         int err;
561
562         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
563         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
564
565         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
566         if (err != FW_PORT_DCB_CFG_SUCCESS) {
567                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
568                         -err);
569                 return;
570         }
571
572         pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
573
574         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
575         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
576                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
577
578         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
579
580         if (err != FW_PORT_DCB_CFG_SUCCESS)
581                 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
582                         -err);
583 }
584
585 /* Return whether the specified Traffic Class Priority has Priority Pause
586  * Frames enabled.
587  */
588 static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
589 {
590         struct port_info *pi = netdev2pinfo(dev);
591         struct port_dcb_info *dcb = &pi->dcb;
592
593         if (dcb->state != CXGB4_DCB_STATE_FW_ALLSYNCED ||
594             priority >= CXGB4_MAX_PRIORITY)
595                 *pfccfg = 0;
596         else
597                 *pfccfg = (pi->dcb.pfcen >> priority) & 1;
598 }
599
600 /* Enable/disable Priority Pause Frames for the specified Traffic Class
601  * Priority.
602  */
603 static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
604 {
605         struct fw_port_cmd pcmd;
606         struct port_info *pi = netdev2pinfo(dev);
607         struct adapter *adap = pi->adapter;
608         int err;
609
610         if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED ||
611             priority >= CXGB4_MAX_PRIORITY)
612                 return;
613
614         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
615         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
616                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
617
618         pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
619         pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
620
621         if (pfccfg)
622                 pcmd.u.dcb.pfc.pfcen |= (1 << priority);
623         else
624                 pcmd.u.dcb.pfc.pfcen &= (~(1 << priority));
625
626         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
627         if (err != FW_PORT_DCB_CFG_SUCCESS) {
628                 dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
629                 return;
630         }
631
632         pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
633 }
634
635 static u8 cxgb4_setall(struct net_device *dev)
636 {
637         return 0;
638 }
639
640 /* Return DCB capabilities.
641  */
642 static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
643 {
644         struct port_info *pi = netdev2pinfo(dev);
645
646         switch (cap_id) {
647         case DCB_CAP_ATTR_PG:
648         case DCB_CAP_ATTR_PFC:
649                 *caps = true;
650                 break;
651
652         case DCB_CAP_ATTR_PG_TCS:
653                 /* 8 priorities for PG represented by bitmap */
654                 *caps = 0x80;
655                 break;
656
657         case DCB_CAP_ATTR_PFC_TCS:
658                 /* 8 priorities for PFC represented by bitmap */
659                 *caps = 0x80;
660                 break;
661
662         case DCB_CAP_ATTR_GSP:
663                 *caps = true;
664                 break;
665
666         case DCB_CAP_ATTR_UP2TC:
667         case DCB_CAP_ATTR_BCN:
668                 *caps = false;
669                 break;
670
671         case DCB_CAP_ATTR_DCBX:
672                 *caps = pi->dcb.supported;
673                 break;
674
675         default:
676                 *caps = false;
677         }
678
679         return 0;
680 }
681
682 /* Return the number of Traffic Classes for the indicated Traffic Class ID.
683  */
684 static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
685 {
686         struct port_info *pi = netdev2pinfo(dev);
687
688         switch (tcs_id) {
689         case DCB_NUMTCS_ATTR_PG:
690                 if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
691                         *num = pi->dcb.pg_num_tcs_supported;
692                 else
693                         *num = 0x8;
694                 break;
695
696         case DCB_NUMTCS_ATTR_PFC:
697                 *num = 0x8;
698                 break;
699
700         default:
701                 return -EINVAL;
702         }
703
704         return 0;
705 }
706
707 /* Set the number of Traffic Classes supported for the indicated Traffic Class
708  * ID.
709  */
710 static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
711 {
712         /* Setting the number of Traffic Classes isn't supported.
713          */
714         return -ENOSYS;
715 }
716
717 /* Return whether Priority Flow Control is enabled.  */
718 static u8 cxgb4_getpfcstate(struct net_device *dev)
719 {
720         struct port_info *pi = netdev2pinfo(dev);
721
722         if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
723                 return false;
724
725         return pi->dcb.pfcen != 0;
726 }
727
728 /* Enable/disable Priority Flow Control. */
729 static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
730 {
731         /* We can't enable/disable Priority Flow Control but we also can't
732          * return an error ...
733          */
734 }
735
736 /* Return the Application User Priority Map associated with the specified
737  * Application ID.
738  */
739 static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
740                           int peer)
741 {
742         struct port_info *pi = netdev2pinfo(dev);
743         struct adapter *adap = pi->adapter;
744         int i;
745
746         if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
747                 return 0;
748
749         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
750                 struct fw_port_cmd pcmd;
751                 int err;
752
753                 if (peer)
754                         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
755                 else
756                         INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
757
758                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
759                 pcmd.u.dcb.app_priority.idx = i;
760
761                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
762                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
763                         dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
764                                 -err);
765                         return err;
766                 }
767                 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
768                         if (pcmd.u.dcb.app_priority.sel_field == app_idtype)
769                                 return pcmd.u.dcb.app_priority.user_prio_map;
770
771                 /* exhausted app list */
772                 if (!pcmd.u.dcb.app_priority.protocolid)
773                         break;
774         }
775
776         return -EEXIST;
777 }
778
779 /* Return the Application User Priority Map associated with the specified
780  * Application ID.
781  */
782 static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
783 {
784         return __cxgb4_getapp(dev, app_idtype, app_id, 0);
785 }
786
787 /* Write a new Application User Priority Map for the specified Application ID
788  */
789 static int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
790                           u8 app_prio)
791 {
792         struct fw_port_cmd pcmd;
793         struct port_info *pi = netdev2pinfo(dev);
794         struct adapter *adap = pi->adapter;
795         int i, err;
796
797
798         if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
799                 return -EINVAL;
800
801         /* DCB info gets thrown away on link up */
802         if (!netif_carrier_ok(dev))
803                 return -ENOLINK;
804
805         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
806                 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
807                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
808                 pcmd.u.dcb.app_priority.idx = i;
809                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
810
811                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
812                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
813                                 -err);
814                         return err;
815                 }
816                 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
817                         /* overwrite existing app table */
818                         pcmd.u.dcb.app_priority.protocolid = 0;
819                         break;
820                 }
821                 /* find first empty slot */
822                 if (!pcmd.u.dcb.app_priority.protocolid)
823                         break;
824         }
825
826         if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
827                 /* no empty slots available */
828                 dev_err(adap->pdev_dev, "DCB app table full\n");
829                 return -EBUSY;
830         }
831
832         /* write out new app table entry */
833         INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
834         if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
835                 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
836
837         pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
838         pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
839         pcmd.u.dcb.app_priority.sel_field = app_idtype;
840         pcmd.u.dcb.app_priority.user_prio_map = app_prio;
841         pcmd.u.dcb.app_priority.idx = i;
842
843         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
844         if (err != FW_PORT_DCB_CFG_SUCCESS) {
845                 dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
846                         -err);
847                 return err;
848         }
849
850         return 0;
851 }
852
853 /* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */
854 static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
855                         u8 app_prio)
856 {
857         int ret;
858         struct dcb_app app = {
859                 .selector = app_idtype,
860                 .protocol = app_id,
861                 .priority = app_prio,
862         };
863
864         if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
865             app_idtype != DCB_APP_IDTYPE_PORTNUM)
866                 return -EINVAL;
867
868         /* Convert app_idtype to a format that firmware understands */
869         ret = __cxgb4_setapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
870                               app_idtype : 3, app_id, app_prio);
871         if (ret)
872                 return ret;
873
874         return dcb_setapp(dev, &app);
875 }
876
877 /* Return whether IEEE Data Center Bridging has been negotiated.
878  */
879 static inline int
880 cxgb4_ieee_negotiation_complete(struct net_device *dev,
881                                 enum cxgb4_dcb_fw_msgs dcb_subtype)
882 {
883         struct port_info *pi = netdev2pinfo(dev);
884         struct port_dcb_info *dcb = &pi->dcb;
885
886         if (dcb_subtype && !(dcb->msgs & dcb_subtype))
887                 return 0;
888
889         return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
890                 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
891 }
892
893 /* Fill in the Application User Priority Map associated with the
894  * specified Application.
895  * Priority for IEEE dcb_app is an integer, with 0 being a valid value
896  */
897 static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
898 {
899         int prio;
900
901         if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
902                 return -EINVAL;
903         if (!(app->selector && app->protocol))
904                 return -EINVAL;
905
906         /* Try querying firmware first, use firmware format */
907         prio = __cxgb4_getapp(dev, app->selector - 1, app->protocol, 0);
908
909         if (prio < 0)
910                 prio = dcb_ieee_getapp_mask(dev, app);
911
912         app->priority = ffs(prio) - 1;
913         return 0;
914 }
915
916 /* Write a new Application User Priority Map for the specified Application ID.
917  * Priority for IEEE dcb_app is an integer, with 0 being a valid value
918  */
919 static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
920 {
921         int ret;
922
923         if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
924                 return -EINVAL;
925         if (!(app->selector && app->protocol))
926                 return -EINVAL;
927
928         if (!(app->selector > IEEE_8021QAZ_APP_SEL_ETHERTYPE  &&
929               app->selector < IEEE_8021QAZ_APP_SEL_ANY))
930                 return -EINVAL;
931
932         /* change selector to a format that firmware understands */
933         ret = __cxgb4_setapp(dev, app->selector - 1, app->protocol,
934                              (1 << app->priority));
935         if (ret)
936                 return ret;
937
938         return dcb_ieee_setapp(dev, app);
939 }
940
941 /* Return our DCBX parameters.
942  */
943 static u8 cxgb4_getdcbx(struct net_device *dev)
944 {
945         struct port_info *pi = netdev2pinfo(dev);
946
947         /* This is already set by cxgb4_set_dcb_caps, so just return it */
948         return pi->dcb.supported;
949 }
950
951 /* Set our DCBX parameters.
952  */
953 static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
954 {
955         struct port_info *pi = netdev2pinfo(dev);
956
957         /* Filter out requests which exceed our capabilities.
958          */
959         if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
960             != dcb_request)
961                 return 1;
962
963         /* Can't enable DCB if we haven't successfully negotiated it.
964          */
965         if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
966                 return 1;
967
968         /* There's currently no mechanism to allow for the firmware DCBX
969          * negotiation to be changed from the Host Driver.  If the caller
970          * requests exactly the same parameters that we already have then
971          * we'll allow them to be successfully "set" ...
972          */
973         if (dcb_request != pi->dcb.supported)
974                 return 1;
975
976         pi->dcb.supported = dcb_request;
977         return 0;
978 }
979
980 static int cxgb4_getpeer_app(struct net_device *dev,
981                              struct dcb_peer_app_info *info, u16 *app_count)
982 {
983         struct fw_port_cmd pcmd;
984         struct port_info *pi = netdev2pinfo(dev);
985         struct adapter *adap = pi->adapter;
986         int i, err = 0;
987
988         if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
989                 return 1;
990
991         info->willing = 0;
992         info->error = 0;
993
994         *app_count = 0;
995         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
996                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
997                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
998                 pcmd.u.dcb.app_priority.idx = *app_count;
999                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1000
1001                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1002                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1003                                 -err);
1004                         return err;
1005                 }
1006
1007                 /* find first empty slot */
1008                 if (!pcmd.u.dcb.app_priority.protocolid)
1009                         break;
1010         }
1011         *app_count = i;
1012         return err;
1013 }
1014
1015 static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
1016 {
1017         struct fw_port_cmd pcmd;
1018         struct port_info *pi = netdev2pinfo(dev);
1019         struct adapter *adap = pi->adapter;
1020         int i, err = 0;
1021
1022         if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
1023                 return 1;
1024
1025         for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1026                 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1027                 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1028                 pcmd.u.dcb.app_priority.idx = i;
1029                 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1030
1031                 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1032                         dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1033                                 -err);
1034                         return err;
1035                 }
1036
1037                 /* find first empty slot */
1038                 if (!pcmd.u.dcb.app_priority.protocolid)
1039                         break;
1040
1041                 table[i].selector = pcmd.u.dcb.app_priority.sel_field;
1042                 table[i].protocol =
1043                         be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
1044                 table[i].priority =
1045                         ffs(pcmd.u.dcb.app_priority.user_prio_map) - 1;
1046         }
1047         return err;
1048 }
1049
1050 /* Return Priority Group information.
1051  */
1052 static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
1053 {
1054         struct fw_port_cmd pcmd;
1055         struct port_info *pi = netdev2pinfo(dev);
1056         struct adapter *adap = pi->adapter;
1057         u32 pgid;
1058         int i, err;
1059
1060         /* We're always "willing" -- the Switch Fabric always dictates the
1061          * DCBX parameters to us.
1062          */
1063         pg->willing = true;
1064
1065         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1066         pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
1067         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1068         if (err != FW_PORT_DCB_CFG_SUCCESS) {
1069                 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
1070                 return err;
1071         }
1072         pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
1073
1074         for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1075                 pg->prio_pg[i] = (pgid >> (i * 4)) & 0xF;
1076
1077         INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1078         pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
1079         err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1080         if (err != FW_PORT_DCB_CFG_SUCCESS) {
1081                 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
1082                         -err);
1083                 return err;
1084         }
1085
1086         for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1087                 pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
1088
1089         return 0;
1090 }
1091
1092 /* Return Priority Flow Control information.
1093  */
1094 static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
1095 {
1096         struct port_info *pi = netdev2pinfo(dev);
1097
1098         cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
1099         pfc->pfc_en = pi->dcb.pfcen;
1100
1101         return 0;
1102 }
1103
1104 const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
1105         .ieee_getapp            = cxgb4_ieee_getapp,
1106         .ieee_setapp            = cxgb4_ieee_setapp,
1107
1108         /* CEE std */
1109         .getstate               = cxgb4_getstate,
1110         .setstate               = cxgb4_setstate,
1111         .getpgtccfgtx           = cxgb4_getpgtccfg_tx,
1112         .getpgbwgcfgtx          = cxgb4_getpgbwgcfg_tx,
1113         .getpgtccfgrx           = cxgb4_getpgtccfg_rx,
1114         .getpgbwgcfgrx          = cxgb4_getpgbwgcfg_rx,
1115         .setpgtccfgtx           = cxgb4_setpgtccfg_tx,
1116         .setpgbwgcfgtx          = cxgb4_setpgbwgcfg_tx,
1117         .setpfccfg              = cxgb4_setpfccfg,
1118         .getpfccfg              = cxgb4_getpfccfg,
1119         .setall                 = cxgb4_setall,
1120         .getcap                 = cxgb4_getcap,
1121         .getnumtcs              = cxgb4_getnumtcs,
1122         .setnumtcs              = cxgb4_setnumtcs,
1123         .getpfcstate            = cxgb4_getpfcstate,
1124         .setpfcstate            = cxgb4_setpfcstate,
1125         .getapp                 = cxgb4_getapp,
1126         .setapp                 = cxgb4_setapp,
1127
1128         /* DCBX configuration */
1129         .getdcbx                = cxgb4_getdcbx,
1130         .setdcbx                = cxgb4_setdcbx,
1131
1132         /* peer apps */
1133         .peer_getappinfo        = cxgb4_getpeer_app,
1134         .peer_getapptable       = cxgb4_getpeerapp_tbl,
1135
1136         /* CEE peer */
1137         .cee_peer_getpg         = cxgb4_cee_peer_getpg,
1138         .cee_peer_getpfc        = cxgb4_cee_peer_getpfc,
1139 };