diff options
Diffstat (limited to 'kernel/linux/kni')
-rw-r--r-- | kernel/linux/kni/Kbuild | 8 | ||||
-rw-r--r-- | kernel/linux/kni/ethtool/igb/igb_ethtool.c | 8 | ||||
-rw-r--r-- | kernel/linux/kni/ethtool/igb/meson.build | 16 | ||||
-rw-r--r-- | kernel/linux/kni/ethtool/ixgbe/ixgbe.h | 2 | ||||
-rw-r--r-- | kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c | 8 | ||||
-rw-r--r-- | kernel/linux/kni/ethtool/ixgbe/meson.build | 13 | ||||
-rw-r--r-- | kernel/linux/kni/ethtool/meson.build | 5 | ||||
-rw-r--r-- | kernel/linux/kni/kni_dev.h | 3 | ||||
-rw-r--r-- | kernel/linux/kni/kni_ethtool.c | 10 | ||||
-rw-r--r-- | kernel/linux/kni/kni_fifo.h | 24 | ||||
-rw-r--r-- | kernel/linux/kni/kni_misc.c | 60 | ||||
-rw-r--r-- | kernel/linux/kni/kni_net.c | 7 | ||||
-rw-r--r-- | kernel/linux/kni/meson.build | 34 |
13 files changed, 182 insertions, 16 deletions
diff --git a/kernel/linux/kni/Kbuild b/kernel/linux/kni/Kbuild new file mode 100644 index 00000000..de5c27f3 --- /dev/null +++ b/kernel/linux/kni/Kbuild @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Luca Boccassi <bluca@debian.org> + +ccflags-y := $(MODULE_CFLAGS) +obj-m := rte_kni.o +rte_kni-y := $(patsubst $(src)/%.c,%.o,$(wildcard $(src)/*.c)) \ + $(patsubst $(src)/%.c,%.o,$(wildcard $(src)/ethtool/ixgbe/*.c)) \ + $(patsubst $(src)/%.c,%.o,$(wildcard $(src)/ethtool/igb/*.c)) diff --git a/kernel/linux/kni/ethtool/igb/igb_ethtool.c b/kernel/linux/kni/ethtool/igb/igb_ethtool.c index 002f75c4..b6bddc02 100644 --- a/kernel/linux/kni/ethtool/igb/igb_ethtool.c +++ b/kernel/linux/kni/ethtool/igb/igb_ethtool.c @@ -135,6 +135,7 @@ static const char igb_gstrings_test[][ETH_GSTRING_LEN] = { #define IGB_TEST_LEN (sizeof(igb_gstrings_test) / ETH_GSTRING_LEN) #endif /* ETHTOOL_TEST */ +#ifndef ETHTOOL_GLINKSETTINGS static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct igb_adapter *adapter = netdev_priv(netdev); @@ -259,7 +260,9 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) #endif /* ETH_TP_MDI_X */ return 0; } +#endif +#ifndef ETHTOOL_SLINKSETTINGS static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct igb_adapter *adapter = netdev_priv(netdev); @@ -364,6 +367,7 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) clear_bit(__IGB_RESETTING, &adapter->state); return 0; } +#endif static u32 igb_get_link(struct net_device *netdev) { @@ -2737,8 +2741,12 @@ static int igb_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) #endif /* ETHTOOL_GRXRINGS */ static const struct ethtool_ops igb_ethtool_ops = { +#ifndef ETHTOOL_GLINKSETTINGS .get_settings = igb_get_settings, +#endif +#ifndef ETHTOOL_SLINKSETTINGS .set_settings = igb_set_settings, +#endif .get_drvinfo = igb_get_drvinfo, .get_regs_len = igb_get_regs_len, .get_regs = igb_get_regs, diff --git a/kernel/linux/kni/ethtool/igb/meson.build b/kernel/linux/kni/ethtool/igb/meson.build new file mode 100644 index 00000000..2f796ac0 --- /dev/null +++ b/kernel/linux/kni/ethtool/igb/meson.build @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Luca Boccassi <bluca@debian.org> + +kni_igb_sources = files( + 'e1000_82575.c', + 'e1000_api.c', + 'e1000_i210.c', + 'e1000_mac.c', + 'e1000_manage.c', + 'e1000_mbx.c', + 'e1000_nvm.c', + 'e1000_phy.c', + 'igb_ethtool.c', + 'igb_main.c', + 'igb_param.c', + 'igb_vmdq.c') diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe.h index 6ff94133..cc15ec6a 100644 --- a/kernel/linux/kni/ethtool/ixgbe/ixgbe.h +++ b/kernel/linux/kni/ethtool/ixgbe/ixgbe.h @@ -890,8 +890,10 @@ s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame); #endif /* CONFIG_DCB */ extern void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring); +#ifndef ETHTOOL_GLINKSETTINGS extern int ixgbe_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd); +#endif extern int ixgbe_write_uc_addr_list(struct ixgbe_adapter *adapter, struct net_device *netdev, unsigned int vfn); extern void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter); diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c index 44cdc9f2..f2ded19e 100644 --- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c +++ b/kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c @@ -158,6 +158,7 @@ static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { #define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) #endif /* ETHTOOL_TEST */ +#ifndef ETHTOOL_GLINKSETTINGS int ixgbe_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { @@ -347,7 +348,9 @@ int ixgbe_get_settings(struct net_device *netdev, return 0; } +#endif +#ifndef ETHTOOL_SLINKSETTINGS static int ixgbe_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { @@ -391,6 +394,7 @@ static int ixgbe_set_settings(struct net_device *netdev, } return err; } +#endif static void ixgbe_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) @@ -2815,8 +2819,12 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) #endif /* ETHTOOL_GRXRINGS */ //static struct ethtool_ops ixgbe_ethtool_ops = { +#ifndef ETHTOOL_GLINKSETTINGS .get_settings = ixgbe_get_settings, +#endif +#ifndef ETHTOOL_SLINKSETTINGS .set_settings = ixgbe_set_settings, +#endif .get_drvinfo = ixgbe_get_drvinfo, .get_regs_len = ixgbe_get_regs_len, .get_regs = ixgbe_get_regs, diff --git a/kernel/linux/kni/ethtool/ixgbe/meson.build b/kernel/linux/kni/ethtool/ixgbe/meson.build new file mode 100644 index 00000000..73248b13 --- /dev/null +++ b/kernel/linux/kni/ethtool/ixgbe/meson.build @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Luca Boccassi <bluca@debian.org> + +kni_ixgbe_sources = files( + 'ixgbe_82598.c', + 'ixgbe_82599.c', + 'ixgbe_api.c', + 'ixgbe_common.c', + 'ixgbe_ethtool.c', + 'ixgbe_main.c', + 'ixgbe_phy.c', + 'ixgbe_x540.c', + 'kcompat.c') diff --git a/kernel/linux/kni/ethtool/meson.build b/kernel/linux/kni/ethtool/meson.build new file mode 100644 index 00000000..7a8458dd --- /dev/null +++ b/kernel/linux/kni/ethtool/meson.build @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Luca Boccassi <bluca@debian.org> + +subdir('igb') +subdir('ixgbe') diff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h index 6275ef27..688f574a 100644 --- a/kernel/linux/kni/kni_dev.h +++ b/kernel/linux/kni/kni_dev.h @@ -29,6 +29,9 @@ #define MBUF_BURST_SZ 32 +/* Default carrier state for created KNI network interfaces */ +extern uint32_t dflt_carrier; + /** * A structure describing the private information for a kni device. */ diff --git a/kernel/linux/kni/kni_ethtool.c b/kernel/linux/kni/kni_ethtool.c index a44e7d94..b1c84f8f 100644 --- a/kernel/linux/kni/kni_ethtool.c +++ b/kernel/linux/kni/kni_ethtool.c @@ -27,6 +27,8 @@ kni_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) priv->lad_dev->ethtool_ops->get_drvinfo(priv->lad_dev, info); } +/* ETHTOOL_GLINKSETTINGS replaces ETHTOOL_GSET */ +#ifndef ETHTOOL_GLINKSETTINGS static int kni_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { @@ -34,7 +36,10 @@ kni_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) return priv->lad_dev->ethtool_ops->get_settings(priv->lad_dev, ecmd); } +#endif +/* ETHTOOL_SLINKSETTINGS replaces ETHTOOL_SSET */ +#ifndef ETHTOOL_SLINKSETTINGS static int kni_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { @@ -42,6 +47,7 @@ kni_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) return priv->lad_dev->ethtool_ops->set_settings(priv->lad_dev, ecmd); } +#endif static void kni_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) @@ -190,8 +196,12 @@ kni_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, struct ethtool_ops kni_ethtool_ops = { .begin = kni_check_if_running, .get_drvinfo = kni_get_drvinfo, +#ifndef ETHTOOL_GLINKSETTINGS .get_settings = kni_get_settings, +#endif +#ifndef ETHTOOL_SLINKSETTINGS .set_settings = kni_set_settings, +#endif .get_regs_len = kni_get_regs_len, .get_regs = kni_get_regs, .get_wol = kni_get_wol, diff --git a/kernel/linux/kni/kni_fifo.h b/kernel/linux/kni/kni_fifo.h index 9a4762de..3f4781c2 100644 --- a/kernel/linux/kni/kni_fifo.h +++ b/kernel/linux/kni/kni_fifo.h @@ -8,6 +8,14 @@ #include <exec-env/rte_kni_common.h> +/* Skip some memory barriers on Linux < 3.14 */ +#ifndef smp_load_acquire +#define smp_load_acquire(a) (*(a)) +#endif +#ifndef smp_store_release +#define smp_store_release(a, b) *(a) = (b) +#endif + /** * Adds num elements into the fifo. Return the number actually written */ @@ -16,7 +24,7 @@ kni_fifo_put(struct rte_kni_fifo *fifo, void **data, uint32_t num) { uint32_t i = 0; uint32_t fifo_write = fifo->write; - uint32_t fifo_read = fifo->read; + uint32_t fifo_read = smp_load_acquire(&fifo->read); uint32_t new_write = fifo_write; for (i = 0; i < num; i++) { @@ -27,7 +35,7 @@ kni_fifo_put(struct rte_kni_fifo *fifo, void **data, uint32_t num) fifo->buffer[fifo_write] = data[i]; fifo_write = new_write; } - fifo->write = fifo_write; + smp_store_release(&fifo->write, fifo_write); return i; } @@ -40,7 +48,7 @@ kni_fifo_get(struct rte_kni_fifo *fifo, void **data, uint32_t num) { uint32_t i = 0; uint32_t new_read = fifo->read; - uint32_t fifo_write = fifo->write; + uint32_t fifo_write = smp_load_acquire(&fifo->write); for (i = 0; i < num; i++) { if (new_read == fifo_write) @@ -49,7 +57,7 @@ kni_fifo_get(struct rte_kni_fifo *fifo, void **data, uint32_t num) data[i] = fifo->buffer[new_read]; new_read = (new_read + 1) & (fifo->len - 1); } - fifo->read = new_read; + smp_store_release(&fifo->read, new_read); return i; } @@ -60,7 +68,9 @@ kni_fifo_get(struct rte_kni_fifo *fifo, void **data, uint32_t num) static inline uint32_t kni_fifo_count(struct rte_kni_fifo *fifo) { - return (fifo->len + fifo->write - fifo->read) & (fifo->len - 1); + uint32_t fifo_write = smp_load_acquire(&fifo->write); + uint32_t fifo_read = smp_load_acquire(&fifo->read); + return (fifo->len + fifo_write - fifo_read) & (fifo->len - 1); } /** @@ -69,7 +79,9 @@ kni_fifo_count(struct rte_kni_fifo *fifo) static inline uint32_t kni_fifo_free_count(struct rte_kni_fifo *fifo) { - return (fifo->read - fifo->write - 1) & (fifo->len - 1); + uint32_t fifo_write = smp_load_acquire(&fifo->write); + uint32_t fifo_read = smp_load_acquire(&fifo->read); + return (fifo_read - fifo_write - 1) & (fifo->len - 1); } #endif /* _KNI_FIFO_H_ */ diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c index fa69f8e6..522ae23b 100644 --- a/kernel/linux/kni/kni_misc.c +++ b/kernel/linux/kni/kni_misc.c @@ -39,6 +39,10 @@ static char *lo_mode; static char *kthread_mode; static uint32_t multiple_kthread_on; +/* Default carrier state for created KNI network interfaces */ +static char *carrier; +uint32_t dflt_carrier; + #define KNI_DEV_IN_USE_BIT_NUM 0 /* Bit number for device in use */ static int kni_net_id; @@ -466,6 +470,8 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, return -ENODEV; } + netif_carrier_off(net_dev); + ret = kni_run_thread(knet, kni, dev_info.force_bind); if (ret != 0) return ret; @@ -591,6 +597,24 @@ kni_parse_kthread_mode(void) } static int __init +kni_parse_carrier_state(void) +{ + if (!carrier) { + dflt_carrier = 0; + return 0; + } + + if (strcmp(carrier, "off") == 0) + dflt_carrier = 0; + else if (strcmp(carrier, "on") == 0) + dflt_carrier = 1; + else + return -1; + + return 0; +} + +static int __init kni_init(void) { int rc; @@ -605,6 +629,16 @@ kni_init(void) else pr_debug("Multiple kernel thread mode enabled\n"); + if (kni_parse_carrier_state() < 0) { + pr_err("Invalid parameter for carrier\n"); + return -EINVAL; + } + + if (dflt_carrier == 0) + pr_debug("Default carrier state set to off.\n"); + else + pr_debug("Default carrier state set to on.\n"); + #ifdef HAVE_SIMPLIFIED_PERNET_OPERATIONS rc = register_pernet_subsys(&kni_net_ops); #else @@ -647,19 +681,27 @@ kni_exit(void) module_init(kni_init); module_exit(kni_exit); -module_param(lo_mode, charp, S_IRUGO | S_IWUSR); +module_param(lo_mode, charp, 0644); MODULE_PARM_DESC(lo_mode, "KNI loopback mode (default=lo_mode_none):\n" -" lo_mode_none Kernel loopback disabled\n" -" lo_mode_fifo Enable kernel loopback with fifo\n" -" lo_mode_fifo_skb Enable kernel loopback with fifo and skb buffer\n" -"\n" +"\t\tlo_mode_none Kernel loopback disabled\n" +"\t\tlo_mode_fifo Enable kernel loopback with fifo\n" +"\t\tlo_mode_fifo_skb Enable kernel loopback with fifo and skb buffer\n" +"\t\t" ); -module_param(kthread_mode, charp, S_IRUGO); +module_param(kthread_mode, charp, 0644); MODULE_PARM_DESC(kthread_mode, "Kernel thread mode (default=single):\n" -" single Single kernel thread mode enabled.\n" -" multiple Multiple kernel thread mode enabled.\n" -"\n" +"\t\tsingle Single kernel thread mode enabled.\n" +"\t\tmultiple Multiple kernel thread mode enabled.\n" +"\t\t" +); + +module_param(carrier, charp, 0644); +MODULE_PARM_DESC(carrier, +"Default carrier state for KNI interface (default=off):\n" +"\t\toff Interfaces will be created with carrier state set to off.\n" +"\t\ton Interfaces will be created with carrier state set to on.\n" +"\t\t" ); diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c index 7fcfa106..7371b6d5 100644 --- a/kernel/linux/kni/kni_net.c +++ b/kernel/linux/kni/kni_net.c @@ -133,6 +133,10 @@ kni_net_open(struct net_device *dev) struct kni_dev *kni = netdev_priv(dev); netif_start_queue(dev); + if (dflt_carrier == 1) + netif_carrier_on(dev); + else + netif_carrier_off(dev); memset(&req, 0, sizeof(req)); req.req_id = RTE_KNI_REQ_CFG_NETWORK_IF; @@ -152,6 +156,7 @@ kni_net_release(struct net_device *dev) struct kni_dev *kni = netdev_priv(dev); netif_stop_queue(dev); /* can't transmit any more */ + netif_carrier_off(dev); memset(&req, 0, sizeof(req)); req.req_id = RTE_KNI_REQ_CFG_NETWORK_IF; @@ -597,7 +602,7 @@ kni_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) pr_debug("kni_net_ioctl group:%d cmd:%d\n", ((struct kni_dev *)netdev_priv(dev))->group_id, cmd); - return 0; + return -EOPNOTSUPP; } static void diff --git a/kernel/linux/kni/meson.build b/kernel/linux/kni/meson.build new file mode 100644 index 00000000..a09af5aa --- /dev/null +++ b/kernel/linux/kni/meson.build @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Luca Boccassi <bluca@debian.org> + +subdir('ethtool') + +kni_mkfile = custom_target('rte_kni_makefile', + output: 'Makefile', + command: ['touch', '@OUTPUT@']) + +kni_sources = files( + 'kni_ethtool.c', + 'kni_misc.c', + 'kni_net.c', + 'Kbuild') + +custom_target('rte_kni', + input: kni_sources + kni_igb_sources + kni_ixgbe_sources, + output: 'rte_kni.ko', + command: ['make', '-j4', '-C', kernel_dir, + 'M=' + meson.current_build_dir(), + 'src=' + meson.current_source_dir(), + 'MODULE_CFLAGS=-include ' + meson.source_root() + '/config/rte_config.h' + + ' -I' + meson.source_root() + '/lib/librte_eal/common/include' + + ' -I' + meson.source_root() + '/lib/librte_eal/linuxapp/eal/include' + + ' -I' + meson.build_root() + + ' -I' + meson.current_source_dir() + + ' -I' + meson.current_source_dir() + '/ethtool/ixgbe' + + ' -I' + meson.current_source_dir() + '/ethtool/igb', + 'modules'], + depends: kni_mkfile, + console: true, + install: true, + install_dir: kernel_dir + '/../extra/dpdk', + build_by_default: get_option('enable_kmods')) |