2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
24 #include <sys/types.h>
25 #include <sys/queue.h>
26 #include <netinet/in.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <rte_common.h>
39 #include <rte_malloc.h>
40 #include <rte_memory.h>
41 #include <rte_memcpy.h>
42 #include <rte_memzone.h>
44 #include <rte_per_lcore.h>
45 #include <rte_launch.h>
46 #include <rte_atomic.h>
47 #include <rte_cycles.h>
48 #include <rte_prefetch.h>
49 #include <rte_lcore.h>
50 #include <rte_per_lcore.h>
51 #include <rte_branch_prediction.h>
52 #include <rte_interrupts.h>
54 #include <rte_random.h>
55 #include <rte_debug.h>
56 #include <rte_ether.h>
57 #include <rte_ethdev.h>
59 #include <rte_mempool.h>
61 #include <rte_eth_ctrl.h>
62 #include <rte_errno.h>
63 #include <rte_port_ethdev.h>
64 #include <rte_eth_bond.h>
65 #include <rte_rwlock.h>
67 #define RTE_LOGTYPE_IFM RTE_LOGTYPE_USER1
69 #define IFM_FAILURE -1
71 * IFM Ether link related macros
73 #define IFM_ETH_LINK_HALF_DUPLEX 0
74 #define IFM_ETH_LINK_FULL_DUPLEX 1
75 #define IFM_ETH_LINK_DOWN 0
76 #define IFM_ETH_LINK_UP 1
77 #define IFM_ETH_LINK_FIXED 0
82 #define IFM_SLAVE (1<<0)
83 #define IFM_MASTER (1<<1)
84 #define IFM_BONDED (1<<2)
85 #define IFM_IPV4_ENABLED (1<<3)
86 #define IFM_IPV6_ENABLED (1<<4)
88 #define IFM_BONDING_MODE_ROUND_ROBIN 0
89 #define IFM_BONDING_MODE_ACTIVE_BACKUP 1
90 #define IFM_BONDING_MODE_BALANCE 2
91 #define IFM_BONDING_MODE_BROADCAST 3
92 #define IFM_BONDING_MODE_8023AD 4
93 #define IFM_BONDING_MODE_TLB 5
94 #define IFM_BONDING_MODE_ALB 6
96 #define IFM_BALANCE_XMIT_POLICY_LAYER2 0
97 #define IFM_BALANCE_XMIT_POLICY_LAYER23 1
98 #define IFM_BALANCE_XMIT_POLICY_LAYER34 2
100 * Queue related macros
102 #define IFM_QUEUE_STAT_CNTRS 16
103 #define IFM_TX_DEFAULT_Q 0
104 #define IFM_RX_DEFAULT_Q 0
105 #define IFM_RX_DESC_DEFAULT 128
106 #define IFM_TX_DESC_DEFAULT 512
107 #define IFM_BURST_SIZE 32
108 #define IFM_BURST_TX_WAIT_US 1
109 #define IFM_BURST_TX_RETRIES 64
110 #define BURST_TX_DRAIN_US 100
115 #define IFM_IFNAME_LEN 16
116 #define IFM_CLIENT_NAME 20
117 #define IFM_MAX_CLIENT 10
119 #define IFM_ETHER_ADDR_SIZE 6
120 #define IFM_IPV6_ADDR_SIZE 16
122 #define IFM_DEBUG_CONFIG (1<<0)
123 #define IFM_DEBUG_RXTX (1<<1)
124 #define IFM_DEBUG_LOCKS (1<<2)
125 #define IFM_DEBUG (1<<4)
126 #define IFM_MAX_PORTARR_SZ 64
127 #define IFM_MAX_PORTARR_SZ 64
129 * Mempool configuration details:
130 * Stores the mempool configuration information for the port.
132 struct mempool_config {
133 uint32_t pool_size;/**< The number of elements in the mempool.*/
134 uint32_t buffer_size;
135 /**< The size of an element*/
138 uint32_t cpu_socket_id;
139 /**< The socket identifier in the case of NUMA.*/
140 } __rte_cache_aligned;
143 * Port configuration:
144 * Stores the configuration information for the port.
145 * This structure is used during port and tx/rx queue setup.
147 typedef struct _port_config_ {
148 uint8_t port_id; /**< port id or pmd id to be configured */
149 int nrx_queue; /**< no of rx queues */
150 int ntx_queue; /**< no of tx queues */
151 uint32_t tx_buf_size;
152 uint32_t state; /**< noshut/shut the admin state of the port*/
153 uint32_t promisc; /**< enable/diable promisc mode*/
154 struct mempool_config mempool;
155 /**< Mempool configurations */
156 struct rte_eth_conf port_conf;
157 /**< port configuration */
158 struct rte_eth_rxconf rx_conf;
159 /**< rx queue configurations */
160 struct rte_eth_txconf tx_conf;
161 /**< tx queue configurations */
166 * if_stats structure is a member variable of structure l2_phy_interface_t.
167 * Used to maintain stats retreived from rte_eth_stats structure.
169 typedef struct _if_stats_ {
170 uint64_t rx_npkts;/**< Total number of successfully received packets.*/
171 uint64_t tx_npkts;/**< Total number of successfully transmitted bytes. */
172 uint64_t rx_bytes;/**< Total number of successfully received bytes.*/
173 uint64_t tx_bytes;/**< Total number of successfully transmitted bytes.*/
174 uint64_t rx_missed_pkts;
175 /**< no of packets dropped by hw due because rx queues are full*/
176 uint64_t rx_err_pkts;/**< Total number of erroneous received packets. */
177 uint64_t rx_nobuf_fail;/**< Total number of RX mbuf allocation failures. */
178 uint64_t tx_failed_pkts;/**< Total number of failed transmitted packets.*/
179 uint64_t q_rxpkts[IFM_QUEUE_STAT_CNTRS];/**< Total number of queue RX packets.*/
180 uint64_t q_txpkts[IFM_QUEUE_STAT_CNTRS];/**< Total number of queue TX packets.*/
181 uint64_t q_rx_bytes[IFM_QUEUE_STAT_CNTRS];
182 /**< Total number of successfully received queue bytes.*/
183 uint64_t q_tx_bytes[IFM_QUEUE_STAT_CNTRS];
184 /**< Total number of successfully transmitted queue bytes.*/
185 uint64_t q_rx_pkt_drop[IFM_QUEUE_STAT_CNTRS];
186 /**<Total number of queue packets received that are dropped.*/
187 } __rte_cache_aligned if_stats;
189 * structure to store bond port information
193 /**<portid of the bond port.*/
195 /**<socketid of the port.*/
199 /**<xmit policy for this port.*/
200 uint32_t internal_ms;
202 uint32_t link_up_delay_ms;
203 /**<frequency of informing linkup delay.*/
204 uint32_t link_down_delay_ms;
205 /**<frequency of informing linkdown delay.*/
207 /**<primary port of this bond.*/
208 uint8_t slaves[RTE_MAX_ETHPORTS];
212 uint8_t active_slaves[RTE_MAX_ETHPORTS];
213 /**<list of active slaves.*/
214 int active_slave_count;
215 /**<cnt of active slave.*/
216 } __rte_cache_aligned;
219 * Physical port details:
220 * Used to store information about configured port.
221 * Most of the member variables in this structure are populated
222 * from struct rte_eth_dev_info
224 typedef struct _l2_phy_interface_ {
225 struct _l2_phy_interface_ *next; /**< pointer to physical interface list */
226 uint8_t pmdid; /**< populated from rth_eth_dev_info */
227 unsigned int if_index; /**< populated from rth_eth_dev_info */
228 char ifname[IFM_IFNAME_LEN]; /**< populated from rth_eth_dev_info */
229 uint16_t mtu; /**< mtu value - configurable */
230 uint8_t macaddr[IFM_ETHER_ADDR_SIZE]; /**< Ether addr*/
231 uint32_t promisc; /**< promisc mode - configurable*/
232 uint32_t flags; /**< Used for link bonding */
234 uint32_t link_speed; /**< line speed */
235 uint16_t link_duplex:1; /**< duplex mode */
236 uint16_t link_autoneg:1; /**< auto negotiation*/
237 uint16_t link_status:1; /**< operational status */
238 uint16_t admin_status:1; /**< Admin status of a port*/
240 struct rte_mempool *mempool; /**< HW Q*/
241 uint32_t min_rx_bufsize; /**< rx buffer size supported */
242 uint32_t max_rx_pktlen; /**< max size of packet*/
243 uint16_t max_rx_queues; /**< max number of rx queues supported */
244 uint16_t max_tx_queues; /**< max number queues supported*/
245 uint64_t n_rxpkts; /**< number of packets received */
246 uint64_t n_txpkts; /**< number of packets transmitted */
247 if_stats stats; /**< port stats - populated from rte_eth_ifstats */
248 uint16_t(*retrieve_bulk_pkts) (uint8_t, uint16_t, struct rte_mbuf **);
249 /**< pointer to read packets*/
250 uint16_t(*transmit_bulk_pkts) (struct _l2_phy_interface_ *, struct rte_mbuf **, uint64_t);
251 /**< pointer to transmit the bulk of packets */
252 int (*transmit_single_pkt) (struct _l2_phy_interface_ *, struct rte_mbuf *);
253 /**< pointer to transmit the a single packet*/
254 struct rte_eth_dev_tx_buffer *tx_buffer;
255 uint64_t tx_buf_len; /**< number of packets in tx_buf */
256 void *ipv4_list; /**< pointer to ip list */
257 void *ipv6_list; /**< pointer to ipv6 list */
258 struct bond_port *bond_config; /**< pointer to bond info*/
259 port_config_t port_config;
260 } __rte_cache_aligned l2_phy_interface_t;
263 * Port IPv4 address details:
264 * Used to maintain IPv4 information of a port.
266 typedef struct _ipv4list_ {
267 struct _ipv4list_ *next;/**< pointer to IPv4 list */
268 uint32_t ipaddr; /**< Configured ipv4 address */
269 unsigned int addrlen; /**< subnet mask or addrlen */
270 unsigned int mtu; /**< IPv6 mtu*/
271 l2_phy_interface_t *port;
272 /**< pointer to a port on which this ipaddr is configured*/
276 * Port IPv6 address details:
277 * Used to maintain IPv6 information of a port.
279 typedef struct _ipv6list_ {
280 struct _ipv6list_ *next; /**< Ptr IPv6 list */
281 uint8_t ipaddr[IFM_IPV6_ADDR_SIZE]; /**< Configured ipv6 address */
282 unsigned int addrlen; /**< subnet mask or addrlen*/
283 unsigned int mtu; /**< IPv6 mtu*/
284 l2_phy_interface_t *port; /**< ptr to a port on whicch ipv6 addr is configured*/
288 * Interface Manager client details:
289 * Maintains information about clients who registered for link status update.
290 * Stores callback function to be called in case of link state change.
292 typedef struct _ifm_client_ {
293 uint32_t clientid; /**< unique client id identifies the client used for indexing*/
294 void (*cb_linkupdate) (uint8_t, unsigned int);
295 /**< callback function to be triggered during an event*/
296 } __rte_cache_aligned ifm_client;
299 * Interface manager global structure:
300 * IFM main structure has pointer configured port list.
302 typedef struct _interface_main_ {
303 l2_phy_interface_t *port_list[IFM_MAX_PORTARR_SZ];
304 uint32_t nport_configured; /**< no of ports sucessfully configured during PCI probe*/
305 uint32_t nport_intialized; /**< no of ports sucessfully initialized through ifm_init*/
306 uint8_t nclient; /**< no of clients registered for Interface manager events*/
307 ifm_client if_client[IFM_MAX_CLIENT]; /**< Array of interface manager client details*/
308 } __rte_cache_aligned interface_main_t;
311 * Init function of Interface manager. Calls port_setup function for every port.
314 * A pointer to port_config_t contains port configuration.
317 * IFM_SUCCESS - On success.
318 * IFM_FAILURE - On Failure.
320 int ifm_configure_ports(port_config_t *pconfig);
323 * Returns first port from port list.
329 * On success - Returns a pointer to first port in the list of
330 * type l2_phy_interface_t.
333 l2_phy_interface_t *ifm_get_first_port(void);
336 * Get a port from the physical port list which is next node to
337 * the given portid in the list.
343 * On success - Returns a pointer to next port in the list of
344 * type l2_phy_interface_t.
347 l2_phy_interface_t *ifm_get_next_port(uint8_t port_id);
350 * Get a pointer to port for the given portid from the physical port list.
353 * A pmd id of the port.
356 * On success - returns pointer to l2_phy_interface_t.
359 l2_phy_interface_t *ifm_get_port(uint8_t);
362 * Get a pointer to port for the given port name from the physical port list.
368 * On success - returns pointer to l2_phy_interface_t.
371 l2_phy_interface_t *ifm_get_port_by_name(const char *name);
373 * Removes given port from the physical interface list.
376 * portid - pmd_id of port.
380 void ifm_remove_port_details(uint8_t portid);
383 * Adds give port to the begining of physical interface list.
385 * @param l2_phy_interface_t *
386 * pointer to l2_phy_interface_t.
390 void ifm_add_port_to_port_list(l2_phy_interface_t *);
393 * Checks whether the global physical port list is NULL.
399 int is_port_list_null(void);
402 * Configures the device port. Also sets tx and rx queue.
403 * Populates port structure and adds it physical interface list.
406 * Contains configuration about rx queue, tx queue.
409 * IFM_SUCCESS - On success.
410 * IFM_FAILURE - On Failure.
412 int ifm_port_setup(uint8_t port_id, port_config_t *);
415 * Initializes interface manager main structure
424 * Returns number of ports initialized during pci probe.
430 * number of ports initialized - On success.
431 * IFM_FAILURE - On Failure.
433 int32_t ifm_get_nports_initialized(void);
436 * Returns number of ports initialized ifm_init.
442 * number of ports initialized - On success.
443 * IFM_FAILURE - On Failure.
445 int32_t ifm_get_nactive_ports(void);
448 * Checks whether port is ipv4 enabled.
451 * A pmd id of the port.
454 * IFM_SUCCESS - On success.
455 * IFM_FAILURE - On Failure.
457 int32_t ifm_chk_port_ipv4_enabled(uint8_t port_id);
460 * Checks whether port is ipv6 enabled.
463 * A pmd id of the port.
466 * IFM_SUCCESS - On success.
467 * IFM_FAILURE - On Failure.
469 int32_t ifm_chk_port_ipv6_enabled(uint8_t port_id);
472 * Remove ipv4 address from the given port.
475 * A pmd id of the port.
477 * ipv4 address to be removed
479 * ipv4 address length
482 * IFM_SUCCESS - On success.
483 * IFM_FAILURE - On Failure.
485 int16_t ifm_remove_ipv4_port(uint8_t port_id, uint32_t ipaddr,
489 * Remove ipv6 address from the given port.
492 * A pmd id of the port.
494 * ipv4 address to be removed
496 * ipv4 address length
499 * IFM_SUCCESS - On success.
500 * IFM_FAILURE - On Failure.
502 int16_t ifm_remove_ipv6_port(uint8_t port_id, uint32_t ip6addr,
506 * Add ipv4 address to the given port.
509 * A pmd id of the port.
511 * ipv4 address to be configured
513 * ipv4 address length
516 * IFM_SUCCESS - On success.
517 * IFM_FAILURE - On Failure.
519 int16_t ifm_add_ipv4_port(uint8_t port_id, uint32_t ipaddr, uint32_t addrlen);
522 * Add ipv6 address to the given port.
525 * A pmd id of the port.
527 * ipv6 address to be configured
529 * ipv4 address length
532 * IFM_SUCCESS - On success.
533 * IFM_FAILURE - On Failure.
535 int8_t ifm_add_ipv6_port(uint8_t port_id, uint8_t ip6addr[], uint32_t addrlen);
538 * Buffers the packet in the tx quueue.
541 * pointer to the port.
543 * packet to be transmitted
546 * number of packets transmitted
548 int ifm_transmit_single_pkt(l2_phy_interface_t *port,
549 struct rte_mbuf *tx_pkts);
552 * Transmit the packet
555 * pointer to the port.
557 * packets to be transmitted
559 * number of packets to be transmitted
562 * number of packets transmitted
564 uint16_t ifm_transmit_bulk_pkts(l2_phy_interface_t *, struct rte_mbuf **tx_pkts,
568 * Receive burst of 32 packets
571 * From which port we need to read packets
573 * From which port we need to read packets
575 * mbuf in which read packets will be placed
578 * number of packets read
580 uint16_t ifm_receive_bulk_pkts(uint8_t port_id, uint16_t qid,
581 struct rte_mbuf **rx_pkts);
584 * Enable or disable promiscmous mode
589 * 1 - enable, IFM_SUCCESS - disable
594 void ifm_set_port_promisc(uint8_t port_id, uint8_t enable);
597 * Enable or disable promiscmous mode
602 * 1 - enable, 0 - disable
607 void ifm_set_l2_interface_mtu(uint8_t port_id, uint16_t mtu);
610 * Set MTU value for the port
620 void ifm_update_linkstatus(uint8_t port_id, uint16_t linkstatus);
623 * Register for link state event
626 * Unique number identifies client.
627 * @param cb_linkupdate
628 * Callback function which has to be called at time of event
633 void ifm_register_for_linkupdate(uint32_t clientid,
634 void (*cb_linkupdate) (uint8_t, unsigned int));
637 * Callback which is triggered at the time of link state change which in turn triggers registered
650 void lsi_event_callback(uint8_t port_id, enum rte_eth_event_type type,
653 * Prints list of interfaces
656 void print_interface_details(void);
658 * Creates bond interface
664 * port configuration to be applied
665 * @returns 0 on success and 1 on failure
667 int ifm_bond_port_create(const char *name, int mode, port_config_t *portconf);
669 * Deletes bond interface
672 * @returns 0 on success and 1 on failure
674 int ifm_bond_port_delete(const char *name);
676 * Addes a port as slave to bond
677 * @Param bonded_port_id
679 * @Param slave_port_id
680 * slave port s port id
681 * @returns 0 on success and 1 on failure
683 int ifm_add_slave_port(uint8_t bonded_port_id, uint8_t slave_port_id);
685 * Removes a port as slave to bond
686 * @Param bonded_port_id
688 * @Param slave_port_id
689 * slave port s port id
690 * @returns 0 on success and 1 on failure
692 int ifm_remove_slave_port(uint8_t bonded_port_id, uint8_t slave_port_id);
694 * Sets bond port 's mode
695 * @Param bonded_port_id
699 * @returns 0 on success and 1 on failure
701 int set_bond_mode(uint8_t bonded_port_id, uint8_t mode);
703 * Get bond port 's mode
704 * @Param bonded_port_id
706 * @returns mode value or -1 on failure
708 int get_bond_mode(uint8_t bonded_port_id);
710 * Set a slave port to bond
711 * @Param bonded_port_id
713 * @Param slave_port_id
714 * slave port s port id
715 * @returns 0 on success and 1 on failure
717 int set_bond_primary(uint8_t bonded_port_id, uint8_t slave_port_id);
719 * Get primary port of the bond
720 * @Param bonded_port_id
722 * @returns port id of primary on success and 1 on failure
724 int get_bond_primary_port(uint8_t bonded_port_id);
726 * Get slave count for the bond
727 * @Param bonded_port_id
729 * @returns slave count on success and 1 on failure
731 int get_bond_slave_count(uint8_t bonded_port_id);
733 * Get active slave count for the bond
734 * @Param bonded_port_id
736 * @returns active slaves count on success and 1 on failure
738 int get_bond_active_slave_count(uint8_t bonded_port_id);
740 * Get slaves in the bond
741 * @Param bonded_port_id
744 * array to save slave port
745 * @returns 0 on success and 1 on failure
747 int get_bond_slaves(uint8_t bonded_port_id, uint8_t slaves[RTE_MAX_ETHPORTS]);
749 * Get active slaves in the bond
750 * @Param bonded_port_id
753 * array to save slave port
754 * @returns 0 on success and 1 on failure
756 int get_bond_active_slaves(uint8_t bonded_port_id,
757 uint8_t slaves[RTE_MAX_ETHPORTS]);
759 * Sets bond port 's mac address
760 * @Param bonded_port_id
763 * mac_addr - mac addr
764 * @returns 0 on success and 1 on failure
766 int set_bond_mac_address(uint8_t bonded_port_id, struct ether_addr *mac_addr);
768 * Sets bond port 's MAC
769 * @Param bonded_port_id
771 * @returns 0 on success and 1 on failure
773 int reset_bond_mac_addr(uint8_t bonded_port_id);
774 int get_bond_mac(uint8_t bonded_port_id, struct ether_addr *macaddr);
776 * Sets bond port 's policy
777 * @Param bonded_port_id
781 * @returns 0 on success and 1 on failure
783 int set_bond_xmitpolicy(uint8_t bonded_port_id, uint8_t policy);
785 * Get bond port 's xmit policy
786 * @Param bonded_port_id
788 * @returns xmit policy value or -1 on failure
790 int get_bond_xmitpolicy(uint8_t bonded_port_id);
792 * Sets bond port 's monitor frequency
793 * @Param bonded_port_id
797 * @returns 0 on success and 1 on failure
799 int set_bond_link_montitor_frequency(uint8_t bonded_port_id,
800 uint32_t internal_ms);
802 * Get bond port 's monitor frequency
803 * @Param bonded_port_id
805 * @returns frequency value or -1 on failure
807 int get_bond_link_monitor_frequency(uint8_t bonded_port_id);
809 * Sets bond port 's link down delay
810 * @Param bonded_port_id
814 * @returns 0 on success and 1 on failure
816 int set_bond_linkdown_delay(uint8_t bonded_port_id, uint32_t delay_ms);
818 * Get bond port 's link down delay
819 * @Param bonded_port_id
821 * @returns delay ms value or -1 on failure
823 int get_bond_link_down_delay(uint8_t bonded_port_id);
825 * Sets bond port 's link up delay
826 * @Param bonded_port_id
830 * @returns 0 on success and 1 on failure
832 int set_bond_linkup_delay(uint8_t bonded_port_id, uint32_t delay_ms);
834 * Get bond port 's link up delay
835 * @Param bonded_port_id
837 * @returns delay ms value or -1 on failure
839 int get_bond_link_up_delay(uint8_t bonded_port_id);
841 * Print port s statistics
845 void print_stats(void);
847 * Gets information about port
851 * port to address to copy port info
852 * @returns 0 on success otherwise -1
854 int ifm_get_port_info(uint8_t port_id, l2_phy_interface_t *port_info);
856 * Gets information about next port of given portid
860 * port to address to copy port info
861 * @returns 0 on success otherwise -1
863 int ifm_get_next_port_info(uint8_t port_id, l2_phy_interface_t *port_info);
867 * Debug- 1(port config),2(port RXTX),3(hle LOCKS),4(GENERALDEBUG)
869 * Enable 1, disable 0
870 * @returns 0 on success otherwise -1
872 void config_ifm_debug(int dbg, int flag);