Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-lan966x-use-the-newly-introduced-fdma-library'

Daniel Machon says:

====================
net: lan966x: use the newly introduced FDMA library

This patch series is the second of a 2-part series [1], that adds a new
common FDMA library for Microchip switch chips Sparx5 and lan966x. These
chips share the same FDMA engine, and as such will benefit from a common
library with a common implementation. This also has the benefit of
removing a lot of open-coded bookkeeping and duplicate code for the two
drivers.

In this second series, the FDMA library will be taken into use by the
lan966x switch driver.

###################
# Example of use: #
###################

- Initialize the rx and tx fdma structs with values for: number of
DCB's, number of DB's, channel ID, DB size (data buffer size), and
total size of the requested memory. Also provide two callbacks:
nextptr_cb() and dataptr_cb() for getting the nextptr and dataptr.

- Allocate memory using fdma_alloc_phys() or fdma_alloc_coherent().

- Initialize the DCB's with fdma_dcb_init().

- Add new DCB's with fdma_dcb_add().

- Free memory with fdma_free_phys() or fdma_free_coherent().

#####################
# Patch breakdown: #
#####################

Patch #1: select FDMA library for lan966x.

Patch #2: includes the fdma_api.h header and removes old symbols.

Patch #3: replaces old rx and tx variables with equivalent ones from the
fdma struct. Only the variables that can be changed without
breaking traffic is changed in this patch.

Patch #4: uses the library for allocation of rx buffers. This requires
quite a bit of refactoring in this single patch.

Patch #5: uses the library for adding DCB's in the rx path.

Patch #6: uses the library for freeing rx buffers.

Patch #7: uses the library for allocation of tx buffers. This requires
quite a bit of refactoring in this single patch.

Patch #8: uses the library for adding DCB's in the tx path.

Patch #9: uses the library helpers in the tx path.

Patch #10: ditch last_in_use variable and use library instead.

Patch #11: uses library helpers throughout.

Patch #12: refactor lan966x_fdma_reload() function.

[1] https://lore.kernel.org/netdev/20240902-fdma-sparx5-v1-0-1e7d5e5a9f34@microchip.com/

Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
====================

