Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 409cd63e authored by Al Viro's avatar Al Viro Committed by Jeff Garzik
Browse files

dscc4 endian fixes



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 5f490c96
Loading
Loading
Loading
Loading
+49 −45
Original line number Original line Diff line number Diff line
@@ -139,19 +139,21 @@ struct thingie {
};
};


struct TxFD {
struct TxFD {
	u32 state;
	__le32 state;
	u32 next;
	__le32 next;
	u32 data;
	__le32 data;
	u32 complete;
	__le32 complete;
	u32 jiffies; /* Allows sizeof(TxFD) == sizeof(RxFD) + extra hack */
	u32 jiffies; /* Allows sizeof(TxFD) == sizeof(RxFD) + extra hack */
		     /* FWIW, datasheet calls that "dummy" and says that card
		      * never looks at it; neither does the driver */
};
};


struct RxFD {
struct RxFD {
	u32 state1;
	__le32 state1;
	u32 next;
	__le32 next;
	u32 data;
	__le32 data;
	u32 state2;
	__le32 state2;
	u32 end;
	__le32 end;
};
};


#define DUMMY_SKB_SIZE		64
#define DUMMY_SKB_SIZE		64
@@ -181,7 +183,7 @@ struct RxFD {
#define SCC_REG_START(dpriv)	(SCC_START+(dpriv->dev_id)*SCC_OFFSET)
#define SCC_REG_START(dpriv)	(SCC_START+(dpriv->dev_id)*SCC_OFFSET)


struct dscc4_pci_priv {
struct dscc4_pci_priv {
        u32 *iqcfg;
        __le32 *iqcfg;
        int cfg_cur;
        int cfg_cur;
        spinlock_t lock;
        spinlock_t lock;
        struct pci_dev *pdev;
        struct pci_dev *pdev;
@@ -197,8 +199,8 @@ struct dscc4_dev_priv {


        struct RxFD *rx_fd;
        struct RxFD *rx_fd;
        struct TxFD *tx_fd;
        struct TxFD *tx_fd;
        u32 *iqrx;
        __le32 *iqrx;
        u32 *iqtx;
        __le32 *iqtx;


	/* FIXME: check all the volatile are required */
	/* FIXME: check all the volatile are required */
        volatile u32 tx_current;
        volatile u32 tx_current;
@@ -298,7 +300,7 @@ struct dscc4_dev_priv {
#define BrrExpMask	0x00000f00
#define BrrExpMask	0x00000f00
#define BrrMultMask	0x0000003f
#define BrrMultMask	0x0000003f
#define EncodingMask	0x00700000
#define EncodingMask	0x00700000
#define Hold		0x40000000
#define Hold		cpu_to_le32(0x40000000)
#define SccBusy		0x10000000
#define SccBusy		0x10000000
#define PowerUp		0x80000000
#define PowerUp		0x80000000
#define Vis		0x00001000
#define Vis		0x00001000
@@ -307,14 +309,14 @@ struct dscc4_dev_priv {
#define FrameRdo	0x40
#define FrameRdo	0x40
#define FrameCrc	0x20
#define FrameCrc	0x20
#define FrameRab	0x10
#define FrameRab	0x10
#define FrameAborted	0x00000200
#define FrameAborted	cpu_to_le32(0x00000200)
#define FrameEnd	0x80000000
#define FrameEnd	cpu_to_le32(0x80000000)
#define DataComplete	0x40000000
#define DataComplete	cpu_to_le32(0x40000000)
#define LengthCheck	0x00008000
#define LengthCheck	0x00008000
#define SccEvt		0x02000000
#define SccEvt		0x02000000
#define NoAck		0x00000200
#define NoAck		0x00000200
#define Action		0x00000001
#define Action		0x00000001
#define HiDesc		0x20000000
#define HiDesc		cpu_to_le32(0x20000000)


/* SCC events */
/* SCC events */
#define RxEvt		0xf0000000
#define RxEvt		0xf0000000
@@ -489,8 +491,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
	skbuff = dpriv->tx_skbuff;
	skbuff = dpriv->tx_skbuff;
	for (i = 0; i < TX_RING_SIZE; i++) {
	for (i = 0; i < TX_RING_SIZE; i++) {
		if (*skbuff) {
		if (*skbuff) {
			pci_unmap_single(pdev, tx_fd->data, (*skbuff)->len,
			pci_unmap_single(pdev, le32_to_cpu(tx_fd->data),
				PCI_DMA_TODEVICE);
				(*skbuff)->len, PCI_DMA_TODEVICE);
			dev_kfree_skb(*skbuff);
			dev_kfree_skb(*skbuff);
		}
		}
		skbuff++;
		skbuff++;
@@ -500,7 +502,7 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
	skbuff = dpriv->rx_skbuff;
	skbuff = dpriv->rx_skbuff;
	for (i = 0; i < RX_RING_SIZE; i++) {
	for (i = 0; i < RX_RING_SIZE; i++) {
		if (*skbuff) {
		if (*skbuff) {
			pci_unmap_single(pdev, rx_fd->data,
			pci_unmap_single(pdev, le32_to_cpu(rx_fd->data),
				RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
				RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
			dev_kfree_skb(*skbuff);
			dev_kfree_skb(*skbuff);
		}
		}
@@ -522,10 +524,10 @@ static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
	dpriv->rx_skbuff[dirty] = skb;
	dpriv->rx_skbuff[dirty] = skb;
	if (skb) {
	if (skb) {
		skb->protocol = hdlc_type_trans(skb, dev);
		skb->protocol = hdlc_type_trans(skb, dev);
		rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
		rx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev,
					     len, PCI_DMA_FROMDEVICE);
					  skb->data, len, PCI_DMA_FROMDEVICE));
	} else {
	} else {
		rx_fd->data = (u32) NULL;
		rx_fd->data = 0;
		ret = -1;
		ret = -1;
	}
	}
	return ret;
	return ret;
@@ -587,7 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)


	do {
	do {
		if (!(dpriv->flags & (NeedIDR | NeedIDT)) ||
		if (!(dpriv->flags & (NeedIDR | NeedIDT)) ||
		    (dpriv->iqtx[cur] & Xpr))
		    (dpriv->iqtx[cur] & cpu_to_le32(Xpr)))
			break;
			break;
		smp_rmb();
		smp_rmb();
		schedule_timeout_uninterruptible(10);
		schedule_timeout_uninterruptible(10);
@@ -650,8 +652,9 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
		printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__);
		printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__);
		goto refill;
		goto refill;
	}
	}
	pkt_len = TO_SIZE(rx_fd->state2);
	pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2));
	pci_unmap_single(pdev, rx_fd->data, RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
	pci_unmap_single(pdev, le32_to_cpu(rx_fd->data),
			 RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
	if ((skb->data[--pkt_len] & FrameOk) == FrameOk) {
	if ((skb->data[--pkt_len] & FrameOk) == FrameOk) {
		stats->rx_packets++;
		stats->rx_packets++;
		stats->rx_bytes += pkt_len;
		stats->rx_bytes += pkt_len;
@@ -679,7 +682,7 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
	}
	}
	dscc4_rx_update(dpriv, dev);
	dscc4_rx_update(dpriv, dev);
	rx_fd->state2 = 0x00000000;
	rx_fd->state2 = 0x00000000;
	rx_fd->end = 0xbabeface;
	rx_fd->end = cpu_to_le32(0xbabeface);
}
}


static void dscc4_free1(struct pci_dev *pdev)
static void dscc4_free1(struct pci_dev *pdev)
@@ -772,8 +775,8 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
	}
	}
	/* Global interrupt queue */
	/* Global interrupt queue */
	writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1);
	writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1);
	priv->iqcfg = (u32 *) pci_alloc_consistent(pdev,
	priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev,
		IRQ_RING_SIZE*sizeof(u32), &priv->iqcfg_dma);
		IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma);
	if (!priv->iqcfg)
	if (!priv->iqcfg)
		goto err_free_irq_5;
		goto err_free_irq_5;
	writel(priv->iqcfg_dma, ioaddr + IQCFG);
	writel(priv->iqcfg_dma, ioaddr + IQCFG);
