dma.h (24684B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: socdma.h 8 * Purpose: Maps out structures used for DMA operations and 9 * exports routines. 10 */ 11 12 #ifndef _SOC_DMA_H 13 #define _SOC_DMA_H 14 15 #include <sal/types.h> 16 #include <sal/core/sync.h> 17 #include <shared/alloc.h> 18 #include <sal/core/spl.h> 19 20 #include <shared/types.h> 21 22 #include <soc/types.h> 23 #include <soc/cmic.h> 24 #include <soc/dcb.h> 25 26 #if defined(BE_HOST) && defined(LE_HOST) 27 #error "Define either BE_HOST or LE_HOST. Both BE_HOST and LE_HOST should not be defined at the same time" 28 #endif 29 30 #define SOC_DMA_ROUND_LEN(x) (((x) + 3) & ~3) 31 32 /* Type for DMA channel number */ 33 34 typedef _shr_dma_chan_t dma_chan_t; 35 36 /* 37 * Defines: 38 * SOC_DMA_DV_FREE_CNT/SOC_DMA_DV_FREE_SIZE 39 * Purpose: 40 * Defines the number of free DV's that the DMA code will cache 41 * to avoid calling alloc/free routines. FREE_CNT is number of 42 * dv_t's, and FREE_SIZE is the number of DCBs in the DV. 43 * Notes: 44 * Allocation requests for DV's with < FREE_SIZE dcbs MAY result in 45 * an allocation of a DV with FREE_SIZE dcbs. Allocations with 46 * > FREE_SIZE will always result in calls to memory allocation 47 * routines. 48 */ 49 50 #define SOC_DMA_DV_FREE_CNT 32 51 #define SOC_DMA_DV_FREE_SIZE 160 /*Common DCBs *(1 + Extra DCBs)*/ 52 53 #define SOC_DV_PKTS_MAX 32 /* Determines alloc size of 54 DMA'able data in DVs */ 55 56 typedef int8 dvt_t; /* DV Type definition */ 57 58 #define DV_NONE 0 /* Disable/Invalid */ 59 #define DV_TX 1 /* Transmit data */ 60 #define DV_RX 2 /* Receive data */ 61 62 #define SOC_DMA_DV_TX_FREE_SIZE 3 63 #define SOC_DMA_DV_RX_FREE_SIZE 1 64 65 #define CMICX_DMA_CONTIGUOUS_DESCS 8 /* Max no. of contiguous descriptors */ 66 67 /* 68 * Typedef: 69 * soc_tx_param_t 70 * Purpose: 71 * Strata XGS hardware specific info related to packet TX; 72 * Will be used as a vehicle for passing information to 73 * the DCB-Add-TX operation. 74 * Information is per packet. The data buffer pointer and 75 * byte count is passed separately. 76 */ 77 78 typedef struct soc_tx_param_s { 79 uint8 cos; /* The local COS# to use */ 80 uint8 prio_int; /* Internal priority of the packet */ 81 uint8 src_port; /* Header/tag ONLY. Use rx_port below */ 82 uint8 src_mod; 83 uint8 dest_port; /* Header/tag ONLY. Use tx_pbmp below */ 84 uint8 dest_mod; 85 uint8 opcode; 86 uint8 pfm; /* see BCM_PORT_PFM_* */ 87 88 soc_pbmp_t tx_pbmp; /* Target ports */ 89 soc_pbmp_t tx_upbmp; /* Untagged ports */ 90 soc_pbmp_t tx_l3pbmp; /* L3 ports */ 91 92 /* Uses SOC_DMA and SOC_DMA_F flags from below */ 93 uint32 flags; 94 95 #if 0 /* Not yet */ 96 /* Representations for HiGig header data (12 bytes) */ 97 union { 98 uint8 higig8[12]; 99 uint32 higig32[3]; 100 /* Add higig_hdr_t here */ 101 } higig_u; 102 103 /* Accessors for the HiGig header in the soc_tx_param_t structure */ 104 #define SOC_TXP_HIGIG8(data) ((data).higig_u.higig8) 105 #define SOC_TXP_HIGIG32(data) ((data).higig_u.higig32) 106 #define SOC_TXP_HG_HDR(data) ((data).higig_u.hg_hdr) 107 108 #endif 109 110 /* Other new headers/tags may be added here */ 111 } soc_tx_param_t; 112 113 /* 114 * Typedef: 115 * dv_t 116 * Purpose: 117 * Maps out the I/O Vec structure used to pass DMA chains to the 118 * the SOC DMA routines "DMA I/O Vector". 119 * Notes: 120 * To start a DMA request, the caller must fill in: 121 * dv_op: operation to perform (DV_RX or DV_TX). 122 * dv_flags: Set DV_F_NOTIFY_DSC for descriptor done callout 123 * Set DV_F_NOTIFY_CHN for chain done callout 124 * Set DV_F_WAIT to suspend in dma driver 125 * dv_valid: # valid DCB entries (this field is initialized 126 * by soc_dma_dv_alloc, and set properly if 127 * soc_dma_add_dcb is called to build chain). 128 * dv_done_chain: NULL if no callout for chain done, or the 129 * address of the routine to call when chain done 130 * is seen. It is called with 2 parameters, the 131 * unit # and a pointer to the DV chain done has been 132 * seen on. 133 * dv_done_desc: NULL for synchronous call, or the address of 134 * the function to call on descriptor done. The function 135 * is with 3 parameters, the unit #, a pointer to 136 * the DV structure, and a pointer to the DCB completed. 137 * One call is made for EVERY DCB, and only if the 138 * DCB is DONE. 139 * dv_done_packet: NULL if no callout for packet done, or the 140 * address of the routine to call when packet done 141 * is seen. It has the same prototype as dv_done_desc. 142 * dv_public1 - 4: Not used by DMA routines, 143 * for use by caller. 144 * 145 * Scatter/gather is implemented through multiple DCBs pointing to 146 * different buffers with the S/G bit set. End of S/G chain (end of 147 * packet) is indicated by having S/G bit clear in the DCB. 148 * 149 * Chains of packets can be associated with a single DV. This 150 * keeps the HW busy DMA'ing packets even as interrupts are 151 * processed. DVs can be chained (a software construction) 152 * which will start a new DV from this file rather than calling 153 * back. This is not done much in our code. 154 */ 155 156 typedef struct dv_s { 157 struct dv_s *dv_next, /* Queue pointers if required */ 158 *dv_chain; /* Pointer to next DV in chain */ 159 int dv_unit; /* Unit dv is allocated on */ 160 uint32 dv_magic; /* Used to indicate valid */ 161 dvt_t dv_op; /* Operation to be performed */ 162 dma_chan_t dv_channel; /* Channel queued on */ 163 int dv_flags; /* Flags for operation */ 164 /* Fix soc_dma_dv_reset if you add flags */ 165 # define DV_F_NOTIFY_DSC 0x01 /* Notify on dsc done */ 166 # define DV_F_NOTIFY_CHN 0x02 /* Notify on chain done */ 167 # define DV_F_COMBINE_DCB 0x04 /* Combine DCB where poss. */ 168 # define DV_F_NEEDS_REFILL 0x10 /* Needs to be refilled */ 169 int dv_cnt; /* # descriptors allocated */ 170 int dv_vcnt; /* # descriptors valid */ 171 int dv_dcnt; /* # descriptors done */ 172 void (*dv_done_reload)(int u, struct dv_s *dv_chain); 173 void (*dv_done_chain)(int u, struct dv_s *dv_chain); 174 void (*dv_done_desc)(int u, struct dv_s *dv, dcb_t *dcb); 175 void (*dv_done_desc_subs)(int u, struct dv_s *dv, dcb_t *dcb); 176 void (*dv_done_packet)(int u, struct dv_s *dv, dcb_t *dcb); 177 any_t dv_public1; /* For caller */ 178 any_t dv_public2; /* For caller */ 179 any_t dv_public3; /* For caller */ 180 any_t dv_public4; /* For caller */ 181 182 /* 183 * Information for SOC_TX_PKT_PROPERTIES. 184 * Normally, packets are completely independent across a DMA TX chain. 185 * In order to program the cmic dma tx register effeciently, the data 186 * in soc_tx_param must be consistent for all packets in the chain. 187 */ 188 soc_tx_param_t tx_param; 189 190 /* 191 * Buffer for gather-inserted data. Possibly includes: 192 * HiGig hdr (12 bytes) 193 * HiGig2 hdr (16 bytes) (HG2/SL mutually exclusive) 194 * SL tag (4 bytes) 195 * VLAN tag (4 bytes) 196 * Dbl VLAN tag (4 bytes) 197 */ 198 uint8 *dv_dmabuf; 199 uint32 dv_dma_buf_size; 200 #define SOC_DMA_BUF_LEN 24 /* Maximum header size from above */ 201 #define SOC_DV_DMABUF_SIZE (SOC_DV_PKTS_MAX * SOC_DMA_BUF_LEN) 202 #define SOC_DV_HG_HDR(dv, i) (&((dv)->dv_dmabuf[SOC_DMA_BUF_LEN*i+0])) 203 #define SOC_DV_SL_TAG(dv, i) (&((dv)->dv_dmabuf[SOC_DMA_BUF_LEN*i+12])) 204 #define SOC_DV_VLAN_TAG(dv, i) (&((dv)->dv_dmabuf[SOC_DMA_BUF_LEN*i+16])) 205 #define SOC_DV_VLAN_TAG2(dv, i) (&((dv)->dv_dmabuf[SOC_DMA_BUF_LEN*i+20])) 206 207 /* Optionally allocated for Tx alignment */ 208 #define SOC_DV_TX_ALIGN(dv, i) (&((dv)->dv_dmabuf[dv->dv_dma_buf_size + 4 * i])) 209 210 dcb_t *dv_dcb; 211 } dv_t; 212 213 /* Poll type */ 214 typedef enum soc_dma_poll_type_e { 215 SOC_DMA_POLL_DESC_DONE = 0, 216 SOC_DMA_POLL_CTRLD_DESC_DONE = 1, 217 SOC_DMA_POLL_CHAIN_DONE = 2 218 } soc_dma_poll_type_t; 219 220 /* 221 * Typedef: 222 * sdc_t (SOC DMA Control) 223 * Purpose: 224 * Each DMA channel on each SOC has one of these structures to 225 * track the currently active or queued operations. 226 */ 227 228 typedef struct sdc_s { 229 dma_chan_t sc_channel; /* Channel # for reverse lookup */ 230 dvt_t sc_type; /* DV type that we accept */ 231 uint8 sc_flags; /* See SDMA_CONFIG_XXX */ 232 dv_t *sc_q; /* Request queue head */ 233 dv_t *sc_q_tail; /* Request queue tail */ 234 dv_t *sc_dv_active; /* Pointer to individual active DV */ 235 int sc_q_cnt; /* # requests queued + active */ 236 int sc_dma_started; /* Continuous DMA chan started */ 237 } sdc_t; 238 239 /* CMIC DMA Driver Interface for CMIC type abstraction */ 240 typedef struct soc_cmic_dma_drv_s { 241 int (*init)(int unit); 242 int (*ctrl_init)(int unit); 243 int (*chan_abort)(int unit, int chan); 244 int (*chan_tx_purge)(int unit, int chan, dv_t *dv); 245 int (*chan_config)(int unit, int chan, dvt_t type, uint32 flags); 246 int (*chan_dv_start)(int unit, sdc_t *sc, dv_t *dv); 247 int (*chan_start)(int unit, sdc_t *sc); 248 int (*chan_poll)(int unit, int chan, soc_dma_poll_type_t type, int *detected); 249 int (*chan_desc_done_intr_enable)(int unit, int chan); 250 int (*chan_desc_done)(int unit, int chan); 251 int (*chan_chain_done)(int unit, int chan, int mitigation); 252 int (*chan_reload_done)(int unit, int chan, dcb_t *dcb, int *rld_done); 253 int (*chan_counter_get)(int unit, int chan, uint32 *tx_pkt, uint32 *rx_pkt); 254 int (*chan_counter_clear)(int unit, int chan, uint32 mask); 255 int (*chan_cos_ctrl_get)(int unit, int chan, uint32 mask, uint32 *cos_ctrl); 256 int (*chan_cos_ctrl_set)(int unit, int chan, uint32 mask, uint32 cos_ctrl); 257 int (*chan_cos_ctrl_queue_get)(int unit, int cmc, int chan, int queue, uint32 *cos_ctrl); 258 int (*chan_cos_ctrl_reg_addr_get)(int unit, int cmc, int chan, int queue, uint32 *reg_addr); 259 int (*chan_status_get)(int unit, int chan, uint32 mask, int *status); 260 int (*chan_status_clear)(int unit, int chan); 261 int (*chan_halt_get)(int unit, int chan, uint32 mask, int *active); 262 int (*chan_ctrl_reg_get)(int unit, int chan, uint32 *val); 263 int (*chan_ctrl_reg_set)(int unit, int chan, uint32 val); 264 int (*chan_rxbuf_threshold_cfg)(int unit, int chan, uint32 val); 265 int (*cmc_rxbuf_threshold_cfg)(int unit, int cmc, uint32 val); 266 int (*cmc_counter_get)(int unit, int cmc, uint32 *tx_pkt, uint32 *rx_pkt); 267 int (*cmc_counter_clear)(int unit, int cmc, uint32 mask); 268 int (*masks_get)(int unit, uint32 *pkt_endian, uint32 *desc_endian, uint32 *header_endian); 269 int (*loopback_config)(int unit, uint32 cfg); 270 int (*header_size_get)(int unit, uint32 *hdr_size); 271 int (*max_rx_channels_get)(int unit, uint32 *max_rx_channels); 272 int (*pci_timeout_handle)(int unit); 273 } soc_cmic_dma_drv_t; 274 275 #define SOC_DMA_MODE(unit)(SOC_CONTROL(unit)->dma_mode) 276 277 /* Do not alter ext_dcb flag below */ 278 #define SET_NOTIFY_CHN_ONLY(flags) do { \ 279 (flags) |= DV_F_NOTIFY_CHN; \ 280 (flags) &= ~DV_F_NOTIFY_DSC; \ 281 } while (0) 282 283 #define SET_NOTIFY_DSC_ONLY(flags) do { \ 284 (flags) |= DV_F_NOTIFY_DSC; \ 285 (flags) &= ~DV_F_NOTIFY_CHN; \ 286 } while (0) 287 288 /* Try to avoid all other flags */ 289 #define SOC_DMA_F_PKT_PROP 0x10000000 /* 1 << 28 */ 290 291 /* 292 * Note DMA_F_INTR is NOT a normal flag. 293 * Interrupt mode is the default behavior and is ! POLLED mode. 294 */ 295 #define SOC_DMA_F_INTR 0x00 /* Interrupt Mode */ 296 297 #define SOC_DMA_F_MBM 0x01 /* Modify bit MAP */ 298 #define SOC_DMA_F_POLL 0x02 /* POLL mode */ 299 #define SOC_DMA_F_TX_DROP 0x04 /* Drop if no ports */ 300 #define SOC_DMA_F_JOIN 0x08 /* Allow low level DV joins */ 301 #define SOC_DMA_F_DEFAULT 0x10 /* Default channel for type */ 302 #define SOC_DMA_F_CLR_CHN_DONE 0x20 /* Clear Chain-done on start */ 303 #define SOC_DMA_F_INTR_ON_DESC 0x40 /* Interrupt per descriptor */ 304 305 extern int soc_dma_init(int unit); 306 extern int soc_dma_attach(int unit, int reset); 307 extern int soc_dma_detach(int unit); 308 extern void soc_dma_chan_started_clear(int unit, dma_chan_t c); 309 extern int soc_dma_chan_config(int unit, dma_chan_t chan, dvt_t type, 310 uint32 flags); 311 extern dvt_t soc_dma_chan_dvt_get(int unit, dma_chan_t chan); 312 313 extern dv_t *soc_dma_dv_alloc(int unit, dvt_t, int cnt); 314 extern dv_t *soc_dma_dv_alloc_by_port(int unit, dvt_t op, int cnt, 315 int pkt_to_ports); 316 extern void soc_dma_dv_free(int unit, dv_t *); 317 extern void soc_dma_dv_reset(dvt_t, dv_t *); 318 extern int soc_dma_dv_join(dv_t *dv_list, dv_t *dv_add); 319 320 extern int soc_dma_desc_add(dv_t *, sal_vaddr_t, uint16, pbmp_t, 321 pbmp_t, pbmp_t, uint32 flags, uint32 *hgh); 322 extern void soc_dma_dump_dv_dcb(int unit, char *pfx, 323 dv_t *dv_chain, int index); 324 325 /* CMIC driver functions */ 326 extern int soc_cmice_dma_drv_init(int unit, soc_cmic_dma_drv_t *drv); 327 extern int soc_cmicm_dma_drv_init(int unit, soc_cmic_dma_drv_t *drv); 328 extern int soc_cmicd_dma_drv_init(int unit, soc_cmic_dma_drv_t *drv); 329 extern int soc_cmicx_dma_drv_init(int unit, soc_cmic_dma_drv_t *drv); 330 331 /* abort and disable previous DMA operations */ 332 extern int soc_cmicx_dma_abort(int unit, uint32 flags); 333 /* flags specifying not to abort and disable some DMA types */ 334 #define SOC_DMA_ABORT_SKIP_SBUS 1 335 #define SOC_DMA_ABORT_SKIP_PACKET 2 336 #define SOC_DMA_ABORT_SKIP_FIFO 4 337 #define SOC_DMA_ABORT_SKIP_CCM 8 338 #define SOC_DMA_ABORT_SKIP_SCHAN_FIFO 16 339 #define SOC_DMA_ABORT_CMC0 32 340 341 342 #define SOC_DMA_COS(_x) ((_x) << 0) 343 #define SOC_DMA_COS_GET(_x) (((_x) >> 0) & 7) 344 #define SOC_DMA_CRC_REGEN (1 << 3) 345 #define SOC_DMA_CRC_GET(_x) (((_x) >> 3) & 1) 346 #define SOC_DMA_RLD (1 << 4) 347 #define SOC_DMA_HG (1 << 22) 348 #define SOC_DMA_STATS (1 << 23) 349 #define SOC_DMA_PURGE (1 << 24) 350 351 /* Max 7 bits for mod, 6 bits for port and 1 for trunk indicator */ 352 #define _SDP_MSK 0x3f /* 10:5 */ 353 #define _SDP_S 5 /* 10:5 */ 354 #define _SDM_MSK 0x7f /* 17:11 */ 355 #define _SDM_S 11 /* 17:11 */ 356 #define _SDT_MSK 0x1 /* 18:18 */ 357 #define _SDT_S 18 /* 18:18 */ 358 #define _SMHOP_MSK 0x7 /* 21:19 */ 359 #define _SMHOP_S 19 /* 21:19 */ 360 361 /* 362 * type 9 descriptor, Higig, stats, purge bits 363 */ 364 365 #define _SHG_MSK 0x1 /* 22:22 */ 366 #define _SHG_S 22 /* 22:22 */ 367 #define _SSTATS_MSK 0x1 /* 23:23 */ 368 #define _SSTATS_S 23 /* 23:23 */ 369 #define _SPURGE_MSK 0x1 /* 24:24 */ 370 #define _SPURGE_S 24 /* 24:24 */ 371 372 #define SOC_DMA_LOOPBACK_SET 0x1 373 #define SOC_DMA_LOOPBACK_RESET 0x2 374 #define SOC_DMA_COS_RX_0 0x1 375 #define SOC_DMA_COS_RX_1 0x2 376 #define SOC_DMA_TXPKT 0x1 377 #define SOC_DMA_RXPKT 0x2 378 #define SOC_DMA_RXPKT_DROP 0x4 379 #define SOC_DMA_STATUS_LOW 0x1 380 #define SOC_DMA_STATUS_HI 0x2 381 382 #define SOC_DMA_DPORT_GET(flags) \ 383 SOC_SM_FLAGS_GET(flags, _SDP_S, _SDP_MSK) 384 #define SOC_DMA_DPORT_SET(flags, val) \ 385 SOC_SM_FLAGS_SET(flags, val, _SDP_S, _SDP_MSK) 386 387 #define SOC_DMA_DMOD_GET(flags) \ 388 SOC_SM_FLAGS_GET(flags, _SDM_S, _SDM_MSK) 389 #define SOC_DMA_DMOD_SET(flags, val) \ 390 SOC_SM_FLAGS_SET(flags, val, _SDM_S, _SDM_MSK) 391 392 #define SOC_DMA_DTGID_GET(flags) \ 393 SOC_SM_FLAGS_GET(flags, _SDT_S, _SDT_MSK) 394 #define SOC_DMA_DTGID_SET(flags, val) \ 395 SOC_SM_FLAGS_SET(flags, val, _SDT_S, _SDT_MSK) 396 397 #define SOC_DMA_MHOP_GET(flags) \ 398 SOC_SM_FLAGS_GET(flags, _SMHOP_S, _SMHOP_MSK) 399 #define SOC_DMA_MHOP_SET(flags, val) \ 400 SOC_SM_FLAGS_SET(flags, val, _SMHOP_S, _SMHOP_MSK) 401 402 #define SOC_DMA_HG_GET(flags) \ 403 SOC_SM_FLAGS_GET(flags, _SHG_S, _SHG_MSK) 404 #define SOC_DMA_HG_SET(flags, val) \ 405 SOC_SM_FLAGS_SET(flags, val, _SHG_S, _SHG_MSK) 406 407 #define SOC_DMA_STATS_GET(flags) \ 408 SOC_SM_FLAGS_GET(flags, _SSTATS_S, _SSTATS_MSK) 409 #define SOC_DMA_STATS_SET(flags, val) \ 410 SOC_SM_FLAGS_SET(flags, val, _SSTATS_S, _SSTATS_MSK) 411 412 #define SOC_DMA_PURGE_GET(flags) \ 413 SOC_SM_FLAGS_GET(flags, _SPURGE_S, _SPURGE_MSK) 414 #define SOC_DMA_PURGE_SET(flags, val) \ 415 SOC_SM_FLAGS_SET(flags, val, _SPURGE_S, _SPURGE_MSK) 416 417 extern int soc_dma_rld_desc_add(dv_t *, sal_vaddr_t); 418 extern void soc_dma_desc_end_packet(dv_t *); 419 420 extern int soc_dma_contiguous_desc_add(dv_t *); 421 422 extern int soc_dma_start(int unit, dma_chan_t, dv_t *); 423 424 extern int soc_dma_abort_channel_total(int unit, dma_chan_t channel); 425 extern int soc_dma_abort_dv(int unit, dv_t *); 426 extern int soc_dma_abort(int unit); 427 428 extern int soc_dma_chan_counter_get(int unit, dma_chan_t channel, 429 uint32 *tx_pkt, uint32 *rx_pkt); 430 extern int soc_dma_chan_counter_clear(int unit, dma_chan_t channel, 431 uint32 mask); 432 extern int soc_dma_loopback_config(int unit, uint32 cfg); 433 extern int soc_dma_header_size_get(int unit, uint32 *hdr_size); 434 extern int soc_dma_chan_cos_ctrl_get(int unit, dma_chan_t channel, 435 uint32 cfg, uint32 *cos_ctrl); 436 extern int soc_dma_chan_cos_ctrl_set(int unit, dma_chan_t channel, 437 uint32 cfg, uint32 cos_ctrl); 438 extern int soc_dma_cos_ctrl_queue_get(int unit, int cmc, int chan, 439 int queue, uint32 *cos_ctrl); 440 extern int soc_dma_cos_ctrl_reg_addr_get(int unit, int cmc, int chan, 441 int queue, uint32 *reg_addr); 442 extern int soc_dma_chan_poll_done(int unit, dma_chan_t channel, 443 soc_dma_poll_type_t type, 444 int *detected); 445 extern int soc_dma_chan_status_get(int unit, dma_chan_t channel, 446 uint32 mask, int *status); 447 extern int soc_dma_chan_status_clear(int unit, dma_chan_t channel); 448 extern int soc_dma_chan_halt_get(int unit, dma_chan_t channel, 449 uint32 mask, int *active); 450 extern int soc_dma_chan_rxbuf_threshold_cfg(int unit, dma_chan_t channel, 451 uint32 val); 452 extern int soc_dma_cmc_rxbuf_threshold_cfg(int unit, int cmc, 453 uint32 val); 454 extern int soc_dma_chan_ctrl_reg_get(int unit, dma_chan_t channel, 455 uint32 *val); 456 extern int soc_dma_chan_ctrl_reg_set(int unit, dma_chan_t channel, 457 uint32 val); 458 extern int soc_dma_cmc_counter_get(int unit, int cmc, 459 uint32 *tx_pkt, uint32 *rx_pkt); 460 extern int soc_dma_cmc_counter_clear(int unit, int cmc, 461 uint32 mask); 462 extern int soc_dma_masks_get(int unit, uint32 *pkt_endian, 463 uint32 *desc_endian, uint32 *header_endian); 464 extern int soc_dma_max_rx_channels_get(int unit, uint32 *max_rx_channels); 465 466 467 /* Wait on synchronous send - requires a context */ 468 extern int soc_dma_wait(int unit, dv_t *dv_chain); 469 extern int soc_dma_wait_timeout(int unit, dv_t *dv_chain, int usec); 470 471 extern void soc_dma_higig_dump(int unit, char *pfx, uint8 *addr, 472 int len, int pkt_len, int *ether_offset); 473 extern void soc_dma_ether_dump(int unit, char *pfx, uint8 *addr, 474 int len, int offset); 475 extern void soc_dma_ep_to_cpu_hdr_dump(int unit, char *pfx, uint8 *addr, 476 int len, int offset); 477 extern void soc_dma_ep_to_cpu_hdr_decoded_dump(int unit, char *pfx, void *addr, 478 int skip_mhdr, int hdr_size); 479 extern void soc_dma_usage_get(int unit); 480 481 extern int soc_dma_dv_valid(dv_t *dv); 482 extern void soc_dma_dump_dv(int unit, char *pfx, dv_t *); 483 extern void soc_dma_dump_pkt(int unit, char *pfx, uint8 *addr, int len, 484 int decode); 485 486 /* Interrupt Routines */ 487 488 extern void soc_dma_done_desc(int unit, uint32 chan); 489 extern void soc_dma_cmicx_done_desc(int unit, uint32 chan); 490 extern void soc_dma_done_chain(int unit, uint32 chan); 491 extern void soc_dma_pci_timeout_handle(int unit, uint32 data); 492 493 #ifdef BCM_XGS3_SWITCH_SUPPORT 494 int soc_dma_tx_purge(int unit, dma_chan_t c); 495 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 496 497 /* 498 * Simplified API for ROM TX/RX polled mode. 499 * See $SDK/doc/dma_rom.txt for more information. 500 */ 501 502 #ifndef SOC_DMA_ROM_TX_CHANNEL 503 #define SOC_DMA_ROM_TX_CHANNEL 2 504 #endif 505 506 #ifndef SOC_DMA_ROM_RX_CHANNEL 507 #define SOC_DMA_ROM_RX_CHANNEL 3 508 #endif 509 510 extern int soc_dma_rom_init(int unit, int max_packet_rx, int tx, int rx); 511 extern int soc_dma_rom_detach(int unit); 512 extern dcb_t *soc_dma_rom_dcb_alloc(int unit, int psize); 513 extern int soc_dma_rom_dcb_free(int unit, dcb_t *dcb); 514 extern int soc_dma_rom_tx_start(int unit, dcb_t *dcb); 515 extern int soc_dma_rom_tx_poll(int unit, int *done); 516 extern int soc_dma_rom_tx_abort(int unit); 517 extern int soc_dma_rom_rx_poll(int unit, dcb_t **dcb); 518 519 extern void soc_cmicx_pktdma_desc_endian_set(int unit, int cmc, int channel, int big_endian); 520 extern void soc_cmicx_pktdma_hdr_endian_set(int unit, int cmc, int channel, int big_endian); 521 extern void soc_cmicx_pktdma_data_endian_set(int unit, int cmc, int channel, int big_endian); 522 extern uint32 soc_cmicx_pktdma_header_size_get(int unit); 523 extern uint32 soc_cmicx_pktdma_cos_ctrl_rx0_get(int unit, int cmc, int channel); 524 extern uint32 soc_cmicx_pktdma_cos_ctrl_rx1_get(int unit, int cmc, int channel); 525 extern uint32 soc_cmicx_pktdma_cos_ctrl_rx0_reg_addr_get(int unit, int cmc, int channel); 526 extern uint32 soc_cmicx_pktdma_cos_ctrl_rx1_reg_addr_get(int unit, int cmc, int channel); 527 extern uint32 soc_cmicx_pktdma_cos_ctrl_queue_id_get(int unit, int cmc, int channel, int queue); 528 extern sal_vaddr_t soc_cmicx_pktdma_desc_addr_get(int unit, int cmc, int channel); 529 530 /* 531 * Atomic memory allocation functions that are safe to call 532 * from interrupt context when BCM_TX_FROM_INTR is defined. 533 * This memory does not necessarily need to be DMA-safe. 534 * 535 * Currently the assumption is that soc_cm_salloc/sfree are 536 * atomic if BCM_TX_FROM_INTR is defined. 537 */ 538 #ifdef BCM_TX_FROM_INTR 539 #define SOC_DMA_NEEDS_ATOMIC_ALLOC 540 #endif 541 542 #if defined(SAL_HAS_ATOMIC_ALLOC) 543 /* Dedicated functions provided by SAL */ 544 extern void *soc_at_alloc(int dev, int size, const char *name); 545 extern void soc_at_free(int dev, void *ptr); 546 #elif defined(SOC_DMA_NEEDS_ATOMIC_ALLOC) && !defined(SAL_ALLOC_IS_ATOMIC) 547 /* Use CM DMA allocator for atomic allocation */ 548 #define soc_at_alloc(_u, _sz, _nm) soc_cm_salloc(_u, _sz, _nm) 549 #define soc_at_free(_u, _ptr) soc_cm_sfree(_u, _ptr) 550 #else 551 /* */ 552 #define soc_at_alloc(_u, _sz, _nm) sal_alloc(_sz, _nm) 553 #define soc_at_free(_u, _ptr) sal_free(_ptr) 554 #endif 555 556 /* microsec */ 557 #ifdef BCM_ICS 558 /* Same time on Quickturn as well */ 559 #define DMA_ABORT_TIMEOUT 10000 560 #else 561 #define DMA_ABORT_TIMEOUT \ 562 (SAL_BOOT_SIMULATION ? 10000000 : 10000) 563 #endif 564 565 #endif /* !_SOC_DMA_H */