| 
														
															@@ -307,24 +307,20 @@ no_rx_mem: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void fe_txd_unmap(struct device *dev, struct fe_tx_buf *tx_buf) 
														 | 
														
														 | 
														
															 static void fe_txd_unmap(struct device *dev, struct fe_tx_buf *tx_buf) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	if (tx_buf->flags & FE_TX_FLAGS_SINGLE0) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		dma_unmap_single(dev, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				 dma_unmap_addr(tx_buf, dma_addr0), 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				 dma_unmap_len(tx_buf, dma_len0), 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				 DMA_TO_DEVICE); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	} else if (tx_buf->flags & FE_TX_FLAGS_PAGE0) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (dma_unmap_len(tx_buf, dma_len0)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		dma_unmap_page(dev, 
														 | 
														
														 | 
														
															 		dma_unmap_page(dev, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			       dma_unmap_addr(tx_buf, dma_addr0), 
														 | 
														
														 | 
														
															 			       dma_unmap_addr(tx_buf, dma_addr0), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			       dma_unmap_len(tx_buf, dma_len0), 
														 | 
														
														 | 
														
															 			       dma_unmap_len(tx_buf, dma_len0), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			       DMA_TO_DEVICE); 
														 | 
														
														 | 
														
															 			       DMA_TO_DEVICE); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	} 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	if (tx_buf->flags & FE_TX_FLAGS_PAGE1) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (dma_unmap_len(tx_buf, dma_len1)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		dma_unmap_page(dev, 
														 | 
														
														 | 
														
															 		dma_unmap_page(dev, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			       dma_unmap_addr(tx_buf, dma_addr1), 
														 | 
														
														 | 
														
															 			       dma_unmap_addr(tx_buf, dma_addr1), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			       dma_unmap_len(tx_buf, dma_len1), 
														 | 
														
														 | 
														
															 			       dma_unmap_len(tx_buf, dma_len1), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			       DMA_TO_DEVICE); 
														 | 
														
														 | 
														
															 			       DMA_TO_DEVICE); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	tx_buf->flags = 0; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	dma_unmap_len_set(tx_buf, dma_addr0, 0); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	dma_unmap_len_set(tx_buf, dma_addr1, 0); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	if (tx_buf->skb && (tx_buf->skb != (struct sk_buff *)DMA_DUMMY_DESC)) 
														 | 
														
														 | 
														
															 	if (tx_buf->skb && (tx_buf->skb != (struct sk_buff *)DMA_DUMMY_DESC)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		dev_kfree_skb_any(tx_buf->skb); 
														 | 
														
														 | 
														
															 		dev_kfree_skb_any(tx_buf->skb); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	tx_buf->skb = NULL; 
														 | 
														
														 | 
														
															 	tx_buf->skb = NULL; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -559,6 +555,54 @@ static inline u32 fe_empty_txd(struct fe_tx_ring *ring) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			 (ring->tx_ring_size - 1))); 
														 | 
														
														 | 
														
															 			 (ring->tx_ring_size - 1))); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static int fe_tx_dma_map_page(struct device *dev, struct fe_tx_buf *tx_buf, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			      struct fe_tx_dma *txd, int idx, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			      struct page *page, size_t offset, size_t size) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	dma_addr_t mapped_addr; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	mapped_addr = dma_map_page(dev, page, offset, size, DMA_TO_DEVICE); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (unlikely(dma_mapping_error(dev, mapped_addr))) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		return -EIO; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (idx & 1) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		txd->txd3 = mapped_addr; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		txd->txd2 |= TX_DMA_PLEN1(size); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		dma_unmap_addr_set(tx_buf, dma_addr1, mapped_addr); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		dma_unmap_len_set(tx_buf, dma_len1, size); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	} else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		tx_buf->skb = (struct sk_buff *)DMA_DUMMY_DESC; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		txd->txd1 = mapped_addr; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		txd->txd2 = TX_DMA_PLEN0(size); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		dma_unmap_len_set(tx_buf, dma_len0, size); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	return 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static int fe_tx_dma_map_skb(struct device *dev, struct fe_tx_buf *tx_buf, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			     struct fe_tx_dma *txd, int idx, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			     struct sk_buff *skb) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	struct page *page = virt_to_page(skb->data); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	size_t offset = offset_in_page(skb->data); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	size_t size = skb_headlen(skb); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	return fe_tx_dma_map_page(dev, tx_buf, txd, idx, page, offset, size); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static inline struct sk_buff * 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+fe_next_frag(struct sk_buff *head, struct sk_buff *skb) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (skb != head) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		return skb->next; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (skb_has_frag_list(skb)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		return skb_shinfo(skb)->frag_list; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	return NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, 
														 | 
														
														 | 
														
															 static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			 int tx_num, struct fe_tx_ring *ring) 
														 | 
														
														 | 
														
															 			 int tx_num, struct fe_tx_ring *ring) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -566,7 +610,7 @@ static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	struct skb_frag_struct *frag; 
														 | 
														
														 | 
														
															 	struct skb_frag_struct *frag; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	struct fe_tx_dma txd, *ptxd; 
														 | 
														
														 | 
														
															 	struct fe_tx_dma txd, *ptxd; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	struct fe_tx_buf *tx_buf; 
														 | 
														
														 | 
														
															 	struct fe_tx_buf *tx_buf; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	dma_addr_t mapped_addr; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	struct sk_buff *head = skb; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	unsigned int nr_frags; 
														 | 
														
														 | 
														
															 	unsigned int nr_frags; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	u32 def_txd4; 
														 | 
														
														 | 
														
															 	u32 def_txd4; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	int i, j, k, frag_size, frag_map_size, offset; 
														 | 
														
														 | 
														
															 	int i, j, k, frag_size, frag_map_size, offset; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -574,7 +618,6 @@ static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	tx_buf = &ring->tx_buf[ring->tx_next_idx]; 
														 | 
														
														 | 
														
															 	tx_buf = &ring->tx_buf[ring->tx_next_idx]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	memset(tx_buf, 0, sizeof(*tx_buf)); 
														 | 
														
														 | 
														
															 	memset(tx_buf, 0, sizeof(*tx_buf)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	memset(&txd, 0, sizeof(txd)); 
														 | 
														
														 | 
														
															 	memset(&txd, 0, sizeof(txd)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	nr_frags = skb_shinfo(skb)->nr_frags; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	/* init tx descriptor */ 
														 | 
														
														 | 
														
															 	/* init tx descriptor */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	if (priv->soc->tx_dma) 
														 | 
														
														 | 
														
															 	if (priv->soc->tx_dma) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -613,82 +656,68 @@ static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		} 
														 | 
														
														 | 
														
															 		} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	} 
														 | 
														
														 | 
														
															 	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	mapped_addr = dma_map_single(&dev->dev, skb->data, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				     skb_headlen(skb), DMA_TO_DEVICE); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	if (unlikely(dma_mapping_error(&dev->dev, mapped_addr))) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		goto err_out; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	txd.txd1 = mapped_addr; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	txd.txd2 = TX_DMA_PLEN0(skb_headlen(skb)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	k = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	j = ring->tx_next_idx; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	tx_buf->flags |= FE_TX_FLAGS_SINGLE0; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	dma_unmap_len_set(tx_buf, dma_len0, skb_headlen(skb)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+next_frag: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (skb_headlen(skb)) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		if (fe_tx_dma_map_skb(&dev->dev, tx_buf, &txd, k++, skb)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			goto err_dma; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	/* TX SG offload */ 
														 | 
														
														 | 
														
															 	/* TX SG offload */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	j = ring->tx_next_idx; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	k = 0; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	nr_frags = skb_shinfo(skb)->nr_frags; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	for (i = 0; i < nr_frags; i++) { 
														 | 
														
														 | 
														
															 	for (i = 0; i < nr_frags; i++) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		offset = 0; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		struct page *page; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		frag = &skb_shinfo(skb)->frags[i]; 
														 | 
														
														 | 
														
															 		frag = &skb_shinfo(skb)->frags[i]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		frag_size = skb_frag_size(frag); 
														 | 
														
														 | 
														
															 		frag_size = skb_frag_size(frag); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		offset = frag->page_offset; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		page = skb_frag_page(frag); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		while (frag_size > 0) { 
														 | 
														
														 | 
														
															 		while (frag_size > 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			frag_map_size = min(frag_size, TX_DMA_BUF_LEN); 
														 | 
														
														 | 
														
															 			frag_map_size = min(frag_size, TX_DMA_BUF_LEN); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-			mapped_addr = skb_frag_dma_map(&dev->dev, frag, offset, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						       frag_map_size, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						       DMA_TO_DEVICE); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-			if (unlikely(dma_mapping_error(&dev->dev, mapped_addr))) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				goto err_dma; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-			if (k & 0x1) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				j = NEXT_TX_DESP_IDX(j); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				txd.txd1 = mapped_addr; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				txd.txd2 = TX_DMA_PLEN0(frag_map_size); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			if (!(k & 0x1)) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				fe_set_txd(&txd, &ring->tx_dma[j]); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				memset(&txd, 0, sizeof(txd)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 				txd.txd4 = def_txd4; 
														 | 
														
														 | 
														
															 				txd.txd4 = def_txd4; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				j = NEXT_TX_DESP_IDX(j); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 				tx_buf = &ring->tx_buf[j]; 
														 | 
														
														 | 
														
															 				tx_buf = &ring->tx_buf[j]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				memset(tx_buf, 0, sizeof(*tx_buf)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				tx_buf->flags |= FE_TX_FLAGS_PAGE0; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				dma_unmap_addr_set(tx_buf, dma_addr0, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						   mapped_addr); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				dma_unmap_len_set(tx_buf, dma_len0, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						  frag_map_size); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-			} else { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				txd.txd3 = mapped_addr; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				txd.txd2 |= TX_DMA_PLEN1(frag_map_size); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				tx_buf->skb = (struct sk_buff *)DMA_DUMMY_DESC; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				tx_buf->flags |= FE_TX_FLAGS_PAGE1; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				dma_unmap_addr_set(tx_buf, dma_addr1, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						   mapped_addr); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				dma_unmap_len_set(tx_buf, dma_len1, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						  frag_map_size); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				if (!((i == (nr_frags - 1)) && 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				      (frag_map_size == frag_size))) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					fe_set_txd(&txd, &ring->tx_dma[j]); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					memset(&txd, 0, sizeof(txd)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-				} 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			} 
														 | 
														
														 | 
														
															 			} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			if (fe_tx_dma_map_page(&dev->dev, tx_buf, &txd, k++, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					       page, offset, frag_map_size)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				goto err_dma; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			frag_size -= frag_map_size; 
														 | 
														
														 | 
														
															 			frag_size -= frag_map_size; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			offset += frag_map_size; 
														 | 
														
														 | 
														
															 			offset += frag_map_size; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-			k++; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		} 
														 | 
														
														 | 
														
															 		} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	} 
														 | 
														
														 | 
														
															 	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	skb = fe_next_frag(head, skb); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (skb) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		if (!(k & 0x1)) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			fe_set_txd(&txd, &ring->tx_dma[j]); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			memset(&txd, 0, sizeof(txd)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			txd.txd4 = def_txd4; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			j = NEXT_TX_DESP_IDX(j); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			tx_buf = &ring->tx_buf[j]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		goto next_frag; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	/* set last segment */ 
														 | 
														
														 | 
														
															 	/* set last segment */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	if (k & 0x1) 
														 | 
														
														 | 
														
															 	if (k & 0x1) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		txd.txd2 |= TX_DMA_LS1; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	else 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		txd.txd2 |= TX_DMA_LS0; 
														 | 
														
														 | 
														
															 		txd.txd2 |= TX_DMA_LS0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	else 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		txd.txd2 |= TX_DMA_LS1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	fe_set_txd(&txd, &ring->tx_dma[j]); 
														 | 
														
														 | 
														
															 	fe_set_txd(&txd, &ring->tx_dma[j]); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	/* store skb to cleanup */ 
														 | 
														
														 | 
														
															 	/* store skb to cleanup */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	tx_buf->skb = skb; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	tx_buf->skb = head; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	netdev_sent_queue(dev, skb->len); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	skb_tx_timestamp(skb); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	netdev_sent_queue(dev, head->len); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	skb_tx_timestamp(head); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	ring->tx_next_idx = NEXT_TX_DESP_IDX(j); 
														 | 
														
														 | 
														
															 	ring->tx_next_idx = NEXT_TX_DESP_IDX(j); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	/* make sure that all changes to the dma ring are flushed before we 
														 | 
														
														 | 
														
															 	/* make sure that all changes to the dma ring are flushed before we 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -702,7 +731,7 @@ static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			netif_wake_queue(dev); 
														 | 
														
														 | 
														
															 			netif_wake_queue(dev); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	} 
														 | 
														
														 | 
														
															 	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || !skb->xmit_more) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || !head->xmit_more) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		fe_reg_w32(ring->tx_next_idx, FE_REG_TX_CTX_IDX0); 
														 | 
														
														 | 
														
															 		fe_reg_w32(ring->tx_next_idx, FE_REG_TX_CTX_IDX0); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	return 0; 
														 | 
														
														 | 
														
															 	return 0; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -762,10 +791,12 @@ static inline int fe_skb_padto(struct sk_buff *skb, struct fe_priv *priv) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static inline int fe_cal_txd_req(struct sk_buff *skb) 
														 | 
														
														 | 
														
															 static inline int fe_cal_txd_req(struct sk_buff *skb) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	int i, nfrags; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	struct sk_buff *head = skb; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	int i, nfrags = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	struct skb_frag_struct *frag; 
														 | 
														
														 | 
														
															 	struct skb_frag_struct *frag; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	nfrags = 1; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+next_frag: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	nfrags++; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	if (skb_is_gso(skb)) { 
														 | 
														
														 | 
														
															 	if (skb_is_gso(skb)) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 
														 | 
														
														 | 
														
															 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			frag = &skb_shinfo(skb)->frags[i]; 
														 | 
														
														 | 
														
															 			frag = &skb_shinfo(skb)->frags[i]; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -775,6 +806,10 @@ static inline int fe_cal_txd_req(struct sk_buff *skb) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		nfrags += skb_shinfo(skb)->nr_frags; 
														 | 
														
														 | 
														
															 		nfrags += skb_shinfo(skb)->nr_frags; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	} 
														 | 
														
														 | 
														
															 	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	skb = fe_next_frag(head, skb); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	if (skb) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		goto next_frag; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	return DIV_ROUND_UP(nfrags, 2); 
														 | 
														
														 | 
														
															 	return DIV_ROUND_UP(nfrags, 2); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 |