@@ -786,7 +789,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
	 */
	 */
	for (i = 0; i < dev_per_card; i++) {
	for (i = 0; i < dev_per_card; i++) {
		dpriv = priv->root + i;
		dpriv = priv->root + i;
		dpriv->iqtx = (u32 *) pci_alloc_consistent(pdev,
		dpriv->iqtx = (__le32 *) pci_alloc_consistent(pdev,
			IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma);
			IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma);
		if (!dpriv->iqtx)
		if (!dpriv->iqtx)
			goto err_free_iqtx_6;
			goto err_free_iqtx_6;
@@ -794,7 +797,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
	}
	}
	for (i = 0; i < dev_per_card; i++) {
	for (i = 0; i < dev_per_card; i++) {
		dpriv = priv->root + i;
		dpriv = priv->root + i;
		dpriv->iqrx = (u32 *) pci_alloc_consistent(pdev,
		dpriv->iqrx = (__le32 *) pci_alloc_consistent(pdev,
			IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma);
			IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma);
		if (!dpriv->iqrx)
		if (!dpriv->iqrx)
			goto err_free_iqrx_7;
			goto err_free_iqrx_7;
@@ -1156,8 +1159,8 @@ static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev)
	dpriv->tx_skbuff[next] = skb;
	dpriv->tx_skbuff[next] = skb;
	tx_fd = dpriv->tx_fd + next;
	tx_fd = dpriv->tx_fd + next;
	tx_fd->state = FrameEnd | TO_STATE_TX(skb->len);
	tx_fd->state = FrameEnd | TO_STATE_TX(skb->len);
	tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len,
	tx_fd->data = cpu_to_le32(pci_map_single(ppriv->pdev, skb->data, skb->len,
				     PCI_DMA_TODEVICE);
				     PCI_DMA_TODEVICE));
	tx_fd->complete = 0x00000000;
	tx_fd->complete = 0x00000000;
	tx_fd->jiffies = jiffies;
	tx_fd->jiffies = jiffies;
	mb();
	mb();
