Commit 46251282 authored by Alexey Denisov's avatar Alexey Denisov Committed by Jakub Kicinski

lan743x: fix endianness when accessing descriptors

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: default avatarAlexey Denisov <rtgbnm@gmail.com>
Link: https://lore.kernel.org/r/20210128044859.280219-1-rtgbnm@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4140ff1b
...@@ -1253,7 +1253,7 @@ static void lan743x_tx_release_desc(struct lan743x_tx *tx, ...@@ -1253,7 +1253,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;
...@@ -1313,7 +1313,7 @@ static int lan743x_tx_next_index(struct lan743x_tx *tx, int index) ...@@ -1313,7 +1313,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);
} }
...@@ -1399,10 +1399,10 @@ static int lan743x_tx_frame_start(struct lan743x_tx *tx, ...@@ -1399,10 +1399,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;
...@@ -1443,7 +1443,7 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx, ...@@ -1443,7 +1443,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);
...@@ -1487,7 +1487,7 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx, ...@@ -1487,7 +1487,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);
...@@ -1513,10 +1513,10 @@ static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx, ...@@ -1513,10 +1513,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;
...@@ -1560,7 +1560,7 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx, ...@@ -1560,7 +1560,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;
...@@ -1967,11 +1967,11 @@ static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index, ...@@ -1967,11 +1967,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);
...@@ -1986,12 +1986,12 @@ static void lan743x_rx_reuse_ring_element(struct lan743x_rx *rx, int index) ...@@ -1986,12 +1986,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);
} }
...@@ -2025,7 +2025,7 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) ...@@ -2025,7 +2025,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;
...@@ -2040,14 +2040,14 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) ...@@ -2040,14 +2040,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;
...@@ -2055,10 +2055,10 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) ...@@ -2055,10 +2055,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;
} }
...@@ -2067,17 +2067,17 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) ...@@ -2067,17 +2067,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 {
...@@ -2129,7 +2129,7 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) ...@@ -2129,7 +2129,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);
...@@ -2167,8 +2167,8 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx) ...@@ -2167,8 +2167,8 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
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;
......
...@@ -661,7 +661,7 @@ struct lan743x_tx { ...@@ -661,7 +661,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;
...@@ -691,7 +691,7 @@ struct lan743x_rx { ...@@ -691,7 +691,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 { ...@@ -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 { ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment