.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * IBM Power Virtual Ethernet Device Driver |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License as published by |
---|
6 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
7 | | - * (at your option) any later version. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | | - * |
---|
14 | | - * You should have received a copy of the GNU General Public License |
---|
15 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
---|
16 | 4 | * |
---|
17 | 5 | * Copyright (C) IBM Corporation, 2003, 2010 |
---|
18 | 6 | * |
---|
.. | .. |
---|
24 | 12 | */ |
---|
25 | 13 | |
---|
26 | 14 | #include <linux/module.h> |
---|
27 | | -#include <linux/moduleparam.h> |
---|
28 | 15 | #include <linux/types.h> |
---|
29 | 16 | #include <linux/errno.h> |
---|
30 | 17 | #include <linux/dma-mapping.h> |
---|
.. | .. |
---|
94 | 81 | #define IBMVETH_STAT_OFF(stat) offsetof(struct ibmveth_adapter, stat) |
---|
95 | 82 | #define IBMVETH_GET_STAT(a, off) *((u64 *)(((unsigned long)(a)) + off)) |
---|
96 | 83 | |
---|
97 | | -struct ibmveth_stat ibmveth_stats[] = { |
---|
| 84 | +static struct ibmveth_stat ibmveth_stats[] = { |
---|
98 | 85 | { "replenish_task_cycles", IBMVETH_STAT_OFF(replenish_task_cycles) }, |
---|
99 | 86 | { "replenish_no_mem", IBMVETH_STAT_OFF(replenish_no_mem) }, |
---|
100 | 87 | { "replenish_add_buff_failure", |
---|
.. | .. |
---|
209 | 196 | unsigned long offset; |
---|
210 | 197 | |
---|
211 | 198 | for (offset = 0; offset < length; offset += SMP_CACHE_BYTES) |
---|
212 | | - asm("dcbfl %0,%1" :: "b" (addr), "r" (offset)); |
---|
| 199 | + asm("dcbf %0,%1,1" :: "b" (addr), "r" (offset)); |
---|
213 | 200 | } |
---|
214 | 201 | |
---|
215 | 202 | /* replenish the buffers for a pool. note that we don't need to |
---|
.. | .. |
---|
725 | 712 | return 0; |
---|
726 | 713 | } |
---|
727 | 714 | |
---|
728 | | -static int netdev_get_link_ksettings(struct net_device *dev, |
---|
729 | | - struct ethtool_link_ksettings *cmd) |
---|
| 715 | +static int ibmveth_set_link_ksettings(struct net_device *dev, |
---|
| 716 | + const struct ethtool_link_ksettings *cmd) |
---|
730 | 717 | { |
---|
731 | | - u32 supported, advertising; |
---|
| 718 | + struct ibmveth_adapter *adapter = netdev_priv(dev); |
---|
732 | 719 | |
---|
733 | | - supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | |
---|
734 | | - SUPPORTED_FIBRE); |
---|
735 | | - advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | |
---|
736 | | - ADVERTISED_FIBRE); |
---|
737 | | - cmd->base.speed = SPEED_1000; |
---|
738 | | - cmd->base.duplex = DUPLEX_FULL; |
---|
739 | | - cmd->base.port = PORT_FIBRE; |
---|
740 | | - cmd->base.phy_address = 0; |
---|
741 | | - cmd->base.autoneg = AUTONEG_ENABLE; |
---|
| 720 | + return ethtool_virtdev_set_link_ksettings(dev, cmd, |
---|
| 721 | + &adapter->speed, |
---|
| 722 | + &adapter->duplex); |
---|
| 723 | +} |
---|
742 | 724 | |
---|
743 | | - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, |
---|
744 | | - supported); |
---|
745 | | - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, |
---|
746 | | - advertising); |
---|
| 725 | +static int ibmveth_get_link_ksettings(struct net_device *dev, |
---|
| 726 | + struct ethtool_link_ksettings *cmd) |
---|
| 727 | +{ |
---|
| 728 | + struct ibmveth_adapter *adapter = netdev_priv(dev); |
---|
| 729 | + |
---|
| 730 | + cmd->base.speed = adapter->speed; |
---|
| 731 | + cmd->base.duplex = adapter->duplex; |
---|
| 732 | + cmd->base.port = PORT_OTHER; |
---|
747 | 733 | |
---|
748 | 734 | return 0; |
---|
| 735 | +} |
---|
| 736 | + |
---|
| 737 | +static void ibmveth_init_link_settings(struct net_device *dev) |
---|
| 738 | +{ |
---|
| 739 | + struct ibmveth_adapter *adapter = netdev_priv(dev); |
---|
| 740 | + |
---|
| 741 | + adapter->speed = SPEED_1000; |
---|
| 742 | + adapter->duplex = DUPLEX_FULL; |
---|
749 | 743 | } |
---|
750 | 744 | |
---|
751 | 745 | static void netdev_get_drvinfo(struct net_device *dev, |
---|
.. | .. |
---|
978 | 972 | } |
---|
979 | 973 | |
---|
980 | 974 | static const struct ethtool_ops netdev_ethtool_ops = { |
---|
981 | | - .get_drvinfo = netdev_get_drvinfo, |
---|
982 | | - .get_link = ethtool_op_get_link, |
---|
983 | | - .get_strings = ibmveth_get_strings, |
---|
984 | | - .get_sset_count = ibmveth_get_sset_count, |
---|
985 | | - .get_ethtool_stats = ibmveth_get_ethtool_stats, |
---|
986 | | - .get_link_ksettings = netdev_get_link_ksettings, |
---|
| 975 | + .get_drvinfo = netdev_get_drvinfo, |
---|
| 976 | + .get_link = ethtool_op_get_link, |
---|
| 977 | + .get_strings = ibmveth_get_strings, |
---|
| 978 | + .get_sset_count = ibmveth_get_sset_count, |
---|
| 979 | + .get_ethtool_stats = ibmveth_get_ethtool_stats, |
---|
| 980 | + .get_link_ksettings = ibmveth_get_link_ksettings, |
---|
| 981 | + .set_link_ksettings = ibmveth_set_link_ksettings, |
---|
987 | 982 | }; |
---|
988 | 983 | |
---|
989 | 984 | static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
---|
990 | 985 | { |
---|
991 | 986 | return -EOPNOTSUPP; |
---|
992 | 987 | } |
---|
993 | | - |
---|
994 | | -#define page_offset(v) ((unsigned long)(v) & ((1 << 12) - 1)) |
---|
995 | 988 | |
---|
996 | 989 | static int ibmveth_send(struct ibmveth_adapter *adapter, |
---|
997 | 990 | union ibmveth_buf_desc *descs, unsigned long mss) |
---|
.. | .. |
---|
1024 | 1017 | return 0; |
---|
1025 | 1018 | } |
---|
1026 | 1019 | |
---|
| 1020 | +static int ibmveth_is_packet_unsupported(struct sk_buff *skb, |
---|
| 1021 | + struct net_device *netdev) |
---|
| 1022 | +{ |
---|
| 1023 | + struct ethhdr *ether_header; |
---|
| 1024 | + int ret = 0; |
---|
| 1025 | + |
---|
| 1026 | + ether_header = eth_hdr(skb); |
---|
| 1027 | + |
---|
| 1028 | + if (ether_addr_equal(ether_header->h_dest, netdev->dev_addr)) { |
---|
| 1029 | + netdev_dbg(netdev, "veth doesn't support loopback packets, dropping packet.\n"); |
---|
| 1030 | + netdev->stats.tx_dropped++; |
---|
| 1031 | + ret = -EOPNOTSUPP; |
---|
| 1032 | + } |
---|
| 1033 | + |
---|
| 1034 | + return ret; |
---|
| 1035 | +} |
---|
| 1036 | + |
---|
1027 | 1037 | static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, |
---|
1028 | 1038 | struct net_device *netdev) |
---|
1029 | 1039 | { |
---|
.. | .. |
---|
1034 | 1044 | int force_bounce = 0; |
---|
1035 | 1045 | dma_addr_t dma_addr; |
---|
1036 | 1046 | unsigned long mss = 0; |
---|
| 1047 | + |
---|
| 1048 | + if (ibmveth_is_packet_unsupported(skb, netdev)) |
---|
| 1049 | + goto out; |
---|
1037 | 1050 | |
---|
1038 | 1051 | /* veth doesn't handle frag_list, so linearize the skb. |
---|
1039 | 1052 | * When GRO is enabled SKB's can have frag_list. |
---|
.. | .. |
---|
1672 | 1685 | adapter->netdev = netdev; |
---|
1673 | 1686 | adapter->mcastFilterSize = be32_to_cpu(*mcastFilterSize_p); |
---|
1674 | 1687 | adapter->pool_config = 0; |
---|
| 1688 | + ibmveth_init_link_settings(netdev); |
---|
1675 | 1689 | |
---|
1676 | 1690 | netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); |
---|
1677 | 1691 | |
---|