346 lines
14 KiB
C
346 lines
14 KiB
C
/*
|
|
* AMD 10Gb Ethernet driver
|
|
*
|
|
* Copyright (c) 2014-2016,2020 Advanced Micro Devices, Inc.
|
|
*
|
|
* This file is available to you under your choice of the following two
|
|
* licenses:
|
|
*
|
|
* License 1: GPLv2
|
|
*
|
|
* This file is free software; you may copy, redistribute and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or (at
|
|
* your option) any later version.
|
|
*
|
|
* This file is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* This file incorporates work covered by the following copyright and
|
|
* permission notice:
|
|
* The Synopsys DWC ETHER XGMAC Software Driver and documentation
|
|
* (hereinafter "Software") is an unsupported proprietary work of Synopsys,
|
|
* Inc. unless otherwise expressly agreed to in writing between Synopsys
|
|
* and you.
|
|
*
|
|
* The Software IS NOT an item of Licensed Software or Licensed Product
|
|
* under any End User Software License Agreement or Agreement for Licensed
|
|
* Product with Synopsys or any supplement thereto. Permission is hereby
|
|
* granted, free of charge, to any person obtaining a copy of this software
|
|
* annotated with this license and the Software, to deal in the Software
|
|
* without restriction, including without limitation the rights to use,
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
* of the Software, and to permit persons to whom the Software is furnished
|
|
* to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included
|
|
* in all copies or substantial portions of the Software.
|
|
*
|
|
* THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
|
|
* BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
* PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*
|
|
* License 2: Modified BSD
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of Advanced Micro Devices, Inc. nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* This file incorporates work covered by the following copyright and
|
|
* permission notice:
|
|
* The Synopsys DWC ETHER XGMAC Software Driver and documentation
|
|
* (hereinafter "Software") is an unsupported proprietary work of Synopsys,
|
|
* Inc. unless otherwise expressly agreed to in writing between Synopsys
|
|
* and you.
|
|
*
|
|
* The Software IS NOT an item of Licensed Software or Licensed Product
|
|
* under any End User Software License Agreement or Agreement for Licensed
|
|
* Product with Synopsys or any supplement thereto. Permission is hereby
|
|
* granted, free of charge, to any person obtaining a copy of this software
|
|
* annotated with this license and the Software, to deal in the Software
|
|
* without restriction, including without limitation the rights to use,
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
* of the Software, and to permit persons to whom the Software is furnished
|
|
* to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included
|
|
* in all copies or substantial portions of the Software.
|
|
*
|
|
* THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
|
|
* BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
* PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
#include "xgbe.h"
|
|
#include "xgbe-common.h"
|
|
|
|
int
|
|
xgbe_calc_rx_buf_size(if_t netdev, unsigned int mtu)
|
|
{
|
|
unsigned int rx_buf_size;
|
|
|
|
if (mtu > XGMAC_JUMBO_PACKET_MTU)
|
|
return (-EINVAL);
|
|
|
|
rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
|
|
rx_buf_size = min(max(rx_buf_size, XGBE_RX_MIN_BUF_SIZE), PAGE_SIZE);
|
|
rx_buf_size = (rx_buf_size + XGBE_RX_BUF_ALIGN - 1) &
|
|
~(XGBE_RX_BUF_ALIGN - 1);
|
|
|
|
return (rx_buf_size);
|
|
}
|
|
|
|
void
|
|
xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
|
|
{
|
|
unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
|
|
struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
|
|
|
|
DBGPR("-->xgbe_get_all_hw_features\n");
|
|
|
|
mac_hfr0 = XGMAC_IOREAD(pdata, MAC_HWF0R);
|
|
mac_hfr1 = XGMAC_IOREAD(pdata, MAC_HWF1R);
|
|
mac_hfr2 = XGMAC_IOREAD(pdata, MAC_HWF2R);
|
|
|
|
memset(hw_feat, 0, sizeof(*hw_feat));
|
|
|
|
hw_feat->version = XGMAC_IOREAD(pdata, MAC_VR);
|
|
|
|
/* Hardware feature register 0 */
|
|
hw_feat->gmii = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL);
|
|
hw_feat->vlhash = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH);
|
|
hw_feat->sma = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL);
|
|
hw_feat->rwk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL);
|
|
hw_feat->mgk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL);
|
|
hw_feat->mmc = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL);
|
|
hw_feat->aoe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL);
|
|
hw_feat->ts = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL);
|
|
hw_feat->eee = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL);
|
|
hw_feat->tx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL);
|
|
hw_feat->rx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL);
|
|
hw_feat->addn_mac = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R,
|
|
ADDMACADRSEL);
|
|
hw_feat->ts_src = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL);
|
|
hw_feat->sa_vlan_ins = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS);
|
|
hw_feat->vxn = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VXN);
|
|
|
|
/* Hardware feature register 1 */
|
|
hw_feat->rx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
|
|
RXFIFOSIZE);
|
|
hw_feat->tx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
|
|
TXFIFOSIZE);
|
|
hw_feat->adv_ts_hi = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADVTHWORD);
|
|
hw_feat->dma_width = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64);
|
|
hw_feat->dcb = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
|
|
hw_feat->sph = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
|
|
hw_feat->tso = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
|
|
hw_feat->dma_debug = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA);
|
|
hw_feat->rss = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, RSSEN);
|
|
hw_feat->tc_cnt = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC);
|
|
hw_feat->hash_table_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
|
|
HASHTBLSZ);
|
|
hw_feat->l3l4_filter_num = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
|
|
L3L4FNUM);
|
|
|
|
/* Hardware feature register 2 */
|
|
hw_feat->rx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT);
|
|
hw_feat->tx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT);
|
|
hw_feat->rx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT);
|
|
hw_feat->tx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT);
|
|
hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
|
|
hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, AUXSNAPNUM);
|
|
|
|
/* Translate the Hash Table size into actual number */
|
|
switch (hw_feat->hash_table_size) {
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
hw_feat->hash_table_size = 64;
|
|
break;
|
|
case 2:
|
|
hw_feat->hash_table_size = 128;
|
|
break;
|
|
case 3:
|
|
hw_feat->hash_table_size = 256;
|
|
break;
|
|
}
|
|
|
|
/* Translate the address width setting into actual number */
|
|
switch (hw_feat->dma_width) {
|
|
case 0:
|
|
hw_feat->dma_width = 32;
|
|
break;
|
|
case 1:
|
|
hw_feat->dma_width = 40;
|
|
break;
|
|
case 2:
|
|
hw_feat->dma_width = 48;
|
|
break;
|
|
default:
|
|
hw_feat->dma_width = 32;
|
|
}
|
|
|
|
/* The Queue, Channel and TC counts are zero based so increment them
|
|
* to get the actual number
|
|
*/
|
|
hw_feat->rx_q_cnt++;
|
|
hw_feat->tx_q_cnt++;
|
|
hw_feat->rx_ch_cnt++;
|
|
hw_feat->tx_ch_cnt++;
|
|
hw_feat->tc_cnt++;
|
|
|
|
/* Translate the fifo sizes into actual numbers */
|
|
hw_feat->rx_fifo_size = 1 << (hw_feat->rx_fifo_size + 7);
|
|
hw_feat->tx_fifo_size = 1 << (hw_feat->tx_fifo_size + 7);
|
|
DBGPR("%s: Tx fifo 0x%x Rx fifo 0x%x\n", __func__,
|
|
hw_feat->tx_fifo_size, hw_feat->rx_fifo_size);
|
|
|
|
DBGPR("Hardware features:\n");
|
|
|
|
/* Hardware feature register 0 */
|
|
DBGPR(" 1GbE support : %s\n",
|
|
hw_feat->gmii ? "yes" : "no");
|
|
DBGPR(" VLAN hash filter : %s\n",
|
|
hw_feat->vlhash ? "yes" : "no");
|
|
DBGPR(" MDIO interface : %s\n",
|
|
hw_feat->sma ? "yes" : "no");
|
|
DBGPR(" Wake-up packet support : %s\n",
|
|
hw_feat->rwk ? "yes" : "no");
|
|
DBGPR(" Magic packet support : %s\n",
|
|
hw_feat->mgk ? "yes" : "no");
|
|
DBGPR(" Management counters : %s\n",
|
|
hw_feat->mmc ? "yes" : "no");
|
|
DBGPR(" ARP offload : %s\n",
|
|
hw_feat->aoe ? "yes" : "no");
|
|
DBGPR(" IEEE 1588-2008 Timestamp : %s\n",
|
|
hw_feat->ts ? "yes" : "no");
|
|
DBGPR(" Energy Efficient Ethernet : %s\n",
|
|
hw_feat->eee ? "yes" : "no");
|
|
DBGPR(" TX checksum offload : %s\n",
|
|
hw_feat->tx_coe ? "yes" : "no");
|
|
DBGPR(" RX checksum offload : %s\n",
|
|
hw_feat->rx_coe ? "yes" : "no");
|
|
DBGPR(" Additional MAC addresses : %u\n",
|
|
hw_feat->addn_mac);
|
|
DBGPR(" Timestamp source : %s\n",
|
|
(hw_feat->ts_src == 1) ? "internal" :
|
|
(hw_feat->ts_src == 2) ? "external" :
|
|
(hw_feat->ts_src == 3) ? "internal/external" : "n/a");
|
|
DBGPR(" SA/VLAN insertion : %s\n",
|
|
hw_feat->sa_vlan_ins ? "yes" : "no");
|
|
|
|
/* Hardware feature register 1 */
|
|
DBGPR(" RX fifo size : %u\n",
|
|
hw_feat->rx_fifo_size);
|
|
DBGPR(" TX fifo size : %u\n",
|
|
hw_feat->tx_fifo_size);
|
|
DBGPR(" IEEE 1588 high word : %s\n",
|
|
hw_feat->adv_ts_hi ? "yes" : "no");
|
|
DBGPR(" DMA width : %u\n",
|
|
hw_feat->dma_width);
|
|
DBGPR(" Data Center Bridging : %s\n",
|
|
hw_feat->dcb ? "yes" : "no");
|
|
DBGPR(" Split header : %s\n",
|
|
hw_feat->sph ? "yes" : "no");
|
|
DBGPR(" TCP Segmentation Offload : %s\n",
|
|
hw_feat->tso ? "yes" : "no");
|
|
DBGPR(" Debug memory interface : %s\n",
|
|
hw_feat->dma_debug ? "yes" : "no");
|
|
DBGPR(" Receive Side Scaling : %s\n",
|
|
hw_feat->rss ? "yes" : "no");
|
|
DBGPR(" Traffic Class count : %u\n",
|
|
hw_feat->tc_cnt);
|
|
DBGPR(" Hash table size : %u\n",
|
|
hw_feat->hash_table_size);
|
|
DBGPR(" L3/L4 Filters : %u\n",
|
|
hw_feat->l3l4_filter_num);
|
|
|
|
/* Hardware feature register 2 */
|
|
DBGPR(" RX queue count : %u\n",
|
|
hw_feat->rx_q_cnt);
|
|
DBGPR(" TX queue count : %u\n",
|
|
hw_feat->tx_q_cnt);
|
|
DBGPR(" RX DMA channel count : %u\n",
|
|
hw_feat->rx_ch_cnt);
|
|
DBGPR(" TX DMA channel count : %u\n",
|
|
hw_feat->rx_ch_cnt);
|
|
DBGPR(" PPS outputs : %u\n",
|
|
hw_feat->pps_out_num);
|
|
DBGPR(" Auxiliary snapshot inputs : %u\n",
|
|
hw_feat->aux_snap_num);
|
|
|
|
DBGPR("<--xgbe_get_all_hw_features\n");
|
|
}
|
|
|
|
void
|
|
xgbe_init_tx_coalesce(struct xgbe_prv_data *pdata)
|
|
{
|
|
struct xgbe_hw_if *hw_if = &pdata->hw_if;
|
|
|
|
DBGPR("-->xgbe_init_tx_coalesce\n");
|
|
|
|
pdata->tx_usecs = XGMAC_INIT_DMA_TX_USECS;
|
|
pdata->tx_frames = XGMAC_INIT_DMA_TX_FRAMES;
|
|
|
|
hw_if->config_tx_coalesce(pdata);
|
|
|
|
DBGPR("<--xgbe_init_tx_coalesce\n");
|
|
}
|
|
|
|
void
|
|
xgbe_init_rx_coalesce(struct xgbe_prv_data *pdata)
|
|
{
|
|
struct xgbe_hw_if *hw_if = &pdata->hw_if;
|
|
|
|
DBGPR("-->xgbe_init_rx_coalesce\n");
|
|
|
|
pdata->rx_riwt = hw_if->usec_to_riwt(pdata, XGMAC_INIT_DMA_RX_USECS);
|
|
pdata->rx_usecs = XGMAC_INIT_DMA_RX_USECS;
|
|
pdata->rx_frames = XGMAC_INIT_DMA_RX_FRAMES;
|
|
|
|
hw_if->config_rx_coalesce(pdata);
|
|
|
|
DBGPR("<--xgbe_init_rx_coalesce\n");
|
|
}
|