i40e: base driver
[dpdk.git] / lib / librte_pmd_i40e / i40e / i40e_dcb.c
1 /*******************************************************************************
2
3 Copyright (c) 2013 - 2014, Intel Corporation
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11
12  2. Redistributions in binary form must reproduce the above copyright
13     notice, this list of conditions and the following disclaimer in the
14     documentation and/or other materials provided with the distribution.
15
16  3. Neither the name of the Intel Corporation nor the names of its
17     contributors may be used to endorse or promote products derived from
18     this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31
32 ***************************************************************************/
33
34 #include "i40e_adminq.h"
35 #include "i40e_prototype.h"
36 #include "i40e_dcb.h"
37
38 /**
39  * i40e_get_dcbx_status
40  * @hw: pointer to the hw struct
41  * @status: Embedded DCBX Engine Status
42  *
43  * Get the DCBX status from the Firmware
44  **/
45 enum i40e_status_code i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
46 {
47         u32 reg;
48
49         if (!status)
50                 return I40E_ERR_PARAM;
51
52         reg = rd32(hw, I40E_PRTDCB_GENS);
53         *status = (u16)((reg & I40E_PRTDCB_GENS_DCBX_STATUS_MASK) >>
54                         I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT);
55
56         return I40E_SUCCESS;
57 }
58
59 /**
60  * i40e_parse_ieee_etscfg_tlv
61  * @tlv: IEEE 802.1Qaz ETS CFG TLV
62  * @dcbcfg: Local store to update ETS CFG data
63  *
64  * Parses IEEE 802.1Qaz ETS CFG TLV
65  **/
66 static void i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv *tlv,
67                                        struct i40e_dcbx_config *dcbcfg)
68 {
69         struct i40e_ieee_ets_config *etscfg;
70         u8 *buf = tlv->tlvinfo;
71         u16 offset = 0;
72         u8 priority;
73         int i;
74
75         /* First Octet post subtype
76          * --------------------------
77          * |will-|CBS  | Re-  | Max |
78          * |ing  |     |served| TCs |
79          * --------------------------
80          * |1bit | 1bit|3 bits|3bits|
81          */
82         etscfg = &dcbcfg->etscfg;
83         etscfg->willing = (u8)((buf[offset] & I40E_IEEE_ETS_WILLING_MASK) >>
84                                I40E_IEEE_ETS_WILLING_SHIFT);
85         etscfg->cbs = (u8)((buf[offset] & I40E_IEEE_ETS_CBS_MASK) >>
86                            I40E_IEEE_ETS_CBS_SHIFT);
87         etscfg->maxtcs = (u8)((buf[offset] & I40E_IEEE_ETS_MAXTC_MASK) >>
88                               I40E_IEEE_ETS_MAXTC_SHIFT);
89
90         /* Move offset to Priority Assignment Table */
91         offset++;
92
93         /* Priority Assignment Table (4 octets)
94          * Octets:|    1    |    2    |    3    |    4    |
95          *        -----------------------------------------
96          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
97          *        -----------------------------------------
98          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
99          *        -----------------------------------------
100          */
101         for (i = 0; i < 4; i++) {
102                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
103                                 I40E_IEEE_ETS_PRIO_1_SHIFT);
104                 etscfg->prioritytable[i * 2] =  priority;
105                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
106                                 I40E_IEEE_ETS_PRIO_0_SHIFT);
107                 etscfg->prioritytable[i * 2 + 1] = priority;
108                 offset++;
109         }
110
111         /* TC Bandwidth Table (8 octets)
112          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
113          *        ---------------------------------
114          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
115          *        ---------------------------------
116          */
117         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
118                 etscfg->tcbwtable[i] = buf[offset++];
119
120         /* TSA Assignment Table (8 octets)
121          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
122          *        ---------------------------------
123          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
124          *        ---------------------------------
125          */
126         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
127                 etscfg->tsatable[i] = buf[offset++];
128 }
129
130 /**
131  * i40e_parse_ieee_etsrec_tlv
132  * @tlv: IEEE 802.1Qaz ETS REC TLV
133  * @dcbcfg: Local store to update ETS REC data
134  *
135  * Parses IEEE 802.1Qaz ETS REC TLV
136  **/
137 static void i40e_parse_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
138                                        struct i40e_dcbx_config *dcbcfg)
139 {
140         u8 *buf = tlv->tlvinfo;
141         u16 offset = 0;
142         u8 priority;
143         int i;
144
145         /* Move offset to priority table */
146         offset++;
147
148         /* Priority Assignment Table (4 octets)
149          * Octets:|    1    |    2    |    3    |    4    |
150          *        -----------------------------------------
151          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
152          *        -----------------------------------------
153          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
154          *        -----------------------------------------
155          */
156         for (i = 0; i < 4; i++) {
157                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
158                                 I40E_IEEE_ETS_PRIO_1_SHIFT);
159                 dcbcfg->etsrec.prioritytable[i*2] =  priority;
160                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
161                                 I40E_IEEE_ETS_PRIO_0_SHIFT);
162                 dcbcfg->etsrec.prioritytable[i*2 + 1] = priority;
163                 offset++;
164         }
165
166         /* TC Bandwidth Table (8 octets)
167          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
168          *        ---------------------------------
169          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
170          *        ---------------------------------
171          */
172         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
173                 dcbcfg->etsrec.tcbwtable[i] = buf[offset++];
174
175         /* TSA Assignment Table (8 octets)
176          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
177          *        ---------------------------------
178          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
179          *        ---------------------------------
180          */
181         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
182                 dcbcfg->etsrec.tsatable[i] = buf[offset++];
183 }
184
185 /**
186  * i40e_parse_ieee_pfccfg_tlv
187  * @tlv: IEEE 802.1Qaz PFC CFG TLV
188  * @dcbcfg: Local store to update PFC CFG data
189  *
190  * Parses IEEE 802.1Qaz PFC CFG TLV
191  **/
192 static void i40e_parse_ieee_pfccfg_tlv(struct i40e_lldp_org_tlv *tlv,
193                                        struct i40e_dcbx_config *dcbcfg)
194 {
195         u8 *buf = tlv->tlvinfo;
196
197         /* ----------------------------------------
198          * |will-|MBC  | Re-  | PFC |  PFC Enable  |
199          * |ing  |     |served| cap |              |
200          * -----------------------------------------
201          * |1bit | 1bit|2 bits|4bits| 1 octet      |
202          */
203         dcbcfg->pfc.willing = (u8)((buf[0] & I40E_IEEE_PFC_WILLING_MASK) >>
204                                    I40E_IEEE_PFC_WILLING_SHIFT);
205         dcbcfg->pfc.mbc = (u8)((buf[0] & I40E_IEEE_PFC_MBC_MASK) >>
206                                I40E_IEEE_PFC_MBC_SHIFT);
207         dcbcfg->pfc.pfccap = (u8)((buf[0] & I40E_IEEE_PFC_CAP_MASK) >>
208                                   I40E_IEEE_PFC_CAP_SHIFT);
209         dcbcfg->pfc.pfcenable = buf[1];
210 }
211
212 /**
213  * i40e_parse_ieee_app_tlv
214  * @tlv: IEEE 802.1Qaz APP TLV
215  * @dcbcfg: Local store to update APP PRIO data
216  *
217  * Parses IEEE 802.1Qaz APP PRIO TLV
218  **/
219 static void i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv *tlv,
220                                     struct i40e_dcbx_config *dcbcfg)
221 {
222         u16 typelength;
223         u16 offset = 0;
224         u16 length;
225         int i = 0;
226         u8 *buf;
227
228         typelength = I40E_NTOHS(tlv->typelength);
229         length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
230                        I40E_LLDP_TLV_LEN_SHIFT);
231         buf = tlv->tlvinfo;
232
233         /* The App priority table starts 5 octets after TLV header */
234         length -= (sizeof(tlv->ouisubtype) + 1);
235
236         /* Move offset to App Priority Table */
237         offset++;
238
239         /* Application Priority Table (3 octets)
240          * Octets:|         1          |    2    |    3    |
241          *        -----------------------------------------
242          *        |Priority|Rsrvd| Sel |    Protocol ID    |
243          *        -----------------------------------------
244          *   Bits:|23    21|20 19|18 16|15                0|
245          *        -----------------------------------------
246          */
247         while (offset < length) {
248                 dcbcfg->app[i].priority = (u8)((buf[offset] &
249                                                 I40E_IEEE_APP_PRIO_MASK) >>
250                                                I40E_IEEE_APP_PRIO_SHIFT);
251                 dcbcfg->app[i].selector = (u8)((buf[offset] &
252                                                 I40E_IEEE_APP_SEL_MASK) >>
253                                                I40E_IEEE_APP_SEL_SHIFT);
254                 dcbcfg->app[i].protocolid = (buf[offset + 1] << 0x8) |
255                                              buf[offset + 2];
256                 /* Move to next app */
257                 offset += 3;
258                 i++;
259                 if (i >= I40E_DCBX_MAX_APPS)
260                         break;
261         }
262
263         dcbcfg->numapps = i;
264 }
265
266 /**
267  * i40e_parse_ieee_etsrec_tlv
268  * @tlv: IEEE 802.1Qaz TLV
269  * @dcbcfg: Local store to update ETS REC data
270  *
271  * Get the TLV subtype and send it to parsing function
272  * based on the subtype value
273  **/
274 static void i40e_parse_ieee_tlv(struct i40e_lldp_org_tlv *tlv,
275                                 struct i40e_dcbx_config *dcbcfg)
276 {
277         u32 ouisubtype;
278         u8 subtype;
279
280         ouisubtype = I40E_NTOHL(tlv->ouisubtype);
281         subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
282                        I40E_LLDP_TLV_SUBTYPE_SHIFT);
283         switch (subtype) {
284         case I40E_IEEE_SUBTYPE_ETS_CFG:
285                 i40e_parse_ieee_etscfg_tlv(tlv, dcbcfg);
286                 break;
287         case I40E_IEEE_SUBTYPE_ETS_REC:
288                 i40e_parse_ieee_etsrec_tlv(tlv, dcbcfg);
289                 break;
290         case I40E_IEEE_SUBTYPE_PFC_CFG:
291                 i40e_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
292                 break;
293         case I40E_IEEE_SUBTYPE_APP_PRI:
294                 i40e_parse_ieee_app_tlv(tlv, dcbcfg);
295                 break;
296         default:
297                 break;
298         }
299 }
300
301 /**
302  * i40e_parse_org_tlv
303  * @tlv: Organization specific TLV
304  * @dcbcfg: Local store to update ETS REC data
305  *
306  * Currently only IEEE 802.1Qaz TLV is supported, all others
307  * will be returned
308  **/
309 static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
310                                struct i40e_dcbx_config *dcbcfg)
311 {
312         u32 ouisubtype;
313         u32 oui;
314
315         ouisubtype = I40E_NTOHL(tlv->ouisubtype);
316         oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
317                     I40E_LLDP_TLV_OUI_SHIFT);
318         switch (oui) {
319         case I40E_IEEE_8021QAZ_OUI:
320                 i40e_parse_ieee_tlv(tlv, dcbcfg);
321                 break;
322         default:
323                 break;
324         }
325 }
326
327 /**
328  * i40e_lldp_to_dcb_config
329  * @lldpmib: LLDPDU to be parsed
330  * @dcbcfg: store for LLDPDU data
331  *
332  * Parse DCB configuration from the LLDPDU
333  **/
334 enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib,
335                                     struct i40e_dcbx_config *dcbcfg)
336 {
337         enum i40e_status_code ret = I40E_SUCCESS;
338         struct i40e_lldp_org_tlv *tlv;
339         u16 type;
340         u16 length;
341         u16 typelength;
342         u16 offset = 0;
343
344         if (!lldpmib || !dcbcfg)
345                 return I40E_ERR_PARAM;
346
347         /* set to the start of LLDPDU */
348         lldpmib += I40E_LLDP_MIB_HLEN;
349         tlv = (struct i40e_lldp_org_tlv *)lldpmib;
350         while (1) {
351                 typelength = I40E_NTOHS(tlv->typelength);
352                 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
353                              I40E_LLDP_TLV_TYPE_SHIFT);
354                 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
355                                I40E_LLDP_TLV_LEN_SHIFT);
356                 offset += sizeof(typelength) + length;
357
358                 /* END TLV or beyond LLDPDU size */
359                 if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
360                         break;
361
362                 switch (type) {
363                 case I40E_TLV_TYPE_ORG:
364                         i40e_parse_org_tlv(tlv, dcbcfg);
365                         break;
366                 default:
367                         break;
368                 }
369
370                 /* Move to next TLV */
371                 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
372                                                     sizeof(tlv->typelength) +
373                                                     length);
374         }
375
376         return ret;
377 }
378
379 /**
380  * i40e_aq_get_dcb_config
381  * @hw: pointer to the hw struct
382  * @mib_type: mib type for the query
383  * @bridgetype: bridge type for the query (remote)
384  * @dcbcfg: store for LLDPDU data
385  *
386  * Query DCB configuration from the Firmware
387  **/
388 enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
389                                    u8 bridgetype,
390                                    struct i40e_dcbx_config *dcbcfg)
391 {
392         enum i40e_status_code ret = I40E_SUCCESS;
393         struct i40e_virt_mem mem;
394         u8 *lldpmib;
395
396         /* Allocate the LLDPDU */
397         ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
398         if (ret)
399                 return ret;
400
401         lldpmib = (u8 *)mem.va;
402         ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
403                                    (void *)lldpmib, I40E_LLDPDU_SIZE,
404                                    NULL, NULL, NULL);
405         if (ret)
406                 goto free_mem;
407
408         /* Parse LLDP MIB to get dcb configuration */
409         ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
410
411 free_mem:
412         i40e_free_virt_mem(hw, &mem);
413         return ret;
414 }
415
416 /**
417  * i40e_get_dcb_config
418  * @hw: pointer to the hw struct
419  *
420  * Get DCB configuration from the Firmware
421  **/
422 enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
423 {
424         enum i40e_status_code ret = I40E_SUCCESS;
425
426         /* Get Local DCB Config */
427         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
428                                      &hw->local_dcbx_config);
429         if (ret)
430                 goto out;
431
432         /* Get Remote DCB Config */
433         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
434                                      I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
435                                      &hw->remote_dcbx_config);
436 out:
437         return ret;
438 }
439
440 /**
441  * i40e_init_dcb
442  * @hw: pointer to the hw struct
443  *
444  * Update DCB configuration from the Firmware
445  **/
446 enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw)
447 {
448         enum i40e_status_code ret = I40E_SUCCESS;
449
450         if (!hw->func_caps.dcb)
451                 return ret;
452
453         /* Get DCBX status */
454         ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
455         if (ret)
456                 return ret;
457
458         /* Check the DCBX Status */
459         switch (hw->dcbx_status) {
460         case I40E_DCBX_STATUS_DONE:
461         case I40E_DCBX_STATUS_IN_PROGRESS:
462                 /* Get current DCBX configuration */
463                 ret = i40e_get_dcb_config(hw);
464                 break;
465         case I40E_DCBX_STATUS_DISABLED:
466                 return ret;
467         case I40E_DCBX_STATUS_NOT_STARTED:
468         case I40E_DCBX_STATUS_MULTIPLE_PEERS:
469         default:
470                 break;
471         }
472
473         /* Configure the LLDP MIB change event */
474         ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
475         if (ret)
476                 return ret;
477
478         return ret;
479 }
480 #ifdef I40E_DCB_SW
481
482 /**
483  * i40e_dcbx_event_handler
484  * @hw: pointer to the hw struct
485  * @e: event data to be processed (LLDPDU)
486  *
487  * Process LLDP MIB Change event from the Firmware
488  **/
489 enum i40e_status_code i40e_process_lldp_event(struct i40e_hw *hw,
490                                               struct i40e_arq_event_info *e)
491 {
492         enum i40e_status_code ret = I40E_SUCCESS;
493         UNREFERENCED_2PARAMETER(hw, e);
494
495         return ret;
496 }
497
498 /**
499  * i40e_dcb_hw_rx_fifo_config
500  * @hw: pointer to the hw struct
501  * @ets_mode: Strict Priority or Round Robin mode
502  * @non_ets_mode: Strict Priority or Round Robin
503  * @max_exponent: Exponent to calculate max refill credits
504  * @lltc_map: Low latency TC bitmap
505  *
506  * Configure HW Rx FIFO as part of DCB configuration.
507  **/
508 void i40e_dcb_hw_rx_fifo_config(struct i40e_hw *hw,
509                                 enum i40e_dcb_arbiter_mode ets_mode,
510                                 enum i40e_dcb_arbiter_mode non_ets_mode,
511                                 u32 max_exponent,
512                                 u8 lltc_map)
513 {
514         u32 reg = 0;
515
516         reg = rd32(hw, I40E_PRTDCB_RETSC);
517
518         reg &= ~I40E_PRTDCB_RETSC_ETS_MODE_MASK;
519         reg |= ((u32)ets_mode << I40E_PRTDCB_RETSC_ETS_MODE_SHIFT) &
520                 I40E_PRTDCB_RETSC_ETS_MODE_MASK;
521
522         reg &= ~I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK;
523         reg |= ((u32)non_ets_mode << I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT) &
524                 I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK;
525
526         reg &= ~I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK;
527         reg |= (max_exponent << I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT) &
528                 I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK;
529
530         reg &= ~I40E_PRTDCB_RETSC_LLTC_MASK;
531         reg |= (lltc_map << I40E_PRTDCB_RETSC_LLTC_SHIFT) &
532                 I40E_PRTDCB_RETSC_LLTC_MASK;
533         wr32(hw, I40E_PRTDCB_RETSC, reg);
534 }
535
536 /**
537  * i40e_dcb_hw_rx_cmd_monitor_config
538  * @hw: pointer to the hw struct
539  * @num_tc: Total number of traffic class
540  * @num_ports: Total number of ports on device
541  *
542  * Configure HW Rx command monitor as part of DCB configuration.
543  **/
544 void i40e_dcb_hw_rx_cmd_monitor_config(struct i40e_hw *hw,
545                                        u8 num_tc, u8 num_ports)
546 {
547         u32 threshold = 0;
548         u32 fifo_size = 0;
549         u32 reg = 0;
550
551         /* Set the threshold and fifo_size based on number of ports */
552         switch (num_ports) {
553         case 1:
554                 threshold = 0xF;
555                 fifo_size = 0x10;
556                 break;
557         case 2:
558                 if (num_tc > 4) {
559                         threshold = 0xC;
560                         fifo_size = 0x8;
561                 } else {
562                         threshold = 0xF;
563                         fifo_size = 0x10;
564                 }
565                 break;
566         case 4:
567                 if (num_tc > 4) {
568                         threshold = 0x6;
569                         fifo_size = 0x4;
570                 } else {
571                         threshold = 0x9;
572                         fifo_size = 0x8;
573                 }
574                 break;
575         }
576
577
578         reg = rd32(hw, I40E_PRTDCB_RPPMC);
579         reg &= ~I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK;
580         reg |= (fifo_size << I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT) &
581                 I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK;
582         wr32(hw, I40E_PRTDCB_RPPMC, reg);
583 }
584
585 /**
586  * i40e_dcb_hw_pfc_config
587  * @hw: pointer to the hw struct
588  * @pfc_en: Bitmap of PFC enabled priorities
589  * @prio_tc: priority to tc assignment indexed by priority
590  *
591  * Configure HW Priority Flow Controller as part of DCB configuration.
592  **/
593 void i40e_dcb_hw_pfc_config(struct i40e_hw *hw,
594                             u8 pfc_en, u8 *prio_tc)
595 {
596         u16 pause_time = I40E_DEFAULT_PAUSE_TIME;
597         u16 refresh_time = pause_time/2;
598         u8 first_pfc_prio = 0;
599         u32 link_speed = 0;
600         u8 num_pfc_tc = 0;
601         u8 tc2pfc = 0;
602         u32 reg = 0;
603         u8 i;
604
605         /* Get Number of PFC TCs and TC2PFC map */
606         for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
607                 if (pfc_en & (1 << i)) {
608                         if (!first_pfc_prio)
609                                 first_pfc_prio = i;
610                         /* Set bit for the PFC TC */
611                         tc2pfc |= 1 << prio_tc[i];
612                         num_pfc_tc++;
613                 }
614         }
615
616         link_speed = hw->phy.link_info.link_speed;
617         switch (link_speed) {
618         case I40E_LINK_SPEED_10GB:
619                 reg = rd32(hw, I40E_PRTDCB_MFLCN);
620                 reg |= (1 << I40E_PRTDCB_MFLCN_DPF_SHIFT) &
621                         I40E_PRTDCB_MFLCN_DPF_MASK;
622                 reg &= ~I40E_PRTDCB_MFLCN_RFCE_MASK;
623                 reg &= ~I40E_PRTDCB_MFLCN_RPFCE_MASK;
624                 if (pfc_en) {
625                         reg |= (1 << I40E_PRTDCB_MFLCN_RPFCM_SHIFT) &
626                                 I40E_PRTDCB_MFLCN_RPFCM_MASK;
627                         reg |= ((u32)pfc_en << I40E_PRTDCB_MFLCN_RPFCE_SHIFT) &
628                                 I40E_PRTDCB_MFLCN_RPFCE_MASK;
629                 }
630                 wr32(hw, I40E_PRTDCB_MFLCN, reg);
631
632                 reg = rd32(hw, I40E_PRTDCB_FCCFG);
633                 reg &= ~I40E_PRTDCB_FCCFG_TFCE_MASK;
634                 if (pfc_en)
635                         reg |= (2 << I40E_PRTDCB_FCCFG_TFCE_SHIFT) &
636                                 I40E_PRTDCB_FCCFG_TFCE_MASK;
637                 wr32(hw, I40E_PRTDCB_FCCFG, reg);
638
639                 /* FCTTV and FCRTV to be set by default */
640                 break;
641         case I40E_LINK_SPEED_40GB:
642                 reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP);
643                 reg &= ~I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_MASK;
644                 wr32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP, reg);
645
646                 reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP);
647                 reg &= ~I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_MASK;
648                 reg |= (1 <<
649                            I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT) &
650                         I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_MASK;
651                 wr32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP, reg);
652
653                 reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE);
654                 reg &= ~I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_MASK;
655                 reg |= ((u32)pfc_en <<
656                            I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT) &
657                         I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_MASK;
658                 wr32(hw, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE, reg);
659
660                 reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE);
661                 reg &= ~I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_MASK;
662                 reg |= ((u32)pfc_en <<
663                            I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT) &
664                         I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_MASK;
665                 wr32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE, reg);
666
667                 for (i = 0; i < I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MAX_INDEX; i++) {
668                         reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(i));
669                         reg &= ~I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK;
670                         if (pfc_en) {
671                                 reg |= ((u32)refresh_time <<
672                                         I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT) &
673                                         I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK;
674                         }
675                         wr32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(i), reg);
676                 }
677                 /*
678                  * PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA default value is 0xFFFF
679                  * for all user priorities
680                  */
681                 break;
682         }
683
684         reg = rd32(hw, I40E_PRTDCB_TC2PFC);
685         reg &= ~I40E_PRTDCB_TC2PFC_TC2PFC_MASK;
686         reg |= ((u32)tc2pfc << I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT) &
687                 I40E_PRTDCB_TC2PFC_TC2PFC_MASK;
688         wr32(hw, I40E_PRTDCB_TC2PFC, reg);
689
690         reg = rd32(hw, I40E_PRTDCB_RUP);
691         reg &= ~I40E_PRTDCB_RUP_NOVLANUP_MASK;
692         reg |= ((u32)first_pfc_prio << I40E_PRTDCB_RUP_NOVLANUP_SHIFT) &
693                  I40E_PRTDCB_RUP_NOVLANUP_MASK;
694         wr32(hw, I40E_PRTDCB_RUP, reg);
695
696         reg = rd32(hw, I40E_PRTDCB_TDPMC);
697         reg &= ~I40E_PRTDCB_TDPMC_TCPM_MODE_MASK;
698         if (num_pfc_tc > 2) {
699                 reg |= (1 << I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT) &
700                         I40E_PRTDCB_TDPMC_TCPM_MODE_MASK;
701         }
702         wr32(hw, I40E_PRTDCB_TDPMC, reg);
703
704         reg = rd32(hw, I40E_PRTDCB_TCPMC);
705         reg &= ~I40E_PRTDCB_TCPMC_TCPM_MODE_MASK;
706         if (num_pfc_tc > 2) {
707                 reg |= (1 << I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT) &
708                         I40E_PRTDCB_TCPMC_TCPM_MODE_MASK;
709         }
710         wr32(hw, I40E_PRTDCB_TCPMC, reg);
711 }
712
713 /**
714  * i40e_dcb_hw_set_num_tc
715  * @hw: pointer to the hw struct
716  * @num_tc: number of traffic classes
717  *
718  * Configure number of traffic classes in HW
719  **/
720 void i40e_dcb_hw_set_num_tc(struct i40e_hw *hw, u8 num_tc)
721 {
722         u32 reg = rd32(hw, I40E_PRTDCB_GENC);
723
724         reg &= ~I40E_PRTDCB_GENC_NUMTC_MASK;
725         reg |= ((u32)num_tc << I40E_PRTDCB_GENC_NUMTC_SHIFT) &
726                 I40E_PRTDCB_GENC_NUMTC_MASK;
727         wr32(hw, I40E_PRTDCB_GENC, reg);
728 }
729
730 /**
731  * i40e_dcb_hw_get_num_tc
732  * @hw: pointer to the hw struct
733  *
734  * Returns number of traffic classes configured in HW
735  **/
736 u8 i40e_dcb_hw_get_num_tc(struct i40e_hw *hw)
737 {
738         u32 reg = rd32(hw, I40E_PRTDCB_GENC);
739
740         return (reg >> I40E_PRTDCB_GENC_NUMTC_SHIFT) &
741                 I40E_PRTDCB_GENC_NUMTC_MASK;
742 }
743
744 /**
745  * i40e_dcb_hw_rx_ets_bw_config
746  * @hw: pointer to the hw struct
747  * @bw_share: Bandwidth share indexed per traffic class
748  * @mode: Strict Priority or Round Robin mode between UP sharing same
749  * traffic class
750  * @prio_type: TC is ETS enabled or strict priority
751  *
752  * Configure HW Rx ETS bandwidth as part of DCB configuration.
753  **/
754 void i40e_dcb_hw_rx_ets_bw_config(struct i40e_hw *hw, u8 *bw_share,
755                                   u8 *mode, u8 *prio_type)
756 {
757         u32 reg = 0;
758         u8 i = 0;
759
760         for (i = 0; i <= I40E_PRTDCB_RETSTCC_MAX_INDEX; i++) {
761                 reg = rd32(hw, I40E_PRTDCB_RETSTCC(i));
762                 reg &= ~(I40E_PRTDCB_RETSTCC_BWSHARE_MASK     |
763                          I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK |
764                          I40E_PRTDCB_RETSTCC_ETSTC_SHIFT);
765                 reg |= ((u32)bw_share[i] << I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT) &
766                          I40E_PRTDCB_RETSTCC_BWSHARE_MASK;
767                 reg |= ((u32)mode[i] << I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT) &
768                          I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK;
769                 reg |= ((u32)prio_type[i] << I40E_PRTDCB_RETSTCC_ETSTC_SHIFT) &
770                          I40E_PRTDCB_RETSTCC_ETSTC_MASK;
771                 wr32(hw, I40E_PRTDCB_RETSTCC(i), reg);
772         }
773 }
774
775 /**
776  * i40e_dcb_hw_rx_ets_bw_config
777  * @hw: pointer to the hw struct
778  * @prio_tc: priority to tc assignment indexed by priority
779  *
780  * Configure HW Rx UP2TC map as part of DCB configuration.
781  **/
782 void i40e_dcb_hw_rx_up2tc_config(struct i40e_hw *hw, u8 *prio_tc)
783 {
784         u32 reg = 0;
785
786 #define I40E_UP2TC_REG(val, i) \
787                 ((val << I40E_PRTDCB_RUP2TC_UP##i##TC_SHIFT) & \
788                   I40E_PRTDCB_RUP2TC_UP##i##TC_MASK)
789
790         reg = rd32(hw, I40E_PRTDCB_RUP2TC);
791         reg |= I40E_UP2TC_REG(prio_tc[0], 0);
792         reg |= I40E_UP2TC_REG(prio_tc[1], 1);
793         reg |= I40E_UP2TC_REG(prio_tc[2], 2);
794         reg |= I40E_UP2TC_REG(prio_tc[3], 3);
795         reg |= I40E_UP2TC_REG(prio_tc[4], 4);
796         reg |= I40E_UP2TC_REG(prio_tc[5], 5);
797         reg |= I40E_UP2TC_REG(prio_tc[6], 6);
798         reg |= I40E_UP2TC_REG(prio_tc[7], 7);
799         wr32(hw, I40E_PRTDCB_RUP2TC, reg);
800 }
801
802 /**
803  * i40e_dcb_hw_calculate_pool_sizes
804  * @hw: pointer to the hw struct
805  * @num_ports: Number of available ports on the device
806  * @eee_enabled: EEE enabled for the given port
807  * @pfc_en: Bit map of PFC enabled traffic classes
808  * @mfs_tc: Array of max frame size for each traffic class
809  *
810  * Calculate the shared and dedicated per TC pool sizes,
811  * watermarks and threshold values.
812  **/
813 void i40e_dcb_hw_calculate_pool_sizes(struct i40e_hw *hw,
814                                       u8 num_ports, bool eee_enabled,
815                                       u8 pfc_en, u32 *mfs_tc,
816                                       struct i40e_rx_pb_config *pb_cfg)
817 {
818         u32 pool_size[I40E_MAX_TRAFFIC_CLASS];
819         u32 high_wm[I40E_MAX_TRAFFIC_CLASS];
820         u32 low_wm[I40E_MAX_TRAFFIC_CLASS];
821         int shared_pool_size = 0; /* Need signed variable */
822         u32 total_pool_size = 0;
823         u32 port_pb_size = 0;
824         u32 mfs_max = 0;
825         u32 pcirtt = 0;
826         u8 i = 0;
827
828         /* Get the MFS(max) for the port */
829         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
830                 if (mfs_tc[i] > mfs_max)
831                         mfs_max = mfs_tc[i];
832         }
833
834         pcirtt = I40E_BT2B(I40E_PCIRTT_LINK_SPEED_10G);
835
836         /* Calculate effective Rx PB size per port */
837         port_pb_size = (I40E_DEVICE_RPB_SIZE/num_ports);
838         if (eee_enabled)
839                 port_pb_size -= I40E_BT2B(I40E_EEE_TX_LPI_EXIT_TIME);
840         port_pb_size -= mfs_max;
841
842         /* Step 1 Calculating tc pool/shared pool sizes and watermarks */
843         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
844                 if (pfc_en & (1 << i)) {
845                         low_wm[i] = (2 * mfs_tc[i]) + pcirtt;
846                         high_wm[i] = low_wm[i];
847                         high_wm[i] += ((mfs_max > I40E_MAX_FRAME_SIZE)
848                                         ? mfs_max : I40E_MAX_FRAME_SIZE);
849                         pool_size[i] = high_wm[i];
850                         pool_size[i] += I40E_BT2B(I40E_STD_DV_TC(mfs_max,
851                                                                 mfs_tc[i]));
852                 } else {
853                         low_wm[i] = 0;
854                         pool_size[i] = (2 * mfs_tc[i]) + pcirtt;
855                         high_wm[i] = pool_size[i];
856                 }
857                 total_pool_size += pool_size[i];
858         }
859
860         shared_pool_size = port_pb_size - total_pool_size;
861         if (shared_pool_size > 0) {
862                 pb_cfg->shared_pool_size = shared_pool_size;
863                 pb_cfg->shared_pool_high_wm = shared_pool_size;
864                 pb_cfg->shared_pool_low_wm = 0;
865                 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
866                         pb_cfg->shared_pool_low_thresh[i] = 0;
867                         pb_cfg->shared_pool_high_thresh[i] = shared_pool_size;
868                         pb_cfg->tc_pool_size[i] = pool_size[i];
869                         pb_cfg->tc_pool_high_wm[i] = high_wm[i];
870                         pb_cfg->tc_pool_low_wm[i] = low_wm[i];
871                 }
872
873         } else {
874                 i40e_debug(hw, I40E_DEBUG_DCB,
875                            "The shared pool size for the port is negative %d.\n",
876                            shared_pool_size);
877         }
878 }
879
880 /**
881  * i40e_dcb_hw_rx_pb_config
882  * @hw: pointer to the hw struct
883  * @old_pb_cfg: Existing Rx Packet buffer configuration
884  * @new_pb_cfg: New Rx Packet buffer configuration
885  *
886  * Program the Rx Packet Buffer registers.
887  **/
888 void i40e_dcb_hw_rx_pb_config(struct i40e_hw *hw,
889                               struct i40e_rx_pb_config *old_pb_cfg,
890                               struct i40e_rx_pb_config *new_pb_cfg)
891 {
892         u32 old_val = 0;
893         u32 new_val = 0;
894         u32 reg = 0;
895         u8 i = 0;
896
897         /* Program the shared pool low water mark per port if decreasing */
898         old_val = old_pb_cfg->shared_pool_low_wm;
899         new_val = new_pb_cfg->shared_pool_low_wm;
900         if (new_val < old_val) {
901                 reg = rd32(hw, I40E_PRTRPB_SLW);
902                 reg &= ~I40E_PRTRPB_SLW_SLW_MASK;
903                 reg |= (new_val << I40E_PRTRPB_SLW_SLW_SHIFT) &
904                         I40E_PRTRPB_SLW_SLW_MASK;
905                 wr32(hw, I40E_PRTRPB_SLW, reg);
906         }
907
908         /* Program the shared pool low threshold and tc pool
909          * low water mark per TC that are decreasing.
910          */
911         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
912                 old_val = old_pb_cfg->shared_pool_low_thresh[i];
913                 new_val = new_pb_cfg->shared_pool_low_thresh[i];
914                 if (new_val < old_val) {
915                         reg = rd32(hw, I40E_PRTRPB_SLT(i));
916                         reg &= ~I40E_PRTRPB_SLT_SLT_TCN_MASK;
917                         reg |= (new_val << I40E_PRTRPB_SLT_SLT_TCN_SHIFT) &
918                                 I40E_PRTRPB_SLT_SLT_TCN_MASK;
919                         wr32(hw, I40E_PRTRPB_SLT(i), reg);
920                 }
921
922                 old_val = old_pb_cfg->tc_pool_low_wm[i];
923                 new_val = new_pb_cfg->tc_pool_low_wm[i];
924                 if (new_val < old_val) {
925                         reg = rd32(hw, I40E_PRTRPB_DLW(i));
926                         reg &= ~I40E_PRTRPB_DLW_DLW_TCN_MASK;
927                         reg |= (new_val << I40E_PRTRPB_DLW_DLW_TCN_SHIFT) &
928                                 I40E_PRTRPB_DLW_DLW_TCN_MASK;
929                         wr32(hw, I40E_PRTRPB_DLW(i), reg);
930                 }
931         }
932
933         /* Program the shared pool high water mark per port if decreasing */
934         old_val = old_pb_cfg->shared_pool_high_wm;
935         new_val = new_pb_cfg->shared_pool_high_wm;
936         if (new_val < old_val) {
937                 reg = rd32(hw, I40E_PRTRPB_SHW);
938                 reg &= ~I40E_PRTRPB_SHW_SHW_MASK;
939                 reg |= (new_val << I40E_PRTRPB_SHW_SHW_SHIFT) &
940                         I40E_PRTRPB_SHW_SHW_MASK;
941                 wr32(hw, I40E_PRTRPB_SHW, reg);
942         }
943
944         /* Program the shared pool high threshold and tc pool
945          * high water mark per TC that are decreasing.
946          */
947         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
948                 old_val = old_pb_cfg->shared_pool_high_thresh[i];
949                 new_val = new_pb_cfg->shared_pool_high_thresh[i];
950                 if (new_val < old_val) {
951                         reg = rd32(hw, I40E_PRTRPB_SHT(i));
952                         reg &= ~I40E_PRTRPB_SHT_SHT_TCN_MASK;
953                         reg |= (new_val << I40E_PRTRPB_SHT_SHT_TCN_SHIFT) &
954                                 I40E_PRTRPB_SHT_SHT_TCN_MASK;
955                         wr32(hw, I40E_PRTRPB_SHT(i), reg);
956                 }
957
958                 old_val = old_pb_cfg->tc_pool_high_wm[i];
959                 new_val = new_pb_cfg->tc_pool_high_wm[i];
960                 if (new_val < old_val) {
961                         reg = rd32(hw, I40E_PRTRPB_DHW(i));
962                         reg &= ~I40E_PRTRPB_DHW_DHW_TCN_MASK;
963                         reg |= (new_val << I40E_PRTRPB_DHW_DHW_TCN_SHIFT) &
964                                 I40E_PRTRPB_DHW_DHW_TCN_MASK;
965                         wr32(hw, I40E_PRTRPB_DHW(i), reg);
966                 }
967         }
968
969         /* Write Dedicated Pool Sizes per TC */
970         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
971                 new_val = new_pb_cfg->tc_pool_size[i];
972                 reg = rd32(hw, I40E_PRTRPB_DPS(i));
973                 reg &= ~I40E_PRTRPB_DPS_DPS_TCN_MASK;
974                 reg |= (new_val << I40E_PRTRPB_DPS_DPS_TCN_SHIFT) &
975                         I40E_PRTRPB_DPS_DPS_TCN_MASK;
976                 wr32(hw, I40E_PRTRPB_DPS(i), reg);
977         }
978
979         /* Write Shared Pool Size per port */
980         new_val = new_pb_cfg->shared_pool_size;
981         reg = rd32(hw, I40E_PRTRPB_SPS);
982         reg &= ~I40E_PRTRPB_SPS_SPS_MASK;
983         reg |= (new_val << I40E_PRTRPB_SPS_SPS_SHIFT) &
984                 I40E_PRTRPB_SPS_SPS_MASK;
985         wr32(hw, I40E_PRTRPB_SPS, reg);
986
987         /* Program the shared pool low water mark per port if increasing */
988         old_val = old_pb_cfg->shared_pool_low_wm;
989         new_val = new_pb_cfg->shared_pool_low_wm;
990         if (new_val > old_val) {
991                 reg = rd32(hw, I40E_PRTRPB_SLW);
992                 reg &= ~I40E_PRTRPB_SLW_SLW_MASK;
993                 reg |= (new_val << I40E_PRTRPB_SLW_SLW_SHIFT) &
994                         I40E_PRTRPB_SLW_SLW_MASK;
995                 wr32(hw, I40E_PRTRPB_SLW, reg);
996         }
997
998         /* Program the shared pool low threshold and tc pool
999          * low water mark per TC that are increasing.
1000          */
1001         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1002                 old_val = old_pb_cfg->shared_pool_low_thresh[i];
1003                 new_val = new_pb_cfg->shared_pool_low_thresh[i];
1004                 if (new_val > old_val) {
1005                         reg = rd32(hw, I40E_PRTRPB_SLT(i));
1006                         reg &= ~I40E_PRTRPB_SLT_SLT_TCN_MASK;
1007                         reg |= (new_val << I40E_PRTRPB_SLT_SLT_TCN_SHIFT) &
1008                                 I40E_PRTRPB_SLT_SLT_TCN_MASK;
1009                         wr32(hw, I40E_PRTRPB_SLT(i), reg);
1010                 }
1011
1012                 old_val = old_pb_cfg->tc_pool_low_wm[i];
1013                 new_val = new_pb_cfg->tc_pool_low_wm[i];
1014                 if (new_val > old_val) {
1015                         reg = rd32(hw, I40E_PRTRPB_DLW(i));
1016                         reg &= ~I40E_PRTRPB_DLW_DLW_TCN_MASK;
1017                         reg |= (new_val << I40E_PRTRPB_DLW_DLW_TCN_SHIFT) &
1018                                 I40E_PRTRPB_DLW_DLW_TCN_MASK;
1019                         wr32(hw, I40E_PRTRPB_DLW(i), reg);
1020                 }
1021         }
1022
1023         /* Program the shared pool high water mark per port if increasing */
1024         old_val = old_pb_cfg->shared_pool_high_wm;
1025         new_val = new_pb_cfg->shared_pool_high_wm;
1026         if (new_val > old_val) {
1027                 reg = rd32(hw, I40E_PRTRPB_SHW);
1028                 reg &= ~I40E_PRTRPB_SHW_SHW_MASK;
1029                 reg |= (new_val << I40E_PRTRPB_SHW_SHW_SHIFT) &
1030                         I40E_PRTRPB_SHW_SHW_MASK;
1031                 wr32(hw, I40E_PRTRPB_SHW, reg);
1032         }
1033
1034         /* Program the shared pool high threshold and tc pool
1035          * high water mark per TC that are increasing.
1036          */
1037         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1038                 old_val = old_pb_cfg->shared_pool_high_thresh[i];
1039                 new_val = new_pb_cfg->shared_pool_high_thresh[i];
1040                 if (new_val > old_val) {
1041                         reg = rd32(hw, I40E_PRTRPB_SHT(i));
1042                         reg &= ~I40E_PRTRPB_SHT_SHT_TCN_MASK;
1043                         reg |= (new_val << I40E_PRTRPB_SHT_SHT_TCN_SHIFT) &
1044                                 I40E_PRTRPB_SHT_SHT_TCN_MASK;
1045                         wr32(hw, I40E_PRTRPB_SHT(i), reg);
1046                 }
1047
1048                 old_val = old_pb_cfg->tc_pool_high_wm[i];
1049                 new_val = new_pb_cfg->tc_pool_high_wm[i];
1050                 if (new_val > old_val) {
1051                         reg = rd32(hw, I40E_PRTRPB_DHW(i));
1052                         reg &= ~I40E_PRTRPB_DHW_DHW_TCN_MASK;
1053                         reg |= (new_val << I40E_PRTRPB_DHW_DHW_TCN_SHIFT) &
1054                                 I40E_PRTRPB_DHW_DHW_TCN_MASK;
1055                         wr32(hw, I40E_PRTRPB_DHW(i), reg);
1056                 }
1057         }
1058 }
1059
1060 /**
1061  * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
1062  * @hw: pointer to the HW structure
1063  * @lldp_cfg: pointer to hold lldp configuration variables
1064  *
1065  * Reads the LLDP configuration data from NVM
1066  **/
1067 enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
1068                                          struct i40e_lldp_variables *lldp_cfg)
1069 {
1070         enum i40e_status_code ret = I40E_SUCCESS;
1071         struct i40e_emp_settings_module emp_ptr;
1072         u32 offset = 0;
1073
1074         if (!lldp_cfg)
1075                 return I40E_ERR_PARAM;
1076
1077         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1078         if (ret != I40E_SUCCESS)
1079                 goto err_lldp_cfg;
1080
1081         ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, 0,
1082                                sizeof(emp_ptr), (u8 *)&emp_ptr,
1083                                true, NULL);
1084         i40e_release_nvm(hw);
1085         if (ret != I40E_SUCCESS)
1086                 goto err_lldp_cfg;
1087
1088         /* Calculate the byte offset for LLDP config pointer */
1089         offset = (2 * emp_ptr.lldp_cfg_ptr);
1090         offset += (2 * I40E_NVM_LLDP_CFG_PTR);
1091         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1092         if (ret != I40E_SUCCESS)
1093                 goto err_lldp_cfg;
1094
1095         ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
1096                                sizeof(struct i40e_lldp_variables),
1097                                (u8 *)lldp_cfg,
1098                                true, NULL);
1099         i40e_release_nvm(hw);
1100
1101 err_lldp_cfg:
1102         return ret;
1103 }
1104 #endif /* I40E_DCB_SW */