summaryrefslogtreecommitdiffstats
path: root/src/main_dpdk.h
blob: 3104ff5078fae9cc5f4f60cebd28148b6a4f49b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
  Copyright (c) 2015-2016 Cisco Systems, Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#ifndef MAIN_DPDK_H
#define MAIN_DPDK_H

#include <rte_ethdev.h>
#include "bp_sim.h"

enum {
    MAIN_DPDK_DATA_Q = 0,
    MAIN_DPDK_RX_Q = 1,
};

class CPhyEthIFStats {

 public:
    uint64_t ipackets;  /**< Total number of successfully received packets. */
    uint64_t ibytes;    /**< Total number of successfully received bytes. */
    uint64_t f_ipackets;  /**< Total number of successfully received packets - filter SCTP*/
    uint64_t f_ibytes;    /**< Total number of successfully received bytes. - filter SCTP */
    uint64_t opackets;  /**< Total number of successfully transmitted packets.*/
    uint64_t obytes;    /**< Total number of successfully transmitted bytes. */
    uint64_t ierrors;   /**< Total number of erroneous received packets. */
    uint64_t oerrors;   /**< Total number of failed transmitted packets. */
    uint64_t imcasts;   /**< Total number of multicast received packets. */
    uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */
    uint64_t m_rx_per_flow_pkts [MAX_FLOW_STATS]; // Per flow RX pkts
    uint64_t m_rx_per_flow_bytes[MAX_FLOW_STATS]; // Per flow RX bytes
    // Previous fdir stats values read from driver. Since on xl710 this is 32 bit, we save old value, to handle wrap around.
    uint32_t  m_fdir_prev_pkts [MAX_FLOW_STATS];
    uint32_t  m_fdir_prev_bytes [MAX_FLOW_STATS];
 public:
    void Clear();
    void Dump(FILE *fd);
    void DumpAll(FILE *fd);
};

class CPhyEthIF  {
 public:
    CPhyEthIF (){
        m_port_id=0;
        m_rx_queue=0;
    }
    bool Create(uint8_t portid);
    void Delete();

    void set_rx_queue(uint8_t rx_queue){
        m_rx_queue=rx_queue;
    }

    void configure(uint16_t nb_rx_queue,
                   uint16_t nb_tx_queue,
                   const struct rte_eth_conf *eth_conf);
    void macaddr_get(struct ether_addr *mac_addr);
    void get_stats(CPhyEthIFStats *stats);
    int dump_fdir_global_stats(FILE *fd);
    int reset_hw_flow_stats();
    int get_flow_stats(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, int min, int max, bool reset);
    int get_flow_stats_payload(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, int min, int max, bool reset);
    void get_stats_1g(CPhyEthIFStats *stats);
    void rx_queue_setup(uint16_t rx_queue_id,
                        uint16_t nb_rx_desc,
                        unsigned int socket_id,
                        const struct rte_eth_rxconf *rx_conf,
                        struct rte_mempool *mb_pool);
    void tx_queue_setup(uint16_t tx_queue_id,
                        uint16_t nb_tx_desc,
                        unsigned int socket_id,
                        const struct rte_eth_txconf *tx_conf);
    void configure_rx_drop_queue();
    void configure_rx_duplicate_rules();
    void start();
    void stop();
    void update_link_status();
    void update_link_status_nowait();
    bool is_link_up(){
        return (m_link.link_status?true:false);
    }
    void get_link_speed(uint32_t *link_speed){
        *link_speed = m_link.link_speed;
    }
    void dump_link(FILE *fd);
    void disable_flow_control();
    void set_promiscuous(bool enable);
    void add_mac(char * mac);
    bool get_promiscuous();
    void dump_stats(FILE *fd);
    void update_counters();
    void stats_clear();
    uint8_t             get_port_id(){
        return (m_port_id);
    }
    float get_last_tx_rate(){
        return (m_last_tx_rate);
    }
    float get_last_rx_rate(){
        return (m_last_rx_rate);
    }
    float get_last_tx_pps_rate(){
        return (m_last_tx_pps);
    }
    float get_last_rx_pps_rate(){
        return (m_last_rx_pps);
    }

    CPhyEthIFStats     & get_stats(){
        return ( m_stats );
    }
    void flush_dp_rx_queue(void);
    void flush_rx_queue(void);
    int add_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type, uint8_t l4_proto
                          , uint8_t ipv6_next_h, uint16_t id) const;
    int del_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type, uint8_t l4_proto
                          , uint8_t ipv6_next_h, uint16_t id) const;
    inline uint16_t  tx_burst(uint16_t queue_id, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) {
        return rte_eth_tx_burst(m_port_id, queue_id, tx_pkts, nb_pkts);
    }
    inline uint16_t  rx_burst(uint16_t queue_id, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) {
        return rte_eth_rx_burst(m_port_id, queue_id, rx_pkts, nb_pkts);
    }
    inline uint32_t pci_reg_read(uint32_t reg_off) {
        void *reg_addr;
        uint32_t reg_v;
        reg_addr = (void *)((char *)m_dev_info.pci_dev->mem_resource[0].addr +
                            reg_off);
        reg_v = *((volatile uint32_t *)reg_addr);
        return rte_le_to_cpu_32(reg_v);
    }
    inline void pci_reg_write(uint32_t reg_off,
                              uint32_t reg_v) {
        void *reg_addr;

        reg_addr = (void *)((char *)m_dev_info.pci_dev->mem_resource[0].addr +
                            reg_off);
        *((volatile uint32_t *)reg_addr) = rte_cpu_to_le_32(reg_v);
    }
    void dump_stats_extended(FILE *fd);
    uint8_t                  get_rte_port_id(void) {
        return m_port_id;
    }
    int get_rx_stat_capabilities();

    const std::vector<std::pair<uint8_t, uint8_t>> & get_core_list();

 private:
    struct rte_eth_link      m_link;
    uint8_t                  m_port_id;
    uint8_t                  m_rx_queue;
    uint64_t                 m_sw_try_tx_pkt;
    uint64_t                 m_sw_tx_drop_pkt;
    CBwMeasure               m_bw_tx;
    CBwMeasure               m_bw_rx;
    CPPSMeasure              m_pps_tx;
    CPPSMeasure              m_pps_rx;
    CPhyEthIFStats           m_stats;
    float                    m_last_tx_rate;
    float                    m_last_rx_rate;
    float                    m_last_tx_pps;
    float                    m_last_rx_pps;

    /* holds the core ID list for this port - (core, dir) list*/
    std::vector<std::pair<uint8_t, uint8_t>> m_core_id_list;

 public:
    struct rte_eth_dev_info  m_dev_info;
};

// Because it is difficult to move CGlobalTRex into this h file, defining interface class to it
class CGlobalTRexInterface  {
 public:
    CPhyEthIF *get_ports(uint8_t &port_num);
};

#endif