/* Responds to VF's READY message with VF's * ID, node, MAC address e.t.c * @vf: VF which sent READY message */ static void nic_mbx_send_ready(struct nicpf *nic, int vf) { union nic_mbx mbx = {}; int bgx_idx, lmac; const char *mac; mbx.nic_cfg.msg = NIC_MBOX_MSG_READY; mbx.nic_cfg.vf_id = vf; mbx.nic_cfg.tns_mode = NIC_TNS_BYPASS_MODE; if (vf < MAX_LMAC) { bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac); if (mac) ether_addr_copy((u8 *)&mbx.nic_cfg.mac_addr, mac); } mbx.nic_cfg.sqs_mode = (vf >= nic->num_vf_en) ? true : false; mbx.nic_cfg.node_id = nic->node; mbx.nic_cfg.loopback_supported = vf < MAX_LMAC; nic_send_msg_to_vf(nic, vf, &mbx); }
/* Update hardware min/max frame size */ static int nic_update_hw_frs(struct nicpf *nic, int new_frs, int vf) { int bgx, lmac, lmac_cnt; u64 lmac_credits; if ((new_frs > NIC_HW_MAX_FRS) || (new_frs < NIC_HW_MIN_FRS)) return 1; bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); lmac += bgx * MAX_LMAC_PER_BGX; new_frs += VLAN_ETH_HLEN + ETH_FCS_LEN + 4; /* Update corresponding LMAC credits */ lmac_cnt = bgx_get_lmac_count(nic->node, bgx); lmac_credits = nic_reg_read(nic, NIC_PF_LMAC_0_7_CREDIT + (lmac * 8)); lmac_credits &= ~(0xFFFFFULL << 12); lmac_credits |= (((((48 * 1024) / lmac_cnt) - new_frs) / 16) << 12); nic_reg_write(nic, NIC_PF_LMAC_0_7_CREDIT + (lmac * 8), lmac_credits); /* Enforce MTU in HW * This config is supported only from 88xx pass 2.0 onwards. */ if (!pass1_silicon(nic->pdev)) nic_reg_write(nic, NIC_PF_LMAC_0_7_CFG2 + (lmac * 8), new_frs); return 0; }
/* Get BGX Rx/Tx stats and respond to VF's request */ static void nic_get_bgx_stats(struct nicpf *nic, struct bgx_stats_msg *bgx) { int bgx_idx, lmac; union nic_mbx mbx = {}; bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[bgx->vf_id]); lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[bgx->vf_id]); mbx.bgx_stats.msg = NIC_MBOX_MSG_BGX_STATS; mbx.bgx_stats.vf_id = bgx->vf_id; mbx.bgx_stats.rx = bgx->rx; mbx.bgx_stats.idx = bgx->idx; if (bgx->rx) mbx.bgx_stats.stats = bgx_get_rx_stats(nic->node, bgx_idx, lmac, bgx->idx); else mbx.bgx_stats.stats = bgx_get_tx_stats(nic->node, bgx_idx, lmac, bgx->idx); nic_send_msg_to_vf(nic, bgx->vf_id, &mbx); }
/* Channel parse index configuration */ static void nic_config_cpi(struct nicpf *nic, struct cpi_cfg_msg *cfg) { u32 vnic, bgx, lmac, chan; u32 padd, cpi_count = 0; u64 cpi_base, cpi, rssi_base, rssi; u8 qset, rq_idx = 0; vnic = cfg->vf_id; bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]); lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]); chan = (lmac * MAX_BGX_CHANS_PER_LMAC) + (bgx * NIC_CHANS_PER_INF); cpi_base = (lmac * NIC_MAX_CPI_PER_LMAC) + (bgx * NIC_CPI_PER_BGX); rssi_base = (lmac * nic->rss_ind_tbl_size) + (bgx * NIC_RSSI_PER_BGX); /* Rx channel configuration */ nic_reg_write(nic, NIC_PF_CHAN_0_255_RX_BP_CFG | (chan << 3), (1ull << 63) | (vnic << 0)); nic_reg_write(nic, NIC_PF_CHAN_0_255_RX_CFG | (chan << 3), ((u64)cfg->cpi_alg << 62) | (cpi_base << 48)); if (cfg->cpi_alg == CPI_ALG_NONE) cpi_count = 1; else if (cfg->cpi_alg == CPI_ALG_VLAN) /* 3 bits of PCP */ cpi_count = 8; else if (cfg->cpi_alg == CPI_ALG_VLAN16) /* 3 bits PCP + DEI */ cpi_count = 16; else if (cfg->cpi_alg == CPI_ALG_DIFF) /* 6bits DSCP */ cpi_count = NIC_MAX_CPI_PER_LMAC; /* RSS Qset, Qidx mapping */ qset = cfg->vf_id; rssi = rssi_base; for (; rssi < (rssi_base + cfg->rq_cnt); rssi++) { nic_reg_write(nic, NIC_PF_RSSI_0_4097_RQ | (rssi << 3), (qset << 3) | rq_idx); rq_idx++; } rssi = 0; cpi = cpi_base; for (; cpi < (cpi_base + cpi_count); cpi++) { /* Determine port to channel adder */ if (cfg->cpi_alg != CPI_ALG_DIFF) padd = cpi % cpi_count; else padd = cpi % 8; /* 3 bits CS out of 6bits DSCP */ /* Leave RSS_SIZE as '0' to disable RSS */ if (pass1_silicon(nic)) { nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3), (vnic << 24) | (padd << 16) | (rssi_base + rssi)); } else { /* Set MPI_ALG to '0' to disable MCAM parsing */ nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3), (padd << 16)); /* MPI index is same as CPI if MPI_ALG is not enabled */ nic_reg_write(nic, NIC_PF_MPI_0_2047_CFG | (cpi << 3), (vnic << 24) | (rssi_base + rssi)); } if ((rssi + 1) >= cfg->rq_cnt) continue; if (cfg->cpi_alg == CPI_ALG_VLAN) rssi++; else if (cfg->cpi_alg == CPI_ALG_VLAN16) rssi = ((cpi - cpi_base) & 0xe) >> 1; else if (cfg->cpi_alg == CPI_ALG_DIFF) rssi = ((cpi - cpi_base) & 0x38) >> 3; }