+
+int
+nfp_nsp_eth_config(nspu_desc_t *desc, int port, int up)
+{
+ union eth_table_entry *entries, *entry;
+ int modified;
+ int ret, idx;
+ int i;
+
+ idx = port;
+
+ RTE_LOG(INFO, PMD, "Hw ethernet port %d configure...\n", port);
+ rte_spinlock_lock(&desc->nsp_lock);
+ entries = malloc(NSP_ETH_TABLE_SIZE);
+ if (!entries) {
+ rte_spinlock_unlock(&desc->nsp_lock);
+ return -ENOMEM;
+ }
+
+ ret = nspu_command(desc, NSP_CMD_READ_ETH_TABLE, 1, 0, entries,
+ NSP_ETH_TABLE_SIZE, 0);
+ if (ret) {
+ rte_spinlock_unlock(&desc->nsp_lock);
+ return ret;
+ }
+
+ entry = entries;
+
+ for (i = 0; i < NSP_ETH_MAX_COUNT; i++) {
+ /* ports in use do not appear sequentially in the table */
+ if (!(entry->port & NSP_ETH_PORT_LANES_MASK)) {
+ /* entry not in use */
+ entry++;
+ continue;
+ }
+ if (idx == 0)
+ break;
+ idx--;
+ entry++;
+ }
+
+ if (i == NSP_ETH_MAX_COUNT) {
+ rte_spinlock_unlock(&desc->nsp_lock);
+ return -EINVAL;
+ }
+
+ if (up && !(entry->state & NSP_ETH_STATE_CONFIGURED)) {
+ entry->control |= NSP_ETH_STATE_CONFIGURED;
+ modified = 1;
+ }
+
+ if (!up && (entry->state & NSP_ETH_STATE_CONFIGURED)) {
+ entry->control &= ~NSP_ETH_STATE_CONFIGURED;
+ modified = 1;
+ }
+
+ if (modified) {
+ ret = nspu_command(desc, NSP_CMD_WRITE_ETH_TABLE, 0, 1, entries,
+ 0, NSP_ETH_TABLE_SIZE);
+ if (!ret)
+ RTE_LOG(INFO, PMD,
+ "Hw ethernet port %d configure done\n", port);
+ else
+ RTE_LOG(INFO, PMD,
+ "Hw ethernet port %d configure failed\n", port);
+ }
+ rte_spinlock_unlock(&desc->nsp_lock);
+ return ret;
+}