diff options
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_cmn.c')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 710ce5d04c53..93798129061b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
@@ -259,10 +259,44 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
259 | #endif | 259 | #endif |
260 | } | 260 | } |
261 | 261 | ||
262 | /* Timestamp option length allowed for TPA aggregation: | ||
263 | * | ||
264 | * nop nop kind length echo val | ||
265 | */ | ||
266 | #define TPA_TSTAMP_OPT_LEN 12 | ||
267 | /** | ||
268 | * Calculate the approximate value of the MSS for this | ||
269 | * aggregation using the first packet of it. | ||
270 | * | ||
271 | * @param bp | ||
272 | * @param parsing_flags Parsing flags from the START CQE | ||
273 | * @param len_on_bd Total length of the first packet for the | ||
274 | * aggregation. | ||
275 | */ | ||
276 | static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags, | ||
277 | u16 len_on_bd) | ||
278 | { | ||
279 | /* TPA arrgregation won't have an IP options and TCP options | ||
280 | * other than timestamp. | ||
281 | */ | ||
282 | u16 hdrs_len = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr); | ||
283 | |||
284 | |||
285 | /* Check if there was a TCP timestamp, if there is it's will | ||
286 | * always be 12 bytes length: nop nop kind length echo val. | ||
287 | * | ||
288 | * Otherwise FW would close the aggregation. | ||
289 | */ | ||
290 | if (parsing_flags & PARSING_FLAGS_TIME_STAMP_EXIST_FLAG) | ||
291 | hdrs_len += TPA_TSTAMP_OPT_LEN; | ||
292 | |||
293 | return len_on_bd - hdrs_len; | ||
294 | } | ||
295 | |||
262 | static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, | 296 | static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, |
263 | struct sk_buff *skb, | 297 | struct sk_buff *skb, |
264 | struct eth_fast_path_rx_cqe *fp_cqe, | 298 | struct eth_fast_path_rx_cqe *fp_cqe, |
265 | u16 cqe_idx) | 299 | u16 cqe_idx, u16 parsing_flags) |
266 | { | 300 | { |
267 | struct sw_rx_page *rx_pg, old_rx_pg; | 301 | struct sw_rx_page *rx_pg, old_rx_pg; |
268 | u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); | 302 | u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); |
@@ -275,8 +309,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
275 | 309 | ||
276 | /* This is needed in order to enable forwarding support */ | 310 | /* This is needed in order to enable forwarding support */ |
277 | if (frag_size) | 311 | if (frag_size) |
278 | skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, | 312 | skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp, parsing_flags, |
279 | max(frag_size, (u32)len_on_bd)); | 313 | len_on_bd); |
280 | 314 | ||
281 | #ifdef BNX2X_STOP_ON_ERROR | 315 | #ifdef BNX2X_STOP_ON_ERROR |
282 | if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { | 316 | if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { |
@@ -344,6 +378,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
344 | if (likely(new_skb)) { | 378 | if (likely(new_skb)) { |
345 | /* fix ip xsum and give it to the stack */ | 379 | /* fix ip xsum and give it to the stack */ |
346 | /* (no need to map the new skb) */ | 380 | /* (no need to map the new skb) */ |
381 | u16 parsing_flags = | ||
382 | le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags); | ||
347 | 383 | ||
348 | prefetch(skb); | 384 | prefetch(skb); |
349 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | 385 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); |
@@ -373,9 +409,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
373 | } | 409 | } |
374 | 410 | ||
375 | if (!bnx2x_fill_frag_skb(bp, fp, skb, | 411 | if (!bnx2x_fill_frag_skb(bp, fp, skb, |
376 | &cqe->fast_path_cqe, cqe_idx)) { | 412 | &cqe->fast_path_cqe, cqe_idx, |
377 | if ((le16_to_cpu(cqe->fast_path_cqe. | 413 | parsing_flags)) { |
378 | pars_flags.flags) & PARSING_FLAGS_VLAN)) | 414 | if (parsing_flags & PARSING_FLAGS_VLAN) |
379 | __vlan_hwaccel_put_tag(skb, | 415 | __vlan_hwaccel_put_tag(skb, |
380 | le16_to_cpu(cqe->fast_path_cqe. | 416 | le16_to_cpu(cqe->fast_path_cqe. |
381 | vlan_tag)); | 417 | vlan_tag)); |
@@ -703,19 +739,20 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp) | |||
703 | { | 739 | { |
704 | u16 line_speed = bp->link_vars.line_speed; | 740 | u16 line_speed = bp->link_vars.line_speed; |
705 | if (IS_MF(bp)) { | 741 | if (IS_MF(bp)) { |
706 | u16 maxCfg = (bp->mf_config[BP_VN(bp)] & | 742 | u16 maxCfg = bnx2x_extract_max_cfg(bp, |
707 | FUNC_MF_CFG_MAX_BW_MASK) >> | 743 | bp->mf_config[BP_VN(bp)]); |
708 | FUNC_MF_CFG_MAX_BW_SHIFT; | 744 | |
709 | /* Calculate the current MAX line speed limit for the DCC | 745 | /* Calculate the current MAX line speed limit for the MF |
710 | * capable devices | 746 | * devices |
711 | */ | 747 | */ |
712 | if (IS_MF_SD(bp)) { | 748 | if (IS_MF_SI(bp)) |
749 | line_speed = (line_speed * maxCfg) / 100; | ||
750 | else { /* SD mode */ | ||
713 | u16 vn_max_rate = maxCfg * 100; | 751 | u16 vn_max_rate = maxCfg * 100; |
714 | 752 | ||
715 | if (vn_max_rate < line_speed) | 753 | if (vn_max_rate < line_speed) |
716 | line_speed = vn_max_rate; | 754 | line_speed = vn_max_rate; |
717 | } else /* IS_MF_SI(bp)) */ | 755 | } |
718 | line_speed = (line_speed * maxCfg) / 100; | ||
719 | } | 756 | } |
720 | 757 | ||
721 | return line_speed; | 758 | return line_speed; |