diff options
author | David S. Miller <davem@davemloft.net> | 2011-03-10 17:26:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-10 17:26:00 -0500 |
commit | 33175d84ee3fa29991adb80513683e010769e807 (patch) | |
tree | 3731f61cf82451b6892cf1368701e57e35d92908 /drivers/net | |
parent | c5908939b2738bafe1b309bc2465cb9f2e6184c5 (diff) | |
parent | 6dfbd87a20a737641ef228230c77f4262434fa24 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/bnx2x/bnx2x_cmn.c
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 5 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 22 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.h | 9 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 18 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 19 | ||||
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 32 | ||||
-rw-r--r-- | drivers/net/bonding/bond_3ad.h | 3 | ||||
-rw-r--r-- | drivers/net/macvtap.c | 3 | ||||
-rw-r--r-- | drivers/net/smsc911x.c | 5 |
9 files changed, 80 insertions, 36 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 50d1e0793091..b7ff87b35fbb 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -1223,6 +1223,7 @@ struct bnx2x { | |||
1223 | /* DCBX Negotation results */ | 1223 | /* DCBX Negotation results */ |
1224 | struct dcbx_features dcbx_local_feat; | 1224 | struct dcbx_features dcbx_local_feat; |
1225 | u32 dcbx_error; | 1225 | u32 dcbx_error; |
1226 | u32 pending_max; | ||
1226 | }; | 1227 | }; |
1227 | 1228 | ||
1228 | /** | 1229 | /** |
@@ -1634,8 +1635,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, | |||
1634 | /* CMNG constants, as derived from system spec calculations */ | 1635 | /* CMNG constants, as derived from system spec calculations */ |
1635 | /* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ | 1636 | /* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ |
1636 | #define DEF_MIN_RATE 100 | 1637 | #define DEF_MIN_RATE 100 |
1637 | /* resolution of the rate shaping timer - 100 usec */ | 1638 | /* resolution of the rate shaping timer - 400 usec */ |
1638 | #define RS_PERIODIC_TIMEOUT_USEC 100 | 1639 | #define RS_PERIODIC_TIMEOUT_USEC 400 |
1639 | /* number of bytes in single QM arbitration cycle - | 1640 | /* number of bytes in single QM arbitration cycle - |
1640 | * coefficient for calculating the fairness timer */ | 1641 | * coefficient for calculating the fairness timer */ |
1641 | #define QM_ARB_BYTES 160000 | 1642 | #define QM_ARB_BYTES 160000 |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index b01b622f4e13..e83ac6dd6fc0 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
@@ -993,6 +993,23 @@ void bnx2x_free_skbs(struct bnx2x *bp) | |||
993 | bnx2x_free_rx_skbs(bp); | 993 | bnx2x_free_rx_skbs(bp); |
994 | } | 994 | } |
995 | 995 | ||
996 | void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value) | ||
997 | { | ||
998 | /* load old values */ | ||
999 | u32 mf_cfg = bp->mf_config[BP_VN(bp)]; | ||
1000 | |||
1001 | if (value != bnx2x_extract_max_cfg(bp, mf_cfg)) { | ||
1002 | /* leave all but MAX value */ | ||
1003 | mf_cfg &= ~FUNC_MF_CFG_MAX_BW_MASK; | ||
1004 | |||
1005 | /* set new MAX value */ | ||
1006 | mf_cfg |= (value << FUNC_MF_CFG_MAX_BW_SHIFT) | ||
1007 | & FUNC_MF_CFG_MAX_BW_MASK; | ||
1008 | |||
1009 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, mf_cfg); | ||
1010 | } | ||
1011 | } | ||
1012 | |||
996 | static void bnx2x_free_msix_irqs(struct bnx2x *bp) | 1013 | static void bnx2x_free_msix_irqs(struct bnx2x *bp) |
997 | { | 1014 | { |
998 | int i, offset = 1; | 1015 | int i, offset = 1; |
@@ -1498,6 +1515,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
1498 | /* Clear UC lists configuration */ | 1515 | /* Clear UC lists configuration */ |
1499 | bnx2x_invalidate_uc_list(bp); | 1516 | bnx2x_invalidate_uc_list(bp); |
1500 | 1517 | ||
1518 | if (bp->pending_max) { | ||
1519 | bnx2x_update_max_mf_config(bp, bp->pending_max); | ||
1520 | bp->pending_max = 0; | ||
1521 | } | ||
1522 | |||
1501 | if (bp->port.pmf) | 1523 | if (bp->port.pmf) |
1502 | bnx2x_initial_phy_init(bp, load_mode); | 1524 | bnx2x_initial_phy_init(bp, load_mode); |
1503 | 1525 | ||
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 8c401c990bf2..ef37b98d6146 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h | |||
@@ -341,6 +341,15 @@ void bnx2x_dcbx_init(struct bnx2x *bp); | |||
341 | */ | 341 | */ |
342 | int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); | 342 | int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); |
343 | 343 | ||
344 | /** | ||
345 | * Updates MAX part of MF configuration in HW | ||
346 | * (if required) | ||
347 | * | ||
348 | * @param bp | ||
349 | * @param value | ||
350 | */ | ||
351 | void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value); | ||
352 | |||
344 | /* dev_close main block */ | 353 | /* dev_close main block */ |
345 | int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); | 354 | int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); |
346 | 355 | ||
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 85291d8b3329..f5050155c6b5 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c | |||
@@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
238 | speed |= (cmd->speed_hi << 16); | 238 | speed |= (cmd->speed_hi << 16); |
239 | 239 | ||
240 | if (IS_MF_SI(bp)) { | 240 | if (IS_MF_SI(bp)) { |
241 | u32 param = 0, part; | 241 | u32 part; |
242 | u32 line_speed = bp->link_vars.line_speed; | 242 | u32 line_speed = bp->link_vars.line_speed; |
243 | 243 | ||
244 | /* use 10G if no link detected */ | 244 | /* use 10G if no link detected */ |
@@ -251,24 +251,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
251 | REQ_BC_VER_4_SET_MF_BW); | 251 | REQ_BC_VER_4_SET_MF_BW); |
252 | return -EINVAL; | 252 | return -EINVAL; |
253 | } | 253 | } |
254 | |||
254 | part = (speed * 100) / line_speed; | 255 | part = (speed * 100) / line_speed; |
256 | |||
255 | if (line_speed < speed || !part) { | 257 | if (line_speed < speed || !part) { |
256 | BNX2X_DEV_INFO("Speed setting should be in a range " | 258 | BNX2X_DEV_INFO("Speed setting should be in a range " |
257 | "from 1%% to 100%% " | 259 | "from 1%% to 100%% " |
258 | "of actual line speed\n"); | 260 | "of actual line speed\n"); |
259 | return -EINVAL; | 261 | return -EINVAL; |
260 | } | 262 | } |
261 | /* load old values */ | ||
262 | param = bp->mf_config[BP_VN(bp)]; | ||
263 | 263 | ||
264 | /* leave only MIN value */ | 264 | if (bp->state != BNX2X_STATE_OPEN) |
265 | param &= FUNC_MF_CFG_MIN_BW_MASK; | 265 | /* store value for following "load" */ |
266 | 266 | bp->pending_max = part; | |
267 | /* set new MAX value */ | 267 | else |
268 | param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT) | 268 | bnx2x_update_max_mf_config(bp, part); |
269 | & FUNC_MF_CFG_MAX_BW_MASK; | ||
270 | 269 | ||
271 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); | ||
272 | return 0; | 270 | return 0; |
273 | } | 271 | } |
274 | 272 | ||
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 30b21d2f26f6..bba21d5f708b 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -2092,8 +2092,9 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) | |||
2092 | bnx2x_calc_vn_weight_sum(bp); | 2092 | bnx2x_calc_vn_weight_sum(bp); |
2093 | 2093 | ||
2094 | /* calculate and set min-max rate for each vn */ | 2094 | /* calculate and set min-max rate for each vn */ |
2095 | for (vn = VN_0; vn < E1HVN_MAX; vn++) | 2095 | if (bp->port.pmf) |
2096 | bnx2x_init_vn_minmax(bp, vn); | 2096 | for (vn = VN_0; vn < E1HVN_MAX; vn++) |
2097 | bnx2x_init_vn_minmax(bp, vn); | ||
2097 | 2098 | ||
2098 | /* always enable rate shaping and fairness */ | 2099 | /* always enable rate shaping and fairness */ |
2099 | bp->cmng.flags.cmng_enables |= | 2100 | bp->cmng.flags.cmng_enables |= |
@@ -2162,13 +2163,6 @@ static void bnx2x_link_attn(struct bnx2x *bp) | |||
2162 | bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); | 2163 | bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); |
2163 | } | 2164 | } |
2164 | 2165 | ||
2165 | /* indicate link status only if link status actually changed */ | ||
2166 | if (prev_link_status != bp->link_vars.link_status) | ||
2167 | bnx2x_link_report(bp); | ||
2168 | |||
2169 | if (IS_MF(bp)) | ||
2170 | bnx2x_link_sync_notify(bp); | ||
2171 | |||
2172 | if (bp->link_vars.link_up && bp->link_vars.line_speed) { | 2166 | if (bp->link_vars.link_up && bp->link_vars.line_speed) { |
2173 | int cmng_fns = bnx2x_get_cmng_fns_mode(bp); | 2167 | int cmng_fns = bnx2x_get_cmng_fns_mode(bp); |
2174 | 2168 | ||
@@ -2180,6 +2174,13 @@ static void bnx2x_link_attn(struct bnx2x *bp) | |||
2180 | DP(NETIF_MSG_IFUP, | 2174 | DP(NETIF_MSG_IFUP, |
2181 | "single function mode without fairness\n"); | 2175 | "single function mode without fairness\n"); |
2182 | } | 2176 | } |
2177 | |||
2178 | if (IS_MF(bp)) | ||
2179 | bnx2x_link_sync_notify(bp); | ||
2180 | |||
2181 | /* indicate link status only if link status actually changed */ | ||
2182 | if (prev_link_status != bp->link_vars.link_status) | ||
2183 | bnx2x_link_report(bp); | ||
2183 | } | 2184 | } |
2184 | 2185 | ||
2185 | void bnx2x__link_status_update(struct bnx2x *bp) | 2186 | void bnx2x__link_status_update(struct bnx2x *bp) |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 1024ae158227..a5d5d0b5b155 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -281,23 +281,23 @@ static inline int __check_agg_selection_timer(struct port *port) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | /** | 283 | /** |
284 | * __get_rx_machine_lock - lock the port's RX machine | 284 | * __get_state_machine_lock - lock the port's state machines |
285 | * @port: the port we're looking at | 285 | * @port: the port we're looking at |
286 | * | 286 | * |
287 | */ | 287 | */ |
288 | static inline void __get_rx_machine_lock(struct port *port) | 288 | static inline void __get_state_machine_lock(struct port *port) |
289 | { | 289 | { |
290 | spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 290 | spin_lock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); |
291 | } | 291 | } |
292 | 292 | ||
293 | /** | 293 | /** |
294 | * __release_rx_machine_lock - unlock the port's RX machine | 294 | * __release_state_machine_lock - unlock the port's state machines |
295 | * @port: the port we're looking at | 295 | * @port: the port we're looking at |
296 | * | 296 | * |
297 | */ | 297 | */ |
298 | static inline void __release_rx_machine_lock(struct port *port) | 298 | static inline void __release_state_machine_lock(struct port *port) |
299 | { | 299 | { |
300 | spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 300 | spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); |
301 | } | 301 | } |
302 | 302 | ||
303 | /** | 303 | /** |
@@ -388,14 +388,14 @@ static u8 __get_duplex(struct port *port) | |||
388 | } | 388 | } |
389 | 389 | ||
390 | /** | 390 | /** |
391 | * __initialize_port_locks - initialize a port's RX machine spinlock | 391 | * __initialize_port_locks - initialize a port's STATE machine spinlock |
392 | * @port: the port we're looking at | 392 | * @port: the port we're looking at |
393 | * | 393 | * |
394 | */ | 394 | */ |
395 | static inline void __initialize_port_locks(struct port *port) | 395 | static inline void __initialize_port_locks(struct port *port) |
396 | { | 396 | { |
397 | // make sure it isn't called twice | 397 | // make sure it isn't called twice |
398 | spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); | 398 | spin_lock_init(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); |
399 | } | 399 | } |
400 | 400 | ||
401 | //conversions | 401 | //conversions |
@@ -1025,9 +1025,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1025 | { | 1025 | { |
1026 | rx_states_t last_state; | 1026 | rx_states_t last_state; |
1027 | 1027 | ||
1028 | // Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback) | ||
1029 | __get_rx_machine_lock(port); | ||
1030 | |||
1031 | // keep current State Machine state to compare later if it was changed | 1028 | // keep current State Machine state to compare later if it was changed |
1032 | last_state = port->sm_rx_state; | 1029 | last_state = port->sm_rx_state; |
1033 | 1030 | ||
@@ -1133,7 +1130,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1133 | pr_err("%s: An illegal loopback occurred on adapter (%s).\n" | 1130 | pr_err("%s: An illegal loopback occurred on adapter (%s).\n" |
1134 | "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", | 1131 | "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", |
1135 | port->slave->dev->master->name, port->slave->dev->name); | 1132 | port->slave->dev->master->name, port->slave->dev->name); |
1136 | __release_rx_machine_lock(port); | ||
1137 | return; | 1133 | return; |
1138 | } | 1134 | } |
1139 | __update_selected(lacpdu, port); | 1135 | __update_selected(lacpdu, port); |
@@ -1153,7 +1149,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1153 | break; | 1149 | break; |
1154 | } | 1150 | } |
1155 | } | 1151 | } |
1156 | __release_rx_machine_lock(port); | ||
1157 | } | 1152 | } |
1158 | 1153 | ||
1159 | /** | 1154 | /** |
@@ -2155,6 +2150,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2155 | goto re_arm; | 2150 | goto re_arm; |
2156 | } | 2151 | } |
2157 | 2152 | ||
2153 | /* Lock around state machines to protect data accessed | ||
2154 | * by all (e.g., port->sm_vars). ad_rx_machine may run | ||
2155 | * concurrently due to incoming LACPDU. | ||
2156 | */ | ||
2157 | __get_state_machine_lock(port); | ||
2158 | |||
2158 | ad_rx_machine(NULL, port); | 2159 | ad_rx_machine(NULL, port); |
2159 | ad_periodic_machine(port); | 2160 | ad_periodic_machine(port); |
2160 | ad_port_selection_logic(port); | 2161 | ad_port_selection_logic(port); |
@@ -2164,6 +2165,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2164 | // turn off the BEGIN bit, since we already handled it | 2165 | // turn off the BEGIN bit, since we already handled it |
2165 | if (port->sm_vars & AD_PORT_BEGIN) | 2166 | if (port->sm_vars & AD_PORT_BEGIN) |
2166 | port->sm_vars &= ~AD_PORT_BEGIN; | 2167 | port->sm_vars &= ~AD_PORT_BEGIN; |
2168 | |||
2169 | __release_state_machine_lock(port); | ||
2167 | } | 2170 | } |
2168 | 2171 | ||
2169 | re_arm: | 2172 | re_arm: |
@@ -2200,7 +2203,10 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u | |||
2200 | case AD_TYPE_LACPDU: | 2203 | case AD_TYPE_LACPDU: |
2201 | pr_debug("Received LACPDU on port %d\n", | 2204 | pr_debug("Received LACPDU on port %d\n", |
2202 | port->actor_port_number); | 2205 | port->actor_port_number); |
2206 | /* Protect against concurrent state machines */ | ||
2207 | __get_state_machine_lock(port); | ||
2203 | ad_rx_machine(lacpdu, port); | 2208 | ad_rx_machine(lacpdu, port); |
2209 | __release_state_machine_lock(port); | ||
2204 | break; | 2210 | break; |
2205 | 2211 | ||
2206 | case AD_TYPE_MARKER: | 2212 | case AD_TYPE_MARKER: |
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 2c46a154f2c6..b28baff70864 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
@@ -264,7 +264,8 @@ struct ad_bond_info { | |||
264 | struct ad_slave_info { | 264 | struct ad_slave_info { |
265 | struct aggregator aggregator; // 802.3ad aggregator structure | 265 | struct aggregator aggregator; // 802.3ad aggregator structure |
266 | struct port port; // 802.3ad port structure | 266 | struct port port; // 802.3ad port structure |
267 | spinlock_t rx_machine_lock; // To avoid race condition between callback and receive interrupt | 267 | spinlock_t state_machine_lock; /* mutex state machines vs. |
268 | incoming LACPDU */ | ||
268 | u16 id; | 269 | u16 id; |
269 | }; | 270 | }; |
270 | 271 | ||
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 2300e4599520..6696e56e6320 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -530,8 +530,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, | |||
530 | vnet_hdr_len = q->vnet_hdr_sz; | 530 | vnet_hdr_len = q->vnet_hdr_sz; |
531 | 531 | ||
532 | err = -EINVAL; | 532 | err = -EINVAL; |
533 | if ((len -= vnet_hdr_len) < 0) | 533 | if (len < vnet_hdr_len) |
534 | goto err; | 534 | goto err; |
535 | len -= vnet_hdr_len; | ||
535 | 536 | ||
536 | err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, | 537 | err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, |
537 | sizeof(vnet_hdr)); | 538 | sizeof(vnet_hdr)); |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 64bfdae5956f..d70bde95460b 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -1178,6 +1178,11 @@ static int smsc911x_open(struct net_device *dev) | |||
1178 | smsc911x_reg_write(pdata, HW_CFG, 0x00050000); | 1178 | smsc911x_reg_write(pdata, HW_CFG, 0x00050000); |
1179 | smsc911x_reg_write(pdata, AFC_CFG, 0x006E3740); | 1179 | smsc911x_reg_write(pdata, AFC_CFG, 0x006E3740); |
1180 | 1180 | ||
1181 | /* Increase the legal frame size of VLAN tagged frames to 1522 bytes */ | ||
1182 | spin_lock_irq(&pdata->mac_lock); | ||
1183 | smsc911x_mac_write(pdata, VLAN1, ETH_P_8021Q); | ||
1184 | spin_unlock_irq(&pdata->mac_lock); | ||
1185 | |||
1181 | /* Make sure EEPROM has finished loading before setting GPIO_CFG */ | 1186 | /* Make sure EEPROM has finished loading before setting GPIO_CFG */ |
1182 | timeout = 50; | 1187 | timeout = 50; |
1183 | while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) && | 1188 | while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) && |