From: David S. Miller Date: Tue, 14 Jan 2014 05:50:27 +0000 (-0800) Subject: Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=853dc21bfe15f545347b5c82aad02735d552110d;hp=12afc36e38b3b6a0ec9bda71632c2285e7fdbab2;p=~andy%2Flinux Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge Included changes: - drop dependency against CRC16 - move to new release version - add size check at compile time for packet structs - update copyright years in every file - implement new bonding/interface alternation feature Signed-off-by: David S. Miller --- diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 7373115407e..c97932c88ea 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -26,12 +26,36 @@ ip_no_pmtu_disc - INTEGER discarded. Outgoing frames are handled the same as in mode 1, implicitly setting IP_PMTUDISC_DONT on every created socket. - Possible values: 0-2 + Mode 3 is a hardend pmtu discover mode. The kernel will only + accept fragmentation-needed errors if the underlying protocol + can verify them besides a plain socket lookup. Current + protocols for which pmtu events will be honored are TCP, SCTP + and DCCP as they verify e.g. the sequence number or the + association. This mode should not be enabled globally but is + only intended to secure e.g. name servers in namespaces where + TCP path mtu must still work but path MTU information of other + protocols should be discarded. If enabled globally this mode + could break other protocols. + + Possible values: 0-3 Default: FALSE min_pmtu - INTEGER default 552 - minimum discovered Path MTU +ip_forward_use_pmtu - BOOLEAN + By default we don't trust protocol path MTUs while forwarding + because they could be easily forged and can lead to unwanted + fragmentation by the router. + You only need to enable this if you have user-space software + which tries to discover path mtus by itself and depends on the + kernel honoring this information. This is normally not the + case. + Default: 0 (disabled) + Possible values: + 0 - disabled + 1 - enabled + route/max_size - INTEGER Maximum number of routes allowed in the kernel. Increase this when using large numbers of interfaces and/or routes. diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt index 723bf3d33a6..91ffe1d9e8c 100644 --- a/Documentation/networking/packet_mmap.txt +++ b/Documentation/networking/packet_mmap.txt @@ -98,6 +98,11 @@ by the kernel. The destruction of the socket and all associated resources is done by a simple call to close(fd). +Similarly as without PACKET_MMAP, it is possible to use one socket +for capture and transmission. This can be done by mapping the +allocated RX and TX buffer ring with a single mmap() call. +See "Mapping and use of the circular buffer (ring)". + Next I will describe PACKET_MMAP settings and its constraints, also the mapping of the circular buffer in the user process and the use of this buffer. @@ -414,6 +419,19 @@ tp_block_size/tp_frame_size frames there will be a gap between the frames. This is because a frame cannot be spawn across two blocks. +To use one socket for capture and transmission, the mapping of both the +RX and TX buffer ring has to be done with one call to mmap: + + ... + setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &foo, sizeof(foo)); + setsockopt(fd, SOL_PACKET, PACKET_TX_RING, &bar, sizeof(bar)); + ... + rx_ring = mmap(0, size * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + tx_ring = rx_ring + size; + +RX must be the first as the kernel maps the TX ring memory right +after the RX one. + At the beginning of each frame there is an status field (see struct tpacket_hdr). If this field is 0 means that the frame is ready to be used for the kernel, If not, there is a frame the user can read diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 93e6ca91962..cf29d84fd9c 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -11,6 +11,7 @@ generic-y += fcntl.h generic-y += fb.h generic-y += ftrace.h generic-y += hardirq.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h @@ -47,4 +48,3 @@ generic-y += user.h generic-y += vga.h generic-y += xor.h generic-y += preempt.h -generic-y += hash.h diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index c5963b3e462..406cbd3ebd5 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -5,6 +5,7 @@ header-y += arch-v32/ generic-y += clkdev.h generic-y += exec.h +generic-y += hash.h generic-y += kvm_para.h generic-y += linkage.h generic-y += module.h @@ -12,4 +13,3 @@ generic-y += trace_clock.h generic-y += vga.h generic-y += xor.h generic-y += preempt.h -generic-y += hash.h diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 469d223950f..ae45d75a318 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -15,6 +15,7 @@ generic-y += fb.h generic-y += fcntl.h generic-y += ftrace.h generic-y += hardirq.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h @@ -54,4 +55,3 @@ generic-y += ucontext.h generic-y += unaligned.h generic-y += xor.h generic-y += preempt.h -generic-y += hash.h diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 43eec338ff5..ca60945ddf3 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -1,7 +1,7 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += hash.h generic-y += trace_clock.h generic-y += syscalls.h generic-y += preempt.h -generic-y += hash.h diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index bc42f14c9c2..199345207d8 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@ -1,6 +1,6 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += hash.h generic-y += trace_clock.h generic-y += preempt.h -generic-y += hash.h diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index 099e7ba4059..1d35e33ccf8 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild @@ -2,8 +2,8 @@ header-y += generic-y += clkdev.h +generic-y += hash.h generic-y += trace_clock.h generic-y += xor.h generic-y += preempt.h -generic-y += hash.h diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 539e24a1c86..29db1caee76 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -34,14 +34,14 @@ #include "bonding.h" #include "bond_3ad.h" -// General definitions +/* General definitions */ #define AD_SHORT_TIMEOUT 1 #define AD_LONG_TIMEOUT 0 #define AD_STANDBY 0x2 #define AD_MAX_TX_IN_SECOND 3 #define AD_COLLECTOR_MAX_DELAY 0 -// Timer definitions(43.4.4 in the 802.3ad standard) +/* Timer definitions (43.4.4 in the 802.3ad standard) */ #define AD_FAST_PERIODIC_TIME 1 #define AD_SLOW_PERIODIC_TIME 30 #define AD_SHORT_TIMEOUT_TIME (3*AD_FAST_PERIODIC_TIME) @@ -49,7 +49,7 @@ #define AD_CHURN_DETECTION_TIME 60 #define AD_AGGREGATE_WAIT_TIME 2 -// Port state definitions(43.4.2.2 in the 802.3ad standard) +/* Port state definitions (43.4.2.2 in the 802.3ad standard) */ #define AD_STATE_LACP_ACTIVITY 0x1 #define AD_STATE_LACP_TIMEOUT 0x2 #define AD_STATE_AGGREGATION 0x4 @@ -59,7 +59,9 @@ #define AD_STATE_DEFAULTED 0x40 #define AD_STATE_EXPIRED 0x80 -// Port Variables definitions used by the State Machines(43.4.7 in the 802.3ad standard) +/* Port Variables definitions used by the State Machines (43.4.7 in the + * 802.3ad standard) + */ #define AD_PORT_BEGIN 0x1 #define AD_PORT_LACP_ENABLED 0x2 #define AD_PORT_ACTOR_CHURN 0x4 @@ -71,24 +73,23 @@ #define AD_PORT_SELECTED 0x100 #define AD_PORT_MOVED 0x200 -// Port Key definitions -// key is determined according to the link speed, duplex and -// user key(which is yet not supported) -// ------------------------------------------------------------ -// Port key : | User key | Speed |Duplex| -// ------------------------------------------------------------ -// 16 6 1 0 +/* Port Key definitions + * key is determined according to the link speed, duplex and + * user key (which is yet not supported) + * -------------------------------------------------------------- + * Port key : | User key | Speed | Duplex | + * -------------------------------------------------------------- + * 16 6 1 0 + */ #define AD_DUPLEX_KEY_BITS 0x1 #define AD_SPEED_KEY_BITS 0x3E #define AD_USER_KEY_BITS 0xFFC0 -//dalloun #define AD_LINK_SPEED_BITMASK_1MBPS 0x1 #define AD_LINK_SPEED_BITMASK_10MBPS 0x2 #define AD_LINK_SPEED_BITMASK_100MBPS 0x4 #define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 #define AD_LINK_SPEED_BITMASK_10000MBPS 0x10 -//endalloun /* compare MAC addresses */ #define MAC_ADDRESS_EQUAL(A, B) \ @@ -100,7 +101,7 @@ static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000; static const u8 lacpdu_mcast_addr[ETH_ALEN] = MULTICAST_LACPDU_ADDR; -// ================= main 802.3ad protocol functions ================== +/* ================= main 802.3ad protocol functions ================== */ static int ad_lacpdu_send(struct port *port); static int ad_marker_send(struct port *port, struct bond_marker *marker); static void ad_mux_machine(struct port *port); @@ -114,13 +115,13 @@ static void ad_initialize_agg(struct aggregator *aggregator); static void ad_initialize_port(struct port *port, int lacp_fast); static void ad_enable_collecting_distributing(struct port *port); static void ad_disable_collecting_distributing(struct port *port); -static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port); -static void ad_marker_response_received(struct bond_marker *marker, struct port *port); +static void ad_marker_info_received(struct bond_marker *marker_info, + struct port *port); +static void ad_marker_response_received(struct bond_marker *marker, + struct port *port); -///////////////////////////////////////////////////////////////////////////////// -// ================= api to bonding and kernel code ================== -///////////////////////////////////////////////////////////////////////////////// +/* ================= api to bonding and kernel code ================== */ /** * __get_bond_by_port - get the port's bonding struct @@ -151,17 +152,20 @@ static inline struct aggregator *__get_first_agg(struct port *port) /* If there's no bond for this port, or bond has no slaves */ if (bond == NULL) return NULL; + rcu_read_lock(); first_slave = bond_first_slave_rcu(bond); rcu_read_unlock(); + return first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL; } -/* - * __agg_has_partner +/** + * __agg_has_partner - see if we have a partner + * @agg: the agregator we're looking at * * Return nonzero if aggregator has a partner (denoted by a non-zero ether - * address for the partner). Return 0 if not. + * address for the partner). Return 0 if not. */ static inline int __agg_has_partner(struct aggregator *agg) { @@ -171,7 +175,6 @@ static inline int __agg_has_partner(struct aggregator *agg) /** * __disable_port - disable the port's slave * @port: the port we're looking at - * */ static inline void __disable_port(struct port *port) { @@ -181,7 +184,6 @@ static inline void __disable_port(struct port *port) /** * __enable_port - enable the port's slave, if it's up * @port: the port we're looking at - * */ static inline void __enable_port(struct port *port) { @@ -194,7 +196,6 @@ static inline void __enable_port(struct port *port) /** * __port_is_enabled - check if the port's slave is in active state * @port: the port we're looking at - * */ static inline int __port_is_enabled(struct port *port) { @@ -220,7 +221,6 @@ static inline u32 __get_agg_selection_mode(struct port *port) /** * __check_agg_selection_timer - check if the selection timer has expired * @port: the port we're looking at - * */ static inline int __check_agg_selection_timer(struct port *port) { @@ -235,7 +235,6 @@ static inline int __check_agg_selection_timer(struct port *port) /** * __get_state_machine_lock - lock the port's state machines * @port: the port we're looking at - * */ static inline void __get_state_machine_lock(struct port *port) { @@ -245,7 +244,6 @@ static inline void __get_state_machine_lock(struct port *port) /** * __release_state_machine_lock - unlock the port's state machines * @port: the port we're looking at - * */ static inline void __release_state_machine_lock(struct port *port) { @@ -268,10 +266,11 @@ static u16 __get_link_speed(struct port *port) struct slave *slave = port->slave; u16 speed; - /* this if covers only a special case: when the configuration starts with - * link down, it sets the speed to 0. - * This is done in spite of the fact that the e100 driver reports 0 to be - * compatible with MVT in the future.*/ + /* this if covers only a special case: when the configuration starts + * with link down, it sets the speed to 0. + * This is done in spite of the fact that the e100 driver reports 0 + * to be compatible with MVT in the future. + */ if (slave->link != BOND_LINK_UP) speed = 0; else { @@ -293,7 +292,8 @@ static u16 __get_link_speed(struct port *port) break; default: - speed = 0; // unknown speed value from ethtool. shouldn't happen + /* unknown speed value from ethtool. shouldn't happen */ + speed = 0; break; } } @@ -317,8 +317,9 @@ static u8 __get_duplex(struct port *port) u8 retval; - // handling a special case: when the configuration starts with - // link down, it sets the duplex to 0. + /* handling a special case: when the configuration starts with + * link down, it sets the duplex to 0. + */ if (slave->link != BOND_LINK_UP) retval = 0x0; else { @@ -342,15 +343,14 @@ static u8 __get_duplex(struct port *port) /** * __initialize_port_locks - initialize a port's STATE machine spinlock * @port: the slave of the port we're looking at - * */ static inline void __initialize_port_locks(struct slave *slave) { - // make sure it isn't called twice + /* make sure it isn't called twice */ spin_lock_init(&(SLAVE_AD_INFO(slave).state_machine_lock)); } -//conversions +/* Conversions */ /** * __ad_timer_to_ticks - convert a given timer type to AD module ticks @@ -359,39 +359,38 @@ static inline void __initialize_port_locks(struct slave *slave) * * If @timer_type is %current_while_timer, @par indicates long/short timer. * If @timer_type is %periodic_timer, @par is one of %FAST_PERIODIC_TIME, - * %SLOW_PERIODIC_TIME. + * %SLOW_PERIODIC_TIME. */ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) { u16 retval = 0; /* to silence the compiler */ switch (timer_type) { - case AD_CURRENT_WHILE_TIMER: // for rx machine usage + case AD_CURRENT_WHILE_TIMER: /* for rx machine usage */ if (par) - retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout + retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); else - retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout + retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); break; - case AD_ACTOR_CHURN_TIMER: // for local churn machine + case AD_ACTOR_CHURN_TIMER: /* for local churn machine */ retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); break; - case AD_PERIODIC_TIMER: // for periodic machine - retval = (par*ad_ticks_per_sec); // long timeout + case AD_PERIODIC_TIMER: /* for periodic machine */ + retval = (par*ad_ticks_per_sec); /* long timeout */ break; - case AD_PARTNER_CHURN_TIMER: // for remote churn machine + case AD_PARTNER_CHURN_TIMER: /* for remote churn machine */ retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); break; - case AD_WAIT_WHILE_TIMER: // for selection machine + case AD_WAIT_WHILE_TIMER: /* for selection machine */ retval = (AD_AGGREGATE_WAIT_TIME*ad_ticks_per_sec); break; } + return retval; } -///////////////////////////////////////////////////////////////////////////////// -// ================= ad_rx_machine helper functions ================== -///////////////////////////////////////////////////////////////////////////////// +/* ================= ad_rx_machine helper functions ================== */ /** * __choose_matched - update a port's matched variable from a received lacpdu @@ -451,7 +450,9 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) struct port_params *partner = &port->partner_oper; __choose_matched(lacpdu, port); - // record the new parameter values for the partner operational + /* record the new parameter values for the partner + * operational + */ partner->port_number = ntohs(lacpdu->actor_port); partner->port_priority = ntohs(lacpdu->actor_port_priority); partner->system = lacpdu->actor_system; @@ -459,10 +460,12 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) partner->key = ntohs(lacpdu->actor_key); partner->port_state = lacpdu->actor_state; - // set actor_oper_port_state.defaulted to FALSE + /* set actor_oper_port_state.defaulted to FALSE */ port->actor_oper_port_state &= ~AD_STATE_DEFAULTED; - // set the partner sync. to on if the partner is sync. and the port is matched + /* set the partner sync. to on if the partner is sync, + * and the port is matched + */ if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) partner->port_state |= AD_STATE_SYNCHRONIZATION; @@ -482,11 +485,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) static void __record_default(struct port *port) { if (port) { - // record the partner admin parameters + /* record the partner admin parameters */ memcpy(&port->partner_oper, &port->partner_admin, sizeof(struct port_params)); - // set actor_oper_port_state.defaulted to true + /* set actor_oper_port_state.defaulted to true */ port->actor_oper_port_state |= AD_STATE_DEFAULTED; } } @@ -590,36 +593,6 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port) } } -/** - * __attach_bond_to_agg - * @port: the port we're looking at - * - * Handle the attaching of the port's control parser/multiplexer and the - * aggregator. This function does nothing since the parser/multiplexer of the - * receive and the parser/multiplexer of the aggregator are already combined. - */ -static void __attach_bond_to_agg(struct port *port) -{ - port = NULL; /* just to satisfy the compiler */ - // This function does nothing since the parser/multiplexer of the receive - // and the parser/multiplexer of the aggregator are already combined -} - -/** - * __detach_bond_from_agg - * @port: the port we're looking at - * - * Handle the detaching of the port's control parser/multiplexer from the - * aggregator. This function does nothing since the parser/multiplexer of the - * receive and the parser/multiplexer of the aggregator are already combined. - */ -static void __detach_bond_from_agg(struct port *port) -{ - port = NULL; /* just to satisfy the compiler */ - // This function does nothing since the parser/multiplexer of the receive - // and the parser/multiplexer of the aggregator are already combined -} - /** * __agg_ports_are_ready - check if all ports in an aggregator are ready * @aggregator: the aggregator we're looking at @@ -631,7 +604,9 @@ static int __agg_ports_are_ready(struct aggregator *aggregator) int retval = 1; if (aggregator) { - // scan all ports in this aggregator to verfy if they are all ready + /* scan all ports in this aggregator to verfy if they are + * all ready. + */ for (port = aggregator->lag_ports; port; port = port->next_port_in_aggregator) { @@ -691,7 +666,7 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) bandwidth = aggregator->num_of_ports * 10000; break; default: - bandwidth = 0; /*to silence the compiler ....*/ + bandwidth = 0; /* to silence the compiler */ } } return bandwidth; @@ -700,7 +675,6 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) /** * __get_active_agg - get the current active aggregator * @aggregator: the aggregator we're looking at - * */ static struct aggregator *__get_active_agg(struct aggregator *aggregator) { @@ -722,15 +696,14 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator) /** * __update_lacpdu_from_port - update a port's lacpdu fields * @port: the port we're looking at - * */ static inline void __update_lacpdu_from_port(struct port *port) { struct lacpdu *lacpdu = &port->lacpdu; const struct port_params *partner = &port->partner_oper; - /* update current actual Actor parameters */ - /* lacpdu->subtype initialized + /* update current actual Actor parameters + * lacpdu->subtype initialized * lacpdu->version_number initialized * lacpdu->tlv_type_actor_info initialized * lacpdu->actor_information_length initialized @@ -766,9 +739,7 @@ static inline void __update_lacpdu_from_port(struct port *port) */ } -////////////////////////////////////////////////////////////////////////////////////// -// ================= main 802.3ad protocol code ====================================== -////////////////////////////////////////////////////////////////////////////////////// +/* ================= main 802.3ad protocol code ========================= */ /** * ad_lacpdu_send - send out a lacpdu packet on a given port @@ -798,11 +769,12 @@ static int ad_lacpdu_send(struct port *port) memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); /* Note: source address is set to be the member's PERMANENT address, - because we use it to identify loopback lacpdus in receive. */ + * because we use it to identify loopback lacpdus in receive. + */ memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; - lacpdu_header->lacpdu = port->lacpdu; // struct copy + lacpdu_header->lacpdu = port->lacpdu; dev_queue_xmit(skb); @@ -839,11 +811,12 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); /* Note: source address is set to be the member's PERMANENT address, - because we use it to identify loopback MARKERs in receive. */ + * because we use it to identify loopback MARKERs in receive. + */ memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); marker_header->hdr.h_proto = PKT_TYPE_LACPDU; - marker_header->marker = *marker; // struct copy + marker_header->marker = *marker; dev_queue_xmit(skb); @@ -853,72 +826,90 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) /** * ad_mux_machine - handle a port's mux state machine * @port: the port we're looking at - * */ static void ad_mux_machine(struct port *port) { mux_states_t last_state; - // keep current State Machine state to compare later if it was changed + /* keep current State Machine state to compare later if it was + * changed + */ last_state = port->sm_mux_state; if (port->sm_vars & AD_PORT_BEGIN) { - port->sm_mux_state = AD_MUX_DETACHED; // next state + port->sm_mux_state = AD_MUX_DETACHED; } else { switch (port->sm_mux_state) { case AD_MUX_DETACHED: if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) /* if SELECTED or STANDBY */ - port->sm_mux_state = AD_MUX_WAITING; // next state + port->sm_mux_state = AD_MUX_WAITING; break; case AD_MUX_WAITING: - // if SELECTED == FALSE return to DETACH state - if (!(port->sm_vars & AD_PORT_SELECTED)) { // if UNSELECTED + /* if SELECTED == FALSE return to DETACH state */ + if (!(port->sm_vars & AD_PORT_SELECTED)) { port->sm_vars &= ~AD_PORT_READY_N; - // in order to withhold the Selection Logic to check all ports READY_N value - // every callback cycle to update ready variable, we check READY_N and update READY here + /* in order to withhold the Selection Logic to + * check all ports READY_N value every callback + * cycle to update ready variable, we check + * READY_N and update READY here + */ __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); - port->sm_mux_state = AD_MUX_DETACHED; // next state + port->sm_mux_state = AD_MUX_DETACHED; break; } - // check if the wait_while_timer expired + /* check if the wait_while_timer expired */ if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) port->sm_vars |= AD_PORT_READY_N; - // in order to withhold the selection logic to check all ports READY_N value - // every callback cycle to update ready variable, we check READY_N and update READY here + /* in order to withhold the selection logic to check + * all ports READY_N value every callback cycle to + * update ready variable, we check READY_N and update + * READY here + */ __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); - // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state + /* if the wait_while_timer expired, and the port is + * in READY state, move to ATTACHED state + */ if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) - port->sm_mux_state = AD_MUX_ATTACHED; // next state + port->sm_mux_state = AD_MUX_ATTACHED; break; case AD_MUX_ATTACHED: - // check also if agg_select_timer expired(so the edable port will take place only after this timer) - if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) { - port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state - } else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if UNSELECTED or STANDBY + /* check also if agg_select_timer expired (so the + * edable port will take place only after this timer) + */ + if ((port->sm_vars & AD_PORT_SELECTED) && + (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) && + !__check_agg_selection_timer(port)) { + port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING; + } else if (!(port->sm_vars & AD_PORT_SELECTED) || + (port->sm_vars & AD_PORT_STANDBY)) { + /* if UNSELECTED or STANDBY */ port->sm_vars &= ~AD_PORT_READY_N; - // in order to withhold the selection logic to check all ports READY_N value - // every callback cycle to update ready variable, we check READY_N and update READY here + /* in order to withhold the selection logic to + * check all ports READY_N value every callback + * cycle to update ready variable, we check + * READY_N and update READY here + */ __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); - port->sm_mux_state = AD_MUX_DETACHED;// next state + port->sm_mux_state = AD_MUX_DETACHED; } break; case AD_MUX_COLLECTING_DISTRIBUTING: - if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) || - !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) - ) { - port->sm_mux_state = AD_MUX_ATTACHED;// next state - + if (!(port->sm_vars & AD_PORT_SELECTED) || + (port->sm_vars & AD_PORT_STANDBY) || + !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION)) { + port->sm_mux_state = AD_MUX_ATTACHED; } else { - // if port state hasn't changed make - // sure that a collecting distributing - // port in an active aggregator is enabled + /* if port state hasn't changed make + * sure that a collecting distributing + * port in an active aggregator is enabled + */ if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) { @@ -927,19 +918,18 @@ static void ad_mux_machine(struct port *port) } } break; - default: //to silence the compiler + default: break; } } - // check if the state machine was changed + /* check if the state machine was changed */ if (port->sm_mux_state != last_state) { pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state); switch (port->sm_mux_state) { case AD_MUX_DETACHED: - __detach_bond_from_agg(port); port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; ad_disable_collecting_distributing(port); port->actor_oper_port_state &= ~AD_STATE_COLLECTING; @@ -950,7 +940,6 @@ static void ad_mux_machine(struct port *port) port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0); break; case AD_MUX_ATTACHED: - __attach_bond_to_agg(port); port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; port->actor_oper_port_state &= ~AD_STATE_COLLECTING; port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING; @@ -963,7 +952,7 @@ static void ad_mux_machine(struct port *port) ad_enable_collecting_distributing(port); port->ntt = true; break; - default: //to silence the compiler + default: break; } } @@ -982,59 +971,63 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) { rx_states_t last_state; - // keep current State Machine state to compare later if it was changed + /* keep current State Machine state to compare later if it was + * changed + */ last_state = port->sm_rx_state; - // check if state machine should change state - // first, check if port was reinitialized + /* check if state machine should change state */ + + /* first, check if port was reinitialized */ if (port->sm_vars & AD_PORT_BEGIN) - /* next state */ port->sm_rx_state = AD_RX_INITIALIZE; - // check if port is not enabled + /* check if port is not enabled */ else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) - /* next state */ port->sm_rx_state = AD_RX_PORT_DISABLED; - // check if new lacpdu arrived - else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) { - port->sm_rx_timer_counter = 0; // zero timer + /* check if new lacpdu arrived */ + else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || + (port->sm_rx_state == AD_RX_DEFAULTED) || + (port->sm_rx_state == AD_RX_CURRENT))) { + port->sm_rx_timer_counter = 0; port->sm_rx_state = AD_RX_CURRENT; } else { - // if timer is on, and if it is expired - if (port->sm_rx_timer_counter && !(--port->sm_rx_timer_counter)) { + /* if timer is on, and if it is expired */ + if (port->sm_rx_timer_counter && + !(--port->sm_rx_timer_counter)) { switch (port->sm_rx_state) { case AD_RX_EXPIRED: - port->sm_rx_state = AD_RX_DEFAULTED; // next state + port->sm_rx_state = AD_RX_DEFAULTED; break; case AD_RX_CURRENT: - port->sm_rx_state = AD_RX_EXPIRED; // next state + port->sm_rx_state = AD_RX_EXPIRED; break; - default: //to silence the compiler + default: break; } } else { - // if no lacpdu arrived and no timer is on + /* if no lacpdu arrived and no timer is on */ switch (port->sm_rx_state) { case AD_RX_PORT_DISABLED: if (port->sm_vars & AD_PORT_MOVED) - port->sm_rx_state = AD_RX_INITIALIZE; // next state + port->sm_rx_state = AD_RX_INITIALIZE; else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) - port->sm_rx_state = AD_RX_EXPIRED; // next state + port->sm_rx_state = AD_RX_EXPIRED; else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) - port->sm_rx_state = AD_RX_LACP_DISABLED; // next state + port->sm_rx_state = AD_RX_LACP_DISABLED; break; - default: //to silence the compiler + default: break; } } } - // check if the State machine was changed or new lacpdu arrived + /* check if the State machine was changed or new lacpdu arrived */ if ((port->sm_rx_state != last_state) || (lacpdu)) { pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, @@ -1049,10 +1042,9 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) __record_default(port); port->actor_oper_port_state &= ~AD_STATE_EXPIRED; port->sm_vars &= ~AD_PORT_MOVED; - port->sm_rx_state = AD_RX_PORT_DISABLED; // next state - - /*- Fall Through -*/ + port->sm_rx_state = AD_RX_PORT_DISABLED; + /* Fall Through */ case AD_RX_PORT_DISABLED: port->sm_vars &= ~AD_PORT_MATCHED; break; @@ -1064,13 +1056,15 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) port->actor_oper_port_state &= ~AD_STATE_EXPIRED; break; case AD_RX_EXPIRED: - //Reset of the Synchronization flag. (Standard 43.4.12) - //This reset cause to disable this port in the COLLECTING_DISTRIBUTING state of the - //mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port. + /* Reset of the Synchronization flag (Standard 43.4.12) + * This reset cause to disable this port in the + * COLLECTING_DISTRIBUTING state of the mux machine in + * case of EXPIRED even if LINK_DOWN didn't arrive for + * the port. + */ port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION; port->sm_vars &= ~AD_PORT_MATCHED; - port->partner_oper.port_state |= - AD_STATE_LACP_ACTIVITY; + port->partner_oper.port_state |= AD_STATE_LACP_ACTIVITY; port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT)); port->actor_oper_port_state |= AD_STATE_EXPIRED; break; @@ -1082,10 +1076,11 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) break; case AD_RX_CURRENT: /* detect loopback situation */ - if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system), &(port->actor_system))) { - pr_err("%s: An illegal loopback occurred on adapter (%s).\n" - "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", - port->slave->bond->dev->name, port->slave->dev->name); + if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system), + &(port->actor_system))) { + pr_err("%s: An illegal loopback occurred on adapter (%s).\nCheck the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", + port->slave->bond->dev->name, + port->slave->dev->name); return; } __update_selected(lacpdu, port); @@ -1094,7 +1089,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)); port->actor_oper_port_state &= ~AD_STATE_EXPIRED; break; - default: /* to silence the compiler */ + default: break; } } @@ -1103,13 +1098,14 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) /** * ad_tx_machine - handle a port's tx state machine * @port: the port we're looking at - * */ static void ad_tx_machine(struct port *port) { - // check if tx timer expired, to verify that we do not send more than 3 packets per second + /* check if tx timer expired, to verify that we do not send more than + * 3 packets per second + */ if (port->sm_tx_timer_counter && !(--port->sm_tx_timer_counter)) { - // check if there is something to send + /* check if there is something to send */ if (port->ntt && (port->sm_vars & AD_PORT_LACP_ENABLED)) { __update_lacpdu_from_port(port); @@ -1117,14 +1113,16 @@ static void ad_tx_machine(struct port *port) pr_debug("Sent LACPDU on port %d\n", port->actor_port_number); - /* mark ntt as false, so it will not be sent again until - demanded */ + /* mark ntt as false, so it will not be sent + * again until demanded + */ port->ntt = false; } } - // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND - port->sm_tx_timer_counter = - ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; + /* restart tx timer(to verify that we will not exceed + * AD_MAX_TX_IN_SECOND + */ + port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; } } @@ -1138,76 +1136,79 @@ static void ad_periodic_machine(struct port *port) { periodic_states_t last_state; - // keep current state machine state to compare later if it was changed + /* keep current state machine state to compare later if it was changed */ last_state = port->sm_periodic_state; - // check if port was reinitialized + /* check if port was reinitialized */ if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) || (!(port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY) && !(port->partner_oper.port_state & AD_STATE_LACP_ACTIVITY)) ) { - port->sm_periodic_state = AD_NO_PERIODIC; // next state + port->sm_periodic_state = AD_NO_PERIODIC; } - // check if state machine should change state + /* check if state machine should change state */ else if (port->sm_periodic_timer_counter) { - // check if periodic state machine expired + /* check if periodic state machine expired */ if (!(--port->sm_periodic_timer_counter)) { - // if expired then do tx - port->sm_periodic_state = AD_PERIODIC_TX; // next state + /* if expired then do tx */ + port->sm_periodic_state = AD_PERIODIC_TX; } else { - // If not expired, check if there is some new timeout parameter from the partner state + /* If not expired, check if there is some new timeout + * parameter from the partner state + */ switch (port->sm_periodic_state) { case AD_FAST_PERIODIC: if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) - port->sm_periodic_state = AD_SLOW_PERIODIC; // next state + port->sm_periodic_state = AD_SLOW_PERIODIC; break; case AD_SLOW_PERIODIC: if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { - // stop current timer port->sm_periodic_timer_counter = 0; - port->sm_periodic_state = AD_PERIODIC_TX; // next state + port->sm_periodic_state = AD_PERIODIC_TX; } break; - default: //to silence the compiler + default: break; } } } else { switch (port->sm_periodic_state) { case AD_NO_PERIODIC: - port->sm_periodic_state = AD_FAST_PERIODIC; // next state + port->sm_periodic_state = AD_FAST_PERIODIC; break; case AD_PERIODIC_TX: - if (!(port->partner_oper.port_state - & AD_STATE_LACP_TIMEOUT)) - port->sm_periodic_state = AD_SLOW_PERIODIC; // next state + if (!(port->partner_oper.port_state & + AD_STATE_LACP_TIMEOUT)) + port->sm_periodic_state = AD_SLOW_PERIODIC; else - port->sm_periodic_state = AD_FAST_PERIODIC; // next state + port->sm_periodic_state = AD_FAST_PERIODIC; break; - default: //to silence the compiler + default: break; } } - // check if the state machine was changed + /* check if the state machine was changed */ if (port->sm_periodic_state != last_state) { pr_debug("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state); switch (port->sm_periodic_state) { case AD_NO_PERIODIC: - port->sm_periodic_timer_counter = 0; // zero timer + port->sm_periodic_timer_counter = 0; break; case AD_FAST_PERIODIC: - 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 + /* decrement 1 tick we lost in the PERIODIC_TX cycle */ + port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_FAST_PERIODIC_TIME))-1; break; case AD_SLOW_PERIODIC: - 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 + /* decrement 1 tick we lost in the PERIODIC_TX cycle */ + port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_SLOW_PERIODIC_TIME))-1; break; case AD_PERIODIC_TX: port->ntt = true; break; - default: //to silence the compiler + default: break; } } @@ -1230,30 +1231,38 @@ static void ad_port_selection_logic(struct port *port) struct slave *slave; int found = 0; - // if the port is already Selected, do nothing + /* if the port is already Selected, do nothing */ if (port->sm_vars & AD_PORT_SELECTED) return; bond = __get_bond_by_port(port); - // if the port is connected to other aggregator, detach it + /* if the port is connected to other aggregator, detach it */ if (port->aggregator) { - // detach the port from its former aggregator + /* detach the port from its former aggregator */ temp_aggregator = port->aggregator; for (curr_port = temp_aggregator->lag_ports; curr_port; last_port = curr_port, - curr_port = curr_port->next_port_in_aggregator) { + curr_port = curr_port->next_port_in_aggregator) { if (curr_port == port) { temp_aggregator->num_of_ports--; - if (!last_port) {// if it is the first port attached to the aggregator + /* if it is the first port attached to the + * aggregator + */ + if (!last_port) { temp_aggregator->lag_ports = port->next_port_in_aggregator; - } else {// not the first port attached to the aggregator + } else { + /* not the first port attached to the + * aggregator + */ last_port->next_port_in_aggregator = port->next_port_in_aggregator; } - // clear the port's relations to this aggregator + /* clear the port's relations to this + * aggregator + */ port->aggregator = NULL; port->next_port_in_aggregator = NULL; port->actor_port_aggregator_identifier = 0; @@ -1261,25 +1270,30 @@ static void ad_port_selection_logic(struct port *port) pr_debug("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier); - // if the aggregator is empty, clear its parameters, and set it ready to be attached + /* if the aggregator is empty, clear its + * parameters, and set it ready to be attached + */ if (!temp_aggregator->lag_ports) ad_clear_agg(temp_aggregator); break; } } - if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list - pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n", - port->slave->bond->dev->name, - port->actor_port_number, - port->slave->dev->name, - port->aggregator->aggregator_identifier); + if (!curr_port) { + /* meaning: the port was related to an aggregator + * but was not on the aggregator port list + */ + pr_warn("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n", + port->slave->bond->dev->name, + port->actor_port_number, + port->slave->dev->name, + port->aggregator->aggregator_identifier); } } - // search on all aggregators for a suitable aggregator for this port + /* search on all aggregators for a suitable aggregator for this port */ bond_for_each_slave(bond, slave, iter) { aggregator = &(SLAVE_AD_INFO(slave).aggregator); - // keep a free aggregator for later use(if needed) + /* keep a free aggregator for later use(if needed) */ if (!aggregator->lag_ports) { if (!free_aggregator) free_aggregator = aggregator; @@ -1306,23 +1320,26 @@ static void ad_port_selection_logic(struct port *port) port->actor_port_number, port->aggregator->aggregator_identifier); - // mark this port as selected + /* mark this port as selected */ port->sm_vars |= AD_PORT_SELECTED; found = 1; break; } } - // the port couldn't find an aggregator - attach it to a new aggregator + /* the port couldn't find an aggregator - attach it to a new + * aggregator + */ if (!found) { if (free_aggregator) { - // assign port a new aggregator + /* assign port a new aggregator */ port->aggregator = free_aggregator; port->actor_port_aggregator_identifier = port->aggregator->aggregator_identifier; - // update the new aggregator's parameters - // if port was responsed from the end-user + /* update the new aggregator's parameters + * if port was responsed from the end-user + */ if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) /* if port is full duplex */ port->aggregator->is_individual = false; @@ -1341,7 +1358,7 @@ static void ad_port_selection_logic(struct port *port) port->aggregator->lag_ports = port; port->aggregator->num_of_ports++; - // mark this port as selected + /* mark this port as selected */ port->sm_vars |= AD_PORT_SELECTED; pr_debug("Port %d joined LAG %d(new LAG)\n", @@ -1353,23 +1370,24 @@ static void ad_port_selection_logic(struct port *port) port->actor_port_number, port->slave->dev->name); } } - // if all aggregator's ports are READY_N == TRUE, set ready=TRUE in all aggregator's ports - // else set ready=FALSE in all aggregator's ports - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); + /* if all aggregator's ports are READY_N == TRUE, set ready=TRUE + * in all aggregator's ports, else set ready=FALSE in all + * aggregator's ports + */ + __set_agg_ports_ready(port->aggregator, + __agg_ports_are_ready(port->aggregator)); aggregator = __get_first_agg(port); ad_agg_selection_logic(aggregator); } -/* - * Decide if "agg" is a better choice for the new active aggregator that +/* Decide if "agg" is a better choice for the new active aggregator that * the current best, according to the ad_select policy. */ static struct aggregator *ad_agg_selection_test(struct aggregator *best, struct aggregator *curr) { - /* - * 0. If no best, select current. + /* 0. If no best, select current. * * 1. If the current agg is not individual, and the best is * individual, select current. @@ -1425,9 +1443,9 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, break; default: - pr_warning("%s: Impossible agg select mode %d\n", - curr->slave->bond->dev->name, - __get_agg_selection_mode(curr->lag_ports)); + pr_warn("%s: Impossible agg select mode %d\n", + curr->slave->bond->dev->name, + __get_agg_selection_mode(curr->lag_ports)); break; } @@ -1437,10 +1455,12 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, static int agg_device_up(const struct aggregator *agg) { struct port *port = agg->lag_ports; + if (!port) return 0; - return (netif_running(port->slave->dev) && - netif_carrier_ok(port->slave->dev)); + + return netif_running(port->slave->dev) && + netif_carrier_ok(port->slave->dev); } /** @@ -1492,8 +1512,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) if (best && __get_agg_selection_mode(best->lag_ports) == BOND_AD_STABLE) { - /* - * For the STABLE policy, don't replace the old active + /* For the STABLE policy, don't replace the old active * aggregator if it's still active (it has an answering * partner) or if both the best and active don't have an * answering partner. @@ -1501,7 +1520,8 @@ static void ad_agg_selection_logic(struct aggregator *agg) if (active && active->lag_ports && active->lag_ports->is_enabled && (__agg_has_partner(active) || - (!__agg_has_partner(active) && !__agg_has_partner(best)))) { + (!__agg_has_partner(active) && + !__agg_has_partner(best)))) { if (!(!active->actor_oper_aggregator_key && best->actor_oper_aggregator_key)) { best = NULL; @@ -1538,7 +1558,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) /* check if any partner replys */ if (best->is_individual) { - pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", + pr_warn("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", best->slave ? best->slave->bond->dev->name : "NULL"); } @@ -1552,7 +1572,9 @@ static void ad_agg_selection_logic(struct aggregator *agg) best->partner_oper_aggregator_key, best->is_individual, best->is_active); - /* disable the ports that were related to the former active_aggregator */ + /* disable the ports that were related to the former + * active_aggregator + */ if (active) { for (port = active->lag_ports; port; port = port->next_port_in_aggregator) { @@ -1561,8 +1583,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) } } - /* - * if the selected aggregator is of join individuals + /* if the selected aggregator is of join individuals * (partner_system is NULL), enable their ports */ active = __get_active_agg(origin); @@ -1584,7 +1605,6 @@ static void ad_agg_selection_logic(struct aggregator *agg) /** * ad_clear_agg - clear a given aggregator's parameters * @aggregator: the aggregator we're looking at - * */ static void ad_clear_agg(struct aggregator *aggregator) { @@ -1608,7 +1628,6 @@ static void ad_clear_agg(struct aggregator *aggregator) /** * ad_initialize_agg - initialize a given aggregator's parameters * @aggregator: the aggregator we're looking at - * */ static void ad_initialize_agg(struct aggregator *aggregator) { @@ -1625,7 +1644,6 @@ static void ad_initialize_agg(struct aggregator *aggregator) * ad_initialize_port - initialize a given port's parameters * @aggregator: the aggregator we're looking at * @lacp_fast: boolean. whether fast periodic should be used - * */ static void ad_initialize_port(struct port *port, int lacp_fast) { @@ -1657,8 +1675,10 @@ static void ad_initialize_port(struct port *port, int lacp_fast) port->ntt = false; port->actor_admin_port_key = 1; port->actor_oper_port_key = 1; - port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; - port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; + port->actor_admin_port_state = AD_STATE_AGGREGATION | + AD_STATE_LACP_ACTIVITY; + port->actor_oper_port_state = AD_STATE_AGGREGATION | + AD_STATE_LACP_ACTIVITY; if (lacp_fast) port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; @@ -1667,7 +1687,7 @@ static void ad_initialize_port(struct port *port, int lacp_fast) memcpy(&port->partner_oper, &tmpl, sizeof(tmpl)); port->is_enabled = true; - // ****** private parameters ****** + /* private parameters */ port->sm_vars = 0x3; port->sm_rx_state = 0; port->sm_rx_timer_counter = 0; @@ -1705,11 +1725,12 @@ static void ad_enable_collecting_distributing(struct port *port) /** * ad_disable_collecting_distributing - disable a port's transmit/receive * @port: the port we're looking at - * */ static void ad_disable_collecting_distributing(struct port *port) { - if (port->aggregator && !MAC_ADDRESS_EQUAL(&(port->aggregator->partner_system), &(null_mac_addr))) { + if (port->aggregator && + !MAC_ADDRESS_EQUAL(&(port->aggregator->partner_system), + &(null_mac_addr))) { pr_debug("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier); @@ -1717,66 +1738,22 @@ static void ad_disable_collecting_distributing(struct port *port) } } -#if 0 -/** - * ad_marker_info_send - send a marker information frame - * @port: the port we're looking at - * - * This function does nothing since we decided not to implement send and handle - * response for marker PDU's, in this stage, but only to respond to marker - * information. - */ -static void ad_marker_info_send(struct port *port) -{ - struct bond_marker marker; - u16 index; - - // fill the marker PDU with the appropriate values - marker.subtype = 0x02; - marker.version_number = 0x01; - marker.tlv_type = AD_MARKER_INFORMATION_SUBTYPE; - marker.marker_length = 0x16; - // convert requester_port to Big Endian - marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8)); - marker.requester_system = port->actor_system; - // convert requester_port(u32) to Big Endian - marker.requester_transaction_id = - (((++port->transaction_id & 0xFF) << 24) - | ((port->transaction_id & 0xFF00) << 8) - | ((port->transaction_id & 0xFF0000) >> 8) - | ((port->transaction_id & 0xFF000000) >> 24)); - marker.pad = 0; - marker.tlv_type_terminator = 0x00; - marker.terminator_length = 0x00; - for (index = 0; index < 90; index++) - marker.reserved_90[index] = 0; - - // send the marker information - if (ad_marker_send(port, &marker) >= 0) { - pr_debug("Sent Marker Information on port %d\n", - port->actor_port_number); - } -} -#endif - /** * ad_marker_info_received - handle receive of a Marker information frame * @marker_info: Marker info received * @port: the port we're looking at - * */ static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port) { struct bond_marker marker; - // copy the received marker data to the response marker - //marker = *marker_info; + /* copy the received marker data to the response marker */ memcpy(&marker, marker_info, sizeof(struct bond_marker)); - // change the marker subtype to marker response + /* change the marker subtype to marker response */ marker.tlv_type = AD_MARKER_RESPONSE_SUBTYPE; - // send the marker response + /* send the marker response */ if (ad_marker_send(port, &marker) >= 0) { pr_debug("Sent Marker Response on port %d\n", port->actor_port_number); @@ -1793,22 +1770,21 @@ static void ad_marker_info_received(struct bond_marker *marker_info, * information. */ static void ad_marker_response_received(struct bond_marker *marker, - struct port *port) + struct port *port) { - marker = NULL; /* just to satisfy the compiler */ - port = NULL; /* just to satisfy the compiler */ - // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW + marker = NULL; + port = NULL; + /* DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW */ } -////////////////////////////////////////////////////////////////////////////////////// -// ================= AD exported functions to the main bonding code ================== -////////////////////////////////////////////////////////////////////////////////////// +/* ========= AD exported functions to the main bonding code ========= */ -// Check aggregators status in team every T seconds +/* Check aggregators status in team every T seconds */ #define AD_AGGREGATOR_SELECTION_TIMER 8 -/* - * bond_3ad_initiate_agg_selection(struct bonding *bond) +/** + * bond_3ad_initiate_agg_selection - initate aggregator selection + * @bond: bonding struct * * Set the aggregation selection timer, to initiate an agg selection in * the very near future. Called during first initialization, and during @@ -1839,7 +1815,9 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); - // initialize how many times this module is called in one second(should be about every 100ms) + /* initialize how many times this module is called in one + * second (should be about every 100ms) + */ ad_ticks_per_sec = tick_resolution; bond_3ad_initiate_agg_selection(bond, @@ -1874,21 +1852,21 @@ void bond_3ad_bind_slave(struct slave *slave) port->actor_port_number = SLAVE_AD_INFO(slave).id; /* key is determined according to the link speed, duplex and user key(which * is yet not supported) - * ------------------------------------------------------------ - * Port key : | User key | Speed |Duplex| - * ------------------------------------------------------------ - * 16 6 1 0 */ - port->actor_admin_port_key = 0; /* initialize this parameter */ + port->actor_admin_port_key = 0; port->actor_admin_port_key |= __get_duplex(port); port->actor_admin_port_key |= (__get_link_speed(port) << 1); port->actor_oper_port_key = port->actor_admin_port_key; - /* if the port is not full duplex, then the port should be not lacp Enabled */ + /* if the port is not full duplex, then the port should be not + * lacp Enabled + */ if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) port->sm_vars &= ~AD_PORT_LACP_ENABLED; /* actor system is the bond's system */ port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; - /* tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) */ + /* tx timer(to verify that no more than MAX_TX_IN_SECOND + * lacpdu's are sent in one second) + */ port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; port->aggregator = NULL; port->next_port_in_aggregator = NULL; @@ -1925,16 +1903,13 @@ void bond_3ad_unbind_slave(struct slave *slave) struct slave *slave_iter; struct list_head *iter; - // find the aggregator related to this slave aggregator = &(SLAVE_AD_INFO(slave).aggregator); - - // find the port related to this slave port = &(SLAVE_AD_INFO(slave).port); - // if slave is null, the whole port is not initialized + /* if slave is null, the whole port is not initialized */ if (!port->slave) { - pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n", - slave->bond->dev->name, slave->dev->name); + pr_warn("Warning: %s: Trying to unbind an uninitialized port on %s\n", + slave->bond->dev->name, slave->dev->name); return; } @@ -1946,34 +1921,42 @@ void bond_3ad_unbind_slave(struct slave *slave) __update_lacpdu_from_port(port); ad_lacpdu_send(port); - // check if this aggregator is occupied + /* check if this aggregator is occupied */ if (aggregator->lag_ports) { - // check if there are other ports related to this aggregator except - // the port related to this slave(thats ensure us that there is a - // reason to search for new aggregator, and that we will find one - if ((aggregator->lag_ports != port) || (aggregator->lag_ports->next_port_in_aggregator)) { - // find new aggregator for the related port(s) + /* check if there are other ports related to this aggregator + * except the port related to this slave(thats ensure us that + * there is a reason to search for new aggregator, and that we + * will find one + */ + if ((aggregator->lag_ports != port) || + (aggregator->lag_ports->next_port_in_aggregator)) { + /* find new aggregator for the related port(s) */ bond_for_each_slave(bond, slave_iter, iter) { new_aggregator = &(SLAVE_AD_INFO(slave_iter).aggregator); - // if the new aggregator is empty, or it is connected to our port only - if (!new_aggregator->lag_ports - || ((new_aggregator->lag_ports == port) - && !new_aggregator->lag_ports->next_port_in_aggregator)) + /* if the new aggregator is empty, or it is + * connected to our port only + */ + if (!new_aggregator->lag_ports || + ((new_aggregator->lag_ports == port) && + !new_aggregator->lag_ports->next_port_in_aggregator)) break; } if (!slave_iter) new_aggregator = NULL; - // if new aggregator found, copy the aggregator's parameters - // and connect the related lag_ports to the new aggregator + + /* if new aggregator found, copy the aggregator's + * parameters and connect the related lag_ports to the + * new aggregator + */ if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) { pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier); - if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) { + if ((new_aggregator->lag_ports == port) && + new_aggregator->is_active) { pr_info("%s: Removing an active aggregator\n", aggregator->slave->bond->dev->name); - // select new active aggregator select_new_active_agg = 1; } @@ -1989,30 +1972,33 @@ void bond_3ad_unbind_slave(struct slave *slave) new_aggregator->is_active = aggregator->is_active; new_aggregator->num_of_ports = aggregator->num_of_ports; - // update the information that is written on the ports about the aggregator + /* update the information that is written on + * the ports about the aggregator + */ for (temp_port = aggregator->lag_ports; temp_port; temp_port = temp_port->next_port_in_aggregator) { temp_port->aggregator = new_aggregator; temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; } - // clear the aggregator ad_clear_agg(aggregator); if (select_new_active_agg) ad_agg_selection_logic(__get_first_agg(port)); } else { - pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", - slave->bond->dev->name); + pr_warn("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", + slave->bond->dev->name); } - } else { // in case that the only port related to this aggregator is the one we want to remove + } else { + /* in case that the only port related to this + * aggregator is the one we want to remove + */ select_new_active_agg = aggregator->is_active; - // clear the aggregator ad_clear_agg(aggregator); if (select_new_active_agg) { pr_info("%s: Removing an active aggregator\n", slave->bond->dev->name); - // select new active aggregator + /* select new active aggregator */ temp_aggregator = __get_first_agg(port); if (temp_aggregator) ad_agg_selection_logic(temp_aggregator); @@ -2021,15 +2007,19 @@ void bond_3ad_unbind_slave(struct slave *slave) } pr_debug("Unbinding port %d\n", port->actor_port_number); - // find the aggregator that this port is connected to + + /* find the aggregator that this port is connected to */ bond_for_each_slave(bond, slave_iter, iter) { temp_aggregator = &(SLAVE_AD_INFO(slave_iter).aggregator); prev_port = NULL; - // search the port in the aggregator's related ports + /* search the port in the aggregator's related ports */ for (temp_port = temp_aggregator->lag_ports; temp_port; prev_port = temp_port, - temp_port = temp_port->next_port_in_aggregator) { - if (temp_port == port) { // the aggregator found - detach the port from this aggregator + temp_port = temp_port->next_port_in_aggregator) { + if (temp_port == port) { + /* the aggregator found - detach the port from + * this aggregator + */ if (prev_port) prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator; else @@ -2037,12 +2027,11 @@ void bond_3ad_unbind_slave(struct slave *slave) temp_aggregator->num_of_ports--; if (temp_aggregator->num_of_ports == 0) { select_new_active_agg = temp_aggregator->is_active; - // clear the aggregator ad_clear_agg(temp_aggregator); if (select_new_active_agg) { pr_info("%s: Removing an active aggregator\n", slave->bond->dev->name); - // select new active aggregator + /* select new active aggregator */ ad_agg_selection_logic(__get_first_agg(port)); } } @@ -2083,15 +2072,16 @@ void bond_3ad_state_machine_handler(struct work_struct *work) goto re_arm; /* check if agg_select_timer timer after initialize is timed out */ - if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { + if (BOND_AD_INFO(bond).agg_select_timer && + !(--BOND_AD_INFO(bond).agg_select_timer)) { slave = bond_first_slave_rcu(bond); port = slave ? &(SLAVE_AD_INFO(slave).port) : NULL; /* select the active aggregator for the bond */ if (port) { if (!port->slave) { - pr_warning("%s: Warning: bond's first port is uninitialized\n", - bond->dev->name); + pr_warn("%s: Warning: bond's first port is uninitialized\n", + bond->dev->name); goto re_arm; } @@ -2105,8 +2095,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) bond_for_each_slave_rcu(bond, slave, iter) { port = &(SLAVE_AD_INFO(slave).port); if (!port->slave) { - pr_warning("%s: Warning: Found an uninitialized port\n", - bond->dev->name); + pr_warn("%s: Warning: Found an uninitialized port\n", + bond->dev->name); goto re_arm; } @@ -2145,7 +2135,8 @@ re_arm: * received frames (loopback). Since only the payload is given to this * function, it check for loopback. */ -static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length) +static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, + u16 length) { struct port *port; int ret = RX_HANDLER_ANOTHER; @@ -2155,8 +2146,8 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1 port = &(SLAVE_AD_INFO(slave).port); if (!port->slave) { - pr_warning("%s: Warning: port of slave %s is uninitialized\n", - slave->dev->name, slave->bond->dev->name); + pr_warn("%s: Warning: port of slave %s is uninitialized\n", + slave->dev->name, slave->bond->dev->name); return ret; } @@ -2173,7 +2164,9 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1 case AD_TYPE_MARKER: ret = RX_HANDLER_CONSUMED; - // No need to convert fields to Little Endian since we don't use the marker's fields. + /* No need to convert fields to Little Endian since we + * don't use the marker's fields. + */ switch (((struct bond_marker *)lacpdu)->tlv_type) { case AD_MARKER_INFORMATION_SUBTYPE: @@ -2211,8 +2204,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) /* if slave is null, the whole port is not initialized */ if (!port->slave) { - pr_warning("Warning: %s: speed changed for uninitialized port on %s\n", - slave->bond->dev->name, slave->dev->name); + pr_warn("Warning: %s: speed changed for uninitialized port on %s\n", + slave->bond->dev->name, slave->dev->name); return; } @@ -2244,8 +2237,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) /* if slave is null, the whole port is not initialized */ if (!port->slave) { - pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n", - slave->bond->dev->name, slave->dev->name); + pr_warn("%s: Warning: duplex changed for uninitialized port on %s\n", + slave->bond->dev->name, slave->dev->name); return; } @@ -2278,8 +2271,8 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) /* if slave is null, the whole port is not initialized */ if (!port->slave) { - pr_warning("Warning: %s: link status changed for uninitialized port on %s\n", - slave->bond->dev->name, slave->dev->name); + pr_warn("Warning: %s: link status changed for uninitialized port on %s\n", + slave->bond->dev->name, slave->dev->name); return; } @@ -2317,10 +2310,13 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) __release_state_machine_lock(port); } -/* - * set link state for bonding master: if we have an active - * aggregator, we're up, if not, we're down. Presumes that we cannot - * have an active aggregator if there are no slaves with link up. +/** + * bond_3ad_set_carrier - set link state for bonding master + * @bond - bonding structure + * + * if we have an active aggregator, we're up, if not, we're down. + * Presumes that we cannot have an active aggregator if there are + * no slaves with link up. * * This behavior complies with IEEE 802.3 section 43.3.9. * @@ -2388,7 +2384,8 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond, ad_info->ports = aggregator->num_of_ports; ad_info->actor_key = aggregator->actor_oper_aggregator_key; ad_info->partner_key = aggregator->partner_oper_aggregator_key; - memcpy(ad_info->partner_system, aggregator->partner_system.mac_addr_value, ETH_ALEN); + memcpy(ad_info->partner_system, + aggregator->partner_system.mac_addr_value, ETH_ALEN); return 0; } @@ -2460,7 +2457,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) } /* we couldn't find any suitable slave after the agg_no, so use the - * first suitable found, if found. */ + * first suitable found, if found. + */ if (first_ok_slave) bond_dev_queue_xmit(bond, skb, first_ok_slave->dev); else @@ -2493,7 +2491,10 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, return ret; } -/* +/** + * bond_3ad_update_lacp_rate - change the lacp rate + * @bond - bonding struct + * * When modify lacp_rate parameter via sysfs, * update actor_oper_port_state of each port. * diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index eb105abcf0e..0578fb90d8f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -2057,7 +2057,6 @@ int bnx2x_del_all_macs(struct bnx2x *bp, void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p); void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, u8 vf_valid, int fw_sb_id, int igu_sb_id); -u32 bnx2x_get_pretend_reg(struct bnx2x *bp); int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); int bnx2x_set_mult_gpio(struct bnx2x *bp, u8 pins, u32 mode); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 282ebf61f53..cdc12ea0fc3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -30,6 +30,43 @@ #include "bnx2x_init.h" #include "bnx2x_sp.h" +static void bnx2x_free_fp_mem_cnic(struct bnx2x *bp); +static int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp); +static int bnx2x_alloc_fp_mem(struct bnx2x *bp); +static int bnx2x_poll(struct napi_struct *napi, int budget); + +static void bnx2x_add_all_napi_cnic(struct bnx2x *bp) +{ + int i; + + /* Add NAPI objects */ + for_each_rx_queue_cnic(bp, i) { + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), + bnx2x_poll, NAPI_POLL_WEIGHT); + napi_hash_add(&bnx2x_fp(bp, i, napi)); + } +} + +static void bnx2x_add_all_napi(struct bnx2x *bp) +{ + int i; + + /* Add NAPI objects */ + for_each_eth_queue(bp, i) { + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), + bnx2x_poll, NAPI_POLL_WEIGHT); + napi_hash_add(&bnx2x_fp(bp, i, napi)); + } +} + +static int bnx2x_calc_num_queues(struct bnx2x *bp) +{ + return bnx2x_num_queues ? + min_t(int, bnx2x_num_queues, BNX2X_MAX_QUEUES(bp)) : + min_t(int, netif_get_num_default_rss_queues(), + BNX2X_MAX_QUEUES(bp)); +} + /** * bnx2x_move_fp - move content of the fastpath structure. * @@ -145,7 +182,7 @@ static void bnx2x_shrink_eth_fp(struct bnx2x *bp, int delta) } } -int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ +int bnx2x_load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ /* free skb in the packet ring at pos idx * return idx of last bd freed @@ -813,7 +850,7 @@ void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, skb->ip_summed = CHECKSUM_UNNECESSARY; } -int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) +static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) { struct bnx2x *bp = fp->bp; u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons; @@ -1483,7 +1520,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp) } } -void bnx2x_free_skbs_cnic(struct bnx2x *bp) +static void bnx2x_free_skbs_cnic(struct bnx2x *bp) { bnx2x_free_tx_skbs_cnic(bp); bnx2x_free_rx_skbs_cnic(bp); @@ -2302,16 +2339,16 @@ static int bnx2x_nic_load_no_mcp(struct bnx2x *bp, int port) int path = BP_PATH(bp); DP(NETIF_MSG_IFUP, "NO MCP - load counts[%d] %d, %d, %d\n", - path, load_count[path][0], load_count[path][1], - load_count[path][2]); - load_count[path][0]++; - load_count[path][1 + port]++; + path, bnx2x_load_count[path][0], bnx2x_load_count[path][1], + bnx2x_load_count[path][2]); + bnx2x_load_count[path][0]++; + bnx2x_load_count[path][1 + port]++; DP(NETIF_MSG_IFUP, "NO MCP - new load counts[%d] %d, %d, %d\n", - path, load_count[path][0], load_count[path][1], - load_count[path][2]); - if (load_count[path][0] == 1) + path, bnx2x_load_count[path][0], bnx2x_load_count[path][1], + bnx2x_load_count[path][2]); + if (bnx2x_load_count[path][0] == 1) return FW_MSG_CODE_DRV_LOAD_COMMON; - else if (load_count[path][1 + port] == 1) + else if (bnx2x_load_count[path][1 + port] == 1) return FW_MSG_CODE_DRV_LOAD_PORT; else return FW_MSG_CODE_DRV_LOAD_FUNCTION; @@ -3069,7 +3106,7 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) /* * net_device service functions */ -int bnx2x_poll(struct napi_struct *napi, int budget) +static int bnx2x_poll(struct napi_struct *napi, int budget) { int work_done = 0; u8 cos; @@ -4196,7 +4233,7 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) /* end of fastpath */ } -void bnx2x_free_fp_mem_cnic(struct bnx2x *bp) +static void bnx2x_free_fp_mem_cnic(struct bnx2x *bp) { int i; for_each_cnic_queue(bp, i) @@ -4410,7 +4447,7 @@ alloc_mem_err: return 0; } -int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp) +static int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp) { if (!NO_FCOE(bp)) /* FCoE */ @@ -4423,7 +4460,7 @@ int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp) return 0; } -int bnx2x_alloc_fp_mem(struct bnx2x *bp) +static int bnx2x_alloc_fp_mem(struct bnx2x *bp) { int i; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index da8fcaa7449..7ebbddc7290 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -26,10 +26,8 @@ #include "bnx2x_sriov.h" /* This is used as a replacement for an MCP if it's not present */ -extern int load_count[2][3]; /* per-path: 0-common, 1-port0, 2-port1 */ - -extern int num_queues; -extern int int_mode; +extern int bnx2x_load_count[2][3]; /* per-path: 0-common, 1-port0, 2-port1 */ +extern int bnx2x_num_queues; /************************ Macros ********************************/ #define BNX2X_PCI_FREE(x, y, size) \ @@ -417,35 +415,8 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set); * If bp->state is OPEN, should be called with * netif_addr_lock_bh() */ -void bnx2x_set_rx_mode(struct net_device *dev); void bnx2x_set_rx_mode_inner(struct bnx2x *bp); -/** - * bnx2x_set_storm_rx_mode - configure MAC filtering rules in a FW. - * - * @bp: driver handle - * - * If bp->state is OPEN, should be called with - * netif_addr_lock_bh(). - */ -int bnx2x_set_storm_rx_mode(struct bnx2x *bp); - -/** - * bnx2x_set_q_rx_mode - configures rx_mode for a single queue. - * - * @bp: driver handle - * @cl_id: client id - * @rx_mode_flags: rx mode configuration - * @rx_accept_flags: rx accept configuration - * @tx_accept_flags: tx accept configuration (tx switch) - * @ramrod_flags: ramrod configuration - */ -int bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, - unsigned long rx_mode_flags, - unsigned long rx_accept_flags, - unsigned long tx_accept_flags, - unsigned long ramrod_flags); - /* Parity errors related */ void bnx2x_set_pf_load(struct bnx2x *bp); bool bnx2x_clear_pf_load(struct bnx2x *bp); @@ -564,9 +535,6 @@ int bnx2x_reload_if_running(struct net_device *dev); int bnx2x_change_mac_addr(struct net_device *dev, void *p); -/* NAPI poll Rx part */ -int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); - /* NAPI poll Tx part */ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata); @@ -577,13 +545,9 @@ int bnx2x_resume(struct pci_dev *pdev); /* Release IRQ vectors */ void bnx2x_free_irq(struct bnx2x *bp); -void bnx2x_free_fp_mem_cnic(struct bnx2x *bp); void bnx2x_free_fp_mem(struct bnx2x *bp); -int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp); -int bnx2x_alloc_fp_mem(struct bnx2x *bp); void bnx2x_init_rx_rings(struct bnx2x *bp); void bnx2x_init_rx_rings_cnic(struct bnx2x *bp); -void bnx2x_free_skbs_cnic(struct bnx2x *bp); void bnx2x_free_skbs(struct bnx2x *bp); void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); void bnx2x_netif_start(struct bnx2x *bp); @@ -606,15 +570,6 @@ int bnx2x_enable_msix(struct bnx2x *bp); */ int bnx2x_enable_msi(struct bnx2x *bp); -/** - * bnx2x_poll - NAPI callback - * - * @napi: napi structure - * @budget: - * - */ -int bnx2x_poll(struct napi_struct *napi, int budget); - /** * bnx2x_low_latency_recv - LL callback * @@ -861,30 +816,6 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, sge->addr_lo = 0; } -static inline void bnx2x_add_all_napi_cnic(struct bnx2x *bp) -{ - int i; - - /* Add NAPI objects */ - for_each_rx_queue_cnic(bp, i) { - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, NAPI_POLL_WEIGHT); - napi_hash_add(&bnx2x_fp(bp, i, napi)); - } -} - -static inline void bnx2x_add_all_napi(struct bnx2x *bp) -{ - int i; - - /* Add NAPI objects */ - for_each_eth_queue(bp, i) { - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, NAPI_POLL_WEIGHT); - napi_hash_add(&bnx2x_fp(bp, i, napi)); - } -} - static inline void bnx2x_del_all_napi_cnic(struct bnx2x *bp) { int i; @@ -918,14 +849,6 @@ static inline void bnx2x_disable_msi(struct bnx2x *bp) } } -static inline int bnx2x_calc_num_queues(struct bnx2x *bp) -{ - return num_queues ? - min_t(int, num_queues, BNX2X_MAX_QUEUES(bp)) : - min_t(int, netif_get_num_default_rss_queues(), - BNX2X_MAX_QUEUES(bp)); -} - static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) { int i, j; @@ -1172,8 +1095,6 @@ static inline u8 bnx2x_fp_qzone_id(struct bnx2x_fastpath *fp) return fp->cl_id; } -u32 bnx2x_rx_ustorm_prods_offset(struct bnx2x_fastpath *fp); - static inline void bnx2x_init_txdata(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, u32 cid, int txq_index, __le16 *tx_cons_sb, @@ -1206,47 +1127,6 @@ static inline u8 bnx2x_cnic_igu_sb_id(struct bnx2x *bp) return bp->igu_base_sb; } -static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) -{ - struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); - unsigned long q_type = 0; - - bnx2x_fcoe(bp, rx_queue) = BNX2X_NUM_ETH_QUEUES(bp); - bnx2x_fcoe(bp, cl_id) = bnx2x_cnic_eth_cl_id(bp, - BNX2X_FCOE_ETH_CL_ID_IDX); - bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID(bp); - bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; - bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; - bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; - bnx2x_init_txdata(bp, bnx2x_fcoe(bp, txdata_ptr[0]), - fp->cid, FCOE_TXQ_IDX(bp), BNX2X_FCOE_L2_TX_INDEX, - fp); - - DP(NETIF_MSG_IFUP, "created fcoe tx data (fp index %d)\n", fp->index); - - /* qZone id equals to FW (per path) client id */ - bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fp_qzone_id(fp); - /* init shortcut */ - bnx2x_fcoe(bp, ustorm_rx_prods_offset) = - bnx2x_rx_ustorm_prods_offset(fp); - - /* Configure Queue State object */ - __set_bit(BNX2X_Q_TYPE_HAS_RX, &q_type); - __set_bit(BNX2X_Q_TYPE_HAS_TX, &q_type); - - /* No multi-CoS for FCoE L2 client */ - BUG_ON(fp->max_cos != 1); - - bnx2x_init_queue_obj(bp, &bnx2x_sp_obj(bp, fp).q_obj, fp->cl_id, - &fp->cid, 1, BP_FUNC(bp), bnx2x_sp(bp, q_rdata), - bnx2x_sp_mapping(bp, q_rdata), q_type); - - DP(NETIF_MSG_IFUP, - "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d fw_sb %d igu_sb %d\n", - fp->index, bp, fp->status_blk.e2_sb, fp->cl_id, fp->fw_sb_id, - fp->igu_sb_id); -} - static inline int bnx2x_clean_tx_queue(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) { diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 11fc7958549..c5ce99be4d9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -205,6 +205,11 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy, (_bank + (_addr & 0xf)), \ _val) +static int bnx2x_check_half_open_conn(struct link_params *params, + struct link_vars *vars, u8 notify); +static int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, + struct link_params *params); + static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) { u32 val = REG_RD(bp, reg); @@ -1399,57 +1404,6 @@ static void bnx2x_update_pfc_xmac(struct link_params *params, udelay(30); } - -static void bnx2x_emac_get_pfc_stat(struct link_params *params, - u32 pfc_frames_sent[2], - u32 pfc_frames_received[2]) -{ - /* Read pfc statistic */ - struct bnx2x *bp = params->bp; - u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 val_xon = 0; - u32 val_xoff = 0; - - DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n"); - - /* PFC received frames */ - val_xoff = REG_RD(bp, emac_base + - EMAC_REG_RX_PFC_STATS_XOFF_RCVD); - val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT; - val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD); - val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT; - - pfc_frames_received[0] = val_xon + val_xoff; - - /* PFC received sent */ - val_xoff = REG_RD(bp, emac_base + - EMAC_REG_RX_PFC_STATS_XOFF_SENT); - val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT; - val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT); - val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT; - - pfc_frames_sent[0] = val_xon + val_xoff; -} - -/* Read pfc statistic*/ -void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, - u32 pfc_frames_sent[2], - u32 pfc_frames_received[2]) -{ - /* Read pfc statistic */ - struct bnx2x *bp = params->bp; - - DP(NETIF_MSG_LINK, "pfc statistic\n"); - - if (!vars->link_up) - return; - - if (vars->mac_type == MAC_TYPE_EMAC) { - DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n"); - bnx2x_emac_get_pfc_stat(params, pfc_frames_sent, - pfc_frames_received); - } -} /******************************************************************/ /* MAC/PBF section */ /******************************************************************/ @@ -13413,9 +13367,9 @@ static u8 bnx2x_analyze_link_error(struct link_params *params, * a fault, for example, due to break in the TX side of fiber. * ******************************************************************************/ -int bnx2x_check_half_open_conn(struct link_params *params, - struct link_vars *vars, - u8 notify) +static int bnx2x_check_half_open_conn(struct link_params *params, + struct link_vars *vars, + u8 notify) { struct bnx2x *bp = params->bp; u32 lss_status = 0; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index 4df45234fdc..389f5f8cb0a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -533,19 +533,11 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); int bnx2x_ets_e3b0_config(const struct link_params *params, const struct link_vars *vars, struct bnx2x_ets_params *ets_params); -/* Read pfc statistic*/ -void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, - u32 pfc_frames_sent[2], - u32 pfc_frames_received[2]); + void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, u32 chip_id, u32 shmem_base, u32 shmem2_base, u8 port); -int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, - struct link_params *params); - void bnx2x_period_func(struct link_params *params, struct link_vars *vars); -int bnx2x_check_half_open_conn(struct link_params *params, - struct link_vars *vars, u8 notify); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 18498fed520..f90079acb58 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -94,8 +94,8 @@ MODULE_FIRMWARE(FW_FILE_NAME_E1); MODULE_FIRMWARE(FW_FILE_NAME_E1H); MODULE_FIRMWARE(FW_FILE_NAME_E2); -int num_queues; -module_param(num_queues, int, 0); +int bnx2x_num_queues; +module_param_named(num_queues, bnx2x_num_queues, int, 0); MODULE_PARM_DESC(num_queues, " Set number of queues (default is as a number of CPUs)"); @@ -103,7 +103,7 @@ static int disable_tpa; module_param(disable_tpa, int, 0); MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); -int int_mode; +static int int_mode; module_param(int_mode, int, 0); MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " "(1 INT#x; 2 MSI)"); @@ -279,6 +279,12 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); #define BNX2X_PREV_WAIT_NEEDED 1 static DEFINE_SEMAPHORE(bnx2x_prev_sem); static LIST_HEAD(bnx2x_prev_list); + +/* Forward declaration */ +static struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev); +static u32 bnx2x_rx_ustorm_prods_offset(struct bnx2x_fastpath *fp); +static int bnx2x_set_storm_rx_mode(struct bnx2x *bp); + /**************************************************************************** * General service functions ****************************************************************************/ @@ -5857,11 +5863,11 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp) } /* called with netif_addr_lock_bh() */ -int bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, - unsigned long rx_mode_flags, - unsigned long rx_accept_flags, - unsigned long tx_accept_flags, - unsigned long ramrod_flags) +static int bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, + unsigned long rx_mode_flags, + unsigned long rx_accept_flags, + unsigned long tx_accept_flags, + unsigned long ramrod_flags) { struct bnx2x_rx_mode_ramrod_params ramrod_param; int rc; @@ -5969,7 +5975,7 @@ static int bnx2x_fill_accept_flags(struct bnx2x *bp, u32 rx_mode, } /* called with netif_addr_lock_bh() */ -int bnx2x_set_storm_rx_mode(struct bnx2x *bp) +static int bnx2x_set_storm_rx_mode(struct bnx2x *bp) { unsigned long rx_mode_flags = 0, ramrod_flags = 0; unsigned long rx_accept_flags = 0, tx_accept_flags = 0; @@ -6165,6 +6171,47 @@ static void bnx2x_init_tx_rings(struct bnx2x *bp) bnx2x_init_tx_ring_one(bp->fp[i].txdata_ptr[cos]); } +static void bnx2x_init_fcoe_fp(struct bnx2x *bp) +{ + struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); + unsigned long q_type = 0; + + bnx2x_fcoe(bp, rx_queue) = BNX2X_NUM_ETH_QUEUES(bp); + bnx2x_fcoe(bp, cl_id) = bnx2x_cnic_eth_cl_id(bp, + BNX2X_FCOE_ETH_CL_ID_IDX); + bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID(bp); + bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; + bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; + bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; + bnx2x_init_txdata(bp, bnx2x_fcoe(bp, txdata_ptr[0]), + fp->cid, FCOE_TXQ_IDX(bp), BNX2X_FCOE_L2_TX_INDEX, + fp); + + DP(NETIF_MSG_IFUP, "created fcoe tx data (fp index %d)\n", fp->index); + + /* qZone id equals to FW (per path) client id */ + bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fp_qzone_id(fp); + /* init shortcut */ + bnx2x_fcoe(bp, ustorm_rx_prods_offset) = + bnx2x_rx_ustorm_prods_offset(fp); + + /* Configure Queue State object */ + __set_bit(BNX2X_Q_TYPE_HAS_RX, &q_type); + __set_bit(BNX2X_Q_TYPE_HAS_TX, &q_type); + + /* No multi-CoS for FCoE L2 client */ + BUG_ON(fp->max_cos != 1); + + bnx2x_init_queue_obj(bp, &bnx2x_sp_obj(bp, fp).q_obj, fp->cl_id, + &fp->cid, 1, BP_FUNC(bp), bnx2x_sp(bp, q_rdata), + bnx2x_sp_mapping(bp, q_rdata), q_type); + + DP(NETIF_MSG_IFUP, + "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d fw_sb %d igu_sb %d\n", + fp->index, bp, fp->status_blk.e2_sb, fp->cl_id, fp->fw_sb_id, + fp->igu_sb_id); +} + void bnx2x_nic_init_cnic(struct bnx2x *bp) { if (!NO_FCOE(bp)) @@ -8737,16 +8784,16 @@ u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode) int path = BP_PATH(bp); DP(NETIF_MSG_IFDOWN, "NO MCP - load counts[%d] %d, %d, %d\n", - path, load_count[path][0], load_count[path][1], - load_count[path][2]); - load_count[path][0]--; - load_count[path][1 + port]--; + path, bnx2x_load_count[path][0], bnx2x_load_count[path][1], + bnx2x_load_count[path][2]); + bnx2x_load_count[path][0]--; + bnx2x_load_count[path][1 + port]--; DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts[%d] %d, %d, %d\n", - path, load_count[path][0], load_count[path][1], - load_count[path][2]); - if (load_count[path][0] == 0) + path, bnx2x_load_count[path][0], bnx2x_load_count[path][1], + bnx2x_load_count[path][2]); + if (bnx2x_load_count[path][0] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; - else if (load_count[path][1 + port] == 0) + else if (bnx2x_load_count[path][1 + port] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; else reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; @@ -9772,7 +9819,7 @@ period_task_exit: * Init service functions */ -u32 bnx2x_get_pretend_reg(struct bnx2x *bp) +static u32 bnx2x_get_pretend_reg(struct bnx2x *bp) { u32 base = PXP2_REG_PGL_PRETEND_FUNC_F0; u32 stride = PXP2_REG_PGL_PRETEND_FUNC_F1 - base; @@ -12005,7 +12052,7 @@ static int bnx2x_set_mc_list(struct bnx2x *bp) } /* If bp->state is OPEN, should be called with netif_addr_lock_bh() */ -void bnx2x_set_rx_mode(struct net_device *dev) +static void bnx2x_set_rx_mode(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); @@ -12783,8 +12830,6 @@ static int set_is_vf(int chip_id) } } -struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev); - static int bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -13859,7 +13904,7 @@ static int bnx2x_unregister_cnic(struct net_device *dev) return 0; } -struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) +static struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); struct cnic_eth_dev *cp = &bp->cnic_eth_dev; @@ -13909,7 +13954,7 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) return cp; } -u32 bnx2x_rx_ustorm_prods_offset(struct bnx2x_fastpath *fp) +static u32 bnx2x_rx_ustorm_prods_offset(struct bnx2x_fastpath *fp) { struct bnx2x *bp = fp->bp; u32 offset = BAR_USTRORM_INTMEM; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 98cccd487fc..9373584e400 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -355,23 +355,6 @@ static bool bnx2x_get_credit_vlan(struct bnx2x_vlan_mac_obj *o) return vp->get(vp, 1); } - -static bool bnx2x_get_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o) -{ - struct bnx2x_credit_pool_obj *mp = o->macs_pool; - struct bnx2x_credit_pool_obj *vp = o->vlans_pool; - - if (!mp->get(mp, 1)) - return false; - - if (!vp->get(vp, 1)) { - mp->put(mp, 1); - return false; - } - - return true; -} - static bool bnx2x_put_cam_offset_mac(struct bnx2x_vlan_mac_obj *o, int offset) { struct bnx2x_credit_pool_obj *mp = o->macs_pool; @@ -400,22 +383,6 @@ static bool bnx2x_put_credit_vlan(struct bnx2x_vlan_mac_obj *o) return vp->put(vp, 1); } -static bool bnx2x_put_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o) -{ - struct bnx2x_credit_pool_obj *mp = o->macs_pool; - struct bnx2x_credit_pool_obj *vp = o->vlans_pool; - - if (!mp->put(mp, 1)) - return false; - - if (!vp->put(vp, 1)) { - mp->get(mp, 1); - return false; - } - - return true; -} - /** * __bnx2x_vlan_mac_h_write_trylock - try getting the vlan mac writer lock * @@ -507,22 +474,6 @@ static void __bnx2x_vlan_mac_h_write_unlock(struct bnx2x *bp, } } -/** - * bnx2x_vlan_mac_h_write_unlock - unlock the vlan mac head list writer lock - * - * @bp: device handle - * @o: vlan_mac object - * - * @details Notice if a pending execution exists, it would perform it - - * possibly releasing and reclaiming the execution queue lock. - */ -void bnx2x_vlan_mac_h_write_unlock(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *o) -{ - spin_lock_bh(&o->exe_queue.lock); - __bnx2x_vlan_mac_h_write_unlock(bp, o); - spin_unlock_bh(&o->exe_queue.lock); -} /** * __bnx2x_vlan_mac_h_read_lock - lock the vlan mac head list reader lock @@ -685,25 +636,6 @@ static int bnx2x_check_vlan_add(struct bnx2x *bp, return 0; } -static int bnx2x_check_vlan_mac_add(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *o, - union bnx2x_classification_ramrod_data *data) -{ - struct bnx2x_vlan_mac_registry_elem *pos; - - DP(BNX2X_MSG_SP, "Checking VLAN_MAC (%pM, %d) for ADD command\n", - data->vlan_mac.mac, data->vlan_mac.vlan); - - list_for_each_entry(pos, &o->head, link) - if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && - ether_addr_equal_unaligned(data->vlan_mac.mac, pos->u.vlan_mac.mac) && - (data->vlan_mac.is_inner_mac == - pos->u.vlan_mac.is_inner_mac)) - return -EEXIST; - - return 0; -} - /* check_del() callbacks */ static struct bnx2x_vlan_mac_registry_elem * bnx2x_check_mac_del(struct bnx2x *bp, @@ -738,26 +670,6 @@ static struct bnx2x_vlan_mac_registry_elem * return NULL; } -static struct bnx2x_vlan_mac_registry_elem * - bnx2x_check_vlan_mac_del(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *o, - union bnx2x_classification_ramrod_data *data) -{ - struct bnx2x_vlan_mac_registry_elem *pos; - - DP(BNX2X_MSG_SP, "Checking VLAN_MAC (%pM, %d) for DEL command\n", - data->vlan_mac.mac, data->vlan_mac.vlan); - - list_for_each_entry(pos, &o->head, link) - if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && - ether_addr_equal_unaligned(data->vlan_mac.mac, pos->u.vlan_mac.mac) && - (data->vlan_mac.is_inner_mac == - pos->u.vlan_mac.is_inner_mac)) - return pos; - - return NULL; -} - /* check_move() callback */ static bool bnx2x_check_move(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *src_o, @@ -809,8 +721,8 @@ static inline u8 bnx2x_vlan_mac_get_rx_tx_flag(struct bnx2x_vlan_mac_obj *o) return rx_tx_flag; } -void bnx2x_set_mac_in_nig(struct bnx2x *bp, - bool add, unsigned char *dev_addr, int index) +static void bnx2x_set_mac_in_nig(struct bnx2x *bp, + bool add, unsigned char *dev_addr, int index) { u32 wb_data[2]; u32 reg_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM : @@ -1124,97 +1036,6 @@ static void bnx2x_set_one_vlan_e2(struct bnx2x *bp, rule_cnt); } -static void bnx2x_set_one_vlan_mac_e2(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *o, - struct bnx2x_exeq_elem *elem, - int rule_idx, int cam_offset) -{ - struct bnx2x_raw_obj *raw = &o->raw; - struct eth_classify_rules_ramrod_data *data = - (struct eth_classify_rules_ramrod_data *)(raw->rdata); - int rule_cnt = rule_idx + 1; - union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx]; - enum bnx2x_vlan_mac_cmd cmd = elem->cmd_data.vlan_mac.cmd; - bool add = (cmd == BNX2X_VLAN_MAC_ADD) ? true : false; - u16 vlan = elem->cmd_data.vlan_mac.u.vlan_mac.vlan; - u8 *mac = elem->cmd_data.vlan_mac.u.vlan_mac.mac; - - /* Reset the ramrod data buffer for the first rule */ - if (rule_idx == 0) - memset(data, 0, sizeof(*data)); - - /* Set a rule header */ - bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_PAIR, - &rule_entry->pair.header); - - /* Set VLAN and MAC themselves */ - rule_entry->pair.vlan = cpu_to_le16(vlan); - bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, - &rule_entry->pair.mac_mid, - &rule_entry->pair.mac_lsb, mac); - rule_entry->pair.inner_mac = - cpu_to_le16(elem->cmd_data.vlan_mac.u.vlan_mac.is_inner_mac); - /* MOVE: Add a rule that will add this MAC to the target Queue */ - if (cmd == BNX2X_VLAN_MAC_MOVE) { - rule_entry++; - rule_cnt++; - - /* Setup ramrod data */ - bnx2x_vlan_mac_set_cmd_hdr_e2(bp, - elem->cmd_data.vlan_mac.target_obj, - true, CLASSIFY_RULE_OPCODE_PAIR, - &rule_entry->pair.header); - - /* Set a VLAN itself */ - rule_entry->pair.vlan = cpu_to_le16(vlan); - bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, - &rule_entry->pair.mac_mid, - &rule_entry->pair.mac_lsb, mac); - rule_entry->pair.inner_mac = - cpu_to_le16(elem->cmd_data.vlan_mac.u. - vlan_mac.is_inner_mac); - } - - /* Set the ramrod data header */ - /* TODO: take this to the higher level in order to prevent multiple - writing */ - bnx2x_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header, - rule_cnt); -} - -/** - * bnx2x_set_one_vlan_mac_e1h - - * - * @bp: device handle - * @o: bnx2x_vlan_mac_obj - * @elem: bnx2x_exeq_elem - * @rule_idx: rule_idx - * @cam_offset: cam_offset - */ -static void bnx2x_set_one_vlan_mac_e1h(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *o, - struct bnx2x_exeq_elem *elem, - int rule_idx, int cam_offset) -{ - struct bnx2x_raw_obj *raw = &o->raw; - struct mac_configuration_cmd *config = - (struct mac_configuration_cmd *)(raw->rdata); - /* 57710 and 57711 do not support MOVE command, - * so it's either ADD or DEL - */ - bool add = (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ? - true : false; - - /* Reset the ramrod data buffer */ - memset(config, 0, sizeof(*config)); - - bnx2x_vlan_mac_set_rdata_e1x(bp, o, BNX2X_FILTER_VLAN_MAC_PENDING, - cam_offset, add, - elem->cmd_data.vlan_mac.u.vlan_mac.mac, - elem->cmd_data.vlan_mac.u.vlan_mac.vlan, - ETH_VLAN_FILTER_CLASSIFY, config); -} - /** * bnx2x_vlan_mac_restore - reconfigure next MAC/VLAN/VLAN-MAC element * @@ -1314,24 +1135,6 @@ static struct bnx2x_exeq_elem *bnx2x_exeq_get_vlan( return NULL; } -static struct bnx2x_exeq_elem *bnx2x_exeq_get_vlan_mac( - struct bnx2x_exe_queue_obj *o, - struct bnx2x_exeq_elem *elem) -{ - struct bnx2x_exeq_elem *pos; - struct bnx2x_vlan_mac_ramrod_data *data = - &elem->cmd_data.vlan_mac.u.vlan_mac; - - /* Check pending for execution commands */ - list_for_each_entry(pos, &o->exe_queue, link) - if (!memcmp(&pos->cmd_data.vlan_mac.u.vlan_mac, data, - sizeof(*data)) && - (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd)) - return pos; - - return NULL; -} - /** * bnx2x_validate_vlan_mac_add - check if an ADD command can be executed * @@ -2239,69 +2042,6 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp, } } -void bnx2x_init_vlan_mac_obj(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *vlan_mac_obj, - u8 cl_id, u32 cid, u8 func_id, void *rdata, - dma_addr_t rdata_mapping, int state, - unsigned long *pstate, bnx2x_obj_type type, - struct bnx2x_credit_pool_obj *macs_pool, - struct bnx2x_credit_pool_obj *vlans_pool) -{ - union bnx2x_qable_obj *qable_obj = - (union bnx2x_qable_obj *)vlan_mac_obj; - - bnx2x_init_vlan_mac_common(vlan_mac_obj, cl_id, cid, func_id, rdata, - rdata_mapping, state, pstate, type, - macs_pool, vlans_pool); - - /* CAM pool handling */ - vlan_mac_obj->get_credit = bnx2x_get_credit_vlan_mac; - vlan_mac_obj->put_credit = bnx2x_put_credit_vlan_mac; - /* CAM offset is relevant for 57710 and 57711 chips only which have a - * single CAM for both MACs and VLAN-MAC pairs. So the offset - * will be taken from MACs' pool object only. - */ - vlan_mac_obj->get_cam_offset = bnx2x_get_cam_offset_mac; - vlan_mac_obj->put_cam_offset = bnx2x_put_cam_offset_mac; - - if (CHIP_IS_E1(bp)) { - BNX2X_ERR("Do not support chips others than E2\n"); - BUG(); - } else if (CHIP_IS_E1H(bp)) { - vlan_mac_obj->set_one_rule = bnx2x_set_one_vlan_mac_e1h; - vlan_mac_obj->check_del = bnx2x_check_vlan_mac_del; - vlan_mac_obj->check_add = bnx2x_check_vlan_mac_add; - vlan_mac_obj->check_move = bnx2x_check_move_always_err; - vlan_mac_obj->ramrod_cmd = RAMROD_CMD_ID_ETH_SET_MAC; - - /* Exe Queue */ - bnx2x_exe_queue_init(bp, - &vlan_mac_obj->exe_queue, 1, qable_obj, - bnx2x_validate_vlan_mac, - bnx2x_remove_vlan_mac, - bnx2x_optimize_vlan_mac, - bnx2x_execute_vlan_mac, - bnx2x_exeq_get_vlan_mac); - } else { - vlan_mac_obj->set_one_rule = bnx2x_set_one_vlan_mac_e2; - vlan_mac_obj->check_del = bnx2x_check_vlan_mac_del; - vlan_mac_obj->check_add = bnx2x_check_vlan_mac_add; - vlan_mac_obj->check_move = bnx2x_check_move; - vlan_mac_obj->ramrod_cmd = - RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; - - /* Exe Queue */ - bnx2x_exe_queue_init(bp, - &vlan_mac_obj->exe_queue, - CLASSIFY_RULES_COUNT, - qable_obj, bnx2x_validate_vlan_mac, - bnx2x_remove_vlan_mac, - bnx2x_optimize_vlan_mac, - bnx2x_execute_vlan_mac, - bnx2x_exeq_get_vlan_mac); - } -} - /* RX_MODE verbs: DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */ static inline void __storm_memset_mac_filters(struct bnx2x *bp, struct tstorm_eth_mac_filter_config *mac_filters, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index 6a53c15c85a..c8b939b141d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -448,9 +448,6 @@ enum { BNX2X_LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE / 2 }; -void bnx2x_set_mac_in_nig(struct bnx2x *bp, - bool add, unsigned char *dev_addr, int index); - /** RX_MODE verbs:DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */ /* RX_MODE ramrod special flags: set in rx_mode_flags field in @@ -1307,22 +1304,12 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp, unsigned long *pstate, bnx2x_obj_type type, struct bnx2x_credit_pool_obj *vlans_pool); -void bnx2x_init_vlan_mac_obj(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *vlan_mac_obj, - u8 cl_id, u32 cid, u8 func_id, void *rdata, - dma_addr_t rdata_mapping, int state, - unsigned long *pstate, bnx2x_obj_type type, - struct bnx2x_credit_pool_obj *macs_pool, - struct bnx2x_credit_pool_obj *vlans_pool); - int bnx2x_vlan_mac_h_read_lock(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o); void bnx2x_vlan_mac_h_read_unlock(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o); int bnx2x_vlan_mac_h_write_lock(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o); -void bnx2x_vlan_mac_h_write_unlock(struct bnx2x *bp, - struct bnx2x_vlan_mac_obj *o); int bnx2x_config_vlan_mac(struct bnx2x *bp, struct bnx2x_vlan_mac_ramrod_params *p); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 31ab924600c..208636d05cc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -799,10 +799,10 @@ int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp, return -ENOMEM; } -int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp, - struct bnx2x_virtf *vf, - struct bnx2x_vfop_cmd *cmd, - int qid, u16 vid, bool add) +static int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp, + struct bnx2x_virtf *vf, + struct bnx2x_vfop_cmd *cmd, + int qid, u16 vid, bool add) { struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); int rc; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index d72ab7e24de..d9fcca1b5a9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h @@ -665,11 +665,6 @@ int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp, struct bnx2x_vfop_filters *macs, int qid, bool drv_only); -int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp, - struct bnx2x_virtf *vf, - struct bnx2x_vfop_cmd *cmd, - int qid, u16 vid, bool add); - int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp, struct bnx2x_virtf *vf, struct bnx2x_vfop_cmd *cmd, @@ -727,13 +722,6 @@ void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid); /* Handles an FLR (or VF_DISABLE) notification form the MCP */ void bnx2x_vf_handle_flr_event(struct bnx2x *bp); -void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type, - u16 length); -void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, - u16 type, u16 length); -void bnx2x_vfpf_finalize(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv); -void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list); - bool bnx2x_tlv_supported(u16 tlvtype); u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp, @@ -750,7 +738,6 @@ int bnx2x_vfpf_init(struct bnx2x *bp); void bnx2x_vfpf_close_vf(struct bnx2x *bp); int bnx2x_vfpf_setup_q(struct bnx2x *bp, struct bnx2x_fastpath *fp, bool is_leading); -int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx); int bnx2x_vfpf_config_mac(struct bnx2x *bp, u8 *addr, u8 vf_qid, bool set); int bnx2x_vfpf_config_rss(struct bnx2x *bp, struct bnx2x_config_rss_params *params); @@ -814,7 +801,6 @@ static inline int bnx2x_vfpf_release(struct bnx2x *bp) {return 0; } static inline int bnx2x_vfpf_init(struct bnx2x *bp) {return 0; } static inline void bnx2x_vfpf_close_vf(struct bnx2x *bp) {} static inline int bnx2x_vfpf_setup_q(struct bnx2x *bp, struct bnx2x_fastpath *fp, bool is_leading) {return 0; } -static inline int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx) {return 0; } static inline int bnx2x_vfpf_config_mac(struct bnx2x *bp, u8 *addr, u8 vf_qid, bool set) {return 0; } static inline int bnx2x_vfpf_config_rss(struct bnx2x *bp, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index 1b1ad31b455..3fa6c2a2a5a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -21,9 +21,11 @@ #include "bnx2x_cmn.h" #include +static int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx); + /* place a given tlv on the tlv buffer at a given offset */ -void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type, - u16 length) +static void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, + u16 offset, u16 type, u16 length) { struct channel_tlv *tl = (struct channel_tlv *)(tlvs_list + offset); @@ -33,8 +35,8 @@ void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type, } /* Clear the mailbox and init the header of the first tlv */ -void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, - u16 type, u16 length) +static void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, + u16 type, u16 length) { mutex_lock(&bp->vf2pf_mutex); @@ -52,7 +54,8 @@ void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, } /* releases the mailbox */ -void bnx2x_vfpf_finalize(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv) +static void bnx2x_vfpf_finalize(struct bnx2x *bp, + struct vfpf_first_tlv *first_tlv) { DP(BNX2X_MSG_IOV, "done sending [%d] tlv over vf pf channel\n", first_tlv->tl.type); @@ -85,7 +88,7 @@ static void *bnx2x_search_tlv_list(struct bnx2x *bp, void *tlvs_list, } /* list the types and lengths of the tlvs on the buffer */ -void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list) +static void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list) { int i = 1; struct channel_tlv *tlv = (struct channel_tlv *)tlvs_list; @@ -633,7 +636,7 @@ int bnx2x_vfpf_setup_q(struct bnx2x *bp, struct bnx2x_fastpath *fp, return rc; } -int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx) +static int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx) { struct vfpf_q_op_tlv *req = &bp->vf2pf_mbox->req.q_op; struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 3b66f26ba04..890922c1c8e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -724,7 +724,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud * - not an IP fragment * - no LLS polling in progress */ - if (!mlx4_en_cq_ll_polling(cq) && + if (!mlx4_en_cq_busy_polling(cq) && (dev->features & NETIF_F_GRO)) { struct sk_buff *gro_skb = napi_get_frags(&cq->napi); if (!gro_skb) @@ -816,8 +816,10 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud skb_mark_napi_id(skb, &cq->napi); - /* Push it up the stack */ - netif_receive_skb(skb); + if (!mlx4_en_cq_busy_polling(cq)) + napi_gro_receive(&cq->napi, skb); + else + netif_receive_skb(skb); next: for (nr = 0; nr < priv->num_frags; nr++) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 2f1e200f2e4..fe7bdfebf35 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -661,7 +661,7 @@ static inline bool mlx4_en_cq_unlock_poll(struct mlx4_en_cq *cq) } /* true if a socket is polling, even if it did not get the lock */ -static inline bool mlx4_en_cq_ll_polling(struct mlx4_en_cq *cq) +static inline bool mlx4_en_cq_busy_polling(struct mlx4_en_cq *cq) { WARN_ON(!(cq->state & MLX4_CQ_LOCKED)); return cq->state & CQ_USER_PEND; @@ -691,7 +691,7 @@ static inline bool mlx4_en_cq_unlock_poll(struct mlx4_en_cq *cq) return false; } -static inline bool mlx4_en_cq_ll_polling(struct mlx4_en_cq *cq) +static inline bool mlx4_en_cq_busy_polling(struct mlx4_en_cq *cq) { return false; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 35d48766d84..25e1492ad52 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -38,8 +38,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 3 -#define _QLCNIC_LINUX_SUBVERSION 53 -#define QLCNIC_LINUX_VERSIONID "5.3.53" +#define _QLCNIC_LINUX_SUBVERSION 54 +#define QLCNIC_LINUX_VERSIONID "5.3.54" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -970,6 +970,9 @@ struct qlcnic_ipaddr { #define QLCNIC_BEACON_EANBLE 0xC #define QLCNIC_BEACON_DISABLE 0xD +#define QLCNIC_BEACON_ON 2 +#define QLCNIC_BEACON_OFF 0 + #define QLCNIC_MSIX_TBL_SPACE 8192 #define QLCNIC_PCI_REG_MSIX_TBL 0x44 #define QLCNIC_MSIX_TBL_PGSIZE 4096 @@ -1079,6 +1082,7 @@ struct qlcnic_adapter { u64 dev_rst_time; bool drv_mac_learn; bool fdb_mac_learn; + u8 rx_mac_learn; unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)]; u8 flash_mfg_id; struct qlcnic_npar_info *npars; @@ -1267,7 +1271,7 @@ struct qlcnic_pci_func_cfg { u16 port_num; u8 pci_func; u8 func_state; - u8 def_mac_addr[6]; + u8 def_mac_addr[ETH_ALEN]; }; struct qlcnic_npar_func_cfg { @@ -1640,7 +1644,6 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *); int qlcnic_reset_npar_config(struct qlcnic_adapter *); int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16); -int qlcnic_get_beacon_state(struct qlcnic_adapter *, u8 *); int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); int qlcnic_read_mac_addr(struct qlcnic_adapter *); int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); @@ -1767,6 +1770,7 @@ struct qlcnic_hardware_ops { pci_channel_state_t); pci_ers_result_t (*io_slot_reset) (struct pci_dev *); void (*io_resume) (struct pci_dev *); + void (*get_beacon_state)(struct qlcnic_adapter *); }; extern struct qlcnic_nic_template qlcnic_vf_ops; @@ -1993,6 +1997,11 @@ static inline void qlcnic_set_mac_filter_count(struct qlcnic_adapter *adapter) adapter->ahw->hw_ops->set_mac_filter_count(adapter); } +static inline void qlcnic_get_beacon_state(struct qlcnic_adapter *adapter) +{ + adapter->ahw->hw_ops->get_beacon_state(adapter); +} + static inline void qlcnic_read_phys_port_id(struct qlcnic_adapter *adapter) { if (adapter->ahw->hw_ops->read_phys_port_id) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 03eb2ad9611..a684d28e37a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -181,7 +181,7 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { .io_error_detected = qlcnic_83xx_io_error_detected, .io_slot_reset = qlcnic_83xx_io_slot_reset, .io_resume = qlcnic_83xx_io_resume, - + .get_beacon_state = qlcnic_83xx_get_beacon_state, }; static struct qlcnic_nic_template qlcnic_83xx_ops = { @@ -1388,6 +1388,33 @@ out: netif_device_attach(netdev); } +void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *adapter) +{ + struct qlcnic_hardware_context *ahw = adapter->ahw; + struct qlcnic_cmd_args cmd; + u8 beacon_state; + int err = 0; + + err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_CONFIG); + if (!err) { + err = qlcnic_issue_cmd(adapter, &cmd); + if (!err) { + beacon_state = cmd.rsp.arg[4]; + if (beacon_state == QLCNIC_BEACON_DISABLE) + ahw->beacon_state = QLC_83XX_BEACON_OFF; + else if (beacon_state == QLC_83XX_ENABLE_BEACON) + ahw->beacon_state = QLC_83XX_BEACON_ON; + } + } else { + netdev_err(adapter->netdev, "Get beacon state failed, err=%d\n", + err); + } + + qlcnic_free_mbx_args(&cmd); + + return; +} + int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 beacon) { @@ -1591,7 +1618,9 @@ static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter, u32 *interface_id) { if (qlcnic_sriov_pf_check(adapter)) { + qlcnic_alloc_lb_filters_mem(adapter); qlcnic_pf_set_interface_id_promisc(adapter, interface_id); + adapter->rx_mac_learn = 1; } else { if (!qlcnic_sriov_vf_check(adapter)) *interface_id = adapter->recv_ctx->context_id << 16; @@ -1618,6 +1647,10 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) cmd->type = QLC_83XX_MBX_CMD_NO_WAIT; qlcnic_83xx_set_interface_id_promisc(adapter, &temp); + + if (qlcnic_84xx_check(adapter) && qlcnic_sriov_pf_check(adapter)) + mode = VPORT_MISS_MODE_ACCEPT_ALL; + cmd->req.arg[1] = mode | temp; err = qlcnic_issue_cmd(adapter, cmd); if (!err) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 34d291168b7..4643b159df8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -381,6 +381,8 @@ enum qlcnic_83xx_states { /* LED configuration settings */ #define QLC_83XX_ENABLE_BEACON 0xe +#define QLC_83XX_BEACON_ON 1 +#define QLC_83XX_BEACON_OFF 0 #define QLC_83XX_LED_RATE 0xff #define QLC_83XX_LED_ACT (1 << 10) #define QLC_83XX_LED_MOD (0 << 13) @@ -559,6 +561,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *); void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); +void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *); void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); int qlcnic_ind_rd(struct qlcnic_adapter *, u32); int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 22ae884728b..abe3924c61c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -2214,6 +2214,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) struct qlcnic_hardware_context *ahw = adapter->ahw; int err = 0; + adapter->rx_mac_learn = 0; ahw->msix_supported = !!qlcnic_use_msi_x; qlcnic_83xx_init_rings(adapter); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c index 474320a5f0c..23c4fd10e50 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c @@ -224,10 +224,14 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter) return -EIO; } - if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) + if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) { adapter->flags |= QLCNIC_ESWITCH_ENABLED; - else + if (adapter->drv_mac_learn) + adapter->rx_mac_learn = 1; + } else { adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; + adapter->rx_mac_learn = 0; + } ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER; ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index a9a149b8237..6ca5e57da3d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -546,8 +546,11 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) !adapter->fdb_mac_learn) { qlcnic_alloc_lb_filters_mem(adapter); adapter->drv_mac_learn = 1; + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) + adapter->rx_mac_learn = 1; } else { adapter->drv_mac_learn = 0; + adapter->rx_mac_learn = 0; } qlcnic_nic_set_promisc(adapter, mode); @@ -779,8 +782,8 @@ void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter) "Could not send interrupt coalescing parameters\n"); } -#define QLCNIC_ENABLE_IPV4_LRO 1 -#define QLCNIC_ENABLE_IPV6_LRO 2 +#define QLCNIC_ENABLE_IPV4_LRO BIT_0 +#define QLCNIC_ENABLE_IPV6_LRO (BIT_1 | BIT_9) int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable) { @@ -1530,19 +1533,34 @@ int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) return rv; } -int qlcnic_get_beacon_state(struct qlcnic_adapter *adapter, u8 *h_state) +void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *adapter) { + struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_cmd_args cmd; - int err; + u8 beacon_state; + int err = 0; - err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_STATUS); - if (!err) { - err = qlcnic_issue_cmd(adapter, &cmd); - if (!err) - *h_state = cmd.rsp.arg[1]; + if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_BEACON) { + err = qlcnic_alloc_mbx_args(&cmd, adapter, + QLCNIC_CMD_GET_LED_STATUS); + if (!err) { + err = qlcnic_issue_cmd(adapter, &cmd); + if (err) { + netdev_err(adapter->netdev, + "Failed to get current beacon state, err=%d\n", + err); + } else { + beacon_state = cmd.rsp.arg[1]; + if (beacon_state == QLCNIC_BEACON_DISABLE) + ahw->beacon_state = QLCNIC_BEACON_OFF; + else if (beacon_state == QLCNIC_BEACON_EANBLE) + ahw->beacon_state = QLCNIC_BEACON_ON; + } + } + qlcnic_free_mbx_args(&cmd); } - qlcnic_free_mbx_args(&cmd); - return err; + + return; } void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h index 13303e7d1ed..0e739aed1bc 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h @@ -169,6 +169,7 @@ int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int); int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32); int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev); +void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *); void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr, u16 vlan_id); void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 6373f602248..cbe4a30abd7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -156,9 +156,9 @@ static inline void qlcnic_83xx_disable_tx_intr(struct qlcnic_adapter *adapter, writel(1, tx_ring->crb_intr_mask); } -static inline u8 qlcnic_mac_hash(u64 mac) +static inline u8 qlcnic_mac_hash(u64 mac, u16 vlan) { - return (u8)((mac & 0xff) ^ ((mac >> 40) & 0xff)); + return (u8)((mac & 0xff) ^ ((mac >> 40) & 0xff) ^ (vlan & 0xff)); } static inline u32 qlcnic_get_ref_handle(struct qlcnic_adapter *adapter, @@ -221,8 +221,11 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *adapter, struct sk_buff *skb, u8 hindex, op; int ret; + if (!qlcnic_sriov_pf_check(adapter) || (vlan_id == 0xffff)) + vlan_id = 0; + memcpy(&src_addr, phdr->h_source, ETH_ALEN); - hindex = qlcnic_mac_hash(src_addr) & + hindex = qlcnic_mac_hash(src_addr, vlan_id) & (adapter->fhash.fbucket_size - 1); if (loopback_pkt) { @@ -322,27 +325,43 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, struct cmd_desc_type0 *first_desc, struct sk_buff *skb) { + struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data); + struct ethhdr *phdr = (struct ethhdr *)(skb->data); + struct net_device *netdev = adapter->netdev; + u16 protocol = ntohs(skb->protocol); struct qlcnic_filter *fil, *tmp_fil; - struct hlist_node *n; struct hlist_head *head; - struct net_device *netdev = adapter->netdev; - struct ethhdr *phdr = (struct ethhdr *)(skb->data); + struct hlist_node *n; u64 src_addr = 0; u16 vlan_id = 0; - u8 hindex; + u8 hindex, hval; - if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) - return; + if (!qlcnic_sriov_pf_check(adapter)) { + if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) + return; + } else { + if (protocol == ETH_P_8021Q) { + vh = (struct vlan_ethhdr *)skb->data; + vlan_id = ntohs(vh->h_vlan_TCI); + } else if (vlan_tx_tag_present(skb)) { + vlan_id = vlan_tx_tag_get(skb); + } + + if (ether_addr_equal(phdr->h_source, adapter->mac_addr) && + !vlan_id) + return; + } if (adapter->fhash.fnum >= adapter->fhash.fmax) { adapter->stats.mac_filter_limit_overrun++; - netdev_info(netdev, "Can not add more than %d mac addresses\n", - adapter->fhash.fmax); + netdev_info(netdev, "Can not add more than %d mac-vlan filters, configured %d\n", + adapter->fhash.fmax, adapter->fhash.fnum); return; } memcpy(&src_addr, phdr->h_source, ETH_ALEN); - hindex = qlcnic_mac_hash(src_addr) & (adapter->fhash.fbucket_size - 1); + hval = qlcnic_mac_hash(src_addr, vlan_id); + hindex = hval & (adapter->fhash.fbucket_size - 1); head = &(adapter->fhash.fhead[hindex]); hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { @@ -1599,7 +1618,8 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, struct sk_buff *skb; struct qlcnic_host_rds_ring *rds_ring; int index, length, cksum, is_lb_pkt; - u16 vid = 0xffff, t_vid; + u16 vid = 0xffff; + int err; if (unlikely(ring >= adapter->max_rds_rings)) return NULL; @@ -1617,19 +1637,19 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, if (!skb) return buffer; - if (adapter->drv_mac_learn && - (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { - t_vid = 0; - is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 0); - qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); - } - if (length > rds_ring->skb_size) skb_put(skb, rds_ring->skb_size); else skb_put(skb, length); - if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { + err = qlcnic_check_rx_tagging(adapter, skb, &vid); + + if (adapter->rx_mac_learn) { + is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 0); + qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, vid); + } + + if (unlikely(err)) { adapter->stats.rxdropped++; dev_kfree_skb(skb); return buffer; @@ -1664,7 +1684,8 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, int l2_hdr_offset, l4_hdr_offset; int index, is_lb_pkt; u16 lro_length, length, data_offset, gso_size; - u16 vid = 0xffff, t_vid; + u16 vid = 0xffff; + int err; if (unlikely(ring > adapter->max_rds_rings)) return NULL; @@ -1686,12 +1707,6 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, if (!skb) return buffer; - if (adapter->drv_mac_learn && - (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { - t_vid = 0; - is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 1); - qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); - } if (qlcnic_83xx_is_tstamp(sts_data[1])) data_offset = l4_hdr_offset + QLCNIC_TCP_TS_HDR_SIZE; else @@ -1700,7 +1715,14 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, skb_put(skb, lro_length + data_offset); skb_pull(skb, l2_hdr_offset); - if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { + err = qlcnic_check_rx_tagging(adapter, skb, &vid); + + if (adapter->rx_mac_learn) { + is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 1); + qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, vid); + } + + if (unlikely(err)) { adapter->stats.rxdropped++; dev_kfree_skb(skb); return buffer; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index eeec83a0e66..a57dfe4ad40 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -546,6 +546,7 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = { .io_error_detected = qlcnic_82xx_io_error_detected, .io_slot_reset = qlcnic_82xx_io_slot_reset, .io_resume = qlcnic_82xx_io_resume, + .get_beacon_state = qlcnic_82xx_get_beacon_state, }; static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index bf8fca7d874..f998fdcd755 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -277,9 +277,7 @@ static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter) void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) { - struct qlcnic_sriov *sriov = adapter->ahw->sriov; - - if (!sriov) + if (!test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state)) return; qlcnic_sriov_free_vlans(adapter); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index d14d9a139ee..09acf15c3a5 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -9,9 +9,14 @@ #include "qlcnic.h" #include -#define QLCNIC_SRIOV_VF_MAX_MAC 8 +#define QLCNIC_SRIOV_VF_MAX_MAC 7 #define QLC_VF_MIN_TX_RATE 100 #define QLC_VF_MAX_TX_RATE 9999 +#define QLC_MAC_OPCODE_MASK 0x7 +#define QLC_MAC_STAR_ADD 6 +#define QLC_MAC_STAR_DEL 7 +#define QLC_VF_FLOOD_BIT BIT_16 +#define QLC_FLOOD_MODE 0x5 static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); @@ -344,6 +349,28 @@ static int qlcnic_sriov_pf_cfg_vlan_filtering(struct qlcnic_adapter *adapter, return err; } +/* On configuring VF flood bit, PFD will receive traffic from all VFs */ +static int qlcnic_sriov_pf_cfg_flood(struct qlcnic_adapter *adapter) +{ + struct qlcnic_cmd_args cmd; + int err; + + err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO); + if (err) + return err; + + cmd.req.arg[1] = QLC_FLOOD_MODE | QLC_VF_FLOOD_BIT; + + err = qlcnic_issue_cmd(adapter, &cmd); + if (err) + dev_err(&adapter->pdev->dev, + "Failed to configure VF Flood bit on PF, err=%d\n", + err); + + qlcnic_free_mbx_args(&cmd); + return err; +} + static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter, u8 func, u8 enable) { @@ -471,6 +498,12 @@ static int qlcnic_sriov_pf_init(struct qlcnic_adapter *adapter) if (err) return err; + if (qlcnic_84xx_check(adapter)) { + err = qlcnic_sriov_pf_cfg_flood(adapter); + if (err) + goto disable_vlan_filtering; + } + err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1); if (err) goto disable_vlan_filtering; @@ -1173,6 +1206,13 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, struct qlcnic_vport *vp = vf->vp; u8 op, new_op; + if (((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_ADD) || + ((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_DEL)) { + netdev_err(adapter->netdev, "MAC + any VLAN filter not allowed from VF %d\n", + vf->pci_func); + return -EINVAL; + } + if (!(cmd->req.arg[1] & BIT_8)) return -EINVAL; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index b5296672c44..1c8552f682d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -6,7 +6,6 @@ */ #include -#include #include #include "qlcnic.h" @@ -127,6 +126,8 @@ static int qlcnic_83xx_store_beacon(struct qlcnic_adapter *adapter, if (kstrtoul(buf, 2, &h_beacon)) return -EINVAL; + qlcnic_get_beacon_state(adapter); + if (ahw->beacon_state == h_beacon) return len; @@ -158,7 +159,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter, struct qlcnic_hardware_context *ahw = adapter->ahw; int err, drv_sds_rings = adapter->drv_sds_rings; u16 beacon; - u8 h_beacon_state, b_state, b_rate; + u8 b_state, b_rate; if (len != sizeof(u16)) return QL_STATUS_INVALID_PARAM; @@ -168,18 +169,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter, if (err) return err; - if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_BEACON) { - err = qlcnic_get_beacon_state(adapter, &h_beacon_state); - if (err) { - netdev_err(adapter->netdev, - "Failed to get current beacon state\n"); - } else { - if (h_beacon_state == QLCNIC_BEACON_DISABLE) - ahw->beacon_state = 0; - else if (h_beacon_state == QLCNIC_BEACON_EANBLE) - ahw->beacon_state = 2; - } - } + qlcnic_get_beacon_state(adapter); if (ahw->beacon_state == b_state) return len; @@ -927,38 +917,35 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, u32 pci_func_count = qlcnic_get_pci_func_count(adapter); struct qlcnic_pci_func_cfg *pci_cfg; struct qlcnic_pci_info *pci_info; - size_t pci_info_sz, pci_cfg_sz; + size_t pci_cfg_sz; int i, ret; pci_cfg_sz = pci_func_count * sizeof(*pci_cfg); if (size != pci_cfg_sz) return QL_STATUS_INVALID_PARAM; - pci_info_sz = pci_func_count * sizeof(*pci_info); - pci_info = vmalloc(pci_info_sz); + pci_info = kcalloc(pci_func_count, sizeof(*pci_info), GFP_KERNEL); if (!pci_info) return -ENOMEM; - memset(pci_info, 0, pci_info_sz); - memset(buf, 0, pci_cfg_sz); - pci_cfg = (struct qlcnic_pci_func_cfg *)buf; - ret = qlcnic_get_pci_info(adapter, pci_info); if (ret) { - vfree(pci_info); + kfree(pci_info); return ret; } + pci_cfg = (struct qlcnic_pci_func_cfg *)buf; for (i = 0; i < pci_func_count; i++) { pci_cfg[i].pci_func = pci_info[i].id; pci_cfg[i].func_type = pci_info[i].type; + pci_cfg[i].func_state = 0; pci_cfg[i].port_num = pci_info[i].default_port; pci_cfg[i].min_bw = pci_info[i].tx_min_bw; pci_cfg[i].max_bw = pci_info[i].tx_max_bw; memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); } - vfree(pci_info); + kfree(pci_info); return size; } diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 96f79f7c439..a6a9e1ebe30 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -1894,7 +1894,7 @@ static int smc_probe(struct net_device *dev, void __iomem *ioaddr, SMC_SELECT_BANK(lp, 1); val = SMC_GET_BASE(lp); val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; - if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { + if (((unsigned long)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { netdev_warn(dev, "%s: IOADDR %p doesn't match configuration (%x).\n", CARDNAME, ioaddr, val); } diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 5d81c89ee52..39794c4d7b2 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -50,14 +51,17 @@ static void phy_device_release(struct device *dev) kfree(to_phy_device(dev)); } -static struct phy_driver genphy_driver; +enum genphy_driver { + GENPHY_DRV_1G, + GENPHY_DRV_10G, + GENPHY_DRV_MAX +}; + +static struct phy_driver genphy_driver[GENPHY_DRV_MAX]; static LIST_HEAD(phy_fixup_list); static DEFINE_MUTEX(phy_fixup_lock); -static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, - u32 flags, phy_interface_t interface); - /** * phy_register_fixup - creates a new phy_fixup and adds it to the list * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID) @@ -560,13 +564,13 @@ EXPORT_SYMBOL(phy_init_hw); * * Description: Called by drivers to attach to a particular PHY * device. The phy_device is found, and properly hooked up - * to the phy_driver. If no driver is attached, then the - * genphy_driver is used. The phy_device is given a ptr to + * to the phy_driver. If no driver is attached, then a + * generic driver is used. The phy_device is given a ptr to * the attaching device, and given a callback for link status * change. The phy_device is returned to the attaching driver. */ -static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, - u32 flags, phy_interface_t interface) +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface) { struct device *d = &phydev->dev; int err; @@ -575,12 +579,10 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, * exist, and we should use the genphy driver. */ if (NULL == d->driver) { - if (phydev->is_c45) { - pr_err("No driver for phy %x\n", phydev->phy_id); - return -ENODEV; - } - - d->driver = &genphy_driver.driver; + if (phydev->is_c45) + d->driver = &genphy_driver[GENPHY_DRV_10G].driver; + else + d->driver = &genphy_driver[GENPHY_DRV_1G].driver; err = d->driver->probe(d); if (err >= 0) @@ -616,6 +618,7 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, return err; } +EXPORT_SYMBOL(phy_attach_direct); /** * phy_attach - attach a network device to a particular PHY device @@ -658,6 +661,7 @@ EXPORT_SYMBOL(phy_attach); */ void phy_detach(struct phy_device *phydev) { + int i; phydev->attached_dev->phydev = NULL; phydev->attached_dev = NULL; phy_suspend(phydev); @@ -667,8 +671,12 @@ void phy_detach(struct phy_device *phydev) * from the generic driver so that there's a chance a * real driver could be loaded */ - if (phydev->dev.driver == &genphy_driver.driver) - device_release_driver(&phydev->dev); + for (i = 0; i < ARRAY_SIZE(genphy_driver); i++) { + if (phydev->dev.driver == &genphy_driver[i].driver) { + device_release_driver(&phydev->dev); + break; + } + } } EXPORT_SYMBOL(phy_detach); @@ -759,6 +767,12 @@ static int genphy_config_advert(struct phy_device *phydev) return changed; } +int gen10g_config_advert(struct phy_device *dev) +{ + return 0; +} +EXPORT_SYMBOL(gen10g_config_advert); + /** * genphy_setup_forced - configures/forces speed/duplex from @phydev * @phydev: target phy_device struct @@ -806,6 +820,12 @@ int genphy_restart_aneg(struct phy_device *phydev) } EXPORT_SYMBOL(genphy_restart_aneg); +int gen10g_restart_aneg(struct phy_device *phydev) +{ + return 0; +} +EXPORT_SYMBOL(gen10g_restart_aneg); + /** * genphy_config_aneg - restart auto-negotiation or write BMCR * @phydev: target phy_device struct @@ -847,6 +867,12 @@ int genphy_config_aneg(struct phy_device *phydev) } EXPORT_SYMBOL(genphy_config_aneg); +int gen10g_config_aneg(struct phy_device *phydev) +{ + return 0; +} +EXPORT_SYMBOL(gen10g_config_aneg); + /** * genphy_update_link - update link status in @phydev * @phydev: target phy_device struct @@ -978,6 +1004,34 @@ int genphy_read_status(struct phy_device *phydev) } EXPORT_SYMBOL(genphy_read_status); +int gen10g_read_status(struct phy_device *phydev) +{ + int devad, reg; + u32 mmd_mask = phydev->c45_ids.devices_in_package; + + phydev->link = 1; + + /* For now just lie and say it's 10G all the time */ + phydev->speed = SPEED_10000; + phydev->duplex = DUPLEX_FULL; + + for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) { + if (!(mmd_mask & 1)) + continue; + + /* Read twice because link state is latched and a + * read moves the current state into the register + */ + phy_read_mmd(phydev, devad, MDIO_STAT1); + reg = phy_read_mmd(phydev, devad, MDIO_STAT1); + if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) + phydev->link = 0; + } + + return 0; +} +EXPORT_SYMBOL(gen10g_read_status); + static int genphy_config_init(struct phy_device *phydev) { int val; @@ -1023,6 +1077,16 @@ static int genphy_config_init(struct phy_device *phydev) return 0; } + +static int gen10g_config_init(struct phy_device *phydev) +{ + /* Temporarily just say we support everything */ + phydev->supported = SUPPORTED_10000baseT_Full; + phydev->advertising = SUPPORTED_10000baseT_Full; + + return 0; +} + int genphy_suspend(struct phy_device *phydev) { int value; @@ -1038,6 +1102,12 @@ int genphy_suspend(struct phy_device *phydev) } EXPORT_SYMBOL(genphy_suspend); +int gen10g_suspend(struct phy_device *phydev) +{ + return 0; +} +EXPORT_SYMBOL(gen10g_suspend); + int genphy_resume(struct phy_device *phydev) { int value; @@ -1053,6 +1123,12 @@ int genphy_resume(struct phy_device *phydev) } EXPORT_SYMBOL(genphy_resume); +int gen10g_resume(struct phy_device *phydev) +{ + return 0; +} +EXPORT_SYMBOL(gen10g_resume); + /** * phy_probe - probe and init a PHY device * @dev: device to probe and init @@ -1173,7 +1249,8 @@ void phy_drivers_unregister(struct phy_driver *drv, int n) } EXPORT_SYMBOL(phy_drivers_unregister); -static struct phy_driver genphy_driver = { +static struct phy_driver genphy_driver[] = { +{ .phy_id = 0xffffffff, .phy_id_mask = 0xffffffff, .name = "Generic PHY", @@ -1184,7 +1261,18 @@ static struct phy_driver genphy_driver = { .suspend = genphy_suspend, .resume = genphy_resume, .driver = { .owner = THIS_MODULE, }, -}; +}, { + .phy_id = 0xffffffff, + .phy_id_mask = 0xffffffff, + .name = "Generic 10G PHY", + .config_init = gen10g_config_init, + .features = 0, + .config_aneg = gen10g_config_aneg, + .read_status = gen10g_read_status, + .suspend = gen10g_suspend, + .resume = gen10g_resume, + .driver = {.owner = THIS_MODULE, }, +} }; static int __init phy_init(void) { @@ -1194,7 +1282,8 @@ static int __init phy_init(void) if (rc) return rc; - rc = phy_driver_register(&genphy_driver); + rc = phy_drivers_register(genphy_driver, + ARRAY_SIZE(genphy_driver)); if (rc) mdio_bus_exit(); @@ -1203,7 +1292,8 @@ static int __init phy_init(void) static void __exit phy_exit(void) { - phy_driver_unregister(&genphy_driver); + phy_drivers_unregister(genphy_driver, + ARRAY_SIZE(genphy_driver)); mdio_bus_exit(); } diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index a43b8523c61..875b7b6f0d2 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -254,3 +254,23 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, return IS_ERR(phy) ? NULL : phy; } EXPORT_SYMBOL(of_phy_connect_fixed_link); + +/** + * of_phy_attach - Attach to a PHY without starting the state machine + * @dev: pointer to net_device claiming the phy + * @phy_np: Node pointer for the PHY + * @flags: flags to pass to the PHY + * @iface: PHY data interface type + */ +struct phy_device *of_phy_attach(struct net_device *dev, + struct device_node *phy_np, u32 flags, + phy_interface_t iface) +{ + struct phy_device *phy = of_phy_find_device(phy_np); + + if (!phy) + return NULL; + + return phy_attach_direct(dev, phy, flags, iface) ? NULL : phy; +} +EXPORT_SYMBOL(of_phy_attach); diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c index 8f9be2e0993..a208a457558 100644 --- a/drivers/of/of_net.c +++ b/drivers/of/of_net.c @@ -30,6 +30,7 @@ static const char *phy_modes[] = { [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid", [PHY_INTERFACE_MODE_RTBI] = "rtbi", [PHY_INTERFACE_MODE_SMII] = "smii", + [PHY_INTERFACE_MODE_XGMII] = "xgmii", }; /** diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index 8163107b94b..6fe8464ed76 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h @@ -19,6 +19,9 @@ extern struct phy_device *of_phy_connect(struct net_device *dev, struct device_node *phy_np, void (*hndlr)(struct net_device *), u32 flags, phy_interface_t iface); +struct phy_device *of_phy_attach(struct net_device *dev, + struct device_node *phy_np, u32 flags, + phy_interface_t iface); extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, void (*hndlr)(struct net_device *), phy_interface_t iface); @@ -44,6 +47,13 @@ static inline struct phy_device *of_phy_connect(struct net_device *dev, return NULL; } +static inline struct phy_device *of_phy_attach(struct net_device *dev, + struct device_node *phy_np, + u32 flags, phy_interface_t iface) +{ + return NULL; +} + static inline struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, void (*hndlr)(struct net_device *), phy_interface_t iface) diff --git a/include/linux/phy.h b/include/linux/phy.h index 7c81dd8870d..565188ca328 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -73,6 +73,7 @@ typedef enum { PHY_INTERFACE_MODE_RGMII_TXID, PHY_INTERFACE_MODE_RTBI, PHY_INTERFACE_MODE_SMII, + PHY_INTERFACE_MODE_XGMII, } phy_interface_t; @@ -487,6 +488,24 @@ struct phy_fixup { int (*run)(struct phy_device *phydev); }; +/** + * phy_read_mmd - Convenience function for reading a register + * from an MMD on a given PHY. + * @phydev: The phy_device struct + * @devad: The MMD to read from + * @regnum: The register on the MMD to read + * + * Same rules as for phy_read(); + */ +static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) +{ + if (!phydev->is_c45) + return -EOPNOTSUPP; + + return mdiobus_read(phydev->bus, phydev->addr, + MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff)); +} + /** * phy_read - Convenience function for reading a given PHY register * @phydev: the phy_device struct @@ -537,6 +556,27 @@ static inline bool phy_is_internal(struct phy_device *phydev) return phydev->is_internal; } +/** + * phy_write_mmd - Convenience function for writing a register + * on an MMD on a given PHY. + * @phydev: The phy_device struct + * @devad: The MMD to read from + * @regnum: The register on the MMD to read + * @val: value to write to @regnum + * + * Same rules as for phy_write(); + */ +static inline int phy_write_mmd(struct phy_device *phydev, int devad, + u32 regnum, u16 val) +{ + if (!phydev->is_c45) + return -EOPNOTSUPP; + + regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff); + + return mdiobus_write(phydev->bus, phydev->addr, regnum, val); +} + struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, bool is_c45, struct phy_c45_device_ids *c45_ids); @@ -548,6 +588,8 @@ int phy_resume(struct phy_device *phydev); struct phy_device *phy_attach(struct net_device *dev, const char *bus_id, phy_interface_t interface); struct phy_device *phy_find_first(struct mii_bus *bus); +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface); int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, void (*handler)(struct net_device *), phy_interface_t interface); diff --git a/include/net/act_api.h b/include/net/act_api.h index d34e1f4d897..e171387512b 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -39,6 +39,7 @@ struct tcf_hashinfo { struct hlist_head *htab; unsigned int hmask; spinlock_t lock; + u32 index; }; static inline unsigned int tcf_hash(u32 index, unsigned int hmask) @@ -51,6 +52,7 @@ static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask) int i; spin_lock_init(&hf->lock); + hf->index = 0; hf->hmask = mask; hf->htab = kzalloc((mask + 1) * sizeof(struct hlist_head), GFP_KERNEL); @@ -71,10 +73,6 @@ static inline void tcf_hashinfo_destroy(struct tcf_hashinfo *hf) #define ACT_P_CREATED 1 #define ACT_P_DELETED 1 -struct tcf_act_hdr { - struct tcf_common common; -}; - struct tc_action { void *priv; const struct tc_action_ops *ops; @@ -105,13 +103,12 @@ struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo); void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_hash_release(struct tcf_common *p, int bind, struct tcf_hashinfo *hinfo); -u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo); +u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo); struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, struct tcf_hashinfo *hinfo); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, - int bind, u32 *idx_gen, - struct tcf_hashinfo *hinfo); + int bind, struct tcf_hashinfo *hinfo); void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo); int tcf_register_action(struct tc_action_ops *a); diff --git a/include/net/ip.h b/include/net/ip.h index 535664477c4..0dab95c2e4d 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -263,6 +263,39 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) !(dst_metric_locked(dst, RTAX_MTU))); } +static inline bool ip_sk_accept_pmtu(const struct sock *sk) +{ + return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE; +} + +static inline bool ip_sk_use_pmtu(const struct sock *sk) +{ + return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE; +} + +static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, + bool forwarding) +{ + struct net *net = dev_net(dst->dev); + + if (net->ipv4.sysctl_ip_fwd_use_pmtu || + dst_metric_locked(dst, RTAX_MTU) || + !forwarding) + return dst_mtu(dst); + + return min(dst->dev->mtu, IP_MAX_MTU); +} + +static inline unsigned int ip_skb_dst_mtu(const struct sk_buff *skb) +{ + if (!skb->sk || ip_sk_use_pmtu(skb->sk)) { + bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; + return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); + } else { + return min(skb_dst(skb)->dev->mtu, IP_MAX_MTU); + } +} + void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 929a668e91a..80f500a2949 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -70,6 +70,7 @@ struct netns_ipv4 { int sysctl_tcp_ecn; int sysctl_ip_no_pmtu_disc; + int sysctl_ip_fwd_use_pmtu; kgid_t sysctl_ping_group_range[2]; diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 50ea07969c0..a2441fb1428 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -338,27 +338,27 @@ static inline int tcf_valid_offset(const struct sk_buff *skb, #include static inline int -tcf_change_indev(struct tcf_proto *tp, char *indev, struct nlattr *indev_tlv) +tcf_change_indev(struct net *net, struct nlattr *indev_tlv) { + char indev[IFNAMSIZ]; + struct net_device *dev; + if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) return -EINVAL; - return 0; + dev = __dev_get_by_name(net, indev); + if (!dev) + return -ENODEV; + return dev->ifindex; } -static inline int -tcf_match_indev(struct sk_buff *skb, char *indev) +static inline bool +tcf_match_indev(struct sk_buff *skb, int ifindex) { - struct net_device *dev; - - if (indev[0]) { - if (!skb->skb_iif) - return 0; - dev = __dev_get_by_index(dev_net(skb->dev), skb->skb_iif); - if (!dev || strcmp(indev, dev->name)) - return 0; - } - - return 1; + if (!ifindex) + return true; + if (!skb->skb_iif) + return false; + return ifindex == skb->skb_iif; } #endif /* CONFIG_NET_CLS_IND */ diff --git a/include/net/protocol.h b/include/net/protocol.h index fbf7676c9a0..0e5f8665d7f 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -43,7 +43,12 @@ struct net_protocol { int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); unsigned int no_policy:1, - netns_ok:1; + netns_ok:1, + /* does the protocol do more stringent + * icmp tag validation than simple + * socket lookup? + */ + icmp_strict_tag_validation:1; }; #if IS_ENABLED(CONFIG_IPV6) diff --git a/include/net/route.h b/include/net/route.h index 638e3ebf76f..9d1f423d594 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -36,6 +36,9 @@ #include #include +/* IPv4 datagram length is stored into 16bit field (tot_len) */ +#define IP_MAX_MTU 0xFFFFU + #define RTO_ONLINK 0x01 #define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE)) @@ -311,20 +314,4 @@ static inline int ip4_dst_hoplimit(const struct dst_entry *dst) return hoplimit; } -static inline bool ip_sk_accept_pmtu(const struct sock *sk) -{ - return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE; -} - -static inline bool ip_sk_use_pmtu(const struct sock *sk) -{ - return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE; -} - -static inline int ip_skb_dst_mtu(const struct sk_buff *skb) -{ - return (!skb->sk || ip_sk_use_pmtu(skb->sk)) ? - dst_mtu(skb_dst(skb)) : skb_dst(skb)->dev->mtu; -} - #endif /* _ROUTE_H */ diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 013d96dc691..d062f81c692 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -204,7 +204,7 @@ struct tcf_proto_ops { void (*walk)(struct tcf_proto*, struct tcf_walker *arg); /* rtnetlink specific */ - int (*dump)(struct tcf_proto*, unsigned long, + int (*dump)(struct net*, struct tcf_proto*, unsigned long, struct sk_buff *skb, struct tcmsg*); struct module *owner; diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index e9f732fda95..d992ca3145f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -649,7 +649,6 @@ int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, struct iovec *data); void sctp_chunk_free(struct sctp_chunk *); void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); -void *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, const void *data); struct sctp_chunk *sctp_chunkify(struct sk_buff *, const struct sctp_association *, struct sock *); diff --git a/net/core/dev.c b/net/core/dev.c index ce01847793c..87312dcf0aa 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3882,10 +3882,23 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff if (same_flow) goto ok; - if (NAPI_GRO_CB(skb)->flush || napi->gro_count >= MAX_GRO_SKBS) + if (NAPI_GRO_CB(skb)->flush) goto normal; - napi->gro_count++; + if (unlikely(napi->gro_count >= MAX_GRO_SKBS)) { + struct sk_buff *nskb = napi->gro_list; + + /* locate the end of the list to select the 'oldest' flow */ + while (nskb->next) { + pp = &nskb->next; + nskb = *pp; + } + *pp = NULL; + nskb->next = NULL; + napi_gro_complete(nskb); + } else { + napi->gro_count++; + } NAPI_GRO_CB(skb)->count = 1; NAPI_GRO_CB(skb)->age = jiffies; skb_shinfo(skb)->gso_size = skb_gro_len(skb); @@ -5287,6 +5300,17 @@ int dev_change_flags(struct net_device *dev, unsigned int flags) } EXPORT_SYMBOL(dev_change_flags); +static int __dev_set_mtu(struct net_device *dev, int new_mtu) +{ + const struct net_device_ops *ops = dev->netdev_ops; + + if (ops->ndo_change_mtu) + return ops->ndo_change_mtu(dev, new_mtu); + + dev->mtu = new_mtu; + return 0; +} + /** * dev_set_mtu - Change maximum transfer unit * @dev: device @@ -5296,8 +5320,7 @@ EXPORT_SYMBOL(dev_change_flags); */ int dev_set_mtu(struct net_device *dev, int new_mtu) { - const struct net_device_ops *ops = dev->netdev_ops; - int err; + int err, orig_mtu; if (new_mtu == dev->mtu) return 0; @@ -5309,14 +5332,20 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) if (!netif_device_present(dev)) return -ENODEV; - err = 0; - if (ops->ndo_change_mtu) - err = ops->ndo_change_mtu(dev, new_mtu); - else - dev->mtu = new_mtu; + orig_mtu = dev->mtu; + err = __dev_set_mtu(dev, new_mtu); - if (!err) - call_netdevice_notifiers(NETDEV_CHANGEMTU, dev); + if (!err) { + err = call_netdevice_notifiers(NETDEV_CHANGEMTU, dev); + err = notifier_to_errno(err); + if (err) { + /* setting mtu back and notifying everyone again, + * so that they have a chance to revert changes. + */ + __dev_set_mtu(dev, orig_mtu); + call_netdevice_notifiers(NETDEV_CHANGEMTU, dev); + } + } return err; } EXPORT_SYMBOL(dev_set_mtu); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 88299c29101..22b5d818b20 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -989,6 +989,7 @@ static const struct net_protocol dccp_v4_protocol = { .err_handler = dccp_v4_err, .no_policy = 1, .netns_ok = 1, + .icmp_strict_tag_validation = 1, }; static const struct proto_ops inet_dccp_ops = { diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 6268a4751e6..ecd2c3f245c 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1545,6 +1545,7 @@ static const struct net_protocol tcp_protocol = { .err_handler = tcp_v4_err, .no_policy = 1, .netns_ok = 1, + .icmp_strict_tag_validation = 1, }; static const struct net_protocol udp_protocol = { diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index 746a7b10d43..29512e3e7e7 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c @@ -26,7 +26,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, { struct sk_buff *segs = ERR_PTR(-EINVAL); netdev_features_t enc_features; - int ghl = GRE_HEADER_SECTION; + int ghl; struct gre_base_hdr *greh; u16 mac_offset = skb->mac_header; int mac_len = skb->mac_len; @@ -49,15 +49,11 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, greh = (struct gre_base_hdr *)skb_transport_header(skb); - if (greh->flags & GRE_KEY) - ghl += GRE_HEADER_SECTION; - if (greh->flags & GRE_SEQ) - ghl += GRE_HEADER_SECTION; - if (greh->flags & GRE_CSUM) { - ghl += GRE_HEADER_SECTION; - csum = true; - } else - csum = false; + ghl = skb_inner_network_header(skb) - skb_transport_header(skb); + if (unlikely(ghl < sizeof(*greh))) + goto out; + + csum = !!(greh->flags & GRE_CSUM); if (unlikely(!pskb_may_pull(skb, ghl))) goto out; @@ -250,7 +246,7 @@ out: return pp; } -int gre_gro_complete(struct sk_buff *skb, int nhoff) +static int gre_gro_complete(struct sk_buff *skb, int nhoff) { struct gre_base_hdr *greh = (struct gre_base_hdr *)(skb->data + nhoff); struct packet_offload *ptype; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index fb3c5637199..0134663fdbc 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -668,6 +668,16 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info) rcu_read_unlock(); } +static bool icmp_tag_validation(int proto) +{ + bool ok; + + rcu_read_lock(); + ok = rcu_dereference(inet_protos[proto])->icmp_strict_tag_validation; + rcu_read_unlock(); + return ok; +} + /* * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, ICMP_QUENCH, and * ICMP_PARAMETERPROB. @@ -705,12 +715,22 @@ static void icmp_unreach(struct sk_buff *skb) case ICMP_PORT_UNREACH: break; case ICMP_FRAG_NEEDED: - if (net->ipv4.sysctl_ip_no_pmtu_disc == 2) { - goto out; - } else if (net->ipv4.sysctl_ip_no_pmtu_disc) { + /* for documentation of the ip_no_pmtu_disc + * values please see + * Documentation/networking/ip-sysctl.txt + */ + switch (net->ipv4.sysctl_ip_no_pmtu_disc) { + default: LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: fragmentation needed and DF set\n"), &iph->daddr); - } else { + break; + case 2: + goto out; + case 3: + if (!icmp_tag_validation(iph->protocol)) + goto out; + /* fall through */ + case 0: info = ntohs(icmph->un.frag.mtu); if (!info) goto out; diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 694de3b7aeb..e9f1217a8af 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -54,6 +54,7 @@ static int ip_forward_finish(struct sk_buff *skb) int ip_forward(struct sk_buff *skb) { + u32 mtu; struct iphdr *iph; /* Our header */ struct rtable *rt; /* Route we use */ struct ip_options *opt = &(IPCB(skb)->opt); @@ -88,11 +89,13 @@ int ip_forward(struct sk_buff *skb) if (opt->is_strictroute && rt->rt_uses_gateway) goto sr_failed; - if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) && + IPCB(skb)->flags |= IPSKB_FORWARDED; + mtu = ip_dst_mtu_maybe_forward(&rt->dst, true); + if (unlikely(skb->len > mtu && !skb_is_gso(skb) && (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(dst_mtu(&rt->dst))); + htonl(mtu)); goto drop; } diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index df184616493..9a78804cfe9 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -449,6 +449,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) __be16 not_last_frag; struct rtable *rt = skb_rtable(skb); int err = 0; + bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; dev = rt->dst.dev; @@ -458,12 +459,13 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) iph = ip_hdr(skb); + mtu = ip_dst_mtu_maybe_forward(&rt->dst, forwarding); if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->local_df) || (IPCB(skb)->frag_max_size && - IPCB(skb)->frag_max_size > dst_mtu(&rt->dst)))) { + IPCB(skb)->frag_max_size > mtu))) { IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(ip_skb_dst_mtu(skb))); + htonl(mtu)); kfree_skb(skb); return -EMSGSIZE; } @@ -473,7 +475,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) */ hlen = iph->ihl * 4; - mtu = dst_mtu(&rt->dst) - hlen; /* Size of data space */ + mtu = mtu - hlen; /* Size of data space */ #ifdef CONFIG_BRIDGE_NETFILTER if (skb->nf_bridge) mtu -= nf_bridge_mtu_reduction(skb); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index f8da2827801..25071b48921 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -112,9 +112,6 @@ #define RT_FL_TOS(oldflp4) \ ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)) -/* IPv4 datagram length is stored into 16bit field (tot_len) */ -#define IP_MAX_MTU 0xFFFF - #define RT_GC_TIMEOUT (300*HZ) static int ip_rt_max_size; diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 1d2480ac2bb..44eba052b43 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -831,6 +831,13 @@ static struct ctl_table ipv4_net_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "ip_forward_use_pmtu", + .data = &init_net.ipv4.sysctl_ip_fwd_use_pmtu, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, { } }; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d1de9560c42..ef02b26ccf8 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -321,6 +321,27 @@ static inline int ip6_forward_finish(struct sk_buff *skb) return dst_output(skb); } +static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) +{ + unsigned int mtu; + struct inet6_dev *idev; + + if (dst_metric_locked(dst, RTAX_MTU)) { + mtu = dst_metric_raw(dst, RTAX_MTU); + if (mtu) + return mtu; + } + + mtu = IPV6_MIN_MTU; + rcu_read_lock(); + idev = __in6_dev_get(dst->dev); + if (idev) + mtu = idev->cnf.mtu6; + rcu_read_unlock(); + + return mtu; +} + int ip6_forward(struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); @@ -441,7 +462,7 @@ int ip6_forward(struct sk_buff *skb) } } - mtu = dst_mtu(dst); + mtu = ip6_dst_mtu_forward(dst); if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 9af77d9c0ec..735d0f60c83 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -176,7 +176,7 @@ l2tp_session_id_hash_2(struct l2tp_net *pn, u32 session_id) * owned by userspace. A struct sock returned from this function must be * released using l2tp_tunnel_sock_put once you're done with it. */ -struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel) +static struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel) { int err = 0; struct socket *sock = NULL; @@ -202,10 +202,9 @@ struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel) out: return sk; } -EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_lookup); /* Drop a reference to a tunnel socket obtained via. l2tp_tunnel_sock_put */ -void l2tp_tunnel_sock_put(struct sock *sk) +static void l2tp_tunnel_sock_put(struct sock *sk) { struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk); if (tunnel) { @@ -217,7 +216,6 @@ void l2tp_tunnel_sock_put(struct sock *sk) } sock_put(sk); } -EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_put); /* Lookup a session by id in the global session list */ diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 1ee9f6965d6..1f01ba3435b 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -238,8 +238,6 @@ out: return tunnel; } -struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel); -void l2tp_tunnel_sock_put(struct sock *sk); struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index f63e1467cd3..35f89e9ce49 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -173,16 +173,16 @@ struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) } EXPORT_SYMBOL(tcf_hash_lookup); -u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo) +u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo) { - u32 val = *idx_gen; + u32 val = hinfo->index; do { if (++val == 0) val = 1; } while (tcf_hash_lookup(val, hinfo)); - *idx_gen = val; + hinfo->index = val; return val; } EXPORT_SYMBOL(tcf_hash_new_index); @@ -215,7 +215,7 @@ EXPORT_SYMBOL(tcf_hash_check); struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, int bind, - u32 *idx_gen, struct tcf_hashinfo *hinfo) + struct tcf_hashinfo *hinfo) { struct tcf_common *p = kzalloc(size, GFP_KERNEL); @@ -227,7 +227,7 @@ struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, spin_lock_init(&p->tcfc_lock); INIT_HLIST_NODE(&p->tcfc_head); - p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo); + p->tcfc_index = index ? index : tcf_hash_new_index(hinfo); p->tcfc_tm.install = jiffies; p->tcfc_tm.lastuse = jiffies; if (est) { @@ -556,9 +556,9 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, { int err = 0; struct gnet_dump d; - struct tcf_act_hdr *h = a->priv; + struct tcf_common *p = a->priv; - if (h == NULL) + if (p == NULL) goto errout; /* compat_mode being true specifies a call that is supposed @@ -567,20 +567,20 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, if (compat_mode) { if (a->type == TCA_OLD_COMPAT) err = gnet_stats_start_copy_compat(skb, 0, - TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d); + TCA_STATS, TCA_XSTATS, &p->tcfc_lock, &d); else return 0; } else err = gnet_stats_start_copy(skb, TCA_ACT_STATS, - &h->tcf_lock, &d); + &p->tcfc_lock, &d); if (err < 0) goto errout; - if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 || - gnet_stats_copy_rate_est(&d, &h->tcf_bstats, - &h->tcf_rate_est) < 0 || - gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0) + if (gnet_stats_copy_basic(&d, &p->tcfc_bstats) < 0 || + gnet_stats_copy_rate_est(&d, &p->tcfc_bstats, + &p->tcfc_rate_est) < 0 || + gnet_stats_copy_queue(&d, &p->tcfc_qstats) < 0) goto errout; if (gnet_stats_finish_copy(&d) < 0) @@ -788,6 +788,33 @@ noflush_out: return err; } +static int +tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions, + u32 portid) +{ + int ret; + struct sk_buff *skb; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION, + 0, 1) <= 0) { + kfree_skb(skb); + return -EINVAL; + } + + /* now do the delete */ + tcf_action_destroy(actions, 0); + + ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); + if (ret > 0) + return 0; + return ret; +} + static int tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, u32 portid, int event) @@ -821,27 +848,9 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, if (event == RTM_GETACTION) ret = act_get_notify(net, portid, n, &actions, event); else { /* delete */ - struct sk_buff *skb; - - skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); - if (!skb) { - ret = -ENOBUFS; - goto err; - } - - if (tca_get_fill(skb, &actions, portid, n->nlmsg_seq, 0, event, - 0, 1) <= 0) { - kfree_skb(skb); - ret = -EINVAL; + ret = tcf_del_notify(net, n, &actions, portid); + if (ret) goto err; - } - - /* now do the delete */ - tcf_action_destroy(&actions, 0); - ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC, - n->nlmsg_flags & NLM_F_ECHO); - if (ret > 0) - return 0; return ret; } err: @@ -849,60 +858,36 @@ err: return ret; } -static int tcf_add_notify(struct net *net, struct list_head *actions, - u32 portid, u32 seq, int event, u16 flags) +static int +tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions, + u32 portid) { - struct tcamsg *t; - struct nlmsghdr *nlh; struct sk_buff *skb; - struct nlattr *nest; - unsigned char *b; int err = 0; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); if (!skb) return -ENOBUFS; - b = skb_tail_pointer(skb); - - nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags); - if (!nlh) - goto out_kfree_skb; - t = nlmsg_data(nlh); - t->tca_family = AF_UNSPEC; - t->tca__pad1 = 0; - t->tca__pad2 = 0; - - nest = nla_nest_start(skb, TCA_ACT_TAB); - if (nest == NULL) - goto out_kfree_skb; - - if (tcf_action_dump(skb, actions, 0, 0) < 0) - goto out_kfree_skb; - - nla_nest_end(skb, nest); - - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - NETLINK_CB(skb).dst_group = RTNLGRP_TC; + if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags, + RTM_NEWACTION, 0, 0) <= 0) { + kfree_skb(skb); + return -EINVAL; + } - err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, flags & NLM_F_ECHO); + err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); if (err > 0) err = 0; return err; - -out_kfree_skb: - kfree_skb(skb); - return -1; } - static int tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, u32 portid, int ovr) { int ret = 0; LIST_HEAD(actions); - u32 seq = n->nlmsg_seq; ret = tcf_action_init(net, nla, NULL, NULL, ovr, 0, &actions); if (ret) @@ -911,7 +896,7 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, /* dump then free all the actions after update; inserted policy * stays intact */ - ret = tcf_add_notify(net, &actions, portid, seq, RTM_NEWACTION, n->nlmsg_flags); + ret = tcf_add_notify(net, n, &actions, portid); cleanup_a(&actions); done: return ret; diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 8b1d65772a8..ee28e1ccbbd 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -37,7 +37,6 @@ #include #define CSUM_TAB_MASK 15 -static u32 csum_idx_gen; static struct tcf_hashinfo csum_hash_info; static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = { @@ -67,7 +66,7 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &csum_idx_gen, &csum_hash_info); + &csum_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index af5641c290f..f26e6b890cc 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -24,7 +24,6 @@ #include #define GACT_TAB_MASK 15 -static u32 gact_idx_gen; static struct tcf_hashinfo gact_hash_info; #ifdef CONFIG_GACT_PROB @@ -90,7 +89,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*gact), - bind, &gact_idx_gen, &gact_hash_info); + bind, &gact_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 242636950ea..484bd19601e 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -29,7 +29,6 @@ #define IPT_TAB_MASK 15 -static u32 ipt_idx_gen; static struct tcf_hashinfo ipt_hash_info; static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int hook) @@ -129,7 +128,7 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, pc = tcf_hash_check(index, a, bind, &ipt_hash_info); if (!pc) { pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind, - &ipt_idx_gen, &ipt_hash_info); + &ipt_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 9dbb8cd64cb..5d05b573a62 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -30,7 +30,6 @@ #include #define MIRRED_TAB_MASK 7 -static u32 mirred_idx_gen; static LIST_HEAD(mirred_list); static struct tcf_hashinfo mirred_hash_info; @@ -107,7 +106,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, if (dev == NULL) return -EINVAL; pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind, - &mirred_idx_gen, &mirred_hash_info); + &mirred_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 584e65503ed..a49fa23b49d 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -30,7 +30,6 @@ #define NAT_TAB_MASK 15 -static u32 nat_idx_gen; static struct tcf_hashinfo nat_hash_info; @@ -61,7 +60,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, pc = tcf_hash_check(parm->index, a, bind, &nat_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &nat_idx_gen, &nat_hash_info); + &nat_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); ret = ACT_P_CREATED; diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 72918934193..f361e4e3c31 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -24,7 +24,6 @@ #include #define PEDIT_TAB_MASK 15 -static u32 pedit_idx_gen; static struct tcf_hashinfo pedit_hash_info; @@ -63,7 +62,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, if (!parm->nkeys) return -EINVAL; pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, - &pedit_idx_gen, &pedit_hash_info); + &pedit_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); p = to_pedit(pc); diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 9295b86d531..a719fdff575 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -41,7 +41,6 @@ struct tcf_police { container_of(pc, struct tcf_police, common) #define POL_TAB_MASK 15 -static u32 police_idx_gen; static struct tcf_hashinfo police_hash_info; /* old policer structure from before tc actions */ @@ -251,7 +250,7 @@ override: police->tcfp_t_c = ktime_to_ns(ktime_get()); police->tcf_index = parm->index ? parm->index : - tcf_hash_new_index(&police_idx_gen, &police_hash_info); + tcf_hash_new_index(&police_hash_info); h = tcf_hash(police->tcf_index, POL_TAB_MASK); spin_lock_bh(&police_hash_info.lock); hlist_add_head(&police->tcf_head, &police_hash_info.htab[h]); diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index b44491e3ec1..f7d5406c1fe 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -25,7 +25,6 @@ #include #define SIMP_TAB_MASK 7 -static u32 simp_idx_gen; static struct tcf_hashinfo simp_hash_info; #define SIMP_MAX_DATA 32 @@ -118,7 +117,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &simp_idx_gen, &simp_hash_info); + &simp_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 0fa1aad6e20..74af4612706 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -28,7 +28,6 @@ #include #define SKBEDIT_TAB_MASK 15 -static u32 skbedit_idx_gen; static struct tcf_hashinfo skbedit_hash_info; static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a, @@ -104,7 +103,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, pc = tcf_hash_check(parm->index, a, bind, &skbedit_hash_info); if (!pc) { pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind, - &skbedit_idx_gen, &skbedit_hash_info); + &skbedit_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index d8c42b1b88e..29a30a14c31 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -340,7 +340,7 @@ errout: return err; } -static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, +static int tcf_fill_node(struct net *net, struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh, u32 portid, u32 seq, u16 flags, int event) { struct tcmsg *tcm; @@ -362,7 +362,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, tcm->tcm_handle = fh; if (RTM_DELTFILTER != event) { tcm->tcm_handle = 0; - if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0) + if (tp->ops->dump && tp->ops->dump(net, tp, fh, skb, tcm) < 0) goto nla_put_failure; } nlh->nlmsg_len = skb_tail_pointer(skb) - b; @@ -385,7 +385,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, if (!skb) return -ENOBUFS; - if (tcf_fill_node(skb, tp, fh, portid, n->nlmsg_seq, 0, event) <= 0) { + if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, 0, event) <= 0) { kfree_skb(skb); return -EINVAL; } @@ -404,8 +404,9 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, struct tcf_walker *arg) { struct tcf_dump_args *a = (void *)arg; + struct net *net = sock_net(a->skb->sk); - return tcf_fill_node(a->skb, tp, n, NETLINK_CB(a->cb->skb).portid, + return tcf_fill_node(net, a->skb, tp, n, NETLINK_CB(a->cb->skb).portid, a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER); } @@ -463,7 +464,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) if (t > s_t) memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); if (cb->args[1] == 0) { - if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).portid, + if (tcf_fill_node(net, skb, tp, 0, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER) <= 0) break; diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index b6552035d1f..e98ca99c202 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -38,7 +38,7 @@ static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct tcf_result *res) { int r; - struct basic_head *head = (struct basic_head *) tp->root; + struct basic_head *head = tp->root; struct basic_filter *f; list_for_each_entry(f, &head->flist, link) { @@ -56,7 +56,7 @@ static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp, static unsigned long basic_get(struct tcf_proto *tp, u32 handle) { unsigned long l = 0UL; - struct basic_head *head = (struct basic_head *) tp->root; + struct basic_head *head = tp->root; struct basic_filter *f; if (head == NULL) @@ -107,7 +107,7 @@ static void basic_destroy(struct tcf_proto *tp) static int basic_delete(struct tcf_proto *tp, unsigned long arg) { - struct basic_head *head = (struct basic_head *) tp->root; + struct basic_head *head = tp->root; struct basic_filter *t, *f = (struct basic_filter *) arg; list_for_each_entry(t, &head->flist, link) @@ -164,7 +164,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb, struct nlattr **tca, unsigned long *arg) { int err; - struct basic_head *head = (struct basic_head *) tp->root; + struct basic_head *head = tp->root; struct nlattr *tb[TCA_BASIC_MAX + 1]; struct basic_filter *f = (struct basic_filter *) *arg; @@ -225,7 +225,7 @@ errout: static void basic_walk(struct tcf_proto *tp, struct tcf_walker *arg) { - struct basic_head *head = (struct basic_head *) tp->root; + struct basic_head *head = tp->root; struct basic_filter *f; list_for_each_entry(f, &head->flist, link) { @@ -241,7 +241,7 @@ skip: } } -static int basic_dump(struct tcf_proto *tp, unsigned long fh, +static int basic_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct basic_filter *f = (struct basic_filter *) fh; diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 00a5a585e5f..8e3cf49118e 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -295,7 +295,7 @@ errout: return ret; } -static int cls_bpf_dump(struct tcf_proto *tp, unsigned long fh, +static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *tm) { struct cls_bpf_prog *prog = (struct cls_bpf_prog *) fh; diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 8349fcdc50f..8e2158ab551 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -164,7 +164,7 @@ skip: arg->count++; } -static int cls_cgroup_dump(struct tcf_proto *tp, unsigned long fh, +static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct cls_cgroup_head *head = tp->root; diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index dfd18a5c3e8..257029c5433 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -563,7 +563,7 @@ static void flow_put(struct tcf_proto *tp, unsigned long f) { } -static int flow_dump(struct tcf_proto *tp, unsigned long fh, +static int flow_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct flow_filter *f = (struct flow_filter *)fh; diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 3f9cece1380..ed00e8c21ce 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -41,7 +41,7 @@ struct fw_filter { u32 id; struct tcf_result res; #ifdef CONFIG_NET_CLS_IND - char indev[IFNAMSIZ]; + int ifindex; #endif /* CONFIG_NET_CLS_IND */ struct tcf_exts exts; }; @@ -75,7 +75,7 @@ static inline int fw_hash(u32 handle) static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct tcf_result *res) { - struct fw_head *head = (struct fw_head *)tp->root; + struct fw_head *head = tp->root; struct fw_filter *f; int r; u32 id = skb->mark; @@ -86,7 +86,7 @@ static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, if (f->id == id) { *res = f->res; #ifdef CONFIG_NET_CLS_IND - if (!tcf_match_indev(skb, f->indev)) + if (!tcf_match_indev(skb, f->ifindex)) continue; #endif /* CONFIG_NET_CLS_IND */ r = tcf_exts_exec(skb, &f->exts, res); @@ -111,7 +111,7 @@ static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, static unsigned long fw_get(struct tcf_proto *tp, u32 handle) { - struct fw_head *head = (struct fw_head *)tp->root; + struct fw_head *head = tp->root; struct fw_filter *f; if (head == NULL) @@ -160,7 +160,7 @@ static void fw_destroy(struct tcf_proto *tp) static int fw_delete(struct tcf_proto *tp, unsigned long arg) { - struct fw_head *head = (struct fw_head *)tp->root; + struct fw_head *head = tp->root; struct fw_filter *f = (struct fw_filter *)arg; struct fw_filter **fp; @@ -190,7 +190,7 @@ static int fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, struct nlattr **tb, struct nlattr **tca, unsigned long base) { - struct fw_head *head = (struct fw_head *)tp->root; + struct fw_head *head = tp->root; struct tcf_exts e; u32 mask; int err; @@ -207,9 +207,11 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, #ifdef CONFIG_NET_CLS_IND if (tb[TCA_FW_INDEV]) { - err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV]); - if (err < 0) + int ret; + ret = tcf_change_indev(net, tb[TCA_FW_INDEV]); + if (ret < 0) goto errout; + f->ifindex = ret; } #endif /* CONFIG_NET_CLS_IND */ @@ -235,7 +237,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, struct nlattr **tca, unsigned long *arg) { - struct fw_head *head = (struct fw_head *)tp->root; + struct fw_head *head = tp->root; struct fw_filter *f = (struct fw_filter *) *arg; struct nlattr *opt = tca[TCA_OPTIONS]; struct nlattr *tb[TCA_FW_MAX + 1]; @@ -298,7 +300,7 @@ errout: static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg) { - struct fw_head *head = (struct fw_head *)tp->root; + struct fw_head *head = tp->root; int h; if (head == NULL) @@ -324,10 +326,10 @@ static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int fw_dump(struct tcf_proto *tp, unsigned long fh, +static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { - struct fw_head *head = (struct fw_head *)tp->root; + struct fw_head *head = tp->root; struct fw_filter *f = (struct fw_filter *)fh; unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; @@ -348,9 +350,12 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh, nla_put_u32(skb, TCA_FW_CLASSID, f->res.classid)) goto nla_put_failure; #ifdef CONFIG_NET_CLS_IND - if (strlen(f->indev) && - nla_put_string(skb, TCA_FW_INDEV, f->indev)) - goto nla_put_failure; + if (f->ifindex) { + struct net_device *dev; + dev = __dev_get_by_index(net, f->ifindex); + if (dev && nla_put_string(skb, TCA_FW_INDEV, dev->name)) + goto nla_put_failure; + } #endif /* CONFIG_NET_CLS_IND */ if (head->mask != 0xFFFFFFFF && nla_put_u32(skb, TCA_FW_MASK, head->mask)) diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 2473953a594..1ad3068f2ce 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -123,7 +123,7 @@ static inline int route4_hash_wild(void) static int route4_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct tcf_result *res) { - struct route4_head *head = (struct route4_head *)tp->root; + struct route4_head *head = tp->root; struct dst_entry *dst; struct route4_bucket *b; struct route4_filter *f; @@ -213,7 +213,7 @@ static inline u32 from_hash(u32 id) static unsigned long route4_get(struct tcf_proto *tp, u32 handle) { - struct route4_head *head = (struct route4_head *)tp->root; + struct route4_head *head = tp->root; struct route4_bucket *b; struct route4_filter *f; unsigned int h1, h2; @@ -284,7 +284,7 @@ static void route4_destroy(struct tcf_proto *tp) static int route4_delete(struct tcf_proto *tp, unsigned long arg) { - struct route4_head *head = (struct route4_head *)tp->root; + struct route4_head *head = tp->root; struct route4_filter **fp, *f = (struct route4_filter *)arg; unsigned int h = 0; struct route4_bucket *b; @@ -551,7 +551,7 @@ static void route4_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int route4_dump(struct tcf_proto *tp, unsigned long fh, +static int route4_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct route4_filter *f = (struct route4_filter *)fh; diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 4f25c2ac825..19f8e5dfa8b 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -594,7 +594,7 @@ static void rsvp_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, +static int rsvp_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct rsvp_filter *f = (struct rsvp_filter *)fh; diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index ffad18791c9..eed8404443d 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -24,9 +24,6 @@ #define DEFAULT_HASH_SIZE 64 /* optimized for diffserv */ -#define PRIV(tp) ((struct tcindex_data *) (tp)->root) - - struct tcindex_filter_result { struct tcf_exts exts; struct tcf_result res; @@ -77,7 +74,7 @@ tcindex_lookup(struct tcindex_data *p, u16 key) static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct tcf_result *res) { - struct tcindex_data *p = PRIV(tp); + struct tcindex_data *p = tp->root; struct tcindex_filter_result *f; int key = (skb->tc_index & p->mask) >> p->shift; @@ -102,7 +99,7 @@ static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp, static unsigned long tcindex_get(struct tcf_proto *tp, u32 handle) { - struct tcindex_data *p = PRIV(tp); + struct tcindex_data *p = tp->root; struct tcindex_filter_result *r; pr_debug("tcindex_get(tp %p,handle 0x%08x)\n", tp, handle); @@ -140,7 +137,7 @@ static int tcindex_init(struct tcf_proto *tp) static int __tcindex_delete(struct tcf_proto *tp, unsigned long arg, int lock) { - struct tcindex_data *p = PRIV(tp); + struct tcindex_data *p = tp->root; struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg; struct tcindex_filter *f = NULL; @@ -338,7 +335,7 @@ tcindex_change(struct net *net, struct sk_buff *in_skb, { struct nlattr *opt = tca[TCA_OPTIONS]; struct nlattr *tb[TCA_TCINDEX_MAX + 1]; - struct tcindex_data *p = PRIV(tp); + struct tcindex_data *p = tp->root; struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg; int err; @@ -360,7 +357,7 @@ tcindex_change(struct net *net, struct sk_buff *in_skb, static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) { - struct tcindex_data *p = PRIV(tp); + struct tcindex_data *p = tp->root; struct tcindex_filter *f, *next; int i; @@ -407,7 +404,7 @@ static int tcindex_destroy_element(struct tcf_proto *tp, static void tcindex_destroy(struct tcf_proto *tp) { - struct tcindex_data *p = PRIV(tp); + struct tcindex_data *p = tp->root; struct tcf_walker walker; pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p); @@ -422,10 +419,10 @@ static void tcindex_destroy(struct tcf_proto *tp) } -static int tcindex_dump(struct tcf_proto *tp, unsigned long fh, +static int tcindex_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { - struct tcindex_data *p = PRIV(tp); + struct tcindex_data *p = tp->root; struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh; unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 20f2fb79c74..84c28daff84 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -48,7 +48,7 @@ struct tc_u_knode { struct tc_u_hnode *ht_up; struct tcf_exts exts; #ifdef CONFIG_NET_CLS_IND - char indev[IFNAMSIZ]; + int ifindex; #endif u8 fshift; struct tcf_result res; @@ -95,7 +95,7 @@ static int u32_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct unsigned int off; } stack[TC_U32_MAXDEPTH]; - struct tc_u_hnode *ht = (struct tc_u_hnode *)tp->root; + struct tc_u_hnode *ht = tp->root; unsigned int off = skb_network_offset(skb); struct tc_u_knode *n; int sdepth = 0; @@ -152,7 +152,7 @@ check_terminal: *res = n->res; #ifdef CONFIG_NET_CLS_IND - if (!tcf_match_indev(skb, n->indev)) { + if (!tcf_match_indev(skb, n->ifindex)) { n = n->next; goto next_knode; } @@ -527,9 +527,11 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, #ifdef CONFIG_NET_CLS_IND if (tb[TCA_U32_INDEV]) { - err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV]); - if (err < 0) + int ret; + ret = tcf_change_indev(net, tb[TCA_U32_INDEV]); + if (ret < 0) goto errout; + n->ifindex = ret; } #endif tcf_exts_change(tp, &n->exts, &e); @@ -712,7 +714,7 @@ static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int u32_dump(struct tcf_proto *tp, unsigned long fh, +static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct tc_u_knode *n = (struct tc_u_knode *)fh; @@ -760,9 +762,12 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; #ifdef CONFIG_NET_CLS_IND - if (strlen(n->indev) && - nla_put_string(skb, TCA_U32_INDEV, n->indev)) - goto nla_put_failure; + if (n->ifindex) { + struct net_device *dev; + dev = __dev_get_by_index(net, n->ifindex); + if (dev && nla_put_string(skb, TCA_U32_INDEV, dev->name)) + goto nla_put_failure; + } #endif #ifdef CONFIG_CLS_U32_PERF if (nla_put(skb, TCA_U32_PCNT, diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c index cf7f614e841..1cf84a9e13a 100644 --- a/net/sched/sch_hhf.c +++ b/net/sched/sch_hhf.c @@ -574,18 +574,18 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt) q->hh_flows_limit = nla_get_u32(tb[TCA_HHF_HH_FLOWS_LIMIT]); if (tb[TCA_HHF_RESET_TIMEOUT]) { - u32 ms = nla_get_u32(tb[TCA_HHF_RESET_TIMEOUT]); + u32 us = nla_get_u32(tb[TCA_HHF_RESET_TIMEOUT]); - q->hhf_reset_timeout = msecs_to_jiffies(ms); + q->hhf_reset_timeout = usecs_to_jiffies(us); } if (tb[TCA_HHF_ADMIT_BYTES]) q->hhf_admit_bytes = nla_get_u32(tb[TCA_HHF_ADMIT_BYTES]); if (tb[TCA_HHF_EVICT_TIMEOUT]) { - u32 ms = nla_get_u32(tb[TCA_HHF_EVICT_TIMEOUT]); + u32 us = nla_get_u32(tb[TCA_HHF_EVICT_TIMEOUT]); - q->hhf_evict_timeout = msecs_to_jiffies(ms); + q->hhf_evict_timeout = usecs_to_jiffies(us); } qlen = sch->q.qlen; @@ -684,10 +684,10 @@ static int hhf_dump(struct Qdisc *sch, struct sk_buff *skb) nla_put_u32(skb, TCA_HHF_QUANTUM, q->quantum) || nla_put_u32(skb, TCA_HHF_HH_FLOWS_LIMIT, q->hh_flows_limit) || nla_put_u32(skb, TCA_HHF_RESET_TIMEOUT, - jiffies_to_msecs(q->hhf_reset_timeout)) || + jiffies_to_usecs(q->hhf_reset_timeout)) || nla_put_u32(skb, TCA_HHF_ADMIT_BYTES, q->hhf_admit_bytes) || nla_put_u32(skb, TCA_HHF_EVICT_TIMEOUT, - jiffies_to_msecs(q->hhf_evict_timeout)) || + jiffies_to_usecs(q->hhf_evict_timeout)) || nla_put_u32(skb, TCA_HHF_NON_HH_WEIGHT, q->hhf_non_hh_weight)) goto nla_put_failure; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 34b7726bcd7..7c161084f24 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1030,6 +1030,7 @@ static const struct net_protocol sctp_protocol = { .err_handler = sctp_v4_err, .no_policy = 1, .netns_ok = 1, + .icmp_strict_tag_validation = 1, }; /* IPv4 address related functions. */ diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index e5f7cdb42a8..632090b961c 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -78,6 +78,8 @@ static int sctp_process_param(struct sctp_association *asoc, gfp_t gfp); static void *sctp_addto_param(struct sctp_chunk *chunk, int len, const void *data); +static void *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, + const void *data); /* Control chunk destructor */ static void sctp_control_release_owner(struct sk_buff *skb) @@ -1475,8 +1477,8 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) /* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient * space in the chunk */ -void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, - int len, const void *data) +static void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, + int len, const void *data) { if (skb_tailroom(chunk->skb) >= len) return sctp_addto_chunk(chunk, len, data);