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 61680715cde0..48b45df85ec9 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; |
| @@ -3077,6 +3106,12 @@ err_irq: | |||
| 3077 | 3106 | ||
| 3078 | static int ql_start_rss(struct ql_adapter *qdev) | 3107 | static int ql_start_rss(struct ql_adapter *qdev) |
| 3079 | { | 3108 | { |
| 3109 | u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, | ||
| 3110 | 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, | ||
| 3111 | 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, | ||
| 3112 | 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80, | ||
| 3113 | 0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, | ||
| 3114 | 0xbe, 0xac, 0x01, 0xfa}; | ||
| 3080 | struct ricb *ricb = &qdev->ricb; | 3115 | struct ricb *ricb = &qdev->ricb; |
| 3081 | int status = 0; | 3116 | int status = 0; |
| 3082 | int i; | 3117 | int i; |
| @@ -3086,21 +3121,17 @@ static int ql_start_rss(struct ql_adapter *qdev) | |||
| 3086 | 3121 | ||
| 3087 | ricb->base_cq = RSS_L4K; | 3122 | ricb->base_cq = RSS_L4K; |
| 3088 | ricb->flags = | 3123 | ricb->flags = |
| 3089 | (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 | | 3124 | (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6); |
| 3090 | RSS_RT6); | 3125 | ricb->mask = cpu_to_le16((u16)(0x3ff)); |
| 3091 | ricb->mask = cpu_to_le16(qdev->rss_ring_count - 1); | ||
| 3092 | 3126 | ||
| 3093 | /* | 3127 | /* |
| 3094 | * Fill out the Indirection Table. | 3128 | * Fill out the Indirection Table. |
| 3095 | */ | 3129 | */ |
| 3096 | for (i = 0; i < 256; i++) | 3130 | for (i = 0; i < 1024; i++) |
| 3097 | hash_id[i] = i & (qdev->rss_ring_count - 1); | 3131 | hash_id[i] = (i & (qdev->rss_ring_count - 1)); |
| 3098 | 3132 | ||
| 3099 | /* | 3133 | memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40); |
| 3100 | * Random values for the IPv6 and IPv4 Hash Keys. | 3134 | memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16); |
| 3101 | */ | ||
| 3102 | get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40); | ||
| 3103 | get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16); | ||
| 3104 | 3135 | ||
| 3105 | QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); | 3136 | QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); |
| 3106 | 3137 | ||
| @@ -3239,6 +3270,13 @@ static int ql_adapter_initialize(struct ql_adapter *qdev) | |||
| 3239 | ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP | | 3270 | ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP | |
| 3240 | min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE)); | 3271 | min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE)); |
| 3241 | 3272 | ||
| 3273 | /* Set RX packet routing to use port/pci function on which the | ||
| 3274 | * packet arrived on in addition to usual frame routing. | ||
| 3275 | * This is helpful on bonding where both interfaces can have | ||
| 3276 | * the same MAC address. | ||
| 3277 | */ | ||
| 3278 | ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ); | ||
| 3279 | |||
| 3242 | /* Start up the rx queues. */ | 3280 | /* Start up the rx queues. */ |
| 3243 | for (i = 0; i < qdev->rx_ring_count; i++) { | 3281 | for (i = 0; i < qdev->rx_ring_count; i++) { |
| 3244 | status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]); | 3282 | status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]); |
| @@ -3311,6 +3349,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
| 3311 | 3349 | ||
| 3312 | end_jiffies = jiffies + | 3350 | end_jiffies = jiffies + |
| 3313 | max((unsigned long)1, usecs_to_jiffies(30)); | 3351 | max((unsigned long)1, usecs_to_jiffies(30)); |
| 3352 | |||
| 3353 | /* Stop management traffic. */ | ||
| 3354 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); | ||
| 3355 | |||
| 3356 | /* Wait for the NIC and MGMNT FIFOs to empty. */ | ||
| 3357 | ql_wait_fifo_empty(qdev); | ||
| 3358 | |||
| 3314 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); | 3359 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); |
| 3315 | 3360 | ||
| 3316 | do { | 3361 | do { |
| @@ -3326,6 +3371,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
| 3326 | status = -ETIMEDOUT; | 3371 | status = -ETIMEDOUT; |
| 3327 | } | 3372 | } |
| 3328 | 3373 | ||
| 3374 | /* Resume management traffic. */ | ||
| 3375 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME); | ||
| 3329 | return status; | 3376 | return status; |
| 3330 | } | 3377 | } |
| 3331 | 3378 | ||
| @@ -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: |
