diff options
Diffstat (limited to 'drivers/net/bonding/bond_3ad.c')
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 359 |
1 files changed, 173 insertions, 186 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0ddf4c66afe2..c7537abca4f2 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -93,7 +93,7 @@ | |||
93 | // compare MAC addresses | 93 | // compare MAC addresses |
94 | #define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN) | 94 | #define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN) |
95 | 95 | ||
96 | static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}}; | 96 | static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } }; |
97 | static u16 ad_ticks_per_sec; | 97 | static u16 ad_ticks_per_sec; |
98 | static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000; | 98 | static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000; |
99 | 99 | ||
@@ -129,9 +129,8 @@ static void ad_marker_response_received(struct bond_marker *marker, struct port | |||
129 | */ | 129 | */ |
130 | static inline struct bonding *__get_bond_by_port(struct port *port) | 130 | static inline struct bonding *__get_bond_by_port(struct port *port) |
131 | { | 131 | { |
132 | if (port->slave == NULL) { | 132 | if (port->slave == NULL) |
133 | return NULL; | 133 | return NULL; |
134 | } | ||
135 | 134 | ||
136 | return bond_get_bond_by_slave(port->slave); | 135 | return bond_get_bond_by_slave(port->slave); |
137 | } | 136 | } |
@@ -144,9 +143,8 @@ static inline struct bonding *__get_bond_by_port(struct port *port) | |||
144 | */ | 143 | */ |
145 | static inline struct port *__get_first_port(struct bonding *bond) | 144 | static inline struct port *__get_first_port(struct bonding *bond) |
146 | { | 145 | { |
147 | if (bond->slave_cnt == 0) { | 146 | if (bond->slave_cnt == 0) |
148 | return NULL; | 147 | return NULL; |
149 | } | ||
150 | 148 | ||
151 | return &(SLAVE_AD_INFO(bond->first_slave).port); | 149 | return &(SLAVE_AD_INFO(bond->first_slave).port); |
152 | } | 150 | } |
@@ -164,9 +162,8 @@ static inline struct port *__get_next_port(struct port *port) | |||
164 | struct slave *slave = port->slave; | 162 | struct slave *slave = port->slave; |
165 | 163 | ||
166 | // If there's no bond for this port, or this is the last slave | 164 | // If there's no bond for this port, or this is the last slave |
167 | if ((bond == NULL) || (slave->next == bond->first_slave)) { | 165 | if ((bond == NULL) || (slave->next == bond->first_slave)) |
168 | return NULL; | 166 | return NULL; |
169 | } | ||
170 | 167 | ||
171 | return &(SLAVE_AD_INFO(slave->next).port); | 168 | return &(SLAVE_AD_INFO(slave->next).port); |
172 | } | 169 | } |
@@ -183,9 +180,8 @@ static inline struct aggregator *__get_first_agg(struct port *port) | |||
183 | struct bonding *bond = __get_bond_by_port(port); | 180 | struct bonding *bond = __get_bond_by_port(port); |
184 | 181 | ||
185 | // If there's no bond for this port, or bond has no slaves | 182 | // If there's no bond for this port, or bond has no slaves |
186 | if ((bond == NULL) || (bond->slave_cnt == 0)) { | 183 | if ((bond == NULL) || (bond->slave_cnt == 0)) |
187 | return NULL; | 184 | return NULL; |
188 | } | ||
189 | 185 | ||
190 | return &(SLAVE_AD_INFO(bond->first_slave).aggregator); | 186 | return &(SLAVE_AD_INFO(bond->first_slave).aggregator); |
191 | } | 187 | } |
@@ -203,9 +199,8 @@ static inline struct aggregator *__get_next_agg(struct aggregator *aggregator) | |||
203 | struct bonding *bond = bond_get_bond_by_slave(slave); | 199 | struct bonding *bond = bond_get_bond_by_slave(slave); |
204 | 200 | ||
205 | // If there's no bond for this aggregator, or this is the last slave | 201 | // If there's no bond for this aggregator, or this is the last slave |
206 | if ((bond == NULL) || (slave->next == bond->first_slave)) { | 202 | if ((bond == NULL) || (slave->next == bond->first_slave)) |
207 | return NULL; | 203 | return NULL; |
208 | } | ||
209 | 204 | ||
210 | return &(SLAVE_AD_INFO(slave->next).aggregator); | 205 | return &(SLAVE_AD_INFO(slave->next).aggregator); |
211 | } | 206 | } |
@@ -240,9 +235,8 @@ static inline void __enable_port(struct port *port) | |||
240 | { | 235 | { |
241 | struct slave *slave = port->slave; | 236 | struct slave *slave = port->slave; |
242 | 237 | ||
243 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) { | 238 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) |
244 | bond_set_slave_active_flags(slave); | 239 | bond_set_slave_active_flags(slave); |
245 | } | ||
246 | } | 240 | } |
247 | 241 | ||
248 | /** | 242 | /** |
@@ -252,7 +246,7 @@ static inline void __enable_port(struct port *port) | |||
252 | */ | 246 | */ |
253 | static inline int __port_is_enabled(struct port *port) | 247 | static inline int __port_is_enabled(struct port *port) |
254 | { | 248 | { |
255 | return(port->slave->state == BOND_STATE_ACTIVE); | 249 | return bond_is_active_slave(port->slave); |
256 | } | 250 | } |
257 | 251 | ||
258 | /** | 252 | /** |
@@ -265,9 +259,8 @@ static inline u32 __get_agg_selection_mode(struct port *port) | |||
265 | { | 259 | { |
266 | struct bonding *bond = __get_bond_by_port(port); | 260 | struct bonding *bond = __get_bond_by_port(port); |
267 | 261 | ||
268 | if (bond == NULL) { | 262 | if (bond == NULL) |
269 | return BOND_AD_STABLE; | 263 | return BOND_AD_STABLE; |
270 | } | ||
271 | 264 | ||
272 | return BOND_AD_INFO(bond).agg_select_mode; | 265 | return BOND_AD_INFO(bond).agg_select_mode; |
273 | } | 266 | } |
@@ -281,31 +274,30 @@ static inline int __check_agg_selection_timer(struct port *port) | |||
281 | { | 274 | { |
282 | struct bonding *bond = __get_bond_by_port(port); | 275 | struct bonding *bond = __get_bond_by_port(port); |
283 | 276 | ||
284 | if (bond == NULL) { | 277 | if (bond == NULL) |
285 | return 0; | 278 | return 0; |
286 | } | ||
287 | 279 | ||
288 | return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0; | 280 | return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0; |
289 | } | 281 | } |
290 | 282 | ||
291 | /** | 283 | /** |
292 | * __get_rx_machine_lock - lock the port's RX machine | 284 | * __get_state_machine_lock - lock the port's state machines |
293 | * @port: the port we're looking at | 285 | * @port: the port we're looking at |
294 | * | 286 | * |
295 | */ | 287 | */ |
296 | static inline void __get_rx_machine_lock(struct port *port) | 288 | static inline void __get_state_machine_lock(struct port *port) |
297 | { | 289 | { |
298 | spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 290 | spin_lock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); |
299 | } | 291 | } |
300 | 292 | ||
301 | /** | 293 | /** |
302 | * __release_rx_machine_lock - unlock the port's RX machine | 294 | * __release_state_machine_lock - unlock the port's state machines |
303 | * @port: the port we're looking at | 295 | * @port: the port we're looking at |
304 | * | 296 | * |
305 | */ | 297 | */ |
306 | static inline void __release_rx_machine_lock(struct port *port) | 298 | static inline void __release_state_machine_lock(struct port *port) |
307 | { | 299 | { |
308 | spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 300 | spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); |
309 | } | 301 | } |
310 | 302 | ||
311 | /** | 303 | /** |
@@ -328,9 +320,9 @@ static u16 __get_link_speed(struct port *port) | |||
328 | * link down, it sets the speed to 0. | 320 | * link down, it sets the speed to 0. |
329 | * This is done in spite of the fact that the e100 driver reports 0 to be | 321 | * This is done in spite of the fact that the e100 driver reports 0 to be |
330 | * compatible with MVT in the future.*/ | 322 | * compatible with MVT in the future.*/ |
331 | if (slave->link != BOND_LINK_UP) { | 323 | if (slave->link != BOND_LINK_UP) |
332 | speed=0; | 324 | speed = 0; |
333 | } else { | 325 | else { |
334 | switch (slave->speed) { | 326 | switch (slave->speed) { |
335 | case SPEED_10: | 327 | case SPEED_10: |
336 | speed = AD_LINK_SPEED_BITMASK_10MBPS; | 328 | speed = AD_LINK_SPEED_BITMASK_10MBPS; |
@@ -375,18 +367,18 @@ static u8 __get_duplex(struct port *port) | |||
375 | 367 | ||
376 | // handling a special case: when the configuration starts with | 368 | // handling a special case: when the configuration starts with |
377 | // link down, it sets the duplex to 0. | 369 | // link down, it sets the duplex to 0. |
378 | if (slave->link != BOND_LINK_UP) { | 370 | if (slave->link != BOND_LINK_UP) |
379 | retval=0x0; | 371 | retval = 0x0; |
380 | } else { | 372 | else { |
381 | switch (slave->duplex) { | 373 | switch (slave->duplex) { |
382 | case DUPLEX_FULL: | 374 | case DUPLEX_FULL: |
383 | retval=0x1; | 375 | retval = 0x1; |
384 | pr_debug("Port %d Received status full duplex update from adapter\n", | 376 | pr_debug("Port %d Received status full duplex update from adapter\n", |
385 | port->actor_port_number); | 377 | port->actor_port_number); |
386 | break; | 378 | break; |
387 | case DUPLEX_HALF: | 379 | case DUPLEX_HALF: |
388 | default: | 380 | default: |
389 | retval=0x0; | 381 | retval = 0x0; |
390 | pr_debug("Port %d Received status NOT full duplex update from adapter\n", | 382 | pr_debug("Port %d Received status NOT full duplex update from adapter\n", |
391 | port->actor_port_number); | 383 | port->actor_port_number); |
392 | break; | 384 | break; |
@@ -396,14 +388,14 @@ static u8 __get_duplex(struct port *port) | |||
396 | } | 388 | } |
397 | 389 | ||
398 | /** | 390 | /** |
399 | * __initialize_port_locks - initialize a port's RX machine spinlock | 391 | * __initialize_port_locks - initialize a port's STATE machine spinlock |
400 | * @port: the port we're looking at | 392 | * @port: the port we're looking at |
401 | * | 393 | * |
402 | */ | 394 | */ |
403 | static inline void __initialize_port_locks(struct port *port) | 395 | static inline void __initialize_port_locks(struct port *port) |
404 | { | 396 | { |
405 | // make sure it isn't called twice | 397 | // make sure it isn't called twice |
406 | spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 398 | spin_lock_init(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); |
407 | } | 399 | } |
408 | 400 | ||
409 | //conversions | 401 | //conversions |
@@ -419,15 +411,14 @@ static inline void __initialize_port_locks(struct port *port) | |||
419 | */ | 411 | */ |
420 | static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) | 412 | static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) |
421 | { | 413 | { |
422 | u16 retval=0; //to silence the compiler | 414 | u16 retval = 0; /* to silence the compiler */ |
423 | 415 | ||
424 | switch (timer_type) { | 416 | switch (timer_type) { |
425 | case AD_CURRENT_WHILE_TIMER: // for rx machine usage | 417 | case AD_CURRENT_WHILE_TIMER: // for rx machine usage |
426 | if (par) { // for short or long timeout | 418 | if (par) |
427 | retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout | 419 | retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout |
428 | } else { | 420 | else |
429 | retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout | 421 | retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout |
430 | } | ||
431 | break; | 422 | break; |
432 | case AD_ACTOR_CHURN_TIMER: // for local churn machine | 423 | case AD_ACTOR_CHURN_TIMER: // for local churn machine |
433 | retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); | 424 | retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); |
@@ -519,11 +510,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) | |||
519 | port->actor_oper_port_state &= ~AD_STATE_DEFAULTED; | 510 | port->actor_oper_port_state &= ~AD_STATE_DEFAULTED; |
520 | 511 | ||
521 | // set the partner sync. to on if the partner is sync. and the port is matched | 512 | // set the partner sync. to on if the partner is sync. and the port is matched |
522 | if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) { | 513 | if ((port->sm_vars & AD_PORT_MATCHED) |
514 | && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) | ||
523 | partner->port_state |= AD_STATE_SYNCHRONIZATION; | 515 | partner->port_state |= AD_STATE_SYNCHRONIZATION; |
524 | } else { | 516 | else |
525 | partner->port_state &= ~AD_STATE_SYNCHRONIZATION; | 517 | partner->port_state &= ~AD_STATE_SYNCHRONIZATION; |
526 | } | ||
527 | } | 518 | } |
528 | } | 519 | } |
529 | 520 | ||
@@ -653,7 +644,7 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port) | |||
653 | */ | 644 | */ |
654 | static void __attach_bond_to_agg(struct port *port) | 645 | static void __attach_bond_to_agg(struct port *port) |
655 | { | 646 | { |
656 | port=NULL; // just to satisfy the compiler | 647 | port = NULL; /* just to satisfy the compiler */ |
657 | // This function does nothing since the parser/multiplexer of the receive | 648 | // This function does nothing since the parser/multiplexer of the receive |
658 | // and the parser/multiplexer of the aggregator are already combined | 649 | // and the parser/multiplexer of the aggregator are already combined |
659 | } | 650 | } |
@@ -668,7 +659,7 @@ static void __attach_bond_to_agg(struct port *port) | |||
668 | */ | 659 | */ |
669 | static void __detach_bond_from_agg(struct port *port) | 660 | static void __detach_bond_from_agg(struct port *port) |
670 | { | 661 | { |
671 | port=NULL; // just to satisfy the compiler | 662 | port = NULL; /* just to satisfy the compiler */ |
672 | // This function does nothing sience the parser/multiplexer of the receive | 663 | // This function does nothing sience the parser/multiplexer of the receive |
673 | // and the parser/multiplexer of the aggregator are already combined | 664 | // and the parser/multiplexer of the aggregator are already combined |
674 | } | 665 | } |
@@ -685,7 +676,9 @@ static int __agg_ports_are_ready(struct aggregator *aggregator) | |||
685 | 676 | ||
686 | if (aggregator) { | 677 | if (aggregator) { |
687 | // scan all ports in this aggregator to verfy if they are all ready | 678 | // scan all ports in this aggregator to verfy if they are all ready |
688 | for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { | 679 | for (port = aggregator->lag_ports; |
680 | port; | ||
681 | port = port->next_port_in_aggregator) { | ||
689 | if (!(port->sm_vars & AD_PORT_READY_N)) { | 682 | if (!(port->sm_vars & AD_PORT_READY_N)) { |
690 | retval = 0; | 683 | retval = 0; |
691 | break; | 684 | break; |
@@ -706,12 +699,12 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) | |||
706 | { | 699 | { |
707 | struct port *port; | 700 | struct port *port; |
708 | 701 | ||
709 | for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { | 702 | for (port = aggregator->lag_ports; port; |
710 | if (val) { | 703 | port = port->next_port_in_aggregator) { |
704 | if (val) | ||
711 | port->sm_vars |= AD_PORT_READY; | 705 | port->sm_vars |= AD_PORT_READY; |
712 | } else { | 706 | else |
713 | port->sm_vars &= ~AD_PORT_READY; | 707 | port->sm_vars &= ~AD_PORT_READY; |
714 | } | ||
715 | } | 708 | } |
716 | } | 709 | } |
717 | 710 | ||
@@ -722,12 +715,10 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) | |||
722 | */ | 715 | */ |
723 | static u32 __get_agg_bandwidth(struct aggregator *aggregator) | 716 | static u32 __get_agg_bandwidth(struct aggregator *aggregator) |
724 | { | 717 | { |
725 | u32 bandwidth=0; | 718 | u32 bandwidth = 0; |
726 | u32 basic_speed; | ||
727 | 719 | ||
728 | if (aggregator->num_of_ports) { | 720 | if (aggregator->num_of_ports) { |
729 | basic_speed = __get_link_speed(aggregator->lag_ports); | 721 | switch (__get_link_speed(aggregator->lag_ports)) { |
730 | switch (basic_speed) { | ||
731 | case AD_LINK_SPEED_BITMASK_1MBPS: | 722 | case AD_LINK_SPEED_BITMASK_1MBPS: |
732 | bandwidth = aggregator->num_of_ports; | 723 | bandwidth = aggregator->num_of_ports; |
733 | break; | 724 | break; |
@@ -744,7 +735,7 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) | |||
744 | bandwidth = aggregator->num_of_ports * 10000; | 735 | bandwidth = aggregator->num_of_ports * 10000; |
745 | break; | 736 | break; |
746 | default: | 737 | default: |
747 | bandwidth=0; // to silent the compilor .... | 738 | bandwidth = 0; /*to silence the compiler ....*/ |
748 | } | 739 | } |
749 | } | 740 | } |
750 | return bandwidth; | 741 | return bandwidth; |
@@ -835,9 +826,8 @@ static int ad_lacpdu_send(struct port *port) | |||
835 | int length = sizeof(struct lacpdu_header); | 826 | int length = sizeof(struct lacpdu_header); |
836 | 827 | ||
837 | skb = dev_alloc_skb(length); | 828 | skb = dev_alloc_skb(length); |
838 | if (!skb) { | 829 | if (!skb) |
839 | return -ENOMEM; | 830 | return -ENOMEM; |
840 | } | ||
841 | 831 | ||
842 | skb->dev = slave->dev; | 832 | skb->dev = slave->dev; |
843 | skb_reset_mac_header(skb); | 833 | skb_reset_mac_header(skb); |
@@ -848,7 +838,7 @@ static int ad_lacpdu_send(struct port *port) | |||
848 | lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); | 838 | lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); |
849 | 839 | ||
850 | memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); | 840 | memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); |
851 | /* Note: source addres is set to be the member's PERMANENT address, | 841 | /* Note: source address is set to be the member's PERMANENT address, |
852 | because we use it to identify loopback lacpdus in receive. */ | 842 | because we use it to identify loopback lacpdus in receive. */ |
853 | memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); | 843 | memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); |
854 | lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; | 844 | lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; |
@@ -876,9 +866,8 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) | |||
876 | int length = sizeof(struct bond_marker_header); | 866 | int length = sizeof(struct bond_marker_header); |
877 | 867 | ||
878 | skb = dev_alloc_skb(length + 16); | 868 | skb = dev_alloc_skb(length + 16); |
879 | if (!skb) { | 869 | if (!skb) |
880 | return -ENOMEM; | 870 | return -ENOMEM; |
881 | } | ||
882 | 871 | ||
883 | skb_reserve(skb, 16); | 872 | skb_reserve(skb, 16); |
884 | 873 | ||
@@ -890,7 +879,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) | |||
890 | marker_header = (struct bond_marker_header *)skb_put(skb, length); | 879 | marker_header = (struct bond_marker_header *)skb_put(skb, length); |
891 | 880 | ||
892 | memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); | 881 | memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); |
893 | /* Note: source addres is set to be the member's PERMANENT address, | 882 | /* Note: source address is set to be the member's PERMANENT address, |
894 | because we use it to identify loopback MARKERs in receive. */ | 883 | because we use it to identify loopback MARKERs in receive. */ |
895 | memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); | 884 | memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); |
896 | marker_header->hdr.h_proto = PKT_TYPE_LACPDU; | 885 | marker_header->hdr.h_proto = PKT_TYPE_LACPDU; |
@@ -919,9 +908,10 @@ static void ad_mux_machine(struct port *port) | |||
919 | } else { | 908 | } else { |
920 | switch (port->sm_mux_state) { | 909 | switch (port->sm_mux_state) { |
921 | case AD_MUX_DETACHED: | 910 | case AD_MUX_DETACHED: |
922 | if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY | 911 | if ((port->sm_vars & AD_PORT_SELECTED) |
912 | || (port->sm_vars & AD_PORT_STANDBY)) | ||
913 | /* if SELECTED or STANDBY */ | ||
923 | port->sm_mux_state = AD_MUX_WAITING; // next state | 914 | port->sm_mux_state = AD_MUX_WAITING; // next state |
924 | } | ||
925 | break; | 915 | break; |
926 | case AD_MUX_WAITING: | 916 | case AD_MUX_WAITING: |
927 | // if SELECTED == FALSE return to DETACH state | 917 | // if SELECTED == FALSE return to DETACH state |
@@ -935,18 +925,18 @@ static void ad_mux_machine(struct port *port) | |||
935 | } | 925 | } |
936 | 926 | ||
937 | // check if the wait_while_timer expired | 927 | // check if the wait_while_timer expired |
938 | if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) { | 928 | if (port->sm_mux_timer_counter |
929 | && !(--port->sm_mux_timer_counter)) | ||
939 | port->sm_vars |= AD_PORT_READY_N; | 930 | port->sm_vars |= AD_PORT_READY_N; |
940 | } | ||
941 | 931 | ||
942 | // in order to withhold the selection logic to check all ports READY_N value | 932 | // in order to withhold the selection logic to check all ports READY_N value |
943 | // every callback cycle to update ready variable, we check READY_N and update READY here | 933 | // every callback cycle to update ready variable, we check READY_N and update READY here |
944 | __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); | 934 | __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); |
945 | 935 | ||
946 | // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state | 936 | // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state |
947 | if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) { | 937 | if ((port->sm_vars & AD_PORT_READY) |
938 | && !port->sm_mux_timer_counter) | ||
948 | port->sm_mux_state = AD_MUX_ATTACHED; // next state | 939 | port->sm_mux_state = AD_MUX_ATTACHED; // next state |
949 | } | ||
950 | break; | 940 | break; |
951 | case AD_MUX_ATTACHED: | 941 | case AD_MUX_ATTACHED: |
952 | // check also if agg_select_timer expired(so the edable port will take place only after this timer) | 942 | // check also if agg_select_timer expired(so the edable port will take place only after this timer) |
@@ -1033,21 +1023,19 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1033 | { | 1023 | { |
1034 | rx_states_t last_state; | 1024 | rx_states_t last_state; |
1035 | 1025 | ||
1036 | // Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback) | ||
1037 | __get_rx_machine_lock(port); | ||
1038 | |||
1039 | // keep current State Machine state to compare later if it was changed | 1026 | // keep current State Machine state to compare later if it was changed |
1040 | last_state = port->sm_rx_state; | 1027 | last_state = port->sm_rx_state; |
1041 | 1028 | ||
1042 | // check if state machine should change state | 1029 | // check if state machine should change state |
1043 | // first, check if port was reinitialized | 1030 | // first, check if port was reinitialized |
1044 | if (port->sm_vars & AD_PORT_BEGIN) { | 1031 | if (port->sm_vars & AD_PORT_BEGIN) |
1045 | port->sm_rx_state = AD_RX_INITIALIZE; // next state | 1032 | /* next state */ |
1046 | } | 1033 | port->sm_rx_state = AD_RX_INITIALIZE; |
1047 | // check if port is not enabled | 1034 | // check if port is not enabled |
1048 | else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) { | 1035 | else if (!(port->sm_vars & AD_PORT_BEGIN) |
1049 | port->sm_rx_state = AD_RX_PORT_DISABLED; // next state | 1036 | && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) |
1050 | } | 1037 | /* next state */ |
1038 | port->sm_rx_state = AD_RX_PORT_DISABLED; | ||
1051 | // check if new lacpdu arrived | 1039 | // check if new lacpdu arrived |
1052 | else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) { | 1040 | else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) { |
1053 | port->sm_rx_timer_counter = 0; // zero timer | 1041 | port->sm_rx_timer_counter = 0; // zero timer |
@@ -1069,13 +1057,16 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1069 | // if no lacpdu arrived and no timer is on | 1057 | // if no lacpdu arrived and no timer is on |
1070 | switch (port->sm_rx_state) { | 1058 | switch (port->sm_rx_state) { |
1071 | case AD_RX_PORT_DISABLED: | 1059 | case AD_RX_PORT_DISABLED: |
1072 | if (port->sm_vars & AD_PORT_MOVED) { | 1060 | if (port->sm_vars & AD_PORT_MOVED) |
1073 | port->sm_rx_state = AD_RX_INITIALIZE; // next state | 1061 | port->sm_rx_state = AD_RX_INITIALIZE; // next state |
1074 | } else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) { | 1062 | else if (port->is_enabled |
1063 | && (port->sm_vars | ||
1064 | & AD_PORT_LACP_ENABLED)) | ||
1075 | port->sm_rx_state = AD_RX_EXPIRED; // next state | 1065 | port->sm_rx_state = AD_RX_EXPIRED; // next state |
1076 | } else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) { | 1066 | else if (port->is_enabled |
1067 | && ((port->sm_vars | ||
1068 | & AD_PORT_LACP_ENABLED) == 0)) | ||
1077 | port->sm_rx_state = AD_RX_LACP_DISABLED; // next state | 1069 | port->sm_rx_state = AD_RX_LACP_DISABLED; // next state |
1078 | } | ||
1079 | break; | 1070 | break; |
1080 | default: //to silence the compiler | 1071 | default: //to silence the compiler |
1081 | break; | 1072 | break; |
@@ -1091,11 +1082,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1091 | port->sm_rx_state); | 1082 | port->sm_rx_state); |
1092 | switch (port->sm_rx_state) { | 1083 | switch (port->sm_rx_state) { |
1093 | case AD_RX_INITIALIZE: | 1084 | case AD_RX_INITIALIZE: |
1094 | if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { | 1085 | if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) |
1095 | port->sm_vars &= ~AD_PORT_LACP_ENABLED; | 1086 | port->sm_vars &= ~AD_PORT_LACP_ENABLED; |
1096 | } else { | 1087 | else |
1097 | port->sm_vars |= AD_PORT_LACP_ENABLED; | 1088 | port->sm_vars |= AD_PORT_LACP_ENABLED; |
1098 | } | ||
1099 | port->sm_vars &= ~AD_PORT_SELECTED; | 1089 | port->sm_vars &= ~AD_PORT_SELECTED; |
1100 | __record_default(port); | 1090 | __record_default(port); |
1101 | port->actor_oper_port_state &= ~AD_STATE_EXPIRED; | 1091 | port->actor_oper_port_state &= ~AD_STATE_EXPIRED; |
@@ -1138,7 +1128,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1138 | pr_err("%s: An illegal loopback occurred on adapter (%s).\n" | 1128 | pr_err("%s: An illegal loopback occurred on adapter (%s).\n" |
1139 | "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", | 1129 | "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", |
1140 | port->slave->dev->master->name, port->slave->dev->name); | 1130 | port->slave->dev->master->name, port->slave->dev->name); |
1141 | __release_rx_machine_lock(port); | ||
1142 | return; | 1131 | return; |
1143 | } | 1132 | } |
1144 | __update_selected(lacpdu, port); | 1133 | __update_selected(lacpdu, port); |
@@ -1149,15 +1138,15 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1149 | // verify that if the aggregator is enabled, the port is enabled too. | 1138 | // verify that if the aggregator is enabled, the port is enabled too. |
1150 | //(because if the link goes down for a short time, the 802.3ad will not | 1139 | //(because if the link goes down for a short time, the 802.3ad will not |
1151 | // catch it, and the port will continue to be disabled) | 1140 | // catch it, and the port will continue to be disabled) |
1152 | if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) { | 1141 | if (port->aggregator |
1142 | && port->aggregator->is_active | ||
1143 | && !__port_is_enabled(port)) | ||
1153 | __enable_port(port); | 1144 | __enable_port(port); |
1154 | } | ||
1155 | break; | 1145 | break; |
1156 | default: //to silence the compiler | 1146 | default: //to silence the compiler |
1157 | break; | 1147 | break; |
1158 | } | 1148 | } |
1159 | } | 1149 | } |
1160 | __release_rx_machine_lock(port); | ||
1161 | } | 1150 | } |
1162 | 1151 | ||
1163 | /** | 1152 | /** |
@@ -1183,7 +1172,8 @@ static void ad_tx_machine(struct port *port) | |||
1183 | } | 1172 | } |
1184 | } | 1173 | } |
1185 | // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND | 1174 | // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND |
1186 | port->sm_tx_timer_counter=ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; | 1175 | port->sm_tx_timer_counter = |
1176 | ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; | ||
1187 | } | 1177 | } |
1188 | } | 1178 | } |
1189 | 1179 | ||
@@ -1216,9 +1206,9 @@ static void ad_periodic_machine(struct port *port) | |||
1216 | // If not expired, check if there is some new timeout parameter from the partner state | 1206 | // If not expired, check if there is some new timeout parameter from the partner state |
1217 | switch (port->sm_periodic_state) { | 1207 | switch (port->sm_periodic_state) { |
1218 | case AD_FAST_PERIODIC: | 1208 | case AD_FAST_PERIODIC: |
1219 | if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { | 1209 | if (!(port->partner_oper.port_state |
1210 | & AD_STATE_LACP_TIMEOUT)) | ||
1220 | port->sm_periodic_state = AD_SLOW_PERIODIC; // next state | 1211 | port->sm_periodic_state = AD_SLOW_PERIODIC; // next state |
1221 | } | ||
1222 | break; | 1212 | break; |
1223 | case AD_SLOW_PERIODIC: | 1213 | case AD_SLOW_PERIODIC: |
1224 | if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { | 1214 | if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { |
@@ -1237,11 +1227,11 @@ static void ad_periodic_machine(struct port *port) | |||
1237 | port->sm_periodic_state = AD_FAST_PERIODIC; // next state | 1227 | port->sm_periodic_state = AD_FAST_PERIODIC; // next state |
1238 | break; | 1228 | break; |
1239 | case AD_PERIODIC_TX: | 1229 | case AD_PERIODIC_TX: |
1240 | if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { | 1230 | if (!(port->partner_oper.port_state |
1231 | & AD_STATE_LACP_TIMEOUT)) | ||
1241 | port->sm_periodic_state = AD_SLOW_PERIODIC; // next state | 1232 | port->sm_periodic_state = AD_SLOW_PERIODIC; // next state |
1242 | } else { | 1233 | else |
1243 | port->sm_periodic_state = AD_FAST_PERIODIC; // next state | 1234 | port->sm_periodic_state = AD_FAST_PERIODIC; // next state |
1244 | } | ||
1245 | break; | 1235 | break; |
1246 | default: //to silence the compiler | 1236 | default: //to silence the compiler |
1247 | break; | 1237 | break; |
@@ -1287,35 +1277,37 @@ static void ad_port_selection_logic(struct port *port) | |||
1287 | int found = 0; | 1277 | int found = 0; |
1288 | 1278 | ||
1289 | // if the port is already Selected, do nothing | 1279 | // if the port is already Selected, do nothing |
1290 | if (port->sm_vars & AD_PORT_SELECTED) { | 1280 | if (port->sm_vars & AD_PORT_SELECTED) |
1291 | return; | 1281 | return; |
1292 | } | ||
1293 | 1282 | ||
1294 | // if the port is connected to other aggregator, detach it | 1283 | // if the port is connected to other aggregator, detach it |
1295 | if (port->aggregator) { | 1284 | if (port->aggregator) { |
1296 | // detach the port from its former aggregator | 1285 | // detach the port from its former aggregator |
1297 | temp_aggregator=port->aggregator; | 1286 | temp_aggregator = port->aggregator; |
1298 | for (curr_port=temp_aggregator->lag_ports; curr_port; last_port=curr_port, curr_port=curr_port->next_port_in_aggregator) { | 1287 | for (curr_port = temp_aggregator->lag_ports; curr_port; |
1288 | last_port = curr_port, | ||
1289 | curr_port = curr_port->next_port_in_aggregator) { | ||
1299 | if (curr_port == port) { | 1290 | if (curr_port == port) { |
1300 | temp_aggregator->num_of_ports--; | 1291 | temp_aggregator->num_of_ports--; |
1301 | if (!last_port) {// if it is the first port attached to the aggregator | 1292 | if (!last_port) {// if it is the first port attached to the aggregator |
1302 | temp_aggregator->lag_ports=port->next_port_in_aggregator; | 1293 | temp_aggregator->lag_ports = |
1294 | port->next_port_in_aggregator; | ||
1303 | } else {// not the first port attached to the aggregator | 1295 | } else {// not the first port attached to the aggregator |
1304 | last_port->next_port_in_aggregator=port->next_port_in_aggregator; | 1296 | last_port->next_port_in_aggregator = |
1297 | port->next_port_in_aggregator; | ||
1305 | } | 1298 | } |
1306 | 1299 | ||
1307 | // clear the port's relations to this aggregator | 1300 | // clear the port's relations to this aggregator |
1308 | port->aggregator = NULL; | 1301 | port->aggregator = NULL; |
1309 | port->next_port_in_aggregator=NULL; | 1302 | port->next_port_in_aggregator = NULL; |
1310 | port->actor_port_aggregator_identifier=0; | 1303 | port->actor_port_aggregator_identifier = 0; |
1311 | 1304 | ||
1312 | pr_debug("Port %d left LAG %d\n", | 1305 | pr_debug("Port %d left LAG %d\n", |
1313 | port->actor_port_number, | 1306 | port->actor_port_number, |
1314 | temp_aggregator->aggregator_identifier); | 1307 | temp_aggregator->aggregator_identifier); |
1315 | // if the aggregator is empty, clear its parameters, and set it ready to be attached | 1308 | // if the aggregator is empty, clear its parameters, and set it ready to be attached |
1316 | if (!temp_aggregator->lag_ports) { | 1309 | if (!temp_aggregator->lag_ports) |
1317 | ad_clear_agg(temp_aggregator); | 1310 | ad_clear_agg(temp_aggregator); |
1318 | } | ||
1319 | break; | 1311 | break; |
1320 | } | 1312 | } |
1321 | } | 1313 | } |
@@ -1333,9 +1325,8 @@ static void ad_port_selection_logic(struct port *port) | |||
1333 | 1325 | ||
1334 | // keep a free aggregator for later use(if needed) | 1326 | // keep a free aggregator for later use(if needed) |
1335 | if (!aggregator->lag_ports) { | 1327 | if (!aggregator->lag_ports) { |
1336 | if (!free_aggregator) { | 1328 | if (!free_aggregator) |
1337 | free_aggregator=aggregator; | 1329 | free_aggregator = aggregator; |
1338 | } | ||
1339 | continue; | 1330 | continue; |
1340 | } | 1331 | } |
1341 | // check if current aggregator suits us | 1332 | // check if current aggregator suits us |
@@ -1350,10 +1341,11 @@ static void ad_port_selection_logic(struct port *port) | |||
1350 | ) { | 1341 | ) { |
1351 | // attach to the founded aggregator | 1342 | // attach to the founded aggregator |
1352 | port->aggregator = aggregator; | 1343 | port->aggregator = aggregator; |
1353 | port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; | 1344 | port->actor_port_aggregator_identifier = |
1354 | port->next_port_in_aggregator=aggregator->lag_ports; | 1345 | port->aggregator->aggregator_identifier; |
1346 | port->next_port_in_aggregator = aggregator->lag_ports; | ||
1355 | port->aggregator->num_of_ports++; | 1347 | port->aggregator->num_of_ports++; |
1356 | aggregator->lag_ports=port; | 1348 | aggregator->lag_ports = port; |
1357 | pr_debug("Port %d joined LAG %d(existing LAG)\n", | 1349 | pr_debug("Port %d joined LAG %d(existing LAG)\n", |
1358 | port->actor_port_number, | 1350 | port->actor_port_number, |
1359 | port->aggregator->aggregator_identifier); | 1351 | port->aggregator->aggregator_identifier); |
@@ -1370,20 +1362,23 @@ static void ad_port_selection_logic(struct port *port) | |||
1370 | if (free_aggregator) { | 1362 | if (free_aggregator) { |
1371 | // assign port a new aggregator | 1363 | // assign port a new aggregator |
1372 | port->aggregator = free_aggregator; | 1364 | port->aggregator = free_aggregator; |
1373 | port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; | 1365 | port->actor_port_aggregator_identifier = |
1366 | port->aggregator->aggregator_identifier; | ||
1374 | 1367 | ||
1375 | // update the new aggregator's parameters | 1368 | // update the new aggregator's parameters |
1376 | // if port was responsed from the end-user | 1369 | // if port was responsed from the end-user |
1377 | if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) {// if port is full duplex | 1370 | if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) |
1371 | /* if port is full duplex */ | ||
1378 | port->aggregator->is_individual = false; | 1372 | port->aggregator->is_individual = false; |
1379 | } else { | 1373 | else |
1380 | port->aggregator->is_individual = true; | 1374 | port->aggregator->is_individual = true; |
1381 | } | ||
1382 | 1375 | ||
1383 | port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key; | 1376 | port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key; |
1384 | port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key; | 1377 | port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key; |
1385 | port->aggregator->partner_system=port->partner_oper.system; | 1378 | port->aggregator->partner_system = |
1386 | port->aggregator->partner_system_priority = port->partner_oper.system_priority; | 1379 | port->partner_oper.system; |
1380 | port->aggregator->partner_system_priority = | ||
1381 | port->partner_oper.system_priority; | ||
1387 | port->aggregator->partner_oper_aggregator_key = port->partner_oper.key; | 1382 | port->aggregator->partner_oper_aggregator_key = port->partner_oper.key; |
1388 | port->aggregator->receive_state = 1; | 1383 | port->aggregator->receive_state = 1; |
1389 | port->aggregator->transmit_state = 1; | 1384 | port->aggregator->transmit_state = 1; |
@@ -1485,8 +1480,11 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, | |||
1485 | 1480 | ||
1486 | static int agg_device_up(const struct aggregator *agg) | 1481 | static int agg_device_up(const struct aggregator *agg) |
1487 | { | 1482 | { |
1488 | return (netif_running(agg->slave->dev) && | 1483 | struct port *port = agg->lag_ports; |
1489 | netif_carrier_ok(agg->slave->dev)); | 1484 | if (!port) |
1485 | return 0; | ||
1486 | return (netif_running(port->slave->dev) && | ||
1487 | netif_carrier_ok(port->slave->dev)); | ||
1490 | } | 1488 | } |
1491 | 1489 | ||
1492 | /** | 1490 | /** |
@@ -1704,9 +1702,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast) | |||
1704 | port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; | 1702 | port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; |
1705 | port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; | 1703 | port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; |
1706 | 1704 | ||
1707 | if (lacp_fast) { | 1705 | if (lacp_fast) |
1708 | port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; | 1706 | port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; |
1709 | } | ||
1710 | 1707 | ||
1711 | memcpy(&port->partner_admin, &tmpl, sizeof(tmpl)); | 1708 | memcpy(&port->partner_admin, &tmpl, sizeof(tmpl)); |
1712 | memcpy(&port->partner_oper, &tmpl, sizeof(tmpl)); | 1709 | memcpy(&port->partner_oper, &tmpl, sizeof(tmpl)); |
@@ -1785,13 +1782,16 @@ static void ad_marker_info_send(struct port *port) | |||
1785 | marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8)); | 1782 | marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8)); |
1786 | marker.requester_system = port->actor_system; | 1783 | marker.requester_system = port->actor_system; |
1787 | // convert requester_port(u32) to Big Endian | 1784 | // convert requester_port(u32) to Big Endian |
1788 | marker.requester_transaction_id = (((++port->transaction_id & 0xFF) << 24) |((port->transaction_id & 0xFF00) << 8) |((port->transaction_id & 0xFF0000) >> 8) |((port->transaction_id & 0xFF000000) >> 24)); | 1785 | marker.requester_transaction_id = |
1786 | (((++port->transaction_id & 0xFF) << 24) | ||
1787 | | ((port->transaction_id & 0xFF00) << 8) | ||
1788 | | ((port->transaction_id & 0xFF0000) >> 8) | ||
1789 | | ((port->transaction_id & 0xFF000000) >> 24)); | ||
1789 | marker.pad = 0; | 1790 | marker.pad = 0; |
1790 | marker.tlv_type_terminator = 0x00; | 1791 | marker.tlv_type_terminator = 0x00; |
1791 | marker.terminator_length = 0x00; | 1792 | marker.terminator_length = 0x00; |
1792 | for (index=0; index<90; index++) { | 1793 | for (index = 0; index < 90; index++) |
1793 | marker.reserved_90[index]=0; | 1794 | marker.reserved_90[index] = 0; |
1794 | } | ||
1795 | 1795 | ||
1796 | // send the marker information | 1796 | // send the marker information |
1797 | if (ad_marker_send(port, &marker) >= 0) { | 1797 | if (ad_marker_send(port, &marker) >= 0) { |
@@ -1816,7 +1816,7 @@ static void ad_marker_info_received(struct bond_marker *marker_info, | |||
1816 | //marker = *marker_info; | 1816 | //marker = *marker_info; |
1817 | memcpy(&marker, marker_info, sizeof(struct bond_marker)); | 1817 | memcpy(&marker, marker_info, sizeof(struct bond_marker)); |
1818 | // change the marker subtype to marker response | 1818 | // change the marker subtype to marker response |
1819 | marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE; | 1819 | marker.tlv_type = AD_MARKER_RESPONSE_SUBTYPE; |
1820 | // send the marker response | 1820 | // send the marker response |
1821 | 1821 | ||
1822 | if (ad_marker_send(port, &marker) >= 0) { | 1822 | if (ad_marker_send(port, &marker) >= 0) { |
@@ -1837,8 +1837,8 @@ static void ad_marker_info_received(struct bond_marker *marker_info, | |||
1837 | static void ad_marker_response_received(struct bond_marker *marker, | 1837 | static void ad_marker_response_received(struct bond_marker *marker, |
1838 | struct port *port) | 1838 | struct port *port) |
1839 | { | 1839 | { |
1840 | marker=NULL; // just to satisfy the compiler | 1840 | marker = NULL; /* just to satisfy the compiler */ |
1841 | port=NULL; // just to satisfy the compiler | 1841 | port = NULL; /* just to satisfy the compiler */ |
1842 | // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW | 1842 | // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW |
1843 | } | 1843 | } |
1844 | 1844 | ||
@@ -1912,7 +1912,7 @@ int bond_3ad_bind_slave(struct slave *slave) | |||
1912 | return -1; | 1912 | return -1; |
1913 | } | 1913 | } |
1914 | 1914 | ||
1915 | //check that the slave has not been intialized yet. | 1915 | //check that the slave has not been initialized yet. |
1916 | if (SLAVE_AD_INFO(slave).port.slave != slave) { | 1916 | if (SLAVE_AD_INFO(slave).port.slave != slave) { |
1917 | 1917 | ||
1918 | // port initialization | 1918 | // port initialization |
@@ -1932,9 +1932,8 @@ int bond_3ad_bind_slave(struct slave *slave) | |||
1932 | port->actor_admin_port_key |= (__get_link_speed(port) << 1); | 1932 | port->actor_admin_port_key |= (__get_link_speed(port) << 1); |
1933 | port->actor_oper_port_key = port->actor_admin_port_key; | 1933 | port->actor_oper_port_key = port->actor_admin_port_key; |
1934 | // if the port is not full duplex, then the port should be not lacp Enabled | 1934 | // if the port is not full duplex, then the port should be not lacp Enabled |
1935 | if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { | 1935 | if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) |
1936 | port->sm_vars &= ~AD_PORT_LACP_ENABLED; | 1936 | port->sm_vars &= ~AD_PORT_LACP_ENABLED; |
1937 | } | ||
1938 | // actor system is the bond's system | 1937 | // actor system is the bond's system |
1939 | port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; | 1938 | port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; |
1940 | // tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) | 1939 | // tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) |
@@ -2006,9 +2005,10 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2006 | new_aggregator = __get_first_agg(port); | 2005 | new_aggregator = __get_first_agg(port); |
2007 | for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) { | 2006 | for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) { |
2008 | // if the new aggregator is empty, or it is connected to our port only | 2007 | // if the new aggregator is empty, or it is connected to our port only |
2009 | if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) { | 2008 | if (!new_aggregator->lag_ports |
2009 | || ((new_aggregator->lag_ports == port) | ||
2010 | && !new_aggregator->lag_ports->next_port_in_aggregator)) | ||
2010 | break; | 2011 | break; |
2011 | } | ||
2012 | } | 2012 | } |
2013 | // if new aggregator found, copy the aggregator's parameters | 2013 | // if new aggregator found, copy the aggregator's parameters |
2014 | // and connect the related lag_ports to the new aggregator | 2014 | // and connect the related lag_ports to the new aggregator |
@@ -2037,17 +2037,17 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2037 | new_aggregator->num_of_ports = aggregator->num_of_ports; | 2037 | new_aggregator->num_of_ports = aggregator->num_of_ports; |
2038 | 2038 | ||
2039 | // update the information that is written on the ports about the aggregator | 2039 | // update the information that is written on the ports about the aggregator |
2040 | for (temp_port=aggregator->lag_ports; temp_port; temp_port=temp_port->next_port_in_aggregator) { | 2040 | for (temp_port = aggregator->lag_ports; temp_port; |
2041 | temp_port->aggregator=new_aggregator; | 2041 | temp_port = temp_port->next_port_in_aggregator) { |
2042 | temp_port->aggregator = new_aggregator; | ||
2042 | temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; | 2043 | temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; |
2043 | } | 2044 | } |
2044 | 2045 | ||
2045 | // clear the aggregator | 2046 | // clear the aggregator |
2046 | ad_clear_agg(aggregator); | 2047 | ad_clear_agg(aggregator); |
2047 | 2048 | ||
2048 | if (select_new_active_agg) { | 2049 | if (select_new_active_agg) |
2049 | ad_agg_selection_logic(__get_first_agg(port)); | 2050 | ad_agg_selection_logic(__get_first_agg(port)); |
2050 | } | ||
2051 | } else { | 2051 | } else { |
2052 | pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", | 2052 | pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", |
2053 | slave->dev->master->name); | 2053 | slave->dev->master->name); |
@@ -2071,15 +2071,16 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2071 | for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) { | 2071 | for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) { |
2072 | prev_port = NULL; | 2072 | prev_port = NULL; |
2073 | // search the port in the aggregator's related ports | 2073 | // search the port in the aggregator's related ports |
2074 | for (temp_port=temp_aggregator->lag_ports; temp_port; prev_port=temp_port, temp_port=temp_port->next_port_in_aggregator) { | 2074 | for (temp_port = temp_aggregator->lag_ports; temp_port; |
2075 | prev_port = temp_port, | ||
2076 | temp_port = temp_port->next_port_in_aggregator) { | ||
2075 | if (temp_port == port) { // the aggregator found - detach the port from this aggregator | 2077 | if (temp_port == port) { // the aggregator found - detach the port from this aggregator |
2076 | if (prev_port) { | 2078 | if (prev_port) |
2077 | prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator; | 2079 | prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator; |
2078 | } else { | 2080 | else |
2079 | temp_aggregator->lag_ports = temp_port->next_port_in_aggregator; | 2081 | temp_aggregator->lag_ports = temp_port->next_port_in_aggregator; |
2080 | } | ||
2081 | temp_aggregator->num_of_ports--; | 2082 | temp_aggregator->num_of_ports--; |
2082 | if (temp_aggregator->num_of_ports==0) { | 2083 | if (temp_aggregator->num_of_ports == 0) { |
2083 | select_new_active_agg = temp_aggregator->is_active; | 2084 | select_new_active_agg = temp_aggregator->is_active; |
2084 | // clear the aggregator | 2085 | // clear the aggregator |
2085 | ad_clear_agg(temp_aggregator); | 2086 | ad_clear_agg(temp_aggregator); |
@@ -2094,7 +2095,7 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2094 | } | 2095 | } |
2095 | } | 2096 | } |
2096 | } | 2097 | } |
2097 | port->slave=NULL; | 2098 | port->slave = NULL; |
2098 | } | 2099 | } |
2099 | 2100 | ||
2100 | /** | 2101 | /** |
@@ -2119,14 +2120,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2119 | 2120 | ||
2120 | read_lock(&bond->lock); | 2121 | read_lock(&bond->lock); |
2121 | 2122 | ||
2122 | if (bond->kill_timers) { | 2123 | if (bond->kill_timers) |
2123 | goto out; | 2124 | goto out; |
2124 | } | ||
2125 | 2125 | ||
2126 | //check if there are any slaves | 2126 | //check if there are any slaves |
2127 | if (bond->slave_cnt == 0) { | 2127 | if (bond->slave_cnt == 0) |
2128 | goto re_arm; | 2128 | goto re_arm; |
2129 | } | ||
2130 | 2129 | ||
2131 | // check if agg_select_timer timer after initialize is timed out | 2130 | // check if agg_select_timer timer after initialize is timed out |
2132 | if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { | 2131 | if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { |
@@ -2152,6 +2151,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2152 | goto re_arm; | 2151 | goto re_arm; |
2153 | } | 2152 | } |
2154 | 2153 | ||
2154 | /* Lock around state machines to protect data accessed | ||
2155 | * by all (e.g., port->sm_vars). ad_rx_machine may run | ||
2156 | * concurrently due to incoming LACPDU. | ||
2157 | */ | ||
2158 | __get_state_machine_lock(port); | ||
2159 | |||
2155 | ad_rx_machine(NULL, port); | 2160 | ad_rx_machine(NULL, port); |
2156 | ad_periodic_machine(port); | 2161 | ad_periodic_machine(port); |
2157 | ad_port_selection_logic(port); | 2162 | ad_port_selection_logic(port); |
@@ -2159,9 +2164,10 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2159 | ad_tx_machine(port); | 2164 | ad_tx_machine(port); |
2160 | 2165 | ||
2161 | // turn off the BEGIN bit, since we already handled it | 2166 | // turn off the BEGIN bit, since we already handled it |
2162 | if (port->sm_vars & AD_PORT_BEGIN) { | 2167 | if (port->sm_vars & AD_PORT_BEGIN) |
2163 | port->sm_vars &= ~AD_PORT_BEGIN; | 2168 | port->sm_vars &= ~AD_PORT_BEGIN; |
2164 | } | 2169 | |
2170 | __release_state_machine_lock(port); | ||
2165 | } | 2171 | } |
2166 | 2172 | ||
2167 | re_arm: | 2173 | re_arm: |
@@ -2198,7 +2204,10 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u | |||
2198 | case AD_TYPE_LACPDU: | 2204 | case AD_TYPE_LACPDU: |
2199 | pr_debug("Received LACPDU on port %d\n", | 2205 | pr_debug("Received LACPDU on port %d\n", |
2200 | port->actor_port_number); | 2206 | port->actor_port_number); |
2207 | /* Protect against concurrent state machines */ | ||
2208 | __get_state_machine_lock(port); | ||
2201 | ad_rx_machine(lacpdu, port); | 2209 | ad_rx_machine(lacpdu, port); |
2210 | __release_state_machine_lock(port); | ||
2202 | break; | 2211 | break; |
2203 | 2212 | ||
2204 | case AD_TYPE_MARKER: | 2213 | case AD_TYPE_MARKER: |
@@ -2245,7 +2254,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) | |||
2245 | } | 2254 | } |
2246 | 2255 | ||
2247 | port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; | 2256 | port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; |
2248 | port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); | 2257 | port->actor_oper_port_key = port->actor_admin_port_key |= |
2258 | (__get_link_speed(port) << 1); | ||
2249 | pr_debug("Port %d changed speed\n", port->actor_port_number); | 2259 | pr_debug("Port %d changed speed\n", port->actor_port_number); |
2250 | // there is no need to reselect a new aggregator, just signal the | 2260 | // there is no need to reselect a new aggregator, just signal the |
2251 | // state machines to reinitialize | 2261 | // state machines to reinitialize |
@@ -2262,7 +2272,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) | |||
2262 | { | 2272 | { |
2263 | struct port *port; | 2273 | struct port *port; |
2264 | 2274 | ||
2265 | port=&(SLAVE_AD_INFO(slave).port); | 2275 | port = &(SLAVE_AD_INFO(slave).port); |
2266 | 2276 | ||
2267 | // if slave is null, the whole port is not initialized | 2277 | // if slave is null, the whole port is not initialized |
2268 | if (!port->slave) { | 2278 | if (!port->slave) { |
@@ -2272,7 +2282,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) | |||
2272 | } | 2282 | } |
2273 | 2283 | ||
2274 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; | 2284 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; |
2275 | port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); | 2285 | port->actor_oper_port_key = port->actor_admin_port_key |= |
2286 | __get_duplex(port); | ||
2276 | pr_debug("Port %d changed duplex\n", port->actor_port_number); | 2287 | pr_debug("Port %d changed duplex\n", port->actor_port_number); |
2277 | // there is no need to reselect a new aggregator, just signal the | 2288 | // there is no need to reselect a new aggregator, just signal the |
2278 | // state machines to reinitialize | 2289 | // state machines to reinitialize |
@@ -2304,14 +2315,17 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) | |||
2304 | if (link == BOND_LINK_UP) { | 2315 | if (link == BOND_LINK_UP) { |
2305 | port->is_enabled = true; | 2316 | port->is_enabled = true; |
2306 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; | 2317 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; |
2307 | port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); | 2318 | port->actor_oper_port_key = port->actor_admin_port_key |= |
2319 | __get_duplex(port); | ||
2308 | port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; | 2320 | port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; |
2309 | port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); | 2321 | port->actor_oper_port_key = port->actor_admin_port_key |= |
2322 | (__get_link_speed(port) << 1); | ||
2310 | } else { | 2323 | } else { |
2311 | /* link has failed */ | 2324 | /* link has failed */ |
2312 | port->is_enabled = false; | 2325 | port->is_enabled = false; |
2313 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; | 2326 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; |
2314 | port->actor_oper_port_key= (port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS); | 2327 | port->actor_oper_port_key = (port->actor_admin_port_key &= |
2328 | ~AD_SPEED_KEY_BITS); | ||
2315 | } | 2329 | } |
2316 | //BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN"))); | 2330 | //BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN"))); |
2317 | // there is no need to reselect a new aggregator, just signal the | 2331 | // there is no need to reselect a new aggregator, just signal the |
@@ -2389,15 +2403,6 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) | |||
2389 | struct ad_info ad_info; | 2403 | struct ad_info ad_info; |
2390 | int res = 1; | 2404 | int res = 1; |
2391 | 2405 | ||
2392 | /* make sure that the slaves list will | ||
2393 | * not change during tx | ||
2394 | */ | ||
2395 | read_lock(&bond->lock); | ||
2396 | |||
2397 | if (!BOND_IS_OK(bond)) { | ||
2398 | goto out; | ||
2399 | } | ||
2400 | |||
2401 | if (bond_3ad_get_active_agg_info(bond, &ad_info)) { | 2406 | if (bond_3ad_get_active_agg_info(bond, &ad_info)) { |
2402 | pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n", | 2407 | pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n", |
2403 | dev->name); | 2408 | dev->name); |
@@ -2420,9 +2425,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) | |||
2420 | 2425 | ||
2421 | if (agg && (agg->aggregator_identifier == agg_id)) { | 2426 | if (agg && (agg->aggregator_identifier == agg_id)) { |
2422 | slave_agg_no--; | 2427 | slave_agg_no--; |
2423 | if (slave_agg_no < 0) { | 2428 | if (slave_agg_no < 0) |
2424 | break; | 2429 | break; |
2425 | } | ||
2426 | } | 2430 | } |
2427 | } | 2431 | } |
2428 | 2432 | ||
@@ -2438,9 +2442,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) | |||
2438 | int slave_agg_id = 0; | 2442 | int slave_agg_id = 0; |
2439 | struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; | 2443 | struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; |
2440 | 2444 | ||
2441 | if (agg) { | 2445 | if (agg) |
2442 | slave_agg_id = agg->aggregator_identifier; | 2446 | slave_agg_id = agg->aggregator_identifier; |
2443 | } | ||
2444 | 2447 | ||
2445 | if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) { | 2448 | if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) { |
2446 | res = bond_dev_queue_xmit(bond, skb, slave->dev); | 2449 | res = bond_dev_queue_xmit(bond, skb, slave->dev); |
@@ -2453,36 +2456,20 @@ out: | |||
2453 | /* no suitable interface, frame not sent */ | 2456 | /* no suitable interface, frame not sent */ |
2454 | dev_kfree_skb(skb); | 2457 | dev_kfree_skb(skb); |
2455 | } | 2458 | } |
2456 | read_unlock(&bond->lock); | 2459 | |
2457 | return NETDEV_TX_OK; | 2460 | return NETDEV_TX_OK; |
2458 | } | 2461 | } |
2459 | 2462 | ||
2460 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev) | 2463 | void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, |
2464 | struct slave *slave) | ||
2461 | { | 2465 | { |
2462 | struct bonding *bond = netdev_priv(dev); | 2466 | if (skb->protocol != PKT_TYPE_LACPDU) |
2463 | struct slave *slave = NULL; | 2467 | return; |
2464 | int ret = NET_RX_DROP; | ||
2465 | |||
2466 | if (!(dev->flags & IFF_MASTER)) | ||
2467 | goto out; | ||
2468 | 2468 | ||
2469 | if (!pskb_may_pull(skb, sizeof(struct lacpdu))) | 2469 | if (!pskb_may_pull(skb, sizeof(struct lacpdu))) |
2470 | goto out; | 2470 | return; |
2471 | 2471 | ||
2472 | read_lock(&bond->lock); | 2472 | read_lock(&bond->lock); |
2473 | slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev), | ||
2474 | orig_dev); | ||
2475 | if (!slave) | ||
2476 | goto out_unlock; | ||
2477 | |||
2478 | bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); | 2473 | bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); |
2479 | |||
2480 | ret = NET_RX_SUCCESS; | ||
2481 | |||
2482 | out_unlock: | ||
2483 | read_unlock(&bond->lock); | 2474 | read_unlock(&bond->lock); |
2484 | out: | ||
2485 | dev_kfree_skb(skb); | ||
2486 | |||
2487 | return ret; | ||
2488 | } | 2475 | } |