lan743x: fix endianness when accessing descriptors
[ Upstream commit 462512824f902a24de794290dd622e664587da1d ] TX/RX descriptor ring fields are always little-endian, but conversion wasn't performed for big-endian CPUs, so the driver failed to work. This patch makes the driver work on big-endian CPUs. It was tested and confirmed to work on NXP P1010 processor (PowerPC). Signed-off-by: Alexey Denisov <rtgbnm@gmail.com> Link: https://lore.kernel.org/r/20210128044859.280219-1-rtgbnm@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
a7112b8eeb
commit
727e5deca8
@@ -1280,7 +1280,7 @@ static void lan743x_tx_release_desc(struct lan743x_tx *tx,
|
|||||||
if (!(buffer_info->flags & TX_BUFFER_INFO_FLAG_ACTIVE))
|
if (!(buffer_info->flags & TX_BUFFER_INFO_FLAG_ACTIVE))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
descriptor_type = (descriptor->data0) &
|
descriptor_type = le32_to_cpu(descriptor->data0) &
|
||||||
TX_DESC_DATA0_DTYPE_MASK_;
|
TX_DESC_DATA0_DTYPE_MASK_;
|
||||||
if (descriptor_type == TX_DESC_DATA0_DTYPE_DATA_)
|
if (descriptor_type == TX_DESC_DATA0_DTYPE_DATA_)
|
||||||
goto clean_up_data_descriptor;
|
goto clean_up_data_descriptor;
|
||||||
@@ -1340,7 +1340,7 @@ static int lan743x_tx_next_index(struct lan743x_tx *tx, int index)
|
|||||||
|
|
||||||
static void lan743x_tx_release_completed_descriptors(struct lan743x_tx *tx)
|
static void lan743x_tx_release_completed_descriptors(struct lan743x_tx *tx)
|
||||||
{
|
{
|
||||||
while ((*tx->head_cpu_ptr) != (tx->last_head)) {
|
while (le32_to_cpu(*tx->head_cpu_ptr) != (tx->last_head)) {
|
||||||
lan743x_tx_release_desc(tx, tx->last_head, false);
|
lan743x_tx_release_desc(tx, tx->last_head, false);
|
||||||
tx->last_head = lan743x_tx_next_index(tx, tx->last_head);
|
tx->last_head = lan743x_tx_next_index(tx, tx->last_head);
|
||||||
}
|
}
|
||||||
@@ -1426,10 +1426,10 @@ static int lan743x_tx_frame_start(struct lan743x_tx *tx,
|
|||||||
if (dma_mapping_error(dev, dma_ptr))
|
if (dma_mapping_error(dev, dma_ptr))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
tx_descriptor->data1 = DMA_ADDR_LOW32(dma_ptr);
|
tx_descriptor->data1 = cpu_to_le32(DMA_ADDR_LOW32(dma_ptr));
|
||||||
tx_descriptor->data2 = DMA_ADDR_HIGH32(dma_ptr);
|
tx_descriptor->data2 = cpu_to_le32(DMA_ADDR_HIGH32(dma_ptr));
|
||||||
tx_descriptor->data3 = (frame_length << 16) &
|
tx_descriptor->data3 = cpu_to_le32((frame_length << 16) &
|
||||||
TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_;
|
TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_);
|
||||||
|
|
||||||
buffer_info->skb = NULL;
|
buffer_info->skb = NULL;
|
||||||
buffer_info->dma_ptr = dma_ptr;
|
buffer_info->dma_ptr = dma_ptr;
|
||||||
@@ -1470,7 +1470,7 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
|
|||||||
tx->frame_data0 |= TX_DESC_DATA0_IOC_;
|
tx->frame_data0 |= TX_DESC_DATA0_IOC_;
|
||||||
}
|
}
|
||||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
||||||
tx_descriptor->data0 = tx->frame_data0;
|
tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
|
||||||
|
|
||||||
/* move to next descriptor */
|
/* move to next descriptor */
|
||||||
tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
|
tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
|
||||||
@@ -1514,7 +1514,7 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx,
|
|||||||
|
|
||||||
/* wrap up previous descriptor */
|
/* wrap up previous descriptor */
|
||||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
||||||
tx_descriptor->data0 = tx->frame_data0;
|
tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
|
||||||
|
|
||||||
/* move to next descriptor */
|
/* move to next descriptor */
|
||||||
tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
|
tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
|
||||||
@@ -1540,10 +1540,10 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_descriptor->data1 = DMA_ADDR_LOW32(dma_ptr);
|
tx_descriptor->data1 = cpu_to_le32(DMA_ADDR_LOW32(dma_ptr));
|
||||||
tx_descriptor->data2 = DMA_ADDR_HIGH32(dma_ptr);
|
tx_descriptor->data2 = cpu_to_le32(DMA_ADDR_HIGH32(dma_ptr));
|
||||||
tx_descriptor->data3 = (frame_length << 16) &
|
tx_descriptor->data3 = cpu_to_le32((frame_length << 16) &
|
||||||
TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_;
|
TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_);
|
||||||
|
|
||||||
buffer_info->skb = NULL;
|
buffer_info->skb = NULL;
|
||||||
buffer_info->dma_ptr = dma_ptr;
|
buffer_info->dma_ptr = dma_ptr;
|
||||||
@@ -1587,7 +1587,7 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx,
|
|||||||
if (ignore_sync)
|
if (ignore_sync)
|
||||||
buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC;
|
buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC;
|
||||||
|
|
||||||
tx_descriptor->data0 = tx->frame_data0;
|
tx_descriptor->data0 = cpu_to_le32(tx->frame_data0);
|
||||||
tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
|
tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
|
||||||
tx->last_tail = tx->frame_tail;
|
tx->last_tail = tx->frame_tail;
|
||||||
|
|
||||||
@@ -2004,11 +2004,11 @@ static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer_info->buffer_length = length;
|
buffer_info->buffer_length = length;
|
||||||
descriptor->data1 = DMA_ADDR_LOW32(buffer_info->dma_ptr);
|
descriptor->data1 = cpu_to_le32(DMA_ADDR_LOW32(buffer_info->dma_ptr));
|
||||||
descriptor->data2 = DMA_ADDR_HIGH32(buffer_info->dma_ptr);
|
descriptor->data2 = cpu_to_le32(DMA_ADDR_HIGH32(buffer_info->dma_ptr));
|
||||||
descriptor->data3 = 0;
|
descriptor->data3 = 0;
|
||||||
descriptor->data0 = (RX_DESC_DATA0_OWN_ |
|
descriptor->data0 = cpu_to_le32((RX_DESC_DATA0_OWN_ |
|
||||||
(length & RX_DESC_DATA0_BUF_LENGTH_MASK_));
|
(length & RX_DESC_DATA0_BUF_LENGTH_MASK_)));
|
||||||
skb_reserve(buffer_info->skb, RX_HEAD_PADDING);
|
skb_reserve(buffer_info->skb, RX_HEAD_PADDING);
|
||||||
lan743x_rx_update_tail(rx, index);
|
lan743x_rx_update_tail(rx, index);
|
||||||
|
|
||||||
@@ -2023,12 +2023,12 @@ static void lan743x_rx_reuse_ring_element(struct lan743x_rx *rx, int index)
|
|||||||
descriptor = &rx->ring_cpu_ptr[index];
|
descriptor = &rx->ring_cpu_ptr[index];
|
||||||
buffer_info = &rx->buffer_info[index];
|
buffer_info = &rx->buffer_info[index];
|
||||||
|
|
||||||
descriptor->data1 = DMA_ADDR_LOW32(buffer_info->dma_ptr);
|
descriptor->data1 = cpu_to_le32(DMA_ADDR_LOW32(buffer_info->dma_ptr));
|
||||||
descriptor->data2 = DMA_ADDR_HIGH32(buffer_info->dma_ptr);
|
descriptor->data2 = cpu_to_le32(DMA_ADDR_HIGH32(buffer_info->dma_ptr));
|
||||||
descriptor->data3 = 0;
|
descriptor->data3 = 0;
|
||||||
descriptor->data0 = (RX_DESC_DATA0_OWN_ |
|
descriptor->data0 = cpu_to_le32((RX_DESC_DATA0_OWN_ |
|
||||||
((buffer_info->buffer_length) &
|
((buffer_info->buffer_length) &
|
||||||
RX_DESC_DATA0_BUF_LENGTH_MASK_));
|
RX_DESC_DATA0_BUF_LENGTH_MASK_)));
|
||||||
lan743x_rx_update_tail(rx, index);
|
lan743x_rx_update_tail(rx, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2062,7 +2062,7 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
|
|||||||
{
|
{
|
||||||
struct skb_shared_hwtstamps *hwtstamps = NULL;
|
struct skb_shared_hwtstamps *hwtstamps = NULL;
|
||||||
int result = RX_PROCESS_RESULT_NOTHING_TO_DO;
|
int result = RX_PROCESS_RESULT_NOTHING_TO_DO;
|
||||||
int current_head_index = *rx->head_cpu_ptr;
|
int current_head_index = le32_to_cpu(*rx->head_cpu_ptr);
|
||||||
struct lan743x_rx_buffer_info *buffer_info;
|
struct lan743x_rx_buffer_info *buffer_info;
|
||||||
struct lan743x_rx_descriptor *descriptor;
|
struct lan743x_rx_descriptor *descriptor;
|
||||||
int extension_index = -1;
|
int extension_index = -1;
|
||||||
@@ -2077,14 +2077,14 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
|
|||||||
|
|
||||||
if (rx->last_head != current_head_index) {
|
if (rx->last_head != current_head_index) {
|
||||||
descriptor = &rx->ring_cpu_ptr[rx->last_head];
|
descriptor = &rx->ring_cpu_ptr[rx->last_head];
|
||||||
if (descriptor->data0 & RX_DESC_DATA0_OWN_)
|
if (le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_OWN_)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (!(descriptor->data0 & RX_DESC_DATA0_FS_))
|
if (!(le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_FS_))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
first_index = rx->last_head;
|
first_index = rx->last_head;
|
||||||
if (descriptor->data0 & RX_DESC_DATA0_LS_) {
|
if (le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_LS_) {
|
||||||
last_index = rx->last_head;
|
last_index = rx->last_head;
|
||||||
} else {
|
} else {
|
||||||
int index;
|
int index;
|
||||||
@@ -2092,10 +2092,10 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
|
|||||||
index = lan743x_rx_next_index(rx, first_index);
|
index = lan743x_rx_next_index(rx, first_index);
|
||||||
while (index != current_head_index) {
|
while (index != current_head_index) {
|
||||||
descriptor = &rx->ring_cpu_ptr[index];
|
descriptor = &rx->ring_cpu_ptr[index];
|
||||||
if (descriptor->data0 & RX_DESC_DATA0_OWN_)
|
if (le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_OWN_)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (descriptor->data0 & RX_DESC_DATA0_LS_) {
|
if (le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_LS_) {
|
||||||
last_index = index;
|
last_index = index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2104,17 +2104,17 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
|
|||||||
}
|
}
|
||||||
if (last_index >= 0) {
|
if (last_index >= 0) {
|
||||||
descriptor = &rx->ring_cpu_ptr[last_index];
|
descriptor = &rx->ring_cpu_ptr[last_index];
|
||||||
if (descriptor->data0 & RX_DESC_DATA0_EXT_) {
|
if (le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_EXT_) {
|
||||||
/* extension is expected to follow */
|
/* extension is expected to follow */
|
||||||
int index = lan743x_rx_next_index(rx,
|
int index = lan743x_rx_next_index(rx,
|
||||||
last_index);
|
last_index);
|
||||||
if (index != current_head_index) {
|
if (index != current_head_index) {
|
||||||
descriptor = &rx->ring_cpu_ptr[index];
|
descriptor = &rx->ring_cpu_ptr[index];
|
||||||
if (descriptor->data0 &
|
if (le32_to_cpu(descriptor->data0) &
|
||||||
RX_DESC_DATA0_OWN_) {
|
RX_DESC_DATA0_OWN_) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (descriptor->data0 &
|
if (le32_to_cpu(descriptor->data0) &
|
||||||
RX_DESC_DATA0_EXT_) {
|
RX_DESC_DATA0_EXT_) {
|
||||||
extension_index = index;
|
extension_index = index;
|
||||||
} else {
|
} else {
|
||||||
@@ -2166,7 +2166,7 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
|
|||||||
}
|
}
|
||||||
buffer_info->skb = NULL;
|
buffer_info->skb = NULL;
|
||||||
packet_length = RX_DESC_DATA0_FRAME_LENGTH_GET_
|
packet_length = RX_DESC_DATA0_FRAME_LENGTH_GET_
|
||||||
(descriptor->data0);
|
(le32_to_cpu(descriptor->data0));
|
||||||
skb_put(skb, packet_length - 4);
|
skb_put(skb, packet_length - 4);
|
||||||
skb->protocol = eth_type_trans(skb,
|
skb->protocol = eth_type_trans(skb,
|
||||||
rx->adapter->netdev);
|
rx->adapter->netdev);
|
||||||
@@ -2204,8 +2204,8 @@ process_extension:
|
|||||||
descriptor = &rx->ring_cpu_ptr[extension_index];
|
descriptor = &rx->ring_cpu_ptr[extension_index];
|
||||||
buffer_info = &rx->buffer_info[extension_index];
|
buffer_info = &rx->buffer_info[extension_index];
|
||||||
|
|
||||||
ts_sec = descriptor->data1;
|
ts_sec = le32_to_cpu(descriptor->data1);
|
||||||
ts_nsec = (descriptor->data2 &
|
ts_nsec = (le32_to_cpu(descriptor->data2) &
|
||||||
RX_DESC_DATA2_TS_NS_MASK_);
|
RX_DESC_DATA2_TS_NS_MASK_);
|
||||||
lan743x_rx_reuse_ring_element(rx, extension_index);
|
lan743x_rx_reuse_ring_element(rx, extension_index);
|
||||||
real_last_index = extension_index;
|
real_last_index = extension_index;
|
||||||
|
@@ -660,7 +660,7 @@ struct lan743x_tx {
|
|||||||
|
|
||||||
struct lan743x_tx_buffer_info *buffer_info;
|
struct lan743x_tx_buffer_info *buffer_info;
|
||||||
|
|
||||||
u32 *head_cpu_ptr;
|
__le32 *head_cpu_ptr;
|
||||||
dma_addr_t head_dma_ptr;
|
dma_addr_t head_dma_ptr;
|
||||||
int last_head;
|
int last_head;
|
||||||
int last_tail;
|
int last_tail;
|
||||||
@@ -690,7 +690,7 @@ struct lan743x_rx {
|
|||||||
|
|
||||||
struct lan743x_rx_buffer_info *buffer_info;
|
struct lan743x_rx_buffer_info *buffer_info;
|
||||||
|
|
||||||
u32 *head_cpu_ptr;
|
__le32 *head_cpu_ptr;
|
||||||
dma_addr_t head_dma_ptr;
|
dma_addr_t head_dma_ptr;
|
||||||
u32 last_head;
|
u32 last_head;
|
||||||
u32 last_tail;
|
u32 last_tail;
|
||||||
@@ -775,10 +775,10 @@ struct lan743x_adapter {
|
|||||||
#define TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_ (0x3FFF0000)
|
#define TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_ (0x3FFF0000)
|
||||||
|
|
||||||
struct lan743x_tx_descriptor {
|
struct lan743x_tx_descriptor {
|
||||||
u32 data0;
|
__le32 data0;
|
||||||
u32 data1;
|
__le32 data1;
|
||||||
u32 data2;
|
__le32 data2;
|
||||||
u32 data3;
|
__le32 data3;
|
||||||
} __aligned(DEFAULT_DMA_DESCRIPTOR_SPACING);
|
} __aligned(DEFAULT_DMA_DESCRIPTOR_SPACING);
|
||||||
|
|
||||||
#define TX_BUFFER_INFO_FLAG_ACTIVE BIT(0)
|
#define TX_BUFFER_INFO_FLAG_ACTIVE BIT(0)
|
||||||
@@ -813,10 +813,10 @@ struct lan743x_tx_buffer_info {
|
|||||||
#define RX_HEAD_PADDING NET_IP_ALIGN
|
#define RX_HEAD_PADDING NET_IP_ALIGN
|
||||||
|
|
||||||
struct lan743x_rx_descriptor {
|
struct lan743x_rx_descriptor {
|
||||||
u32 data0;
|
__le32 data0;
|
||||||
u32 data1;
|
__le32 data1;
|
||||||
u32 data2;
|
__le32 data2;
|
||||||
u32 data3;
|
__le32 data3;
|
||||||
} __aligned(DEFAULT_DMA_DESCRIPTOR_SPACING);
|
} __aligned(DEFAULT_DMA_DESCRIPTOR_SPACING);
|
||||||
|
|
||||||
#define RX_BUFFER_INFO_FLAG_ACTIVE BIT(0)
|
#define RX_BUFFER_INFO_FLAG_ACTIVE BIT(0)
|
||||||
|
Reference in New Issue
Block a user