1316485Sdavidcs/* 2316485Sdavidcs * Copyright (c) 2017-2018 Cavium, Inc. 3316485Sdavidcs * All rights reserved. 4316485Sdavidcs * 5316485Sdavidcs * Redistribution and use in source and binary forms, with or without 6316485Sdavidcs * modification, are permitted provided that the following conditions 7316485Sdavidcs * are met: 8316485Sdavidcs * 9316485Sdavidcs * 1. Redistributions of source code must retain the above copyright 10316485Sdavidcs * notice, this list of conditions and the following disclaimer. 11316485Sdavidcs * 2. Redistributions in binary form must reproduce the above copyright 12316485Sdavidcs * notice, this list of conditions and the following disclaimer in the 13316485Sdavidcs * documentation and/or other materials provided with the distribution. 14316485Sdavidcs * 15316485Sdavidcs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16316485Sdavidcs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17316485Sdavidcs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18316485Sdavidcs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19316485Sdavidcs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20316485Sdavidcs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21316485Sdavidcs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22316485Sdavidcs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23316485Sdavidcs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24316485Sdavidcs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25316485Sdavidcs * POSSIBILITY OF SUCH DAMAGE. 26316485Sdavidcs */ 27316485Sdavidcs 28316485Sdavidcs/* 29316485Sdavidcs * File : ecore_sp_commands.c 30316485Sdavidcs */ 31316485Sdavidcs#include <sys/cdefs.h> 32316485Sdavidcs__FBSDID("$FreeBSD: stable/10/sys/dev/qlnx/qlnxe/ecore_sp_commands.c 337519 2018-08-09 01:39:47Z davidcs $"); 33316485Sdavidcs 34316485Sdavidcs#include "bcm_osal.h" 35316485Sdavidcs 36316485Sdavidcs#include "ecore.h" 37316485Sdavidcs#include "ecore_status.h" 38316485Sdavidcs#include "ecore_chain.h" 39316485Sdavidcs#include "ecore_spq.h" 40316485Sdavidcs#include "ecore_init_fw_funcs.h" 41316485Sdavidcs#include "ecore_cxt.h" 42316485Sdavidcs#include "ecore_sp_commands.h" 43316485Sdavidcs#include "ecore_gtt_reg_addr.h" 44316485Sdavidcs#include "ecore_iro.h" 45316485Sdavidcs#include "reg_addr.h" 46316485Sdavidcs#include "ecore_int.h" 47316485Sdavidcs#include "ecore_hw.h" 48316485Sdavidcs#include "ecore_dcbx.h" 49316485Sdavidcs#include "ecore_sriov.h" 50316485Sdavidcs#include "ecore_vf.h" 51337519Sdavidcs#ifndef LINUX_REMOVE 52337519Sdavidcs#include "ecore_tcp_ip.h" 53337519Sdavidcs#endif 54316485Sdavidcs 55316485Sdavidcsenum _ecore_status_t ecore_sp_init_request(struct ecore_hwfn *p_hwfn, 56316485Sdavidcs struct ecore_spq_entry **pp_ent, 57316485Sdavidcs u8 cmd, 58316485Sdavidcs u8 protocol, 59316485Sdavidcs struct ecore_sp_init_data *p_data) 60316485Sdavidcs{ 61316485Sdavidcs u32 opaque_cid = p_data->opaque_fid << 16 | p_data->cid; 62316485Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 63316485Sdavidcs enum _ecore_status_t rc; 64316485Sdavidcs 65316485Sdavidcs if (!pp_ent) 66316485Sdavidcs return ECORE_INVAL; 67316485Sdavidcs 68316485Sdavidcs /* Get an SPQ entry */ 69316485Sdavidcs rc = ecore_spq_get_entry(p_hwfn, pp_ent); 70316485Sdavidcs if (rc != ECORE_SUCCESS) 71316485Sdavidcs return rc; 72316485Sdavidcs 73316485Sdavidcs /* Fill the SPQ entry */ 74316485Sdavidcs p_ent = *pp_ent; 75316485Sdavidcs p_ent->elem.hdr.cid = OSAL_CPU_TO_LE32(opaque_cid); 76316485Sdavidcs p_ent->elem.hdr.cmd_id = cmd; 77316485Sdavidcs p_ent->elem.hdr.protocol_id = protocol; 78316485Sdavidcs p_ent->priority = ECORE_SPQ_PRIORITY_NORMAL; 79316485Sdavidcs p_ent->comp_mode = p_data->comp_mode; 80316485Sdavidcs p_ent->comp_done.done = 0; 81316485Sdavidcs 82316485Sdavidcs switch (p_ent->comp_mode) { 83316485Sdavidcs case ECORE_SPQ_MODE_EBLOCK: 84316485Sdavidcs p_ent->comp_cb.cookie = &p_ent->comp_done; 85316485Sdavidcs break; 86316485Sdavidcs 87316485Sdavidcs case ECORE_SPQ_MODE_BLOCK: 88316485Sdavidcs if (!p_data->p_comp_data) 89316485Sdavidcs return ECORE_INVAL; 90316485Sdavidcs 91316485Sdavidcs p_ent->comp_cb.cookie = p_data->p_comp_data->cookie; 92316485Sdavidcs break; 93316485Sdavidcs 94316485Sdavidcs case ECORE_SPQ_MODE_CB: 95316485Sdavidcs if (!p_data->p_comp_data) 96316485Sdavidcs p_ent->comp_cb.function = OSAL_NULL; 97316485Sdavidcs else 98316485Sdavidcs p_ent->comp_cb = *p_data->p_comp_data; 99316485Sdavidcs break; 100316485Sdavidcs 101316485Sdavidcs default: 102316485Sdavidcs DP_NOTICE(p_hwfn, true, "Unknown SPQE completion mode %d\n", 103316485Sdavidcs p_ent->comp_mode); 104316485Sdavidcs return ECORE_INVAL; 105316485Sdavidcs } 106316485Sdavidcs 107316485Sdavidcs DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, 108337519Sdavidcs "Initialized: CID %08x cmd %02x protocol %02x data_addr %llx comp_mode [%s]\n", 109316485Sdavidcs opaque_cid, cmd, protocol, 110337519Sdavidcs (unsigned long long)(osal_uintptr_t)&p_ent->ramrod, 111316485Sdavidcs D_TRINE(p_ent->comp_mode, ECORE_SPQ_MODE_EBLOCK, 112316485Sdavidcs ECORE_SPQ_MODE_BLOCK, "MODE_EBLOCK", "MODE_BLOCK", 113316485Sdavidcs "MODE_CB")); 114316485Sdavidcs 115316485Sdavidcs OSAL_MEMSET(&p_ent->ramrod, 0, sizeof(p_ent->ramrod)); 116316485Sdavidcs 117316485Sdavidcs return ECORE_SUCCESS; 118316485Sdavidcs} 119316485Sdavidcs 120316485Sdavidcsstatic enum tunnel_clss ecore_tunn_clss_to_fw_clss(u8 type) 121316485Sdavidcs{ 122316485Sdavidcs switch (type) { 123316485Sdavidcs case ECORE_TUNN_CLSS_MAC_VLAN: 124316485Sdavidcs return TUNNEL_CLSS_MAC_VLAN; 125316485Sdavidcs case ECORE_TUNN_CLSS_MAC_VNI: 126316485Sdavidcs return TUNNEL_CLSS_MAC_VNI; 127316485Sdavidcs case ECORE_TUNN_CLSS_INNER_MAC_VLAN: 128316485Sdavidcs return TUNNEL_CLSS_INNER_MAC_VLAN; 129316485Sdavidcs case ECORE_TUNN_CLSS_INNER_MAC_VNI: 130316485Sdavidcs return TUNNEL_CLSS_INNER_MAC_VNI; 131316485Sdavidcs case ECORE_TUNN_CLSS_MAC_VLAN_DUAL_STAGE: 132316485Sdavidcs return TUNNEL_CLSS_MAC_VLAN_DUAL_STAGE; 133316485Sdavidcs default: 134316485Sdavidcs return TUNNEL_CLSS_MAC_VLAN; 135316485Sdavidcs } 136316485Sdavidcs} 137316485Sdavidcs 138316485Sdavidcsstatic void 139316485Sdavidcsecore_set_pf_update_tunn_mode(struct ecore_tunnel_info *p_tun, 140316485Sdavidcs struct ecore_tunnel_info *p_src, 141316485Sdavidcs bool b_pf_start) 142316485Sdavidcs{ 143316485Sdavidcs if (p_src->vxlan.b_update_mode || b_pf_start) 144316485Sdavidcs p_tun->vxlan.b_mode_enabled = p_src->vxlan.b_mode_enabled; 145316485Sdavidcs 146316485Sdavidcs if (p_src->l2_gre.b_update_mode || b_pf_start) 147316485Sdavidcs p_tun->l2_gre.b_mode_enabled = p_src->l2_gre.b_mode_enabled; 148316485Sdavidcs 149316485Sdavidcs if (p_src->ip_gre.b_update_mode || b_pf_start) 150316485Sdavidcs p_tun->ip_gre.b_mode_enabled = p_src->ip_gre.b_mode_enabled; 151316485Sdavidcs 152316485Sdavidcs if (p_src->l2_geneve.b_update_mode || b_pf_start) 153316485Sdavidcs p_tun->l2_geneve.b_mode_enabled = 154316485Sdavidcs p_src->l2_geneve.b_mode_enabled; 155316485Sdavidcs 156316485Sdavidcs if (p_src->ip_geneve.b_update_mode || b_pf_start) 157316485Sdavidcs p_tun->ip_geneve.b_mode_enabled = 158316485Sdavidcs p_src->ip_geneve.b_mode_enabled; 159316485Sdavidcs} 160316485Sdavidcs 161316485Sdavidcsstatic void ecore_set_tunn_cls_info(struct ecore_tunnel_info *p_tun, 162316485Sdavidcs struct ecore_tunnel_info *p_src) 163316485Sdavidcs{ 164316485Sdavidcs enum tunnel_clss type; 165316485Sdavidcs 166316485Sdavidcs p_tun->b_update_rx_cls = p_src->b_update_rx_cls; 167316485Sdavidcs p_tun->b_update_tx_cls = p_src->b_update_tx_cls; 168316485Sdavidcs 169316485Sdavidcs type = ecore_tunn_clss_to_fw_clss(p_src->vxlan.tun_cls); 170316485Sdavidcs p_tun->vxlan.tun_cls = (enum ecore_tunn_clss)type; 171316485Sdavidcs type = ecore_tunn_clss_to_fw_clss(p_src->l2_gre.tun_cls); 172316485Sdavidcs p_tun->l2_gre.tun_cls = (enum ecore_tunn_clss)type; 173316485Sdavidcs type = ecore_tunn_clss_to_fw_clss(p_src->ip_gre.tun_cls); 174316485Sdavidcs p_tun->ip_gre.tun_cls = (enum ecore_tunn_clss)type; 175316485Sdavidcs type = ecore_tunn_clss_to_fw_clss(p_src->l2_geneve.tun_cls); 176316485Sdavidcs p_tun->l2_geneve.tun_cls = (enum ecore_tunn_clss)type; 177316485Sdavidcs type = ecore_tunn_clss_to_fw_clss(p_src->ip_geneve.tun_cls); 178316485Sdavidcs p_tun->ip_geneve.tun_cls = (enum ecore_tunn_clss)type; 179316485Sdavidcs} 180316485Sdavidcs 181316485Sdavidcsstatic void ecore_set_tunn_ports(struct ecore_tunnel_info *p_tun, 182316485Sdavidcs struct ecore_tunnel_info *p_src) 183316485Sdavidcs{ 184316485Sdavidcs p_tun->geneve_port.b_update_port = p_src->geneve_port.b_update_port; 185316485Sdavidcs p_tun->vxlan_port.b_update_port = p_src->vxlan_port.b_update_port; 186316485Sdavidcs 187316485Sdavidcs if (p_src->geneve_port.b_update_port) 188316485Sdavidcs p_tun->geneve_port.port = p_src->geneve_port.port; 189316485Sdavidcs 190316485Sdavidcs if (p_src->vxlan_port.b_update_port) 191316485Sdavidcs p_tun->vxlan_port.port = p_src->vxlan_port.port; 192316485Sdavidcs} 193316485Sdavidcs 194316485Sdavidcsstatic void 195316485Sdavidcs__ecore_set_ramrod_tunnel_param(u8 *p_tunn_cls, 196316485Sdavidcs struct ecore_tunn_update_type *tun_type) 197316485Sdavidcs{ 198316485Sdavidcs *p_tunn_cls = tun_type->tun_cls; 199316485Sdavidcs} 200316485Sdavidcs 201316485Sdavidcsstatic void 202316485Sdavidcsecore_set_ramrod_tunnel_param(u8 *p_tunn_cls, 203316485Sdavidcs struct ecore_tunn_update_type *tun_type, 204316485Sdavidcs u8 *p_update_port, __le16 *p_port, 205316485Sdavidcs struct ecore_tunn_update_udp_port *p_udp_port) 206316485Sdavidcs{ 207316485Sdavidcs __ecore_set_ramrod_tunnel_param(p_tunn_cls, tun_type); 208316485Sdavidcs if (p_udp_port->b_update_port) { 209316485Sdavidcs *p_update_port = 1; 210316485Sdavidcs *p_port = OSAL_CPU_TO_LE16(p_udp_port->port); 211316485Sdavidcs } 212316485Sdavidcs} 213316485Sdavidcs 214316485Sdavidcsstatic void 215316485Sdavidcsecore_tunn_set_pf_update_params(struct ecore_hwfn *p_hwfn, 216316485Sdavidcs struct ecore_tunnel_info *p_src, 217316485Sdavidcs struct pf_update_tunnel_config *p_tunn_cfg) 218316485Sdavidcs{ 219316485Sdavidcs struct ecore_tunnel_info *p_tun = &p_hwfn->p_dev->tunnel; 220316485Sdavidcs 221316485Sdavidcs ecore_set_pf_update_tunn_mode(p_tun, p_src, false); 222316485Sdavidcs ecore_set_tunn_cls_info(p_tun, p_src); 223316485Sdavidcs ecore_set_tunn_ports(p_tun, p_src); 224316485Sdavidcs 225316485Sdavidcs ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_vxlan, 226316485Sdavidcs &p_tun->vxlan, 227316485Sdavidcs &p_tunn_cfg->set_vxlan_udp_port_flg, 228316485Sdavidcs &p_tunn_cfg->vxlan_udp_port, 229316485Sdavidcs &p_tun->vxlan_port); 230316485Sdavidcs 231316485Sdavidcs ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_l2geneve, 232316485Sdavidcs &p_tun->l2_geneve, 233316485Sdavidcs &p_tunn_cfg->set_geneve_udp_port_flg, 234316485Sdavidcs &p_tunn_cfg->geneve_udp_port, 235316485Sdavidcs &p_tun->geneve_port); 236316485Sdavidcs 237316485Sdavidcs __ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_ipgeneve, 238316485Sdavidcs &p_tun->ip_geneve); 239316485Sdavidcs 240316485Sdavidcs __ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_l2gre, 241316485Sdavidcs &p_tun->l2_gre); 242316485Sdavidcs 243316485Sdavidcs __ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_ipgre, 244316485Sdavidcs &p_tun->ip_gre); 245316485Sdavidcs 246316485Sdavidcs p_tunn_cfg->update_rx_pf_clss = p_tun->b_update_rx_cls; 247316485Sdavidcs} 248316485Sdavidcs 249316485Sdavidcsstatic void ecore_set_hw_tunn_mode(struct ecore_hwfn *p_hwfn, 250316485Sdavidcs struct ecore_ptt *p_ptt, 251316485Sdavidcs struct ecore_tunnel_info *p_tun) 252316485Sdavidcs{ 253316485Sdavidcs ecore_set_gre_enable(p_hwfn, p_ptt, p_tun->l2_gre.b_mode_enabled, 254316485Sdavidcs p_tun->ip_gre.b_mode_enabled); 255316485Sdavidcs ecore_set_vxlan_enable(p_hwfn, p_ptt, p_tun->vxlan.b_mode_enabled); 256316485Sdavidcs 257316485Sdavidcs ecore_set_geneve_enable(p_hwfn, p_ptt, p_tun->l2_geneve.b_mode_enabled, 258316485Sdavidcs p_tun->ip_geneve.b_mode_enabled); 259316485Sdavidcs} 260316485Sdavidcs 261316485Sdavidcsstatic void ecore_set_hw_tunn_mode_port(struct ecore_hwfn *p_hwfn, 262320162Sdavidcs struct ecore_ptt *p_ptt, 263316485Sdavidcs struct ecore_tunnel_info *p_tunn) 264316485Sdavidcs{ 265316485Sdavidcs if (ECORE_IS_BB_A0(p_hwfn->p_dev)) { 266316485Sdavidcs DP_NOTICE(p_hwfn, true, 267316485Sdavidcs "A0 chip: tunnel hw config is not supported\n"); 268316485Sdavidcs return; 269316485Sdavidcs } 270316485Sdavidcs 271316485Sdavidcs if (p_tunn->vxlan_port.b_update_port) 272320162Sdavidcs ecore_set_vxlan_dest_port(p_hwfn, p_ptt, 273316485Sdavidcs p_tunn->vxlan_port.port); 274316485Sdavidcs 275316485Sdavidcs if (p_tunn->geneve_port.b_update_port) 276320162Sdavidcs ecore_set_geneve_dest_port(p_hwfn, p_ptt, 277316485Sdavidcs p_tunn->geneve_port.port); 278316485Sdavidcs 279320162Sdavidcs ecore_set_hw_tunn_mode(p_hwfn, p_ptt, p_tunn); 280316485Sdavidcs} 281316485Sdavidcs 282316485Sdavidcsstatic void 283316485Sdavidcsecore_tunn_set_pf_start_params(struct ecore_hwfn *p_hwfn, 284316485Sdavidcs struct ecore_tunnel_info *p_src, 285316485Sdavidcs struct pf_start_tunnel_config *p_tunn_cfg) 286316485Sdavidcs{ 287316485Sdavidcs struct ecore_tunnel_info *p_tun = &p_hwfn->p_dev->tunnel; 288316485Sdavidcs 289316485Sdavidcs if (ECORE_IS_BB_A0(p_hwfn->p_dev)) { 290316485Sdavidcs DP_NOTICE(p_hwfn, true, 291316485Sdavidcs "A0 chip: tunnel pf start config is not supported\n"); 292316485Sdavidcs return; 293316485Sdavidcs } 294316485Sdavidcs 295316485Sdavidcs if (!p_src) 296316485Sdavidcs return; 297316485Sdavidcs 298316485Sdavidcs ecore_set_pf_update_tunn_mode(p_tun, p_src, true); 299316485Sdavidcs ecore_set_tunn_cls_info(p_tun, p_src); 300316485Sdavidcs ecore_set_tunn_ports(p_tun, p_src); 301316485Sdavidcs 302316485Sdavidcs ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_vxlan, 303316485Sdavidcs &p_tun->vxlan, 304316485Sdavidcs &p_tunn_cfg->set_vxlan_udp_port_flg, 305316485Sdavidcs &p_tunn_cfg->vxlan_udp_port, 306316485Sdavidcs &p_tun->vxlan_port); 307316485Sdavidcs 308316485Sdavidcs ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_l2geneve, 309316485Sdavidcs &p_tun->l2_geneve, 310316485Sdavidcs &p_tunn_cfg->set_geneve_udp_port_flg, 311316485Sdavidcs &p_tunn_cfg->geneve_udp_port, 312316485Sdavidcs &p_tun->geneve_port); 313316485Sdavidcs 314316485Sdavidcs __ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_ipgeneve, 315316485Sdavidcs &p_tun->ip_geneve); 316316485Sdavidcs 317316485Sdavidcs __ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_l2gre, 318316485Sdavidcs &p_tun->l2_gre); 319316485Sdavidcs 320316485Sdavidcs __ecore_set_ramrod_tunnel_param(&p_tunn_cfg->tunnel_clss_ipgre, 321316485Sdavidcs &p_tun->ip_gre); 322316485Sdavidcs} 323316485Sdavidcs 324337519Sdavidcsenum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn, 325320162Sdavidcs struct ecore_ptt *p_ptt, 326316485Sdavidcs struct ecore_tunnel_info *p_tunn, 327316485Sdavidcs bool allow_npar_tx_switch) 328316485Sdavidcs{ 329316485Sdavidcs struct pf_start_ramrod_data *p_ramrod = OSAL_NULL; 330316485Sdavidcs u16 sb = ecore_int_get_sp_sb_id(p_hwfn); 331316485Sdavidcs u8 sb_index = p_hwfn->p_eq->eq_sb_index; 332316485Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 333316485Sdavidcs struct ecore_sp_init_data init_data; 334316485Sdavidcs enum _ecore_status_t rc = ECORE_NOTIMPL; 335316485Sdavidcs u8 page_cnt; 336337519Sdavidcs u8 i; 337316485Sdavidcs 338316485Sdavidcs /* update initial eq producer */ 339316485Sdavidcs ecore_eq_prod_update(p_hwfn, 340316485Sdavidcs ecore_chain_get_prod_idx(&p_hwfn->p_eq->chain)); 341316485Sdavidcs 342316485Sdavidcs /* Initialize the SPQ entry for the ramrod */ 343316485Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 344316485Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 345316485Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 346316485Sdavidcs init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK; 347316485Sdavidcs 348316485Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 349316485Sdavidcs COMMON_RAMROD_PF_START, 350316485Sdavidcs PROTOCOLID_COMMON, 351316485Sdavidcs &init_data); 352316485Sdavidcs if (rc != ECORE_SUCCESS) 353316485Sdavidcs return rc; 354316485Sdavidcs 355316485Sdavidcs /* Fill the ramrod data */ 356316485Sdavidcs p_ramrod = &p_ent->ramrod.pf_start; 357316485Sdavidcs p_ramrod->event_ring_sb_id = OSAL_CPU_TO_LE16(sb); 358316485Sdavidcs p_ramrod->event_ring_sb_index = sb_index; 359316485Sdavidcs p_ramrod->path_id = ECORE_PATH_ID(p_hwfn); 360316485Sdavidcs 361316485Sdavidcs /* For easier debugging */ 362316485Sdavidcs p_ramrod->dont_log_ramrods = 0; 363316485Sdavidcs p_ramrod->log_type_mask = OSAL_CPU_TO_LE16(0x8f); 364316485Sdavidcs 365337519Sdavidcs if (OSAL_TEST_BIT(ECORE_MF_OVLAN_CLSS, &p_hwfn->p_dev->mf_bits)) 366316485Sdavidcs p_ramrod->mf_mode = MF_OVLAN; 367337519Sdavidcs else 368316485Sdavidcs p_ramrod->mf_mode = MF_NPAR; 369337519Sdavidcs 370337519Sdavidcs p_ramrod->outer_tag_config.outer_tag.tci = 371337519Sdavidcs OSAL_CPU_TO_LE16(p_hwfn->hw_info.ovlan); 372337519Sdavidcs if (OSAL_TEST_BIT(ECORE_MF_8021Q_TAGGING, &p_hwfn->p_dev->mf_bits)) 373337519Sdavidcs p_ramrod->outer_tag_config.outer_tag.tpid = ETH_P_8021Q; 374337519Sdavidcs else if (OSAL_TEST_BIT(ECORE_MF_8021AD_TAGGING, 375337519Sdavidcs &p_hwfn->p_dev->mf_bits)) { 376337519Sdavidcs p_ramrod->outer_tag_config.outer_tag.tpid = ETH_P_8021AD; 377337519Sdavidcs p_ramrod->outer_tag_config.enable_stag_pri_change = 1; 378316485Sdavidcs } 379316485Sdavidcs 380337519Sdavidcs p_ramrod->outer_tag_config.pri_map_valid = 1; 381337519Sdavidcs for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) 382337519Sdavidcs p_ramrod->outer_tag_config.inner_to_outer_pri_map[i] = i; 383337519Sdavidcs 384337519Sdavidcs /* enable_stag_pri_change should be set if port is in BD mode or, 385337519Sdavidcs * UFP with Host Control mode or, UFP with DCB over base interface. 386337519Sdavidcs */ 387337519Sdavidcs if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits)) { 388337519Sdavidcs if ((p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS) || 389337519Sdavidcs (p_hwfn->p_dcbx_info->results.dcbx_enabled)) 390337519Sdavidcs p_ramrod->outer_tag_config.enable_stag_pri_change = 1; 391337519Sdavidcs else 392337519Sdavidcs p_ramrod->outer_tag_config.enable_stag_pri_change = 0; 393337519Sdavidcs } 394337519Sdavidcs 395316485Sdavidcs /* Place EQ address in RAMROD */ 396316485Sdavidcs DMA_REGPAIR_LE(p_ramrod->event_ring_pbl_addr, 397316485Sdavidcs p_hwfn->p_eq->chain.pbl_sp.p_phys_table); 398316485Sdavidcs page_cnt = (u8)ecore_chain_get_page_cnt(&p_hwfn->p_eq->chain); 399316485Sdavidcs p_ramrod->event_ring_num_pages = page_cnt; 400316485Sdavidcs DMA_REGPAIR_LE(p_ramrod->consolid_q_pbl_addr, 401316485Sdavidcs p_hwfn->p_consq->chain.pbl_sp.p_phys_table); 402316485Sdavidcs 403316485Sdavidcs ecore_tunn_set_pf_start_params(p_hwfn, p_tunn, 404316485Sdavidcs &p_ramrod->tunnel_config); 405316485Sdavidcs 406337519Sdavidcs if (OSAL_TEST_BIT(ECORE_MF_INTER_PF_SWITCH, 407337519Sdavidcs &p_hwfn->p_dev->mf_bits)) 408316485Sdavidcs p_ramrod->allow_npar_tx_switching = allow_npar_tx_switch; 409316485Sdavidcs 410316485Sdavidcs switch (p_hwfn->hw_info.personality) { 411316485Sdavidcs case ECORE_PCI_ETH: 412316485Sdavidcs p_ramrod->personality = PERSONALITY_ETH; 413316485Sdavidcs break; 414316485Sdavidcs case ECORE_PCI_FCOE: 415316485Sdavidcs p_ramrod->personality = PERSONALITY_FCOE; 416316485Sdavidcs break; 417316485Sdavidcs case ECORE_PCI_ISCSI: 418316485Sdavidcs p_ramrod->personality = PERSONALITY_ISCSI; 419316485Sdavidcs break; 420316485Sdavidcs case ECORE_PCI_ETH_IWARP: 421316485Sdavidcs case ECORE_PCI_ETH_ROCE: 422316485Sdavidcs case ECORE_PCI_ETH_RDMA: 423316485Sdavidcs p_ramrod->personality = PERSONALITY_RDMA_AND_ETH; 424316485Sdavidcs break; 425316485Sdavidcs default: 426316485Sdavidcs DP_NOTICE(p_hwfn, true, "Unknown personality %d\n", 427316485Sdavidcs p_hwfn->hw_info.personality); 428316485Sdavidcs p_ramrod->personality = PERSONALITY_ETH; 429316485Sdavidcs } 430316485Sdavidcs 431316485Sdavidcs if (p_hwfn->p_dev->p_iov_info) { 432316485Sdavidcs struct ecore_hw_sriov_info *p_iov = p_hwfn->p_dev->p_iov_info; 433316485Sdavidcs 434316485Sdavidcs p_ramrod->base_vf_id = (u8)p_iov->first_vf_in_pf; 435316485Sdavidcs p_ramrod->num_vfs = (u8)p_iov->total_vfs; 436316485Sdavidcs } 437316485Sdavidcs /* @@@TBD - update also the "ROCE_VER_KEY" entries when the FW RoCE HSI 438316485Sdavidcs * version is available. 439316485Sdavidcs */ 440316485Sdavidcs p_ramrod->hsi_fp_ver.major_ver_arr[ETH_VER_KEY] = ETH_HSI_VER_MAJOR; 441316485Sdavidcs p_ramrod->hsi_fp_ver.minor_ver_arr[ETH_VER_KEY] = ETH_HSI_VER_MINOR; 442316485Sdavidcs 443316485Sdavidcs DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, 444337519Sdavidcs "Setting event_ring_sb [id %04x index %02x], outer_tag.tpid [%d], outer_tag.tci [%d]\n", 445337519Sdavidcs sb, sb_index, p_ramrod->outer_tag_config.outer_tag.tpid, 446337519Sdavidcs p_ramrod->outer_tag_config.outer_tag.tci); 447316485Sdavidcs 448316485Sdavidcs rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 449316485Sdavidcs 450316485Sdavidcs if (p_tunn) 451320162Sdavidcs ecore_set_hw_tunn_mode_port(p_hwfn, p_ptt, 452320162Sdavidcs &p_hwfn->p_dev->tunnel); 453316485Sdavidcs 454316485Sdavidcs return rc; 455316485Sdavidcs} 456316485Sdavidcs 457320162Sdavidcsenum _ecore_status_t ecore_sp_pf_update_dcbx(struct ecore_hwfn *p_hwfn) 458316485Sdavidcs{ 459316485Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 460316485Sdavidcs struct ecore_sp_init_data init_data; 461316485Sdavidcs enum _ecore_status_t rc = ECORE_NOTIMPL; 462316485Sdavidcs 463316485Sdavidcs /* Get SPQ entry */ 464316485Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 465316485Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 466316485Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 467316485Sdavidcs init_data.comp_mode = ECORE_SPQ_MODE_CB; 468316485Sdavidcs 469316485Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 470316485Sdavidcs COMMON_RAMROD_PF_UPDATE, PROTOCOLID_COMMON, 471316485Sdavidcs &init_data); 472316485Sdavidcs if (rc != ECORE_SUCCESS) 473316485Sdavidcs return rc; 474316485Sdavidcs 475316485Sdavidcs ecore_dcbx_set_pf_update_params(&p_hwfn->p_dcbx_info->results, 476316485Sdavidcs &p_ent->ramrod.pf_update); 477316485Sdavidcs 478316485Sdavidcs return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 479316485Sdavidcs} 480316485Sdavidcs 481337519Sdavidcsenum _ecore_status_t ecore_sp_pf_update_ufp(struct ecore_hwfn *p_hwfn) 482337519Sdavidcs{ 483337519Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 484337519Sdavidcs struct ecore_sp_init_data init_data; 485337519Sdavidcs enum _ecore_status_t rc = ECORE_NOTIMPL; 486337519Sdavidcs 487337519Sdavidcs if (p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_UNKNOWN) { 488337519Sdavidcs DP_INFO(p_hwfn, "Invalid priority type %d\n", 489337519Sdavidcs p_hwfn->ufp_info.pri_type); 490337519Sdavidcs return ECORE_INVAL; 491337519Sdavidcs } 492337519Sdavidcs 493337519Sdavidcs /* Get SPQ entry */ 494337519Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 495337519Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 496337519Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 497337519Sdavidcs init_data.comp_mode = ECORE_SPQ_MODE_CB; 498337519Sdavidcs 499337519Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 500337519Sdavidcs COMMON_RAMROD_PF_UPDATE, PROTOCOLID_COMMON, 501337519Sdavidcs &init_data); 502337519Sdavidcs if (rc != ECORE_SUCCESS) 503337519Sdavidcs return rc; 504337519Sdavidcs 505337519Sdavidcs p_ent->ramrod.pf_update.update_enable_stag_pri_change = true; 506337519Sdavidcs if ((p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS) || 507337519Sdavidcs (p_hwfn->p_dcbx_info->results.dcbx_enabled)) 508337519Sdavidcs p_ent->ramrod.pf_update.enable_stag_pri_change = 1; 509337519Sdavidcs else 510337519Sdavidcs p_ent->ramrod.pf_update.enable_stag_pri_change = 0; 511337519Sdavidcs 512337519Sdavidcs return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 513337519Sdavidcs} 514337519Sdavidcs 515337519Sdavidcs 516337519Sdavidcs/* QM rate limiter resolution is 1.6Mbps */ 517337519Sdavidcs#define QM_RL_RESOLUTION(mb_val) ((mb_val) * 10 / 16) 518337519Sdavidcs 519337519Sdavidcs/* FW uses 1/64k to express gd */ 520337519Sdavidcs#define FW_GD_RESOLUTION(gd) (64 * 1024 / (gd)) 521337519Sdavidcs 522337519Sdavidcsstatic u16 ecore_sp_rl_mb_to_qm(u32 mb_val) 523337519Sdavidcs{ 524337519Sdavidcs return (u16)OSAL_MIN_T(u32, (u16)(~0U), QM_RL_RESOLUTION(mb_val)); 525337519Sdavidcs} 526337519Sdavidcs 527337519Sdavidcsstatic u16 ecore_sp_rl_gd_denom(u32 gd) 528337519Sdavidcs{ 529337519Sdavidcs return gd ? (u16)OSAL_MIN_T(u32, (u16)(~0U), FW_GD_RESOLUTION(gd)) : 0; 530337519Sdavidcs} 531337519Sdavidcs 532316485Sdavidcsenum _ecore_status_t ecore_sp_rl_update(struct ecore_hwfn *p_hwfn, 533316485Sdavidcs struct ecore_rl_update_params *params) 534316485Sdavidcs{ 535316485Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 536316485Sdavidcs enum _ecore_status_t rc = ECORE_NOTIMPL; 537316485Sdavidcs struct rl_update_ramrod_data *rl_update; 538316485Sdavidcs struct ecore_sp_init_data init_data; 539316485Sdavidcs 540316485Sdavidcs /* Get SPQ entry */ 541316485Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 542316485Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 543316485Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 544316485Sdavidcs init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK; 545316485Sdavidcs 546316485Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 547316485Sdavidcs COMMON_RAMROD_RL_UPDATE, PROTOCOLID_COMMON, 548316485Sdavidcs &init_data); 549316485Sdavidcs if (rc != ECORE_SUCCESS) 550316485Sdavidcs return rc; 551316485Sdavidcs 552316485Sdavidcs rl_update = &p_ent->ramrod.rl_update; 553316485Sdavidcs 554316485Sdavidcs rl_update->qcn_update_param_flg = params->qcn_update_param_flg; 555316485Sdavidcs rl_update->dcqcn_update_param_flg = params->dcqcn_update_param_flg; 556316485Sdavidcs rl_update->rl_init_flg = params->rl_init_flg; 557316485Sdavidcs rl_update->rl_start_flg = params->rl_start_flg; 558316485Sdavidcs rl_update->rl_stop_flg = params->rl_stop_flg; 559316485Sdavidcs rl_update->rl_id_first = params->rl_id_first; 560316485Sdavidcs rl_update->rl_id_last = params->rl_id_last; 561316485Sdavidcs rl_update->rl_dc_qcn_flg = params->rl_dc_qcn_flg; 562316485Sdavidcs rl_update->rl_bc_rate = OSAL_CPU_TO_LE32(params->rl_bc_rate); 563337519Sdavidcs rl_update->rl_max_rate = OSAL_CPU_TO_LE16(ecore_sp_rl_mb_to_qm(params->rl_max_rate)); 564337519Sdavidcs rl_update->rl_r_ai = OSAL_CPU_TO_LE16(ecore_sp_rl_mb_to_qm(params->rl_r_ai)); 565337519Sdavidcs rl_update->rl_r_hai = OSAL_CPU_TO_LE16(ecore_sp_rl_mb_to_qm(params->rl_r_hai)); 566337519Sdavidcs rl_update->dcqcn_g = OSAL_CPU_TO_LE16(ecore_sp_rl_gd_denom(params->dcqcn_gd)); 567316485Sdavidcs rl_update->dcqcn_k_us = OSAL_CPU_TO_LE32(params->dcqcn_k_us); 568337519Sdavidcs rl_update->dcqcn_timeuot_us = OSAL_CPU_TO_LE32(params->dcqcn_timeuot_us); 569316485Sdavidcs rl_update->qcn_timeuot_us = OSAL_CPU_TO_LE32(params->qcn_timeuot_us); 570316485Sdavidcs 571337519Sdavidcs DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, "rl_params: qcn_update_param_flg %x, dcqcn_update_param_flg %x, rl_init_flg %x, rl_start_flg %x, rl_stop_flg %x, rl_id_first %x, rl_id_last %x, rl_dc_qcn_flg %x, rl_bc_rate %x, rl_max_rate %x, rl_r_ai %x, rl_r_hai %x, dcqcn_g %x, dcqcn_k_us %x, dcqcn_timeuot_us %x, qcn_timeuot_us %x\n", 572337519Sdavidcs rl_update->qcn_update_param_flg, rl_update->dcqcn_update_param_flg, 573337519Sdavidcs rl_update->rl_init_flg, rl_update->rl_start_flg, 574337519Sdavidcs rl_update->rl_stop_flg, rl_update->rl_id_first, 575337519Sdavidcs rl_update->rl_id_last, rl_update->rl_dc_qcn_flg, 576337519Sdavidcs rl_update->rl_bc_rate, rl_update->rl_max_rate, 577337519Sdavidcs rl_update->rl_r_ai, rl_update->rl_r_hai, 578337519Sdavidcs rl_update->dcqcn_g, rl_update->dcqcn_k_us, 579337519Sdavidcs rl_update->dcqcn_timeuot_us, rl_update->qcn_timeuot_us); 580337519Sdavidcs 581316485Sdavidcs return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 582316485Sdavidcs} 583316485Sdavidcs 584316485Sdavidcs/* Set pf update ramrod command params */ 585316485Sdavidcsenum _ecore_status_t 586316485Sdavidcsecore_sp_pf_update_tunn_cfg(struct ecore_hwfn *p_hwfn, 587320162Sdavidcs struct ecore_ptt *p_ptt, 588316485Sdavidcs struct ecore_tunnel_info *p_tunn, 589316485Sdavidcs enum spq_mode comp_mode, 590316485Sdavidcs struct ecore_spq_comp_cb *p_comp_data) 591316485Sdavidcs{ 592316485Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 593316485Sdavidcs struct ecore_sp_init_data init_data; 594316485Sdavidcs enum _ecore_status_t rc = ECORE_NOTIMPL; 595316485Sdavidcs 596316485Sdavidcs if (IS_VF(p_hwfn->p_dev)) 597316485Sdavidcs return ecore_vf_pf_tunnel_param_update(p_hwfn, p_tunn); 598316485Sdavidcs 599316485Sdavidcs if (ECORE_IS_BB_A0(p_hwfn->p_dev)) { 600316485Sdavidcs DP_NOTICE(p_hwfn, true, 601316485Sdavidcs "A0 chip: tunnel pf update config is not supported\n"); 602316485Sdavidcs return rc; 603316485Sdavidcs } 604316485Sdavidcs 605316485Sdavidcs if (!p_tunn) 606316485Sdavidcs return ECORE_INVAL; 607316485Sdavidcs 608316485Sdavidcs /* Get SPQ entry */ 609316485Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 610316485Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 611316485Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 612316485Sdavidcs init_data.comp_mode = comp_mode; 613316485Sdavidcs init_data.p_comp_data = p_comp_data; 614316485Sdavidcs 615316485Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 616316485Sdavidcs COMMON_RAMROD_PF_UPDATE, PROTOCOLID_COMMON, 617316485Sdavidcs &init_data); 618316485Sdavidcs if (rc != ECORE_SUCCESS) 619316485Sdavidcs return rc; 620316485Sdavidcs 621316485Sdavidcs ecore_tunn_set_pf_update_params(p_hwfn, p_tunn, 622316485Sdavidcs &p_ent->ramrod.pf_update.tunnel_config); 623316485Sdavidcs 624316485Sdavidcs rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 625316485Sdavidcs if (rc != ECORE_SUCCESS) 626316485Sdavidcs return rc; 627316485Sdavidcs 628320162Sdavidcs ecore_set_hw_tunn_mode_port(p_hwfn, p_ptt, &p_hwfn->p_dev->tunnel); 629316485Sdavidcs 630316485Sdavidcs return rc; 631316485Sdavidcs} 632316485Sdavidcs 633316485Sdavidcsenum _ecore_status_t ecore_sp_pf_stop(struct ecore_hwfn *p_hwfn) 634316485Sdavidcs{ 635316485Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 636316485Sdavidcs struct ecore_sp_init_data init_data; 637316485Sdavidcs enum _ecore_status_t rc = ECORE_NOTIMPL; 638316485Sdavidcs 639316485Sdavidcs /* Get SPQ entry */ 640316485Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 641316485Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 642316485Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 643316485Sdavidcs init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK; 644316485Sdavidcs 645316485Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 646316485Sdavidcs COMMON_RAMROD_PF_STOP, PROTOCOLID_COMMON, 647316485Sdavidcs &init_data); 648316485Sdavidcs if (rc != ECORE_SUCCESS) 649316485Sdavidcs return rc; 650316485Sdavidcs 651316485Sdavidcs return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 652316485Sdavidcs} 653316485Sdavidcs 654316485Sdavidcsenum _ecore_status_t ecore_sp_heartbeat_ramrod(struct ecore_hwfn *p_hwfn) 655316485Sdavidcs{ 656316485Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 657316485Sdavidcs struct ecore_sp_init_data init_data; 658316485Sdavidcs enum _ecore_status_t rc; 659316485Sdavidcs 660316485Sdavidcs /* Get SPQ entry */ 661316485Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 662316485Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 663316485Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 664316485Sdavidcs init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK; 665316485Sdavidcs 666316485Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 667316485Sdavidcs COMMON_RAMROD_EMPTY, PROTOCOLID_COMMON, 668316485Sdavidcs &init_data); 669316485Sdavidcs if (rc != ECORE_SUCCESS) 670316485Sdavidcs return rc; 671316485Sdavidcs 672316485Sdavidcs return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 673316485Sdavidcs} 674320162Sdavidcs 675320162Sdavidcsenum _ecore_status_t ecore_sp_pf_update_stag(struct ecore_hwfn *p_hwfn) 676320162Sdavidcs{ 677320162Sdavidcs struct ecore_spq_entry *p_ent = OSAL_NULL; 678320162Sdavidcs struct ecore_sp_init_data init_data; 679320162Sdavidcs enum _ecore_status_t rc = ECORE_NOTIMPL; 680320162Sdavidcs 681320162Sdavidcs /* Get SPQ entry */ 682320162Sdavidcs OSAL_MEMSET(&init_data, 0, sizeof(init_data)); 683320162Sdavidcs init_data.cid = ecore_spq_get_cid(p_hwfn); 684320162Sdavidcs init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; 685320162Sdavidcs init_data.comp_mode = ECORE_SPQ_MODE_CB; 686320162Sdavidcs 687320162Sdavidcs rc = ecore_sp_init_request(p_hwfn, &p_ent, 688320162Sdavidcs COMMON_RAMROD_PF_UPDATE, PROTOCOLID_COMMON, 689320162Sdavidcs &init_data); 690320162Sdavidcs if (rc != ECORE_SUCCESS) 691320162Sdavidcs return rc; 692320162Sdavidcs 693320162Sdavidcs p_ent->ramrod.pf_update.update_mf_vlan_flag = true; 694320162Sdavidcs p_ent->ramrod.pf_update.mf_vlan = OSAL_CPU_TO_LE16(p_hwfn->hw_info.ovlan); 695320162Sdavidcs 696320162Sdavidcs return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL); 697320162Sdavidcs} 698