xref: /linux/drivers/net/bonding/bond_3ad.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 2 of the License, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 59
16  * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  * The full GNU General Public License is included in this distribution in the
19  * file called LICENSE.
20  *
21  */
22 
23 //#define BONDING_DEBUG 1
24 
25 #include <linux/skbuff.h>
26 #include <linux/if_ether.h>
27 #include <linux/netdevice.h>
28 #include <linux/spinlock.h>
29 #include <linux/ethtool.h>
30 #include <linux/if_bonding.h>
31 #include <linux/pkt_sched.h>
32 #include "bonding.h"
33 #include "bond_3ad.h"
34 
35 // General definitions
36 #define AD_SHORT_TIMEOUT           1
37 #define AD_LONG_TIMEOUT            0
38 #define AD_STANDBY                 0x2
39 #define AD_MAX_TX_IN_SECOND        3
40 #define AD_COLLECTOR_MAX_DELAY     0
41 
42 // Timer definitions(43.4.4 in the 802.3ad standard)
43 #define AD_FAST_PERIODIC_TIME      1
44 #define AD_SLOW_PERIODIC_TIME      30
45 #define AD_SHORT_TIMEOUT_TIME      (3*AD_FAST_PERIODIC_TIME)
46 #define AD_LONG_TIMEOUT_TIME       (3*AD_SLOW_PERIODIC_TIME)
47 #define AD_CHURN_DETECTION_TIME    60
48 #define AD_AGGREGATE_WAIT_TIME     2
49 
50 // Port state definitions(43.4.2.2 in the 802.3ad standard)
51 #define AD_STATE_LACP_ACTIVITY   0x1
52 #define AD_STATE_LACP_TIMEOUT    0x2
53 #define AD_STATE_AGGREGATION     0x4
54 #define AD_STATE_SYNCHRONIZATION 0x8
55 #define AD_STATE_COLLECTING      0x10
56 #define AD_STATE_DISTRIBUTING    0x20
57 #define AD_STATE_DEFAULTED       0x40
58 #define AD_STATE_EXPIRED         0x80
59 
60 // Port Variables definitions used by the State Machines(43.4.7 in the 802.3ad standard)
61 #define AD_PORT_BEGIN           0x1
62 #define AD_PORT_LACP_ENABLED    0x2
63 #define AD_PORT_ACTOR_CHURN     0x4
64 #define AD_PORT_PARTNER_CHURN   0x8
65 #define AD_PORT_READY           0x10
66 #define AD_PORT_READY_N         0x20
67 #define AD_PORT_MATCHED         0x40
68 #define AD_PORT_STANDBY         0x80
69 #define AD_PORT_SELECTED        0x100
70 #define AD_PORT_MOVED           0x200
71 
72 // Port Key definitions
73 // key is determined according to the link speed, duplex and
74 // user key(which is yet not supported)
75 //              ------------------------------------------------------------
76 // Port key :   | User key                       |      Speed       |Duplex|
77 //              ------------------------------------------------------------
78 //              16                               6               1 0
79 #define  AD_DUPLEX_KEY_BITS    0x1
80 #define  AD_SPEED_KEY_BITS     0x3E
81 #define  AD_USER_KEY_BITS      0xFFC0
82 
83 //dalloun
84 #define     AD_LINK_SPEED_BITMASK_1MBPS       0x1
85 #define     AD_LINK_SPEED_BITMASK_10MBPS      0x2
86 #define     AD_LINK_SPEED_BITMASK_100MBPS     0x4
87 #define     AD_LINK_SPEED_BITMASK_1000MBPS    0x8
88 #define     AD_LINK_SPEED_BITMASK_10000MBPS   0x10
89 //endalloun
90 
91 // compare MAC addresses
92 #define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN)
93 
94 static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};
95 static u16 ad_ticks_per_sec;
96 static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
97 
98 // ================= 3AD api to bonding and kernel code ==================
99 static u16 __get_link_speed(struct port *port);
100 static u8 __get_duplex(struct port *port);
101 static inline void __initialize_port_locks(struct port *port);
102 //conversions
103 static void __htons_lacpdu(struct lacpdu *lacpdu);
104 static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par);
105 
106 
107 // ================= ad code helper functions ==================
108 //needed by ad_rx_machine(...)
109 static void __record_pdu(struct lacpdu *lacpdu, struct port *port);
110 static void __record_default(struct port *port);
111 static void __update_selected(struct lacpdu *lacpdu, struct port *port);
112 static void __update_default_selected(struct port *port);
113 static void __choose_matched(struct lacpdu *lacpdu, struct port *port);
114 static void __update_ntt(struct lacpdu *lacpdu, struct port *port);
115 
116 //needed for ad_mux_machine(..)
117 static void __attach_bond_to_agg(struct port *port);
118 static void __detach_bond_from_agg(struct port *port);
119 static int __agg_ports_are_ready(struct aggregator *aggregator);
120 static void __set_agg_ports_ready(struct aggregator *aggregator, int val);
121 
122 //needed for ad_agg_selection_logic(...)
123 static u32 __get_agg_bandwidth(struct aggregator *aggregator);
124 static struct aggregator *__get_active_agg(struct aggregator *aggregator);
125 
126 
127 // ================= main 802.3ad protocol functions ==================
128 static int ad_lacpdu_send(struct port *port);
129 static int ad_marker_send(struct port *port, struct marker *marker);
130 static void ad_mux_machine(struct port *port);
131 static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port);
132 static void ad_tx_machine(struct port *port);
133 static void ad_periodic_machine(struct port *port);
134 static void ad_port_selection_logic(struct port *port);
135 static void ad_agg_selection_logic(struct aggregator *aggregator);
136 static void ad_clear_agg(struct aggregator *aggregator);
137 static void ad_initialize_agg(struct aggregator *aggregator);
138 static void ad_initialize_port(struct port *port, int lacp_fast);
139 static void ad_initialize_lacpdu(struct lacpdu *Lacpdu);
140 static void ad_enable_collecting_distributing(struct port *port);
141 static void ad_disable_collecting_distributing(struct port *port);
142 static void ad_marker_info_received(struct marker *marker_info, struct port *port);
143 static void ad_marker_response_received(struct marker *marker, struct port *port);
144 
145 
146 /////////////////////////////////////////////////////////////////////////////////
147 // ================= api to bonding and kernel code ==================
148 /////////////////////////////////////////////////////////////////////////////////
149 
150 /**
151  * __get_bond_by_port - get the port's bonding struct
152  * @port: the port we're looking at
153  *
154  * Return @port's bonding struct, or %NULL if it can't be found.
155  */
156 static inline struct bonding *__get_bond_by_port(struct port *port)
157 {
158 	if (port->slave == NULL) {
159 		return NULL;
160 	}
161 
162 	return bond_get_bond_by_slave(port->slave);
163 }
164 
165 /**
166  * __get_first_port - get the first port in the bond
167  * @bond: the bond we're looking at
168  *
169  * Return the port of the first slave in @bond, or %NULL if it can't be found.
170  */
171 static inline struct port *__get_first_port(struct bonding *bond)
172 {
173 	if (bond->slave_cnt == 0) {
174 		return NULL;
175 	}
176 
177 	return &(SLAVE_AD_INFO(bond->first_slave).port);
178 }
179 
180 /**
181  * __get_next_port - get the next port in the bond
182  * @port: the port we're looking at
183  *
184  * Return the port of the slave that is next in line of @port's slave in the
185  * bond, or %NULL if it can't be found.
186  */
187 static inline struct port *__get_next_port(struct port *port)
188 {
189 	struct bonding *bond = __get_bond_by_port(port);
190 	struct slave *slave = port->slave;
191 
192 	// If there's no bond for this port, or this is the last slave
193 	if ((bond == NULL) || (slave->next == bond->first_slave)) {
194 		return NULL;
195 	}
196 
197 	return &(SLAVE_AD_INFO(slave->next).port);
198 }
199 
200 /**
201  * __get_first_agg - get the first aggregator in the bond
202  * @bond: the bond we're looking at
203  *
204  * Return the aggregator of the first slave in @bond, or %NULL if it can't be
205  * found.
206  */
207 static inline struct aggregator *__get_first_agg(struct port *port)
208 {
209 	struct bonding *bond = __get_bond_by_port(port);
210 
211 	// If there's no bond for this port, or bond has no slaves
212 	if ((bond == NULL) || (bond->slave_cnt == 0)) {
213 		return NULL;
214 	}
215 
216 	return &(SLAVE_AD_INFO(bond->first_slave).aggregator);
217 }
218 
219 /**
220  * __get_next_agg - get the next aggregator in the bond
221  * @aggregator: the aggregator we're looking at
222  *
223  * Return the aggregator of the slave that is next in line of @aggregator's
224  * slave in the bond, or %NULL if it can't be found.
225  */
226 static inline struct aggregator *__get_next_agg(struct aggregator *aggregator)
227 {
228 	struct slave *slave = aggregator->slave;
229 	struct bonding *bond = bond_get_bond_by_slave(slave);
230 
231 	// If there's no bond for this aggregator, or this is the last slave
232 	if ((bond == NULL) || (slave->next == bond->first_slave)) {
233 		return NULL;
234 	}
235 
236 	return &(SLAVE_AD_INFO(slave->next).aggregator);
237 }
238 
239 /**
240  * __disable_port - disable the port's slave
241  * @port: the port we're looking at
242  *
243  */
244 static inline void __disable_port(struct port *port)
245 {
246 	bond_set_slave_inactive_flags(port->slave);
247 }
248 
249 /**
250  * __enable_port - enable the port's slave, if it's up
251  * @port: the port we're looking at
252  *
253  */
254 static inline void __enable_port(struct port *port)
255 {
256 	struct slave *slave = port->slave;
257 
258 	if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) {
259 		bond_set_slave_active_flags(slave);
260 	}
261 }
262 
263 /**
264  * __port_is_enabled - check if the port's slave is in active state
265  * @port: the port we're looking at
266  *
267  */
268 static inline int __port_is_enabled(struct port *port)
269 {
270 	return(port->slave->state == BOND_STATE_ACTIVE);
271 }
272 
273 /**
274  * __get_agg_selection_mode - get the aggregator selection mode
275  * @port: the port we're looking at
276  *
277  * Get the aggregator selection mode. Can be %BANDWIDTH or %COUNT.
278  */
279 static inline u32 __get_agg_selection_mode(struct port *port)
280 {
281 	struct bonding *bond = __get_bond_by_port(port);
282 
283 	if (bond == NULL) {
284 		return AD_BANDWIDTH;
285 	}
286 
287 	return BOND_AD_INFO(bond).agg_select_mode;
288 }
289 
290 /**
291  * __check_agg_selection_timer - check if the selection timer has expired
292  * @port: the port we're looking at
293  *
294  */
295 static inline int __check_agg_selection_timer(struct port *port)
296 {
297 	struct bonding *bond = __get_bond_by_port(port);
298 
299 	if (bond == NULL) {
300 		return 0;
301 	}
302 
303 	return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0;
304 }
305 
306 /**
307  * __get_rx_machine_lock - lock the port's RX machine
308  * @port: the port we're looking at
309  *
310  */
311 static inline void __get_rx_machine_lock(struct port *port)
312 {
313 	spin_lock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
314 }
315 
316 /**
317  * __release_rx_machine_lock - unlock the port's RX machine
318  * @port: the port we're looking at
319  *
320  */
321 static inline void __release_rx_machine_lock(struct port *port)
322 {
323 	spin_unlock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
324 }
325 
326 /**
327  * __get_link_speed - get a port's speed
328  * @port: the port we're looking at
329  *
330  * Return @port's speed in 802.3ad bitmask format. i.e. one of:
331  *     0,
332  *     %AD_LINK_SPEED_BITMASK_10MBPS,
333  *     %AD_LINK_SPEED_BITMASK_100MBPS,
334  *     %AD_LINK_SPEED_BITMASK_1000MBPS,
335  *     %AD_LINK_SPEED_BITMASK_10000MBPS
336  */
337 static u16 __get_link_speed(struct port *port)
338 {
339 	struct slave *slave = port->slave;
340 	u16 speed;
341 
342 	/* this if covers only a special case: when the configuration starts with
343 	 * link down, it sets the speed to 0.
344 	 * This is done in spite of the fact that the e100 driver reports 0 to be
345 	 * compatible with MVT in the future.*/
346 	if (slave->link != BOND_LINK_UP) {
347 		speed=0;
348 	} else {
349 		switch (slave->speed) {
350 		case SPEED_10:
351 			speed = AD_LINK_SPEED_BITMASK_10MBPS;
352 			break;
353 
354 		case SPEED_100:
355 			speed = AD_LINK_SPEED_BITMASK_100MBPS;
356 			break;
357 
358 		case SPEED_1000:
359 			speed = AD_LINK_SPEED_BITMASK_1000MBPS;
360 			break;
361 
362 		case SPEED_10000:
363 			speed = AD_LINK_SPEED_BITMASK_10000MBPS;
364 			break;
365 
366 		default:
367 			speed = 0; // unknown speed value from ethtool. shouldn't happen
368 			break;
369 		}
370 	}
371 
372 	dprintk("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed);
373 	return speed;
374 }
375 
376 /**
377  * __get_duplex - get a port's duplex
378  * @port: the port we're looking at
379  *
380  * Return @port's duplex in 802.3ad bitmask format. i.e.:
381  *     0x01 if in full duplex
382  *     0x00 otherwise
383  */
384 static u8 __get_duplex(struct port *port)
385 {
386 	struct slave *slave = port->slave;
387 
388 	u8 retval;
389 
390 	//  handling a special case: when the configuration starts with
391 	// link down, it sets the duplex to 0.
392 	if (slave->link != BOND_LINK_UP) {
393 		retval=0x0;
394 	} else {
395 		switch (slave->duplex) {
396 		case DUPLEX_FULL:
397 			retval=0x1;
398 			dprintk("Port %d Received status full duplex update from adapter\n", port->actor_port_number);
399 			break;
400 		case DUPLEX_HALF:
401 		default:
402 			retval=0x0;
403 			dprintk("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number);
404 			break;
405 		}
406 	}
407 	return retval;
408 }
409 
410 /**
411  * __initialize_port_locks - initialize a port's RX machine spinlock
412  * @port: the port we're looking at
413  *
414  */
415 static inline void __initialize_port_locks(struct port *port)
416 {
417 	// make sure it isn't called twice
418 	spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
419 }
420 
421 //conversions
422 /**
423  * __htons_lacpdu - convert the contents of a LACPDU to network byte order
424  * @lacpdu: the speicifed lacpdu
425  *
426  * For each multi-byte field in the lacpdu, convert its content
427  */
428 static void __htons_lacpdu(struct lacpdu *lacpdu)
429 {
430 	if (lacpdu) {
431 		lacpdu->actor_system_priority =   htons(lacpdu->actor_system_priority);
432 		lacpdu->actor_key =               htons(lacpdu->actor_key);
433 		lacpdu->actor_port_priority =     htons(lacpdu->actor_port_priority);
434 		lacpdu->actor_port =              htons(lacpdu->actor_port);
435 		lacpdu->partner_system_priority = htons(lacpdu->partner_system_priority);
436 		lacpdu->partner_key =             htons(lacpdu->partner_key);
437 		lacpdu->partner_port_priority =   htons(lacpdu->partner_port_priority);
438 		lacpdu->partner_port =            htons(lacpdu->partner_port);
439 		lacpdu->collector_max_delay =     htons(lacpdu->collector_max_delay);
440 	}
441 }
442 
443 /**
444  * __ad_timer_to_ticks - convert a given timer type to AD module ticks
445  * @timer_type:	which timer to operate
446  * @par: timer parameter. see below
447  *
448  * If @timer_type is %current_while_timer, @par indicates long/short timer.
449  * If @timer_type is %periodic_timer, @par is one of %FAST_PERIODIC_TIME,
450  *						    %SLOW_PERIODIC_TIME.
451  */
452 static u16 __ad_timer_to_ticks(u16 timer_type, u16 par)
453 {
454 	u16 retval=0;	 //to silence the compiler
455 
456 	switch (timer_type) {
457 	case AD_CURRENT_WHILE_TIMER:   // for rx machine usage
458 		if (par) {	      // for short or long timeout
459 			retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout
460 		} else {
461 			retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout
462 		}
463 		break;
464 	case AD_ACTOR_CHURN_TIMER:	    // for local churn machine
465 		retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec);
466 		break;
467 	case AD_PERIODIC_TIMER:	    // for periodic machine
468 		retval = (par*ad_ticks_per_sec); // long timeout
469 		break;
470 	case AD_PARTNER_CHURN_TIMER:   // for remote churn machine
471 		retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec);
472 		break;
473 	case AD_WAIT_WHILE_TIMER:	    // for selection machine
474 		retval = (AD_AGGREGATE_WAIT_TIME*ad_ticks_per_sec);
475 		break;
476 	}
477 	return retval;
478 }
479 
480 
481 /////////////////////////////////////////////////////////////////////////////////
482 // ================= ad_rx_machine helper functions ==================
483 /////////////////////////////////////////////////////////////////////////////////
484 
485 /**
486  * __record_pdu - record parameters from a received lacpdu
487  * @lacpdu: the lacpdu we've received
488  * @port: the port we're looking at
489  *
490  * Record the parameter values for the Actor carried in a received lacpdu as
491  * the current partner operational parameter values and sets
492  * actor_oper_port_state.defaulted to FALSE.
493  */
494 static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
495 {
496 	// validate lacpdu and port
497 	if (lacpdu && port) {
498 		// record the new parameter values for the partner operational
499 		port->partner_oper_port_number = ntohs(lacpdu->actor_port);
500 		port->partner_oper_port_priority = ntohs(lacpdu->actor_port_priority);
501 		port->partner_oper_system = lacpdu->actor_system;
502 		port->partner_oper_system_priority = ntohs(lacpdu->actor_system_priority);
503 		port->partner_oper_key = ntohs(lacpdu->actor_key);
504 		// zero partener's lase states
505 		port->partner_oper_port_state = 0;
506 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY);
507 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_TIMEOUT);
508 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_AGGREGATION);
509 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION);
510 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_COLLECTING);
511 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DISTRIBUTING);
512 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DEFAULTED);
513 		port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_EXPIRED);
514 
515 		// set actor_oper_port_state.defaulted to FALSE
516 		port->actor_oper_port_state &= ~AD_STATE_DEFAULTED;
517 
518 		// set the partner sync. to on if the partner is sync. and the port is matched
519 		if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) {
520 			port->partner_oper_port_state |= AD_STATE_SYNCHRONIZATION;
521 		} else {
522 			port->partner_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;
523 		}
524 	}
525 }
526 
527 /**
528  * __record_default - record default parameters
529  * @port: the port we're looking at
530  *
531  * This function records the default parameter values for the partner carried
532  * in the Partner Admin parameters as the current partner operational parameter
533  * values and sets actor_oper_port_state.defaulted to TRUE.
534  */
535 static void __record_default(struct port *port)
536 {
537 	// validate the port
538 	if (port) {
539 		// record the partner admin parameters
540 		port->partner_oper_port_number = port->partner_admin_port_number;
541 		port->partner_oper_port_priority = port->partner_admin_port_priority;
542 		port->partner_oper_system = port->partner_admin_system;
543 		port->partner_oper_system_priority = port->partner_admin_system_priority;
544 		port->partner_oper_key = port->partner_admin_key;
545 		port->partner_oper_port_state = port->partner_admin_port_state;
546 
547 		// set actor_oper_port_state.defaulted to true
548 		port->actor_oper_port_state |= AD_STATE_DEFAULTED;
549 	}
550 }
551 
552 /**
553  * __update_selected - update a port's Selected variable from a received lacpdu
554  * @lacpdu: the lacpdu we've received
555  * @port: the port we're looking at
556  *
557  * Update the value of the selected variable, using parameter values from a
558  * newly received lacpdu. The parameter values for the Actor carried in the
559  * received PDU are compared with the corresponding operational parameter
560  * values for the ports partner. If one or more of the comparisons shows that
561  * the value(s) received in the PDU differ from the current operational values,
562  * then selected is set to FALSE and actor_oper_port_state.synchronization is
563  * set to out_of_sync. Otherwise, selected remains unchanged.
564  */
565 static void __update_selected(struct lacpdu *lacpdu, struct port *port)
566 {
567 	// validate lacpdu and port
568 	if (lacpdu && port) {
569 		// check if any parameter is different
570 		if ((ntohs(lacpdu->actor_port) != port->partner_oper_port_number) ||
571 		    (ntohs(lacpdu->actor_port_priority) != port->partner_oper_port_priority) ||
572 		    MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) ||
573 		    (ntohs(lacpdu->actor_system_priority) != port->partner_oper_system_priority) ||
574 		    (ntohs(lacpdu->actor_key) != port->partner_oper_key) ||
575 		    ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION))
576 		   ) {
577 			// update the state machine Selected variable
578 			port->sm_vars &= ~AD_PORT_SELECTED;
579 		}
580 	}
581 }
582 
583 /**
584  * __update_default_selected - update a port's Selected variable from Partner
585  * @port: the port we're looking at
586  *
587  * This function updates the value of the selected variable, using the partner
588  * administrative parameter values. The administrative values are compared with
589  * the corresponding operational parameter values for the partner. If one or
590  * more of the comparisons shows that the administrative value(s) differ from
591  * the current operational values, then Selected is set to FALSE and
592  * actor_oper_port_state.synchronization is set to OUT_OF_SYNC. Otherwise,
593  * Selected remains unchanged.
594  */
595 static void __update_default_selected(struct port *port)
596 {
597 	// validate the port
598 	if (port) {
599 		// check if any parameter is different
600 		if ((port->partner_admin_port_number != port->partner_oper_port_number) ||
601 		    (port->partner_admin_port_priority != port->partner_oper_port_priority) ||
602 		    MAC_ADDRESS_COMPARE(&(port->partner_admin_system), &(port->partner_oper_system)) ||
603 		    (port->partner_admin_system_priority != port->partner_oper_system_priority) ||
604 		    (port->partner_admin_key != port->partner_oper_key) ||
605 		    ((port->partner_admin_port_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION))
606 		   ) {
607 			// update the state machine Selected variable
608 			port->sm_vars &= ~AD_PORT_SELECTED;
609 		}
610 	}
611 }
612 
613 /**
614  * __choose_matched - update a port's matched variable from a received lacpdu
615  * @lacpdu: the lacpdu we've received
616  * @port: the port we're looking at
617  *
618  * Update the value of the matched variable, using parameter values from a
619  * newly received lacpdu. Parameter values for the partner carried in the
620  * received PDU are compared with the corresponding operational parameter
621  * values for the actor. Matched is set to TRUE if all of these parameters
622  * match and the PDU parameter partner_state.aggregation has the same value as
623  * actor_oper_port_state.aggregation and lacp will actively maintain the link
624  * in the aggregation. Matched is also set to TRUE if the value of
625  * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates
626  * an individual link and lacp will actively maintain the link. Otherwise,
627  * matched is set to FALSE. LACP is considered to be actively maintaining the
628  * link if either the PDU's actor_state.lacp_activity variable is TRUE or both
629  * the actor's actor_oper_port_state.lacp_activity and the PDU's
630  * partner_state.lacp_activity variables are TRUE.
631  */
632 static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
633 {
634 	// validate lacpdu and port
635 	if (lacpdu && port) {
636 		// check if all parameters are alike
637 		if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
638 		     (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
639 		     !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) &&
640 		     (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
641 		     (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
642 		     ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
643 		    // or this is individual link(aggregation == FALSE)
644 		    ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
645 		   ) {
646 			// update the state machine Matched variable
647 			port->sm_vars |= AD_PORT_MATCHED;
648 		} else {
649 			port->sm_vars &= ~AD_PORT_MATCHED;
650 		}
651 	}
652 }
653 
654 /**
655  * __update_ntt - update a port's ntt variable from a received lacpdu
656  * @lacpdu: the lacpdu we've received
657  * @port: the port we're looking at
658  *
659  * Updates the value of the ntt variable, using parameter values from a newly
660  * received lacpdu. The parameter values for the partner carried in the
661  * received PDU are compared with the corresponding operational parameter
662  * values for the Actor. If one or more of the comparisons shows that the
663  * value(s) received in the PDU differ from the current operational values,
664  * then ntt is set to TRUE. Otherwise, ntt remains unchanged.
665  */
666 static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
667 {
668 	// validate lacpdu and port
669 	if (lacpdu && port) {
670 		// check if any parameter is different
671 		if ((ntohs(lacpdu->partner_port) != port->actor_port_number) ||
672 		    (ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) ||
673 		    MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) ||
674 		    (ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) ||
675 		    (ntohs(lacpdu->partner_key) != port->actor_oper_port_key) ||
676 		    ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) ||
677 		    ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) ||
678 		    ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) ||
679 		    ((lacpdu->partner_state & AD_STATE_AGGREGATION) != (port->actor_oper_port_state & AD_STATE_AGGREGATION))
680 		   ) {
681 			// set ntt to be TRUE
682 			port->ntt = 1;
683 		}
684 	}
685 }
686 
687 /**
688  * __attach_bond_to_agg
689  * @port: the port we're looking at
690  *
691  * Handle the attaching of the port's control parser/multiplexer and the
692  * aggregator. This function does nothing since the parser/multiplexer of the
693  * receive and the parser/multiplexer of the aggregator are already combined.
694  */
695 static void __attach_bond_to_agg(struct port *port)
696 {
697 	port=NULL; // just to satisfy the compiler
698 	// This function does nothing since the parser/multiplexer of the receive
699 	// and the parser/multiplexer of the aggregator are already combined
700 }
701 
702 /**
703  * __detach_bond_from_agg
704  * @port: the port we're looking at
705  *
706  * Handle the detaching of the port's control parser/multiplexer from the
707  * aggregator. This function does nothing since the parser/multiplexer of the
708  * receive and the parser/multiplexer of the aggregator are already combined.
709  */
710 static void __detach_bond_from_agg(struct port *port)
711 {
712 	port=NULL; // just to satisfy the compiler
713 	// This function does nothing sience the parser/multiplexer of the receive
714 	// and the parser/multiplexer of the aggregator are already combined
715 }
716 
717 /**
718  * __agg_ports_are_ready - check if all ports in an aggregator are ready
719  * @aggregator: the aggregator we're looking at
720  *
721  */
722 static int __agg_ports_are_ready(struct aggregator *aggregator)
723 {
724 	struct port *port;
725 	int retval = 1;
726 
727 	if (aggregator) {
728 		// scan all ports in this aggregator to verfy if they are all ready
729 		for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
730 			if (!(port->sm_vars & AD_PORT_READY_N)) {
731 				retval = 0;
732 				break;
733 			}
734 		}
735 	}
736 
737 	return retval;
738 }
739 
740 /**
741  * __set_agg_ports_ready - set value of Ready bit in all ports of an aggregator
742  * @aggregator: the aggregator we're looking at
743  * @val: Should the ports' ready bit be set on or off
744  *
745  */
746 static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
747 {
748 	struct port *port;
749 
750 	for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
751 		if (val) {
752 			port->sm_vars |= AD_PORT_READY;
753 		} else {
754 			port->sm_vars &= ~AD_PORT_READY;
755 		}
756 	}
757 }
758 
759 /**
760  * __get_agg_bandwidth - get the total bandwidth of an aggregator
761  * @aggregator: the aggregator we're looking at
762  *
763  */
764 static u32 __get_agg_bandwidth(struct aggregator *aggregator)
765 {
766 	u32 bandwidth=0;
767 	u32 basic_speed;
768 
769 	if (aggregator->num_of_ports) {
770 		basic_speed = __get_link_speed(aggregator->lag_ports);
771 		switch (basic_speed) {
772 		case AD_LINK_SPEED_BITMASK_1MBPS:
773 			bandwidth = aggregator->num_of_ports;
774 			break;
775 		case AD_LINK_SPEED_BITMASK_10MBPS:
776 			bandwidth = aggregator->num_of_ports * 10;
777 			break;
778 		case AD_LINK_SPEED_BITMASK_100MBPS:
779 			bandwidth = aggregator->num_of_ports * 100;
780 			break;
781 		case AD_LINK_SPEED_BITMASK_1000MBPS:
782 			bandwidth = aggregator->num_of_ports * 1000;
783 			break;
784 		case AD_LINK_SPEED_BITMASK_10000MBPS:
785 			bandwidth = aggregator->num_of_ports * 10000;
786 			break;
787 		default:
788 			bandwidth=0; // to silent the compilor ....
789 		}
790 	}
791 	return bandwidth;
792 }
793 
794 /**
795  * __get_active_agg - get the current active aggregator
796  * @aggregator: the aggregator we're looking at
797  *
798  */
799 static struct aggregator *__get_active_agg(struct aggregator *aggregator)
800 {
801 	struct aggregator *retval = NULL;
802 
803 	for (; aggregator; aggregator = __get_next_agg(aggregator)) {
804 		if (aggregator->is_active) {
805 			retval = aggregator;
806 			break;
807 		}
808 	}
809 
810 	return retval;
811 }
812 
813 /**
814  * __update_lacpdu_from_port - update a port's lacpdu fields
815  * @port: the port we're looking at
816  *
817  */
818 static inline void __update_lacpdu_from_port(struct port *port)
819 {
820 	struct lacpdu *lacpdu = &port->lacpdu;
821 
822 	/* update current actual Actor parameters */
823 	/* lacpdu->subtype                   initialized
824 	 * lacpdu->version_number            initialized
825 	 * lacpdu->tlv_type_actor_info       initialized
826 	 * lacpdu->actor_information_length  initialized
827 	 */
828 
829 	lacpdu->actor_system_priority = port->actor_system_priority;
830 	lacpdu->actor_system = port->actor_system;
831 	lacpdu->actor_key = port->actor_oper_port_key;
832 	lacpdu->actor_port_priority = port->actor_port_priority;
833 	lacpdu->actor_port = port->actor_port_number;
834 	lacpdu->actor_state = port->actor_oper_port_state;
835 
836 	/* lacpdu->reserved_3_1              initialized
837 	 * lacpdu->tlv_type_partner_info     initialized
838 	 * lacpdu->partner_information_length initialized
839 	 */
840 
841 	lacpdu->partner_system_priority = port->partner_oper_system_priority;
842 	lacpdu->partner_system = port->partner_oper_system;
843 	lacpdu->partner_key = port->partner_oper_key;
844 	lacpdu->partner_port_priority = port->partner_oper_port_priority;
845 	lacpdu->partner_port = port->partner_oper_port_number;
846 	lacpdu->partner_state = port->partner_oper_port_state;
847 
848 	/* lacpdu->reserved_3_2              initialized
849 	 * lacpdu->tlv_type_collector_info   initialized
850 	 * lacpdu->collector_information_length initialized
851 	 * collector_max_delay                initialized
852 	 * reserved_12[12]                   initialized
853 	 * tlv_type_terminator               initialized
854 	 * terminator_length                 initialized
855 	 * reserved_50[50]                   initialized
856 	 */
857 
858 	/* Convert all non u8 parameters to Big Endian for transmit */
859 	__htons_lacpdu(lacpdu);
860 }
861 
862 //////////////////////////////////////////////////////////////////////////////////////
863 // ================= main 802.3ad protocol code ======================================
864 //////////////////////////////////////////////////////////////////////////////////////
865 
866 /**
867  * ad_lacpdu_send - send out a lacpdu packet on a given port
868  * @port: the port we're looking at
869  *
870  * Returns:   0 on success
871  *          < 0 on error
872  */
873 static int ad_lacpdu_send(struct port *port)
874 {
875 	struct slave *slave = port->slave;
876 	struct sk_buff *skb;
877 	struct lacpdu_header *lacpdu_header;
878 	int length = sizeof(struct lacpdu_header);
879 	struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;
880 
881 	skb = dev_alloc_skb(length);
882 	if (!skb) {
883 		return -ENOMEM;
884 	}
885 
886 	skb->dev = slave->dev;
887 	skb->mac.raw = skb->data;
888 	skb->nh.raw = skb->data + ETH_HLEN;
889 	skb->protocol = PKT_TYPE_LACPDU;
890 	skb->priority = TC_PRIO_CONTROL;
891 
892 	lacpdu_header = (struct lacpdu_header *)skb_put(skb, length);
893 
894 	lacpdu_header->ad_header.destination_address = lacpdu_multicast_address;
895 	/* Note: source addres is set to be the member's PERMANENT address, because we use it
896 	   to identify loopback lacpdus in receive. */
897 	lacpdu_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr));
898 	lacpdu_header->ad_header.length_type = PKT_TYPE_LACPDU;
899 
900 	lacpdu_header->lacpdu = port->lacpdu; // struct copy
901 
902 	dev_queue_xmit(skb);
903 
904 	return 0;
905 }
906 
907 /**
908  * ad_marker_send - send marker information/response on a given port
909  * @port: the port we're looking at
910  * @marker: marker data to send
911  *
912  * Returns:   0 on success
913  *          < 0 on error
914  */
915 static int ad_marker_send(struct port *port, struct marker *marker)
916 {
917 	struct slave *slave = port->slave;
918 	struct sk_buff *skb;
919 	struct marker_header *marker_header;
920 	int length = sizeof(struct marker_header);
921 	struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;
922 
923 	skb = dev_alloc_skb(length + 16);
924 	if (!skb) {
925 		return -ENOMEM;
926 	}
927 
928 	skb_reserve(skb, 16);
929 
930 	skb->dev = slave->dev;
931 	skb->mac.raw = skb->data;
932 	skb->nh.raw = skb->data + ETH_HLEN;
933 	skb->protocol = PKT_TYPE_LACPDU;
934 
935 	marker_header = (struct marker_header *)skb_put(skb, length);
936 
937 	marker_header->ad_header.destination_address = lacpdu_multicast_address;
938 	/* Note: source addres is set to be the member's PERMANENT address, because we use it
939 	   to identify loopback MARKERs in receive. */
940 	marker_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr));
941 	marker_header->ad_header.length_type = PKT_TYPE_LACPDU;
942 
943 	marker_header->marker = *marker; // struct copy
944 
945 	dev_queue_xmit(skb);
946 
947 	return 0;
948 }
949 
950 /**
951  * ad_mux_machine - handle a port's mux state machine
952  * @port: the port we're looking at
953  *
954  */
955 static void ad_mux_machine(struct port *port)
956 {
957 	mux_states_t last_state;
958 
959 	// keep current State Machine state to compare later if it was changed
960 	last_state = port->sm_mux_state;
961 
962 	if (port->sm_vars & AD_PORT_BEGIN) {
963 		port->sm_mux_state = AD_MUX_DETACHED;		 // next state
964 	} else {
965 		switch (port->sm_mux_state) {
966 		case AD_MUX_DETACHED:
967 			if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY
968 				port->sm_mux_state = AD_MUX_WAITING; // next state
969 			}
970 			break;
971 		case AD_MUX_WAITING:
972 			// if SELECTED == FALSE return to DETACH state
973 			if (!(port->sm_vars & AD_PORT_SELECTED)) { // if UNSELECTED
974 				port->sm_vars &= ~AD_PORT_READY_N;
975 				// in order to withhold the Selection Logic to check all ports READY_N value
976 				// every callback cycle to update ready variable, we check READY_N and update READY here
977 				__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
978 				port->sm_mux_state = AD_MUX_DETACHED;	 // next state
979 				break;
980 			}
981 
982 			// check if the wait_while_timer expired
983 			if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) {
984 				port->sm_vars |= AD_PORT_READY_N;
985 			}
986 
987 			// in order to withhold the selection logic to check all ports READY_N value
988 			// every callback cycle to update ready variable, we check READY_N and update READY here
989 			__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
990 
991 			// if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state
992 			if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) {
993 				port->sm_mux_state = AD_MUX_ATTACHED;	 // next state
994 			}
995 			break;
996 		case AD_MUX_ATTACHED:
997 			// check also if agg_select_timer expired(so the edable port will take place only after this timer)
998 			if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) {
999 				port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state
1000 			} else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) {	  // if UNSELECTED or STANDBY
1001 				port->sm_vars &= ~AD_PORT_READY_N;
1002 				// in order to withhold the selection logic to check all ports READY_N value
1003 				// every callback cycle to update ready variable, we check READY_N and update READY here
1004 				__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
1005 				port->sm_mux_state = AD_MUX_DETACHED;// next state
1006 			}
1007 			break;
1008 		case AD_MUX_COLLECTING_DISTRIBUTING:
1009 			if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) ||
1010 			    !(port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION)
1011 			   ) {
1012 				port->sm_mux_state = AD_MUX_ATTACHED;// next state
1013 
1014 			} else {
1015 				// if port state hasn't changed make
1016 				// sure that a collecting distributing
1017 				// port in an active aggregator is enabled
1018 				if (port->aggregator &&
1019 				    port->aggregator->is_active &&
1020 				    !__port_is_enabled(port)) {
1021 
1022 					__enable_port(port);
1023 				}
1024 			}
1025 			break;
1026 		default:    //to silence the compiler
1027 			break;
1028 		}
1029 	}
1030 
1031 	// check if the state machine was changed
1032 	if (port->sm_mux_state != last_state) {
1033 		dprintk("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state);
1034 		switch (port->sm_mux_state) {
1035 		case AD_MUX_DETACHED:
1036 			__detach_bond_from_agg(port);
1037 			port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;
1038 			ad_disable_collecting_distributing(port);
1039 			port->actor_oper_port_state &= ~AD_STATE_COLLECTING;
1040 			port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING;
1041 			port->ntt = 1;
1042 			break;
1043 		case AD_MUX_WAITING:
1044 			port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0);
1045 			break;
1046 		case AD_MUX_ATTACHED:
1047 			__attach_bond_to_agg(port);
1048 			port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION;
1049 			port->actor_oper_port_state &= ~AD_STATE_COLLECTING;
1050 			port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING;
1051 			ad_disable_collecting_distributing(port);
1052 			port->ntt = 1;
1053 			break;
1054 		case AD_MUX_COLLECTING_DISTRIBUTING:
1055 			port->actor_oper_port_state |= AD_STATE_COLLECTING;
1056 			port->actor_oper_port_state |= AD_STATE_DISTRIBUTING;
1057 			ad_enable_collecting_distributing(port);
1058 			port->ntt = 1;
1059 			break;
1060 		default:    //to silence the compiler
1061 			break;
1062 		}
1063 	}
1064 }
1065 
1066 /**
1067  * ad_rx_machine - handle a port's rx State Machine
1068  * @lacpdu: the lacpdu we've received
1069  * @port: the port we're looking at
1070  *
1071  * If lacpdu arrived, stop previous timer (if exists) and set the next state as
1072  * CURRENT. If timer expired set the state machine in the proper state.
1073  * In other cases, this function checks if we need to switch to other state.
1074  */
1075 static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
1076 {
1077 	rx_states_t last_state;
1078 
1079 	// Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback)
1080 	__get_rx_machine_lock(port);
1081 
1082 	// keep current State Machine state to compare later if it was changed
1083 	last_state = port->sm_rx_state;
1084 
1085 	// check if state machine should change state
1086 	// first, check if port was reinitialized
1087 	if (port->sm_vars & AD_PORT_BEGIN) {
1088 		port->sm_rx_state = AD_RX_INITIALIZE;		    // next state
1089 	}
1090 	// check if port is not enabled
1091 	else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) {
1092 		port->sm_rx_state = AD_RX_PORT_DISABLED;	    // next state
1093 	}
1094 	// check if new lacpdu arrived
1095 	else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) {
1096 		port->sm_rx_timer_counter = 0; // zero timer
1097 		port->sm_rx_state = AD_RX_CURRENT;
1098 	} else {
1099 		// if timer is on, and if it is expired
1100 		if (port->sm_rx_timer_counter && !(--port->sm_rx_timer_counter)) {
1101 			switch (port->sm_rx_state) {
1102 			case AD_RX_EXPIRED:
1103 				port->sm_rx_state = AD_RX_DEFAULTED;		// next state
1104 				break;
1105 			case AD_RX_CURRENT:
1106 				port->sm_rx_state = AD_RX_EXPIRED;	    // next state
1107 				break;
1108 			default:    //to silence the compiler
1109 				break;
1110 			}
1111 		} else {
1112 			// if no lacpdu arrived and no timer is on
1113 			switch (port->sm_rx_state) {
1114 			case AD_RX_PORT_DISABLED:
1115 				if (port->sm_vars & AD_PORT_MOVED) {
1116 					port->sm_rx_state = AD_RX_INITIALIZE;	    // next state
1117 				} else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) {
1118 					port->sm_rx_state = AD_RX_EXPIRED;	// next state
1119 				} else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) {
1120 					port->sm_rx_state = AD_RX_LACP_DISABLED;    // next state
1121 				}
1122 				break;
1123 			default:    //to silence the compiler
1124 				break;
1125 
1126 			}
1127 		}
1128 	}
1129 
1130 	// check if the State machine was changed or new lacpdu arrived
1131 	if ((port->sm_rx_state != last_state) || (lacpdu)) {
1132 		dprintk("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_rx_state);
1133 		switch (port->sm_rx_state) {
1134 		case AD_RX_INITIALIZE:
1135 			if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
1136 				port->sm_vars &= ~AD_PORT_LACP_ENABLED;
1137 			} else {
1138 				port->sm_vars |= AD_PORT_LACP_ENABLED;
1139 			}
1140 			port->sm_vars &= ~AD_PORT_SELECTED;
1141 			__record_default(port);
1142 			port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
1143 			port->sm_vars &= ~AD_PORT_MOVED;
1144 			port->sm_rx_state = AD_RX_PORT_DISABLED;	// next state
1145 
1146 			/*- Fall Through -*/
1147 
1148 		case AD_RX_PORT_DISABLED:
1149 			port->sm_vars &= ~AD_PORT_MATCHED;
1150 			break;
1151 		case AD_RX_LACP_DISABLED:
1152 			port->sm_vars &= ~AD_PORT_SELECTED;
1153 			__record_default(port);
1154 			port->partner_oper_port_state &= ~AD_STATE_AGGREGATION;
1155 			port->sm_vars |= AD_PORT_MATCHED;
1156 			port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
1157 			break;
1158 		case AD_RX_EXPIRED:
1159 			//Reset of the Synchronization flag. (Standard 43.4.12)
1160 			//This reset cause to disable this port in the COLLECTING_DISTRIBUTING state of the
1161 			//mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port.
1162 			port->partner_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;
1163 			port->sm_vars &= ~AD_PORT_MATCHED;
1164 			port->partner_oper_port_state |= AD_SHORT_TIMEOUT;
1165 			port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT));
1166 			port->actor_oper_port_state |= AD_STATE_EXPIRED;
1167 			break;
1168 		case AD_RX_DEFAULTED:
1169 			__update_default_selected(port);
1170 			__record_default(port);
1171 			port->sm_vars |= AD_PORT_MATCHED;
1172 			port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
1173 			break;
1174 		case AD_RX_CURRENT:
1175 			// detect loopback situation
1176 			if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
1177 				// INFO_RECEIVED_LOOPBACK_FRAMES
1178 				printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
1179 				       "adapter (%s). Check the configuration to verify that all "
1180 				       "Adapters are connected to 802.3ad compliant switch ports\n",
1181 				       port->slave->dev->master->name, port->slave->dev->name);
1182 				__release_rx_machine_lock(port);
1183 				return;
1184 			}
1185 			__update_selected(lacpdu, port);
1186 			__update_ntt(lacpdu, port);
1187 			__record_pdu(lacpdu, port);
1188 			__choose_matched(lacpdu, port);
1189 			port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT));
1190 			port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
1191 			// verify that if the aggregator is enabled, the port is enabled too.
1192 			//(because if the link goes down for a short time, the 802.3ad will not
1193 			// catch it, and the port will continue to be disabled)
1194 			if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) {
1195 				__enable_port(port);
1196 			}
1197 			break;
1198 		default:    //to silence the compiler
1199 			break;
1200 		}
1201 	}
1202 	__release_rx_machine_lock(port);
1203 }
1204 
1205 /**
1206  * ad_tx_machine - handle a port's tx state machine
1207  * @port: the port we're looking at
1208  *
1209  */
1210 static void ad_tx_machine(struct port *port)
1211 {
1212 	// check if tx timer expired, to verify that we do not send more than 3 packets per second
1213 	if (port->sm_tx_timer_counter && !(--port->sm_tx_timer_counter)) {
1214 		// check if there is something to send
1215 		if (port->ntt && (port->sm_vars & AD_PORT_LACP_ENABLED)) {
1216 			__update_lacpdu_from_port(port);
1217 			// send the lacpdu
1218 			if (ad_lacpdu_send(port) >= 0) {
1219 				dprintk("Sent LACPDU on port %d\n", port->actor_port_number);
1220 				// mark ntt as false, so it will not be sent again until demanded
1221 				port->ntt = 0;
1222 			}
1223 		}
1224 		// restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND
1225 		port->sm_tx_timer_counter=ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
1226 	}
1227 }
1228 
1229 /**
1230  * ad_periodic_machine - handle a port's periodic state machine
1231  * @port: the port we're looking at
1232  *
1233  * Turn ntt flag on priodically to perform periodic transmission of lacpdu's.
1234  */
1235 static void ad_periodic_machine(struct port *port)
1236 {
1237 	periodic_states_t last_state;
1238 
1239 	// keep current state machine state to compare later if it was changed
1240 	last_state = port->sm_periodic_state;
1241 
1242 	// check if port was reinitialized
1243 	if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) ||
1244 	    (!(port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY) && !(port->partner_oper_port_state & AD_STATE_LACP_ACTIVITY))
1245 	   ) {
1246 		port->sm_periodic_state = AD_NO_PERIODIC;	     // next state
1247 	}
1248 	// check if state machine should change state
1249 	else if (port->sm_periodic_timer_counter) {
1250 		// check if periodic state machine expired
1251 		if (!(--port->sm_periodic_timer_counter)) {
1252 			// if expired then do tx
1253 			port->sm_periodic_state = AD_PERIODIC_TX;    // next state
1254 		} else {
1255 			// If not expired, check if there is some new timeout parameter from the partner state
1256 			switch (port->sm_periodic_state) {
1257 			case AD_FAST_PERIODIC:
1258 				if (!(port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) {
1259 					port->sm_periodic_state = AD_SLOW_PERIODIC;  // next state
1260 				}
1261 				break;
1262 			case AD_SLOW_PERIODIC:
1263 				if ((port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) {
1264 					// stop current timer
1265 					port->sm_periodic_timer_counter = 0;
1266 					port->sm_periodic_state = AD_PERIODIC_TX;	 // next state
1267 				}
1268 				break;
1269 			default:    //to silence the compiler
1270 				break;
1271 			}
1272 		}
1273 	} else {
1274 		switch (port->sm_periodic_state) {
1275 		case AD_NO_PERIODIC:
1276 			port->sm_periodic_state = AD_FAST_PERIODIC;	 // next state
1277 			break;
1278 		case AD_PERIODIC_TX:
1279 			if (!(port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) {
1280 				port->sm_periodic_state = AD_SLOW_PERIODIC;  // next state
1281 			} else {
1282 				port->sm_periodic_state = AD_FAST_PERIODIC;  // next state
1283 			}
1284 			break;
1285 		default:    //to silence the compiler
1286 			break;
1287 		}
1288 	}
1289 
1290 	// check if the state machine was changed
1291 	if (port->sm_periodic_state != last_state) {
1292 		dprintk("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state);
1293 		switch (port->sm_periodic_state) {
1294 		case AD_NO_PERIODIC:
1295 			port->sm_periodic_timer_counter = 0;	   // zero timer
1296 			break;
1297 		case AD_FAST_PERIODIC:
1298 			port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_FAST_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle
1299 			break;
1300 		case AD_SLOW_PERIODIC:
1301 			port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_SLOW_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle
1302 			break;
1303 		case AD_PERIODIC_TX:
1304 			port->ntt = 1;
1305 			break;
1306 		default:    //to silence the compiler
1307 			break;
1308 		}
1309 	}
1310 }
1311 
1312 /**
1313  * ad_port_selection_logic - select aggregation groups
1314  * @port: the port we're looking at
1315  *
1316  * Select aggregation groups, and assign each port for it's aggregetor. The
1317  * selection logic is called in the inititalization (after all the handshkes),
1318  * and after every lacpdu receive (if selected is off).
1319  */
1320 static void ad_port_selection_logic(struct port *port)
1321 {
1322 	struct aggregator *aggregator, *free_aggregator = NULL, *temp_aggregator;
1323 	struct port *last_port = NULL, *curr_port;
1324 	int found = 0;
1325 
1326 	// if the port is already Selected, do nothing
1327 	if (port->sm_vars & AD_PORT_SELECTED) {
1328 		return;
1329 	}
1330 
1331 	// if the port is connected to other aggregator, detach it
1332 	if (port->aggregator) {
1333 		// detach the port from its former aggregator
1334 		temp_aggregator=port->aggregator;
1335 		for (curr_port=temp_aggregator->lag_ports; curr_port; last_port=curr_port, curr_port=curr_port->next_port_in_aggregator) {
1336 			if (curr_port == port) {
1337 				temp_aggregator->num_of_ports--;
1338 				if (!last_port) {// if it is the first port attached to the aggregator
1339 					temp_aggregator->lag_ports=port->next_port_in_aggregator;
1340 				} else {// not the first port attached to the aggregator
1341 					last_port->next_port_in_aggregator=port->next_port_in_aggregator;
1342 				}
1343 
1344 				// clear the port's relations to this aggregator
1345 				port->aggregator = NULL;
1346 				port->next_port_in_aggregator=NULL;
1347 				port->actor_port_aggregator_identifier=0;
1348 
1349 				dprintk("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier);
1350 				// if the aggregator is empty, clear its parameters, and set it ready to be attached
1351 				if (!temp_aggregator->lag_ports) {
1352 					ad_clear_agg(temp_aggregator);
1353 				}
1354 				break;
1355 			}
1356 		}
1357 		if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
1358 			printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
1359 			       "related to aggregator %d but was not on its port list\n",
1360 			       port->slave->dev->master->name,
1361 			       port->actor_port_number, port->slave->dev->name,
1362 			       port->aggregator->aggregator_identifier);
1363 		}
1364 	}
1365 	// search on all aggregators for a suitable aggregator for this port
1366 	for (aggregator = __get_first_agg(port); aggregator;
1367 	     aggregator = __get_next_agg(aggregator)) {
1368 
1369 		// keep a free aggregator for later use(if needed)
1370 		if (!aggregator->lag_ports) {
1371 			if (!free_aggregator) {
1372 				free_aggregator=aggregator;
1373 			}
1374 			continue;
1375 		}
1376 		// check if current aggregator suits us
1377 		if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) && // if all parameters match AND
1378 		     !MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(port->partner_oper_system)) &&
1379 		     (aggregator->partner_system_priority == port->partner_oper_system_priority) &&
1380 		     (aggregator->partner_oper_aggregator_key == port->partner_oper_key)
1381 		    ) &&
1382 		    ((MAC_ADDRESS_COMPARE(&(port->partner_oper_system), &(null_mac_addr)) && // partner answers
1383 		      !aggregator->is_individual)  // but is not individual OR
1384 		    )
1385 		   ) {
1386 			// attach to the founded aggregator
1387 			port->aggregator = aggregator;
1388 			port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier;
1389 			port->next_port_in_aggregator=aggregator->lag_ports;
1390 			port->aggregator->num_of_ports++;
1391 			aggregator->lag_ports=port;
1392 			dprintk("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
1393 
1394 			// mark this port as selected
1395 			port->sm_vars |= AD_PORT_SELECTED;
1396 			found = 1;
1397 			break;
1398 		}
1399 	}
1400 
1401 	// the port couldn't find an aggregator - attach it to a new aggregator
1402 	if (!found) {
1403 		if (free_aggregator) {
1404 			// assign port a new aggregator
1405 			port->aggregator = free_aggregator;
1406 			port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier;
1407 
1408 			// update the new aggregator's parameters
1409 			// if port was responsed from the end-user
1410 			if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) {// if port is full duplex
1411 				port->aggregator->is_individual = 0;
1412 			} else {
1413 				port->aggregator->is_individual = 1;
1414 			}
1415 
1416 			port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key;
1417 			port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key;
1418 			port->aggregator->partner_system=port->partner_oper_system;
1419 			port->aggregator->partner_system_priority = port->partner_oper_system_priority;
1420 			port->aggregator->partner_oper_aggregator_key = port->partner_oper_key;
1421 			port->aggregator->receive_state = 1;
1422 			port->aggregator->transmit_state = 1;
1423 			port->aggregator->lag_ports = port;
1424 			port->aggregator->num_of_ports++;
1425 
1426 			// mark this port as selected
1427 			port->sm_vars |= AD_PORT_SELECTED;
1428 
1429 			dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
1430 		} else {
1431 			printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
1432 			       port->slave->dev->master->name,
1433 			       port->actor_port_number, port->slave->dev->name);
1434 		}
1435 	}
1436 	// if all aggregator's ports are READY_N == TRUE, set ready=TRUE in all aggregator's ports
1437 	// else set ready=FALSE in all aggregator's ports
1438 	__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
1439 
1440 	if (!__check_agg_selection_timer(port) && (aggregator = __get_first_agg(port))) {
1441 		ad_agg_selection_logic(aggregator);
1442 	}
1443 }
1444 
1445 /**
1446  * ad_agg_selection_logic - select an aggregation group for a team
1447  * @aggregator: the aggregator we're looking at
1448  *
1449  * It is assumed that only one aggregator may be selected for a team.
1450  * The logic of this function is to select (at first time) the aggregator with
1451  * the most ports attached to it, and to reselect the active aggregator only if
1452  * the previous aggregator has no more ports related to it.
1453  *
1454  * FIXME: this function MUST be called with the first agg in the bond, or
1455  * __get_active_agg() won't work correctly. This function should be better
1456  * called with the bond itself, and retrieve the first agg from it.
1457  */
1458 static void ad_agg_selection_logic(struct aggregator *aggregator)
1459 {
1460 	struct aggregator *best_aggregator = NULL, *active_aggregator = NULL;
1461 	struct aggregator *last_active_aggregator = NULL, *origin_aggregator;
1462 	struct port *port;
1463 	u16 num_of_aggs=0;
1464 
1465 	origin_aggregator = aggregator;
1466 
1467 	//get current active aggregator
1468 	last_active_aggregator = __get_active_agg(aggregator);
1469 
1470 	// search for the aggregator with the most ports attached to it.
1471 	do {
1472 		// count how many candidate lag's we have
1473 		if (aggregator->lag_ports) {
1474 			num_of_aggs++;
1475 		}
1476 		if (aggregator->is_active && !aggregator->is_individual &&   // if current aggregator is the active aggregator
1477 		    MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr))) {   // and partner answers to 802.3ad PDUs
1478 			if (aggregator->num_of_ports) {	// if any ports attached to the current aggregator
1479 				best_aggregator=NULL;	 // disregard the best aggregator that was chosen by now
1480 				break;		 // stop the selection of other aggregator if there are any ports attached to this active aggregator
1481 			} else { // no ports attached to this active aggregator
1482 				aggregator->is_active = 0; // mark this aggregator as not active anymore
1483 			}
1484 		}
1485 		if (aggregator->num_of_ports) {	// if any ports attached
1486 			if (best_aggregator) {	// if there is a candidte aggregator
1487 				//The reasons for choosing new best aggregator:
1488 				// 1. if current agg is NOT individual and the best agg chosen so far is individual OR
1489 				// current and best aggs are both individual or both not individual, AND
1490 				// 2a.  current agg partner reply but best agg partner do not reply OR
1491 				// 2b.  current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply AND
1492 				//      current has more ports/bandwidth, or same amount of ports but current has faster ports, THEN
1493 				//      current agg become best agg so far
1494 
1495 				//if current agg is NOT individual and the best agg chosen so far is individual change best_aggregator
1496 				if (!aggregator->is_individual && best_aggregator->is_individual) {
1497 					best_aggregator=aggregator;
1498 				}
1499 				// current and best aggs are both individual or both not individual
1500 				else if ((aggregator->is_individual && best_aggregator->is_individual) ||
1501 					 (!aggregator->is_individual && !best_aggregator->is_individual)) {
1502 					//  current and best aggs are both individual or both not individual AND
1503 					//  current agg partner reply but best agg partner do not reply
1504 					if ((MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) &&
1505 					     !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) {
1506 						best_aggregator=aggregator;
1507 					}
1508 					//  current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply
1509 					else if (! (!MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) &&
1510 						    MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) {
1511 						if ((__get_agg_selection_mode(aggregator->lag_ports) == AD_BANDWIDTH)&&
1512 						    (__get_agg_bandwidth(aggregator) > __get_agg_bandwidth(best_aggregator))) {
1513 							best_aggregator=aggregator;
1514 						} else if (__get_agg_selection_mode(aggregator->lag_ports) == AD_COUNT) {
1515 							if (((aggregator->num_of_ports > best_aggregator->num_of_ports) &&
1516 							     (aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS))||
1517 							    ((aggregator->num_of_ports == best_aggregator->num_of_ports) &&
1518 							     ((u16)(aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS) >
1519 							      (u16)(best_aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS)))) {
1520 								best_aggregator=aggregator;
1521 							}
1522 						}
1523 					}
1524 				}
1525 			} else {
1526 				best_aggregator=aggregator;
1527 			}
1528 		}
1529 		aggregator->is_active = 0; // mark all aggregators as not active anymore
1530 	} while ((aggregator = __get_next_agg(aggregator)));
1531 
1532 	// if we have new aggregator selected, don't replace the old aggregator if it has an answering partner,
1533 	// or if both old aggregator and new aggregator don't have answering partner
1534 	if (best_aggregator) {
1535 		if (last_active_aggregator && last_active_aggregator->lag_ports && last_active_aggregator->lag_ports->is_enabled &&
1536 		    (MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) ||   // partner answers OR
1537 		     (!MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) &&	// both old and new
1538 		      !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr))))     // partner do not answer
1539 		   ) {
1540 			// if new aggregator has link, and old aggregator does not, replace old aggregator.(do nothing)
1541 			// -> don't replace otherwise.
1542 			if (!(!last_active_aggregator->actor_oper_aggregator_key && best_aggregator->actor_oper_aggregator_key)) {
1543 				best_aggregator=NULL;
1544 				last_active_aggregator->is_active = 1; // don't replace good old aggregator
1545 
1546 			}
1547 		}
1548 	}
1549 
1550 	// if there is new best aggregator, activate it
1551 	if (best_aggregator) {
1552 		for (aggregator = __get_first_agg(best_aggregator->lag_ports);
1553 		    aggregator;
1554 		    aggregator = __get_next_agg(aggregator)) {
1555 
1556 			dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
1557 					aggregator->aggregator_identifier, aggregator->num_of_ports,
1558 					aggregator->actor_oper_aggregator_key, aggregator->partner_oper_aggregator_key,
1559 					aggregator->is_individual, aggregator->is_active);
1560 		}
1561 
1562 		// check if any partner replys
1563 		if (best_aggregator->is_individual) {
1564 			printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
1565 			       "the link partner for any adapters in the bond\n",
1566 			       best_aggregator->slave->dev->master->name);
1567 		}
1568 
1569 		// check if there are more than one aggregator
1570 		if (num_of_aggs > 1) {
1571 			dprintk("Warning: More than one Link Aggregation Group was "
1572 				"found in the bond. Only one group will function in the bond\n");
1573 		}
1574 
1575 		best_aggregator->is_active = 1;
1576 		dprintk("LAG %d choosed as the active LAG\n", best_aggregator->aggregator_identifier);
1577 		dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
1578 				best_aggregator->aggregator_identifier, best_aggregator->num_of_ports,
1579 				best_aggregator->actor_oper_aggregator_key, best_aggregator->partner_oper_aggregator_key,
1580 				best_aggregator->is_individual, best_aggregator->is_active);
1581 
1582 		// disable the ports that were related to the former active_aggregator
1583 		if (last_active_aggregator) {
1584 			for (port=last_active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
1585 				__disable_port(port);
1586 			}
1587 		}
1588 	}
1589 
1590 	// if the selected aggregator is of join individuals(partner_system is NULL), enable their ports
1591 	active_aggregator = __get_active_agg(origin_aggregator);
1592 
1593 	if (active_aggregator) {
1594 		if (!MAC_ADDRESS_COMPARE(&(active_aggregator->partner_system), &(null_mac_addr))) {
1595 			for (port=active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
1596 				__enable_port(port);
1597 			}
1598 		}
1599 	}
1600 }
1601 
1602 /**
1603  * ad_clear_agg - clear a given aggregator's parameters
1604  * @aggregator: the aggregator we're looking at
1605  *
1606  */
1607 static void ad_clear_agg(struct aggregator *aggregator)
1608 {
1609 	if (aggregator) {
1610 		aggregator->is_individual = 0;
1611 		aggregator->actor_admin_aggregator_key = 0;
1612 		aggregator->actor_oper_aggregator_key = 0;
1613 		aggregator->partner_system = null_mac_addr;
1614 		aggregator->partner_system_priority = 0;
1615 		aggregator->partner_oper_aggregator_key = 0;
1616 		aggregator->receive_state = 0;
1617 		aggregator->transmit_state = 0;
1618 		aggregator->lag_ports = NULL;
1619 		aggregator->is_active = 0;
1620 		aggregator->num_of_ports = 0;
1621 		dprintk("LAG %d was cleared\n", aggregator->aggregator_identifier);
1622 	}
1623 }
1624 
1625 /**
1626  * ad_initialize_agg - initialize a given aggregator's parameters
1627  * @aggregator: the aggregator we're looking at
1628  *
1629  */
1630 static void ad_initialize_agg(struct aggregator *aggregator)
1631 {
1632 	if (aggregator) {
1633 		ad_clear_agg(aggregator);
1634 
1635 		aggregator->aggregator_mac_address = null_mac_addr;
1636 		aggregator->aggregator_identifier = 0;
1637 		aggregator->slave = NULL;
1638 	}
1639 }
1640 
1641 /**
1642  * ad_initialize_port - initialize a given port's parameters
1643  * @aggregator: the aggregator we're looking at
1644  * @lacp_fast: boolean. whether fast periodic should be used
1645  *
1646  */
1647 static void ad_initialize_port(struct port *port, int lacp_fast)
1648 {
1649 	if (port) {
1650 		port->actor_port_number = 1;
1651 		port->actor_port_priority = 0xff;
1652 		port->actor_system = null_mac_addr;
1653 		port->actor_system_priority = 0xffff;
1654 		port->actor_port_aggregator_identifier = 0;
1655 		port->ntt = 0;
1656 		port->actor_admin_port_key = 1;
1657 		port->actor_oper_port_key  = 1;
1658 		port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
1659 		port->actor_oper_port_state  = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
1660 
1661 		if (lacp_fast) {
1662 			port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
1663 		}
1664 
1665 		port->partner_admin_system = null_mac_addr;
1666 		port->partner_oper_system  = null_mac_addr;
1667 		port->partner_admin_system_priority = 0xffff;
1668 		port->partner_oper_system_priority  = 0xffff;
1669 		port->partner_admin_key = 1;
1670 		port->partner_oper_key  = 1;
1671 		port->partner_admin_port_number = 1;
1672 		port->partner_oper_port_number  = 1;
1673 		port->partner_admin_port_priority = 0xff;
1674 		port->partner_oper_port_priority  = 0xff;
1675 		port->partner_admin_port_state = 1;
1676 		port->partner_oper_port_state  = 1;
1677 		port->is_enabled = 1;
1678 		// ****** private parameters ******
1679 		port->sm_vars = 0x3;
1680 		port->sm_rx_state = 0;
1681 		port->sm_rx_timer_counter = 0;
1682 		port->sm_periodic_state = 0;
1683 		port->sm_periodic_timer_counter = 0;
1684 		port->sm_mux_state = 0;
1685 		port->sm_mux_timer_counter = 0;
1686 		port->sm_tx_state = 0;
1687 		port->sm_tx_timer_counter = 0;
1688 		port->slave = NULL;
1689 		port->aggregator = NULL;
1690 		port->next_port_in_aggregator = NULL;
1691 		port->transaction_id = 0;
1692 
1693 		ad_initialize_lacpdu(&(port->lacpdu));
1694 	}
1695 }
1696 
1697 /**
1698  * ad_enable_collecting_distributing - enable a port's transmit/receive
1699  * @port: the port we're looking at
1700  *
1701  * Enable @port if it's in an active aggregator
1702  */
1703 static void ad_enable_collecting_distributing(struct port *port)
1704 {
1705 	if (port->aggregator->is_active) {
1706 		dprintk("Enabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
1707 		__enable_port(port);
1708 	}
1709 }
1710 
1711 /**
1712  * ad_disable_collecting_distributing - disable a port's transmit/receive
1713  * @port: the port we're looking at
1714  *
1715  */
1716 static void ad_disable_collecting_distributing(struct port *port)
1717 {
1718 	if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) {
1719 		dprintk("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
1720 		__disable_port(port);
1721 	}
1722 }
1723 
1724 #if 0
1725 /**
1726  * ad_marker_info_send - send a marker information frame
1727  * @port: the port we're looking at
1728  *
1729  * This function does nothing since we decided not to implement send and handle
1730  * response for marker PDU's, in this stage, but only to respond to marker
1731  * information.
1732  */
1733 static void ad_marker_info_send(struct port *port)
1734 {
1735 	struct marker marker;
1736 	u16 index;
1737 
1738 	// fill the marker PDU with the appropriate values
1739 	marker.subtype = 0x02;
1740 	marker.version_number = 0x01;
1741 	marker.tlv_type = AD_MARKER_INFORMATION_SUBTYPE;
1742 	marker.marker_length = 0x16;
1743 	// convert requester_port to Big Endian
1744 	marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8));
1745 	marker.requester_system = port->actor_system;
1746 	// convert requester_port(u32) to Big Endian
1747 	marker.requester_transaction_id = (((++port->transaction_id & 0xFF) << 24) |((port->transaction_id & 0xFF00) << 8) |((port->transaction_id & 0xFF0000) >> 8) |((port->transaction_id & 0xFF000000) >> 24));
1748 	marker.pad = 0;
1749 	marker.tlv_type_terminator = 0x00;
1750 	marker.terminator_length = 0x00;
1751 	for (index=0; index<90; index++) {
1752 		marker.reserved_90[index]=0;
1753 	}
1754 
1755 	// send the marker information
1756 	if (ad_marker_send(port, &marker) >= 0) {
1757 		dprintk("Sent Marker Information on port %d\n", port->actor_port_number);
1758 	}
1759 }
1760 #endif
1761 
1762 /**
1763  * ad_marker_info_received - handle receive of a Marker information frame
1764  * @marker_info: Marker info received
1765  * @port: the port we're looking at
1766  *
1767  */
1768 static void ad_marker_info_received(struct marker *marker_info,struct port *port)
1769 {
1770 	struct marker marker;
1771 
1772 	// copy the received marker data to the response marker
1773 	//marker = *marker_info;
1774 	memcpy(&marker, marker_info, sizeof(struct marker));
1775 	// change the marker subtype to marker response
1776 	marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE;
1777 	// send the marker response
1778 
1779 	if (ad_marker_send(port, &marker) >= 0) {
1780 		dprintk("Sent Marker Response on port %d\n", port->actor_port_number);
1781 	}
1782 }
1783 
1784 /**
1785  * ad_marker_response_received - handle receive of a marker response frame
1786  * @marker: marker PDU received
1787  * @port: the port we're looking at
1788  *
1789  * This function does nothing since we decided not to implement send and handle
1790  * response for marker PDU's, in this stage, but only to respond to marker
1791  * information.
1792  */
1793 static void ad_marker_response_received(struct marker *marker, struct port *port)
1794 {
1795 	marker=NULL; // just to satisfy the compiler
1796 	port=NULL;  // just to satisfy the compiler
1797 	// DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW
1798 }
1799 
1800 /**
1801  * ad_initialize_lacpdu - initialize a given lacpdu structure
1802  * @lacpdu: lacpdu structure to initialize
1803  *
1804  */
1805 static void ad_initialize_lacpdu(struct lacpdu *lacpdu)
1806 {
1807 	u16 index;
1808 
1809 	// initialize lacpdu data
1810 	lacpdu->subtype = 0x01;
1811 	lacpdu->version_number = 0x01;
1812 	lacpdu->tlv_type_actor_info = 0x01;
1813 	lacpdu->actor_information_length = 0x14;
1814 	// lacpdu->actor_system_priority    updated on send
1815 	// lacpdu->actor_system             updated on send
1816 	// lacpdu->actor_key                updated on send
1817 	// lacpdu->actor_port_priority      updated on send
1818 	// lacpdu->actor_port               updated on send
1819 	// lacpdu->actor_state              updated on send
1820 	lacpdu->tlv_type_partner_info = 0x02;
1821 	lacpdu->partner_information_length = 0x14;
1822 	for (index=0; index<=2; index++) {
1823 		lacpdu->reserved_3_1[index]=0;
1824 	}
1825 	// lacpdu->partner_system_priority  updated on send
1826 	// lacpdu->partner_system           updated on send
1827 	// lacpdu->partner_key              updated on send
1828 	// lacpdu->partner_port_priority    updated on send
1829 	// lacpdu->partner_port             updated on send
1830 	// lacpdu->partner_state            updated on send
1831 	for (index=0; index<=2; index++) {
1832 		lacpdu->reserved_3_2[index]=0;
1833 	}
1834 	lacpdu->tlv_type_collector_info = 0x03;
1835 	lacpdu->collector_information_length= 0x10;
1836 	lacpdu->collector_max_delay = AD_COLLECTOR_MAX_DELAY;
1837 	for (index=0; index<=11; index++) {
1838 		lacpdu->reserved_12[index]=0;
1839 	}
1840 	lacpdu->tlv_type_terminator = 0x00;
1841 	lacpdu->terminator_length = 0;
1842 	for (index=0; index<=49; index++) {
1843 		lacpdu->reserved_50[index]=0;
1844 	}
1845 }
1846 
1847 //////////////////////////////////////////////////////////////////////////////////////
1848 // ================= AD exported functions to the main bonding code ==================
1849 //////////////////////////////////////////////////////////////////////////////////////
1850 
1851 // Check aggregators status in team every T seconds
1852 #define AD_AGGREGATOR_SELECTION_TIMER  8
1853 
1854 static u16 aggregator_identifier;
1855 
1856 /**
1857  * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures
1858  * @bond: bonding struct to work on
1859  * @tick_resolution: tick duration (millisecond resolution)
1860  * @lacp_fast: boolean. whether fast periodic should be used
1861  *
1862  * Can be called only after the mac address of the bond is set.
1863  */
1864 void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
1865 {
1866 	// check that the bond is not initialized yet
1867 	if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
1868 
1869 		aggregator_identifier = 0;
1870 
1871 		BOND_AD_INFO(bond).lacp_fast = lacp_fast;
1872 		BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
1873 		BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
1874 
1875 		// initialize how many times this module is called in one second(should be about every 100ms)
1876 		ad_ticks_per_sec = tick_resolution;
1877 
1878 		// initialize the aggregator selection timer(to activate an aggregation selection after initialize)
1879 		BOND_AD_INFO(bond).agg_select_timer = (AD_AGGREGATOR_SELECTION_TIMER * ad_ticks_per_sec);
1880 		BOND_AD_INFO(bond).agg_select_mode = AD_BANDWIDTH;
1881 	}
1882 }
1883 
1884 /**
1885  * bond_3ad_bind_slave - initialize a slave's port
1886  * @slave: slave struct to work on
1887  *
1888  * Returns:   0 on success
1889  *          < 0 on error
1890  */
1891 int bond_3ad_bind_slave(struct slave *slave)
1892 {
1893 	struct bonding *bond = bond_get_bond_by_slave(slave);
1894 	struct port *port;
1895 	struct aggregator *aggregator;
1896 
1897 	if (bond == NULL) {
1898 		printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
1899 		       slave->dev->master->name, slave->dev->name);
1900 		return -1;
1901 	}
1902 
1903 	//check that the slave has not been intialized yet.
1904 	if (SLAVE_AD_INFO(slave).port.slave != slave) {
1905 
1906 		// port initialization
1907 		port = &(SLAVE_AD_INFO(slave).port);
1908 
1909 		ad_initialize_port(port, BOND_AD_INFO(bond).lacp_fast);
1910 
1911 		port->slave = slave;
1912 		port->actor_port_number = SLAVE_AD_INFO(slave).id;
1913 		// key is determined according to the link speed, duplex and user key(which is yet not supported)
1914 		//              ------------------------------------------------------------
1915 		// Port key :   | User key                       |      Speed       |Duplex|
1916 		//              ------------------------------------------------------------
1917 		//              16                               6               1 0
1918 		port->actor_admin_port_key = 0;	// initialize this parameter
1919 		port->actor_admin_port_key |= __get_duplex(port);
1920 		port->actor_admin_port_key |= (__get_link_speed(port) << 1);
1921 		port->actor_oper_port_key = port->actor_admin_port_key;
1922 		// if the port is not full duplex, then the port should be not lacp Enabled
1923 		if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
1924 			port->sm_vars &= ~AD_PORT_LACP_ENABLED;
1925 		}
1926 		// actor system is the bond's system
1927 		port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
1928 		// tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second)
1929 		port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
1930 		port->aggregator = NULL;
1931 		port->next_port_in_aggregator = NULL;
1932 
1933 		__disable_port(port);
1934 		__initialize_port_locks(port);
1935 
1936 
1937 		// aggregator initialization
1938 		aggregator = &(SLAVE_AD_INFO(slave).aggregator);
1939 
1940 		ad_initialize_agg(aggregator);
1941 
1942 		aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr);
1943 		aggregator->aggregator_identifier = (++aggregator_identifier);
1944 		aggregator->slave = slave;
1945 		aggregator->is_active = 0;
1946 		aggregator->num_of_ports = 0;
1947 	}
1948 
1949 	return 0;
1950 }
1951 
1952 /**
1953  * bond_3ad_unbind_slave - deinitialize a slave's port
1954  * @slave: slave struct to work on
1955  *
1956  * Search for the aggregator that is related to this port, remove the
1957  * aggregator and assign another aggregator for other port related to it
1958  * (if any), and remove the port.
1959  */
1960 void bond_3ad_unbind_slave(struct slave *slave)
1961 {
1962 	struct port *port, *prev_port, *temp_port;
1963 	struct aggregator *aggregator, *new_aggregator, *temp_aggregator;
1964 	int select_new_active_agg = 0;
1965 
1966 	// find the aggregator related to this slave
1967 	aggregator = &(SLAVE_AD_INFO(slave).aggregator);
1968 
1969 	// find the port related to this slave
1970 	port = &(SLAVE_AD_INFO(slave).port);
1971 
1972 	// if slave is null, the whole port is not initialized
1973 	if (!port->slave) {
1974 		printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
1975 		       "unbind an uninitialized port on %s\n",
1976 		       slave->dev->master->name, slave->dev->name);
1977 		return;
1978 	}
1979 
1980 	dprintk("Unbinding Link Aggregation Group %d\n", aggregator->aggregator_identifier);
1981 
1982 	/* Tell the partner that this port is not suitable for aggregation */
1983 	port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
1984 	__update_lacpdu_from_port(port);
1985 	ad_lacpdu_send(port);
1986 
1987 	// check if this aggregator is occupied
1988 	if (aggregator->lag_ports) {
1989 		// check if there are other ports related to this aggregator except
1990 		// the port related to this slave(thats ensure us that there is a
1991 		// reason to search for new aggregator, and that we will find one
1992 		if ((aggregator->lag_ports != port) || (aggregator->lag_ports->next_port_in_aggregator)) {
1993 			// find new aggregator for the related port(s)
1994 			new_aggregator = __get_first_agg(port);
1995 			for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) {
1996 				// if the new aggregator is empty, or it connected to to our port only
1997 				if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) {
1998 					break;
1999 				}
2000 			}
2001 			// if new aggregator found, copy the aggregator's parameters
2002 			// and connect the related lag_ports to the new aggregator
2003 			if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
2004 				dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
2005 
2006 				if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
2007 					printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
2008 					       aggregator->slave->dev->master->name);
2009 					// select new active aggregator
2010 					 select_new_active_agg = 1;
2011 				}
2012 
2013 				new_aggregator->is_individual = aggregator->is_individual;
2014 				new_aggregator->actor_admin_aggregator_key = aggregator->actor_admin_aggregator_key;
2015 				new_aggregator->actor_oper_aggregator_key = aggregator->actor_oper_aggregator_key;
2016 				new_aggregator->partner_system = aggregator->partner_system;
2017 				new_aggregator->partner_system_priority = aggregator->partner_system_priority;
2018 				new_aggregator->partner_oper_aggregator_key = aggregator->partner_oper_aggregator_key;
2019 				new_aggregator->receive_state = aggregator->receive_state;
2020 				new_aggregator->transmit_state = aggregator->transmit_state;
2021 				new_aggregator->lag_ports = aggregator->lag_ports;
2022 				new_aggregator->is_active = aggregator->is_active;
2023 				new_aggregator->num_of_ports = aggregator->num_of_ports;
2024 
2025 				// update the information that is written on the ports about the aggregator
2026 				for (temp_port=aggregator->lag_ports; temp_port; temp_port=temp_port->next_port_in_aggregator) {
2027 					temp_port->aggregator=new_aggregator;
2028 					temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier;
2029 				}
2030 
2031 				// clear the aggregator
2032 				ad_clear_agg(aggregator);
2033 
2034 				if (select_new_active_agg) {
2035 					ad_agg_selection_logic(__get_first_agg(port));
2036 				}
2037 			} else {
2038 				printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
2039 				       "and could not find a new aggregator for its ports\n",
2040 				       slave->dev->master->name);
2041 			}
2042 		} else { // in case that the only port related to this aggregator is the one we want to remove
2043 			select_new_active_agg = aggregator->is_active;
2044 			// clear the aggregator
2045 			ad_clear_agg(aggregator);
2046 			if (select_new_active_agg) {
2047 				printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
2048 				       slave->dev->master->name);
2049 				// select new active aggregator
2050 				ad_agg_selection_logic(__get_first_agg(port));
2051 			}
2052 		}
2053 	}
2054 
2055 	dprintk("Unbinding port %d\n", port->actor_port_number);
2056 	// find the aggregator that this port is connected to
2057 	temp_aggregator = __get_first_agg(port);
2058 	for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) {
2059 		prev_port = NULL;
2060 		// search the port in the aggregator's related ports
2061 		for (temp_port=temp_aggregator->lag_ports; temp_port; prev_port=temp_port, temp_port=temp_port->next_port_in_aggregator) {
2062 			if (temp_port == port) { // the aggregator found - detach the port from this aggregator
2063 				if (prev_port) {
2064 					prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator;
2065 				} else {
2066 					temp_aggregator->lag_ports = temp_port->next_port_in_aggregator;
2067 				}
2068 				temp_aggregator->num_of_ports--;
2069 				if (temp_aggregator->num_of_ports==0) {
2070 					select_new_active_agg = temp_aggregator->is_active;
2071 					// clear the aggregator
2072 					ad_clear_agg(temp_aggregator);
2073 					if (select_new_active_agg) {
2074 						printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
2075 						       slave->dev->master->name);
2076 						// select new active aggregator
2077 						ad_agg_selection_logic(__get_first_agg(port));
2078 					}
2079 				}
2080 				break;
2081 			}
2082 		}
2083 	}
2084 	port->slave=NULL;
2085 }
2086 
2087 /**
2088  * bond_3ad_state_machine_handler - handle state machines timeout
2089  * @bond: bonding struct to work on
2090  *
2091  * The state machine handling concept in this module is to check every tick
2092  * which state machine should operate any function. The execution order is
2093  * round robin, so when we have an interaction between state machines, the
2094  * reply of one to each other might be delayed until next tick.
2095  *
2096  * This function also complete the initialization when the agg_select_timer
2097  * times out, and it selects an aggregator for the ports that are yet not
2098  * related to any aggregator, and selects the active aggregator for a bond.
2099  */
2100 void bond_3ad_state_machine_handler(struct bonding *bond)
2101 {
2102 	struct port *port;
2103 	struct aggregator *aggregator;
2104 
2105 	read_lock(&bond->lock);
2106 
2107 	if (bond->kill_timers) {
2108 		goto out;
2109 	}
2110 
2111 	//check if there are any slaves
2112 	if (bond->slave_cnt == 0) {
2113 		goto re_arm;
2114 	}
2115 
2116 	// check if agg_select_timer timer after initialize is timed out
2117 	if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) {
2118 		// select the active aggregator for the bond
2119 		if ((port = __get_first_port(bond))) {
2120 			if (!port->slave) {
2121 				printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
2122 				       "uninitialized\n", bond->dev->name);
2123 				goto re_arm;
2124 			}
2125 
2126 			aggregator = __get_first_agg(port);
2127 			ad_agg_selection_logic(aggregator);
2128 		}
2129 	}
2130 
2131 	// for each port run the state machines
2132 	for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
2133 		if (!port->slave) {
2134 			printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
2135 			       "port\n", bond->dev->name);
2136 			goto re_arm;
2137 		}
2138 
2139 		ad_rx_machine(NULL, port);
2140 		ad_periodic_machine(port);
2141 		ad_port_selection_logic(port);
2142 		ad_mux_machine(port);
2143 		ad_tx_machine(port);
2144 
2145 		// turn off the BEGIN bit, since we already handled it
2146 		if (port->sm_vars & AD_PORT_BEGIN) {
2147 			port->sm_vars &= ~AD_PORT_BEGIN;
2148 		}
2149 	}
2150 
2151 re_arm:
2152 	mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + ad_delta_in_ticks);
2153 out:
2154 	read_unlock(&bond->lock);
2155 }
2156 
2157 /**
2158  * bond_3ad_rx_indication - handle a received frame
2159  * @lacpdu: received lacpdu
2160  * @slave: slave struct to work on
2161  * @length: length of the data received
2162  *
2163  * It is assumed that frames that were sent on this NIC don't returned as new
2164  * received frames (loopback). Since only the payload is given to this
2165  * function, it check for loopback.
2166  */
2167 static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
2168 {
2169 	struct port *port;
2170 
2171 	if (length >= sizeof(struct lacpdu)) {
2172 
2173 		port = &(SLAVE_AD_INFO(slave).port);
2174 
2175 		if (!port->slave) {
2176 			printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
2177 			       "uninitialized\n", slave->dev->name, slave->dev->master->name);
2178 			return;
2179 		}
2180 
2181 		switch (lacpdu->subtype) {
2182 		case AD_TYPE_LACPDU:
2183 			dprintk("Received LACPDU on port %d\n", port->actor_port_number);
2184 			ad_rx_machine(lacpdu, port);
2185 			break;
2186 
2187 		case AD_TYPE_MARKER:
2188 			// No need to convert fields to Little Endian since we don't use the marker's fields.
2189 
2190 			switch (((struct marker *)lacpdu)->tlv_type) {
2191 			case AD_MARKER_INFORMATION_SUBTYPE:
2192 				dprintk("Received Marker Information on port %d\n", port->actor_port_number);
2193 				ad_marker_info_received((struct marker *)lacpdu, port);
2194 				break;
2195 
2196 			case AD_MARKER_RESPONSE_SUBTYPE:
2197 				dprintk("Received Marker Response on port %d\n", port->actor_port_number);
2198 				ad_marker_response_received((struct marker *)lacpdu, port);
2199 				break;
2200 
2201 			default:
2202 				dprintk("Received an unknown Marker subtype on slot %d\n", port->actor_port_number);
2203 			}
2204 		}
2205 	}
2206 }
2207 
2208 /**
2209  * bond_3ad_adapter_speed_changed - handle a slave's speed change indication
2210  * @slave: slave struct to work on
2211  *
2212  * Handle reselection of aggregator (if needed) for this port.
2213  */
2214 void bond_3ad_adapter_speed_changed(struct slave *slave)
2215 {
2216 	struct port *port;
2217 
2218 	port = &(SLAVE_AD_INFO(slave).port);
2219 
2220 	// if slave is null, the whole port is not initialized
2221 	if (!port->slave) {
2222 		printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
2223 		       "changed for uninitialized port on %s\n",
2224 		       slave->dev->master->name, slave->dev->name);
2225 		return;
2226 	}
2227 
2228 	port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
2229 	port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
2230 	dprintk("Port %d changed speed\n", port->actor_port_number);
2231 	// there is no need to reselect a new aggregator, just signal the
2232 	// state machines to reinitialize
2233 	port->sm_vars |= AD_PORT_BEGIN;
2234 }
2235 
2236 /**
2237  * bond_3ad_adapter_duplex_changed - handle a slave's duplex change indication
2238  * @slave: slave struct to work on
2239  *
2240  * Handle reselection of aggregator (if needed) for this port.
2241  */
2242 void bond_3ad_adapter_duplex_changed(struct slave *slave)
2243 {
2244 	struct port *port;
2245 
2246 	port=&(SLAVE_AD_INFO(slave).port);
2247 
2248 	// if slave is null, the whole port is not initialized
2249 	if (!port->slave) {
2250 		printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
2251 		       "for uninitialized port on %s\n",
2252 		       slave->dev->master->name, slave->dev->name);
2253 		return;
2254 	}
2255 
2256 	port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
2257 	port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
2258 	dprintk("Port %d changed duplex\n", port->actor_port_number);
2259 	// there is no need to reselect a new aggregator, just signal the
2260 	// state machines to reinitialize
2261 	port->sm_vars |= AD_PORT_BEGIN;
2262 }
2263 
2264 /**
2265  * bond_3ad_handle_link_change - handle a slave's link status change indication
2266  * @slave: slave struct to work on
2267  * @status: whether the link is now up or down
2268  *
2269  * Handle reselection of aggregator (if needed) for this port.
2270  */
2271 void bond_3ad_handle_link_change(struct slave *slave, char link)
2272 {
2273 	struct port *port;
2274 
2275 	port = &(SLAVE_AD_INFO(slave).port);
2276 
2277 	// if slave is null, the whole port is not initialized
2278 	if (!port->slave) {
2279 		printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
2280 		       "uninitialized port on %s\n",
2281 			slave->dev->master->name, slave->dev->name);
2282 		return;
2283 	}
2284 
2285 	// on link down we are zeroing duplex and speed since some of the adaptors(ce1000.lan) report full duplex/speed instead of N/A(duplex) / 0(speed)
2286 	// on link up we are forcing recheck on the duplex and speed since some of he adaptors(ce1000.lan) report
2287 	if (link == BOND_LINK_UP) {
2288 		port->is_enabled = 1;
2289 		port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
2290 		port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
2291 		port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
2292 		port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
2293 	} else {
2294 		/* link has failed */
2295 		port->is_enabled = 0;
2296 		port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
2297 		port->actor_oper_port_key= (port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS);
2298 	}
2299 	//BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN")));
2300 	// there is no need to reselect a new aggregator, just signal the
2301 	// state machines to reinitialize
2302 	port->sm_vars |= AD_PORT_BEGIN;
2303 }
2304 
2305 /*
2306  * set link state for bonding master: if we have an active partnered
2307  * aggregator, we're up, if not, we're down.  Presumes that we cannot
2308  * have an active aggregator if there are no slaves with link up.
2309  *
2310  * Called by bond_set_carrier(). Return zero if carrier state does not
2311  * change, nonzero if it does.
2312  */
2313 int bond_3ad_set_carrier(struct bonding *bond)
2314 {
2315 	struct aggregator *agg;
2316 
2317 	agg = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator));
2318 	if (agg && MAC_ADDRESS_COMPARE(&agg->partner_system, &null_mac_addr)) {
2319 		if (!netif_carrier_ok(bond->dev)) {
2320 			netif_carrier_on(bond->dev);
2321 			return 1;
2322 		}
2323 		return 0;
2324 	}
2325 
2326 	if (netif_carrier_ok(bond->dev)) {
2327 		netif_carrier_off(bond->dev);
2328 		return 1;
2329 	}
2330 	return 0;
2331 }
2332 
2333 /**
2334  * bond_3ad_get_active_agg_info - get information of the active aggregator
2335  * @bond: bonding struct to work on
2336  * @ad_info: ad_info struct to fill with the bond's info
2337  *
2338  * Returns:   0 on success
2339  *          < 0 on error
2340  */
2341 int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
2342 {
2343 	struct aggregator *aggregator = NULL;
2344 	struct port *port;
2345 
2346 	for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
2347 		if (port->aggregator && port->aggregator->is_active) {
2348 			aggregator = port->aggregator;
2349 			break;
2350 		}
2351 	}
2352 
2353 	if (aggregator) {
2354 		ad_info->aggregator_id = aggregator->aggregator_identifier;
2355 		ad_info->ports = aggregator->num_of_ports;
2356 		ad_info->actor_key = aggregator->actor_oper_aggregator_key;
2357 		ad_info->partner_key = aggregator->partner_oper_aggregator_key;
2358 		memcpy(ad_info->partner_system, aggregator->partner_system.mac_addr_value, ETH_ALEN);
2359 		return 0;
2360 	}
2361 
2362 	return -1;
2363 }
2364 
2365 int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
2366 {
2367 	struct slave *slave, *start_at;
2368 	struct bonding *bond = dev->priv;
2369 	int slave_agg_no;
2370 	int slaves_in_agg;
2371 	int agg_id;
2372 	int i;
2373 	struct ad_info ad_info;
2374 	int res = 1;
2375 
2376 	/* make sure that the slaves list will
2377 	 * not change during tx
2378 	 */
2379 	read_lock(&bond->lock);
2380 
2381 	if (!BOND_IS_OK(bond)) {
2382 		goto out;
2383 	}
2384 
2385 	if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
2386 		printk(KERN_DEBUG DRV_NAME ": %s: Error: "
2387 		       "bond_3ad_get_active_agg_info failed\n", dev->name);
2388 		goto out;
2389 	}
2390 
2391 	slaves_in_agg = ad_info.ports;
2392 	agg_id = ad_info.aggregator_id;
2393 
2394 	if (slaves_in_agg == 0) {
2395 		/*the aggregator is empty*/
2396 		printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
2397 		       "aggregator is empty\n",
2398 		       dev->name);
2399 		goto out;
2400 	}
2401 
2402 	slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg);
2403 
2404 	bond_for_each_slave(bond, slave, i) {
2405 		struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
2406 
2407 		if (agg && (agg->aggregator_identifier == agg_id)) {
2408 			slave_agg_no--;
2409 			if (slave_agg_no < 0) {
2410 				break;
2411 			}
2412 		}
2413 	}
2414 
2415 	if (slave_agg_no >= 0) {
2416 		printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
2417 		       "for aggregator ID %d\n", dev->name, agg_id);
2418 		goto out;
2419 	}
2420 
2421 	start_at = slave;
2422 
2423 	bond_for_each_slave_from(bond, slave, i, start_at) {
2424 		int slave_agg_id = 0;
2425 		struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
2426 
2427 		if (agg) {
2428 			slave_agg_id = agg->aggregator_identifier;
2429 		}
2430 
2431 		if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) {
2432 			res = bond_dev_queue_xmit(bond, skb, slave->dev);
2433 			break;
2434 		}
2435 	}
2436 
2437 out:
2438 	if (res) {
2439 		/* no suitable interface, frame not sent */
2440 		dev_kfree_skb(skb);
2441 	}
2442 	read_unlock(&bond->lock);
2443 	return 0;
2444 }
2445 
2446 int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
2447 {
2448 	struct bonding *bond = dev->priv;
2449 	struct slave *slave = NULL;
2450 	int ret = NET_RX_DROP;
2451 
2452 	if (!(dev->flags & IFF_MASTER))
2453 		goto out;
2454 
2455 	read_lock(&bond->lock);
2456 	slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
2457 	if (!slave)
2458 		goto out_unlock;
2459 
2460 	bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
2461 
2462 	ret = NET_RX_SUCCESS;
2463 
2464 out_unlock:
2465 	read_unlock(&bond->lock);
2466 out:
2467 	dev_kfree_skb(skb);
2468 
2469 	return ret;
2470 }
2471 
2472