OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [net/] [bonding/] [bond_3ad.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.