Re: [PATCH V3] net: ezchip: adapt driver to little endian architecture
On Friday 04 March 2016 03:50 AM, David Miller wrote: > From: Lada Trimasova> Date: Thu, 3 Mar 2016 17:07:46 +0300 > >> Since ezchip network driver is written with big endian EZChip platform it >> is necessary to add support for little endian architecture. >> >> The first issue is that the order of the bits in a bit field is >> implementation specific. So all the bit fields are removed. >> Named constants are used to access necessary fields. >> >> And the second one is that network byte order is big endian. >> For example, data on ethernet is transmitted with most-significant >> octet (byte) first. So in case of little endian architecture >> it is important to swap data byte order when we read it from >> register. In case of unaligned access we can use "get_unaligned_be32" >> and in other case we can use function "ioread32_rep" which reads all >> data from register and works either with little endian or big endian >> architecture. >> >> And then when we are going to write data to register we need to restore >> byte order using the function "put_unaligned_be32" in case of >> unaligned access and in other case "iowrite32_rep". >> >> The last little fix is a space between type and pointer to observe >> coding style. >> >> Signed-off-by: Lada Trimasova > > Applied to net-next, thanks. > @Lada, could you provide the corresponding arch/arc/{boot/dts,configs}/ updates so we can switch over to this device-model/driver for OSCI platform for 4.6. Thx, -Vineet
Re: [PATCH V3] net: ezchip: adapt driver to little endian architecture
On Friday 04 March 2016 03:50 AM, David Miller wrote: > From: Lada Trimasova > Date: Thu, 3 Mar 2016 17:07:46 +0300 > >> Since ezchip network driver is written with big endian EZChip platform it >> is necessary to add support for little endian architecture. >> >> The first issue is that the order of the bits in a bit field is >> implementation specific. So all the bit fields are removed. >> Named constants are used to access necessary fields. >> >> And the second one is that network byte order is big endian. >> For example, data on ethernet is transmitted with most-significant >> octet (byte) first. So in case of little endian architecture >> it is important to swap data byte order when we read it from >> register. In case of unaligned access we can use "get_unaligned_be32" >> and in other case we can use function "ioread32_rep" which reads all >> data from register and works either with little endian or big endian >> architecture. >> >> And then when we are going to write data to register we need to restore >> byte order using the function "put_unaligned_be32" in case of >> unaligned access and in other case "iowrite32_rep". >> >> The last little fix is a space between type and pointer to observe >> coding style. >> >> Signed-off-by: Lada Trimasova > > Applied to net-next, thanks. > @Lada, could you provide the corresponding arch/arc/{boot/dts,configs}/ updates so we can switch over to this device-model/driver for OSCI platform for 4.6. Thx, -Vineet
Re: [PATCH V3] net: ezchip: adapt driver to little endian architecture
From: Lada TrimasovaDate: Thu, 3 Mar 2016 17:07:46 +0300 > Since ezchip network driver is written with big endian EZChip platform it > is necessary to add support for little endian architecture. > > The first issue is that the order of the bits in a bit field is > implementation specific. So all the bit fields are removed. > Named constants are used to access necessary fields. > > And the second one is that network byte order is big endian. > For example, data on ethernet is transmitted with most-significant > octet (byte) first. So in case of little endian architecture > it is important to swap data byte order when we read it from > register. In case of unaligned access we can use "get_unaligned_be32" > and in other case we can use function "ioread32_rep" which reads all > data from register and works either with little endian or big endian > architecture. > > And then when we are going to write data to register we need to restore > byte order using the function "put_unaligned_be32" in case of > unaligned access and in other case "iowrite32_rep". > > The last little fix is a space between type and pointer to observe > coding style. > > Signed-off-by: Lada Trimasova Applied to net-next, thanks.
Re: [PATCH V3] net: ezchip: adapt driver to little endian architecture
From: Lada Trimasova Date: Thu, 3 Mar 2016 17:07:46 +0300 > Since ezchip network driver is written with big endian EZChip platform it > is necessary to add support for little endian architecture. > > The first issue is that the order of the bits in a bit field is > implementation specific. So all the bit fields are removed. > Named constants are used to access necessary fields. > > And the second one is that network byte order is big endian. > For example, data on ethernet is transmitted with most-significant > octet (byte) first. So in case of little endian architecture > it is important to swap data byte order when we read it from > register. In case of unaligned access we can use "get_unaligned_be32" > and in other case we can use function "ioread32_rep" which reads all > data from register and works either with little endian or big endian > architecture. > > And then when we are going to write data to register we need to restore > byte order using the function "put_unaligned_be32" in case of > unaligned access and in other case "iowrite32_rep". > > The last little fix is a space between type and pointer to observe > coding style. > > Signed-off-by: Lada Trimasova Applied to net-next, thanks.
Re: [PATCH V3] net: ezchip: adapt driver to little endian architecture
On Thursday 03 March 2016 17:07:46 Lada Trimasova wrote: > From: Lada Trimasova> To: net...@vger.kernel.org > CC: linux-kernel@vger.kernel.org, Lada Trimasova > , Alexey Brodkin , > Noam Camus , Tal Zilcer , Arnd Bergmann > > Date: Today 15:07:46 > Since ezchip network driver is written with big endian EZChip platform it > is necessary to add support for little endian architecture. > > The first issue is that the order of the bits in a bit field is > implementation specific. So all the bit fields are removed. > Named constants are used to access necessary fields. > > And the second one is that network byte order is big endian. > For example, data on ethernet is transmitted with most-significant > octet (byte) first. So in case of little endian architecture > it is important to swap data byte order when we read it from > register. In case of unaligned access we can use "get_unaligned_be32" > and in other case we can use function "ioread32_rep" which reads all > data from register and works either with little endian or big endian > architecture. > > And then when we are going to write data to register we need to restore > byte order using the function "put_unaligned_be32" in case of > unaligned access and in other case "iowrite32_rep". > > The last little fix is a space between type and pointer to observe > coding style. > > Signed-off-by: Lada Trimasova > Cc: Alexey Brodkin > Cc: Noam Camus > Cc: Tal Zilcer > Cc: Arnd Bergmann > Acked-by: Arnd Bergmann
Re: [PATCH V3] net: ezchip: adapt driver to little endian architecture
On Thursday 03 March 2016 17:07:46 Lada Trimasova wrote: > From: Lada Trimasova > To: net...@vger.kernel.org > CC: linux-kernel@vger.kernel.org, Lada Trimasova > , Alexey Brodkin , > Noam Camus , Tal Zilcer , Arnd Bergmann > > Date: Today 15:07:46 > Since ezchip network driver is written with big endian EZChip platform it > is necessary to add support for little endian architecture. > > The first issue is that the order of the bits in a bit field is > implementation specific. So all the bit fields are removed. > Named constants are used to access necessary fields. > > And the second one is that network byte order is big endian. > For example, data on ethernet is transmitted with most-significant > octet (byte) first. So in case of little endian architecture > it is important to swap data byte order when we read it from > register. In case of unaligned access we can use "get_unaligned_be32" > and in other case we can use function "ioread32_rep" which reads all > data from register and works either with little endian or big endian > architecture. > > And then when we are going to write data to register we need to restore > byte order using the function "put_unaligned_be32" in case of > unaligned access and in other case "iowrite32_rep". > > The last little fix is a space between type and pointer to observe > coding style. > > Signed-off-by: Lada Trimasova > Cc: Alexey Brodkin > Cc: Noam Camus > Cc: Tal Zilcer > Cc: Arnd Bergmann > Acked-by: Arnd Bergmann
[PATCH V3] net: ezchip: adapt driver to little endian architecture
Since ezchip network driver is written with big endian EZChip platform it is necessary to add support for little endian architecture. The first issue is that the order of the bits in a bit field is implementation specific. So all the bit fields are removed. Named constants are used to access necessary fields. And the second one is that network byte order is big endian. For example, data on ethernet is transmitted with most-significant octet (byte) first. So in case of little endian architecture it is important to swap data byte order when we read it from register. In case of unaligned access we can use "get_unaligned_be32" and in other case we can use function "ioread32_rep" which reads all data from register and works either with little endian or big endian architecture. And then when we are going to write data to register we need to restore byte order using the function "put_unaligned_be32" in case of unaligned access and in other case "iowrite32_rep". The last little fix is a space between type and pointer to observe coding style. Signed-off-by: Lada TrimasovaCc: Alexey Brodkin Cc: Noam Camus Cc: Tal Zilcer Cc: Arnd Bergmann --- changes v2->v3: - using ioread32_rep/iowrite32_rep instead of cpu_to_be32/be32_to_cpu when reading from FIFO register changes v1->v2: - removing all bitfields, using named constants instead - using put_unaligned_be32/get_unaligned_be32 in case of unaligned access --- drivers/net/ethernet/ezchip/nps_enet.c | 222 +++-- drivers/net/ethernet/ezchip/nps_enet.h | 348 +++-- 2 files changed, 238 insertions(+), 332 deletions(-) diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c index b102668..1f23845a 100644 --- a/drivers/net/ethernet/ezchip/nps_enet.c +++ b/drivers/net/ethernet/ezchip/nps_enet.c @@ -43,20 +43,21 @@ static void nps_enet_read_rx_fifo(struct net_device *ndev, bool dst_is_aligned = IS_ALIGNED((unsigned long)dst, sizeof(u32)); /* In case dst is not aligned we need an intermediate buffer */ - if (dst_is_aligned) - for (i = 0; i < len; i++, reg++) - *reg = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); + if (dst_is_aligned) { + ioread32_rep(priv->regs_base + NPS_ENET_REG_RX_BUF, reg, len); + reg += len; + } else { /* !dst_is_aligned */ for (i = 0; i < len; i++, reg++) { u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); - put_unaligned(buf, reg); + put_unaligned_be32(buf, reg); } } - /* copy last bytes (if any) */ if (last) { - u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); - memcpy((u8*)reg, , last); + u32 buf; + ioread32_rep(priv->regs_base + NPS_ENET_REG_RX_BUF, , 1); + memcpy((u8 *)reg, , last); } } @@ -66,26 +67,28 @@ static u32 nps_enet_rx_handler(struct net_device *ndev) u32 work_done = 0; struct nps_enet_priv *priv = netdev_priv(ndev); struct sk_buff *skb; - struct nps_enet_rx_ctl rx_ctrl; + u32 rx_ctrl_value = nps_enet_reg_get(priv, NPS_ENET_REG_RX_CTL); + u32 rx_ctrl_cr = (rx_ctrl_value & RX_CTL_CR_MASK) >> RX_CTL_CR_SHIFT; + u32 rx_ctrl_er = (rx_ctrl_value & RX_CTL_ER_MASK) >> RX_CTL_ER_SHIFT; + u32 rx_ctrl_crc = (rx_ctrl_value & RX_CTL_CRC_MASK) >> RX_CTL_CRC_SHIFT; - rx_ctrl.value = nps_enet_reg_get(priv, NPS_ENET_REG_RX_CTL); - frame_len = rx_ctrl.nr; + frame_len = (rx_ctrl_value & RX_CTL_NR_MASK) >> RX_CTL_NR_SHIFT; /* Check if we got RX */ - if (!rx_ctrl.cr) + if (!rx_ctrl_cr) return work_done; /* If we got here there is a work for us */ work_done++; /* Check Rx error */ - if (rx_ctrl.er) { + if (rx_ctrl_er) { ndev->stats.rx_errors++; err = 1; } /* Check Rx CRC error */ - if (rx_ctrl.crc) { + if (rx_ctrl_crc) { ndev->stats.rx_crc_errors++; ndev->stats.rx_dropped++; err = 1; @@ -136,23 +139,24 @@ rx_irq_frame_done: static void nps_enet_tx_handler(struct net_device *ndev) { struct nps_enet_priv *priv = netdev_priv(ndev); - struct nps_enet_tx_ctl tx_ctrl; - - tx_ctrl.value = nps_enet_reg_get(priv, NPS_ENET_REG_TX_CTL); + u32 tx_ctrl_value = nps_enet_reg_get(priv, NPS_ENET_REG_TX_CTL); + u32 tx_ctrl_ct = (tx_ctrl_value & TX_CTL_CT_MASK) >> TX_CTL_CT_SHIFT; + u32 tx_ctrl_et = (tx_ctrl_value & TX_CTL_ET_MASK) >> TX_CTL_ET_SHIFT; + u32 tx_ctrl_nt = (tx_ctrl_value & TX_CTL_NT_MASK) >> TX_CTL_NT_SHIFT; /* Check if we got TX */ - if
[PATCH V3] net: ezchip: adapt driver to little endian architecture
Since ezchip network driver is written with big endian EZChip platform it is necessary to add support for little endian architecture. The first issue is that the order of the bits in a bit field is implementation specific. So all the bit fields are removed. Named constants are used to access necessary fields. And the second one is that network byte order is big endian. For example, data on ethernet is transmitted with most-significant octet (byte) first. So in case of little endian architecture it is important to swap data byte order when we read it from register. In case of unaligned access we can use "get_unaligned_be32" and in other case we can use function "ioread32_rep" which reads all data from register and works either with little endian or big endian architecture. And then when we are going to write data to register we need to restore byte order using the function "put_unaligned_be32" in case of unaligned access and in other case "iowrite32_rep". The last little fix is a space between type and pointer to observe coding style. Signed-off-by: Lada Trimasova Cc: Alexey Brodkin Cc: Noam Camus Cc: Tal Zilcer Cc: Arnd Bergmann --- changes v2->v3: - using ioread32_rep/iowrite32_rep instead of cpu_to_be32/be32_to_cpu when reading from FIFO register changes v1->v2: - removing all bitfields, using named constants instead - using put_unaligned_be32/get_unaligned_be32 in case of unaligned access --- drivers/net/ethernet/ezchip/nps_enet.c | 222 +++-- drivers/net/ethernet/ezchip/nps_enet.h | 348 +++-- 2 files changed, 238 insertions(+), 332 deletions(-) diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c index b102668..1f23845a 100644 --- a/drivers/net/ethernet/ezchip/nps_enet.c +++ b/drivers/net/ethernet/ezchip/nps_enet.c @@ -43,20 +43,21 @@ static void nps_enet_read_rx_fifo(struct net_device *ndev, bool dst_is_aligned = IS_ALIGNED((unsigned long)dst, sizeof(u32)); /* In case dst is not aligned we need an intermediate buffer */ - if (dst_is_aligned) - for (i = 0; i < len; i++, reg++) - *reg = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); + if (dst_is_aligned) { + ioread32_rep(priv->regs_base + NPS_ENET_REG_RX_BUF, reg, len); + reg += len; + } else { /* !dst_is_aligned */ for (i = 0; i < len; i++, reg++) { u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); - put_unaligned(buf, reg); + put_unaligned_be32(buf, reg); } } - /* copy last bytes (if any) */ if (last) { - u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); - memcpy((u8*)reg, , last); + u32 buf; + ioread32_rep(priv->regs_base + NPS_ENET_REG_RX_BUF, , 1); + memcpy((u8 *)reg, , last); } } @@ -66,26 +67,28 @@ static u32 nps_enet_rx_handler(struct net_device *ndev) u32 work_done = 0; struct nps_enet_priv *priv = netdev_priv(ndev); struct sk_buff *skb; - struct nps_enet_rx_ctl rx_ctrl; + u32 rx_ctrl_value = nps_enet_reg_get(priv, NPS_ENET_REG_RX_CTL); + u32 rx_ctrl_cr = (rx_ctrl_value & RX_CTL_CR_MASK) >> RX_CTL_CR_SHIFT; + u32 rx_ctrl_er = (rx_ctrl_value & RX_CTL_ER_MASK) >> RX_CTL_ER_SHIFT; + u32 rx_ctrl_crc = (rx_ctrl_value & RX_CTL_CRC_MASK) >> RX_CTL_CRC_SHIFT; - rx_ctrl.value = nps_enet_reg_get(priv, NPS_ENET_REG_RX_CTL); - frame_len = rx_ctrl.nr; + frame_len = (rx_ctrl_value & RX_CTL_NR_MASK) >> RX_CTL_NR_SHIFT; /* Check if we got RX */ - if (!rx_ctrl.cr) + if (!rx_ctrl_cr) return work_done; /* If we got here there is a work for us */ work_done++; /* Check Rx error */ - if (rx_ctrl.er) { + if (rx_ctrl_er) { ndev->stats.rx_errors++; err = 1; } /* Check Rx CRC error */ - if (rx_ctrl.crc) { + if (rx_ctrl_crc) { ndev->stats.rx_crc_errors++; ndev->stats.rx_dropped++; err = 1; @@ -136,23 +139,24 @@ rx_irq_frame_done: static void nps_enet_tx_handler(struct net_device *ndev) { struct nps_enet_priv *priv = netdev_priv(ndev); - struct nps_enet_tx_ctl tx_ctrl; - - tx_ctrl.value = nps_enet_reg_get(priv, NPS_ENET_REG_TX_CTL); + u32 tx_ctrl_value = nps_enet_reg_get(priv, NPS_ENET_REG_TX_CTL); + u32 tx_ctrl_ct = (tx_ctrl_value & TX_CTL_CT_MASK) >> TX_CTL_CT_SHIFT; + u32 tx_ctrl_et = (tx_ctrl_value & TX_CTL_ET_MASK) >> TX_CTL_ET_SHIFT; + u32 tx_ctrl_nt = (tx_ctrl_value & TX_CTL_NT_MASK) >> TX_CTL_NT_SHIFT; /* Check if we got TX */ - if (!priv->tx_packet_sent || tx_ctrl.ct) + if (!priv->tx_packet_sent || tx_ctrl_ct)