diff options
Diffstat (limited to 'drivers/net/qlge/qlge_main.c')
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index fde5af0d5b46..cd093db29ada 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -320,6 +320,37 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, | |||
320 | 320 | ||
321 | switch (type) { | 321 | switch (type) { |
322 | case MAC_ADDR_TYPE_MULTI_MAC: | 322 | case MAC_ADDR_TYPE_MULTI_MAC: |
323 | { | ||
324 | u32 upper = (addr[0] << 8) | addr[1]; | ||
325 | u32 lower = (addr[2] << 24) | (addr[3] << 16) | | ||
326 | (addr[4] << 8) | (addr[5]); | ||
327 | |||
328 | status = | ||
329 | ql_wait_reg_rdy(qdev, | ||
330 | MAC_ADDR_IDX, MAC_ADDR_MW, 0); | ||
331 | if (status) | ||
332 | goto exit; | ||
333 | ql_write32(qdev, MAC_ADDR_IDX, (offset++) | | ||
334 | (index << MAC_ADDR_IDX_SHIFT) | | ||
335 | type | MAC_ADDR_E); | ||
336 | ql_write32(qdev, MAC_ADDR_DATA, lower); | ||
337 | status = | ||
338 | ql_wait_reg_rdy(qdev, | ||
339 | MAC_ADDR_IDX, MAC_ADDR_MW, 0); | ||
340 | if (status) | ||
341 | goto exit; | ||
342 | ql_write32(qdev, MAC_ADDR_IDX, (offset++) | | ||
343 | (index << MAC_ADDR_IDX_SHIFT) | | ||
344 | type | MAC_ADDR_E); | ||
345 | |||
346 | ql_write32(qdev, MAC_ADDR_DATA, upper); | ||
347 | status = | ||
348 | ql_wait_reg_rdy(qdev, | ||
349 | MAC_ADDR_IDX, MAC_ADDR_MW, 0); | ||
350 | if (status) | ||
351 | goto exit; | ||
352 | break; | ||
353 | } | ||
323 | case MAC_ADDR_TYPE_CAM_MAC: | 354 | case MAC_ADDR_TYPE_CAM_MAC: |
324 | { | 355 | { |
325 | u32 cam_output; | 356 | u32 cam_output; |
@@ -365,16 +396,14 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, | |||
365 | and possibly the function id. Right now we hardcode | 396 | and possibly the function id. Right now we hardcode |
366 | the route field to NIC core. | 397 | the route field to NIC core. |
367 | */ | 398 | */ |
368 | if (type == MAC_ADDR_TYPE_CAM_MAC) { | 399 | cam_output = (CAM_OUT_ROUTE_NIC | |
369 | cam_output = (CAM_OUT_ROUTE_NIC | | 400 | (qdev-> |
370 | (qdev-> | 401 | func << CAM_OUT_FUNC_SHIFT) | |
371 | func << CAM_OUT_FUNC_SHIFT) | | 402 | (0 << CAM_OUT_CQ_ID_SHIFT)); |
372 | (0 << CAM_OUT_CQ_ID_SHIFT)); | 403 | if (qdev->vlgrp) |
373 | if (qdev->vlgrp) | 404 | cam_output |= CAM_OUT_RV; |
374 | cam_output |= CAM_OUT_RV; | 405 | /* route to NIC core */ |
375 | /* route to NIC core */ | 406 | ql_write32(qdev, MAC_ADDR_DATA, cam_output); |
376 | ql_write32(qdev, MAC_ADDR_DATA, cam_output); | ||
377 | } | ||
378 | break; | 407 | break; |
379 | } | 408 | } |
380 | case MAC_ADDR_TYPE_VLAN: | 409 | case MAC_ADDR_TYPE_VLAN: |
@@ -546,14 +575,14 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask, | |||
546 | } | 575 | } |
547 | case RT_IDX_MCAST: /* Pass up All Multicast frames. */ | 576 | case RT_IDX_MCAST: /* Pass up All Multicast frames. */ |
548 | { | 577 | { |
549 | value = RT_IDX_DST_CAM_Q | /* dest */ | 578 | value = RT_IDX_DST_DFLT_Q | /* dest */ |
550 | RT_IDX_TYPE_NICQ | /* type */ | 579 | RT_IDX_TYPE_NICQ | /* type */ |
551 | (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */ | 580 | (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */ |
552 | break; | 581 | break; |
553 | } | 582 | } |
554 | case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */ | 583 | case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */ |
555 | { | 584 | { |
556 | value = RT_IDX_DST_CAM_Q | /* dest */ | 585 | value = RT_IDX_DST_DFLT_Q | /* dest */ |
557 | RT_IDX_TYPE_NICQ | /* type */ | 586 | RT_IDX_TYPE_NICQ | /* type */ |
558 | (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */ | 587 | (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */ |
559 | break; | 588 | break; |
@@ -3078,6 +3107,12 @@ err_irq: | |||
3078 | 3107 | ||
3079 | static int ql_start_rss(struct ql_adapter *qdev) | 3108 | static int ql_start_rss(struct ql_adapter *qdev) |
3080 | { | 3109 | { |
3110 | u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, | ||
3111 | 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, | ||
3112 | 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, | ||
3113 | 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80, | ||
3114 | 0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, | ||
3115 | 0xbe, 0xac, 0x01, 0xfa}; | ||
3081 | struct ricb *ricb = &qdev->ricb; | 3116 | struct ricb *ricb = &qdev->ricb; |
3082 | int status = 0; | 3117 | int status = 0; |
3083 | int i; | 3118 | int i; |
@@ -3087,21 +3122,17 @@ static int ql_start_rss(struct ql_adapter *qdev) | |||
3087 | 3122 | ||
3088 | ricb->base_cq = RSS_L4K; | 3123 | ricb->base_cq = RSS_L4K; |
3089 | ricb->flags = | 3124 | ricb->flags = |
3090 | (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 | | 3125 | (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6); |
3091 | RSS_RT6); | 3126 | ricb->mask = cpu_to_le16((u16)(0x3ff)); |
3092 | ricb->mask = cpu_to_le16(qdev->rss_ring_count - 1); | ||
3093 | 3127 | ||
3094 | /* | 3128 | /* |
3095 | * Fill out the Indirection Table. | 3129 | * Fill out the Indirection Table. |
3096 | */ | 3130 | */ |
3097 | for (i = 0; i < 256; i++) | 3131 | for (i = 0; i < 1024; i++) |
3098 | hash_id[i] = i & (qdev->rss_ring_count - 1); | 3132 | hash_id[i] = (i & (qdev->rss_ring_count - 1)); |
3099 | 3133 | ||
3100 | /* | 3134 | memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40); |
3101 | * Random values for the IPv6 and IPv4 Hash Keys. | 3135 | memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16); |
3102 | */ | ||
3103 | get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40); | ||
3104 | get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16); | ||
3105 | 3136 | ||
3106 | QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); | 3137 | QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); |
3107 | 3138 | ||
@@ -3240,6 +3271,13 @@ static int ql_adapter_initialize(struct ql_adapter *qdev) | |||
3240 | ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP | | 3271 | ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP | |
3241 | min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE)); | 3272 | min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE)); |
3242 | 3273 | ||
3274 | /* Set RX packet routing to use port/pci function on which the | ||
3275 | * packet arrived on in addition to usual frame routing. | ||
3276 | * This is helpful on bonding where both interfaces can have | ||
3277 | * the same MAC address. | ||
3278 | */ | ||
3279 | ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ); | ||
3280 | |||
3243 | /* Start up the rx queues. */ | 3281 | /* Start up the rx queues. */ |
3244 | for (i = 0; i < qdev->rx_ring_count; i++) { | 3282 | for (i = 0; i < qdev->rx_ring_count; i++) { |
3245 | status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]); | 3283 | status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]); |
@@ -3312,6 +3350,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
3312 | 3350 | ||
3313 | end_jiffies = jiffies + | 3351 | end_jiffies = jiffies + |
3314 | max((unsigned long)1, usecs_to_jiffies(30)); | 3352 | max((unsigned long)1, usecs_to_jiffies(30)); |
3353 | |||
3354 | /* Stop management traffic. */ | ||
3355 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); | ||
3356 | |||
3357 | /* Wait for the NIC and MGMNT FIFOs to empty. */ | ||
3358 | ql_wait_fifo_empty(qdev); | ||
3359 | |||
3315 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); | 3360 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); |
3316 | 3361 | ||
3317 | do { | 3362 | do { |
@@ -3327,6 +3372,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
3327 | status = -ETIMEDOUT; | 3372 | status = -ETIMEDOUT; |
3328 | } | 3373 | } |
3329 | 3374 | ||
3375 | /* Resume management traffic. */ | ||
3376 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME); | ||
3330 | return status; | 3377 | return status; |
3331 | } | 3378 | } |
3332 | 3379 | ||
@@ -3704,6 +3751,12 @@ static void ql_asic_reset_work(struct work_struct *work) | |||
3704 | status = ql_adapter_up(qdev); | 3751 | status = ql_adapter_up(qdev); |
3705 | if (status) | 3752 | if (status) |
3706 | goto error; | 3753 | goto error; |
3754 | |||
3755 | /* Restore rx mode. */ | ||
3756 | clear_bit(QL_ALLMULTI, &qdev->flags); | ||
3757 | clear_bit(QL_PROMISCUOUS, &qdev->flags); | ||
3758 | qlge_set_multicast_list(qdev->ndev); | ||
3759 | |||
3707 | rtnl_unlock(); | 3760 | rtnl_unlock(); |
3708 | return; | 3761 | return; |
3709 | error: | 3762 | error: |