Link: https://patch.msgid.link/20240905-fdma-lan966x-v1-0-e083f8620165@microchip.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+168 -309
+1
drivers/net/ethernet/microchip/lan966x/Kconfig
··· 8 8 select PHYLINK 9 9 select PAGE_POOL 10 10 select VCAP 11 + select FDMA 11 12 help 12 13 This driver supports the Lan966x network switch device. 13 14
+1
drivers/net/ethernet/microchip/lan966x/Makefile
··· 20 20 21 21 # Provide include files 22 22 ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap 23 + ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma
+163 -254
drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
··· 6 6 7 7 #include "lan966x_main.h" 8 8 9 + static int lan966x_fdma_rx_dataptr_cb(struct fdma *fdma, int dcb, int db, 10 + u64 *dataptr) 11 + { 12 + struct lan966x *lan966x = (struct lan966x *)fdma->priv; 13 + struct lan966x_rx *rx = &lan966x->rx; 14 + struct page *page; 15 + 16 + page = page_pool_dev_alloc_pages(rx->page_pool); 17 + if (unlikely(!page)) 18 + return -ENOMEM; 19 + 20 + rx->page[dcb][db] = page; 21 + *dataptr = page_pool_get_dma_addr(page) + XDP_PACKET_HEADROOM; 22 + 23 + return 0; 24 + } 25 + 26 + static int lan966x_fdma_tx_dataptr_cb(struct fdma *fdma, int dcb, int db, 27 + u64 *dataptr) 28 + { 29 + struct lan966x *lan966x = (struct lan966x *)fdma->priv; 30 + 31 + *dataptr = lan966x->tx.dcbs_buf[dcb].dma_addr; 32 + 33 + return 0; 34 + } 35 + 36 + static int lan966x_fdma_xdp_tx_dataptr_cb(struct fdma *fdma, int dcb, int db, 37 + u64 *dataptr) 38 + { 39 + struct lan966x *lan966x = (struct lan966x *)fdma->priv; 40 + 41 + *dataptr = lan966x->tx.dcbs_buf[dcb].dma_addr + XDP_PACKET_HEADROOM; 42 + 43 + return 0; 44 + } 45 + 9 46 static int lan966x_fdma_channel_active(struct lan966x *lan966x) 10 47 { 11 48 return lan_rd(lan966x, FDMA_CH_ACTIVE); 12 49 } 13 50 14 - static struct page *lan966x_fdma_rx_alloc_page(struct lan966x_rx *rx, 15 - struct lan966x_db *db) 16 - { 17 - struct page *page; 18 - 19 - page = page_pool_dev_alloc_pages(rx->page_pool); 20 - if (unlikely(!page)) 21 - return NULL; 22 - 23 - db->dataptr = page_pool_get_dma_addr(page) + XDP_PACKET_HEADROOM; 24 - 25 - return page; 26 - } 27 - 28 51 static void lan966x_fdma_rx_free_pages(struct lan966x_rx *rx) 29 52 { 53 + struct fdma *fdma = &rx->fdma; 30 54 int i, j; 31 55 32 - for (i = 0; i < FDMA_DCB_MAX; ++i) { 33 - for (j = 0; j < FDMA_RX_DCB_MAX_DBS; ++j) 56 + for (i = 0; i < fdma->n_dcbs; ++i) { 57 + for (j = 0; j < fdma->n_dbs; ++j) 34 58 page_pool_put_full_page(rx->page_pool, 35 59 rx->page[i][j], false); 36 60 } ··· 62 38 63 39 static void lan966x_fdma_rx_free_page(struct lan966x_rx *rx) 64 40 { 41 + struct fdma *fdma = &rx->fdma; 65 42 struct page *page; 66 43 67 - page = rx->page[rx->dcb_index][rx->db_index]; 44 + page = rx->page[fdma->dcb_index][fdma->db_index]; 68 45 if (unlikely(!page)) 69 46 return; 70 47 71 48 page_pool_recycle_direct(rx->page_pool, page); 72 - } 73 - 74 - static void lan966x_fdma_rx_add_dcb(struct lan966x_rx *rx, 75 - struct lan966x_rx_dcb *dcb, 76 - u64 nextptr) 77 - { 78 - struct lan966x_db *db; 79 - int i; 80 - 81 - for (i = 0; i < FDMA_RX_DCB_MAX_DBS; ++i) { 82 - db = &dcb->db[i]; 83 - db->status = FDMA_DCB_STATUS_INTR; 84 - } 85 - 86 - dcb->nextptr = FDMA_DCB_INVALID_DATA; 87 - dcb->info = FDMA_DCB_INFO_DATAL(PAGE_SIZE << rx->page_order); 88 - 89 - rx->last_entry->nextptr = nextptr; 90 - rx->last_entry = dcb; 91 49 } 92 50 93 51 static int lan966x_fdma_rx_alloc_page_pool(struct lan966x_rx *rx) ··· 78 72 struct page_pool_params pp_params = { 79 73 .order = rx->page_order, 80 74 .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, 81 - .pool_size = FDMA_DCB_MAX, 75 + .pool_size = rx->fdma.n_dcbs, 82 76 .nid = NUMA_NO_NODE, 83 77 .dev = lan966x->dev, 84 78 .dma_dir = DMA_FROM_DEVICE, ··· 110 104 static int lan966x_fdma_rx_alloc(struct lan966x_rx *rx) 111 105 { 112 106 struct lan966x *lan966x = rx->lan966x; 113 - struct lan966x_rx_dcb *dcb; 114 - struct lan966x_db *db; 115 - struct page *page; 116 - int i, j; 117 - int size; 107 + struct fdma *fdma = &rx->fdma; 108 + int err; 118 109 119 110 if (lan966x_fdma_rx_alloc_page_pool(rx)) 120 111 return PTR_ERR(rx->page_pool); 121 112 122 - /* calculate how many pages are needed to allocate the dcbs */ 123 - size = sizeof(struct lan966x_rx_dcb) * FDMA_DCB_MAX; 124 - size = ALIGN(size, PAGE_SIZE); 113 + err = fdma_alloc_coherent(lan966x->dev, fdma); 114 + if (err) 115 + return err; 125 116 126 - rx->dcbs = dma_alloc_coherent(lan966x->dev, size, &rx->dma, GFP_KERNEL); 127 - if (!rx->dcbs) 128 - return -ENOMEM; 129 - 130 - rx->last_entry = rx->dcbs; 131 - rx->db_index = 0; 132 - rx->dcb_index = 0; 133 - 134 - /* Now for each dcb allocate the dbs */ 135 - for (i = 0; i < FDMA_DCB_MAX; ++i) { 136 - dcb = &rx->dcbs[i]; 137 - dcb->info = 0; 138 - 139 - /* For each db allocate a page and map it to the DB dataptr. */ 140 - for (j = 0; j < FDMA_RX_DCB_MAX_DBS; ++j) { 141 - db = &dcb->db[j]; 142 - page = lan966x_fdma_rx_alloc_page(rx, db); 143 - if (!page) 144 - return -ENOMEM; 145 - 146 - db->status = 0; 147 - rx->page[i][j] = page; 148 - } 149 - 150 - lan966x_fdma_rx_add_dcb(rx, dcb, rx->dma + sizeof(*dcb) * i); 151 - } 117 + fdma_dcbs_init(fdma, FDMA_DCB_INFO_DATAL(fdma->db_size), 118 + FDMA_DCB_STATUS_INTR); 152 119 153 120 return 0; 154 - } 155 - 156 - static void lan966x_fdma_rx_advance_dcb(struct lan966x_rx *rx) 157 - { 158 - rx->dcb_index++; 159 - rx->dcb_index &= FDMA_DCB_MAX - 1; 160 - } 161 - 162 - static void lan966x_fdma_rx_free(struct lan966x_rx *rx) 163 - { 164 - struct lan966x *lan966x = rx->lan966x; 165 - u32 size; 166 - 167 - /* Now it is possible to do the cleanup of dcb */ 168 - size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; 169 - size = ALIGN(size, PAGE_SIZE); 170 - dma_free_coherent(lan966x->dev, size, rx->dcbs, rx->dma); 171 121 } 172 122 173 123 static void lan966x_fdma_rx_start(struct lan966x_rx *rx) 174 124 { 175 125 struct lan966x *lan966x = rx->lan966x; 126 + struct fdma *fdma = &rx->fdma; 176 127 u32 mask; 177 128 178 129 /* When activating a channel, first is required to write the first DCB 179 130 * address and then to activate it 180 131 */ 181 - lan_wr(lower_32_bits((u64)rx->dma), lan966x, 182 - FDMA_DCB_LLP(rx->channel_id)); 183 - lan_wr(upper_32_bits((u64)rx->dma), lan966x, 184 - FDMA_DCB_LLP1(rx->channel_id)); 132 + lan_wr(lower_32_bits((u64)fdma->dma), lan966x, 133 + FDMA_DCB_LLP(fdma->channel_id)); 134 + lan_wr(upper_32_bits((u64)fdma->dma), lan966x, 135 + FDMA_DCB_LLP1(fdma->channel_id)); 185 136 186 - lan_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_RX_DCB_MAX_DBS) | 137 + lan_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(fdma->n_dbs) | 187 138 FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) | 188 139 FDMA_CH_CFG_CH_INJ_PORT_SET(0) | 189 140 FDMA_CH_CFG_CH_MEM_SET(1), 190 - lan966x, FDMA_CH_CFG(rx->channel_id)); 141 + lan966x, FDMA_CH_CFG(fdma->channel_id)); 191 142 192 143 /* Start fdma */ 193 144 lan_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(0), ··· 154 191 /* Enable interrupts */ 155 192 mask = lan_rd(lan966x, FDMA_INTR_DB_ENA); 156 193 mask = FDMA_INTR_DB_ENA_INTR_DB_ENA_GET(mask); 157 - mask |= BIT(rx->channel_id); 194 + mask |= BIT(fdma->channel_id); 158 195 lan_rmw(FDMA_INTR_DB_ENA_INTR_DB_ENA_SET(mask), 159 196 FDMA_INTR_DB_ENA_INTR_DB_ENA, 160 197 lan966x, FDMA_INTR_DB_ENA); 161 198 162 199 /* Activate the channel */ 163 - lan_rmw(FDMA_CH_ACTIVATE_CH_ACTIVATE_SET(BIT(rx->channel_id)), 200 + lan_rmw(FDMA_CH_ACTIVATE_CH_ACTIVATE_SET(BIT(fdma->channel_id)), 164 201 FDMA_CH_ACTIVATE_CH_ACTIVATE, 165 202 lan966x, FDMA_CH_ACTIVATE); 166 203 } ··· 168 205 static void lan966x_fdma_rx_disable(struct lan966x_rx *rx) 169 206 { 170 207 struct lan966x *lan966x = rx->lan966x; 208 + struct fdma *fdma = &rx->fdma; 171 209 u32 val; 172 210 173 211 /* Disable the channel */ 174 - lan_rmw(FDMA_CH_DISABLE_CH_DISABLE_SET(BIT(rx->channel_id)), 212 + lan_rmw(FDMA_CH_DISABLE_CH_DISABLE_SET(BIT(fdma->channel_id)), 175 213 FDMA_CH_DISABLE_CH_DISABLE, 176 214 lan966x, FDMA_CH_DISABLE); 177 215 178 216 readx_poll_timeout_atomic(lan966x_fdma_channel_active, lan966x, 179 - val, !(val & BIT(rx->channel_id)), 217 + val, !(val & BIT(fdma->channel_id)), 180 218 READL_SLEEP_US, READL_TIMEOUT_US); 181 219 182 - lan_rmw(FDMA_CH_DB_DISCARD_DB_DISCARD_SET(BIT(rx->channel_id)), 220 + lan_rmw(FDMA_CH_DB_DISCARD_DB_DISCARD_SET(BIT(fdma->channel_id)), 183 221 FDMA_CH_DB_DISCARD_DB_DISCARD, 184 222 lan966x, FDMA_CH_DB_DISCARD); 185 223 } ··· 189 225 { 190 226 struct lan966x *lan966x = rx->lan966x; 191 227 192 - lan_rmw(FDMA_CH_RELOAD_CH_RELOAD_SET(BIT(rx->channel_id)), 228 + lan_rmw(FDMA_CH_RELOAD_CH_RELOAD_SET(BIT(rx->fdma.channel_id)), 193 229 FDMA_CH_RELOAD_CH_RELOAD, 194 230 lan966x, FDMA_CH_RELOAD); 195 - } 196 - 197 - static void lan966x_fdma_tx_add_dcb(struct lan966x_tx *tx, 198 - struct lan966x_tx_dcb *dcb) 199 - { 200 - dcb->nextptr = FDMA_DCB_INVALID_DATA; 201 - dcb->info = 0; 202 231 } 203 232 204 233 static int lan966x_fdma_tx_alloc(struct lan966x_tx *tx) 205 234 { 206 235 struct lan966x *lan966x = tx->lan966x; 207 - struct lan966x_tx_dcb *dcb; 208 - struct lan966x_db *db; 209 - int size; 210 - int i, j; 236 + struct fdma *fdma = &tx->fdma; 237 + int err; 211 238 212 - tx->dcbs_buf = kcalloc(FDMA_DCB_MAX, sizeof(struct lan966x_tx_dcb_buf), 239 + tx->dcbs_buf = kcalloc(fdma->n_dcbs, sizeof(struct lan966x_tx_dcb_buf), 213 240 GFP_KERNEL); 214 241 if (!tx->dcbs_buf) 215 242 return -ENOMEM; 216 243 217 - /* calculate how many pages are needed to allocate the dcbs */ 218 - size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; 219 - size = ALIGN(size, PAGE_SIZE); 220 - tx->dcbs = dma_alloc_coherent(lan966x->dev, size, &tx->dma, GFP_KERNEL); 221 - if (!tx->dcbs) 244 + err = fdma_alloc_coherent(lan966x->dev, fdma); 245 + if (err) 222 246 goto out; 223 247 224 - /* Now for each dcb allocate the db */ 225 - for (i = 0; i < FDMA_DCB_MAX; ++i) { 226 - dcb = &tx->dcbs[i]; 227 - 228 - for (j = 0; j < FDMA_TX_DCB_MAX_DBS; ++j) { 229 - db = &dcb->db[j]; 230 - db->dataptr = 0; 231 - db->status = 0; 232 - } 233 - 234 - lan966x_fdma_tx_add_dcb(tx, dcb); 235 - } 248 + fdma_dcbs_init(fdma, 0, 0); 236 249 237 250 return 0; 238 251 ··· 221 280 static void lan966x_fdma_tx_free(struct lan966x_tx *tx) 222 281 { 223 282 struct lan966x *lan966x = tx->lan966x; 224 - int size; 225 283 226 284 kfree(tx->dcbs_buf); 227 - 228 - size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; 229 - size = ALIGN(size, PAGE_SIZE); 230 - dma_free_coherent(lan966x->dev, size, tx->dcbs, tx->dma); 285 + fdma_free_coherent(lan966x->dev, &tx->fdma); 231 286 } 232 287 233 288 static void lan966x_fdma_tx_activate(struct lan966x_tx *tx) 234 289 { 235 290 struct lan966x *lan966x = tx->lan966x; 291 + struct fdma *fdma = &tx->fdma; 236 292 u32 mask; 237 293 238 294 /* When activating a channel, first is required to write the first DCB 239 295 * address and then to activate it 240 296 */ 241 - lan_wr(lower_32_bits((u64)tx->dma), lan966x, 242 - FDMA_DCB_LLP(tx->channel_id)); 243 - lan_wr(upper_32_bits((u64)tx->dma), lan966x, 244 - FDMA_DCB_LLP1(tx->channel_id)); 297 + lan_wr(lower_32_bits((u64)fdma->dma), lan966x, 298 + FDMA_DCB_LLP(fdma->channel_id)); 299 + lan_wr(upper_32_bits((u64)fdma->dma), lan966x, 300 + FDMA_DCB_LLP1(fdma->channel_id)); 245 301 246 - lan_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_TX_DCB_MAX_DBS) | 302 + lan_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(fdma->n_dbs) | 247 303 FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) | 248 304 FDMA_CH_CFG_CH_INJ_PORT_SET(0) | 249 305 FDMA_CH_CFG_CH_MEM_SET(1), 250 - lan966x, FDMA_CH_CFG(tx->channel_id)); 306 + lan966x, FDMA_CH_CFG(fdma->channel_id)); 251 307 252 308 /* Start fdma */ 253 309 lan_rmw(FDMA_PORT_CTRL_INJ_STOP_SET(0), ··· 254 316 /* Enable interrupts */ 255 317 mask = lan_rd(lan966x, FDMA_INTR_DB_ENA); 256 318 mask = FDMA_INTR_DB_ENA_INTR_DB_ENA_GET(mask); 257 - mask |= BIT(tx->channel_id); 319 + mask |= BIT(fdma->channel_id); 258 320 lan_rmw(FDMA_INTR_DB_ENA_INTR_DB_ENA_SET(mask), 259 321 FDMA_INTR_DB_ENA_INTR_DB_ENA, 260 322 lan966x, FDMA_INTR_DB_ENA); 261 323 262 324 /* Activate the channel */ 263 - lan_rmw(FDMA_CH_ACTIVATE_CH_ACTIVATE_SET(BIT(tx->channel_id)), 325 + lan_rmw(FDMA_CH_ACTIVATE_CH_ACTIVATE_SET(BIT(fdma->channel_id)), 264 326 FDMA_CH_ACTIVATE_CH_ACTIVATE, 265 327 lan966x, FDMA_CH_ACTIVATE); 266 328 } ··· 268 330 static void lan966x_fdma_tx_disable(struct lan966x_tx *tx) 269 331 { 270 332 struct lan966x *lan966x = tx->lan966x; 333 + struct fdma *fdma = &tx->fdma; 271 334 u32 val; 272 335 273 336 /* Disable the channel */ 274 - lan_rmw(FDMA_CH_DISABLE_CH_DISABLE_SET(BIT(tx->channel_id)), 337 + lan_rmw(FDMA_CH_DISABLE_CH_DISABLE_SET(BIT(fdma->channel_id)), 275 338 FDMA_CH_DISABLE_CH_DISABLE, 276 339 lan966x, FDMA_CH_DISABLE); 277 340 278 341 readx_poll_timeout_atomic(lan966x_fdma_channel_active, lan966x, 279 - val, !(val & BIT(tx->channel_id)), 342 + val, !(val & BIT(fdma->channel_id)), 280 343 READL_SLEEP_US, READL_TIMEOUT_US); 281 344 282 - lan_rmw(FDMA_CH_DB_DISCARD_DB_DISCARD_SET(BIT(tx->channel_id)), 345 + lan_rmw(FDMA_CH_DB_DISCARD_DB_DISCARD_SET(BIT(fdma->channel_id)), 283 346 FDMA_CH_DB_DISCARD_DB_DISCARD, 284 347 lan966x, FDMA_CH_DB_DISCARD); 285 348 286 349 tx->activated = false; 287 - tx->last_in_use = -1; 288 350 } 289 351 290 352 static void lan966x_fdma_tx_reload(struct lan966x_tx *tx) ··· 292 354 struct lan966x *lan966x = tx->lan966x; 293 355 294 356 /* Write the registers to reload the channel */ 295 - lan_rmw(FDMA_CH_RELOAD_CH_RELOAD_SET(BIT(tx->channel_id)), 357 + lan_rmw(FDMA_CH_RELOAD_CH_RELOAD_SET(BIT(tx->fdma.channel_id)), 296 358 FDMA_CH_RELOAD_CH_RELOAD, 297 359 lan966x, FDMA_CH_RELOAD); 298 360 } ··· 331 393 struct lan966x_tx *tx = &lan966x->tx; 332 394 struct lan966x_rx *rx = &lan966x->rx; 333 395 struct lan966x_tx_dcb_buf *dcb_buf; 396 + struct fdma *fdma = &tx->fdma; 334 397 struct xdp_frame_bulk bq; 335 - struct lan966x_db *db; 336 398 unsigned long flags; 337 399 bool clear = false; 400 + struct fdma_db *db; 338 401 int i; 339 402 340 403 xdp_frame_bulk_init(&bq); 341 404 342 405 spin_lock_irqsave(&lan966x->tx_lock, flags); 343 - for (i = 0; i < FDMA_DCB_MAX; ++i) { 406 + for (i = 0; i < fdma->n_dcbs; ++i) { 344 407 dcb_buf = &tx->dcbs_buf[i]; 345 408 346 409 if (!dcb_buf->used) 347 410 continue; 348 411 349 - db = &tx->dcbs[i].db[0]; 350 - if (!(db->status & FDMA_DCB_STATUS_DONE)) 412 + db = fdma_db_get(fdma, i, 0); 413 + if (!fdma_db_is_done(db)) 351 414 continue; 352 415 353 416 dcb_buf->dev->stats.tx_packets++; ··· 388 449 spin_unlock_irqrestore(&lan966x->tx_lock, flags); 389 450 } 390 451 391 - static bool lan966x_fdma_rx_more_frames(struct lan966x_rx *rx) 392 - { 393 - struct lan966x_db *db; 394 - 395 - /* Check if there is any data */ 396 - db = &rx->dcbs[rx->dcb_index].db[rx->db_index]; 397 - if (unlikely(!(db->status & FDMA_DCB_STATUS_DONE))) 398 - return false; 399 - 400 - return true; 401 - } 402 - 403 452 static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port) 404 453 { 405 454 struct lan966x *lan966x = rx->lan966x; 455 + struct fdma *fdma = &rx->fdma; 406 456 struct lan966x_port *port; 407 - struct lan966x_db *db; 457 + struct fdma_db *db; 408 458 struct page *page; 409 459 410 - db = &rx->dcbs[rx->dcb_index].db[rx->db_index]; 411 - page = rx->page[rx->dcb_index][rx->db_index]; 460 + db = fdma_db_next_get(fdma); 461 + page = rx->page[fdma->dcb_index][fdma->db_index]; 412 462 if (unlikely(!page)) 413 463 return FDMA_ERROR; 414 464 ··· 422 494 u64 src_port) 423 495 { 424 496 struct lan966x *lan966x = rx->lan966x; 425 - struct lan966x_db *db; 497 + struct fdma *fdma = &rx->fdma; 426 498 struct sk_buff *skb; 499 + struct fdma_db *db; 427 500 struct page *page; 428 501 u64 timestamp; 429 502 430 503 /* Get the received frame and unmap it */ 431 - db = &rx->dcbs[rx->dcb_index].db[rx->db_index]; 432 - page = rx->page[rx->dcb_index][rx->db_index]; 504 + db = fdma_db_next_get(fdma); 505 + page = rx->page[fdma->dcb_index][fdma->db_index]; 433 506 434 - skb = build_skb(page_address(page), PAGE_SIZE << rx->page_order); 507 + skb = build_skb(page_address(page), fdma->db_size); 435 508 if (unlikely(!skb)) 436 509 goto free_page; 437 510 ··· 475 546 { 476 547 struct lan966x *lan966x = container_of(napi, struct lan966x, napi); 477 548 struct lan966x_rx *rx = &lan966x->rx; 478 - int dcb_reload = rx->dcb_index; 479 - struct lan966x_rx_dcb *old_dcb; 480 - struct lan966x_db *db; 549 + int old_dcb, dcb_reload, counter = 0; 550 + struct fdma *fdma = &rx->fdma; 481 551 bool redirect = false; 482 552 struct sk_buff *skb; 483 - struct page *page; 484 - int counter = 0; 485 553 u64 src_port; 486 - u64 nextptr; 554 + 555 + dcb_reload = fdma->dcb_index; 487 556 488 557 lan966x_fdma_tx_clear_buf(lan966x, weight); 489 558 490 559 /* Get all received skb */ 491 560 while (counter < weight) { 492 - if (!lan966x_fdma_rx_more_frames(rx)) 561 + if (!fdma_has_frames(fdma)) 493 562 break; 494 563 495 564 counter++; ··· 497 570 break; 498 571 case FDMA_ERROR: 499 572 lan966x_fdma_rx_free_page(rx); 500 - lan966x_fdma_rx_advance_dcb(rx); 573 + fdma_dcb_advance(fdma); 501 574 goto allocate_new; 502 575 case FDMA_REDIRECT: 503 576 redirect = true; 504 577 fallthrough; 505 578 case FDMA_TX: 506 - lan966x_fdma_rx_advance_dcb(rx); 579 + fdma_dcb_advance(fdma); 507 580 continue; 508 581 case FDMA_DROP: 509 582 lan966x_fdma_rx_free_page(rx); 510 - lan966x_fdma_rx_advance_dcb(rx); 583 + fdma_dcb_advance(fdma); 511 584 continue; 512 585 } 513 586 514 587 skb = lan966x_fdma_rx_get_frame(rx, src_port); 515 - lan966x_fdma_rx_advance_dcb(rx); 588 + fdma_dcb_advance(fdma); 516 589 if (!skb) 517 590 goto allocate_new; 518 591 ··· 521 594 522 595 allocate_new: 523 596 /* Allocate new pages and map them */ 524 - while (dcb_reload != rx->dcb_index) { 525 - db = &rx->dcbs[dcb_reload].db[rx->db_index]; 526 - page = lan966x_fdma_rx_alloc_page(rx, db); 527 - if (unlikely(!page)) 528 - break; 529 - rx->page[dcb_reload][rx->db_index] = page; 530 - 531 - old_dcb = &rx->dcbs[dcb_reload]; 597 + while (dcb_reload != fdma->dcb_index) { 598 + old_dcb = dcb_reload; 532 599 dcb_reload++; 533 - dcb_reload &= FDMA_DCB_MAX - 1; 600 + dcb_reload &= fdma->n_dcbs - 1; 534 601 535 - nextptr = rx->dma + ((unsigned long)old_dcb - 536 - (unsigned long)rx->dcbs); 537 - lan966x_fdma_rx_add_dcb(rx, old_dcb, nextptr); 602 + fdma_dcb_add(fdma, old_dcb, FDMA_DCB_INFO_DATAL(fdma->db_size), 603 + FDMA_DCB_STATUS_INTR); 604 + 538 605 lan966x_fdma_rx_reload(rx); 539 606 } 540 607 ··· 571 650 static int lan966x_fdma_get_next_dcb(struct lan966x_tx *tx) 572 651 { 573 652 struct lan966x_tx_dcb_buf *dcb_buf; 653 + struct fdma *fdma = &tx->fdma; 574 654 int i; 575 655 576 - for (i = 0; i < FDMA_DCB_MAX; ++i) { 656 + for (i = 0; i < fdma->n_dcbs; ++i) { 577 657 dcb_buf = &tx->dcbs_buf[i]; 578 - if (!dcb_buf->used && i != tx->last_in_use) 658 + if (!dcb_buf->used && 659 + !fdma_is_last(&tx->fdma, &tx->fdma.dcbs[i])) 579 660 return i; 580 661 } 581 662 582 663 return -1; 583 664 } 584 665 585 - static void lan966x_fdma_tx_setup_dcb(struct lan966x_tx *tx, 586 - int next_to_use, int len, 587 - dma_addr_t dma_addr) 588 - { 589 - struct lan966x_tx_dcb *next_dcb; 590 - struct lan966x_db *next_db; 591 - 592 - next_dcb = &tx->dcbs[next_to_use]; 593 - next_dcb->nextptr = FDMA_DCB_INVALID_DATA; 594 - 595 - next_db = &next_dcb->db[0]; 596 - next_db->dataptr = dma_addr; 597 - next_db->status = FDMA_DCB_STATUS_SOF | 598 - FDMA_DCB_STATUS_EOF | 599 - FDMA_DCB_STATUS_INTR | 600 - FDMA_DCB_STATUS_BLOCKO(0) | 601 - FDMA_DCB_STATUS_BLOCKL(len); 602 - } 603 - 604 - static void lan966x_fdma_tx_start(struct lan966x_tx *tx, int next_to_use) 666 + static void lan966x_fdma_tx_start(struct lan966x_tx *tx) 605 667 { 606 668 struct lan966x *lan966x = tx->lan966x; 607 - struct lan966x_tx_dcb *dcb; 608 669 609 670 if (likely(lan966x->tx.activated)) { 610 - /* Connect current dcb to the next db */ 611 - dcb = &tx->dcbs[tx->last_in_use]; 612 - dcb->nextptr = tx->dma + (next_to_use * 613 - sizeof(struct lan966x_tx_dcb)); 614 - 615 671 lan966x_fdma_tx_reload(tx); 616 672 } else { 617 673 /* Because it is first time, then just activate */ 618 674 lan966x->tx.activated = true; 619 675 lan966x_fdma_tx_activate(tx); 620 676 } 621 - 622 - /* Move to next dcb because this last in use */ 623 - tx->last_in_use = next_to_use; 624 677 } 625 678 626 679 int lan966x_fdma_xmit_xdpf(struct lan966x_port *port, void *ptr, u32 len) ··· 647 752 648 753 next_dcb_buf->data.xdpf = xdpf; 649 754 next_dcb_buf->len = xdpf->len + IFH_LEN_BYTES; 650 - 651 - /* Setup next dcb */ 652 - lan966x_fdma_tx_setup_dcb(tx, next_to_use, 653 - xdpf->len + IFH_LEN_BYTES, 654 - dma_addr); 655 755 } else { 656 756 page = ptr; 657 757 ··· 663 773 664 774 next_dcb_buf->data.page = page; 665 775 next_dcb_buf->len = len + IFH_LEN_BYTES; 666 - 667 - /* Setup next dcb */ 668 - lan966x_fdma_tx_setup_dcb(tx, next_to_use, 669 - len + IFH_LEN_BYTES, 670 - dma_addr + XDP_PACKET_HEADROOM); 671 776 } 672 777 673 778 /* Fill up the buffer */ ··· 673 788 next_dcb_buf->ptp = false; 674 789 next_dcb_buf->dev = port->dev; 675 790 791 + __fdma_dcb_add(&tx->fdma, 792 + next_to_use, 793 + 0, 794 + FDMA_DCB_STATUS_INTR | 795 + FDMA_DCB_STATUS_SOF | 796 + FDMA_DCB_STATUS_EOF | 797 + FDMA_DCB_STATUS_BLOCKO(0) | 798 + FDMA_DCB_STATUS_BLOCKL(next_dcb_buf->len), 799 + &fdma_nextptr_cb, 800 + &lan966x_fdma_xdp_tx_dataptr_cb); 801 + 676 802 /* Start the transmission */ 677 - lan966x_fdma_tx_start(tx, next_to_use); 803 + lan966x_fdma_tx_start(tx); 678 804 679 805 out: 680 806 spin_unlock(&lan966x->tx_lock); ··· 743 847 goto release; 744 848 } 745 849 746 - /* Setup next dcb */ 747 - lan966x_fdma_tx_setup_dcb(tx, next_to_use, skb->len, dma_addr); 748 - 749 850 /* Fill up the buffer */ 750 851 next_dcb_buf = &tx->dcbs_buf[next_to_use]; 751 852 next_dcb_buf->use_skb = true; ··· 754 861 next_dcb_buf->ptp = false; 755 862 next_dcb_buf->dev = dev; 756 863 864 + fdma_dcb_add(&tx->fdma, 865 + next_to_use, 866 + 0, 867 + FDMA_DCB_STATUS_INTR | 868 + FDMA_DCB_STATUS_SOF | 869 + FDMA_DCB_STATUS_EOF | 870 + FDMA_DCB_STATUS_BLOCKO(0) | 871 + FDMA_DCB_STATUS_BLOCKL(skb->len)); 872 + 757 873 if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && 758 874 LAN966X_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP) 759 875 next_dcb_buf->ptp = true; 760 876 761 877 /* Start the transmission */ 762 - lan966x_fdma_tx_start(tx, next_to_use); 878 + lan966x_fdma_tx_start(tx); 763 879 764 880 return NETDEV_TX_OK; 765 881 ··· 810 908 static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu) 811 909 { 812 910 struct page_pool *page_pool; 813 - dma_addr_t rx_dma; 814 - void *rx_dcbs; 815 - u32 size; 911 + struct fdma fdma_rx_old; 816 912 int err; 817 913 818 914 /* Store these for later to free them */ 819 - rx_dma = lan966x->rx.dma; 820 - rx_dcbs = lan966x->rx.dcbs; 915 + memcpy(&fdma_rx_old, &lan966x->rx.fdma, sizeof(struct fdma)); 821 916 page_pool = lan966x->rx.page_pool; 822 917 823 918 napi_synchronize(&lan966x->napi); ··· 830 931 goto restore; 831 932 lan966x_fdma_rx_start(&lan966x->rx); 832 933 833 - size = sizeof(struct lan966x_rx_dcb) * FDMA_DCB_MAX; 834 - size = ALIGN(size, PAGE_SIZE); 835 - dma_free_coherent(lan966x->dev, size, rx_dcbs, rx_dma); 934 + fdma_free_coherent(lan966x->dev, &fdma_rx_old); 836 935 837 936 page_pool_destroy(page_pool); 838 937 ··· 840 943 return err; 841 944 restore: 842 945 lan966x->rx.page_pool = page_pool; 843 - lan966x->rx.dma = rx_dma; 844 - lan966x->rx.dcbs = rx_dcbs; 946 + memcpy(&lan966x->rx.fdma, &fdma_rx_old, sizeof(struct fdma)); 845 947 lan966x_fdma_rx_start(&lan966x->rx); 846 948 847 949 return err; ··· 930 1034 return 0; 931 1035 932 1036 lan966x->rx.lan966x = lan966x; 933 - lan966x->rx.channel_id = FDMA_XTR_CHANNEL; 1037 + lan966x->rx.fdma.channel_id = FDMA_XTR_CHANNEL; 1038 + lan966x->rx.fdma.n_dcbs = FDMA_DCB_MAX; 1039 + lan966x->rx.fdma.n_dbs = FDMA_RX_DCB_MAX_DBS; 1040 + lan966x->rx.fdma.priv = lan966x; 1041 + lan966x->rx.fdma.size = fdma_get_size(&lan966x->rx.fdma); 1042 + lan966x->rx.fdma.db_size = PAGE_SIZE << lan966x->rx.page_order; 1043 + lan966x->rx.fdma.ops.nextptr_cb = &fdma_nextptr_cb; 1044 + lan966x->rx.fdma.ops.dataptr_cb = &lan966x_fdma_rx_dataptr_cb; 934 1045 lan966x->rx.max_mtu = lan966x_fdma_get_max_frame(lan966x); 935 1046 lan966x->tx.lan966x = lan966x; 936 - lan966x->tx.channel_id = FDMA_INJ_CHANNEL; 937 - lan966x->tx.last_in_use = -1; 1047 + lan966x->tx.fdma.channel_id = FDMA_INJ_CHANNEL; 1048 + lan966x->tx.fdma.n_dcbs = FDMA_DCB_MAX; 1049 + lan966x->tx.fdma.n_dbs = FDMA_TX_DCB_MAX_DBS; 1050 + lan966x->tx.fdma.priv = lan966x; 1051 + lan966x->tx.fdma.size = fdma_get_size(&lan966x->tx.fdma); 1052 + lan966x->tx.fdma.db_size = PAGE_SIZE << lan966x->rx.page_order; 1053 + lan966x->tx.fdma.ops.nextptr_cb = &fdma_nextptr_cb; 1054 + lan966x->tx.fdma.ops.dataptr_cb = &lan966x_fdma_tx_dataptr_cb; 938 1055 939 1056 err = lan966x_fdma_rx_alloc(&lan966x->rx); 940 1057 if (err) ··· 955 1046 956 1047 err = lan966x_fdma_tx_alloc(&lan966x->tx); 957 1048 if (err) { 958 - lan966x_fdma_rx_free(&lan966x->rx); 1049 + fdma_free_coherent(lan966x->dev, &lan966x->rx.fdma); 959 1050 return err; 960 1051 } 961 1052 ··· 976 1067 napi_disable(&lan966x->napi); 977 1068 978 1069 lan966x_fdma_rx_free_pages(&lan966x->rx); 979 - lan966x_fdma_rx_free(&lan966x->rx); 1070 + fdma_free_coherent(lan966x->dev, &lan966x->rx.fdma); 980 1071 page_pool_destroy(lan966x->rx.page_pool); 981 1072 lan966x_fdma_tx_free(&lan966x->tx); 982 1073 }
+3 -55
drivers/net/ethernet/microchip/lan966x/lan966x_main.h
··· 16 16 #include <net/switchdev.h> 17 17 #include <net/xdp.h> 18 18 19 + #include <fdma_api.h> 19 20 #include <vcap_api.h> 20 21 #include <vcap_api_client.h> 21 22 ··· 77 76 78 77 #define FDMA_RX_DCB_MAX_DBS 1 79 78 #define FDMA_TX_DCB_MAX_DBS 1 80 - #define FDMA_DCB_INFO_DATAL(x) ((x) & GENMASK(15, 0)) 81 - 82 - #define FDMA_DCB_STATUS_BLOCKL(x) ((x) & GENMASK(15, 0)) 83 - #define FDMA_DCB_STATUS_SOF BIT(16) 84 - #define FDMA_DCB_STATUS_EOF BIT(17) 85 - #define FDMA_DCB_STATUS_INTR BIT(18) 86 - #define FDMA_DCB_STATUS_DONE BIT(19) 87 - #define FDMA_DCB_STATUS_BLOCKO(x) (((x) << 20) & GENMASK(31, 20)) 88 - #define FDMA_DCB_INVALID_DATA 0x1 89 79 90 80 #define FDMA_XTR_CHANNEL 6 91 81 #define FDMA_INJ_CHANNEL 0 ··· 191 199 192 200 struct lan966x_port; 193 201 194 - struct lan966x_db { 195 - u64 dataptr; 196 - u64 status; 197 - }; 198 - 199 - struct lan966x_rx_dcb { 200 - u64 nextptr; 201 - u64 info; 202 - struct lan966x_db db[FDMA_RX_DCB_MAX_DBS]; 203 - }; 204 - 205 - struct lan966x_tx_dcb { 206 - u64 nextptr; 207 - u64 info; 208 - struct lan966x_db db[FDMA_TX_DCB_MAX_DBS]; 209 - }; 210 - 211 202 struct lan966x_rx { 212 203 struct lan966x *lan966x; 213 204 214 - /* Pointer to the array of hardware dcbs. */ 215 - struct lan966x_rx_dcb *dcbs; 216 - 217 - /* Pointer to the last address in the dcbs. */ 218 - struct lan966x_rx_dcb *last_entry; 205 + struct fdma fdma; 219 206 220 207 /* For each DB, there is a page */ 221 208 struct page *page[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS]; 222 - 223 - /* Represents the db_index, it can have a value between 0 and 224 - * FDMA_RX_DCB_MAX_DBS, once it reaches the value of FDMA_RX_DCB_MAX_DBS 225 - * it means that the DCB can be reused. 226 - */ 227 - int db_index; 228 - 229 - /* Represents the index in the dcbs. It has a value between 0 and 230 - * FDMA_DCB_MAX 231 - */ 232 - int dcb_index; 233 - 234 - /* Represents the dma address to the dcbs array */ 235 - dma_addr_t dma; 236 209 237 210 /* Represents the page order that is used to allocate the pages for the 238 211 * RX buffers. This value is calculated based on max MTU of the devices. ··· 208 251 * includes the IFH + VLAN tags + frame + skb_shared_info 209 252 */ 210 253 u32 max_mtu; 211 - 212 - u8 channel_id; 213 254 214 255 struct page_pool *page_pool; 215 256 }; ··· 230 275 struct lan966x_tx { 231 276 struct lan966x *lan966x; 232 277 233 - /* Pointer to the dcb list */ 234 - struct lan966x_tx_dcb *dcbs; 235 - u16 last_in_use; 236 - 237 - /* Represents the DMA address to the first entry of the dcb entries. */ 238 - dma_addr_t dma; 278 + struct fdma fdma; 239 279 240 280 /* Array of dcbs that are given to the HW */ 241 281 struct lan966x_tx_dcb_buf *dcbs_buf; 242 - 243 - u8 channel_id; 244 282 245 283 bool activated; 246 284 };