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