diff options
Diffstat (limited to 'drivers/net/ethernet/microchip/lan743x_main.c')
-rw-r--r-- | drivers/net/ethernet/microchip/lan743x_main.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index 4d1b4a24907f..13e6bf13ac4d 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c | |||
@@ -585,8 +585,7 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) | |||
585 | 585 | ||
586 | if (adapter->csr.flags & | 586 | if (adapter->csr.flags & |
587 | LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR) { | 587 | LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR) { |
588 | flags = LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_CLEAR | | 588 | flags = LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET | |
589 | LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET | | ||
590 | LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET | | 589 | LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET | |
591 | LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_CLEAR | | 590 | LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_CLEAR | |
592 | LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR; | 591 | LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR; |
@@ -599,12 +598,6 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) | |||
599 | /* map TX interrupt to vector */ | 598 | /* map TX interrupt to vector */ |
600 | int_vec_map1 |= INT_VEC_MAP1_TX_VEC_(index, vector); | 599 | int_vec_map1 |= INT_VEC_MAP1_TX_VEC_(index, vector); |
601 | lan743x_csr_write(adapter, INT_VEC_MAP1, int_vec_map1); | 600 | lan743x_csr_write(adapter, INT_VEC_MAP1, int_vec_map1); |
602 | if (flags & | ||
603 | LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_CLEAR) { | ||
604 | int_vec_en_auto_clr |= INT_VEC_EN_(vector); | ||
605 | lan743x_csr_write(adapter, INT_VEC_EN_AUTO_CLR, | ||
606 | int_vec_en_auto_clr); | ||
607 | } | ||
608 | 601 | ||
609 | /* Remove TX interrupt from shared mask */ | 602 | /* Remove TX interrupt from shared mask */ |
610 | intr->vector_list[0].int_mask &= ~int_bit; | 603 | intr->vector_list[0].int_mask &= ~int_bit; |
@@ -1902,7 +1895,17 @@ static int lan743x_rx_next_index(struct lan743x_rx *rx, int index) | |||
1902 | return ((++index) % rx->ring_size); | 1895 | return ((++index) % rx->ring_size); |
1903 | } | 1896 | } |
1904 | 1897 | ||
1905 | static int lan743x_rx_allocate_ring_element(struct lan743x_rx *rx, int index) | 1898 | static struct sk_buff *lan743x_rx_allocate_skb(struct lan743x_rx *rx) |
1899 | { | ||
1900 | int length = 0; | ||
1901 | |||
1902 | length = (LAN743X_MAX_FRAME_SIZE + ETH_HLEN + 4 + RX_HEAD_PADDING); | ||
1903 | return __netdev_alloc_skb(rx->adapter->netdev, | ||
1904 | length, GFP_ATOMIC | GFP_DMA); | ||
1905 | } | ||
1906 | |||
1907 | static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index, | ||
1908 | struct sk_buff *skb) | ||
1906 | { | 1909 | { |
1907 | struct lan743x_rx_buffer_info *buffer_info; | 1910 | struct lan743x_rx_buffer_info *buffer_info; |
1908 | struct lan743x_rx_descriptor *descriptor; | 1911 | struct lan743x_rx_descriptor *descriptor; |
@@ -1911,9 +1914,7 @@ static int lan743x_rx_allocate_ring_element(struct lan743x_rx *rx, int index) | |||
1911 | length = (LAN743X_MAX_FRAME_SIZE + ETH_HLEN + 4 + RX_HEAD_PADDING); | 1914 | length = (LAN743X_MAX_FRAME_SIZE + ETH_HLEN + 4 + RX_HEAD_PADDING); |
1912 | descriptor = &rx->ring_cpu_ptr[index]; | 1915 | descriptor = &rx->ring_cpu_ptr[index]; |
1913 | buffer_info = &rx->buffer_info[index]; | 1916 | buffer_info = &rx->buffer_info[index]; |
1914 | buffer_info->skb = __netdev_alloc_skb(rx->adapter->netdev, | 1917 | buffer_info->skb = skb; |
1915 | length, | ||
1916 | GFP_ATOMIC | GFP_DMA); | ||
1917 | if (!(buffer_info->skb)) | 1918 | if (!(buffer_info->skb)) |
1918 | return -ENOMEM; | 1919 | return -ENOMEM; |
1919 | buffer_info->dma_ptr = dma_map_single(&rx->adapter->pdev->dev, | 1920 | buffer_info->dma_ptr = dma_map_single(&rx->adapter->pdev->dev, |
@@ -2060,8 +2061,19 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) | |||
2060 | /* packet is available */ | 2061 | /* packet is available */ |
2061 | if (first_index == last_index) { | 2062 | if (first_index == last_index) { |
2062 | /* single buffer packet */ | 2063 | /* single buffer packet */ |
2064 | struct sk_buff *new_skb = NULL; | ||
2063 | int packet_length; | 2065 | int packet_length; |
2064 | 2066 | ||
2067 | new_skb = lan743x_rx_allocate_skb(rx); | ||
2068 | if (!new_skb) { | ||
2069 | /* failed to allocate next skb. | ||
2070 | * Memory is very low. | ||
2071 | * Drop this packet and reuse buffer. | ||
2072 | */ | ||
2073 | lan743x_rx_reuse_ring_element(rx, first_index); | ||
2074 | goto process_extension; | ||
2075 | } | ||
2076 | |||
2065 | buffer_info = &rx->buffer_info[first_index]; | 2077 | buffer_info = &rx->buffer_info[first_index]; |
2066 | skb = buffer_info->skb; | 2078 | skb = buffer_info->skb; |
2067 | descriptor = &rx->ring_cpu_ptr[first_index]; | 2079 | descriptor = &rx->ring_cpu_ptr[first_index]; |
@@ -2081,7 +2093,7 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) | |||
2081 | skb_put(skb, packet_length - 4); | 2093 | skb_put(skb, packet_length - 4); |
2082 | skb->protocol = eth_type_trans(skb, | 2094 | skb->protocol = eth_type_trans(skb, |
2083 | rx->adapter->netdev); | 2095 | rx->adapter->netdev); |
2084 | lan743x_rx_allocate_ring_element(rx, first_index); | 2096 | lan743x_rx_init_ring_element(rx, first_index, new_skb); |
2085 | } else { | 2097 | } else { |
2086 | int index = first_index; | 2098 | int index = first_index; |
2087 | 2099 | ||
@@ -2094,26 +2106,23 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) | |||
2094 | if (first_index <= last_index) { | 2106 | if (first_index <= last_index) { |
2095 | while ((index >= first_index) && | 2107 | while ((index >= first_index) && |
2096 | (index <= last_index)) { | 2108 | (index <= last_index)) { |
2097 | lan743x_rx_release_ring_element(rx, | 2109 | lan743x_rx_reuse_ring_element(rx, |
2098 | index); | 2110 | index); |
2099 | lan743x_rx_allocate_ring_element(rx, | ||
2100 | index); | ||
2101 | index = lan743x_rx_next_index(rx, | 2111 | index = lan743x_rx_next_index(rx, |
2102 | index); | 2112 | index); |
2103 | } | 2113 | } |
2104 | } else { | 2114 | } else { |
2105 | while ((index >= first_index) || | 2115 | while ((index >= first_index) || |
2106 | (index <= last_index)) { | 2116 | (index <= last_index)) { |
2107 | lan743x_rx_release_ring_element(rx, | 2117 | lan743x_rx_reuse_ring_element(rx, |
2108 | index); | 2118 | index); |
2109 | lan743x_rx_allocate_ring_element(rx, | ||
2110 | index); | ||
2111 | index = lan743x_rx_next_index(rx, | 2119 | index = lan743x_rx_next_index(rx, |
2112 | index); | 2120 | index); |
2113 | } | 2121 | } |
2114 | } | 2122 | } |
2115 | } | 2123 | } |
2116 | 2124 | ||
2125 | process_extension: | ||
2117 | if (extension_index >= 0) { | 2126 | if (extension_index >= 0) { |
2118 | descriptor = &rx->ring_cpu_ptr[extension_index]; | 2127 | descriptor = &rx->ring_cpu_ptr[extension_index]; |
2119 | buffer_info = &rx->buffer_info[extension_index]; | 2128 | buffer_info = &rx->buffer_info[extension_index]; |
@@ -2290,7 +2299,9 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx) | |||
2290 | 2299 | ||
2291 | rx->last_head = 0; | 2300 | rx->last_head = 0; |
2292 | for (index = 0; index < rx->ring_size; index++) { | 2301 | for (index = 0; index < rx->ring_size; index++) { |
2293 | ret = lan743x_rx_allocate_ring_element(rx, index); | 2302 | struct sk_buff *new_skb = lan743x_rx_allocate_skb(rx); |
2303 | |||
2304 | ret = lan743x_rx_init_ring_element(rx, index, new_skb); | ||
2294 | if (ret) | 2305 | if (ret) |
2295 | goto cleanup; | 2306 | goto cleanup; |
2296 | } | 2307 | } |