13d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko/* 23d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * include/linux/if_team.h - Network team device driver header 33d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com> 43d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * 53d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * This program is free software; you can redistribute it and/or modify 63d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * it under the terms of the GNU General Public License as published by 73d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * the Free Software Foundation; either version 2 of the License, or 83d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * (at your option) any later version. 93d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko */ 103d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko#ifndef _LINUX_IF_TEAM_H_ 113d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko#define _LINUX_IF_TEAM_H_ 123d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 13bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko#include <linux/netpoll.h> 146c85f2bdda2086d804e198a3f31b685bc2f86b04Jiri Pirko#include <net/sch_generic.h> 15fc423ff00df3a19554414eed80aef9de9b50313eJiri Pirko#include <linux/types.h> 16607ca46e97a1b6594b29647d98a32d545c24bdffDavid Howells#include <uapi/linux/if_team.h> 17bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko 183d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostruct team_pcpu_stats { 193d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko u64 rx_packets; 203d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko u64 rx_bytes; 213d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko u64 rx_multicast; 223d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko u64 tx_packets; 233d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko u64 tx_bytes; 243d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct u64_stats_sync syncp; 253d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko u32 rx_dropped; 263d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko u32 tx_dropped; 273d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko}; 283d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 293d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostruct team; 303d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 313d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostruct team_port { 323d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct net_device *dev; 3319a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko struct hlist_node hlist; /* node in enabled ports hash list */ 343d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct list_head list; /* node in ordinary list */ 353d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct team *team; 3619a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko int index; /* index of enabled port. If disabled, it's set to -1 */ 373d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 3871472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko bool linkup; /* either state.linkup or user.linkup */ 3971472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko 4071472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko struct { 4171472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko bool linkup; 4271472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko u32 speed; 4371472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko u8 duplex; 4471472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko } state; 4571472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko 4671472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko /* Values set by userspace */ 4771472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko struct { 4871472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko bool linkup; 4971472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko bool linkup_enabled; 5071472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko } user; 5171472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko 5271472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko /* Custom gennetlink interface related flags */ 5371472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko bool changed; 5471472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko bool removed; 5571472ec12c61dd305ab4d11822af7ecc4f9717f9Jiri Pirko 563d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko /* 573d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * A place for storing original values of the device before it 583d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko * become a port. 593d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko */ 603d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct { 613d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko unsigned char dev_addr[MAX_ADDR_LEN]; 623d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko unsigned int mtu; 633d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko } orig; 643d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 65bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko#ifdef CONFIG_NET_POLL_CONTROLLER 66bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko struct netpoll *np; 67bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko#endif 68bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko 69a86fc6b7d603992070c04bd7a8c217d55688b077Jiri Pirko s32 priority; /* lower number ~ higher priority */ 708ff5105a2b9dd0ba596719b165c1827d101e5f1aJiri Pirko u16 queue_id; 718ff5105a2b9dd0ba596719b165c1827d101e5f1aJiri Pirko struct list_head qom_list; /* node in queue override mapping list */ 72d80b35beac78b52faad2359adf6a6b14e2725e51Jiri Pirko struct rcu_head rcu; 735149ee58385bdfef260fb07a89a8ff0913be6b25Jiri Pirko long mode_priv[0]; 743d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko}; 753d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 7668c450426ae665653b06f62539e48727b696496fJiri Pirkostatic inline bool team_port_enabled(struct team_port *port) 7768c450426ae665653b06f62539e48727b696496fJiri Pirko{ 7868c450426ae665653b06f62539e48727b696496fJiri Pirko return port->index != -1; 7968c450426ae665653b06f62539e48727b696496fJiri Pirko} 8068c450426ae665653b06f62539e48727b696496fJiri Pirko 8168c450426ae665653b06f62539e48727b696496fJiri Pirkostatic inline bool team_port_txable(struct team_port *port) 8268c450426ae665653b06f62539e48727b696496fJiri Pirko{ 8368c450426ae665653b06f62539e48727b696496fJiri Pirko return port->linkup && team_port_enabled(port); 8468c450426ae665653b06f62539e48727b696496fJiri Pirko} 8552a4fd77808662a16cd17ad3b0e1ad75e0162d8bJiri Pirko 86bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko#ifdef CONFIG_NET_POLL_CONTROLLER 87bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirkostatic inline void team_netpoll_send_skb(struct team_port *port, 88bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko struct sk_buff *skb) 89bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko{ 90bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko struct netpoll *np = port->np; 91bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko 92bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko if (np) 93bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko netpoll_send_skb(np, skb); 94bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko} 95bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko#else 96bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirkostatic inline void team_netpoll_send_skb(struct team_port *port, 97bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko struct sk_buff *skb) 98bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko{ 99bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko} 100bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko#endif 101bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96bJiri Pirko 1023d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostruct team_mode_ops { 1033d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko int (*init)(struct team *team); 1043d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko void (*exit)(struct team *team); 1053d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko rx_handler_result_t (*receive)(struct team *team, 1063d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct team_port *port, 1073d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct sk_buff *skb); 1083d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko bool (*transmit)(struct team *team, struct sk_buff *skb); 1093d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko int (*port_enter)(struct team *team, struct team_port *port); 1103d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko void (*port_leave)(struct team *team, struct team_port *port); 1111d76efe1577b4323609b1bcbfafa8b731eda071aJiri Pirko void (*port_change_dev_addr)(struct team *team, struct team_port *port); 1124bccfd17e1f77593e99d5321c48c704a0a43ab68Jiri Pirko void (*port_enabled)(struct team *team, struct team_port *port); 1134bccfd17e1f77593e99d5321c48c704a0a43ab68Jiri Pirko void (*port_disabled)(struct team *team, struct team_port *port); 1143d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko}; 1153d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 116acbba0d0f88e2577b9d92b61b136d13f65831a52Jiri Pirkoextern int team_modeop_port_enter(struct team *team, struct team_port *port); 117acbba0d0f88e2577b9d92b61b136d13f65831a52Jiri Pirkoextern void team_modeop_port_change_dev_addr(struct team *team, 118acbba0d0f88e2577b9d92b61b136d13f65831a52Jiri Pirko struct team_port *port); 119acbba0d0f88e2577b9d92b61b136d13f65831a52Jiri Pirko 1203d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkoenum team_option_type { 1213d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko TEAM_OPTION_TYPE_U32, 1223d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko TEAM_OPTION_TYPE_STRING, 1232615598fc100451c71b83d06bdf5faead619a40eJiri Pirko TEAM_OPTION_TYPE_BINARY, 12414f066bab19946545130a7379f420af860a02ae8Jiri Pirko TEAM_OPTION_TYPE_BOOL, 12569821638b27407d8648cb04de01b06b30a291bdeJiri Pirko TEAM_OPTION_TYPE_S32, 1263d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko}; 1273d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 12885d59a87248de90e3266e10dce99477b60f524c0Jiri Pirkostruct team_option_inst_info { 12985d59a87248de90e3266e10dce99477b60f524c0Jiri Pirko u32 array_index; 13085d59a87248de90e3266e10dce99477b60f524c0Jiri Pirko struct team_port *port; /* != NULL if per-port */ 13185d59a87248de90e3266e10dce99477b60f524c0Jiri Pirko}; 13285d59a87248de90e3266e10dce99477b60f524c0Jiri Pirko 13380f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirkostruct team_gsetter_ctx { 13480f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko union { 13580f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko u32 u32_val; 13680f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko const char *str_val; 13780f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko struct { 13880f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko const void *ptr; 13980f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko u32 len; 14080f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko } bin_val; 14114f066bab19946545130a7379f420af860a02ae8Jiri Pirko bool bool_val; 14269821638b27407d8648cb04de01b06b30a291bdeJiri Pirko s32 s32_val; 14380f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko } data; 14485d59a87248de90e3266e10dce99477b60f524c0Jiri Pirko struct team_option_inst_info *info; 14580f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko}; 14680f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko 1473d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostruct team_option { 1483d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct list_head list; 1493d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko const char *name; 15080f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko bool per_port; 151b13033262d2496e271444d5a09226a2be5ceb989Jiri Pirko unsigned int array_size; /* != 0 means the option is array */ 1523d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko enum team_option_type type; 15385d59a87248de90e3266e10dce99477b60f524c0Jiri Pirko int (*init)(struct team *team, struct team_option_inst_info *info); 15480f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko int (*getter)(struct team *team, struct team_gsetter_ctx *ctx); 15580f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko int (*setter)(struct team *team, struct team_gsetter_ctx *ctx); 1563d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko}; 1573d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 1580f1aad2b7f01d88782fbf4ab08b13a7d92b9b6b2Jiri Pirkoextern void team_option_inst_set_change(struct team_option_inst_info *opt_inst_info); 1590f1aad2b7f01d88782fbf4ab08b13a7d92b9b6b2Jiri Pirkoextern void team_options_change_check(struct team *team); 1600f1aad2b7f01d88782fbf4ab08b13a7d92b9b6b2Jiri Pirko 1613d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostruct team_mode { 1623d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko const char *kind; 1633d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct module *owner; 1643d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko size_t priv_size; 1655149ee58385bdfef260fb07a89a8ff0913be6b25Jiri Pirko size_t port_priv_size; 1663d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko const struct team_mode_ops *ops; 1673d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko}; 1683d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 1693d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko#define TEAM_PORT_HASHBITS 4 1703d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko#define TEAM_PORT_HASHENTRIES (1 << TEAM_PORT_HASHBITS) 1713d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 1723d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko#define TEAM_MODE_PRIV_LONGS 4 1733d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko#define TEAM_MODE_PRIV_SIZE (sizeof(long) * TEAM_MODE_PRIV_LONGS) 1743d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 1753d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostruct team { 1763d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct net_device *dev; /* associated netdevice */ 1773d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct team_pcpu_stats __percpu *pcpu_stats; 1783d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 17961dc3461b9549bc10a2f16d254250680cadafcceJiri Pirko struct mutex lock; /* used for overall locking, e.g. port lists write */ 1803d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 1813d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko /* 18219a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko * List of enabled ports and their count 1833d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko */ 18419a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko int en_port_count; 18519a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko struct hlist_head en_port_hlist[TEAM_PORT_HASHENTRIES]; 18619a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko 18719a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko struct list_head port_list; /* list of all ports */ 1883d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 1893d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct list_head option_list; 19080f7c6683fe0e891ef1db7c967d538b5fdddd22cJiri Pirko struct list_head option_inst_list; /* list of option instances */ 1913d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 1923d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko const struct team_mode *mode; 1933d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct team_mode_ops ops; 194e185483e6b84c127d0b1c890b6b703701ae52d35Flavio Leitner bool user_carrier_enabled; 1958ff5105a2b9dd0ba596719b165c1827d101e5f1aJiri Pirko bool queue_override_enabled; 1968ff5105a2b9dd0ba596719b165c1827d101e5f1aJiri Pirko struct list_head *qom_lists; /* array of queue override mapping lists */ 1979d0d68faea6962d62dd501cd6e71ce5cc8ed262bJiri Pirko bool port_mtu_change_allowed; 198fc423ff00df3a19554414eed80aef9de9b50313eJiri Pirko struct { 199fc423ff00df3a19554414eed80aef9de9b50313eJiri Pirko unsigned int count; 200fc423ff00df3a19554414eed80aef9de9b50313eJiri Pirko unsigned int interval; /* in ms */ 201fc423ff00df3a19554414eed80aef9de9b50313eJiri Pirko atomic_t count_pending; 202fc423ff00df3a19554414eed80aef9de9b50313eJiri Pirko struct delayed_work dw; 203fc423ff00df3a19554414eed80aef9de9b50313eJiri Pirko } notify_peers; 204492b200efdd20b8fcfdac873f3cd8d4902386581Jiri Pirko struct { 205492b200efdd20b8fcfdac873f3cd8d4902386581Jiri Pirko unsigned int count; 206492b200efdd20b8fcfdac873f3cd8d4902386581Jiri Pirko unsigned int interval; /* in ms */ 207492b200efdd20b8fcfdac873f3cd8d4902386581Jiri Pirko atomic_t count_pending; 208492b200efdd20b8fcfdac873f3cd8d4902386581Jiri Pirko struct delayed_work dw; 209492b200efdd20b8fcfdac873f3cd8d4902386581Jiri Pirko } mcast_rejoin; 2103d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko long mode_priv[TEAM_MODE_PRIV_LONGS]; 2113d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko}; 2123d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 213e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wangstatic inline int team_dev_queue_xmit(struct team *team, struct team_port *port, 214e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang struct sk_buff *skb) 215e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang{ 216e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang BUILD_BUG_ON(sizeof(skb->queue_mapping) != 217e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); 218e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping); 219e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang 220e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang skb->dev = port->dev; 221e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang if (unlikely(netpoll_tx_running(team->dev))) { 222e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang team_netpoll_send_skb(port, skb); 223e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang return 0; 224e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang } 225e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang return dev_queue_xmit(skb); 226e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang} 227e15c3c2294605f09f9b336b2f3b97086ab4b8145Amerigo Wang 2283d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostatic inline struct hlist_head *team_port_index_hash(struct team *team, 2293d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko int port_index) 2303d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko{ 23119a0b58e506b06fd41659d8734bba6a3e87980f4Jiri Pirko return &team->en_port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)]; 2323d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko} 2333d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 2343d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostatic inline struct team_port *team_get_port_by_index(struct team *team, 2353d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko int port_index) 2363d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko{ 2373d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct team_port *port; 2383d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct hlist_head *head = team_port_index_hash(team, port_index); 2393d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 240b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin hlist_for_each_entry(port, head, hlist) 2413d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko if (port->index == port_index) 2423d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko return port; 2433d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko return NULL; 2443d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko} 245735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko 246735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirkostatic inline int team_num_to_port_index(struct team *team, int num) 247735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko{ 248735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko int en_port_count = ACCESS_ONCE(team->en_port_count); 249735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko 250735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko if (unlikely(!en_port_count)) 251735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko return 0; 252735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko return num % en_port_count; 253735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko} 254735d381fa57c573935d35a24ea271ec99897ac63Jiri Pirko 2553d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkostatic inline struct team_port *team_get_port_by_index_rcu(struct team *team, 2563d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko int port_index) 2573d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko{ 2583d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct team_port *port; 2593d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko struct hlist_head *head = team_port_index_hash(team, port_index); 2603d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 261b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin hlist_for_each_entry_rcu(port, head, hlist) 2623d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko if (port->index == port_index) 2633d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko return port; 2643d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko return NULL; 2653d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko} 2663d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 267753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirkostatic inline struct team_port * 268753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirkoteam_get_first_port_txable_rcu(struct team *team, struct team_port *port) 269753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko{ 270753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko struct team_port *cur; 271753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko 272753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko if (likely(team_port_txable(port))) 273753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko return port; 274753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko cur = port; 275753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko list_for_each_entry_continue_rcu(cur, &team->port_list, list) 276b79462a8b9f9a452edc20c64a70a89ba3b0a6a88Jiri Pirko if (team_port_txable(cur)) 277753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko return cur; 278753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko list_for_each_entry_rcu(cur, &team->port_list, list) { 279753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko if (cur == port) 280753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko break; 281b79462a8b9f9a452edc20c64a70a89ba3b0a6a88Jiri Pirko if (team_port_txable(cur)) 282753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko return cur; 283753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko } 284753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko return NULL; 285753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko} 286753f993911b32e479b4fab5d228dc07c11d1e7e7Jiri Pirko 287358b838291f618278080bbed435b755f9b46748eJiri Pirkoextern int team_options_register(struct team *team, 288358b838291f618278080bbed435b755f9b46748eJiri Pirko const struct team_option *option, 289358b838291f618278080bbed435b755f9b46748eJiri Pirko size_t option_count); 2903d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirkoextern void team_options_unregister(struct team *team, 291358b838291f618278080bbed435b755f9b46748eJiri Pirko const struct team_option *option, 2923d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko size_t option_count); 2930402788a6cda4e204a805e83eaaff64fef9e4418Jiri Pirkoextern int team_mode_register(const struct team_mode *mode); 2940402788a6cda4e204a805e83eaaff64fef9e4418Jiri Pirkoextern void team_mode_unregister(const struct team_mode *mode); 2953d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko 2966c85f2bdda2086d804e198a3f31b685bc2f86b04Jiri Pirko#define TEAM_DEFAULT_NUM_TX_QUEUES 16 2976c85f2bdda2086d804e198a3f31b685bc2f86b04Jiri Pirko#define TEAM_DEFAULT_NUM_RX_QUEUES 16 2986c85f2bdda2086d804e198a3f31b685bc2f86b04Jiri Pirko 2993d249d4ca7d0ed6629a135ea1ea21c72286c0d80Jiri Pirko#endif /* _LINUX_IF_TEAM_H_ */ 300