18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2013-2014 Chelsio Communications. All rights reserved. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Written by Anish Bhatt (anish@chelsio.com) 68c2ecf20Sopenharmony_ci * Casey Leedom (leedom@chelsio.com) 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "cxgb4.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* DCBx version control 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ciconst char * const dcb_ver_array[] = { 148c2ecf20Sopenharmony_ci "Unknown", 158c2ecf20Sopenharmony_ci "DCBx-CIN", 168c2ecf20Sopenharmony_ci "DCBx-CEE 1.01", 178c2ecf20Sopenharmony_ci "DCBx-IEEE", 188c2ecf20Sopenharmony_ci "", "", "", 198c2ecf20Sopenharmony_ci "Auto Negotiated" 208c2ecf20Sopenharmony_ci}; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic inline bool cxgb4_dcb_state_synced(enum cxgb4_dcb_state state) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci if (state == CXGB4_DCB_STATE_FW_ALLSYNCED || 258c2ecf20Sopenharmony_ci state == CXGB4_DCB_STATE_HOST) 268c2ecf20Sopenharmony_ci return true; 278c2ecf20Sopenharmony_ci else 288c2ecf20Sopenharmony_ci return false; 298c2ecf20Sopenharmony_ci} 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* Initialize a port's Data Center Bridging state. 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_civoid cxgb4_dcb_state_init(struct net_device *dev) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 368c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 378c2ecf20Sopenharmony_ci int version_temp = dcb->dcb_version; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci memset(dcb, 0, sizeof(struct port_dcb_info)); 408c2ecf20Sopenharmony_ci dcb->state = CXGB4_DCB_STATE_START; 418c2ecf20Sopenharmony_ci if (version_temp) 428c2ecf20Sopenharmony_ci dcb->dcb_version = version_temp; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci netdev_dbg(dev, "%s: Initializing DCB state for port[%d]\n", 458c2ecf20Sopenharmony_ci __func__, pi->port_id); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_civoid cxgb4_dcb_version_init(struct net_device *dev) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 518c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci /* Any writes here are only done on kernels that exlicitly need 548c2ecf20Sopenharmony_ci * a specific version, say < 2.6.38 which only support CEE 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_ci dcb->dcb_version = FW_PORT_DCB_VER_AUTO; 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic void cxgb4_dcb_cleanup_apps(struct net_device *dev) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 628c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 638c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 648c2ecf20Sopenharmony_ci struct dcb_app app; 658c2ecf20Sopenharmony_ci int i, err; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci /* zero priority implies remove */ 688c2ecf20Sopenharmony_ci app.priority = 0; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) { 718c2ecf20Sopenharmony_ci /* Check if app list is exhausted */ 728c2ecf20Sopenharmony_ci if (!dcb->app_priority[i].protocolid) 738c2ecf20Sopenharmony_ci break; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci app.protocol = dcb->app_priority[i].protocolid; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) { 788c2ecf20Sopenharmony_ci app.priority = dcb->app_priority[i].user_prio_map; 798c2ecf20Sopenharmony_ci app.selector = dcb->app_priority[i].sel_field + 1; 808c2ecf20Sopenharmony_ci err = dcb_ieee_delapp(dev, &app); 818c2ecf20Sopenharmony_ci } else { 828c2ecf20Sopenharmony_ci app.selector = !!(dcb->app_priority[i].sel_field); 838c2ecf20Sopenharmony_ci err = dcb_setapp(dev, &app); 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if (err) { 878c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, 888c2ecf20Sopenharmony_ci "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n", 898c2ecf20Sopenharmony_ci dcb_ver_array[dcb->dcb_version], app.selector, 908c2ecf20Sopenharmony_ci app.protocol, -err); 918c2ecf20Sopenharmony_ci break; 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci } 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* Reset a port's Data Center Bridging state. Typically used after a 978c2ecf20Sopenharmony_ci * Link Down event. 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_civoid cxgb4_dcb_reset(struct net_device *dev) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci cxgb4_dcb_cleanup_apps(dev); 1028c2ecf20Sopenharmony_ci cxgb4_dcb_state_init(dev); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* update the dcb port support, if version is IEEE then set it to 1068c2ecf20Sopenharmony_ci * FW_PORT_DCB_VER_IEEE and if DCB_CAP_DCBX_VER_CEE is already set then 1078c2ecf20Sopenharmony_ci * clear that. and if it is set to CEE then set dcb supported to 1088c2ecf20Sopenharmony_ci * DCB_CAP_DCBX_VER_CEE & if DCB_CAP_DCBX_VER_IEEE is set, clear it 1098c2ecf20Sopenharmony_ci */ 1108c2ecf20Sopenharmony_cistatic inline void cxgb4_dcb_update_support(struct port_dcb_info *dcb) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) { 1138c2ecf20Sopenharmony_ci if (dcb->supported & DCB_CAP_DCBX_VER_CEE) 1148c2ecf20Sopenharmony_ci dcb->supported &= ~DCB_CAP_DCBX_VER_CEE; 1158c2ecf20Sopenharmony_ci dcb->supported |= DCB_CAP_DCBX_VER_IEEE; 1168c2ecf20Sopenharmony_ci } else if (dcb->dcb_version == FW_PORT_DCB_VER_CEE1D01) { 1178c2ecf20Sopenharmony_ci if (dcb->supported & DCB_CAP_DCBX_VER_IEEE) 1188c2ecf20Sopenharmony_ci dcb->supported &= ~DCB_CAP_DCBX_VER_IEEE; 1198c2ecf20Sopenharmony_ci dcb->supported |= DCB_CAP_DCBX_VER_CEE; 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci/* Finite State machine for Data Center Bridging. 1248c2ecf20Sopenharmony_ci */ 1258c2ecf20Sopenharmony_civoid cxgb4_dcb_state_fsm(struct net_device *dev, 1268c2ecf20Sopenharmony_ci enum cxgb4_dcb_state_input transition_to) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 1298c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 1308c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 1318c2ecf20Sopenharmony_ci enum cxgb4_dcb_state current_state = dcb->state; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci netdev_dbg(dev, "%s: State change from %d to %d for %s\n", 1348c2ecf20Sopenharmony_ci __func__, dcb->state, transition_to, dev->name); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci switch (current_state) { 1378c2ecf20Sopenharmony_ci case CXGB4_DCB_STATE_START: { 1388c2ecf20Sopenharmony_ci switch (transition_to) { 1398c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_DISABLED: { 1408c2ecf20Sopenharmony_ci /* we're going to use Host DCB */ 1418c2ecf20Sopenharmony_ci dcb->state = CXGB4_DCB_STATE_HOST; 1428c2ecf20Sopenharmony_ci dcb->supported = CXGB4_DCBX_HOST_SUPPORT; 1438c2ecf20Sopenharmony_ci break; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_ENABLED: { 1478c2ecf20Sopenharmony_ci /* we're going to use Firmware DCB */ 1488c2ecf20Sopenharmony_ci dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE; 1498c2ecf20Sopenharmony_ci dcb->supported = DCB_CAP_DCBX_LLD_MANAGED; 1508c2ecf20Sopenharmony_ci if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) 1518c2ecf20Sopenharmony_ci dcb->supported |= DCB_CAP_DCBX_VER_IEEE; 1528c2ecf20Sopenharmony_ci else 1538c2ecf20Sopenharmony_ci dcb->supported |= DCB_CAP_DCBX_VER_CEE; 1548c2ecf20Sopenharmony_ci break; 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_INCOMPLETE: { 1588c2ecf20Sopenharmony_ci /* expected transition */ 1598c2ecf20Sopenharmony_ci break; 1608c2ecf20Sopenharmony_ci } 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_ALLSYNCED: { 1638c2ecf20Sopenharmony_ci dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED; 1648c2ecf20Sopenharmony_ci break; 1658c2ecf20Sopenharmony_ci } 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci default: 1688c2ecf20Sopenharmony_ci goto bad_state_input; 1698c2ecf20Sopenharmony_ci } 1708c2ecf20Sopenharmony_ci break; 1718c2ecf20Sopenharmony_ci } 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci case CXGB4_DCB_STATE_FW_INCOMPLETE: { 1748c2ecf20Sopenharmony_ci if (transition_to != CXGB4_DCB_INPUT_FW_DISABLED) { 1758c2ecf20Sopenharmony_ci /* during this CXGB4_DCB_STATE_FW_INCOMPLETE state, 1768c2ecf20Sopenharmony_ci * check if the dcb version is changed (there can be 1778c2ecf20Sopenharmony_ci * mismatch in default config & the negotiated switch 1788c2ecf20Sopenharmony_ci * configuration at FW, so update the dcb support 1798c2ecf20Sopenharmony_ci * accordingly. 1808c2ecf20Sopenharmony_ci */ 1818c2ecf20Sopenharmony_ci cxgb4_dcb_update_support(dcb); 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci switch (transition_to) { 1848c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_ENABLED: { 1858c2ecf20Sopenharmony_ci /* we're alreaady in firmware DCB mode */ 1868c2ecf20Sopenharmony_ci break; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_INCOMPLETE: { 1908c2ecf20Sopenharmony_ci /* we're already incomplete */ 1918c2ecf20Sopenharmony_ci break; 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_ALLSYNCED: { 1958c2ecf20Sopenharmony_ci dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED; 1968c2ecf20Sopenharmony_ci dcb->enabled = 1; 1978c2ecf20Sopenharmony_ci linkwatch_fire_event(dev); 1988c2ecf20Sopenharmony_ci break; 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci default: 2028c2ecf20Sopenharmony_ci goto bad_state_input; 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci break; 2058c2ecf20Sopenharmony_ci } 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci case CXGB4_DCB_STATE_FW_ALLSYNCED: { 2088c2ecf20Sopenharmony_ci switch (transition_to) { 2098c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_ENABLED: { 2108c2ecf20Sopenharmony_ci /* we're alreaady in firmware DCB mode */ 2118c2ecf20Sopenharmony_ci break; 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_INCOMPLETE: { 2158c2ecf20Sopenharmony_ci /* We were successfully running with firmware DCB but 2168c2ecf20Sopenharmony_ci * now it's telling us that it's in an "incomplete 2178c2ecf20Sopenharmony_ci * state. We need to reset back to a ground state 2188c2ecf20Sopenharmony_ci * of incomplete. 2198c2ecf20Sopenharmony_ci */ 2208c2ecf20Sopenharmony_ci cxgb4_dcb_reset(dev); 2218c2ecf20Sopenharmony_ci dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE; 2228c2ecf20Sopenharmony_ci dcb->supported = CXGB4_DCBX_FW_SUPPORT; 2238c2ecf20Sopenharmony_ci linkwatch_fire_event(dev); 2248c2ecf20Sopenharmony_ci break; 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_ALLSYNCED: { 2288c2ecf20Sopenharmony_ci /* we're already all sync'ed 2298c2ecf20Sopenharmony_ci * this is only applicable for IEEE or 2308c2ecf20Sopenharmony_ci * when another VI already completed negotiaton 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_ci dcb->enabled = 1; 2338c2ecf20Sopenharmony_ci linkwatch_fire_event(dev); 2348c2ecf20Sopenharmony_ci break; 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci default: 2388c2ecf20Sopenharmony_ci goto bad_state_input; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci break; 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci case CXGB4_DCB_STATE_HOST: { 2448c2ecf20Sopenharmony_ci switch (transition_to) { 2458c2ecf20Sopenharmony_ci case CXGB4_DCB_INPUT_FW_DISABLED: { 2468c2ecf20Sopenharmony_ci /* we're alreaady in Host DCB mode */ 2478c2ecf20Sopenharmony_ci break; 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci default: 2518c2ecf20Sopenharmony_ci goto bad_state_input; 2528c2ecf20Sopenharmony_ci } 2538c2ecf20Sopenharmony_ci break; 2548c2ecf20Sopenharmony_ci } 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci default: 2578c2ecf20Sopenharmony_ci goto bad_state_transition; 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci return; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_cibad_state_input: 2628c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n", 2638c2ecf20Sopenharmony_ci transition_to); 2648c2ecf20Sopenharmony_ci return; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_cibad_state_transition: 2678c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n", 2688c2ecf20Sopenharmony_ci current_state, transition_to); 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/* Handle a DCB/DCBX update message from the firmware. 2728c2ecf20Sopenharmony_ci */ 2738c2ecf20Sopenharmony_civoid cxgb4_dcb_handle_fw_update(struct adapter *adap, 2748c2ecf20Sopenharmony_ci const struct fw_port_cmd *pcmd) 2758c2ecf20Sopenharmony_ci{ 2768c2ecf20Sopenharmony_ci const union fw_port_dcb *fwdcb = &pcmd->u.dcb; 2778c2ecf20Sopenharmony_ci int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid)); 2788c2ecf20Sopenharmony_ci struct net_device *dev = adap->port[adap->chan_map[port]]; 2798c2ecf20Sopenharmony_ci struct port_info *pi = netdev_priv(dev); 2808c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 2818c2ecf20Sopenharmony_ci int dcb_type = pcmd->u.dcb.pgid.type; 2828c2ecf20Sopenharmony_ci int dcb_running_version; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci /* Handle Firmware DCB Control messages separately since they drive 2858c2ecf20Sopenharmony_ci * our state machine. 2868c2ecf20Sopenharmony_ci */ 2878c2ecf20Sopenharmony_ci if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) { 2888c2ecf20Sopenharmony_ci enum cxgb4_dcb_state_input input = 2898c2ecf20Sopenharmony_ci ((pcmd->u.dcb.control.all_syncd_pkd & 2908c2ecf20Sopenharmony_ci FW_PORT_CMD_ALL_SYNCD_F) 2918c2ecf20Sopenharmony_ci ? CXGB4_DCB_INPUT_FW_ALLSYNCED 2928c2ecf20Sopenharmony_ci : CXGB4_DCB_INPUT_FW_INCOMPLETE); 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci if (dcb->dcb_version != FW_PORT_DCB_VER_UNKNOWN) { 2958c2ecf20Sopenharmony_ci dcb_running_version = FW_PORT_CMD_DCB_VERSION_G( 2968c2ecf20Sopenharmony_ci be16_to_cpu( 2978c2ecf20Sopenharmony_ci pcmd->u.dcb.control.dcb_version_to_app_state)); 2988c2ecf20Sopenharmony_ci if (dcb_running_version == FW_PORT_DCB_VER_CEE1D01 || 2998c2ecf20Sopenharmony_ci dcb_running_version == FW_PORT_DCB_VER_IEEE) { 3008c2ecf20Sopenharmony_ci dcb->dcb_version = dcb_running_version; 3018c2ecf20Sopenharmony_ci dev_warn(adap->pdev_dev, "Interface %s is running %s\n", 3028c2ecf20Sopenharmony_ci dev->name, 3038c2ecf20Sopenharmony_ci dcb_ver_array[dcb->dcb_version]); 3048c2ecf20Sopenharmony_ci } else { 3058c2ecf20Sopenharmony_ci dev_warn(adap->pdev_dev, 3068c2ecf20Sopenharmony_ci "Something screwed up, requested firmware for %s, but firmware returned %s instead\n", 3078c2ecf20Sopenharmony_ci dcb_ver_array[dcb->dcb_version], 3088c2ecf20Sopenharmony_ci dcb_ver_array[dcb_running_version]); 3098c2ecf20Sopenharmony_ci dcb->dcb_version = FW_PORT_DCB_VER_UNKNOWN; 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci cxgb4_dcb_state_fsm(dev, input); 3148c2ecf20Sopenharmony_ci return; 3158c2ecf20Sopenharmony_ci } 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci /* It's weird, and almost certainly an error, to get Firmware DCB 3188c2ecf20Sopenharmony_ci * messages when we either haven't been told whether we're going to be 3198c2ecf20Sopenharmony_ci * doing Host or Firmware DCB; and even worse when we've been told 3208c2ecf20Sopenharmony_ci * that we're doing Host DCB! 3218c2ecf20Sopenharmony_ci */ 3228c2ecf20Sopenharmony_ci if (dcb->state == CXGB4_DCB_STATE_START || 3238c2ecf20Sopenharmony_ci dcb->state == CXGB4_DCB_STATE_HOST) { 3248c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n", 3258c2ecf20Sopenharmony_ci dcb->state); 3268c2ecf20Sopenharmony_ci return; 3278c2ecf20Sopenharmony_ci } 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci /* Now handle the general Firmware DCB update messages ... 3308c2ecf20Sopenharmony_ci */ 3318c2ecf20Sopenharmony_ci switch (dcb_type) { 3328c2ecf20Sopenharmony_ci case FW_PORT_DCB_TYPE_PGID: 3338c2ecf20Sopenharmony_ci dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid); 3348c2ecf20Sopenharmony_ci dcb->msgs |= CXGB4_DCB_FW_PGID; 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci case FW_PORT_DCB_TYPE_PGRATE: 3388c2ecf20Sopenharmony_ci dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported; 3398c2ecf20Sopenharmony_ci memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate, 3408c2ecf20Sopenharmony_ci sizeof(dcb->pgrate)); 3418c2ecf20Sopenharmony_ci memcpy(dcb->tsa, &fwdcb->pgrate.tsa, 3428c2ecf20Sopenharmony_ci sizeof(dcb->tsa)); 3438c2ecf20Sopenharmony_ci dcb->msgs |= CXGB4_DCB_FW_PGRATE; 3448c2ecf20Sopenharmony_ci if (dcb->msgs & CXGB4_DCB_FW_PGID) 3458c2ecf20Sopenharmony_ci IEEE_FAUX_SYNC(dev, dcb); 3468c2ecf20Sopenharmony_ci break; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci case FW_PORT_DCB_TYPE_PRIORATE: 3498c2ecf20Sopenharmony_ci memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate, 3508c2ecf20Sopenharmony_ci sizeof(dcb->priorate)); 3518c2ecf20Sopenharmony_ci dcb->msgs |= CXGB4_DCB_FW_PRIORATE; 3528c2ecf20Sopenharmony_ci break; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci case FW_PORT_DCB_TYPE_PFC: 3558c2ecf20Sopenharmony_ci dcb->pfcen = fwdcb->pfc.pfcen; 3568c2ecf20Sopenharmony_ci dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs; 3578c2ecf20Sopenharmony_ci dcb->msgs |= CXGB4_DCB_FW_PFC; 3588c2ecf20Sopenharmony_ci IEEE_FAUX_SYNC(dev, dcb); 3598c2ecf20Sopenharmony_ci break; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci case FW_PORT_DCB_TYPE_APP_ID: { 3628c2ecf20Sopenharmony_ci const struct fw_port_app_priority *fwap = &fwdcb->app_priority; 3638c2ecf20Sopenharmony_ci int idx = fwap->idx; 3648c2ecf20Sopenharmony_ci struct app_priority *ap = &dcb->app_priority[idx]; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci struct dcb_app app = { 3678c2ecf20Sopenharmony_ci .protocol = be16_to_cpu(fwap->protocolid), 3688c2ecf20Sopenharmony_ci }; 3698c2ecf20Sopenharmony_ci int err; 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci /* Convert from firmware format to relevant format 3728c2ecf20Sopenharmony_ci * when using app selector 3738c2ecf20Sopenharmony_ci */ 3748c2ecf20Sopenharmony_ci if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) { 3758c2ecf20Sopenharmony_ci app.selector = (fwap->sel_field + 1); 3768c2ecf20Sopenharmony_ci app.priority = ffs(fwap->user_prio_map) - 1; 3778c2ecf20Sopenharmony_ci err = dcb_ieee_setapp(dev, &app); 3788c2ecf20Sopenharmony_ci IEEE_FAUX_SYNC(dev, dcb); 3798c2ecf20Sopenharmony_ci } else { 3808c2ecf20Sopenharmony_ci /* Default is CEE */ 3818c2ecf20Sopenharmony_ci app.selector = !!(fwap->sel_field); 3828c2ecf20Sopenharmony_ci app.priority = fwap->user_prio_map; 3838c2ecf20Sopenharmony_ci err = dcb_setapp(dev, &app); 3848c2ecf20Sopenharmony_ci } 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci if (err) 3878c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, 3888c2ecf20Sopenharmony_ci "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n", 3898c2ecf20Sopenharmony_ci app.selector, app.protocol, app.priority, -err); 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci ap->user_prio_map = fwap->user_prio_map; 3928c2ecf20Sopenharmony_ci ap->sel_field = fwap->sel_field; 3938c2ecf20Sopenharmony_ci ap->protocolid = be16_to_cpu(fwap->protocolid); 3948c2ecf20Sopenharmony_ci dcb->msgs |= CXGB4_DCB_FW_APP_ID; 3958c2ecf20Sopenharmony_ci break; 3968c2ecf20Sopenharmony_ci } 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci default: 3998c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n", 4008c2ecf20Sopenharmony_ci dcb_type); 4018c2ecf20Sopenharmony_ci break; 4028c2ecf20Sopenharmony_ci } 4038c2ecf20Sopenharmony_ci} 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci/* Data Center Bridging netlink operations. 4068c2ecf20Sopenharmony_ci */ 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci/* Get current DCB enabled/disabled state. 4108c2ecf20Sopenharmony_ci */ 4118c2ecf20Sopenharmony_cistatic u8 cxgb4_getstate(struct net_device *dev) 4128c2ecf20Sopenharmony_ci{ 4138c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci return pi->dcb.enabled; 4168c2ecf20Sopenharmony_ci} 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci/* Set DCB enabled/disabled. 4198c2ecf20Sopenharmony_ci */ 4208c2ecf20Sopenharmony_cistatic u8 cxgb4_setstate(struct net_device *dev, u8 enabled) 4218c2ecf20Sopenharmony_ci{ 4228c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci /* If DCBx is host-managed, dcb is enabled by outside lldp agents */ 4258c2ecf20Sopenharmony_ci if (pi->dcb.state == CXGB4_DCB_STATE_HOST) { 4268c2ecf20Sopenharmony_ci pi->dcb.enabled = enabled; 4278c2ecf20Sopenharmony_ci return 0; 4288c2ecf20Sopenharmony_ci } 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci /* Firmware doesn't provide any mechanism to control the DCB state. 4318c2ecf20Sopenharmony_ci */ 4328c2ecf20Sopenharmony_ci if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED)) 4338c2ecf20Sopenharmony_ci return 1; 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci return 0; 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic void cxgb4_getpgtccfg(struct net_device *dev, int tc, 4398c2ecf20Sopenharmony_ci u8 *prio_type, u8 *pgid, u8 *bw_per, 4408c2ecf20Sopenharmony_ci u8 *up_tc_map, int local) 4418c2ecf20Sopenharmony_ci{ 4428c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 4438c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 4448c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 4458c2ecf20Sopenharmony_ci int err; 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci *prio_type = *pgid = *bw_per = *up_tc_map = 0; 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci if (local) 4508c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 4518c2ecf20Sopenharmony_ci else 4528c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID; 4558c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 4568c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 4578c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err); 4588c2ecf20Sopenharmony_ci return; 4598c2ecf20Sopenharmony_ci } 4608c2ecf20Sopenharmony_ci *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf; 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci if (local) 4638c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 4648c2ecf20Sopenharmony_ci else 4658c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 4668c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; 4678c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 4688c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 4698c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n", 4708c2ecf20Sopenharmony_ci -err); 4718c2ecf20Sopenharmony_ci return; 4728c2ecf20Sopenharmony_ci } 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid]; 4758c2ecf20Sopenharmony_ci *up_tc_map = (1 << tc); 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci /* prio_type is link strict */ 4788c2ecf20Sopenharmony_ci if (*pgid != 0xF) 4798c2ecf20Sopenharmony_ci *prio_type = 0x2; 4808c2ecf20Sopenharmony_ci} 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_cistatic void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc, 4838c2ecf20Sopenharmony_ci u8 *prio_type, u8 *pgid, u8 *bw_per, 4848c2ecf20Sopenharmony_ci u8 *up_tc_map) 4858c2ecf20Sopenharmony_ci{ 4868c2ecf20Sopenharmony_ci /* tc 0 is written at MSB position */ 4878c2ecf20Sopenharmony_ci return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per, 4888c2ecf20Sopenharmony_ci up_tc_map, 1); 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_cistatic void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc, 4938c2ecf20Sopenharmony_ci u8 *prio_type, u8 *pgid, u8 *bw_per, 4948c2ecf20Sopenharmony_ci u8 *up_tc_map) 4958c2ecf20Sopenharmony_ci{ 4968c2ecf20Sopenharmony_ci /* tc 0 is written at MSB position */ 4978c2ecf20Sopenharmony_ci return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per, 4988c2ecf20Sopenharmony_ci up_tc_map, 0); 4998c2ecf20Sopenharmony_ci} 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_cistatic void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc, 5028c2ecf20Sopenharmony_ci u8 prio_type, u8 pgid, u8 bw_per, 5038c2ecf20Sopenharmony_ci u8 up_tc_map) 5048c2ecf20Sopenharmony_ci{ 5058c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 5068c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 5078c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 5088c2ecf20Sopenharmony_ci int fw_tc = 7 - tc; 5098c2ecf20Sopenharmony_ci u32 _pgid; 5108c2ecf20Sopenharmony_ci int err; 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci if (pgid == DCB_ATTR_VALUE_UNDEFINED) 5138c2ecf20Sopenharmony_ci return; 5148c2ecf20Sopenharmony_ci if (bw_per == DCB_ATTR_VALUE_UNDEFINED) 5158c2ecf20Sopenharmony_ci return; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 5188c2ecf20Sopenharmony_ci pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 5218c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 5228c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err); 5238c2ecf20Sopenharmony_ci return; 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid); 5278c2ecf20Sopenharmony_ci _pgid &= ~(0xF << (fw_tc * 4)); 5288c2ecf20Sopenharmony_ci _pgid |= pgid << (fw_tc * 4); 5298c2ecf20Sopenharmony_ci pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid); 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 5348c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 5358c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n", 5368c2ecf20Sopenharmony_ci -err); 5378c2ecf20Sopenharmony_ci return; 5388c2ecf20Sopenharmony_ci } 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci memset(&pcmd, 0, sizeof(struct fw_port_cmd)); 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 5438c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 5468c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 5478c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n", 5488c2ecf20Sopenharmony_ci -err); 5498c2ecf20Sopenharmony_ci return; 5508c2ecf20Sopenharmony_ci } 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); 5558c2ecf20Sopenharmony_ci if (pi->dcb.state == CXGB4_DCB_STATE_HOST) 5568c2ecf20Sopenharmony_ci pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 5598c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) 5608c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n", 5618c2ecf20Sopenharmony_ci -err); 5628c2ecf20Sopenharmony_ci} 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_cistatic void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per, 5658c2ecf20Sopenharmony_ci int local) 5668c2ecf20Sopenharmony_ci{ 5678c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 5688c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 5698c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 5708c2ecf20Sopenharmony_ci int err; 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci if (local) 5738c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 5748c2ecf20Sopenharmony_ci else 5758c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; 5788c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 5798c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 5808c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n", 5818c2ecf20Sopenharmony_ci -err); 5828c2ecf20Sopenharmony_ci return; 5838c2ecf20Sopenharmony_ci } 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid]; 5868c2ecf20Sopenharmony_ci} 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_cistatic void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per) 5898c2ecf20Sopenharmony_ci{ 5908c2ecf20Sopenharmony_ci return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1); 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0); 5968c2ecf20Sopenharmony_ci} 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid, 5998c2ecf20Sopenharmony_ci u8 bw_per) 6008c2ecf20Sopenharmony_ci{ 6018c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 6028c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 6038c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 6048c2ecf20Sopenharmony_ci int err; 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 6078c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 6108c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 6118c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n", 6128c2ecf20Sopenharmony_ci -err); 6138c2ecf20Sopenharmony_ci return; 6148c2ecf20Sopenharmony_ci } 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); 6198c2ecf20Sopenharmony_ci if (pi->dcb.state == CXGB4_DCB_STATE_HOST) 6208c2ecf20Sopenharmony_ci pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) 6258c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n", 6268c2ecf20Sopenharmony_ci -err); 6278c2ecf20Sopenharmony_ci} 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci/* Return whether the specified Traffic Class Priority has Priority Pause 6308c2ecf20Sopenharmony_ci * Frames enabled. 6318c2ecf20Sopenharmony_ci */ 6328c2ecf20Sopenharmony_cistatic void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg) 6338c2ecf20Sopenharmony_ci{ 6348c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 6358c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(dcb->state) || 6388c2ecf20Sopenharmony_ci priority >= CXGB4_MAX_PRIORITY) 6398c2ecf20Sopenharmony_ci *pfccfg = 0; 6408c2ecf20Sopenharmony_ci else 6418c2ecf20Sopenharmony_ci *pfccfg = (pi->dcb.pfcen >> (7 - priority)) & 1; 6428c2ecf20Sopenharmony_ci} 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci/* Enable/disable Priority Pause Frames for the specified Traffic Class 6458c2ecf20Sopenharmony_ci * Priority. 6468c2ecf20Sopenharmony_ci */ 6478c2ecf20Sopenharmony_cistatic void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg) 6488c2ecf20Sopenharmony_ci{ 6498c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 6508c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 6518c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 6528c2ecf20Sopenharmony_ci int err; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(pi->dcb.state) || 6558c2ecf20Sopenharmony_ci priority >= CXGB4_MAX_PRIORITY) 6568c2ecf20Sopenharmony_ci return; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); 6598c2ecf20Sopenharmony_ci if (pi->dcb.state == CXGB4_DCB_STATE_HOST) 6608c2ecf20Sopenharmony_ci pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC; 6638c2ecf20Sopenharmony_ci pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen; 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci if (pfccfg) 6668c2ecf20Sopenharmony_ci pcmd.u.dcb.pfc.pfcen |= (1 << (7 - priority)); 6678c2ecf20Sopenharmony_ci else 6688c2ecf20Sopenharmony_ci pcmd.u.dcb.pfc.pfcen &= (~(1 << (7 - priority))); 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 6718c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 6728c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err); 6738c2ecf20Sopenharmony_ci return; 6748c2ecf20Sopenharmony_ci } 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen; 6778c2ecf20Sopenharmony_ci} 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_cistatic u8 cxgb4_setall(struct net_device *dev) 6808c2ecf20Sopenharmony_ci{ 6818c2ecf20Sopenharmony_ci return 0; 6828c2ecf20Sopenharmony_ci} 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci/* Return DCB capabilities. 6858c2ecf20Sopenharmony_ci */ 6868c2ecf20Sopenharmony_cistatic u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps) 6878c2ecf20Sopenharmony_ci{ 6888c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci switch (cap_id) { 6918c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PG: 6928c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PFC: 6938c2ecf20Sopenharmony_ci *caps = true; 6948c2ecf20Sopenharmony_ci break; 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PG_TCS: 6978c2ecf20Sopenharmony_ci /* 8 priorities for PG represented by bitmap */ 6988c2ecf20Sopenharmony_ci *caps = 0x80; 6998c2ecf20Sopenharmony_ci break; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PFC_TCS: 7028c2ecf20Sopenharmony_ci /* 8 priorities for PFC represented by bitmap */ 7038c2ecf20Sopenharmony_ci *caps = 0x80; 7048c2ecf20Sopenharmony_ci break; 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_GSP: 7078c2ecf20Sopenharmony_ci *caps = true; 7088c2ecf20Sopenharmony_ci break; 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_UP2TC: 7118c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_BCN: 7128c2ecf20Sopenharmony_ci *caps = false; 7138c2ecf20Sopenharmony_ci break; 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_DCBX: 7168c2ecf20Sopenharmony_ci *caps = pi->dcb.supported; 7178c2ecf20Sopenharmony_ci break; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci default: 7208c2ecf20Sopenharmony_ci *caps = false; 7218c2ecf20Sopenharmony_ci } 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci return 0; 7248c2ecf20Sopenharmony_ci} 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci/* Return the number of Traffic Classes for the indicated Traffic Class ID. 7278c2ecf20Sopenharmony_ci */ 7288c2ecf20Sopenharmony_cistatic int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num) 7298c2ecf20Sopenharmony_ci{ 7308c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci switch (tcs_id) { 7338c2ecf20Sopenharmony_ci case DCB_NUMTCS_ATTR_PG: 7348c2ecf20Sopenharmony_ci if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE) 7358c2ecf20Sopenharmony_ci *num = pi->dcb.pg_num_tcs_supported; 7368c2ecf20Sopenharmony_ci else 7378c2ecf20Sopenharmony_ci *num = 0x8; 7388c2ecf20Sopenharmony_ci break; 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci case DCB_NUMTCS_ATTR_PFC: 7418c2ecf20Sopenharmony_ci *num = 0x8; 7428c2ecf20Sopenharmony_ci break; 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci default: 7458c2ecf20Sopenharmony_ci return -EINVAL; 7468c2ecf20Sopenharmony_ci } 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci return 0; 7498c2ecf20Sopenharmony_ci} 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci/* Set the number of Traffic Classes supported for the indicated Traffic Class 7528c2ecf20Sopenharmony_ci * ID. 7538c2ecf20Sopenharmony_ci */ 7548c2ecf20Sopenharmony_cistatic int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num) 7558c2ecf20Sopenharmony_ci{ 7568c2ecf20Sopenharmony_ci /* Setting the number of Traffic Classes isn't supported. 7578c2ecf20Sopenharmony_ci */ 7588c2ecf20Sopenharmony_ci return -ENOSYS; 7598c2ecf20Sopenharmony_ci} 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci/* Return whether Priority Flow Control is enabled. */ 7628c2ecf20Sopenharmony_cistatic u8 cxgb4_getpfcstate(struct net_device *dev) 7638c2ecf20Sopenharmony_ci{ 7648c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(pi->dcb.state)) 7678c2ecf20Sopenharmony_ci return false; 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_ci return pi->dcb.pfcen != 0; 7708c2ecf20Sopenharmony_ci} 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci/* Enable/disable Priority Flow Control. */ 7738c2ecf20Sopenharmony_cistatic void cxgb4_setpfcstate(struct net_device *dev, u8 state) 7748c2ecf20Sopenharmony_ci{ 7758c2ecf20Sopenharmony_ci /* We can't enable/disable Priority Flow Control but we also can't 7768c2ecf20Sopenharmony_ci * return an error ... 7778c2ecf20Sopenharmony_ci */ 7788c2ecf20Sopenharmony_ci} 7798c2ecf20Sopenharmony_ci 7808c2ecf20Sopenharmony_ci/* Return the Application User Priority Map associated with the specified 7818c2ecf20Sopenharmony_ci * Application ID. 7828c2ecf20Sopenharmony_ci */ 7838c2ecf20Sopenharmony_cistatic int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id, 7848c2ecf20Sopenharmony_ci int peer) 7858c2ecf20Sopenharmony_ci{ 7868c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 7878c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 7888c2ecf20Sopenharmony_ci int i; 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(pi->dcb.state)) 7918c2ecf20Sopenharmony_ci return 0; 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) { 7948c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 7958c2ecf20Sopenharmony_ci int err; 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci if (peer) 7988c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 7998c2ecf20Sopenharmony_ci else 8008c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID; 8038c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.idx = i; 8048c2ecf20Sopenharmony_ci 8058c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 8068c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 8078c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB APP read failed with %d\n", 8088c2ecf20Sopenharmony_ci -err); 8098c2ecf20Sopenharmony_ci return err; 8108c2ecf20Sopenharmony_ci } 8118c2ecf20Sopenharmony_ci if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) 8128c2ecf20Sopenharmony_ci if (pcmd.u.dcb.app_priority.sel_field == app_idtype) 8138c2ecf20Sopenharmony_ci return pcmd.u.dcb.app_priority.user_prio_map; 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci /* exhausted app list */ 8168c2ecf20Sopenharmony_ci if (!pcmd.u.dcb.app_priority.protocolid) 8178c2ecf20Sopenharmony_ci break; 8188c2ecf20Sopenharmony_ci } 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci return -EEXIST; 8218c2ecf20Sopenharmony_ci} 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_ci/* Return the Application User Priority Map associated with the specified 8248c2ecf20Sopenharmony_ci * Application ID. 8258c2ecf20Sopenharmony_ci */ 8268c2ecf20Sopenharmony_cistatic int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id) 8278c2ecf20Sopenharmony_ci{ 8288c2ecf20Sopenharmony_ci /* Convert app_idtype to firmware format before querying */ 8298c2ecf20Sopenharmony_ci return __cxgb4_getapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ? 8308c2ecf20Sopenharmony_ci app_idtype : 3, app_id, 0); 8318c2ecf20Sopenharmony_ci} 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci/* Write a new Application User Priority Map for the specified Application ID 8348c2ecf20Sopenharmony_ci */ 8358c2ecf20Sopenharmony_cistatic int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id, 8368c2ecf20Sopenharmony_ci u8 app_prio) 8378c2ecf20Sopenharmony_ci{ 8388c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 8398c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 8408c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 8418c2ecf20Sopenharmony_ci int i, err; 8428c2ecf20Sopenharmony_ci 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(pi->dcb.state)) 8458c2ecf20Sopenharmony_ci return -EINVAL; 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ci /* DCB info gets thrown away on link up */ 8488c2ecf20Sopenharmony_ci if (!netif_carrier_ok(dev)) 8498c2ecf20Sopenharmony_ci return -ENOLINK; 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) { 8528c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 8538c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID; 8548c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.idx = i; 8558c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 8588c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB app table read failed with %d\n", 8598c2ecf20Sopenharmony_ci -err); 8608c2ecf20Sopenharmony_ci return err; 8618c2ecf20Sopenharmony_ci } 8628c2ecf20Sopenharmony_ci if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) { 8638c2ecf20Sopenharmony_ci /* overwrite existing app table */ 8648c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.protocolid = 0; 8658c2ecf20Sopenharmony_ci break; 8668c2ecf20Sopenharmony_ci } 8678c2ecf20Sopenharmony_ci /* find first empty slot */ 8688c2ecf20Sopenharmony_ci if (!pcmd.u.dcb.app_priority.protocolid) 8698c2ecf20Sopenharmony_ci break; 8708c2ecf20Sopenharmony_ci } 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) { 8738c2ecf20Sopenharmony_ci /* no empty slots available */ 8748c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB app table full\n"); 8758c2ecf20Sopenharmony_ci return -EBUSY; 8768c2ecf20Sopenharmony_ci } 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci /* write out new app table entry */ 8798c2ecf20Sopenharmony_ci INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); 8808c2ecf20Sopenharmony_ci if (pi->dcb.state == CXGB4_DCB_STATE_HOST) 8818c2ecf20Sopenharmony_ci pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); 8828c2ecf20Sopenharmony_ci 8838c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID; 8848c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id); 8858c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.sel_field = app_idtype; 8868c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.user_prio_map = app_prio; 8878c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.idx = i; 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 8908c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 8918c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB app table write failed with %d\n", 8928c2ecf20Sopenharmony_ci -err); 8938c2ecf20Sopenharmony_ci return err; 8948c2ecf20Sopenharmony_ci } 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_ci return 0; 8978c2ecf20Sopenharmony_ci} 8988c2ecf20Sopenharmony_ci 8998c2ecf20Sopenharmony_ci/* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */ 9008c2ecf20Sopenharmony_cistatic int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id, 9018c2ecf20Sopenharmony_ci u8 app_prio) 9028c2ecf20Sopenharmony_ci{ 9038c2ecf20Sopenharmony_ci int ret; 9048c2ecf20Sopenharmony_ci struct dcb_app app = { 9058c2ecf20Sopenharmony_ci .selector = app_idtype, 9068c2ecf20Sopenharmony_ci .protocol = app_id, 9078c2ecf20Sopenharmony_ci .priority = app_prio, 9088c2ecf20Sopenharmony_ci }; 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci if (app_idtype != DCB_APP_IDTYPE_ETHTYPE && 9118c2ecf20Sopenharmony_ci app_idtype != DCB_APP_IDTYPE_PORTNUM) 9128c2ecf20Sopenharmony_ci return -EINVAL; 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_ci /* Convert app_idtype to a format that firmware understands */ 9158c2ecf20Sopenharmony_ci ret = __cxgb4_setapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ? 9168c2ecf20Sopenharmony_ci app_idtype : 3, app_id, app_prio); 9178c2ecf20Sopenharmony_ci if (ret) 9188c2ecf20Sopenharmony_ci return ret; 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci return dcb_setapp(dev, &app); 9218c2ecf20Sopenharmony_ci} 9228c2ecf20Sopenharmony_ci 9238c2ecf20Sopenharmony_ci/* Return whether IEEE Data Center Bridging has been negotiated. 9248c2ecf20Sopenharmony_ci */ 9258c2ecf20Sopenharmony_cistatic inline int 9268c2ecf20Sopenharmony_cicxgb4_ieee_negotiation_complete(struct net_device *dev, 9278c2ecf20Sopenharmony_ci enum cxgb4_dcb_fw_msgs dcb_subtype) 9288c2ecf20Sopenharmony_ci{ 9298c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 9308c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci if (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED) 9338c2ecf20Sopenharmony_ci if (dcb_subtype && !(dcb->msgs & dcb_subtype)) 9348c2ecf20Sopenharmony_ci return 0; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci return (cxgb4_dcb_state_synced(dcb->state) && 9378c2ecf20Sopenharmony_ci (dcb->supported & DCB_CAP_DCBX_VER_IEEE)); 9388c2ecf20Sopenharmony_ci} 9398c2ecf20Sopenharmony_ci 9408c2ecf20Sopenharmony_cistatic int cxgb4_ieee_read_ets(struct net_device *dev, struct ieee_ets *ets, 9418c2ecf20Sopenharmony_ci int local) 9428c2ecf20Sopenharmony_ci{ 9438c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 9448c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 9458c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 9468c2ecf20Sopenharmony_ci uint32_t tc_info; 9478c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 9488c2ecf20Sopenharmony_ci int i, bwg, err; 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_ci if (!(dcb->msgs & (CXGB4_DCB_FW_PGID | CXGB4_DCB_FW_PGRATE))) 9518c2ecf20Sopenharmony_ci return 0; 9528c2ecf20Sopenharmony_ci 9538c2ecf20Sopenharmony_ci ets->ets_cap = dcb->pg_num_tcs_supported; 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ci if (local) { 9568c2ecf20Sopenharmony_ci ets->willing = 1; 9578c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 9588c2ecf20Sopenharmony_ci } else { 9598c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 9608c2ecf20Sopenharmony_ci } 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID; 9638c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 9648c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 9658c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err); 9668c2ecf20Sopenharmony_ci return err; 9678c2ecf20Sopenharmony_ci } 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci tc_info = be32_to_cpu(pcmd.u.dcb.pgid.pgid); 9708c2ecf20Sopenharmony_ci 9718c2ecf20Sopenharmony_ci if (local) 9728c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id); 9738c2ecf20Sopenharmony_ci else 9748c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; 9778c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 9788c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 9798c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n", 9808c2ecf20Sopenharmony_ci -err); 9818c2ecf20Sopenharmony_ci return err; 9828c2ecf20Sopenharmony_ci } 9838c2ecf20Sopenharmony_ci 9848c2ecf20Sopenharmony_ci for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 9858c2ecf20Sopenharmony_ci bwg = (tc_info >> ((7 - i) * 4)) & 0xF; 9868c2ecf20Sopenharmony_ci ets->prio_tc[i] = bwg; 9878c2ecf20Sopenharmony_ci ets->tc_tx_bw[i] = pcmd.u.dcb.pgrate.pgrate[i]; 9888c2ecf20Sopenharmony_ci ets->tc_rx_bw[i] = ets->tc_tx_bw[i]; 9898c2ecf20Sopenharmony_ci ets->tc_tsa[i] = pcmd.u.dcb.pgrate.tsa[i]; 9908c2ecf20Sopenharmony_ci } 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_ci return 0; 9938c2ecf20Sopenharmony_ci} 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_cistatic int cxgb4_ieee_get_ets(struct net_device *dev, struct ieee_ets *ets) 9968c2ecf20Sopenharmony_ci{ 9978c2ecf20Sopenharmony_ci return cxgb4_ieee_read_ets(dev, ets, 1); 9988c2ecf20Sopenharmony_ci} 9998c2ecf20Sopenharmony_ci 10008c2ecf20Sopenharmony_ci/* We reuse this for peer PFC as well, as we can't have it enabled one way */ 10018c2ecf20Sopenharmony_cistatic int cxgb4_ieee_get_pfc(struct net_device *dev, struct ieee_pfc *pfc) 10028c2ecf20Sopenharmony_ci{ 10038c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 10048c2ecf20Sopenharmony_ci struct port_dcb_info *dcb = &pi->dcb; 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci memset(pfc, 0, sizeof(struct ieee_pfc)); 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci if (!(dcb->msgs & CXGB4_DCB_FW_PFC)) 10098c2ecf20Sopenharmony_ci return 0; 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_ci pfc->pfc_cap = dcb->pfc_num_tcs_supported; 10128c2ecf20Sopenharmony_ci pfc->pfc_en = bitswap_1(dcb->pfcen); 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci return 0; 10158c2ecf20Sopenharmony_ci} 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_cistatic int cxgb4_ieee_peer_ets(struct net_device *dev, struct ieee_ets *ets) 10188c2ecf20Sopenharmony_ci{ 10198c2ecf20Sopenharmony_ci return cxgb4_ieee_read_ets(dev, ets, 0); 10208c2ecf20Sopenharmony_ci} 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci/* Fill in the Application User Priority Map associated with the 10238c2ecf20Sopenharmony_ci * specified Application. 10248c2ecf20Sopenharmony_ci * Priority for IEEE dcb_app is an integer, with 0 being a valid value 10258c2ecf20Sopenharmony_ci */ 10268c2ecf20Sopenharmony_cistatic int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app) 10278c2ecf20Sopenharmony_ci{ 10288c2ecf20Sopenharmony_ci int prio; 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID)) 10318c2ecf20Sopenharmony_ci return -EINVAL; 10328c2ecf20Sopenharmony_ci if (!(app->selector && app->protocol)) 10338c2ecf20Sopenharmony_ci return -EINVAL; 10348c2ecf20Sopenharmony_ci 10358c2ecf20Sopenharmony_ci /* Try querying firmware first, use firmware format */ 10368c2ecf20Sopenharmony_ci prio = __cxgb4_getapp(dev, app->selector - 1, app->protocol, 0); 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci if (prio < 0) 10398c2ecf20Sopenharmony_ci prio = dcb_ieee_getapp_mask(dev, app); 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci app->priority = ffs(prio) - 1; 10428c2ecf20Sopenharmony_ci return 0; 10438c2ecf20Sopenharmony_ci} 10448c2ecf20Sopenharmony_ci 10458c2ecf20Sopenharmony_ci/* Write a new Application User Priority Map for the specified Application ID. 10468c2ecf20Sopenharmony_ci * Priority for IEEE dcb_app is an integer, with 0 being a valid value 10478c2ecf20Sopenharmony_ci */ 10488c2ecf20Sopenharmony_cistatic int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app) 10498c2ecf20Sopenharmony_ci{ 10508c2ecf20Sopenharmony_ci int ret; 10518c2ecf20Sopenharmony_ci 10528c2ecf20Sopenharmony_ci if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID)) 10538c2ecf20Sopenharmony_ci return -EINVAL; 10548c2ecf20Sopenharmony_ci if (!(app->selector && app->protocol)) 10558c2ecf20Sopenharmony_ci return -EINVAL; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci if (!(app->selector > IEEE_8021QAZ_APP_SEL_ETHERTYPE && 10588c2ecf20Sopenharmony_ci app->selector < IEEE_8021QAZ_APP_SEL_ANY)) 10598c2ecf20Sopenharmony_ci return -EINVAL; 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_ci /* change selector to a format that firmware understands */ 10628c2ecf20Sopenharmony_ci ret = __cxgb4_setapp(dev, app->selector - 1, app->protocol, 10638c2ecf20Sopenharmony_ci (1 << app->priority)); 10648c2ecf20Sopenharmony_ci if (ret) 10658c2ecf20Sopenharmony_ci return ret; 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_ci return dcb_ieee_setapp(dev, app); 10688c2ecf20Sopenharmony_ci} 10698c2ecf20Sopenharmony_ci 10708c2ecf20Sopenharmony_ci/* Return our DCBX parameters. 10718c2ecf20Sopenharmony_ci */ 10728c2ecf20Sopenharmony_cistatic u8 cxgb4_getdcbx(struct net_device *dev) 10738c2ecf20Sopenharmony_ci{ 10748c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_ci /* This is already set by cxgb4_set_dcb_caps, so just return it */ 10778c2ecf20Sopenharmony_ci return pi->dcb.supported; 10788c2ecf20Sopenharmony_ci} 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_ci/* Set our DCBX parameters. 10818c2ecf20Sopenharmony_ci */ 10828c2ecf20Sopenharmony_cistatic u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request) 10838c2ecf20Sopenharmony_ci{ 10848c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 10858c2ecf20Sopenharmony_ci 10868c2ecf20Sopenharmony_ci /* Filter out requests which exceed our capabilities. 10878c2ecf20Sopenharmony_ci */ 10888c2ecf20Sopenharmony_ci if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT)) 10898c2ecf20Sopenharmony_ci != dcb_request) 10908c2ecf20Sopenharmony_ci return 1; 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci /* Can't enable DCB if we haven't successfully negotiated it. 10938c2ecf20Sopenharmony_ci */ 10948c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(pi->dcb.state)) 10958c2ecf20Sopenharmony_ci return 1; 10968c2ecf20Sopenharmony_ci 10978c2ecf20Sopenharmony_ci /* There's currently no mechanism to allow for the firmware DCBX 10988c2ecf20Sopenharmony_ci * negotiation to be changed from the Host Driver. If the caller 10998c2ecf20Sopenharmony_ci * requests exactly the same parameters that we already have then 11008c2ecf20Sopenharmony_ci * we'll allow them to be successfully "set" ... 11018c2ecf20Sopenharmony_ci */ 11028c2ecf20Sopenharmony_ci if (dcb_request != pi->dcb.supported) 11038c2ecf20Sopenharmony_ci return 1; 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_ci pi->dcb.supported = dcb_request; 11068c2ecf20Sopenharmony_ci return 0; 11078c2ecf20Sopenharmony_ci} 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_cistatic int cxgb4_getpeer_app(struct net_device *dev, 11108c2ecf20Sopenharmony_ci struct dcb_peer_app_info *info, u16 *app_count) 11118c2ecf20Sopenharmony_ci{ 11128c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 11138c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 11148c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 11158c2ecf20Sopenharmony_ci int i, err = 0; 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(pi->dcb.state)) 11188c2ecf20Sopenharmony_ci return 1; 11198c2ecf20Sopenharmony_ci 11208c2ecf20Sopenharmony_ci info->willing = 0; 11218c2ecf20Sopenharmony_ci info->error = 0; 11228c2ecf20Sopenharmony_ci 11238c2ecf20Sopenharmony_ci *app_count = 0; 11248c2ecf20Sopenharmony_ci for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) { 11258c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 11268c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID; 11278c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.idx = *app_count; 11288c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 11318c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB app table read failed with %d\n", 11328c2ecf20Sopenharmony_ci -err); 11338c2ecf20Sopenharmony_ci return err; 11348c2ecf20Sopenharmony_ci } 11358c2ecf20Sopenharmony_ci 11368c2ecf20Sopenharmony_ci /* find first empty slot */ 11378c2ecf20Sopenharmony_ci if (!pcmd.u.dcb.app_priority.protocolid) 11388c2ecf20Sopenharmony_ci break; 11398c2ecf20Sopenharmony_ci } 11408c2ecf20Sopenharmony_ci *app_count = i; 11418c2ecf20Sopenharmony_ci return err; 11428c2ecf20Sopenharmony_ci} 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_cistatic int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table) 11458c2ecf20Sopenharmony_ci{ 11468c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 11478c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 11488c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 11498c2ecf20Sopenharmony_ci int i, err = 0; 11508c2ecf20Sopenharmony_ci 11518c2ecf20Sopenharmony_ci if (!cxgb4_dcb_state_synced(pi->dcb.state)) 11528c2ecf20Sopenharmony_ci return 1; 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_ci for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) { 11558c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 11568c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID; 11578c2ecf20Sopenharmony_ci pcmd.u.dcb.app_priority.idx = i; 11588c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 11598c2ecf20Sopenharmony_ci 11608c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 11618c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB app table read failed with %d\n", 11628c2ecf20Sopenharmony_ci -err); 11638c2ecf20Sopenharmony_ci return err; 11648c2ecf20Sopenharmony_ci } 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_ci /* find first empty slot */ 11678c2ecf20Sopenharmony_ci if (!pcmd.u.dcb.app_priority.protocolid) 11688c2ecf20Sopenharmony_ci break; 11698c2ecf20Sopenharmony_ci 11708c2ecf20Sopenharmony_ci table[i].selector = (pcmd.u.dcb.app_priority.sel_field + 1); 11718c2ecf20Sopenharmony_ci table[i].protocol = 11728c2ecf20Sopenharmony_ci be16_to_cpu(pcmd.u.dcb.app_priority.protocolid); 11738c2ecf20Sopenharmony_ci table[i].priority = 11748c2ecf20Sopenharmony_ci ffs(pcmd.u.dcb.app_priority.user_prio_map) - 1; 11758c2ecf20Sopenharmony_ci } 11768c2ecf20Sopenharmony_ci return err; 11778c2ecf20Sopenharmony_ci} 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_ci/* Return Priority Group information. 11808c2ecf20Sopenharmony_ci */ 11818c2ecf20Sopenharmony_cistatic int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg) 11828c2ecf20Sopenharmony_ci{ 11838c2ecf20Sopenharmony_ci struct fw_port_cmd pcmd; 11848c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 11858c2ecf20Sopenharmony_ci struct adapter *adap = pi->adapter; 11868c2ecf20Sopenharmony_ci u32 pgid; 11878c2ecf20Sopenharmony_ci int i, err; 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ci /* We're always "willing" -- the Switch Fabric always dictates the 11908c2ecf20Sopenharmony_ci * DCBX parameters to us. 11918c2ecf20Sopenharmony_ci */ 11928c2ecf20Sopenharmony_ci pg->willing = true; 11938c2ecf20Sopenharmony_ci 11948c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 11958c2ecf20Sopenharmony_ci pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID; 11968c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 11978c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 11988c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err); 11998c2ecf20Sopenharmony_ci return err; 12008c2ecf20Sopenharmony_ci } 12018c2ecf20Sopenharmony_ci pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid); 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ci for (i = 0; i < CXGB4_MAX_PRIORITY; i++) 12048c2ecf20Sopenharmony_ci pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF; 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 12078c2ecf20Sopenharmony_ci pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; 12088c2ecf20Sopenharmony_ci err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 12098c2ecf20Sopenharmony_ci if (err != FW_PORT_DCB_CFG_SUCCESS) { 12108c2ecf20Sopenharmony_ci dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n", 12118c2ecf20Sopenharmony_ci -err); 12128c2ecf20Sopenharmony_ci return err; 12138c2ecf20Sopenharmony_ci } 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci for (i = 0; i < CXGB4_MAX_PRIORITY; i++) 12168c2ecf20Sopenharmony_ci pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i]; 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci pg->tcs_supported = pcmd.u.dcb.pgrate.num_tcs_supported; 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci return 0; 12218c2ecf20Sopenharmony_ci} 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci/* Return Priority Flow Control information. 12248c2ecf20Sopenharmony_ci */ 12258c2ecf20Sopenharmony_cistatic int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc) 12268c2ecf20Sopenharmony_ci{ 12278c2ecf20Sopenharmony_ci struct port_info *pi = netdev2pinfo(dev); 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported)); 12308c2ecf20Sopenharmony_ci 12318c2ecf20Sopenharmony_ci /* Firmware sends this to us in a formwat that is a bit flipped version 12328c2ecf20Sopenharmony_ci * of spec, correct it before we send it to host. This is taken care of 12338c2ecf20Sopenharmony_ci * by bit shifting in other uses of pfcen 12348c2ecf20Sopenharmony_ci */ 12358c2ecf20Sopenharmony_ci pfc->pfc_en = bitswap_1(pi->dcb.pfcen); 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci pfc->tcs_supported = pi->dcb.pfc_num_tcs_supported; 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_ci return 0; 12408c2ecf20Sopenharmony_ci} 12418c2ecf20Sopenharmony_ci 12428c2ecf20Sopenharmony_ciconst struct dcbnl_rtnl_ops cxgb4_dcb_ops = { 12438c2ecf20Sopenharmony_ci .ieee_getets = cxgb4_ieee_get_ets, 12448c2ecf20Sopenharmony_ci .ieee_getpfc = cxgb4_ieee_get_pfc, 12458c2ecf20Sopenharmony_ci .ieee_getapp = cxgb4_ieee_getapp, 12468c2ecf20Sopenharmony_ci .ieee_setapp = cxgb4_ieee_setapp, 12478c2ecf20Sopenharmony_ci .ieee_peer_getets = cxgb4_ieee_peer_ets, 12488c2ecf20Sopenharmony_ci .ieee_peer_getpfc = cxgb4_ieee_get_pfc, 12498c2ecf20Sopenharmony_ci 12508c2ecf20Sopenharmony_ci /* CEE std */ 12518c2ecf20Sopenharmony_ci .getstate = cxgb4_getstate, 12528c2ecf20Sopenharmony_ci .setstate = cxgb4_setstate, 12538c2ecf20Sopenharmony_ci .getpgtccfgtx = cxgb4_getpgtccfg_tx, 12548c2ecf20Sopenharmony_ci .getpgbwgcfgtx = cxgb4_getpgbwgcfg_tx, 12558c2ecf20Sopenharmony_ci .getpgtccfgrx = cxgb4_getpgtccfg_rx, 12568c2ecf20Sopenharmony_ci .getpgbwgcfgrx = cxgb4_getpgbwgcfg_rx, 12578c2ecf20Sopenharmony_ci .setpgtccfgtx = cxgb4_setpgtccfg_tx, 12588c2ecf20Sopenharmony_ci .setpgbwgcfgtx = cxgb4_setpgbwgcfg_tx, 12598c2ecf20Sopenharmony_ci .setpfccfg = cxgb4_setpfccfg, 12608c2ecf20Sopenharmony_ci .getpfccfg = cxgb4_getpfccfg, 12618c2ecf20Sopenharmony_ci .setall = cxgb4_setall, 12628c2ecf20Sopenharmony_ci .getcap = cxgb4_getcap, 12638c2ecf20Sopenharmony_ci .getnumtcs = cxgb4_getnumtcs, 12648c2ecf20Sopenharmony_ci .setnumtcs = cxgb4_setnumtcs, 12658c2ecf20Sopenharmony_ci .getpfcstate = cxgb4_getpfcstate, 12668c2ecf20Sopenharmony_ci .setpfcstate = cxgb4_setpfcstate, 12678c2ecf20Sopenharmony_ci .getapp = cxgb4_getapp, 12688c2ecf20Sopenharmony_ci .setapp = cxgb4_setapp, 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci /* DCBX configuration */ 12718c2ecf20Sopenharmony_ci .getdcbx = cxgb4_getdcbx, 12728c2ecf20Sopenharmony_ci .setdcbx = cxgb4_setdcbx, 12738c2ecf20Sopenharmony_ci 12748c2ecf20Sopenharmony_ci /* peer apps */ 12758c2ecf20Sopenharmony_ci .peer_getappinfo = cxgb4_getpeer_app, 12768c2ecf20Sopenharmony_ci .peer_getapptable = cxgb4_getpeerapp_tbl, 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci /* CEE peer */ 12798c2ecf20Sopenharmony_ci .cee_peer_getpg = cxgb4_cee_peer_getpg, 12808c2ecf20Sopenharmony_ci .cee_peer_getpfc = cxgb4_cee_peer_getpfc, 12818c2ecf20Sopenharmony_ci}; 1282