#include <rte_ethdev.h>
#include <rte_memory.h>
#include <rte_memzone.h>
-#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_atomic.h>
#include <rte_malloc.h>
static void em_init_manageability(struct e1000_hw *hw);
static void em_release_manageability(struct e1000_hw *hw);
+static int eth_em_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
+
static int eth_em_vlan_filter_set(struct rte_eth_dev *dev,
uint16_t vlan_id, int on);
static void eth_em_vlan_offload_set(struct rte_eth_dev *dev, int mask);
.stats_get = eth_em_stats_get,
.stats_reset = eth_em_stats_reset,
.dev_infos_get = eth_em_infos_get,
+ .mtu_set = eth_em_mtu_set,
.vlan_filter_set = eth_em_vlan_filter_set,
.vlan_offload_set = eth_em_vlan_offload_set,
.rx_queue_setup = eth_em_rx_queue_setup,
}
static int
-eth_em_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
- struct rte_eth_dev *eth_dev)
+eth_em_dev_init(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev;
struct e1000_hw *hw =
/* initialize the vfta */
memset(shadow_vfta, 0, sizeof(*shadow_vfta));
- PMD_INIT_LOG(INFO, "port_id %d vendorID=0x%x deviceID=0x%x\n",
- eth_dev->data->port_id, pci_dev->id.vendor_id,
- pci_dev->id.device_id);
+ PMD_INIT_LOG(INFO, "port_id %d vendorID=0x%x deviceID=0x%x",
+ eth_dev->data->port_id, pci_dev->id.vendor_id,
+ pci_dev->id.device_id);
rte_intr_callback_register(&(pci_dev->intr_handle),
eth_em_interrupt_handler, (void *)eth_dev);
{
.name = "rte_em_pmd",
.id_table = pci_id_em_map,
- .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
},
.eth_dev_init = eth_em_dev_init,
.dev_private_size = sizeof(struct e1000_adapter),
diag = hw->mac.ops.init_params(hw);
if (diag != 0) {
- PMD_INIT_LOG(ERR, "MAC Initialization Error\n");
+ PMD_INIT_LOG(ERR, "MAC Initialization Error");
return diag;
}
diag = hw->nvm.ops.init_params(hw);
if (diag != 0) {
- PMD_INIT_LOG(ERR, "NVM Initialization Error\n");
+ PMD_INIT_LOG(ERR, "NVM Initialization Error");
return diag;
}
diag = hw->phy.ops.init_params(hw);
if (diag != 0) {
- PMD_INIT_LOG(ERR, "PHY Initialization Error\n");
+ PMD_INIT_LOG(ERR, "PHY Initialization Error");
return diag;
}
(void) e1000_get_bus_info(hw);
struct e1000_interrupt *intr =
E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
- PMD_INIT_LOG(DEBUG, ">>");
-
+ PMD_INIT_FUNC_TRACE();
intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
+ PMD_INIT_FUNC_TRACE();
- PMD_INIT_LOG(DEBUG, "<<");
return (0);
}
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
int ret, mask;
- PMD_INIT_LOG(DEBUG, ">>");
+ PMD_INIT_FUNC_TRACE();
eth_em_stop(dev);
return (0);
error_invalid_config:
- PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port "
- "%u\n", dev->data->dev_conf.link_speed,
- dev->data->dev_conf.link_duplex, dev->data->port_id);
+ PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
+ dev->data->dev_conf.link_speed,
+ dev->data->dev_conf.link_duplex, dev->data->port_id);
em_dev_clear_queues(dev);
return (-EINVAL);
}
memset(&link, 0, sizeof(link));
rte_em_dev_atomic_read_link_status(dev, &link);
if (link.link_status) {
- PMD_INIT_LOG(INFO,
- " Port %d: Link Up - speed %u Mbps - %s\n",
- dev->data->port_id, (unsigned)link.link_speed,
- link.link_duplex == ETH_LINK_FULL_DUPLEX ?
- "full-duplex" : "half-duplex");
+ PMD_INIT_LOG(INFO, " Port %d: Link Up - speed %u Mbps - %s",
+ dev->data->port_id, (unsigned)link.link_speed,
+ link.link_duplex == ETH_LINK_FULL_DUPLEX ?
+ "full-duplex" : "half-duplex");
} else {
- PMD_INIT_LOG(INFO, " Port %d: Link Down\n",
- dev->data->port_id);
+ PMD_INIT_LOG(INFO, " Port %d: Link Down", dev->data->port_id);
}
PMD_INIT_LOG(INFO, "PCI Address: %04d:%02d:%02d:%d",
- dev->pci_dev->addr.domain,
- dev->pci_dev->addr.bus,
- dev->pci_dev->addr.devid,
- dev->pci_dev->addr.function);
+ dev->pci_dev->addr.domain, dev->pci_dev->addr.bus,
+ dev->pci_dev->addr.devid, dev->pci_dev->addr.function);
tctl = E1000_READ_REG(hw, E1000_TCTL);
rctl = E1000_READ_REG(hw, E1000_RCTL);
if (link.link_status) {
fc_conf->high_water = hw->fc.high_water;
fc_conf->low_water = hw->fc.low_water;
fc_conf->send_xon = hw->fc.send_xon;
+ fc_conf->autoneg = hw->mac.autoneg;
/*
* Return rx_pause and tx_pause status according to actual setting of
uint32_t rctl;
hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ if (fc_conf->autoneg != hw->mac.autoneg)
+ return -ENOTSUP;
rx_buf_size = em_get_rx_buffer_size(hw);
- PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x \n", rx_buf_size);
+ PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x", rx_buf_size);
/* At least reserve one Ethernet frame for watermark */
max_high_water = rx_buf_size - ETHER_MAX_LEN;
if ((fc_conf->high_water > max_high_water) ||
- (fc_conf->high_water < fc_conf->low_water)) {
- PMD_INIT_LOG(ERR, "e1000 incorrect high/low water value \n");
- PMD_INIT_LOG(ERR, "high water must <= 0x%x \n", max_high_water);
+ (fc_conf->high_water < fc_conf->low_water)) {
+ PMD_INIT_LOG(ERR, "e1000 incorrect high/low water value");
+ PMD_INIT_LOG(ERR, "high water must <= 0x%x", max_high_water);
return (-EINVAL);
}
return 0;
}
- PMD_INIT_LOG(ERR, "e1000_setup_link_generic = 0x%x \n", err);
+ PMD_INIT_LOG(ERR, "e1000_setup_link_generic = 0x%x", err);
return (-EIO);
}
e1000_rar_set(hw, addr, index);
}
+static int
+eth_em_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+{
+ struct rte_eth_dev_info dev_info;
+ struct e1000_hw *hw;
+ uint32_t frame_size;
+ uint32_t rctl;
+
+ eth_em_infos_get(dev, &dev_info);
+ frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE;
+
+ /* check that mtu is within the allowed range */
+ if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen))
+ return -EINVAL;
+
+ /* refuse mtu that requires the support of scattered packets when this
+ * feature has not been enabled before. */
+ if (!dev->data->scattered_rx &&
+ frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM)
+ return -EINVAL;
+
+ hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ rctl = E1000_READ_REG(hw, E1000_RCTL);
+
+ /* switch to jumbo mode if needed */
+ if (frame_size > ETHER_MAX_LEN) {
+ dev->data->dev_conf.rxmode.jumbo_frame = 1;
+ rctl |= E1000_RCTL_LPE;
+ } else {
+ dev->data->dev_conf.rxmode.jumbo_frame = 0;
+ rctl &= ~E1000_RCTL_LPE;
+ }
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+
+ /* update max frame size */
+ dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+ return 0;
+}
+
struct rte_driver em_pmd_drv = {
.type = PMD_PDEV,
.init = rte_em_pmd_init,