@@ -1508,7 +1511,7 @@ static irqreturn_t dscc4_irq(int irq, void *token)
	if (state & Cfg) {
	if (state & Cfg) {
		if (debug > 0)
		if (debug > 0)
			printk(KERN_DEBUG "%s: CfgIV\n", DRV_NAME);
			printk(KERN_DEBUG "%s: CfgIV\n", DRV_NAME);
		if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & Arf)
		if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & cpu_to_le32(Arf))
			printk(KERN_ERR "%s: %s failed\n", dev->name, "CFG");
			printk(KERN_ERR "%s: %s failed\n", dev->name, "CFG");
		if (!(state &= ~Cfg))
		if (!(state &= ~Cfg))
			goto out;
			goto out;
@@ -1541,7 +1544,7 @@ static void dscc4_tx_irq(struct dscc4_pci_priv *ppriv,


try:
try:
	cur = dpriv->iqtx_current%IRQ_RING_SIZE;
	cur = dpriv->iqtx_current%IRQ_RING_SIZE;
	state = dpriv->iqtx[cur];
	state = le32_to_cpu(dpriv->iqtx[cur]);
	if (!state) {
	if (!state) {
		if (debug > 4)
		if (debug > 4)
			printk(KERN_DEBUG "%s: Tx ISR = 0x%08x\n", dev->name,
			printk(KERN_DEBUG "%s: Tx ISR = 0x%08x\n", dev->name,
@@ -1580,7 +1583,7 @@ static void dscc4_tx_irq(struct dscc4_pci_priv *ppriv,
			tx_fd = dpriv->tx_fd + cur;
			tx_fd = dpriv->tx_fd + cur;
			skb = dpriv->tx_skbuff[cur];
			skb = dpriv->tx_skbuff[cur];
			if (skb) {
			if (skb) {
				pci_unmap_single(ppriv->pdev, tx_fd->data,
				pci_unmap_single(ppriv->pdev, le32_to_cpu(tx_fd->data),
						 skb->len, PCI_DMA_TODEVICE);
						 skb->len, PCI_DMA_TODEVICE);
				if (tx_fd->state & FrameEnd) {
				if (tx_fd->state & FrameEnd) {
					stats->tx_packets++;
					stats->tx_packets++;
@@ -1711,7 +1714,7 @@ static void dscc4_rx_irq(struct dscc4_pci_priv *priv,


try:
try:
	cur = dpriv->iqrx_current%IRQ_RING_SIZE;
	cur = dpriv->iqrx_current%IRQ_RING_SIZE;
	state = dpriv->iqrx[cur];
	state = le32_to_cpu(dpriv->iqrx[cur]);
	if (!state)
	if (!state)
		return;
		return;
	dpriv->iqrx[cur] = 0;
	dpriv->iqrx[cur] = 0;
@@ -1755,7 +1758,7 @@ static void dscc4_rx_irq(struct dscc4_pci_priv *priv,
					goto try;
					goto try;
				rx_fd->state1 &= ~Hold;
				rx_fd->state1 &= ~Hold;
				rx_fd->state2 = 0x00000000;
				rx_fd->state2 = 0x00000000;
				rx_fd->end = 0xbabeface;
				rx_fd->end = cpu_to_le32(0xbabeface);
			//}
			//}
			goto try;
			goto try;
		}
		}
@@ -1834,7 +1837,7 @@ static void dscc4_rx_irq(struct dscc4_pci_priv *priv,
					hdlc_stats(dev)->rx_over_errors++;
					hdlc_stats(dev)->rx_over_errors++;
					rx_fd->state1 |= Hold;
					rx_fd->state1 |= Hold;
					rx_fd->state2 = 0x00000000;
					rx_fd->state2 = 0x00000000;
					rx_fd->end = 0xbabeface;
					rx_fd->end = cpu_to_le32(0xbabeface);
				} else
				} else
					dscc4_rx_skb(dpriv, dev);
					dscc4_rx_skb(dpriv, dev);
			} while (1);
			} while (1);
@@ -1904,8 +1907,9 @@ static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
		skb_copy_to_linear_data(skb, version,
		skb_copy_to_linear_data(skb, version,
					strlen(version) % DUMMY_SKB_SIZE);
					strlen(version) % DUMMY_SKB_SIZE);
		tx_fd->state = FrameEnd | TO_STATE_TX(DUMMY_SKB_SIZE);
		tx_fd->state = FrameEnd | TO_STATE_TX(DUMMY_SKB_SIZE);
		tx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
		tx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev,
					     DUMMY_SKB_SIZE, PCI_DMA_TODEVICE);
					     skb->data, DUMMY_SKB_SIZE,
					     PCI_DMA_TODEVICE));
		dpriv->tx_skbuff[last] = skb;
		dpriv->tx_skbuff[last] = skb;
	}
	}
	return skb;
	return skb;
@@ -1937,8 +1941,8 @@ static int dscc4_init_ring(struct net_device *dev)
		tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE);
		tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE);
		tx_fd->complete = 0x00000000;
		tx_fd->complete = 0x00000000;
	        /* FIXME: NULL should be ok - to be tried */
	        /* FIXME: NULL should be ok - to be tried */
	        tx_fd->data = dpriv->tx_fd_dma;
	        tx_fd->data = cpu_to_le32(dpriv->tx_fd_dma);
		(tx_fd++)->next = (u32)(dpriv->tx_fd_dma +
		(tx_fd++)->next = cpu_to_le32(dpriv->tx_fd_dma +
					(++i%TX_RING_SIZE)*sizeof(*tx_fd));
					(++i%TX_RING_SIZE)*sizeof(*tx_fd));
	} while (i < TX_RING_SIZE);
	} while (i < TX_RING_SIZE);


