diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 8a87e16e732f..c5de65c6f6e1 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1049,6 +1049,40 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) | |||
1049 | return le; | 1049 | return le; |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | static unsigned sky2_get_rx_threshold(struct sky2_port* sky2) | ||
1053 | { | ||
1054 | unsigned size; | ||
1055 | |||
1056 | /* Space needed for frame data + headers rounded up */ | ||
1057 | size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); | ||
1058 | |||
1059 | /* Stopping point for hardware truncation */ | ||
1060 | return (size - 8) / sizeof(u32); | ||
1061 | } | ||
1062 | |||
1063 | static unsigned sky2_get_rx_data_size(struct sky2_port* sky2) | ||
1064 | { | ||
1065 | struct rx_ring_info *re; | ||
1066 | unsigned size; | ||
1067 | |||
1068 | /* Space needed for frame data + headers rounded up */ | ||
1069 | size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); | ||
1070 | |||
1071 | sky2->rx_nfrags = size >> PAGE_SHIFT; | ||
1072 | BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr)); | ||
1073 | |||
1074 | /* Compute residue after pages */ | ||
1075 | size -= sky2->rx_nfrags << PAGE_SHIFT; | ||
1076 | |||
1077 | /* Optimize to handle small packets and headers */ | ||
1078 | if (size < copybreak) | ||
1079 | size = copybreak; | ||
1080 | if (size < ETH_HLEN) | ||
1081 | size = ETH_HLEN; | ||
1082 | |||
1083 | return size; | ||
1084 | } | ||
1085 | |||
1052 | /* Build description to hardware for one receive segment */ | 1086 | /* Build description to hardware for one receive segment */ |
1053 | static void sky2_rx_add(struct sky2_port *sky2, u8 op, | 1087 | static void sky2_rx_add(struct sky2_port *sky2, u8 op, |
1054 | dma_addr_t map, unsigned len) | 1088 | dma_addr_t map, unsigned len) |
@@ -1343,7 +1377,7 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1343 | struct sky2_hw *hw = sky2->hw; | 1377 | struct sky2_hw *hw = sky2->hw; |
1344 | struct rx_ring_info *re; | 1378 | struct rx_ring_info *re; |
1345 | unsigned rxq = rxqaddr[sky2->port]; | 1379 | unsigned rxq = rxqaddr[sky2->port]; |
1346 | unsigned i, size, thresh; | 1380 | unsigned i, thresh; |
1347 | 1381 | ||
1348 | sky2->rx_put = sky2->rx_next = 0; | 1382 | sky2->rx_put = sky2->rx_next = 0; |
1349 | sky2_qset(hw, rxq); | 1383 | sky2_qset(hw, rxq); |
@@ -1364,25 +1398,7 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1364 | if (!(hw->flags & SKY2_HW_NEW_LE)) | 1398 | if (!(hw->flags & SKY2_HW_NEW_LE)) |
1365 | rx_set_checksum(sky2); | 1399 | rx_set_checksum(sky2); |
1366 | 1400 | ||
1367 | /* Space needed for frame data + headers rounded up */ | 1401 | sky2->rx_data_size = sky2_get_rx_data_size(sky2); |
1368 | size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); | ||
1369 | |||
1370 | /* Stopping point for hardware truncation */ | ||
1371 | thresh = (size - 8) / sizeof(u32); | ||
1372 | |||
1373 | sky2->rx_nfrags = size >> PAGE_SHIFT; | ||
1374 | BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr)); | ||
1375 | |||
1376 | /* Compute residue after pages */ | ||
1377 | size -= sky2->rx_nfrags << PAGE_SHIFT; | ||
1378 | |||
1379 | /* Optimize to handle small packets and headers */ | ||
1380 | if (size < copybreak) | ||
1381 | size = copybreak; | ||
1382 | if (size < ETH_HLEN) | ||
1383 | size = ETH_HLEN; | ||
1384 | |||
1385 | sky2->rx_data_size = size; | ||
1386 | 1402 | ||
1387 | /* Fill Rx ring */ | 1403 | /* Fill Rx ring */ |
1388 | for (i = 0; i < sky2->rx_pending; i++) { | 1404 | for (i = 0; i < sky2->rx_pending; i++) { |
@@ -1407,6 +1423,7 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1407 | * the register is limited to 9 bits, so if you do frames > 2052 | 1423 | * the register is limited to 9 bits, so if you do frames > 2052 |
1408 | * you better get the MTU right! | 1424 | * you better get the MTU right! |
1409 | */ | 1425 | */ |
1426 | thresh = sky2_get_rx_threshold(sky2); | ||
1410 | if (thresh > 0x1ff) | 1427 | if (thresh > 0x1ff) |
1411 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF); | 1428 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF); |
1412 | else { | 1429 | else { |