@@ -10,7 +10,7 @@
#define XSC_VFREP_BASE_LOGICAL_PORT 1081
-
+#define XSC_MAX_MAC_ADDRESSES 3
enum xsc_nic_mode {
XSC_NIC_MODE_LEGACY,
@@ -15,6 +15,9 @@
#define XSC_DEV_REPR_PORT 0
+#define FUNCID_TYPE_MASK 0x1c000
+#define FUNCID_MASK 0x3fff
+
struct xsc_hwinfo {
uint8_t valid; /* 1: current phy info is valid, 0 : invalid */
uint32_t pcie_no; /* pcie number , 0 or 1 */
@@ -8,15 +8,79 @@
#include "xsc_defs.h"
#include "xsc_dev.h"
#include "xsc_ethdev.h"
+#include "xsc_utils.h"
+
+#include "xsc_ctrl.h"
+
+const struct eth_dev_ops xsc_dev_ops = {
+};
static int
xsc_ethdev_init_one_representor(struct rte_eth_dev *eth_dev, void *init_params)
{
struct xsc_repr_port *repr_port = (struct xsc_repr_port *)init_params;
struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev);
+ struct xsc_dev_config *config = &priv->config;
+ struct rte_ether_addr mac;
priv->repr_port = repr_port;
repr_port->drv_data = eth_dev;
+ priv->xdev = repr_port->xdev;
+ priv->mtu = RTE_ETHER_MTU;
+ priv->funcid_type = (repr_port->info.funcid & FUNCID_TYPE_MASK) >> 14;
+ priv->funcid = repr_port->info.funcid & FUNCID_MASK;
+ if (repr_port->info.port_type == XSC_PORT_TYPE_UPLINK ||
+ repr_port->info.port_type == XSC_PORT_TYPE_UPLINK_BOND)
+ priv->eth_type = RTE_ETH_REPRESENTOR_PF;
+ else
+ priv->eth_type = RTE_ETH_REPRESENTOR_VF;
+ priv->representor_id = repr_port->info.repr_id;
+ priv->dev_data = eth_dev->data;
+ priv->ifindex = repr_port->info.ifindex;
+
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
+ eth_dev->data->mac_addrs = priv->mac;
+ if (rte_is_zero_ether_addr(eth_dev->data->mac_addrs)) {
+ if (priv->ifindex > 0) {
+ int ret = xsc_get_mac(mac.addr_bytes, priv->ifindex);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "port %u cannot get MAC address",
+ eth_dev->data->port_id);
+ return -ENODEV;
+ }
+ } else {
+ rte_eth_random_addr(mac.addr_bytes);
+ }
+ }
+
+ xsc_mac_addr_add(eth_dev, &mac, 0);
+
+ if (priv->ifindex > 0)
+ xsc_get_mtu(&priv->mtu, priv->ifindex);
+
+ config->hw_csum = 1;
+
+ config->pph_flag = priv->xdev->devargs.pph_mode;
+ if ((config->pph_flag & XSC_TX_PPH) != 0) {
+ config->tso = 0;
+ } else {
+ config->tso = 1;
+ if (config->tso)
+ config->tso_max_payload_sz = 1500;
+ }
+
+ priv->representor = !!priv->eth_type;
+ if (priv->representor) {
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
+ eth_dev->data->representor_id = priv->representor_id;
+ eth_dev->data->backer_port_id = eth_dev->data->port_id;
+ }
+ eth_dev->dev_ops = &xsc_dev_ops;
+
+ eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
+ eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
+
+ rte_eth_dev_probing_finish(eth_dev);
return 0;
}
@@ -5,11 +5,41 @@
#ifndef _XSC_ETHDEV_H_
#define _XSC_ETHDEV_H_
+struct xsc_dev_config {
+ uint8_t pph_flag;
+ unsigned int hw_csum:1;
+ unsigned int tso:1;
+ unsigned int tso_max_payload_sz;
+};
+
struct xsc_ethdev_priv {
struct rte_eth_dev *eth_dev;
struct rte_pci_device *pci_dev;
struct xsc_dev *xdev;
struct xsc_repr_port *repr_port;
+ struct xsc_dev_config config;
+ struct rte_eth_dev_data *dev_data;
+ struct rte_ether_addr mac[XSC_MAX_MAC_ADDRESSES];
+ struct rte_eth_rss_conf rss_conf;
+
+ int32_t representor_id;
+
+ uint32_t ifindex;
+ uint16_t mtu;
+ uint8_t isolated;
+ uint8_t representor;
+
+ uint32_t mode:7;
+ uint32_t member_bitmap:8;
+ uint32_t funcid_type:3;
+ uint32_t funcid:14;
+
+ uint16_t eth_type;
+ uint16_t qp_set_id;
+
+ uint16_t num_sq;
+ uint16_t num_rq;
+
};
#define TO_XSC_ETHDEV_PRIV(dev) \
@@ -15,8 +15,13 @@
#include <net/if.h>
#include <sys/mman.h>
+#include <rte_memcpy.h>
+#include <rte_ethdev.h>
+#include <ethdev_driver.h>
+
#include "xsc_log.h"
#include "xsc_utils.h"
+#include "xsc_defs.h"
static int
xsc_get_ibdev_pci_addr(const char *dev_path, struct rte_pci_addr *pci_addr)
@@ -216,3 +221,103 @@ xsc_get_ifindex_by_pci_addr(struct rte_pci_addr *addr, int *ifindex)
return 0;
}
+
+
+static int
+xsc_ifreq_by_ifname(const char *ifname, int req, struct ifreq *ifr)
+{
+ int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ int ret = 0;
+
+ if (sock == -1) {
+ rte_errno = errno;
+ return -rte_errno;
+ }
+ rte_strscpy(ifr->ifr_name, ifname, sizeof(ifr->ifr_name));
+ ret = ioctl(sock, req, ifr);
+ if (ret == -1) {
+ rte_errno = errno;
+ goto error;
+ }
+ close(sock);
+ return 0;
+error:
+ close(sock);
+ return -rte_errno;
+}
+
+int
+xsc_get_mac(uint8_t *mac, uint32_t ifindex)
+{
+ struct ifreq request;
+ struct ifreq *ifr = &request;
+ char ifname[sizeof(ifr->ifr_name)];
+ int ret;
+
+ if (if_indextoname(ifindex, ifname) == NULL)
+ return -rte_errno;
+
+ ret = xsc_ifreq_by_ifname(ifname, SIOCGIFHWADDR, &request);
+ if (ret)
+ return ret;
+
+ memcpy(mac, request.ifr_hwaddr.sa_data, RTE_ETHER_ADDR_LEN);
+ return 0;
+}
+
+int
+xsc_get_mtu(uint16_t *mtu, uint32_t ifindex)
+{
+ struct ifreq request;
+ struct ifreq *ifr = &request;
+ char ifname[sizeof(ifr->ifr_name)];
+ int ret;
+
+ if (if_indextoname(ifindex, ifname) == NULL)
+ return -rte_errno;
+
+ ret = xsc_ifreq_by_ifname(ifname, SIOCGIFMTU, &request);
+ if (ret)
+ return ret;
+ *mtu = request.ifr_mtu;
+ return 0;
+}
+
+int
+xsc_set_mtu(uint16_t mtu, uint32_t ifindex)
+{
+ struct ifreq request = { .ifr_mtu = mtu, };
+ struct ifreq *ifr = &request;
+ char ifname[sizeof(ifr->ifr_name)];
+
+ if (if_indextoname(ifindex, ifname) == NULL)
+ return -rte_errno;
+
+ return xsc_ifreq_by_ifname(ifname, SIOCSIFMTU, &request);
+}
+
+int
+xsc_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, uint32_t index)
+{
+ int i;
+ rte_errno = EINVAL;
+
+ if (index > XSC_MAX_MAC_ADDRESSES)
+ return -rte_errno;
+
+ if (rte_is_zero_ether_addr(mac))
+ return -rte_errno;
+
+ for (i = 0; i != XSC_MAX_MAC_ADDRESSES; ++i) {
+ if (i == (int)index)
+ continue;
+ if (memcmp(&dev->data->mac_addrs[i], mac, sizeof(*mac)))
+ continue;
+ /* Address already configured elsewhere, return with error. */
+ rte_errno = EADDRINUSE;
+ return -rte_errno;
+ }
+
+ dev->data->mac_addrs[index] = *mac;
+ return 0;
+}
@@ -14,4 +14,10 @@ int xsc_get_ifname_by_pci_addr(struct rte_pci_addr *addr, char *ifname);
int xsc_get_ifindex_by_ifname(const char *ifname, int *ifindex);
int xsc_get_ifindex_by_pci_addr(struct rte_pci_addr *addr, int *ifindex);
-#endif /* _XSC_UTILS_H_ */
+int xsc_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, uint32_t index);
+int xsc_get_mtu(uint16_t *mtu, uint32_t ifindex);
+int xsc_set_mtu(uint16_t mtu, uint32_t ifindex);
+int xsc_get_mac(uint8_t *mac, uint32_t ifindex);
+
+
+#endif