34 #include "contiki-net.h"
54 typedef struct quarkX1000_eth_tx_desc {
59 uint32_t deferred_bit : 1;
60 uint32_t err_underflow : 1;
61 uint32_t err_excess_defer : 1;
62 uint32_t coll_cnt_slot_num : 4;
63 uint32_t vlan_frm : 1;
64 uint32_t err_excess_coll : 1;
65 uint32_t err_late_coll : 1;
66 uint32_t err_no_carrier : 1;
67 uint32_t err_carrier_loss : 1;
68 uint32_t err_ip_payload : 1;
69 uint32_t err_frm_flushed : 1;
70 uint32_t err_jabber_tout : 1;
72 uint32_t err_summary : 1;
73 uint32_t err_ip_hdr : 1;
74 uint32_t tx_timestamp_stat : 1;
75 uint32_t vlan_ins_ctrl : 2;
76 uint32_t addr2_chained : 1;
77 uint32_t tx_end_of_ring : 1;
78 uint32_t chksum_ins_ctrl : 2;
79 uint32_t replace_crc : 1;
80 uint32_t tx_timestamp_en : 1;
83 uint32_t first_seg_in_frm : 1;
84 uint32_t last_seg_in_frm : 1;
85 uint32_t intr_on_complete : 1;
94 uint32_t tx_buf1_sz : 13;
96 uint32_t tx_buf2_sz : 13;
97 uint32_t src_addr_ins_ctrl : 3;
107 } quarkX1000_eth_tx_desc_t;
110 typedef struct quarkX1000_eth_rx_desc {
114 uint32_t ext_stat : 1;
115 uint32_t err_crc : 1;
116 uint32_t err_dribble_bit : 1;
117 uint32_t err_rx_mii : 1;
118 uint32_t err_rx_wdt : 1;
119 uint32_t frm_type : 1;
120 uint32_t err_late_coll : 1;
121 uint32_t giant_frm : 1;
122 uint32_t last_desc : 1;
123 uint32_t first_desc : 1;
124 uint32_t vlan_tag : 1;
125 uint32_t err_overflow : 1;
126 uint32_t length_err : 1;
127 uint32_t s_addr_filt_fail : 1;
128 uint32_t err_desc : 1;
129 uint32_t err_summary : 1;
130 uint32_t frm_len : 14;
131 uint32_t d_addr_filt_fail : 1;
139 uint32_t rx_buf1_sz : 13;
141 uint32_t addr2_chained : 1;
142 uint32_t rx_end_of_ring : 1;
143 uint32_t rx_buf2_sz : 13;
145 uint32_t dis_int_compl : 1;
155 } quarkX1000_eth_rx_desc_t;
158 typedef struct quarkX1000_eth_meta {
160 volatile quarkX1000_eth_tx_desc_t tx_desc;
164 volatile quarkX1000_eth_rx_desc_t rx_desc;
168 #if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING
178 uint8_t pad[MIN_PAGE_SIZE -
179 (
sizeof(quarkX1000_eth_tx_desc_t) +
181 sizeof(quarkX1000_eth_rx_desc_t) +
186 #define LOG_PFX "quarkX1000_eth: "
188 #define MMIO_SZ 0x2000
190 #define MAC_CONF_14_RMII_100M BIT(14)
191 #define MAC_CONF_11_DUPLEX BIT(11)
192 #define MAC_CONF_3_TX_EN BIT(3)
193 #define MAC_CONF_2_RX_EN BIT(2)
195 #define OP_MODE_25_RX_STORE_N_FORWARD BIT(25)
196 #define OP_MODE_21_TX_STORE_N_FORWARD BIT(21)
197 #define OP_MODE_13_START_TX BIT(13)
198 #define OP_MODE_1_START_RX BIT(1)
200 #define REG_ADDR_MAC_CONF 0x0000
201 #define REG_ADDR_MACADDR_HI 0x0040
202 #define REG_ADDR_MACADDR_LO 0x0044
203 #define REG_ADDR_TX_POLL_DEMAND 0x1004
204 #define REG_ADDR_RX_POLL_DEMAND 0x1008
205 #define REG_ADDR_RX_DESC_LIST 0x100C
206 #define REG_ADDR_TX_DESC_LIST 0x1010
207 #define REG_ADDR_DMA_OPERATION 0x1018
210 static quarkX1000_eth_meta_t ATTR_BSS_DMA meta;
212 void quarkX1000_eth_setup(uintptr_t meta_phys_base);
215 SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_setup, drv, uintptr_t meta_phys_base)
218 uint32_t mac_tmp1, mac_tmp2;
219 quarkX1000_eth_rx_desc_t rx_desc;
220 quarkX1000_eth_tx_desc_t tx_desc;
221 quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta =
222 (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv);
224 prot_domains_enable_mmio();
227 PCI_MMIO_READL(drv, mac_tmp1, REG_ADDR_MACADDR_HI);
228 PCI_MMIO_READL(drv, mac_tmp2, REG_ADDR_MACADDR_LO);
230 prot_domains_disable_mmio();
235 mac_addr.addr[5] = (uint8_t)(mac_tmp1 >> 8);
236 mac_addr.addr[4] = (uint8_t)mac_tmp1;
237 mac_addr.addr[3] = (uint8_t)(mac_tmp2 >> 24);
238 mac_addr.addr[2] = (uint8_t)(mac_tmp2 >> 16);
239 mac_addr.addr[1] = (uint8_t)(mac_tmp2 >> 8);
240 mac_addr.addr[0] = (uint8_t)mac_tmp2;
242 printf(LOG_PFX
"MAC address = %02x:%02x:%02x:%02x:%02x:%02x.\n",
257 tx_desc.tx_end_of_ring = 1;
258 tx_desc.first_seg_in_frm = 1;
259 tx_desc.last_seg_in_frm = 1;
260 tx_desc.tx_end_of_ring = 1;
262 META_WRITEL(loc_meta->tx_desc.tdes0, tx_desc.tdes0);
263 META_WRITEL(loc_meta->tx_desc.tdes1, tx_desc.tdes1);
264 META_WRITEL(loc_meta->tx_desc.buf1_ptr,
265 (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS(
266 (uintptr_t)&loc_meta->tx_buf, meta_phys_base));
267 META_WRITEL(loc_meta->tx_desc.buf2_ptr, 0);
274 rx_desc.first_desc = 1;
275 rx_desc.last_desc = 1;
277 rx_desc.rx_end_of_ring = 1;
279 META_WRITEL(loc_meta->rx_desc.rdes0, rx_desc.rdes0);
280 META_WRITEL(loc_meta->rx_desc.rdes1, rx_desc.rdes1);
281 META_WRITEL(loc_meta->rx_desc.buf1_ptr,
282 (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS(
283 (uintptr_t)&loc_meta->rx_buf, meta_phys_base));
284 META_WRITEL(loc_meta->rx_desc.buf2_ptr, 0);
286 prot_domains_enable_mmio();
289 PCI_MMIO_WRITEL(drv, REG_ADDR_RX_DESC_LIST,
290 PROT_DOMAINS_META_OFF_TO_PHYS(
291 (uintptr_t)&loc_meta->rx_desc, meta_phys_base));
292 PCI_MMIO_WRITEL(drv, REG_ADDR_TX_DESC_LIST,
293 PROT_DOMAINS_META_OFF_TO_PHYS(
294 (uintptr_t)&loc_meta->tx_desc, meta_phys_base));
296 PCI_MMIO_WRITEL(drv, REG_ADDR_MAC_CONF,
298 MAC_CONF_14_RMII_100M |
306 PCI_MMIO_WRITEL(drv, REG_ADDR_DMA_OPERATION,
308 OP_MODE_25_RX_STORE_N_FORWARD |
310 OP_MODE_21_TX_STORE_N_FORWARD |
313 OP_MODE_13_START_TX |
317 prot_domains_disable_mmio();
319 printf(LOG_PFX
"Enabled 100M full-duplex mode.\n");
331 SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_poll, drv, uint16_t * frame_len)
333 uint16_t *loc_frame_len;
334 uint16_t frm_len = 0;
335 quarkX1000_eth_rx_desc_t tmp_desc;
336 quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta =
337 (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv);
339 PROT_DOMAINS_VALIDATE_PTR(loc_frame_len, frame_len,
sizeof(*frame_len));
341 META_READL(tmp_desc.rdes0, loc_meta->rx_desc.rdes0);
346 if(tmp_desc.own == 0) {
347 META_READL(tmp_desc.rdes1, loc_meta->rx_desc.rdes1);
348 if(tmp_desc.err_summary) {
350 LOG_PFX
"Error receiving frame: RDES0 = %08x, RDES1 = %08x.\n",
351 tmp_desc.rdes0, tmp_desc.rdes1);
355 frm_len = tmp_desc.frm_len;
357 MEMCPY_FROM_META(
uip_buf, loc_meta->rx_buf, frm_len);
362 META_WRITEL(loc_meta->rx_desc.rdes0, tmp_desc.rdes0);
364 prot_domains_enable_mmio();
369 PCI_MMIO_WRITEL(drv, REG_ADDR_RX_POLL_DEMAND, 1);
371 prot_domains_disable_mmio();
374 *loc_frame_len = frm_len;
386 SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_send, drv)
388 quarkX1000_eth_tx_desc_t tmp_desc;
389 quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta =
390 (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv);
394 META_READL(tmp_desc.tdes0, loc_meta->tx_desc.tdes0);
395 }
while(tmp_desc.own == 1);
397 META_READL(tmp_desc.tdes1, loc_meta->tx_desc.tdes1);
400 if(tmp_desc.err_summary) {
402 LOG_PFX
"Error transmitting frame: TDES0 = %08x, TDES1 = %08x.\n",
403 tmp_desc.tdes0, tmp_desc.tdes1);
413 META_WRITEL(loc_meta->tx_desc.tdes1, tmp_desc.tdes1);
417 META_WRITEL(loc_meta->tx_desc.tdes0, tmp_desc.tdes0);
419 prot_domains_enable_mmio();
424 PCI_MMIO_WRITEL(drv, REG_ADDR_TX_POLL_DEMAND, 1);
426 prot_domains_disable_mmio();
436 quarkX1000_eth_init(
void)
446 pci_command_enable(pci_addr, PCI_CMD_2_BUS_MST_EN | PCI_CMD_1_MEM_SPACE_EN);
448 printf(LOG_PFX
"Activated MMIO and DMA access.\n");
450 pci_addr.
reg_off = PCI_CONFIG_REG_BAR0;
452 PROT_DOMAINS_INIT_ID(drv);
454 pci_init(&drv, pci_addr, MMIO_SZ,
455 (uintptr_t)&meta,
sizeof(quarkX1000_eth_meta_t));
456 SYSCALLS_INIT(quarkX1000_eth_setup);
457 SYSCALLS_AUTHZ(quarkX1000_eth_setup, drv);
458 SYSCALLS_INIT(quarkX1000_eth_poll);
459 SYSCALLS_AUTHZ(quarkX1000_eth_poll, drv);
460 SYSCALLS_INIT(quarkX1000_eth_send);
461 SYSCALLS_AUTHZ(quarkX1000_eth_send, drv);
463 quarkX1000_eth_setup(prot_domains_lookup_meta_phys_base(&drv));
uip_len
The length of the packet in the uip_buf buffer.
uint32_t func
Function number.
#define __attribute__(nothing)
Define attribute to nothing since it isn't handled by IAR.
PCI configuration address.
uint32_t dev
Device number.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
#define uip_setethaddr(eaddr)
Specifiy the Ethernet MAC address.
Header file for the uIP TCP/IP stack.
Data associated with each protection domain that is owned by clients of that domain and used to ident...
#define UIP_BUFSIZE
The size of the uIP packet buffer.
uint32_t reg_off
Register/offset number.