; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Speed capabilities = Y
+Link status = Y
+Link status event = Y
+MTU update = Y
Linux UIO = Y
Linux VFIO = Y
x86-64 = Y
uint32_t nlifs;
uint32_t max_ntxqs_per_lif;
uint32_t max_nrxqs_per_lif;
+ uint32_t max_mac_addrs;
uint32_t link_speed;
uint32_t nintrs;
bool intrs[IONIC_INTR_CTRL_REGS_MAX];
#include "ionic_if.h"
#include "ionic_regs.h"
+#define IONIC_MIN_MTU RTE_ETHER_MIN_MTU
+#define IONIC_MAX_MTU 9194
+
#define IONIC_MAX_RING_DESC 32768
#define IONIC_MIN_RING_DESC 16
static int eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
static int eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev);
+static int ionic_dev_info_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_dev_info *dev_info);
+static int ionic_dev_configure(struct rte_eth_dev *dev);
+static int ionic_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
+static int ionic_dev_start(struct rte_eth_dev *dev);
+static void ionic_dev_stop(struct rte_eth_dev *dev);
+static void ionic_dev_close(struct rte_eth_dev *dev);
+static int ionic_dev_set_link_up(struct rte_eth_dev *dev);
+static int ionic_dev_set_link_down(struct rte_eth_dev *dev);
+static int ionic_dev_link_update(struct rte_eth_dev *eth_dev,
+ int wait_to_complete);
int ionic_logtype;
};
static const struct eth_dev_ops ionic_eth_dev_ops = {
+ .dev_infos_get = ionic_dev_info_get,
+ .dev_configure = ionic_dev_configure,
+ .mtu_set = ionic_dev_mtu_set,
+ .dev_start = ionic_dev_start,
+ .dev_stop = ionic_dev_stop,
+ .dev_close = ionic_dev_close,
+ .link_update = ionic_dev_link_update,
+ .dev_set_link_up = ionic_dev_set_link_up,
+ .dev_set_link_down = ionic_dev_set_link_down,
};
+/*
+ * Set device link up, enable tx.
+ */
+static int
+ionic_dev_set_link_up(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_dev *idev = &adapter->idev;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP);
+
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ if (err) {
+ IONIC_PRINT(WARNING, "Failed to bring port UP");
+ return err;
+ }
+
+ return 0;
+}
+
+/*
+ * Set device link down, disable tx.
+ */
+static int
+ionic_dev_set_link_down(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_dev *idev = &adapter->idev;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_DOWN);
+
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ if (err) {
+ IONIC_PRINT(WARNING, "Failed to bring port DOWN");
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+ionic_dev_link_update(struct rte_eth_dev *eth_dev,
+ int wait_to_complete __rte_unused)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct rte_eth_link link;
+
+ IONIC_PRINT_CALL();
+
+ /* Initialize */
+ memset(&link, 0, sizeof(link));
+ link.link_autoneg = ETH_LINK_AUTONEG;
+
+ if (!adapter->link_up) {
+ /* Interface is down */
+ link.link_status = ETH_LINK_DOWN;
+ link.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link.link_speed = ETH_SPEED_NUM_NONE;
+ } else {
+ /* Interface is up */
+ link.link_status = ETH_LINK_UP;
+ link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ switch (adapter->link_speed) {
+ case 10000:
+ link.link_speed = ETH_SPEED_NUM_10G;
+ break;
+ case 25000:
+ link.link_speed = ETH_SPEED_NUM_25G;
+ break;
+ case 40000:
+ link.link_speed = ETH_SPEED_NUM_40G;
+ break;
+ case 50000:
+ link.link_speed = ETH_SPEED_NUM_50G;
+ break;
+ case 100000:
+ link.link_speed = ETH_SPEED_NUM_100G;
+ break;
+ default:
+ link.link_speed = ETH_SPEED_NUM_NONE;
+ break;
+ }
+ }
+
+ return rte_eth_linkstatus_set(eth_dev, &link);
+}
+
/**
* Interrupt handler triggered by NIC for handling
* specific interrupt.
}
}
+static int
+ionic_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ uint32_t max_frame_size;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ /*
+ * Note: mtu check against IONIC_MIN_MTU, IONIC_MAX_MTU
+ * is done by the the API.
+ */
+
+ /*
+ * Max frame size is MTU + Ethernet header + VLAN + QinQ
+ * (plus ETHER_CRC_LEN if the adapter is able to keep CRC)
+ */
+ max_frame_size = mtu + RTE_ETHER_HDR_LEN + 4 + 4;
+
+ if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len < max_frame_size)
+ return -EINVAL;
+
+ err = ionic_lif_change_mtu(lif, mtu);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int
+ionic_dev_info_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_dev_info *dev_info)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_identity *ident = &adapter->ident;
+
+ IONIC_PRINT_CALL();
+
+ dev_info->max_rx_queues = (uint16_t)
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
+ dev_info->max_tx_queues = (uint16_t)
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
+ /* Also add ETHER_CRC_LEN if the adapter is able to keep CRC */
+ dev_info->min_rx_bufsize = IONIC_MIN_MTU + RTE_ETHER_HDR_LEN;
+ dev_info->max_rx_pktlen = IONIC_MAX_MTU + RTE_ETHER_HDR_LEN;
+ dev_info->max_mac_addrs = adapter->max_mac_addrs;
+ dev_info->min_mtu = IONIC_MIN_MTU;
+ dev_info->max_mtu = IONIC_MAX_MTU;
+
+ dev_info->speed_capa =
+ ETH_LINK_SPEED_10G |
+ ETH_LINK_SPEED_25G |
+ ETH_LINK_SPEED_40G |
+ ETH_LINK_SPEED_50G |
+ ETH_LINK_SPEED_100G;
+
+ return 0;
+}
+
+static int
+ionic_dev_configure(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_lif_configure(lif);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot configure LIF: %d", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static inline uint32_t
+ionic_parse_link_speeds(uint16_t link_speeds)
+{
+ if (link_speeds & ETH_LINK_SPEED_100G)
+ return 100000;
+ else if (link_speeds & ETH_LINK_SPEED_50G)
+ return 50000;
+ else if (link_speeds & ETH_LINK_SPEED_40G)
+ return 40000;
+ else if (link_speeds & ETH_LINK_SPEED_25G)
+ return 25000;
+ else if (link_speeds & ETH_LINK_SPEED_10G)
+ return 10000;
+ else
+ return 0;
+}
+
+/*
+ * Configure device link speed and setup link.
+ * It returns 0 on success.
+ */
+static int
+ionic_dev_start(struct rte_eth_dev *eth_dev)
+{
+ struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf;
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_dev *idev = &adapter->idev;
+ uint32_t allowed_speeds;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ allowed_speeds =
+ ETH_LINK_SPEED_FIXED |
+ ETH_LINK_SPEED_10G |
+ ETH_LINK_SPEED_25G |
+ ETH_LINK_SPEED_40G |
+ ETH_LINK_SPEED_50G |
+ ETH_LINK_SPEED_100G;
+
+ if (dev_conf->link_speeds & ~allowed_speeds) {
+ IONIC_PRINT(ERR, "Invalid link setting");
+ return -EINVAL;
+ }
+
+ err = ionic_lif_start(lif);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot start LIF: %d", err);
+ return err;
+ }
+
+ if (eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+ uint32_t speed = ionic_parse_link_speeds(dev_conf->link_speeds);
+
+ if (speed)
+ ionic_dev_cmd_port_speed(idev, speed);
+ }
+
+ ionic_dev_link_update(eth_dev, 0);
+
+ return 0;
+}
+
+/*
+ * Stop device: disable rx and tx functions to allow for reconfiguring.
+ */
+static void
+ionic_dev_stop(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_lif_stop(lif);
+ if (err)
+ IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
+}
+
+/*
+ * Reset and stop device.
+ */
+static void
+ionic_dev_close(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_lif_stop(lif);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
+ return;
+ }
+
+ err = eth_ionic_dev_uninit(eth_dev);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err);
+ return;
+ }
+}
+
static int
eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
{
lif->adapter = adapter;
adapter->lifs[adapter->nlifs] = lif;
+ IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported",
+ adapter->max_mac_addrs);
+
+ /* Allocate memory for storing MAC addresses */
+ eth_dev->data->mac_addrs = rte_zmalloc("ionic",
+ RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs, 0);
+
+ if (eth_dev->data->mac_addrs == NULL) {
+ IONIC_PRINT(ERR, "Failed to allocate %u bytes needed to "
+ "store MAC addresses",
+ RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs);
+ err = -ENOMEM;
+ goto err;
+ }
+
err = ionic_lif_alloc(lif);
if (err) {
IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting",
goto err_free_lif;
}
+ /* Copy the MAC address */
+ rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr,
+ ð_dev->data->mac_addrs[0]);
+
IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id);
return 0;
goto err_free_adapter;
}
+ adapter->max_mac_addrs = adapter->ident.lif.eth.max_ucast_filters;
+
adapter->nlifs = 0;
for (i = 0; i < adapter->ident.dev.nlifs; i++) {
snprintf(name, sizeof(name), "net_%s_lif_%lu",
#include "ionic_lif.h"
#include "ionic_ethdev.h"
+static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);
+static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);
+
int
ionic_qcq_enable(struct ionic_qcq *qcq)
{
return ionic_adminq_post_wait(lif, &ctx);
}
+int
+ionic_lif_stop(struct ionic_lif *lif __rte_unused)
+{
+ /* Carrier OFF here */
+
+ return 0;
+}
+
+void
+ionic_lif_reset(struct ionic_lif *lif)
+{
+ struct ionic_dev *idev = &lif->adapter->idev;
+
+ IONIC_PRINT_CALL();
+
+ ionic_dev_cmd_lif_reset(idev, lif->index);
+ ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+}
+
+static int
+ionic_lif_addr_add(struct ionic_lif *lif __rte_unused,
+ const uint8_t *addr __rte_unused)
+{
+ IONIC_PRINT(INFO, "%s: stubbed", __func__);
+
+ return 0;
+}
+
+static int
+ionic_lif_addr_del(struct ionic_lif *lif __rte_unused,
+ const uint8_t *addr __rte_unused)
+{
+ IONIC_PRINT(INFO, "%s: stubbed", __func__);
+
+ return 0;
+}
+
+static void
+ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.rx_mode_set = {
+ .opcode = IONIC_CMD_RX_MODE_SET,
+ .lif_index = lif->index,
+ .rx_mode = rx_mode,
+ },
+ };
+ int err;
+
+ if (rx_mode & IONIC_RX_MODE_F_UNICAST)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_UNICAST");
+ if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_MULTICAST");
+ if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_BROADCAST");
+ if (rx_mode & IONIC_RX_MODE_F_PROMISC)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_PROMISC");
+ if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_ALLMULTI");
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ IONIC_PRINT(ERR, "Failure setting RX mode");
+}
+
+static void
+ionic_set_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
+{
+ if (lif->rx_mode != rx_mode) {
+ lif->rx_mode = rx_mode;
+ ionic_lif_rx_mode(lif, rx_mode);
+ }
+}
+
+
+int
+ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_setattr = {
+ .opcode = IONIC_CMD_LIF_SETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_MTU,
+ .mtu = new_mtu,
+ },
+ };
+ int err;
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ return err;
+
+ lif->mtu = new_mtu;
+
+ return 0;
+}
+
int
ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
{
IONIC_PRINT(DEBUG, "Allocating Notify Queue");
err = ionic_notify_qcq_alloc(lif);
-
if (err) {
IONIC_PRINT(ERR, "Cannot allocate notify queue");
return err;
return 0;
}
+int
+ionic_lif_set_features(struct ionic_lif *lif)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_setattr = {
+ .opcode = IONIC_CMD_LIF_SETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_FEATURES,
+ .features = lif->features,
+ },
+ };
+ int err;
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ return err;
+
+ lif->hw_features = (ctx.cmd.lif_setattr.features &
+ ctx.comp.lif_setattr.features);
+
+ if (lif->hw_features & IONIC_ETH_HW_VLAN_TX_TAG)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_TX_TAG");
+ if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_STRIP)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_STRIP");
+ if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_FILTER)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_FILTER");
+ if (lif->hw_features & IONIC_ETH_HW_RX_HASH)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_HASH");
+ if (lif->hw_features & IONIC_ETH_HW_TX_SG)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_SG");
+ if (lif->hw_features & IONIC_ETH_HW_RX_SG)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_SG");
+ if (lif->hw_features & IONIC_ETH_HW_TX_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_CSUM");
+ if (lif->hw_features & IONIC_ETH_HW_RX_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_CSUM");
+ if (lif->hw_features & IONIC_ETH_HW_TSO)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_IPV6)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPV6");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_ECN)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_ECN");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_GRE)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_GRE_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE_CSUM");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP4)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP4");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP6)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP6");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_UDP)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP_CSUM");
+
+ return 0;
+}
+
+static int
+ionic_station_set(struct ionic_lif *lif)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_getattr = {
+ .opcode = IONIC_CMD_LIF_GETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_MAC,
+ },
+ };
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ return err;
+
+ if (!rte_is_zero_ether_addr((struct rte_ether_addr *)
+ lif->mac_addr)) {
+ IONIC_PRINT(INFO, "deleting station MAC addr");
+
+ ionic_lif_addr_del(lif, lif->mac_addr);
+ }
+
+ memcpy(lif->mac_addr, ctx.comp.lif_getattr.mac, RTE_ETHER_ADDR_LEN);
+
+ if (rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
+ IONIC_PRINT(NOTICE, "empty MAC addr (VF?)");
+ return 0;
+ }
+
+ IONIC_PRINT(DEBUG, "adding station MAC addr");
+
+ ionic_lif_addr_add(lif, lif->mac_addr);
+
+ return 0;
+}
+
+static void
+ionic_lif_set_name(struct ionic_lif *lif)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_setattr = {
+ .opcode = IONIC_CMD_LIF_SETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_NAME,
+ },
+ };
+
+ snprintf(ctx.cmd.lif_setattr.name, sizeof(ctx.cmd.lif_setattr.name),
+ "%d", lif->port_id);
+
+ ionic_adminq_post_wait(lif, &ctx);
+}
+
int
ionic_lif_init(struct ionic_lif *lif)
{
if (err)
goto err_out_adminq_deinit;
+ lif->features = 0;
+
+ err = ionic_lif_set_features(lif);
+ if (err)
+ goto err_out_notifyq_deinit;
+
+ err = ionic_station_set(lif);
+ if (err)
+ goto err_out_notifyq_deinit;
+
+ ionic_lif_set_name(lif);
+
lif->state |= IONIC_LIF_F_INITED;
return 0;
+err_out_notifyq_deinit:
+ ionic_lif_qcq_deinit(lif, lif->notifyqcq);
+
err_out_adminq_deinit:
ionic_lif_qcq_deinit(lif, lif->adminqcq);
lif->state &= ~IONIC_LIF_F_INITED;
}
+int
+ionic_lif_configure(struct ionic_lif *lif)
+{
+ lif->port_id = lif->eth_dev->data->port_id;
+
+ return 0;
+}
+
+int
+ionic_lif_start(struct ionic_lif *lif)
+{
+ uint32_t rx_mode = 0;
+
+ IONIC_PRINT(DEBUG, "Setting RX mode on port %u",
+ lif->port_id);
+
+ rx_mode |= IONIC_RX_MODE_F_UNICAST;
+ rx_mode |= IONIC_RX_MODE_F_MULTICAST;
+ rx_mode |= IONIC_RX_MODE_F_BROADCAST;
+
+ lif->rx_mode = 0; /* set by ionic_set_rx_mode */
+
+ ionic_set_rx_mode(lif, rx_mode);
+
+ ionic_link_status_check(lif);
+
+ /* Carrier ON here */
+
+ return 0;
+}
+
int
ionic_lif_identify(struct ionic_adapter *adapter)
{
struct ionic_adapter *adapter;
struct rte_eth_dev *eth_dev;
uint16_t port_id; /**< Device port identifier */
+ uint16_t mtu;
uint32_t index;
uint32_t hw_index;
uint32_t state;
struct ionic_qcq *notifyqcq;
struct ionic_doorbell __iomem *kern_dbpage;
uint64_t last_eid;
+ uint64_t features;
+ uint32_t hw_features;
+ uint32_t rx_mode;
char name[IONIC_LIF_NAME_MAX_SZ];
+ uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
uint32_t info_sz;
struct ionic_lif_info *info;
rte_iova_t info_pa;
void ionic_lif_deinit(struct ionic_lif *lif);
int ionic_lif_start(struct ionic_lif *lif);
+int ionic_lif_stop(struct ionic_lif *lif);
int ionic_lif_configure(struct ionic_lif *lif);
void ionic_lif_reset(struct ionic_lif *lif);
int ionic_qcq_service(struct ionic_qcq *qcq, int budget, ionic_cq_cb cb,
void *cb_arg);
+int ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu);
+
void ionic_qcq_free(struct ionic_qcq *qcq);
int ionic_qcq_enable(struct ionic_qcq *qcq);
int ionic_qcq_disable(struct ionic_qcq *qcq);
+int ionic_lif_set_features(struct ionic_lif *lif);
+
int ionic_notifyq_handler(struct ionic_lif *lif, int budget);
#endif /* _IONIC_LIF_H_ */