1 #include <adf_os_stdtypes.h>
2 #include <adf_os_types.h>
7 #include <Magpie_api.h>
9 #include <adf_os_util.h>
10 #include <adf_os_mem.h>
11 #include <adf_os_time.h>
17 /**************************Constants******************************/
19 GMAC_HST_QUERY = 0x0001,
20 GMAC_HST_REPLY = 0x0002,
21 GMAC_TGT_QUERY = 0x0003,
22 GMAC_TGT_REPLY = 0x0004
26 MAG_REG_GPIO_OE = 0x00052000,/*GPIO Output Enable*/
27 MAG_REG_RST = 0x00050010,/*Magpie reset reg*/
28 MAG_REG_RST_AHB = 0x00050018,/*Magpie AHB_ARB reset reg*/
29 MAG_REG_MII0_CTRL = 0x00054100,/*Magpie MII0 Control reg*/
30 MAG_REG_STAT_CTRL = 0x00054104,/*Magpie Status reg*/
31 MAG_REG_MDIO = 0x00054200,/*Mapie MDIO register*/
32 MAG_REG_MDIO_CMD = 0x00 + MAG_REG_MDIO,/*CMD register (0)*/
33 MAG_REG_MDIO_OWN = 0x02 + MAG_REG_MDIO,/*OWN register (1)*/
35 * XXX: Endianess inside the word & between words
37 MAG_REG_MDIO_ADDR0 = 0x04 + MAG_REG_MDIO,/*ADDR0 register (2)*/
38 MAG_REG_MDIO_ADDR1 = 0x06 + MAG_REG_MDIO,/*ADDR1 register (3)*/
39 MAG_REG_MDIO_WRITE0 = 0x08 + MAG_REG_MDIO,/*Data WRITE0 register (4)*/
40 MAG_REG_MDIO_WRITE1 = 0x0a + MAG_REG_MDIO,/*Data WRITE1 register (5)*/
41 MAG_REG_MDIO_READ0 = 0x0c + MAG_REG_MDIO,/*Data READ0 register (6)*/
42 MAG_REG_MDIO_READ1 = 0x0e + MAG_REG_MDIO,/*Data READ1 register (7)*/
46 GMAC_REG_BASE = 0x00060000,
47 GMAC_REG_MAC_CFG1 = 0x00 + GMAC_REG_BASE,/*MAC config 1*/
48 GMAC_REG_MAC_CFG2 = 0x04 + GMAC_REG_BASE,/*MAC config 2*/
49 GMAC_REG_IPG_IFG = 0x08 + GMAC_REG_BASE,/*Inter-packet-gap*/
50 GMAC_REG_HALF_DPLX = 0x0c + GMAC_REG_BASE,/*Half duplex*/
51 GMAC_REG_MAX_FRAME = 0x10 + GMAC_REG_BASE,/*Max frame length*/
52 GMAC_REG_MII_CFG = 0x20 + GMAC_REG_BASE,/*MII mgmt config*/
53 GMAC_REG_MII_CMD = 0x24 + GMAC_REG_BASE,/*MII mgmt command*/
54 GMAC_REG_MII_ADDR = 0x28 + GMAC_REG_BASE,/*MII mgmt address*/
55 GMAC_REG_MII_CTRL = 0x2c + GMAC_REG_BASE,/*MII mgmt control*/
56 GMAC_REG_MII_STAT = 0x30 + GMAC_REG_BASE,/*MII mgmt status*/
57 GMAC_REG_MII_PSTAT = 0x34 + GMAC_REG_BASE,/*MII mgmt Phy status/ind*/
58 GMAC_REG_IF_CTRL = 0x38 + GMAC_REG_BASE,/*Interface control*/
59 GMAC_REG_IF_STAT = 0x3c + GMAC_REG_BASE,/*Interface status*/
60 GMAC_REG_MAC_ADDR1 = 0x40 + GMAC_REG_BASE,/*MAC address 1*/
61 GMAC_REG_MAC_ADDR2 = 0x44 + GMAC_REG_BASE,/*MAC address 2*/
62 GMAC_REG_FIFO_CFG0 = 0x48 + GMAC_REG_BASE,/*FIFO config reg0*/
63 GMAC_REG_FIFO_CFG1 = 0x4c + GMAC_REG_BASE,/*FIFO config reg1*/
64 GMAC_REG_FIFO_CFG2 = 0x50 + GMAC_REG_BASE,/*FIFO config reg2*/
65 GMAC_REG_FIFO_CFG3 = 0x54 + GMAC_REG_BASE,/*FIFO config reg3*/
66 GMAC_REG_FIFO_CFG4 = 0x58 + GMAC_REG_BASE,/*FIFO config reg4*/
67 GMAC_REG_FIFO_CFG5 = 0x5c + GMAC_REG_BASE,/*FIFO config reg5*/
68 GMAC_REG_FIFO_RAM0 = 0x60 + GMAC_REG_BASE,/*FIFO RAM access reg0*/
69 GMAC_REG_FIFO_RAM1 = 0x64 + GMAC_REG_BASE,/*FIFO RAM access reg1*/
70 GMAC_REG_FIFO_RAM2 = 0x68 + GMAC_REG_BASE,/*FIFO RAM access reg2*/
71 GMAC_REG_FIFO_RAM3 = 0x6c + GMAC_REG_BASE,/*FIFO RAM access reg3*/
72 GMAC_REG_FIFO_RAM4 = 0x70 + GMAC_REG_BASE,/*FIFO RAM access reg4*/
73 GMAC_REG_FIFO_RAM5 = 0x74 + GMAC_REG_BASE,/*FIFO RAM access reg5*/
74 GMAC_REG_FIFO_RAM6 = 0x78 + GMAC_REG_BASE,/*FIFO RAM access reg6*/
75 GMAC_REG_FIFO_RAM7 = 0x7c + GMAC_REG_BASE,/*FIFO RAM access reg7*/
79 RST_GMAC = (1 << 9),/*Reset the GMAC */
80 RST_MII = (3 << 11),/*Reset the MII*/
81 RST_OTHERS = 0x5df,/*Reset everybody other than GMAC & MII*/
84 enum __mag_reg_rst_ahb{
88 MII0_CTRL_MODE = (1 << 0),/*MII mode*/
89 MII0_CTRL_100 = (1 << 4),/*MII control address 100 Mbps*/
93 MDIO_CMD_DONE = 0x01,/*Operation over*/
94 MDIO_CMD_WRITE = 0x02,/*Write data*/
95 MDIO_CMD_READ = 0x03 /*Read data*/
98 MDIO_OWN_HST = 0x00,/*Host can use CMD & Data Regs*/
99 MDIO_OWN_TGT = 0x01 /*Tgt can use CMD & Data Regs*/
102 enum __gmac_reg_mac_cfg1{
103 MAC_CFG1_TX_EN = (1 << 0),/*TX enable*/
104 MAC_CFG1_RX_EN = (1 << 2),/*RX enable*/
105 MAC_CFG1_TX_FLOW = (1 << 4),/*TX Flow control enable*/
106 MAC_CFG1_RX_FLOW = (1 << 5),/*RX Flow control enable*/
107 MAC_CFG1_LOOP_EN = (1 << 8),/*Enable loopback*/
109 enum __gmac_reg_mac_cfg2{
110 MAC_CFG2_FULL_DUP = (1 << 0),/*Enable Full Duplex*/
111 MAC_CFG2_PAD_CRC = (1 << 2),/*Enable MAC based CRC insertion*/
112 MAC_CFG2_CHK_LEN = (1 << 4),/*Check Length field*/
113 MAC_CFG2_HUGE_FRM = (1 << 5),/*Allow sending huge frames*/
114 MAC_CFG2_MII = (1 << 8),/*MAC is MII in mode*/
115 MAC_CFG2_GMII = (1 << 9),/*MAC is in GMII mode*/
116 MAC_CFG2_PREAMBLE = (7 << 12),/*Default Preamble Length*/
118 enum __gmac_reg_mii_cfg{
119 MII_CFG_CLK_2MHZ = 0x0006,/*Clock is 2Mhz*/
121 enum __gmac_reg_mii_addr{
122 MII_ADDR_RESET = 0x000,/*Flush the MII address register*/
123 MII_ADDR_PHY_REG = 0x011,/*Phy Status Reg*/
125 enum __gmac_reg_mii_ctrl{
126 MII_CTRL_FULL_DPLX = 0x0100,/*Full Duplex mode*/
127 MII_CTRL_SPEED_100 = 0x2000,/*Link Speed 100 Mbps*/
128 MII_CTRL_LOOPBACK = 0x4000,/*Enable Loopback mode at PHY*/
129 MII_CTRL_RESET = 0x8000,/*BMCR reset*/
131 enum __gma_reg_mii_cmd{
133 MII_CMD_READ = 0x1,/*Perform a Read cycle*/
135 enum __gmac_reg_fifo_cfg0{
136 FIFO_CFG0_EN = 0x1f00,/*Enable all the Fifo module*/
138 enum __gmac_reg_fifo_cfg1{
139 FIFO_CFG1_SIZE_2K = (0x7ff << 16),/*Fifo size is 2K*/
141 enum __gmac_reg_fifo_cfg4{
142 FIFO_CFG4_RX_ALL = 0x3ffff,/*receive all frames*/
144 enum __gmac_reg_if_ctrl{
145 IF_CTRL_SPEED_100 = (1 << 16),/*Interface speed 100 Mbps for MII*/
148 /*************************GMAC Data types*******************************/
149 typedef enum __gmac_pkt_type{
155 unsigned char dst[ETH_ALEN];/*destination eth addr */
156 unsigned char src[ETH_ALEN]; /*source ether addr*/
157 A_UINT16 etype;/*ether type*/
158 }__attribute__((packed));
160 * @brief this is will be in big endian format
172 }__attribute__((packed));
174 typedef struct __gmac_hdr{
177 A_UINT16 align_pad;/*pad it for 4 byte boundary*/
178 }__attribute__((packed)) __gmac_hdr_t;
180 /*********************************GMAC softC************************/
182 typedef struct __gmac_softc{
189 #define ret_pkt sw.send_buf_done
190 #define indicate_pkt sw.recv_buf
191 #define htc_ctx sw.context
192 /*********************************DEFINES**********************************/
193 #define hif_gmac_sc(_hdl) (__gmac_softc_t *)(_hdl)
194 #define gmac_hdr(_vbuf) (__gmac_hdr_t *)(_vbuf)->desc_list->buf_addr
195 #define GMAC_HLEN (sizeof(struct __gmac_hdr))
197 #define __gmac_mdelay(_msecs) A_DELAY_USECS((_msecs) * 1000)
199 int __gmac_xmit_buf(hif_handle_t hdl, int pipe, VBUF *vbuf);
200 void __gmac_reap_recv(__gmac_softc_t *sc, dma_engine_t eng_no);
202 /***********************************Globals********************************/
204 * @brief Engines are fixed
206 __gmac_softc_t gmac_sc = {
207 .gran = GMAC_MAX_PKT_LEN
209 A_UINT8 gmac_addr[ETH_ALEN] = {0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
210 A_UINT8 bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
212 /**************************************APIs********************************/
215 * @brief This a replica of the ADF_NBUF_ALLOC
224 __gmac_vbuf_alloc(A_UINT32 size, A_UINT32 reserve, A_UINT32 align)
229 buf = VBUF_alloc_vbuf();
231 desc = VDESC_alloc_vdesc();
232 desc->buf_addr = (A_UINT8 *)A_ALLOCRAM(size);
233 desc->buf_size = size;
234 desc->next_desc = NULL;
235 desc->data_offset = reserve;
239 buf->desc_list = desc;
246 * @brief This is a replica of ADF_NBUF_PULL_HEAD
254 __gmac_vbuf_pull_head(VBUF *buf, A_UINT32 len)
257 VDESC *desc = buf->desc_list;
259 desc->data_offset += len;
260 desc->data_size -= len;
261 buf->buf_length -= len;
262 ptr = desc->buf_addr + desc->data_offset;
267 * @brief This is a replica of ADF_NBUF_PUSH_HEAD
275 __gmac_vbuf_push_head(VBUF *buf, A_UINT32 len)
278 VDESC *desc = buf->desc_list;
280 desc->data_offset -= len;
281 desc->data_size += len;
282 buf->buf_length += len;
283 ptr = desc->buf_addr + desc->data_offset;
287 * @brief This is a replica ADF_NBUF_LAST
294 __gmac_vbuf_last(VBUF *buf)
296 VDESC *desc = buf->desc_list;
298 while(desc->next_desc != NULL)
299 desc = desc->next_desc;
304 * @brief This is a replica of ADF_NBUF_PUT_TAIL
312 __gmac_vbuf_put_tail(VBUF *buf, A_UINT32 len)
314 A_UINT8 *tail = NULL;
315 VDESC *last_desc = __gmac_vbuf_last(buf);
317 tail = ( last_desc->buf_addr + last_desc->data_offset +
318 last_desc->data_size );
320 last_desc->data_size += len;
321 buf->buf_length += len;
326 /************************************GMAC**********************************/
328 __gmac_reg_read16(A_UINT32 addr)
330 return *((volatile A_UINT16 *)addr);
334 __gmac_reg_write16(A_UINT32 addr, A_UINT16 val)
336 *((volatile A_UINT16 *)addr) = val;
341 __gmac_reg_read32(A_UINT32 addr)
343 return *((volatile A_UINT32 *)addr);
347 __gmac_reg_write32(A_UINT32 addr, A_UINT32 val)
349 *((volatile A_UINT32 *)addr) = val;
352 * @brief Read the MAC address from EEPROM
353 * XXX: read from real EEPROM
355 * @param mac (pointer to fill the mac address)
358 __gmac_rom_read_mac(A_UINT8 mac_addr[])
360 A_MEMCPY(mac_addr, gmac_addr, ETH_ALEN);
363 * @brief Write the MAC address into the Station address
369 __gmac_reg_write_mac(A_UINT8 mac_addr[])
371 A_UINT32 mac_lo = 0, mac_hi = 0;
373 A_MEMCPY(&mac_lo, mac_addr, 4);
374 A_MEMCPY(&mac_hi, mac_addr + 4, 2);
376 A_PRINTF("mac address = %x:%x:%x:%x:%x:%x\n",
377 mac_addr[0], mac_addr[1], mac_addr[2],
378 mac_addr[3], mac_addr[4], mac_addr[5]);
380 __gmac_reg_write32(GMAC_REG_MAC_ADDR1, mac_lo);
381 __gmac_reg_write32(GMAC_REG_MAC_ADDR2, mac_hi);
385 * @brief Wait for the MII operation to complete
388 __gmac_mii_op_wait(void)
392 r_data = __gmac_reg_read32(GMAC_REG_MII_PSTAT) & 0x1;
394 r_data = (__gmac_reg_read32(GMAC_REG_MII_PSTAT) & 0x1);
400 volatile A_UINT32 r_data;
401 volatile A_UINT32 w_data;
404 * Reset the GMAC controller from Magpie Reset Register
406 r_data = __gmac_reg_read32(MAG_REG_RST);
408 __gmac_reg_write32(MAG_REG_RST, r_data);
413 * Pull it out from the Reset State
415 r_data = __gmac_reg_read32(MAG_REG_RST);
417 __gmac_reg_write32(MAG_REG_RST, r_data);
422 r_data = __gmac_reg_read32(MAG_REG_RST);
423 r_data |= (RST_MII | RST_GMAC);
424 __gmac_reg_write32(MAG_REG_RST, r_data);
428 * Pull the MII out of reset
430 r_data = __gmac_reg_read32(MAG_REG_RST);
431 r_data &= ~( RST_MII | RST_GMAC);
432 __gmac_reg_write32(MAG_REG_RST, r_data);
437 * Reset other modules PCI, PCIE, USB & Eth PLL
440 // __gmac_reg_write32(MAG_REG_RST, RST_OTHERS);
445 * Reset the AHB Arb. Unit
447 r_data = __gmac_reg_read32(MAG_REG_RST_AHB);
448 r_data |= RST_AHB_GMAC;
449 __gmac_reg_write32(MAG_REG_RST_AHB, r_data);
452 * MII mode initialization
454 w_data = ( MAC_CFG2_FULL_DUP | MAC_CFG2_PAD_CRC | MAC_CFG2_CHK_LEN |
455 MAC_CFG2_HUGE_FRM | MAC_CFG2_MII | MAC_CFG2_PREAMBLE );
457 __gmac_reg_write32(GMAC_REG_MAC_CFG2, w_data);
460 * Enable FIFO modules
462 __gmac_reg_write32(GMAC_REG_FIFO_CFG0, FIFO_CFG0_EN);
465 * Mode = MII & Speed = 100 Mbps
467 w_data = ( MII0_CTRL_100 | MII0_CTRL_MODE );
468 __gmac_reg_write32(MAG_REG_MII0_CTRL, w_data);
471 * Set the interface speed to 100 Mbps
473 __gmac_reg_write32(GMAC_REG_IF_CTRL, IF_CTRL_SPEED_100);
476 * Fifo size set to 2K bytes
478 r_data = __gmac_reg_read32(GMAC_REG_FIFO_CFG1);
479 r_data |= FIFO_CFG1_SIZE_2K;
480 __gmac_reg_write32(GMAC_REG_FIFO_CFG1, r_data);
483 * Enable the transceiver
485 w_data = MAC_CFG1_RX_EN | MAC_CFG1_TX_EN;
486 __gmac_reg_write32(GMAC_REG_MAC_CFG1, w_data);
489 * Set the MII Clock to 2Mhz
491 __gmac_reg_write32(GMAC_REG_MII_CFG, MII_CFG_CLK_2MHZ);
494 * Programming the phy registers
496 __gmac_reg_write32(GMAC_REG_MII_ADDR, MII_ADDR_RESET);
499 * BMCR reset for the PHY
501 __gmac_reg_write32(GMAC_REG_MII_CTRL, MII_CTRL_RESET);
504 * Wait until the MII Reg write has been flushed
506 __gmac_mii_op_wait();
509 * PHY register 0x000 , BMCR
511 __gmac_reg_write32(GMAC_REG_MII_ADDR, MII_ADDR_RESET);
514 * Write the value in the register
516 w_data = ( MII_CTRL_FULL_DPLX | MII_CTRL_SPEED_100 | MII_CTRL_RESET);
517 __gmac_reg_write32(GMAC_REG_MII_CTRL, w_data);
519 __gmac_mii_op_wait();
522 * Pull the BMCR out of the reset state
524 __gmac_reg_write32(GMAC_REG_MII_ADDR, MII_ADDR_RESET);
526 w_data = (MII_CTRL_FULL_DPLX | MII_CTRL_SPEED_100);
527 __gmac_reg_write32(GMAC_REG_MII_ADDR, w_data);
529 __gmac_mii_op_wait();
532 * XXX: This should be for some debugging purpose, don't know
533 * why we should write into the GPIO Output Enable the value
534 * returned from PHY status register Read
536 __gmac_reg_write32(GMAC_REG_MII_CMD, MII_CMD_WRITE);
537 __gmac_reg_write32(GMAC_REG_MII_ADDR, MII_ADDR_PHY_REG);
538 __gmac_reg_write32(GMAC_REG_MII_CMD, MII_CMD_READ);
540 __gmac_mii_op_wait();
542 r_data = __gmac_reg_read32(GMAC_REG_MII_STAT);
544 __gmac_reg_write32(MAG_REG_GPIO_OE, r_data);
547 * Enable Receive Fifo
549 r_data = __gmac_reg_read32(GMAC_REG_FIFO_CFG4);
550 r_data |= FIFO_CFG4_RX_ALL;
551 __gmac_reg_write32(GMAC_REG_FIFO_CFG4, r_data);
555 * @brief return if the pipe is supported
561 static inline a_bool_t
562 __gmac_chk_pipe(hif_gmac_pipe_t pipe)
565 case HIF_GMAC_PIPE_TX:
566 case HIF_GMAC_PIPE_RX:
574 __gmac_pkt_alloc(A_UINT32 size)
583 buf = __gmac_vbuf_alloc(size, GMAC_HLEN, 0);
587 fill_size = size - GMAC_HLEN;
589 data = __gmac_vbuf_put_tail(buf, fill_size);
591 A_MEMSET(data, 0xaa, fill_size);
596 * @brief Slap the header
602 __gmac_put_hdr(VBUF * buf, __gmac_hdr_t *hdr)
606 data = __gmac_vbuf_push_head(buf, GMAC_HLEN);
608 A_MEMCPY(data, hdr, GMAC_HLEN);
617 __gmac_prep_ethhdr(__gmac_hdr_t *hdr, A_UINT8 *dst)
619 A_MEMCPY(hdr->eth.dst, dst, ETH_ALEN);
620 hdr->eth.etype = ETH_P_ATH;
625 __is_ath_header(__gmac_softc_t *sc, VBUF *vbuf)
627 __gmac_hdr_t *hdr = gmac_hdr(vbuf);
629 if(hdr->ath.proto != sc->hdr.ath.proto)
636 __gmac_process_discv(__gmac_softc_t *sc)
638 a_status_t err = A_STATUS_OK;
640 __gmac_hdr_t *buf_hdr ;
643 vbuf = dma_lib_reap_recv(DMA_ENGINE_RX0);
645 if(!__is_ath_header(sc, vbuf))
648 buf_hdr = gmac_hdr(vbuf);
650 A_MEMCPY(sc->hdr.eth.dst, buf_hdr->eth.src, ETH_ALEN);
652 __gmac_vbuf_pull_head(vbuf, GMAC_HLEN);
655 * Application should do the return_recv
657 sc->indicate_pkt(NULL, vbuf, sc->htc_ctx);
663 * This is not our packet
667 dma_lib_return_recv(DMA_ENGINE_RX0, vbuf);
672 * @brief The GMAC host discovery loop
675 __gmac_discover(void)
677 a_status_t err = A_STATUS_FAILED;
679 __gmac_softc_t *sc = &gmac_sc;
685 buf = __gmac_pkt_alloc(GMAC_DISCV_PKT_SZ);
688 * Prepare the broadcast packet
690 __gmac_prep_ethhdr(&sc->hdr, bcast_addr);
691 __gmac_put_hdr(buf, &sc->hdr);
696 dma_lib_hard_xmit(DMA_ENGINE_TX0, buf);
699 __gmac_mdelay(GMAC_DISCV_WAIT);
701 if(dma_lib_xmit_done(DMA_ENGINE_TX0))
702 buf = dma_lib_reap_xmitted(DMA_ENGINE_TX0);
705 while(dma_lib_recv_pkt(DMA_ENGINE_RX0) && err)
706 err = __gmac_process_discv(sc);
716 __gmac_mdio_check(void)
720 /*Read the Ownership register*/
722 own = __gmac_reg_read16(MAG_REG_MDIO_OWN);
723 } while ( own == MDIO_OWN_TGT );
728 __gmac_mdio_load_exec(void)
730 volatile A_UINT16 cmd, more = 1 ;
731 volatile A_UINT16 *addr[2];
732 void ( *exec_fn)(void) = NULL;
736 * Read the Command register
738 cmd = __gmac_reg_read16(MAG_REG_MDIO_CMD);
745 * 1. Read the address from Address register
746 * 2. Write the data from Data register into the address
748 (A_UINT16 *)addr[0] = __gmac_reg_read16(MAG_REG_MDIO_ADDR0);
749 *addr[0] = __gmac_reg_read16(MAG_REG_MDIO_WRITE0);
751 (A_UINT16 *)addr[1] = __gmac_reg_read16(MAG_REG_MDIO_ADDR1);
752 *addr[1] = __gmac_reg_read16(MAG_REG_MDIO_WRITE1);
757 exec_fn = (A_UINT32 *)addr;
768 * 1. Read the address from Address register
769 * 2. Write the data into the Data register from the address
771 addr[0] = (A_UINT16 *)__gmac_reg_read16(MAG_REG_MDIO_ADDR0);
772 __gmac_reg_write16(MAG_REG_MDIO_READ0, *addr[0]);
774 addr[1] = (A_UINT16 *)__gmac_reg_read16(MAG_REG_MDIO_ADDR1);
775 __gmac_reg_write16(MAG_REG_MDIO_READ1, *addr[1]);
780 A_PRINTF("Command not implemmented\n");
788 * Change the Ownership
790 __gmac_reg_write16(MAG_REG_MDIO_OWN, MDIO_OWN_HST);
798 __gmac_mdio_init(void)
804 * Check for Targets turn
809 * Load & execute or Read data, if this returns then keep
812 __gmac_mdio_load_exec();
815 * If we are here then Host wants some more function execs or
822 __gmac_boot_init(void)
824 __gmac_softc_t *sc = &gmac_sc;
832 sc->hdr.ath.proto = ATH_P_MAGBOOT;
834 dma_lib_tx_init(DMA_ENGINE_TX0, DMA_IF_GMAC);
835 dma_lib_rx_init(DMA_ENGINE_RX0, DMA_IF_GMAC);
837 dma_lib_rx_config(DMA_ENGINE_RX0, GMAC_MAX_DESC, GMAC_MAX_PKT_LEN);
840 * Read the MAC address from the ROM & Write it into the
843 __gmac_rom_read_mac(sc->hdr.eth.src);
844 __gmac_reg_write_mac(sc->hdr.eth.src);
856 * @return hif_handle_t
859 __gmac_init(HIF_CONFIG *pConfig)
861 __gmac_softc_t *sc = &gmac_sc;
863 sc->hdr.ath.proto = ATH_P_MAGNORM;
865 dma_lib_tx_init(DMA_ENGINE_TX0, DMA_IF_GMAC);
866 dma_lib_rx_init(DMA_ENGINE_RX0, DMA_IF_GMAC);
871 * @brief Configure the receive pipe
878 __gmac_cfg_pipe(hif_handle_t hdl, int pipe, int num_desc)
880 __gmac_softc_t *sc = &gmac_sc;
882 if(pipe == HIF_GMAC_PIPE_RX)
883 dma_lib_rx_config(DMA_ENGINE_RX0, num_desc, sc->gran);
886 * @brief Start the interface
891 __gmac_start(hif_handle_t hdl)
896 * @brief Register callback of thre HTC
902 __gmac_reg_callback(hif_handle_t hdl, HIF_CALLBACK *sw)
904 __gmac_softc_t *sc = &gmac_sc;
906 sc->htc_ctx = sw->context;
907 sc->indicate_pkt = sw->recv_buf;
908 sc->ret_pkt = sw->send_buf_done;
911 * @brief reap the transmit queue for trasnmitted packets
917 __gmac_reap_xmitted(__gmac_softc_t *sc, dma_engine_t eng_no)
921 * Walk through the all your TX engines
925 vbuf = dma_lib_reap_xmitted(eng_no);
929 __gmac_vbuf_pull_head(vbuf, GMAC_HLEN);
930 sc->ret_pkt(vbuf, sc->htc_ctx);
935 * @brief reap the receive queue for vbuf's on the specified
942 __gmac_reap_recv(__gmac_softc_t *sc, dma_engine_t eng_no)
947 vbuf = dma_lib_reap_recv(eng_no);
952 if(!__is_ath_header(sc, vbuf)){
953 dma_lib_return_recv(eng_no, vbuf);
957 __gmac_vbuf_pull_head(vbuf, GMAC_HLEN);
959 sc->indicate_pkt(NULL, vbuf, sc->htc_ctx);
964 * @brief The interrupt handler
969 __gmac_isr_handler(hif_handle_t hdl)
971 __gmac_softc_t *sc = &gmac_sc;
973 if(dma_lib_xmit_done(DMA_ENGINE_TX0))
974 __gmac_reap_xmitted(sc, DMA_ENGINE_TX0);
976 if(dma_lib_recv_pkt(DMA_ENGINE_RX0))
977 __gmac_reap_recv(sc, DMA_ENGINE_RX0);
980 * @brief transmit the vbuf from the specified pipe
989 __gmac_xmit_buf(hif_handle_t hdl, int pipe, VBUF *vbuf)
991 __gmac_softc_t *sc = &gmac_sc;
993 if (pipe != HIF_GMAC_PIPE_TX)
997 adf_os_assert( vbuf->desc_list->data_offset >= GMAC_HLEN)
1000 __gmac_put_hdr(vbuf, &sc->hdr);
1002 return dma_lib_hard_xmit(DMA_ENGINE_TX0, vbuf);
1005 * @brief Submit the receive vbuf into the receive queue
1012 __gmac_return_recv(hif_handle_t hdl, int pipe, VBUF *vbuf)
1014 if (pipe == HIF_GMAC_PIPE_RX)
1015 dma_lib_return_recv(DMA_ENGINE_RX0, vbuf);
1018 * @brief Is this pipe number supported
1026 __gmac_is_pipe_supported(hif_handle_t hdl, int pipe)
1028 return __gmac_chk_pipe(pipe);
1031 * @brief maximum message length this pipe can support
1039 __gmac_get_max_msg_len(hif_handle_t hdl, int pipe)
1041 if(__gmac_chk_pipe(pipe))
1042 return GMAC_MAX_PKT_LEN;
1047 * @brief return the header room required by this HIF
1054 __gmac_get_reserved_headroom(hif_handle_t hdl)
1059 * @brief Device shutdown, HIF reset required
1064 __gmac_shutdown(hif_handle_t hdl)
1069 __gmac_get_def_pipe(hif_handle_t handle, A_UINT8 *pipe_uplink,
1070 A_UINT8 *pipe_downlink)
1072 *pipe_uplink = HIF_GMAC_PIPE_RX;
1073 *pipe_downlink = HIF_GMAC_PIPE_TX;
1077 * @brief This install the API's of the HIF
1082 hif_gmac_module_install(struct hif_api *apis)
1085 apis->_init = __gmac_init;
1086 apis->_start = __gmac_start;
1087 apis->_config_pipe = __gmac_cfg_pipe;
1088 apis->_isr_handler = __gmac_isr_handler;
1089 apis->_send_buffer = __gmac_xmit_buf;
1090 apis->_return_recv_buf = __gmac_return_recv;
1091 apis->_is_pipe_supported = __gmac_is_pipe_supported;
1092 apis->_get_max_msg_len = __gmac_get_max_msg_len;
1093 apis->_register_callback = __gmac_reg_callback;
1094 apis->_shutdown = __gmac_shutdown;/*XXX*/
1095 apis->_get_reserved_headroom = __gmac_get_reserved_headroom;
1096 apis->_get_default_pipe = __gmac_get_def_pipe;
1100 cmnos_gmac_module_install(struct gmac_api *boot_apis)
1102 boot_apis->gmac_boot_init = __gmac_boot_init;