diff options
| author | Toshiharu Okada <toshiharu-linux@dsn.okisemi.com> | 2011-09-01 10:20:08 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-09-15 17:31:45 -0400 |
| commit | 124d770a6459be21b84445f6ebf7dbfb60d43585 (patch) | |
| tree | 4733fe453d2a8e1a5a4b1a1cb2a24d30ce5b6da2 | |
| parent | 5229d87edcd80a3bceb0708ebd767faff2e589a9 (diff) | |
pch_gbe: added the process of FIFO over run error
This patch added the processing which should be done to hardware,
when a FIFO over run error occurred.
Signed-off-by: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/pch_gbe/pch_gbe.h | 12 | ||||
| -rw-r--r-- | drivers/net/pch_gbe/pch_gbe_main.c | 271 |
2 files changed, 179 insertions, 104 deletions
diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index 59fac77d0dbb..a09a07197eb5 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h | |||
| @@ -127,8 +127,8 @@ struct pch_gbe_regs { | |||
| 127 | 127 | ||
| 128 | /* Reset */ | 128 | /* Reset */ |
| 129 | #define PCH_GBE_ALL_RST 0x80000000 /* All reset */ | 129 | #define PCH_GBE_ALL_RST 0x80000000 /* All reset */ |
| 130 | #define PCH_GBE_TX_RST 0x40000000 /* TX MAC, TX FIFO, TX DMA reset */ | 130 | #define PCH_GBE_TX_RST 0x00008000 /* TX MAC, TX FIFO, TX DMA reset */ |
| 131 | #define PCH_GBE_RX_RST 0x04000000 /* RX MAC, RX FIFO, RX DMA reset */ | 131 | #define PCH_GBE_RX_RST 0x00004000 /* RX MAC, RX FIFO, RX DMA reset */ |
| 132 | 132 | ||
| 133 | /* TCP/IP Accelerator Control */ | 133 | /* TCP/IP Accelerator Control */ |
| 134 | #define PCH_GBE_EX_LIST_EN 0x00000008 /* External List Enable */ | 134 | #define PCH_GBE_EX_LIST_EN 0x00000008 /* External List Enable */ |
| @@ -276,6 +276,9 @@ struct pch_gbe_regs { | |||
| 276 | #define PCH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */ | 276 | #define PCH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */ |
| 277 | #define PCH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */ | 277 | #define PCH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */ |
| 278 | 278 | ||
| 279 | /* RX DMA STATUS */ | ||
| 280 | #define PCH_GBE_IDLE_CHECK 0xFFFFFFFE | ||
| 281 | |||
| 279 | /* Wake On LAN Status */ | 282 | /* Wake On LAN Status */ |
| 280 | #define PCH_GBE_WLS_BR 0x00000008 /* Broadcas Address */ | 283 | #define PCH_GBE_WLS_BR 0x00000008 /* Broadcas Address */ |
| 281 | #define PCH_GBE_WLS_MLT 0x00000004 /* Multicast Address */ | 284 | #define PCH_GBE_WLS_MLT 0x00000004 /* Multicast Address */ |
| @@ -471,6 +474,7 @@ struct pch_gbe_tx_desc { | |||
| 471 | struct pch_gbe_buffer { | 474 | struct pch_gbe_buffer { |
| 472 | struct sk_buff *skb; | 475 | struct sk_buff *skb; |
| 473 | dma_addr_t dma; | 476 | dma_addr_t dma; |
| 477 | unsigned char *rx_buffer; | ||
| 474 | unsigned long time_stamp; | 478 | unsigned long time_stamp; |
| 475 | u16 length; | 479 | u16 length; |
| 476 | bool mapped; | 480 | bool mapped; |
| @@ -511,6 +515,9 @@ struct pch_gbe_tx_ring { | |||
| 511 | struct pch_gbe_rx_ring { | 515 | struct pch_gbe_rx_ring { |
| 512 | struct pch_gbe_rx_desc *desc; | 516 | struct pch_gbe_rx_desc *desc; |
| 513 | dma_addr_t dma; | 517 | dma_addr_t dma; |
| 518 | unsigned char *rx_buff_pool; | ||
| 519 | dma_addr_t rx_buff_pool_logic; | ||
| 520 | unsigned int rx_buff_pool_size; | ||
| 514 | unsigned int size; | 521 | unsigned int size; |
| 515 | unsigned int count; | 522 | unsigned int count; |
| 516 | unsigned int next_to_use; | 523 | unsigned int next_to_use; |
| @@ -622,6 +629,7 @@ struct pch_gbe_adapter { | |||
| 622 | unsigned long rx_buffer_len; | 629 | unsigned long rx_buffer_len; |
| 623 | unsigned long tx_queue_len; | 630 | unsigned long tx_queue_len; |
| 624 | bool have_msi; | 631 | bool have_msi; |
| 632 | bool rx_stop_flag; | ||
| 625 | }; | 633 | }; |
| 626 | 634 | ||
| 627 | extern const char pch_driver_version[]; | 635 | extern const char pch_driver_version[]; |
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 48ff87c455ae..39ce0ee44ad7 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | 20 | ||
| 21 | #include "pch_gbe.h" | 21 | #include "pch_gbe.h" |
| 22 | #include "pch_gbe_api.h" | 22 | #include "pch_gbe_api.h" |
| 23 | #include <linux/prefetch.h> | ||
| 24 | 23 | ||
| 25 | #define DRV_VERSION "1.00" | 24 | #define DRV_VERSION "1.00" |
| 26 | const char pch_driver_version[] = DRV_VERSION; | 25 | const char pch_driver_version[] = DRV_VERSION; |
| @@ -34,6 +33,7 @@ const char pch_driver_version[] = DRV_VERSION; | |||
| 34 | #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ | 33 | #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ |
| 35 | #define PCH_GBE_COPYBREAK_DEFAULT 256 | 34 | #define PCH_GBE_COPYBREAK_DEFAULT 256 |
| 36 | #define PCH_GBE_PCI_BAR 1 | 35 | #define PCH_GBE_PCI_BAR 1 |
| 36 | #define PCH_GBE_RESERVE_MEMORY 0x200000 /* 2MB */ | ||
| 37 | 37 | ||
| 38 | /* Macros for ML7223 */ | 38 | /* Macros for ML7223 */ |
| 39 | #define PCI_VENDOR_ID_ROHM 0x10db | 39 | #define PCI_VENDOR_ID_ROHM 0x10db |
| @@ -52,6 +52,7 @@ const char pch_driver_version[] = DRV_VERSION; | |||
| 52 | ) | 52 | ) |
| 53 | 53 | ||
| 54 | /* Ethertype field values */ | 54 | /* Ethertype field values */ |
| 55 | #define PCH_GBE_MAX_RX_BUFFER_SIZE 0x2880 | ||
| 55 | #define PCH_GBE_MAX_JUMBO_FRAME_SIZE 10318 | 56 | #define PCH_GBE_MAX_JUMBO_FRAME_SIZE 10318 |
| 56 | #define PCH_GBE_FRAME_SIZE_2048 2048 | 57 | #define PCH_GBE_FRAME_SIZE_2048 2048 |
| 57 | #define PCH_GBE_FRAME_SIZE_4096 4096 | 58 | #define PCH_GBE_FRAME_SIZE_4096 4096 |
| @@ -83,10 +84,12 @@ const char pch_driver_version[] = DRV_VERSION; | |||
| 83 | #define PCH_GBE_INT_ENABLE_MASK ( \ | 84 | #define PCH_GBE_INT_ENABLE_MASK ( \ |
| 84 | PCH_GBE_INT_RX_DMA_CMPLT | \ | 85 | PCH_GBE_INT_RX_DMA_CMPLT | \ |
| 85 | PCH_GBE_INT_RX_DSC_EMP | \ | 86 | PCH_GBE_INT_RX_DSC_EMP | \ |
| 87 | PCH_GBE_INT_RX_FIFO_ERR | \ | ||
| 86 | PCH_GBE_INT_WOL_DET | \ | 88 | PCH_GBE_INT_WOL_DET | \ |
| 87 | PCH_GBE_INT_TX_CMPLT \ | 89 | PCH_GBE_INT_TX_CMPLT \ |
| 88 | ) | 90 | ) |
| 89 | 91 | ||
| 92 | #define PCH_GBE_INT_DISABLE_ALL 0 | ||
| 90 | 93 | ||
| 91 | static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; | 94 | static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; |
| 92 | 95 | ||
| @@ -138,6 +141,27 @@ static void pch_gbe_wait_clr_bit(void *reg, u32 bit) | |||
| 138 | if (!tmp) | 141 | if (!tmp) |
| 139 | pr_err("Error: busy bit is not cleared\n"); | 142 | pr_err("Error: busy bit is not cleared\n"); |
| 140 | } | 143 | } |
| 144 | |||
| 145 | /** | ||
| 146 | * pch_gbe_wait_clr_bit_irq - Wait to clear a bit for interrupt context | ||
| 147 | * @reg: Pointer of register | ||
| 148 | * @busy: Busy bit | ||
| 149 | */ | ||
| 150 | static int pch_gbe_wait_clr_bit_irq(void *reg, u32 bit) | ||
| 151 | { | ||
| 152 | u32 tmp; | ||
| 153 | int ret = -1; | ||
| 154 | /* wait busy */ | ||
| 155 | tmp = 20; | ||
| 156 | while ((ioread32(reg) & bit) && --tmp) | ||
| 157 | udelay(5); | ||
| 158 | if (!tmp) | ||
| 159 | pr_err("Error: busy bit is not cleared\n"); | ||
| 160 | else | ||
| 161 | ret = 0; | ||
| 162 | return ret; | ||
| 163 | } | ||
| 164 | |||
| 141 | /** | 165 | /** |
| 142 | * pch_gbe_mac_mar_set - Set MAC address register | 166 | * pch_gbe_mac_mar_set - Set MAC address register |
| 143 | * @hw: Pointer to the HW structure | 167 | * @hw: Pointer to the HW structure |
| @@ -189,6 +213,17 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) | |||
| 189 | return; | 213 | return; |
| 190 | } | 214 | } |
| 191 | 215 | ||
| 216 | static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw) | ||
| 217 | { | ||
| 218 | /* Read the MAC address. and store to the private data */ | ||
| 219 | pch_gbe_mac_read_mac_addr(hw); | ||
| 220 | iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET); | ||
| 221 | pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST); | ||
| 222 | /* Setup the MAC address */ | ||
| 223 | pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); | ||
| 224 | return; | ||
| 225 | } | ||
| 226 | |||
| 192 | /** | 227 | /** |
| 193 | * pch_gbe_mac_init_rx_addrs - Initialize receive address's | 228 | * pch_gbe_mac_init_rx_addrs - Initialize receive address's |
| 194 | * @hw: Pointer to the HW structure | 229 | * @hw: Pointer to the HW structure |
| @@ -671,13 +706,8 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) | |||
| 671 | 706 | ||
| 672 | tcpip = ioread32(&hw->reg->TCPIP_ACC); | 707 | tcpip = ioread32(&hw->reg->TCPIP_ACC); |
| 673 | 708 | ||
| 674 | if (netdev->features & NETIF_F_RXCSUM) { | 709 | tcpip |= PCH_GBE_RX_TCPIPACC_OFF; |
| 675 | tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF; | 710 | tcpip &= ~PCH_GBE_RX_TCPIPACC_EN; |
| 676 | tcpip |= PCH_GBE_RX_TCPIPACC_EN; | ||
| 677 | } else { | ||
| 678 | tcpip |= PCH_GBE_RX_TCPIPACC_OFF; | ||
| 679 | tcpip &= ~PCH_GBE_RX_TCPIPACC_EN; | ||
| 680 | } | ||
| 681 | iowrite32(tcpip, &hw->reg->TCPIP_ACC); | 711 | iowrite32(tcpip, &hw->reg->TCPIP_ACC); |
| 682 | return; | 712 | return; |
| 683 | } | 713 | } |
| @@ -1090,6 +1120,35 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) | |||
| 1090 | spin_unlock_irqrestore(&adapter->stats_lock, flags); | 1120 | spin_unlock_irqrestore(&adapter->stats_lock, flags); |
| 1091 | } | 1121 | } |
| 1092 | 1122 | ||
| 1123 | static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter) | ||
| 1124 | { | ||
| 1125 | struct pch_gbe_hw *hw = &adapter->hw; | ||
| 1126 | u32 rxdma; | ||
| 1127 | u16 value; | ||
| 1128 | int ret; | ||
| 1129 | |||
| 1130 | /* Disable Receive DMA */ | ||
| 1131 | rxdma = ioread32(&hw->reg->DMA_CTRL); | ||
| 1132 | rxdma &= ~PCH_GBE_RX_DMA_EN; | ||
| 1133 | iowrite32(rxdma, &hw->reg->DMA_CTRL); | ||
| 1134 | /* Wait Rx DMA BUS is IDLE */ | ||
| 1135 | ret = pch_gbe_wait_clr_bit_irq(&hw->reg->RX_DMA_ST, PCH_GBE_IDLE_CHECK); | ||
| 1136 | if (ret) { | ||
| 1137 | /* Disable Bus master */ | ||
| 1138 | pci_read_config_word(adapter->pdev, PCI_COMMAND, &value); | ||
| 1139 | value &= ~PCI_COMMAND_MASTER; | ||
| 1140 | pci_write_config_word(adapter->pdev, PCI_COMMAND, value); | ||
| 1141 | /* Stop Receive */ | ||
| 1142 | pch_gbe_mac_reset_rx(hw); | ||
| 1143 | /* Enable Bus master */ | ||
| 1144 | value |= PCI_COMMAND_MASTER; | ||
| 1145 | pci_write_config_word(adapter->pdev, PCI_COMMAND, value); | ||
| 1146 | } else { | ||
| 1147 | /* Stop Receive */ | ||
| 1148 | pch_gbe_mac_reset_rx(hw); | ||
| 1149 | } | ||
| 1150 | } | ||
| 1151 | |||
| 1093 | static void pch_gbe_start_receive(struct pch_gbe_hw *hw) | 1152 | static void pch_gbe_start_receive(struct pch_gbe_hw *hw) |
| 1094 | { | 1153 | { |
| 1095 | u32 rxdma; | 1154 | u32 rxdma; |
| @@ -1129,7 +1188,15 @@ static irqreturn_t pch_gbe_intr(int irq, void *data) | |||
| 1129 | if (int_st & PCH_GBE_INT_RX_FRAME_ERR) | 1188 | if (int_st & PCH_GBE_INT_RX_FRAME_ERR) |
| 1130 | adapter->stats.intr_rx_frame_err_count++; | 1189 | adapter->stats.intr_rx_frame_err_count++; |
| 1131 | if (int_st & PCH_GBE_INT_RX_FIFO_ERR) | 1190 | if (int_st & PCH_GBE_INT_RX_FIFO_ERR) |
| 1132 | adapter->stats.intr_rx_fifo_err_count++; | 1191 | if (!adapter->rx_stop_flag) { |
| 1192 | adapter->stats.intr_rx_fifo_err_count++; | ||
| 1193 | pr_debug("Rx fifo over run\n"); | ||
| 1194 | adapter->rx_stop_flag = true; | ||
| 1195 | int_en = ioread32(&hw->reg->INT_EN); | ||
| 1196 | iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR), | ||
| 1197 | &hw->reg->INT_EN); | ||
| 1198 | pch_gbe_stop_receive(adapter); | ||
| 1199 | } | ||
| 1133 | if (int_st & PCH_GBE_INT_RX_DMA_ERR) | 1200 | if (int_st & PCH_GBE_INT_RX_DMA_ERR) |
| 1134 | adapter->stats.intr_rx_dma_err_count++; | 1201 | adapter->stats.intr_rx_dma_err_count++; |
| 1135 | if (int_st & PCH_GBE_INT_TX_FIFO_ERR) | 1202 | if (int_st & PCH_GBE_INT_TX_FIFO_ERR) |
| @@ -1141,7 +1208,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data) | |||
| 1141 | /* When Rx descriptor is empty */ | 1208 | /* When Rx descriptor is empty */ |
| 1142 | if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) { | 1209 | if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) { |
| 1143 | adapter->stats.intr_rx_dsc_empty_count++; | 1210 | adapter->stats.intr_rx_dsc_empty_count++; |
| 1144 | pr_err("Rx descriptor is empty\n"); | 1211 | pr_debug("Rx descriptor is empty\n"); |
| 1145 | int_en = ioread32(&hw->reg->INT_EN); | 1212 | int_en = ioread32(&hw->reg->INT_EN); |
| 1146 | iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN); | 1213 | iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN); |
| 1147 | if (hw->mac.tx_fc_enable) { | 1214 | if (hw->mac.tx_fc_enable) { |
| @@ -1191,29 +1258,23 @@ pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter, | |||
| 1191 | unsigned int i; | 1258 | unsigned int i; |
| 1192 | unsigned int bufsz; | 1259 | unsigned int bufsz; |
| 1193 | 1260 | ||
| 1194 | bufsz = adapter->rx_buffer_len + PCH_GBE_DMA_ALIGN; | 1261 | bufsz = adapter->rx_buffer_len + NET_IP_ALIGN; |
| 1195 | i = rx_ring->next_to_use; | 1262 | i = rx_ring->next_to_use; |
| 1196 | 1263 | ||
| 1197 | while ((cleaned_count--)) { | 1264 | while ((cleaned_count--)) { |
| 1198 | buffer_info = &rx_ring->buffer_info[i]; | 1265 | buffer_info = &rx_ring->buffer_info[i]; |
| 1199 | skb = buffer_info->skb; | 1266 | skb = netdev_alloc_skb(netdev, bufsz); |
| 1200 | if (skb) { | 1267 | if (unlikely(!skb)) { |
| 1201 | skb_trim(skb, 0); | 1268 | /* Better luck next round */ |
| 1202 | } else { | 1269 | adapter->stats.rx_alloc_buff_failed++; |
| 1203 | skb = netdev_alloc_skb(netdev, bufsz); | 1270 | break; |
| 1204 | if (unlikely(!skb)) { | ||
| 1205 | /* Better luck next round */ | ||
| 1206 | adapter->stats.rx_alloc_buff_failed++; | ||
| 1207 | break; | ||
| 1208 | } | ||
| 1209 | /* 64byte align */ | ||
| 1210 | skb_reserve(skb, PCH_GBE_DMA_ALIGN); | ||
| 1211 | |||
| 1212 | buffer_info->skb = skb; | ||
| 1213 | buffer_info->length = adapter->rx_buffer_len; | ||
| 1214 | } | 1271 | } |
| 1272 | /* align */ | ||
| 1273 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 1274 | buffer_info->skb = skb; | ||
| 1275 | |||
| 1215 | buffer_info->dma = dma_map_single(&pdev->dev, | 1276 | buffer_info->dma = dma_map_single(&pdev->dev, |
| 1216 | skb->data, | 1277 | buffer_info->rx_buffer, |
| 1217 | buffer_info->length, | 1278 | buffer_info->length, |
| 1218 | DMA_FROM_DEVICE); | 1279 | DMA_FROM_DEVICE); |
| 1219 | if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) { | 1280 | if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) { |
| @@ -1246,6 +1307,36 @@ pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter, | |||
| 1246 | return; | 1307 | return; |
| 1247 | } | 1308 | } |
| 1248 | 1309 | ||
| 1310 | static int | ||
| 1311 | pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter, | ||
| 1312 | struct pch_gbe_rx_ring *rx_ring, int cleaned_count) | ||
| 1313 | { | ||
| 1314 | struct pci_dev *pdev = adapter->pdev; | ||
| 1315 | struct pch_gbe_buffer *buffer_info; | ||
| 1316 | unsigned int i; | ||
| 1317 | unsigned int bufsz; | ||
| 1318 | unsigned int size; | ||
| 1319 | |||
| 1320 | bufsz = adapter->rx_buffer_len; | ||
| 1321 | |||
| 1322 | size = rx_ring->count * bufsz + PCH_GBE_RESERVE_MEMORY; | ||
| 1323 | rx_ring->rx_buff_pool = dma_alloc_coherent(&pdev->dev, size, | ||
| 1324 | &rx_ring->rx_buff_pool_logic, | ||
| 1325 | GFP_KERNEL); | ||
| 1326 | if (!rx_ring->rx_buff_pool) { | ||
| 1327 | pr_err("Unable to allocate memory for the receive poll buffer\n"); | ||
| 1328 | return -ENOMEM; | ||
| 1329 | } | ||
| 1330 | memset(rx_ring->rx_buff_pool, 0, size); | ||
| 1331 | rx_ring->rx_buff_pool_size = size; | ||
| 1332 | for (i = 0; i < rx_ring->count; i++) { | ||
| 1333 | buffer_info = &rx_ring->buffer_info[i]; | ||
| 1334 | buffer_info->rx_buffer = rx_ring->rx_buff_pool + bufsz * i; | ||
| 1335 | buffer_info->length = bufsz; | ||
| 1336 | } | ||
| 1337 | return 0; | ||
| 1338 | } | ||
| 1339 | |||
| 1249 | /** | 1340 | /** |
| 1250 | * pch_gbe_alloc_tx_buffers - Allocate transmit buffers | 1341 | * pch_gbe_alloc_tx_buffers - Allocate transmit buffers |
| 1251 | * @adapter: Board private structure | 1342 | * @adapter: Board private structure |
| @@ -1386,7 +1477,7 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1386 | unsigned int i; | 1477 | unsigned int i; |
| 1387 | unsigned int cleaned_count = 0; | 1478 | unsigned int cleaned_count = 0; |
| 1388 | bool cleaned = false; | 1479 | bool cleaned = false; |
| 1389 | struct sk_buff *skb, *new_skb; | 1480 | struct sk_buff *skb; |
| 1390 | u8 dma_status; | 1481 | u8 dma_status; |
| 1391 | u16 gbec_status; | 1482 | u16 gbec_status; |
| 1392 | u32 tcp_ip_status; | 1483 | u32 tcp_ip_status; |
| @@ -1407,13 +1498,12 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1407 | rx_desc->gbec_status = DSC_INIT16; | 1498 | rx_desc->gbec_status = DSC_INIT16; |
| 1408 | buffer_info = &rx_ring->buffer_info[i]; | 1499 | buffer_info = &rx_ring->buffer_info[i]; |
| 1409 | skb = buffer_info->skb; | 1500 | skb = buffer_info->skb; |
| 1501 | buffer_info->skb = NULL; | ||
| 1410 | 1502 | ||
| 1411 | /* unmap dma */ | 1503 | /* unmap dma */ |
| 1412 | dma_unmap_single(&pdev->dev, buffer_info->dma, | 1504 | dma_unmap_single(&pdev->dev, buffer_info->dma, |
| 1413 | buffer_info->length, DMA_FROM_DEVICE); | 1505 | buffer_info->length, DMA_FROM_DEVICE); |
| 1414 | buffer_info->mapped = false; | 1506 | buffer_info->mapped = false; |
| 1415 | /* Prefetch the packet */ | ||
| 1416 | prefetch(skb->data); | ||
| 1417 | 1507 | ||
| 1418 | pr_debug("RxDecNo = 0x%04x Status[DMA:0x%02x GBE:0x%04x " | 1508 | pr_debug("RxDecNo = 0x%04x Status[DMA:0x%02x GBE:0x%04x " |
| 1419 | "TCP:0x%08x] BufInf = 0x%p\n", | 1509 | "TCP:0x%08x] BufInf = 0x%p\n", |
| @@ -1433,70 +1523,16 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1433 | pr_err("Receive CRC Error\n"); | 1523 | pr_err("Receive CRC Error\n"); |
| 1434 | } else { | 1524 | } else { |
| 1435 | /* get receive length */ | 1525 | /* get receive length */ |
| 1436 | /* length convert[-3] */ | 1526 | /* length convert[-3], length includes FCS length */ |
| 1437 | length = (rx_desc->rx_words_eob) - 3; | 1527 | length = (rx_desc->rx_words_eob) - 3 - ETH_FCS_LEN; |
| 1438 | 1528 | if (rx_desc->rx_words_eob & 0x02) | |
| 1439 | /* Decide the data conversion method */ | 1529 | length = length - 4; |
| 1440 | if (!(netdev->features & NETIF_F_RXCSUM)) { | 1530 | /* |
| 1441 | /* [Header:14][payload] */ | 1531 | * buffer_info->rx_buffer: [Header:14][payload] |
| 1442 | if (NET_IP_ALIGN) { | 1532 | * skb->data: [Reserve:2][Header:14][payload] |
| 1443 | /* Because alignment differs, | 1533 | */ |
| 1444 | * the new_skb is newly allocated, | 1534 | memcpy(skb->data, buffer_info->rx_buffer, length); |
| 1445 | * and data is copied to new_skb.*/ | 1535 | |
| 1446 | new_skb = netdev_alloc_skb(netdev, | ||
| 1447 | length + NET_IP_ALIGN); | ||
| 1448 | if (!new_skb) { | ||
| 1449 | /* dorrop error */ | ||
| 1450 | pr_err("New skb allocation " | ||
| 1451 | "Error\n"); | ||
| 1452 | goto dorrop; | ||
| 1453 | } | ||
| 1454 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
| 1455 | memcpy(new_skb->data, skb->data, | ||
| 1456 | length); | ||
| 1457 | skb = new_skb; | ||
| 1458 | } else { | ||
| 1459 | /* DMA buffer is used as SKB as it is.*/ | ||
| 1460 | buffer_info->skb = NULL; | ||
| 1461 | } | ||
| 1462 | } else { | ||
| 1463 | /* [Header:14][padding:2][payload] */ | ||
| 1464 | /* The length includes padding length */ | ||
| 1465 | length = length - PCH_GBE_DMA_PADDING; | ||
| 1466 | if ((length < copybreak) || | ||
| 1467 | (NET_IP_ALIGN != PCH_GBE_DMA_PADDING)) { | ||
| 1468 | /* Because alignment differs, | ||
| 1469 | * the new_skb is newly allocated, | ||
| 1470 | * and data is copied to new_skb. | ||
| 1471 | * Padding data is deleted | ||
| 1472 | * at the time of a copy.*/ | ||
| 1473 | new_skb = netdev_alloc_skb(netdev, | ||
| 1474 | length + NET_IP_ALIGN); | ||
| 1475 | if (!new_skb) { | ||
| 1476 | /* dorrop error */ | ||
| 1477 | pr_err("New skb allocation " | ||
| 1478 | "Error\n"); | ||
| 1479 | goto dorrop; | ||
| 1480 | } | ||
| 1481 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
| 1482 | memcpy(new_skb->data, skb->data, | ||
| 1483 | ETH_HLEN); | ||
| 1484 | memcpy(&new_skb->data[ETH_HLEN], | ||
| 1485 | &skb->data[ETH_HLEN + | ||
| 1486 | PCH_GBE_DMA_PADDING], | ||
| 1487 | length - ETH_HLEN); | ||
| 1488 | skb = new_skb; | ||
| 1489 | } else { | ||
| 1490 | /* Padding data is deleted | ||
| 1491 | * by moving header data.*/ | ||
| 1492 | memmove(&skb->data[PCH_GBE_DMA_PADDING], | ||
| 1493 | &skb->data[0], ETH_HLEN); | ||
| 1494 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 1495 | buffer_info->skb = NULL; | ||
| 1496 | } | ||
| 1497 | } | ||
| 1498 | /* The length includes FCS length */ | ||
| 1499 | length = length - ETH_FCS_LEN; | ||
| 1500 | /* update status of driver */ | 1536 | /* update status of driver */ |
| 1501 | adapter->stats.rx_bytes += length; | 1537 | adapter->stats.rx_bytes += length; |
| 1502 | adapter->stats.rx_packets++; | 1538 | adapter->stats.rx_packets++; |
| @@ -1515,7 +1551,6 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1515 | pr_debug("Receive skb->ip_summed: %d length: %d\n", | 1551 | pr_debug("Receive skb->ip_summed: %d length: %d\n", |
| 1516 | skb->ip_summed, length); | 1552 | skb->ip_summed, length); |
| 1517 | } | 1553 | } |
| 1518 | dorrop: | ||
| 1519 | /* return some buffers to hardware, one at a time is too slow */ | 1554 | /* return some buffers to hardware, one at a time is too slow */ |
| 1520 | if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) { | 1555 | if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) { |
| 1521 | pch_gbe_alloc_rx_buffers(adapter, rx_ring, | 1556 | pch_gbe_alloc_rx_buffers(adapter, rx_ring, |
| @@ -1720,6 +1755,11 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) | |||
| 1720 | pr_err("Error: can't bring device up\n"); | 1755 | pr_err("Error: can't bring device up\n"); |
| 1721 | return err; | 1756 | return err; |
| 1722 | } | 1757 | } |
| 1758 | err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count); | ||
| 1759 | if (err) { | ||
| 1760 | pr_err("Error: can't bring device up\n"); | ||
| 1761 | return err; | ||
| 1762 | } | ||
| 1723 | pch_gbe_alloc_tx_buffers(adapter, tx_ring); | 1763 | pch_gbe_alloc_tx_buffers(adapter, tx_ring); |
| 1724 | pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); | 1764 | pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); |
| 1725 | adapter->tx_queue_len = netdev->tx_queue_len; | 1765 | adapter->tx_queue_len = netdev->tx_queue_len; |
| @@ -1741,6 +1781,7 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) | |||
| 1741 | void pch_gbe_down(struct pch_gbe_adapter *adapter) | 1781 | void pch_gbe_down(struct pch_gbe_adapter *adapter) |
| 1742 | { | 1782 | { |
| 1743 | struct net_device *netdev = adapter->netdev; | 1783 | struct net_device *netdev = adapter->netdev; |
| 1784 | struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; | ||
| 1744 | 1785 | ||
| 1745 | /* signal that we're down so the interrupt handler does not | 1786 | /* signal that we're down so the interrupt handler does not |
| 1746 | * reschedule our watchdog timer */ | 1787 | * reschedule our watchdog timer */ |
| @@ -1759,6 +1800,12 @@ void pch_gbe_down(struct pch_gbe_adapter *adapter) | |||
| 1759 | pch_gbe_reset(adapter); | 1800 | pch_gbe_reset(adapter); |
| 1760 | pch_gbe_clean_tx_ring(adapter, adapter->tx_ring); | 1801 | pch_gbe_clean_tx_ring(adapter, adapter->tx_ring); |
| 1761 | pch_gbe_clean_rx_ring(adapter, adapter->rx_ring); | 1802 | pch_gbe_clean_rx_ring(adapter, adapter->rx_ring); |
| 1803 | |||
| 1804 | pci_free_consistent(adapter->pdev, rx_ring->rx_buff_pool_size, | ||
| 1805 | rx_ring->rx_buff_pool, rx_ring->rx_buff_pool_logic); | ||
| 1806 | rx_ring->rx_buff_pool_logic = 0; | ||
| 1807 | rx_ring->rx_buff_pool_size = 0; | ||
| 1808 | rx_ring->rx_buff_pool = NULL; | ||
| 1762 | } | 1809 | } |
| 1763 | 1810 | ||
| 1764 | /** | 1811 | /** |
| @@ -2011,6 +2058,8 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu) | |||
| 2011 | { | 2058 | { |
| 2012 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); | 2059 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); |
| 2013 | int max_frame; | 2060 | int max_frame; |
| 2061 | unsigned long old_rx_buffer_len = adapter->rx_buffer_len; | ||
| 2062 | int err; | ||
| 2014 | 2063 | ||
| 2015 | max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; | 2064 | max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; |
| 2016 | if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || | 2065 | if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || |
| @@ -2025,14 +2074,24 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu) | |||
| 2025 | else if (max_frame <= PCH_GBE_FRAME_SIZE_8192) | 2074 | else if (max_frame <= PCH_GBE_FRAME_SIZE_8192) |
| 2026 | adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_8192; | 2075 | adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_8192; |
| 2027 | else | 2076 | else |
| 2028 | adapter->rx_buffer_len = PCH_GBE_MAX_JUMBO_FRAME_SIZE; | 2077 | adapter->rx_buffer_len = PCH_GBE_MAX_RX_BUFFER_SIZE; |
| 2029 | netdev->mtu = new_mtu; | ||
| 2030 | adapter->hw.mac.max_frame_size = max_frame; | ||
| 2031 | 2078 | ||
| 2032 | if (netif_running(netdev)) | 2079 | if (netif_running(netdev)) { |
| 2033 | pch_gbe_reinit_locked(adapter); | 2080 | pch_gbe_down(adapter); |
| 2034 | else | 2081 | err = pch_gbe_up(adapter); |
| 2082 | if (err) { | ||
| 2083 | adapter->rx_buffer_len = old_rx_buffer_len; | ||
| 2084 | pch_gbe_up(adapter); | ||
| 2085 | return -ENOMEM; | ||
| 2086 | } else { | ||
| 2087 | netdev->mtu = new_mtu; | ||
| 2088 | adapter->hw.mac.max_frame_size = max_frame; | ||
| 2089 | } | ||
| 2090 | } else { | ||
| 2035 | pch_gbe_reset(adapter); | 2091 | pch_gbe_reset(adapter); |
| 2092 | netdev->mtu = new_mtu; | ||
| 2093 | adapter->hw.mac.max_frame_size = max_frame; | ||
| 2094 | } | ||
| 2036 | 2095 | ||
| 2037 | pr_debug("max_frame : %d rx_buffer_len : %d mtu : %d max_frame_size : %d\n", | 2096 | pr_debug("max_frame : %d rx_buffer_len : %d mtu : %d max_frame_size : %d\n", |
| 2038 | max_frame, (u32) adapter->rx_buffer_len, netdev->mtu, | 2097 | max_frame, (u32) adapter->rx_buffer_len, netdev->mtu, |
| @@ -2110,6 +2169,7 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) | |||
| 2110 | int work_done = 0; | 2169 | int work_done = 0; |
| 2111 | bool poll_end_flag = false; | 2170 | bool poll_end_flag = false; |
| 2112 | bool cleaned = false; | 2171 | bool cleaned = false; |
| 2172 | u32 int_en; | ||
| 2113 | 2173 | ||
| 2114 | pr_debug("budget : %d\n", budget); | 2174 | pr_debug("budget : %d\n", budget); |
| 2115 | 2175 | ||
| @@ -2117,8 +2177,15 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) | |||
| 2117 | if (!netif_carrier_ok(netdev)) { | 2177 | if (!netif_carrier_ok(netdev)) { |
| 2118 | poll_end_flag = true; | 2178 | poll_end_flag = true; |
| 2119 | } else { | 2179 | } else { |
| 2120 | cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring); | ||
| 2121 | pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); | 2180 | pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); |
| 2181 | if (adapter->rx_stop_flag) { | ||
| 2182 | adapter->rx_stop_flag = false; | ||
| 2183 | pch_gbe_start_receive(&adapter->hw); | ||
| 2184 | int_en = ioread32(&adapter->hw.reg->INT_EN); | ||
| 2185 | iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR), | ||
| 2186 | &adapter->hw.reg->INT_EN); | ||
| 2187 | } | ||
| 2188 | cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring); | ||
| 2122 | 2189 | ||
| 2123 | if (cleaned) | 2190 | if (cleaned) |
| 2124 | work_done = budget; | 2191 | work_done = budget; |
