158f1ee52SIdo Barnea/*
258f1ee52SIdo Barnea  Copyright (c) 2016-2016 Cisco Systems, Inc.
358f1ee52SIdo Barnea
458f1ee52SIdo Barnea  Licensed under the Apache License, Version 2.0 (the "License");
558f1ee52SIdo Barnea  you may not use this file except in compliance with the License.
658f1ee52SIdo Barnea  You may obtain a copy of the License at
758f1ee52SIdo Barnea
858f1ee52SIdo Barnea  http://www.apache.org/licenses/LICENSE-2.0
958f1ee52SIdo Barnea
1058f1ee52SIdo Barnea  Unless required by applicable law or agreed to in writing, software
1158f1ee52SIdo Barnea  distributed under the License is distributed on an "AS IS" BASIS,
1258f1ee52SIdo Barnea  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1358f1ee52SIdo Barnea  See the License for the specific language governing permissions and
1458f1ee52SIdo Barnea  limitations under the License.
1558f1ee52SIdo Barnea*/
1658f1ee52SIdo Barnea
1758f1ee52SIdo Barnea#include <stdint.h>
1858f1ee52SIdo Barnea#include <rte_byteorder.h>
1958f1ee52SIdo Barnea#include <rte_ethdev.h>
2058f1ee52SIdo Barnea#include "dpdk/drivers/net/i40e/base/i40e_register.h"
2158f1ee52SIdo Barnea#include "dpdk/drivers/net/i40e/base/i40e_status.h"
2258f1ee52SIdo Barnea#include "dpdk/drivers/net/i40e/base/i40e_osdep.h"
2358f1ee52SIdo Barnea#include "dpdk/drivers/net/i40e/base/i40e_type.h"
2458f1ee52SIdo Barnea#include "dpdk/drivers/net/i40e/i40e_ethdev.h"
2558f1ee52SIdo Barnea#include "dpdk_funcs.h"
2658f1ee52SIdo Barnea
2758f1ee52SIdo Barneavoid i40e_trex_dump_fdir_regs(struct i40e_hw *hw)
2858f1ee52SIdo Barnea{
2958f1ee52SIdo Barnea    int reg_nums[] = {31, 33, 34, 35, 41, 43};
3058f1ee52SIdo Barnea    int i;
3158f1ee52SIdo Barnea    uint32_t reg;
3258f1ee52SIdo Barnea
3358f1ee52SIdo Barnea    for (i =0; i < sizeof (reg_nums)/sizeof(int); i++) {
3458f1ee52SIdo Barnea	reg = I40E_READ_REG(hw,I40E_PRTQF_FD_INSET(reg_nums[i], 0));
3558f1ee52SIdo Barnea        printf("I40E_PRTQF_FD_INSET(%d, 0): 0x%08x\n", reg_nums[i], reg);
3658f1ee52SIdo Barnea	reg = I40E_READ_REG(hw,I40E_PRTQF_FD_INSET(reg_nums[i], 1));
3758f1ee52SIdo Barnea        printf("I40E_PRTQF_FD_INSET(%d, 1): 0x%08x\n", reg_nums[i], reg);
3858f1ee52SIdo Barnea    }
3958f1ee52SIdo Barnea}
4058f1ee52SIdo Barnea
4158f1ee52SIdo Barneavoid i40e_trex_fdir_reg_init(int port_id, int mode)
4258f1ee52SIdo Barnea{
4358f1ee52SIdo Barnea    struct rte_eth_dev *dev = &rte_eth_devices[port_id];
4458f1ee52SIdo Barnea	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
4558f1ee52SIdo Barnea
4658f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_GLQF_ORT(12), 0x00000062);
4758f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_GLQF_PIT(2), 0x000024A0);
4858f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 0), 0);
4958f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 0), 0);
5058f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 0), 0);
5158f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 0), 0);
5258f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 0), 0);
5358f1ee52SIdo Barnea    I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 0), 0);
5458f1ee52SIdo Barnea    switch(mode) {
5558f1ee52SIdo Barnea    case I40E_TREX_INIT_STL:
5658f1ee52SIdo Barnea        // stateless - filter according to IP id or IPv6 identification
5758f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0x00100000);
5858f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0x00100000);
5958f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0x00100000);
6058f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1),   0x0000000000200000ULL);
6158f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1),   0x0000000000200000ULL);
6258f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0x0000000000200000ULL);
6358f1ee52SIdo Barnea        break;
6458f1ee52SIdo Barnea    case I40E_TREX_INIT_RCV_ALL:
6558f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0);
6658f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0);
6758f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0);
6858f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1), 0);
6958f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1), 0);
7058f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0);
7158f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 0), 0);
7258f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 1), 0);
7358f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 0), 0);
7458f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 1), 0);
7558f1ee52SIdo Barnea        break;
7658f1ee52SIdo Barnea    case I40E_TREX_INIT_STF:
7758f1ee52SIdo Barnea    default:
7858f1ee52SIdo Barnea        // stateful - Filter according to TTL or IPv6 hop limit
7958f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0x00040000);
8058f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0x00040000);
8158f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0x00040000);
8258f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1), 0x00080000);
8358f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1), 0x00080000);
8458f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0x00080000);
8558f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 0), 0);
8658f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 1), 0x00040000);
8758f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 0), 0);
8858f1ee52SIdo Barnea        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 1), 0x00080000);
8958f1ee52SIdo Barnea        break;
9058f1ee52SIdo Barnea    }
9158f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_GLQF_FD_MSK(0, 34), 0x000DFF00);
9258f1ee52SIdo Barnea	I40E_WRITE_REG(hw, I40E_GLQF_FD_MSK(0,44), 0x000C00FF);
9358f1ee52SIdo Barnea	I40E_WRITE_FLUSH(hw);
9458f1ee52SIdo Barnea}
958957b863SIdo Barnea
968957b863SIdo Barnea// fill stats array with fdir rules match count statistics
978957b863SIdo Barnea// Notice that we read statistics from start to start + len, but we fill the stats are
988957b863SIdo Barnea//  starting from 0 with len values
998957b863SIdo Barneavoid
1008957b863SIdo Barneai40e_trex_fdir_stats_get(struct rte_eth_dev *dev, uint32_t *stats, uint32_t start, uint32_t len)
1018957b863SIdo Barnea{
1028957b863SIdo Barnea    int i;
1038957b863SIdo Barnea    struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1048957b863SIdo Barnea
1058957b863SIdo Barnea    for (i = 0; i < len; i++) {
1068957b863SIdo Barnea        stats[i] = I40E_READ_REG(hw, I40E_GLQF_PCNT(i + start));
1078957b863SIdo Barnea    }
1088957b863SIdo Barnea}
1098957b863SIdo Barnea
1108957b863SIdo Barneavoid
1118957b863SIdo Barneai40e_trex_fdir_stats_reset(struct rte_eth_dev *dev, uint32_t *stats, uint32_t start, uint32_t len)
1128957b863SIdo Barnea{
1138957b863SIdo Barnea    int i;
1148957b863SIdo Barnea    struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1158957b863SIdo Barnea
1168957b863SIdo Barnea    for (i = 0; i < len; i++) {
1178957b863SIdo Barnea        if (stats) {
1188957b863SIdo Barnea            stats[i] = I40E_READ_REG(hw, I40E_GLQF_PCNT(i + start));
1198957b863SIdo Barnea        }
1208957b863SIdo Barnea        I40E_WRITE_REG(hw, I40E_GLQF_PCNT(i + start), 0xffffffff);
1218957b863SIdo Barnea    }
1228957b863SIdo Barnea}
1238957b863SIdo Barnea
1248957b863SIdo Barneaint
1258957b863SIdo Barneai40e_trex_get_fw_ver(struct rte_eth_dev *dev, uint32_t *nvm_ver)
1268957b863SIdo Barnea{
1278957b863SIdo Barnea    struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1288957b863SIdo Barnea
1298957b863SIdo Barnea    *nvm_ver = hw->nvm.version;
1308957b863SIdo Barnea    return 0;
1318957b863SIdo Barnea}
1328957b863SIdo Barnea
1338957b863SIdo Barnea/* This function existed in older DPDK versions. We keep it */
1348957b863SIdo Barneaint
1358957b863SIdo Barnearte_eth_dev_get_port_by_addr(const struct rte_pci_addr *addr, uint8_t *port_id)
1368957b863SIdo Barnea{
1378957b863SIdo Barnea	int i;
1388957b863SIdo Barnea	struct rte_pci_device *pci_dev = NULL;
1398957b863SIdo Barnea
1408957b863SIdo Barnea	if (addr == NULL) {
1418957b863SIdo Barnea		RTE_PMD_DEBUG_TRACE("Null pointer is specified\n");
1428957b863SIdo Barnea		return -EINVAL;
1438957b863SIdo Barnea	}
1448957b863SIdo Barnea
1458957b863SIdo Barnea	*port_id = RTE_MAX_ETHPORTS;
1468957b863SIdo Barnea
1478957b863SIdo Barnea	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
1488957b863SIdo Barnea		if (
1498957b863SIdo Barnea			!rte_eal_compare_pci_addr(&rte_eth_devices[i].device->devargs->pci.addr, addr)) {
1508957b863SIdo Barnea
1518957b863SIdo Barnea			*port_id = i;
1528957b863SIdo Barnea
1538957b863SIdo Barnea			return 0;
1548957b863SIdo Barnea		}
1558957b863SIdo Barnea	}
1568957b863SIdo Barnea	return -ENODEV;
1578957b863SIdo Barnea}
1588957b863SIdo Barnea
1598957b863SIdo Barnea// return in stats, statistics starting from start, for len counters.
1608957b863SIdo Barneaint
1618957b863SIdo Barnearte_eth_fdir_stats_get(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_t len)
1628957b863SIdo Barnea{
1638957b863SIdo Barnea	struct rte_eth_dev *dev;
1648957b863SIdo Barnea
1658957b863SIdo Barnea	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
1668957b863SIdo Barnea
1678957b863SIdo Barnea	dev = &rte_eth_devices[port_id];
1688957b863SIdo Barnea
1698957b863SIdo Barnea    // Only xl710 support this
1708957b863SIdo Barnea    i40e_trex_fdir_stats_get(dev, stats, start, len);
1718957b863SIdo Barnea
1728957b863SIdo Barnea    return 0;
1738957b863SIdo Barnea}
1748957b863SIdo Barnea
1758957b863SIdo Barnea// zero statistics counters, starting from start, for len counters.
1768957b863SIdo Barneaint
1778957b863SIdo Barnearte_eth_fdir_stats_reset(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_t len)
1788957b863SIdo Barnea{
1798957b863SIdo Barnea	struct rte_eth_dev *dev;
1808957b863SIdo Barnea
1818957b863SIdo Barnea	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
1828957b863SIdo Barnea
1838957b863SIdo Barnea	dev = &rte_eth_devices[port_id];
1848957b863SIdo Barnea
1858957b863SIdo Barnea    // Only xl710 support this
1868957b863SIdo Barnea    i40e_trex_fdir_stats_reset(dev, stats, start, len);
1878957b863SIdo Barnea
1888957b863SIdo Barnea    return 0;
1898957b863SIdo Barnea}
1908957b863SIdo Barnea
1918957b863SIdo Barneaint
1928957b863SIdo Barnearte_eth_get_fw_ver(int port_id, uint32_t *version)
1938957b863SIdo Barnea{
1948957b863SIdo Barnea	struct rte_eth_dev *dev;
1958957b863SIdo Barnea
1968957b863SIdo Barnea	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
1978957b863SIdo Barnea
1988957b863SIdo Barnea	dev = &rte_eth_devices[port_id];
1998957b863SIdo Barnea
2008957b863SIdo Barnea    // Only xl710 support this
2018957b863SIdo Barnea    return i40e_trex_get_fw_ver(dev, version);
2028957b863SIdo Barnea}
203