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