1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2023 Corigine, Inc. 3 * All rights reserved. 4 */ 5 6 #include "nfp_common.h" 7 8 #include "nfp_common_log.h" 9 10 /* 11 * This is used by the reconfig protocol. It sets the maximum time waiting in 12 * milliseconds before a reconfig timeout happens. 13 */ 14 #define NFP_NET_POLL_TIMEOUT 5000 15 16 int 17 nfp_reconfig_real(struct nfp_hw *hw, 18 uint32_t update) 19 { 20 uint32_t cnt; 21 uint32_t new; 22 struct timespec wait; 23 24 PMD_DRV_LOG(DEBUG, "Writing to the configuration queue (%p)...", 25 hw->qcp_cfg); 26 27 if (hw->qcp_cfg == NULL) { 28 PMD_DRV_LOG(ERR, "Bad configuration queue pointer."); 29 return -ENXIO; 30 } 31 32 nfp_qcp_ptr_add(hw->qcp_cfg, NFP_QCP_WRITE_PTR, 1); 33 34 wait.tv_sec = 0; 35 wait.tv_nsec = 1000000; /* 1ms */ 36 37 PMD_DRV_LOG(DEBUG, "Polling for update ack..."); 38 39 /* Poll update field, waiting for NFP to ack the config */ 40 for (cnt = 0; ; cnt++) { 41 new = nn_cfg_readl(hw, NFP_NET_CFG_UPDATE); 42 if (new == 0) 43 break; 44 45 if ((new & NFP_NET_CFG_UPDATE_ERR) != 0) { 46 PMD_DRV_LOG(ERR, "Reconfig error: %#08x.", new); 47 return -1; 48 } 49 50 if (cnt >= NFP_NET_POLL_TIMEOUT) { 51 PMD_DRV_LOG(ERR, "Reconfig timeout for %#08x after %u ms.", 52 update, cnt); 53 return -EIO; 54 } 55 56 nanosleep(&wait, 0); /* waiting for a 1ms */ 57 } 58 59 PMD_DRV_LOG(DEBUG, "Ack DONE."); 60 return 0; 61 } 62 63 /** 64 * Reconfigure the NIC. 65 * 66 * Write the update word to the BAR and ping the reconfig queue. Then poll 67 * until the firmware has acknowledged the update by zeroing the update word. 68 * 69 * @param hw 70 * Device to reconfigure. 71 * @param ctrl 72 * The value for the ctrl field in the BAR config. 73 * @param update 74 * The value for the update field in the BAR config. 75 * 76 * @return 77 * - (0) if OK to reconfigure the device. 78 * - (-EIO) if I/O err and fail to reconfigure the device. 79 */ 80 int 81 nfp_reconfig(struct nfp_hw *hw, 82 uint32_t ctrl, 83 uint32_t update) 84 { 85 int ret; 86 87 rte_spinlock_lock(&hw->reconfig_lock); 88 89 nn_cfg_writel(hw, NFP_NET_CFG_CTRL, ctrl); 90 nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, update); 91 92 rte_wmb(); 93 94 ret = nfp_reconfig_real(hw, update); 95 96 rte_spinlock_unlock(&hw->reconfig_lock); 97 98 if (ret != 0) { 99 PMD_DRV_LOG(ERR, "Error NFP reconfig: ctrl=%#08x update=%#08x.", 100 ctrl, update); 101 return -EIO; 102 } 103 104 return 0; 105 } 106 107 /** 108 * Reconfigure the NIC for the extend ctrl BAR. 109 * 110 * Write the update word to the BAR and ping the reconfig queue. Then poll 111 * until the firmware has acknowledged the update by zeroing the update word. 112 * 113 * @param hw 114 * Device to reconfigure. 115 * @param ctrl_ext 116 * The value for the first word of extend ctrl field in the BAR config. 117 * @param update 118 * The value for the update field in the BAR config. 119 * 120 * @return 121 * - (0) if OK to reconfigure the device. 122 * - (-EIO) if I/O err and fail to reconfigure the device. 123 */ 124 int 125 nfp_ext_reconfig(struct nfp_hw *hw, 126 uint32_t ctrl_ext, 127 uint32_t update) 128 { 129 int ret; 130 131 rte_spinlock_lock(&hw->reconfig_lock); 132 133 nn_cfg_writel(hw, NFP_NET_CFG_CTRL_WORD1, ctrl_ext); 134 nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, update); 135 136 rte_wmb(); 137 138 ret = nfp_reconfig_real(hw, update); 139 140 rte_spinlock_unlock(&hw->reconfig_lock); 141 142 if (ret != 0) { 143 PMD_DRV_LOG(ERR, "Error NFP ext reconfig: ctrl_ext=%#08x update=%#08x.", 144 ctrl_ext, update); 145 return -EIO; 146 } 147 148 return 0; 149 } 150 151 void 152 nfp_read_mac(struct nfp_hw *hw) 153 { 154 uint32_t tmp; 155 156 tmp = rte_be_to_cpu_32(nn_cfg_readl(hw, NFP_NET_CFG_MACADDR)); 157 memcpy(&hw->mac_addr.addr_bytes[0], &tmp, 4); 158 159 tmp = rte_be_to_cpu_32(nn_cfg_readl(hw, NFP_NET_CFG_MACADDR + 4)); 160 memcpy(&hw->mac_addr.addr_bytes[4], &tmp, 2); 161 } 162 163 void 164 nfp_write_mac(struct nfp_hw *hw, 165 uint8_t *mac) 166 { 167 uint32_t mac0; 168 uint16_t mac1; 169 170 mac0 = *(uint32_t *)mac; 171 nn_writel(rte_cpu_to_be_32(mac0), hw->ctrl_bar + NFP_NET_CFG_MACADDR); 172 173 mac += 4; 174 mac1 = *(uint16_t *)mac; 175 nn_writew(rte_cpu_to_be_16(mac1), 176 hw->ctrl_bar + NFP_NET_CFG_MACADDR + 6); 177 } 178 179 void 180 nfp_enable_queues(struct nfp_hw *hw, 181 uint16_t nb_rx_queues, 182 uint16_t nb_tx_queues) 183 { 184 int i; 185 uint64_t enabled_queues; 186 187 /* Enabling the required TX queues in the device */ 188 enabled_queues = 0; 189 for (i = 0; i < nb_tx_queues; i++) 190 enabled_queues |= (1ULL << i); 191 192 nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, enabled_queues); 193 194 /* Enabling the required RX queues in the device */ 195 enabled_queues = 0; 196 for (i = 0; i < nb_rx_queues; i++) 197 enabled_queues |= (1ULL << i); 198 199 nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, enabled_queues); 200 } 201 202 void 203 nfp_disable_queues(struct nfp_hw *hw) 204 { 205 int ret; 206 uint32_t update; 207 uint32_t new_ctrl; 208 209 nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, 0); 210 nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, 0); 211 212 new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_ENABLE; 213 update = NFP_NET_CFG_UPDATE_GEN | 214 NFP_NET_CFG_UPDATE_RING | 215 NFP_NET_CFG_UPDATE_MSIX; 216 217 if ((hw->cap & NFP_NET_CFG_CTRL_RINGCFG) != 0) 218 new_ctrl &= ~NFP_NET_CFG_CTRL_RINGCFG; 219 220 /* If an error when reconfig we avoid to change hw state */ 221 ret = nfp_reconfig(hw, new_ctrl, update); 222 if (ret < 0) 223 return; 224 225 hw->ctrl = new_ctrl; 226 } 227