@@ -1951,12 +1955,12 @@ static int dscc4_init_ring(struct net_device *dev)
		/* size set by the host. Multiple of 4 bytes please */
		/* size set by the host. Multiple of 4 bytes please */
	        rx_fd->state1 = HiDesc;
	        rx_fd->state1 = HiDesc;
	        rx_fd->state2 = 0x00000000;
	        rx_fd->state2 = 0x00000000;
	        rx_fd->end = 0xbabeface;
	        rx_fd->end = cpu_to_le32(0xbabeface);
	        rx_fd->state1 |= TO_STATE_RX(HDLC_MAX_MRU);
	        rx_fd->state1 |= TO_STATE_RX(HDLC_MAX_MRU);
		// FIXME: return value verifiee mais traitement suspect
		// FIXME: return value verifiee mais traitement suspect
		if (try_get_rx_skb(dpriv, dev) >= 0)
		if (try_get_rx_skb(dpriv, dev) >= 0)
			dpriv->rx_dirty++;
			dpriv->rx_dirty++;
		(rx_fd++)->next = (u32)(dpriv->rx_fd_dma +
		(rx_fd++)->next = cpu_to_le32(dpriv->rx_fd_dma +
					(++i%RX_RING_SIZE)*sizeof(*rx_fd));
					(++i%RX_RING_SIZE)*sizeof(*rx_fd));
	} while (i < RX_RING_SIZE);
	} while (i < RX_RING_SIZE);