| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /******************************************************************************* |
|---|
| 2 | 3 | This is the driver for the GMAC on-chip Ethernet controller for ST SoCs. |
|---|
| 3 | 4 | DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for |
|---|
| .. | .. |
|---|
| 7 | 8 | |
|---|
| 8 | 9 | Copyright (C) 2007-2009 STMicroelectronics Ltd |
|---|
| 9 | 10 | |
|---|
| 10 | | - This program is free software; you can redistribute it and/or modify it |
|---|
| 11 | | - under the terms and conditions of the GNU General Public License, |
|---|
| 12 | | - version 2, as published by the Free Software Foundation. |
|---|
| 13 | | - |
|---|
| 14 | | - This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 15 | | - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 16 | | - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 17 | | - more details. |
|---|
| 18 | | - |
|---|
| 19 | | - The full GNU General Public License is included in this distribution in |
|---|
| 20 | | - the file called "COPYING". |
|---|
| 21 | 11 | |
|---|
| 22 | 12 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
|---|
| 23 | 13 | *******************************************************************************/ |
|---|
| .. | .. |
|---|
| 141 | 131 | writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW); |
|---|
| 142 | 132 | writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH); |
|---|
| 143 | 133 | return; |
|---|
| 144 | | - break; |
|---|
| 145 | 134 | case 7: |
|---|
| 146 | 135 | numhashregs = 4; |
|---|
| 147 | 136 | break; |
|---|
| .. | .. |
|---|
| 151 | 140 | default: |
|---|
| 152 | 141 | pr_debug("STMMAC: err in setting multicast filter\n"); |
|---|
| 153 | 142 | return; |
|---|
| 154 | | - break; |
|---|
| 155 | 143 | } |
|---|
| 156 | 144 | for (regs = 0; regs < numhashregs; regs++) |
|---|
| 157 | 145 | writel(mcfilterbits[regs], |
|---|
| .. | .. |
|---|
| 173 | 161 | memset(mc_filter, 0, sizeof(mc_filter)); |
|---|
| 174 | 162 | |
|---|
| 175 | 163 | if (dev->flags & IFF_PROMISC) { |
|---|
| 176 | | - value = GMAC_FRAME_FILTER_PR; |
|---|
| 164 | + value = GMAC_FRAME_FILTER_PR | GMAC_FRAME_FILTER_PCF; |
|---|
| 177 | 165 | } else if (dev->flags & IFF_ALLMULTI) { |
|---|
| 178 | 166 | value = GMAC_FRAME_FILTER_PM; /* pass all multi */ |
|---|
| 179 | 167 | } else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) { |
|---|
| .. | .. |
|---|
| 202 | 190 | } |
|---|
| 203 | 191 | } |
|---|
| 204 | 192 | |
|---|
| 193 | + value |= GMAC_FRAME_FILTER_HPF; |
|---|
| 205 | 194 | dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2); |
|---|
| 206 | 195 | |
|---|
| 207 | 196 | /* Handle multiple unicast addresses (perfect filtering) */ |
|---|
| .. | .. |
|---|
| 509 | 498 | x->mac_gmii_rx_proto_engine++; |
|---|
| 510 | 499 | } |
|---|
| 511 | 500 | |
|---|
| 501 | +static void dwmac1000_set_mac_loopback(void __iomem *ioaddr, bool enable) |
|---|
| 502 | +{ |
|---|
| 503 | + u32 value = readl(ioaddr + GMAC_CONTROL); |
|---|
| 504 | + |
|---|
| 505 | + if (enable) |
|---|
| 506 | + value |= GMAC_CONTROL_LM; |
|---|
| 507 | + else |
|---|
| 508 | + value &= ~GMAC_CONTROL_LM; |
|---|
| 509 | + |
|---|
| 510 | + writel(value, ioaddr + GMAC_CONTROL); |
|---|
| 511 | +} |
|---|
| 512 | + |
|---|
| 512 | 513 | const struct stmmac_ops dwmac1000_ops = { |
|---|
| 513 | 514 | .core_init = dwmac1000_core_init, |
|---|
| 514 | 515 | .set_mac = stmmac_set_mac, |
|---|
| .. | .. |
|---|
| 528 | 529 | .pcs_ctrl_ane = dwmac1000_ctrl_ane, |
|---|
| 529 | 530 | .pcs_rane = dwmac1000_rane, |
|---|
| 530 | 531 | .pcs_get_adv_lp = dwmac1000_get_adv_lp, |
|---|
| 532 | + .set_mac_loopback = dwmac1000_set_mac_loopback, |
|---|
| 531 | 533 | }; |
|---|
| 532 | 534 | |
|---|
| 533 | 535 | int dwmac1000_setup(struct stmmac_priv *priv) |
|---|