Skip to content

Commit f72e255

Browse files
Jijie ShaoPaolo Abeni
authored andcommitted
net: hibmcge: Implement rx_poll function to receive packets
Implement rx_poll function to read the rx descriptor after receiving the rx interrupt. Adjust the skb based on the descriptor to complete the reception of the packet. Signed-off-by: Jijie Shao <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 40735e7 commit f72e255

File tree

6 files changed

+177
-3
lines changed

6 files changed

+177
-3
lines changed

drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#define HBG_VECTOR_NUM 4
1616
#define HBG_PCU_CACHE_LINE_SIZE 32
1717
#define HBG_TX_TIMEOUT_BUF_LEN 1024
18+
#define HBG_RX_DESCR 0x01
19+
20+
#define HBG_PACKET_HEAD_SIZE ((HBG_RX_SKIP1 + HBG_RX_SKIP2 + \
21+
HBG_RX_DESCR) * HBG_PCU_CACHE_LINE_SIZE)
1822

1923
enum hbg_dir {
2024
HBG_DIR_TX = 1 << 0,
@@ -121,6 +125,7 @@ struct hbg_priv {
121125
struct hbg_mac mac;
122126
struct hbg_vector vectors;
123127
struct hbg_ring tx_ring;
128+
struct hbg_ring rx_ring;
124129
};
125130

126131
#endif

drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static int hbg_hw_dev_specs_init(struct hbg_priv *priv)
7474
return -EADDRNOTAVAIL;
7575

7676
specs->max_frame_len = HBG_PCU_CACHE_LINE_SIZE + specs->max_mtu;
77+
specs->rx_buf_size = HBG_PACKET_HEAD_SIZE + specs->max_frame_len;
7778
return 0;
7879
}
7980

@@ -178,6 +179,10 @@ u32 hbg_hw_get_fifo_used_num(struct hbg_priv *priv, enum hbg_dir dir)
178179
return hbg_reg_read_field(priv, HBG_REG_CF_CFF_DATA_NUM_ADDR,
179180
HBG_REG_CF_CFF_DATA_NUM_ADDR_TX_M);
180181

182+
if (dir & HBG_DIR_RX)
183+
return hbg_reg_read_field(priv, HBG_REG_CF_CFF_DATA_NUM_ADDR,
184+
HBG_REG_CF_CFF_DATA_NUM_ADDR_RX_M);
185+
181186
return 0;
182187
}
183188

@@ -189,6 +194,11 @@ void hbg_hw_set_tx_desc(struct hbg_priv *priv, struct hbg_tx_desc *tx_desc)
189194
hbg_reg_write(priv, HBG_REG_TX_CFF_ADDR_3_ADDR, tx_desc->word3);
190195
}
191196

