11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify it 51da177e4SLinus Torvalds * under the terms of the GNU General Public License as published by the Free 61da177e4SLinus Torvalds * Software Foundation; either version 2 of the License, or (at your option) 71da177e4SLinus Torvalds * any later version. 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, but WITHOUT 101da177e4SLinus Torvalds * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111da177e4SLinus Torvalds * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 121da177e4SLinus Torvalds * more details. 131da177e4SLinus Torvalds * 141da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License along with 151da177e4SLinus Torvalds * this program; if not, write to the Free Software Foundation, Inc., 59 161da177e4SLinus Torvalds * Temple Place - Suite 330, Boston, MA 02111-1307, USA. 171da177e4SLinus Torvalds * 181da177e4SLinus Torvalds * The full GNU General Public License is included in this distribution in the 191da177e4SLinus Torvalds * file called LICENSE. 201da177e4SLinus Torvalds * 211da177e4SLinus Torvalds */ 221da177e4SLinus Torvalds 231ef8019bSDavid S. Miller #ifndef _NET_BOND_3AD_H 241ef8019bSDavid S. Miller #define _NET_BOND_3AD_H 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds #include <asm/byteorder.h> 271da177e4SLinus Torvalds #include <linux/skbuff.h> 281da177e4SLinus Torvalds #include <linux/netdevice.h> 29ed9b58bcSRichard Genoud #include <linux/if_ether.h> 301da177e4SLinus Torvalds 312ea24f2eSJoe Perches /* General definitions */ 32ed9b58bcSRichard Genoud #define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW) 331da177e4SLinus Torvalds #define AD_TIMER_INTERVAL 100 /*msec*/ 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds #define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02} 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds #define AD_LACP_SLOW 0 381da177e4SLinus Torvalds #define AD_LACP_FAST 1 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds typedef struct mac_addr { 411da177e4SLinus Torvalds u8 mac_addr_value[ETH_ALEN]; 42a10e1466SVitalii Demianets } __packed mac_addr_t; 431da177e4SLinus Torvalds 44fd989c83SJay Vosburgh enum { 45fd989c83SJay Vosburgh BOND_AD_STABLE = 0, 46fd989c83SJay Vosburgh BOND_AD_BANDWIDTH = 1, 47fd989c83SJay Vosburgh BOND_AD_COUNT = 2, 48fd989c83SJay Vosburgh }; 491da177e4SLinus Torvalds 502ea24f2eSJoe Perches /* rx machine states(43.4.11 in the 802.3ad standard) */ 511da177e4SLinus Torvalds typedef enum { 521da177e4SLinus Torvalds AD_RX_DUMMY, 532ea24f2eSJoe Perches AD_RX_INITIALIZE, /* rx Machine */ 542ea24f2eSJoe Perches AD_RX_PORT_DISABLED, /* rx Machine */ 552ea24f2eSJoe Perches AD_RX_LACP_DISABLED, /* rx Machine */ 562ea24f2eSJoe Perches AD_RX_EXPIRED, /* rx Machine */ 572ea24f2eSJoe Perches AD_RX_DEFAULTED, /* rx Machine */ 582ea24f2eSJoe Perches AD_RX_CURRENT /* rx Machine */ 591da177e4SLinus Torvalds } rx_states_t; 601da177e4SLinus Torvalds 612ea24f2eSJoe Perches /* periodic machine states(43.4.12 in the 802.3ad standard) */ 621da177e4SLinus Torvalds typedef enum { 631da177e4SLinus Torvalds AD_PERIODIC_DUMMY, 642ea24f2eSJoe Perches AD_NO_PERIODIC, /* periodic machine */ 652ea24f2eSJoe Perches AD_FAST_PERIODIC, /* periodic machine */ 662ea24f2eSJoe Perches AD_SLOW_PERIODIC, /* periodic machine */ 672ea24f2eSJoe Perches AD_PERIODIC_TX /* periodic machine */ 681da177e4SLinus Torvalds } periodic_states_t; 691da177e4SLinus Torvalds 702ea24f2eSJoe Perches /* mux machine states(43.4.13 in the 802.3ad standard) */ 711da177e4SLinus Torvalds typedef enum { 721da177e4SLinus Torvalds AD_MUX_DUMMY, 732ea24f2eSJoe Perches AD_MUX_DETACHED, /* mux machine */ 742ea24f2eSJoe Perches AD_MUX_WAITING, /* mux machine */ 752ea24f2eSJoe Perches AD_MUX_ATTACHED, /* mux machine */ 762ea24f2eSJoe Perches AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */ 771da177e4SLinus Torvalds } mux_states_t; 781da177e4SLinus Torvalds 792ea24f2eSJoe Perches /* tx machine states(43.4.15 in the 802.3ad standard) */ 801da177e4SLinus Torvalds typedef enum { 811da177e4SLinus Torvalds AD_TX_DUMMY, 822ea24f2eSJoe Perches AD_TRANSMIT /* tx Machine */ 831da177e4SLinus Torvalds } tx_states_t; 841da177e4SLinus Torvalds 8514c9551aSMahesh Bandewar /* churn machine states(43.4.17 in the 802.3ad standard) */ 8614c9551aSMahesh Bandewar typedef enum { 8714c9551aSMahesh Bandewar AD_CHURN_MONITOR, /* monitoring for churn */ 8814c9551aSMahesh Bandewar AD_CHURN, /* churn detected (error) */ 8914c9551aSMahesh Bandewar AD_NO_CHURN /* no churn (no error) */ 9014c9551aSMahesh Bandewar } churn_state_t; 9114c9551aSMahesh Bandewar 922ea24f2eSJoe Perches /* rx indication types */ 931da177e4SLinus Torvalds typedef enum { 942ea24f2eSJoe Perches AD_TYPE_LACPDU = 1, /* type lacpdu */ 952ea24f2eSJoe Perches AD_TYPE_MARKER /* type marker */ 961da177e4SLinus Torvalds } pdu_type_t; 971da177e4SLinus Torvalds 982ea24f2eSJoe Perches /* rx marker indication types */ 991da177e4SLinus Torvalds typedef enum { 1002ea24f2eSJoe Perches AD_MARKER_INFORMATION_SUBTYPE = 1, /* marker imformation subtype */ 1012ea24f2eSJoe Perches AD_MARKER_RESPONSE_SUBTYPE /* marker response subtype */ 1021c3f0b8eSMathieu Desnoyers } bond_marker_subtype_t; 1031da177e4SLinus Torvalds 1042ea24f2eSJoe Perches /* timers types(43.4.9 in the 802.3ad standard) */ 1051da177e4SLinus Torvalds typedef enum { 1061da177e4SLinus Torvalds AD_CURRENT_WHILE_TIMER, 1071da177e4SLinus Torvalds AD_ACTOR_CHURN_TIMER, 1081da177e4SLinus Torvalds AD_PERIODIC_TIMER, 1091da177e4SLinus Torvalds AD_PARTNER_CHURN_TIMER, 1101da177e4SLinus Torvalds AD_WAIT_WHILE_TIMER 1111da177e4SLinus Torvalds } ad_timers_t; 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds #pragma pack(1) 1141da177e4SLinus Torvalds 1152ea24f2eSJoe Perches /* Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) */ 1161da177e4SLinus Torvalds typedef struct lacpdu { 1172ea24f2eSJoe Perches u8 subtype; /* = LACP(= 0x01) */ 1181da177e4SLinus Torvalds u8 version_number; 1192ea24f2eSJoe Perches u8 tlv_type_actor_info; /* = actor information(type/length/value) */ 1202ea24f2eSJoe Perches u8 actor_information_length; /* = 20 */ 121d3bb52b0SAl Viro __be16 actor_system_priority; 1221da177e4SLinus Torvalds struct mac_addr actor_system; 123d3bb52b0SAl Viro __be16 actor_key; 124d3bb52b0SAl Viro __be16 actor_port_priority; 125d3bb52b0SAl Viro __be16 actor_port; 1261da177e4SLinus Torvalds u8 actor_state; 1272ea24f2eSJoe Perches u8 reserved_3_1[3]; /* = 0 */ 1282ea24f2eSJoe Perches u8 tlv_type_partner_info; /* = partner information */ 1292ea24f2eSJoe Perches u8 partner_information_length; /* = 20 */ 130d3bb52b0SAl Viro __be16 partner_system_priority; 1311da177e4SLinus Torvalds struct mac_addr partner_system; 132d3bb52b0SAl Viro __be16 partner_key; 133d3bb52b0SAl Viro __be16 partner_port_priority; 134d3bb52b0SAl Viro __be16 partner_port; 1351da177e4SLinus Torvalds u8 partner_state; 1362ea24f2eSJoe Perches u8 reserved_3_2[3]; /* = 0 */ 1372ea24f2eSJoe Perches u8 tlv_type_collector_info; /* = collector information */ 1382ea24f2eSJoe Perches u8 collector_information_length;/* = 16 */ 139d3bb52b0SAl Viro __be16 collector_max_delay; 1401da177e4SLinus Torvalds u8 reserved_12[12]; 1412ea24f2eSJoe Perches u8 tlv_type_terminator; /* = terminator */ 1422ea24f2eSJoe Perches u8 terminator_length; /* = 0 */ 1432ea24f2eSJoe Perches u8 reserved_50[50]; /* = 0 */ 144a10e1466SVitalii Demianets } __packed lacpdu_t; 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds typedef struct lacpdu_header { 147e727149eSHolger Eitzenberger struct ethhdr hdr; 1481da177e4SLinus Torvalds struct lacpdu lacpdu; 149a10e1466SVitalii Demianets } __packed lacpdu_header_t; 1501da177e4SLinus Torvalds 1512ea24f2eSJoe Perches /* Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) */ 1521c3f0b8eSMathieu Desnoyers typedef struct bond_marker { 1532ea24f2eSJoe Perches u8 subtype; /* = 0x02 (marker PDU) */ 1542ea24f2eSJoe Perches u8 version_number; /* = 0x01 */ 1552ea24f2eSJoe Perches u8 tlv_type; /* = 0x01 (marker information) */ 1562ea24f2eSJoe Perches /* = 0x02 (marker response information) */ 1572ea24f2eSJoe Perches u8 marker_length; /* = 0x16 */ 1582ea24f2eSJoe Perches u16 requester_port; /* The number assigned to the port by the requester */ 1592ea24f2eSJoe Perches struct mac_addr requester_system; /* The requester's system id */ 1602ea24f2eSJoe Perches u32 requester_transaction_id; /* The transaction id allocated by the requester, */ 1612ea24f2eSJoe Perches u16 pad; /* = 0 */ 1622ea24f2eSJoe Perches u8 tlv_type_terminator; /* = 0x00 */ 1632ea24f2eSJoe Perches u8 terminator_length; /* = 0x00 */ 1642ea24f2eSJoe Perches u8 reserved_90[90]; /* = 0 */ 165a10e1466SVitalii Demianets } __packed bond_marker_t; 1661da177e4SLinus Torvalds 1671c3f0b8eSMathieu Desnoyers typedef struct bond_marker_header { 168e727149eSHolger Eitzenberger struct ethhdr hdr; 1691c3f0b8eSMathieu Desnoyers struct bond_marker marker; 170a10e1466SVitalii Demianets } __packed bond_marker_header_t; 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds #pragma pack() 1731da177e4SLinus Torvalds 1741da177e4SLinus Torvalds struct slave; 1751da177e4SLinus Torvalds struct bonding; 1761da177e4SLinus Torvalds struct ad_info; 1771da177e4SLinus Torvalds struct port; 1781da177e4SLinus Torvalds 1791da177e4SLinus Torvalds #ifdef __ia64__ 1801da177e4SLinus Torvalds #pragma pack(8) 1811da177e4SLinus Torvalds #endif 1821da177e4SLinus Torvalds 1832ea24f2eSJoe Perches /* aggregator structure(43.4.5 in the 802.3ad standard) */ 1841da177e4SLinus Torvalds typedef struct aggregator { 1851da177e4SLinus Torvalds struct mac_addr aggregator_mac_address; 1861da177e4SLinus Torvalds u16 aggregator_identifier; 1871624db7bSHolger Eitzenberger bool is_individual; 1881da177e4SLinus Torvalds u16 actor_admin_aggregator_key; 1891da177e4SLinus Torvalds u16 actor_oper_aggregator_key; 1901da177e4SLinus Torvalds struct mac_addr partner_system; 1911da177e4SLinus Torvalds u16 partner_system_priority; 1921da177e4SLinus Torvalds u16 partner_oper_aggregator_key; 1932ea24f2eSJoe Perches u16 receive_state; /* BOOLEAN */ 1942ea24f2eSJoe Perches u16 transmit_state; /* BOOLEAN */ 1951da177e4SLinus Torvalds struct port *lag_ports; 1962ea24f2eSJoe Perches /* ****** PRIVATE PARAMETERS ****** */ 1972ea24f2eSJoe Perches struct slave *slave; /* pointer to the bond slave that this aggregator belongs to */ 1982ea24f2eSJoe Perches u16 is_active; /* BOOLEAN. Indicates if this aggregator is active */ 1991da177e4SLinus Torvalds u16 num_of_ports; 2001da177e4SLinus Torvalds } aggregator_t; 2011da177e4SLinus Torvalds 2021055c9abSHolger Eitzenberger struct port_params { 2031055c9abSHolger Eitzenberger struct mac_addr system; 2041055c9abSHolger Eitzenberger u16 system_priority; 2051055c9abSHolger Eitzenberger u16 key; 2061055c9abSHolger Eitzenberger u16 port_number; 2071055c9abSHolger Eitzenberger u16 port_priority; 2081055c9abSHolger Eitzenberger u16 port_state; 2091055c9abSHolger Eitzenberger }; 2101055c9abSHolger Eitzenberger 2112ea24f2eSJoe Perches /* port structure(43.4.6 in the 802.3ad standard) */ 2121da177e4SLinus Torvalds typedef struct port { 2131da177e4SLinus Torvalds u16 actor_port_number; 2141da177e4SLinus Torvalds u16 actor_port_priority; 2152ea24f2eSJoe Perches struct mac_addr actor_system; /* This parameter is added here although it is not specified in the standard, just for simplification */ 2162ea24f2eSJoe Perches u16 actor_system_priority; /* This parameter is added here although it is not specified in the standard, just for simplification */ 2171da177e4SLinus Torvalds u16 actor_port_aggregator_identifier; 218d238d458SHolger Eitzenberger bool ntt; 2191da177e4SLinus Torvalds u16 actor_admin_port_key; 2201da177e4SLinus Torvalds u16 actor_oper_port_key; 2211da177e4SLinus Torvalds u8 actor_admin_port_state; 2221da177e4SLinus Torvalds u8 actor_oper_port_state; 2231055c9abSHolger Eitzenberger 2241055c9abSHolger Eitzenberger struct port_params partner_admin; 2251055c9abSHolger Eitzenberger struct port_params partner_oper; 2261055c9abSHolger Eitzenberger 227f48127b6SHolger Eitzenberger bool is_enabled; 228f48127b6SHolger Eitzenberger 2292ea24f2eSJoe Perches /* ****** PRIVATE PARAMETERS ****** */ 2302ea24f2eSJoe Perches u16 sm_vars; /* all state machines variables for this port */ 2312ea24f2eSJoe Perches rx_states_t sm_rx_state; /* state machine rx state */ 2322ea24f2eSJoe Perches u16 sm_rx_timer_counter; /* state machine rx timer counter */ 2332ea24f2eSJoe Perches periodic_states_t sm_periodic_state; /* state machine periodic state */ 2342ea24f2eSJoe Perches u16 sm_periodic_timer_counter; /* state machine periodic timer counter */ 2352ea24f2eSJoe Perches mux_states_t sm_mux_state; /* state machine mux state */ 2362ea24f2eSJoe Perches u16 sm_mux_timer_counter; /* state machine mux timer counter */ 2372ea24f2eSJoe Perches tx_states_t sm_tx_state; /* state machine tx state */ 2382ea24f2eSJoe Perches u16 sm_tx_timer_counter; /* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */ 23914c9551aSMahesh Bandewar u16 sm_churn_actor_timer_counter; 24014c9551aSMahesh Bandewar u16 sm_churn_partner_timer_counter; 24114c9551aSMahesh Bandewar u32 churn_actor_count; 24214c9551aSMahesh Bandewar u32 churn_partner_count; 24314c9551aSMahesh Bandewar churn_state_t sm_churn_actor_state; 24414c9551aSMahesh Bandewar churn_state_t sm_churn_partner_state; 2452ea24f2eSJoe Perches struct slave *slave; /* pointer to the bond slave that this port belongs to */ 2462ea24f2eSJoe Perches struct aggregator *aggregator; /* pointer to an aggregator that this port related to */ 2472ea24f2eSJoe Perches struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */ 2482ea24f2eSJoe Perches u32 transaction_id; /* continuous number for identification of Marker PDU's; */ 2492ea24f2eSJoe Perches struct lacpdu lacpdu; /* the lacpdu that will be sent for this port */ 2501da177e4SLinus Torvalds } port_t; 2511da177e4SLinus Torvalds 2522ea24f2eSJoe Perches /* system structure */ 25387f422f8SHolger Eitzenberger struct ad_system { 2541da177e4SLinus Torvalds u16 sys_priority; 2551da177e4SLinus Torvalds struct mac_addr sys_mac_addr; 25687f422f8SHolger Eitzenberger }; 2571da177e4SLinus Torvalds 2581da177e4SLinus Torvalds #ifdef __ia64__ 2591da177e4SLinus Torvalds #pragma pack() 2601da177e4SLinus Torvalds #endif 2611da177e4SLinus Torvalds 2622ea24f2eSJoe Perches /* ========== AD Exported structures to the main bonding code ========== */ 2631da177e4SLinus Torvalds #define BOND_AD_INFO(bond) ((bond)->ad_info) 2641da177e4SLinus Torvalds #define SLAVE_AD_INFO(slave) ((slave)->ad_info) 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds struct ad_bond_info { 26787f422f8SHolger Eitzenberger struct ad_system system; /* 802.3ad system structure */ 2682ea24f2eSJoe Perches u32 agg_select_timer; /* Timer to select aggregator after all adapter's hand shakes */ 269163c8ff3SJiri Bohac u16 aggregator_identifier; 2701da177e4SLinus Torvalds }; 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds struct ad_slave_info { 2732ea24f2eSJoe Perches struct aggregator aggregator; /* 802.3ad aggregator structure */ 2742ea24f2eSJoe Perches struct port port; /* 802.3ad port structure */ 2751da177e4SLinus Torvalds u16 id; 2761da177e4SLinus Torvalds }; 2771da177e4SLinus Torvalds 27814c9551aSMahesh Bandewar static inline const char *bond_3ad_churn_desc(churn_state_t state) 27914c9551aSMahesh Bandewar { 28014c9551aSMahesh Bandewar static const char *const churn_description[] = { 28114c9551aSMahesh Bandewar "monitoring", 28214c9551aSMahesh Bandewar "churned", 28314c9551aSMahesh Bandewar "none", 28414c9551aSMahesh Bandewar "unknown" 28514c9551aSMahesh Bandewar }; 28614c9551aSMahesh Bandewar int max_size = sizeof(churn_description) / sizeof(churn_description[0]); 28714c9551aSMahesh Bandewar 28814c9551aSMahesh Bandewar if (state >= max_size) 28914c9551aSMahesh Bandewar state = max_size - 1; 29014c9551aSMahesh Bandewar 29114c9551aSMahesh Bandewar return churn_description[state]; 29214c9551aSMahesh Bandewar } 29314c9551aSMahesh Bandewar 2942ea24f2eSJoe Perches /* ========== AD Exported functions to the main bonding code ========== */ 29556d00c67SPeter Pan(潘卫平) void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution); 296359632e5Sdingtianhong void bond_3ad_bind_slave(struct slave *slave); 2971da177e4SLinus Torvalds void bond_3ad_unbind_slave(struct slave *slave); 2981b76b316SJay Vosburgh void bond_3ad_state_machine_handler(struct work_struct *); 299fd989c83SJay Vosburgh void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout); 30052bc6716SMahesh Bandewar void bond_3ad_adapter_speed_duplex_changed(struct slave *slave); 3011da177e4SLinus Torvalds void bond_3ad_handle_link_change(struct slave *slave, char link); 3021da177e4SLinus Torvalds int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); 303318debd8Snikolay@redhat.com int __bond_3ad_get_active_agg_info(struct bonding *bond, 304318debd8Snikolay@redhat.com struct ad_info *ad_info); 305de063b70SEric Dumazet int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, 3063aba891dSJiri Pirko struct slave *slave); 307ff59c456SJay Vosburgh int bond_3ad_set_carrier(struct bonding *bond); 308ba824a8bSPeter Pan(潘卫平) void bond_3ad_update_lacp_rate(struct bonding *bond); 3091ef8019bSDavid S. Miller #endif /* _NET_BOND_3AD_H */ 3101da177e4SLinus Torvalds 311