197+
void hbg_hw_fill_buffer(struct hbg_priv *priv, u32 buffer_dma_addr)
198+
{
199+
hbg_reg_write(priv, HBG_REG_RX_CFF_ADDR_ADDR, buffer_dma_addr);
200+
}
201+
192202
void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex)
193203
{
194204
hbg_reg_write_field(priv, HBG_REG_PORT_MODE_ADDR,

drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,6 @@ void hbg_hw_mac_enable(struct hbg_priv *priv, u32 enable);
5454
void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr);
5555
u32 hbg_hw_get_fifo_used_num(struct hbg_priv *priv, enum hbg_dir dir);
5656
void hbg_hw_set_tx_desc(struct hbg_priv *priv, struct hbg_tx_desc *tx_desc);
57+
void hbg_hw_fill_buffer(struct hbg_priv *priv, u32 buffer_dma_addr);
5758

5859
#endif

drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,19 @@ static void hbg_irq_handle_tx(struct hbg_priv *priv,
1919
napi_schedule(&priv->tx_ring.napi);
2020
}
2121

22+
static void hbg_irq_handle_rx(struct hbg_priv *priv,
23+
struct hbg_irq_info *irq_info)
24+
{
25+
napi_schedule(&priv->rx_ring.napi);
26+
}
27+
2228
#define HBG_TXRX_IRQ_I(name, handle) \
2329
{#name, HBG_INT_MSK_##name##_B, false, false, 0, handle}
2430
#define HBG_ERR_IRQ_I(name, need_print) \
2531
{#name, HBG_INT_MSK_##name##_B, true, need_print, 0, hbg_irq_handle_err}
2632

2733
static struct hbg_irq_info hbg_irqs[] = {
28-
HBG_TXRX_IRQ_I(RX, NULL),
34+
HBG_TXRX_IRQ_I(RX, hbg_irq_handle_rx),
2935
HBG_TXRX_IRQ_I(TX, hbg_irq_handle_tx),
3036
HBG_ERR_IRQ_I(MAC_MII_FIFO_ERR, true),
3137
HBG_ERR_IRQ_I(MAC_PCS_RX_FIFO_ERR, true),

drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@
8282
#define HBG_REG_MAX_FRAME_LEN_M GENMASK(15, 0)
8383
#define HBG_REG_CF_CFF_DATA_NUM_ADDR (HBG_REG_SGMII_BASE + 0x045C)
8484
#define HBG_REG_CF_CFF_DATA_NUM_ADDR_TX_M GENMASK(8, 0)
85+
#define HBG_REG_CF_CFF_DATA_NUM_ADDR_RX_M GENMASK(24, 16)
8586
#define HBG_REG_TX_CFF_ADDR_0_ADDR (HBG_REG_SGMII_BASE + 0x0488)
8687
#define HBG_REG_TX_CFF_ADDR_1_ADDR (HBG_REG_SGMII_BASE + 0x048C)
8788
#define HBG_REG_TX_CFF_ADDR_2_ADDR (HBG_REG_SGMII_BASE + 0x0490)
8889
#define HBG_REG_TX_CFF_ADDR_3_ADDR (HBG_REG_SGMII_BASE + 0x0494)
90+
#define HBG_REG_RX_CFF_ADDR_ADDR (HBG_REG_SGMII_BASE + 0x04A0)
8991
#define HBG_REG_RX_BUF_SIZE_ADDR (HBG_REG_SGMII_BASE + 0x04E4)
9092
#define HBG_REG_RX_BUF_SIZE_M GENMASK(15, 0)
9193
#define HBG_REG_BUS_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x04E8)
@@ -127,4 +129,15 @@ struct hbg_tx_desc {
127129
#define HBG_TX_DESC_W0_l4_CS_B BIT(0)
128130
#define HBG_TX_DESC_W1_SEND_LEN_M GENMASK(19, 4)
129131

132+
struct hbg_rx_desc {
133+
u32 word0;
134+
u32 word1; /* tag */
135+
u32 word2;
136+
u32 word3;
137+
u32 word4;
138+
u32 word5;
139+
};
140+
141+
#define HBG_RX_DESC_W2_PKT_LEN_M GENMASK(31, 16)
142+
130143
#endif

drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c

Lines changed: 141 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121
_r->len - hbg_queue_used_num((head), (tail), _r) - 1; })
2222
#define hbg_queue_is_empty(head, tail, ring) \
2323
(hbg_queue_used_num((head), (tail), (ring)) == 0)
24+
#define hbg_queue_is_full(head, tail, ring) \
25+
(hbg_queue_left_num((head), (tail), (ring)) == 0)
2426
#define hbg_queue_next_prt(p, ring) (((p) + 1) % (ring)->len)
27+
#define hbg_queue_move_next(p, ring) ({ \
28+
typeof(ring) _ring = (ring); \
29+
_ring->p = hbg_queue_next_prt(_ring->p, _ring); })
2530

2631
#define HBG_TX_STOP_THRS 2
2732
#define HBG_TX_START_THRS (2 * HBG_TX_STOP_THRS)
@@ -124,6 +129,20 @@ static void hbg_buffer_free_skb(struct hbg_buffer *buffer)
124129
buffer->skb = NULL;
125130
}
126131

132+
static int hbg_buffer_alloc_skb(struct hbg_buffer *buffer)
133+
{
134+
u32 len = hbg_spec_max_frame_len(buffer->priv, buffer->dir);
135+
struct hbg_priv *priv = buffer->priv;
136+
137+
buffer->skb = netdev_alloc_skb(priv->netdev, len);
138+
if (unlikely(!buffer->skb))
139+
return -ENOMEM;
140+
141+
buffer->skb_len = len;
142+
memset(buffer->skb->data, 0, HBG_PACKET_HEAD_SIZE);
143+
return 0;
144+
}
145+
127146
static void hbg_buffer_free(struct hbg_buffer *buffer)
128147
{
129148
hbg_dma_unmap(buffer);
@@ -176,6 +195,92 @@ static int hbg_napi_tx_recycle(struct napi_struct *napi, int budget)
176195
return packet_done;
177196
}
178197

198+
static int hbg_rx_fill_one_buffer(struct hbg_priv *priv)
199+
{
200+
struct hbg_ring *ring = &priv->rx_ring;
201+
struct hbg_buffer *buffer;
202+
int ret;
203+
204+
if (hbg_queue_is_full(ring->ntc, ring->ntu, ring))
205+
return 0;
206+
207+
buffer = &ring->queue[ring->ntu];
208+
ret = hbg_buffer_alloc_skb(buffer);
209+
if (unlikely(ret))
210+
return ret;
211+
212+
ret = hbg_dma_map(buffer);
213+
if (unlikely(ret)) {
214+
hbg_buffer_free_skb(buffer);
215+
return ret;
216+
}
217+
218+
hbg_hw_fill_buffer(priv, buffer->skb_dma);
219+
hbg_queue_move_next(ntu, ring);
220+
return 0;
221+
}
222+
223+
static bool hbg_sync_data_from_hw(struct hbg_priv *priv,
224+
struct hbg_buffer *buffer)
225+
{
226+
struct hbg_rx_desc *rx_desc;
227+
228+
/* make sure HW write desc complete */
229+
dma_rmb();
230+
231+
dma_sync_single_for_cpu(&priv->pdev->dev, buffer->skb_dma,
232+
buffer->skb_len, DMA_FROM_DEVICE);
233+
234+
rx_desc = (struct hbg_rx_desc *)buffer->skb->data;
235+
return FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2) != 0;
236+
}
237+
238+
static int hbg_napi_rx_poll(struct napi_struct *napi, int budget)
239+
{
240+
struct hbg_ring *ring = container_of(napi, struct hbg_ring, napi);
241+
struct hbg_priv *priv = ring->priv;
242+
struct hbg_rx_desc *rx_desc;
243+
struct hbg_buffer *buffer;
244+
u32 packet_done = 0;
245+
u32 pkt_len;
246+
247+
while (packet_done < budget) {
248+
if (unlikely(hbg_queue_is_empty(ring->ntc, ring->ntu, ring)))
249+
break;
250+
251+
buffer = &ring->queue[ring->ntc];
252+
if (unlikely(!buffer->skb))
253+
goto next_buffer;
254+
255+
if (unlikely(!hbg_sync_data_from_hw(priv, buffer)))
256+
break;
257+
rx_desc = (struct hbg_rx_desc *)buffer->skb->data;
258+
pkt_len = FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2);
259+
260+
hbg_dma_unmap(buffer);
261+
262+
skb_reserve(buffer->skb, HBG_PACKET_HEAD_SIZE + NET_IP_ALIGN);
263+
skb_put(buffer->skb, pkt_len);
264+
buffer->skb->protocol = eth_type_trans(buffer->skb,
265+
priv->netdev);
266+
267+
dev_sw_netstats_rx_add(priv->netdev, pkt_len);
268+
napi_gro_receive(napi, buffer->skb);
269+
buffer->skb = NULL;
270+
271+
next_buffer:
272+
hbg_rx_fill_one_buffer(priv);
273+
hbg_queue_move_next(ntc, ring);
274+
packet_done++;
275+
}
276+
277+
if (likely(packet_done < budget &&
278+
napi_complete_done(napi, packet_done)))
279+
hbg_hw_irq_enable(priv, HBG_INT_MSK_RX_B, true);
280+
281+
return packet_done;
282+
}
283+
179284
static void hbg_ring_uninit(struct hbg_ring *ring)
180285
{
181286
struct hbg_buffer *buffer;
@@ -232,7 +337,11 @@ static int hbg_ring_init(struct hbg_priv *priv, struct hbg_ring *ring,
232337
ring->ntu = 0;
233338
ring->len = len;
234339

235-
netif_napi_add_tx(priv->netdev, &ring->napi, napi_poll);
340+
if (dir == HBG_DIR_TX)
341+
netif_napi_add_tx(priv->netdev, &ring->napi, napi_poll);
342+
else
343+
netif_napi_add(priv->netdev, &ring->napi, napi_poll);
344+
236345
napi_enable(&ring->napi);
237346
return 0;
238347
}
@@ -252,19 +361,49 @@ static int hbg_tx_ring_init(struct hbg_priv *priv)
252361
return hbg_ring_init(priv, tx_ring, hbg_napi_tx_recycle, HBG_DIR_TX);
253362
}
254363

364+
static int hbg_rx_ring_init(struct hbg_priv *priv)
365+
{
366+
int ret;
367+
u32 i;
368+
369+
ret = hbg_ring_init(priv, &priv->rx_ring, hbg_napi_rx_poll, HBG_DIR_RX);
370+
if (ret)
371+
return ret;
372+
373+
for (i = 0; i < priv->rx_ring.len - 1; i++) {
374+
ret = hbg_rx_fill_one_buffer(priv);
375+
if (ret) {
376+
hbg_ring_uninit(&priv->rx_ring);
377+
return ret;
378+
}
379+
}
380+
381+
return 0;
382+
}
383+
255384
int hbg_txrx_init(struct hbg_priv *priv)
256385
{
257386
int ret;
258387

259388
ret = hbg_tx_ring_init(priv);
260-
if (ret)
389+
if (ret) {
261390
dev_err(&priv->pdev->dev,
262391
"failed to init tx ring, ret = %d\n", ret);
392+
return ret;
393+
}
394+
395+
ret = hbg_rx_ring_init(priv);
396+
if (ret) {
397+
dev_err(&priv->pdev->dev,
398+
"failed to init rx ring, ret = %d\n", ret);
399+
hbg_ring_uninit(&priv->tx_ring);
400+
}
263401

264402
return ret;
265403
}
266404

267405
void hbg_txrx_uninit(struct hbg_priv *priv)
268406
{
269407
hbg_ring_uninit(&priv->tx_ring);
408+
hbg_ring_uninit(&priv->rx_ring);
270409
}

0 commit comments

Comments
 (0)