-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f57587e
Showing
16 changed files
with
772 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 Shotaro Gotanda, Masashi Ikarashi | ||
https://github.com/progrunner17/e1000/blob/master/LICENSE.txt | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
CC = gcc | ||
CFLAGS = -g -MMD -MP -Wall -Werror=implicit -pthread -std=gnu99 | ||
SRCS = main.c init.c util.c mem.c reg.c desc.c | ||
LIBS = checker.a | ||
OBJS = $(SRCS:.c=.o) | ||
DEPS= $(filter %.d, $(subst .o,.d, $(OBJS))) | ||
TARGET = driver | ||
|
||
|
||
TARGET_KEYWORD := I217 | ||
TARGET_DEFAULT_DRIVER := e1000e | ||
TARGET_PCI_BUS_ID:=$(if $(TARGET_PCI_BUS_ID),$(TARGET_PCI_BUS_ID),$(shell lspci -D | grep $(TARGET_KEYWORD) | cut -f 1 -d ' ' | head -n1)) | ||
TARGET_PCI_VID_DID=$(shell lspci -n -s $(TARGET_PCI_BUS_ID) | cut -f 3 -d ' ') | ||
TARGET_PCI_VID=$(shell echo $(TARGET_PCI_VID_DID) | cut -f 1 -d ':') | ||
TARGET_PCI_DID=$(shell echo $(TARGET_PCI_VID_DID) | cut -f 2 -d ':') | ||
TARGET_CURRENT_DRIVER=$(shell lspci -k -s $(TARGET_PCI_BUS_ID) | grep "Kernel driver in use:" | cut -f 2 -d ":" | tr -d " ") | ||
|
||
ARGS= | ||
|
||
|
||
|
||
default: $(TARGET) | ||
|
||
.PHONY: load restore run exec | ||
|
||
-include $(DEPS) | ||
|
||
run:load | ||
trap '$(MAKE) restore;' INT ; $(MAKE) exec ; $(MAKE) restore; | ||
|
||
exec: $(TARGET) | ||
sudo sh -c "echo 120 > /proc/sys/vm/nr_hugepages" | ||
sudo ./$(TARGET) $(ARGS) | ||
|
||
|
||
check: | ||
@lspci -vvxxx -n -k -s $(TARGET_PCI_BUS_ID) | ||
@echo " bus: $(TARGET_PCI_BUS_ID)" | ||
@echo " vendor: $(TARGET_PCI_VID)" | ||
@echo " device: $(TARGET_PCI_DID)" | ||
@echo "driver current: $(TARGET_CURRENT_DRIVER)" | ||
@echo " default: $(TARGET_DEFAULT_DRIVER)" | ||
|
||
load: | ||
ifneq ($(shell lspci -v -s $(TARGET_PCI_BUS_ID) | grep $(TARGET_DEFAULT_DRIVER)),) | ||
sudo modprobe uio_pci_generic | ||
sudo sh -c "echo '$(TARGET_PCI_VID) $(TARGET_PCI_DID)' > /sys/bus/pci/drivers/uio_pci_generic/new_id" | ||
sudo sh -c "echo -n $(TARGET_PCI_BUS_ID) > /sys/bus/pci/drivers/$(TARGET_CURRENT_DRIVER)/unbind" | ||
sudo sh -c "echo -n $(TARGET_PCI_BUS_ID) > /sys/bus/pci/drivers/uio_pci_generic/bind" | ||
endif | ||
|
||
restore: | ||
ifeq ($(shell lspci -v -s $(TARGET_PCI_BUS_ID) | grep $(TARGET_DEFAULT_DRIVER)),) | ||
sudo modprobe $(TARGET_DEFAULT_DRIVER) | ||
sudo sh -c "echo -n $(TARGET_PCI_BUS_ID) > /sys/bus/pci/drivers/$(TARGET_CURRENT_DRIVER)/unbind" | ||
sudo sh -c "echo -n $(TARGET_PCI_BUS_ID) > /sys/bus/pci/drivers/$(TARGET_DEFAULT_DRIVER)/bind" | ||
endif | ||
|
||
|
||
watch_irq: | ||
watch -n1 "cat /proc/interrupts" | ||
|
||
|
||
|
||
$(TARGET): $(OBJS) $(LIBS) | ||
$(CC) $(CFLAGS) -o $@ $^ | ||
|
||
|
||
clean: | ||
$(RM) $(TARGET) $(OBJS) $(DEPS) *~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# e1000 | ||
|
||
e1000e向けのデバイスドライバ | ||
|
||
## 使用方法 | ||
- `make run` | ||
- プログラムの実行 | ||
- `make check` | ||
- デバイスの状態チェック | ||
- `make clean` | ||
|
||
## PCに不調が出たら | ||
`make check`で「driver current」と「default」がどちらもe1000eであることを確認してください | ||
万が一「driver current」がuio_pci_genericとなっていた場合`make restore`を実行して下さい。 | ||
|
||
それでも直らない場合はPCを再起動してください。 | ||
|
||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#define CHECK_LEVEL ((check_level)CHECK_STRICT) | ||
|
||
#include <stdint.h> | ||
|
||
// Define check level. | ||
// When CHECK_NONE, these functions do nothing. | ||
#define CHECK_STRICT 2 | ||
#define CHECK_LOOSE 1 | ||
#define CHECK_NONE 0 | ||
|
||
typedef int check_level; | ||
|
||
|
||
void check_set_rqueue_head(check_level l, uint32_t val); | ||
void check_set_tqueue_head(check_level l, uint32_t val); | ||
void check_set_rqueue_tail(check_level l, uint32_t val); | ||
void check_set_tqueue_tail(check_level l, uint32_t val); | ||
void check_before_rqueue_enable(check_level l); | ||
void check_before_tqueue_enable(check_level l); | ||
void check_before_set_rdba(check_level l); | ||
void check_before_set_tdba(check_level l); | ||
void check_before_set_rdlen(check_level l); | ||
void check_before_set_tdlen(check_level l); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#include <stdio.h> | ||
#include <stdint.h> | ||
#include "mem.h" | ||
#define DANGER | ||
#include "reg.h" | ||
#include "desc.h" | ||
#include "checker.h" | ||
|
||
uint64_t get_mac_addr(void) { | ||
static uint64_t mac_addr = 0; | ||
if (mac_addr == 0) { | ||
uint32_t buf32; | ||
buf32 = read_reg_wrapper(RAL_OFFSET); | ||
mac_addr |= buf32; | ||
buf32 = read_reg_wrapper(RAH_OFFSET); | ||
mac_addr |= ((uint64_t)buf32 & 0xFFFFll) << 32; | ||
} | ||
return mac_addr; | ||
} | ||
|
||
void enable_receive(void) { | ||
check_before_rqueue_enable(CHECK_LEVEL); | ||
set_flags((uint32_t)RCTL_OFFSET, (uint32_t)RCTL_EN); | ||
} | ||
void enable_transmit(void) { | ||
check_before_tqueue_enable(CHECK_LEVEL); | ||
set_flags((uint32_t)TCTL_OFFSET, (uint32_t)TCTL_EN); | ||
} | ||
void disable_receive(void) { clear_flags((uint32_t)RCTL_OFFSET, (uint32_t)RCTL_EN); } | ||
void disable_transmit(void) { clear_flags((uint32_t)TCTL_OFFSET, (uint32_t)TCTL_EN); } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#pragma once | ||
#include "mem.h" | ||
uint64_t get_mac_addr(void); | ||
void enable_receive(void); | ||
void enable_transmit(void); | ||
void disable_receive(void); | ||
void disable_transmit(void); | ||
|
||
/* Receive Descriptor | ||
** Legacy Rx Descriptor (RCTL.DTYPE=00b,RFCTL.EXSTEN = 0b) | ||
** see spec p23 3.2.4 Receive Descriptor Format | ||
** 命名規則は基本的にはspec依存 | ||
** 例外 | ||
** buffer address -> addr | ||
** packet checksum -> csm | ||
** vlan tag -> vtag | ||
*/ | ||
typedef struct rdesc *Rdesc; | ||
struct rdesc { | ||
phys_addr addr; | ||
uint16_t length; | ||
uint16_t csm; | ||
uint8_t status; | ||
uint8_t errors; | ||
uint16_t vtag; | ||
}__attribute__((packed)); | ||
|
||
/* Transmit Descriptor | ||
** Legacy Transmit Descriptor (デスクリプタのdext = 1bで設定) | ||
** こちらの命名規則も基本的にはspec準拠 | ||
** その結果ステータスがstaとなっていたりする。(Rxではstatus) | ||
** reserved はstaにまとめた。 | ||
** | ||
*/ | ||
|
||
typedef struct tdesc *Tdesc; | ||
struct tdesc { | ||
phys_addr addr; | ||
uint16_t length; | ||
uint8_t cso; | ||
uint8_t cmd; | ||
uint8_t sta; | ||
uint8_t css; | ||
uint16_t special; | ||
}__attribute__((packed)); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
#include <fcntl.h> | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <sys/mman.h> | ||
#include <sys/types.h> | ||
#include <sys/uio.h> | ||
#include <unistd.h> | ||
|
||
#include "init.h" | ||
#include "util.h" | ||
#define DANGER | ||
#include "reg.h" | ||
#undef DANGER | ||
|
||
void init_pci() { | ||
int uiofd, configfd, csrfd; | ||
uint16_t buf16; | ||
|
||
uiofd = open("/dev/uio0", O_RDONLY); | ||
if (uiofd < 0) { | ||
perror("uio open:"); | ||
panic(""); | ||
} | ||
print_log("open /dev/uio0"); | ||
|
||
configfd = open("/sys/class/uio/uio0/device/config", O_RDWR); | ||
if (configfd < 0) { | ||
perror("config open:"); | ||
panic(""); | ||
} | ||
print_log("[init_pci] open /sys/class/uio/uio0/device/config"); | ||
|
||
// PCICMD see chipset c220 spec p365 | ||
// Bus Master Enable, Memory Space Enable, I/O Space Enable | ||
pread(configfd, &buf16, 2, 0x04); | ||
buf16 |= 0b111; | ||
pwrite(configfd, &buf16, 2, 0x04); | ||
print_log("config PCIe CTRL register"); | ||
|
||
csrfd = open("/sys/class/uio/uio0/device/resource0", O_RDWR); | ||
if (csrfd < 0) { | ||
perror("open"); | ||
panic(""); | ||
} | ||
print_log("[init_pci] open resource0"); | ||
|
||
// Internal registers and memories region is 128KB | ||
// see spec Table 13-1 PCI Base Address Registers (p271) | ||
void *base_addr = | ||
mmap(NULL, 1 << 17, PROT_READ | PROT_WRITE, MAP_SHARED, csrfd, 0); | ||
if (base_addr == MAP_FAILED) { | ||
perror("mmap"); | ||
panic(""); | ||
} | ||
set_regspace(base_addr); | ||
close(csrfd); | ||
print_log("[init_pci] map Internal registers and memories(resource0)"); | ||
print_log("[init_pci] regspace = %p", base_addr); | ||
} | ||
|
||
void init_dev(void) { | ||
uint16_t buf16; | ||
|
||
// Disable Interrupts; | ||
// see spec 14.4 Interrupts Duraing Initialization | ||
// cf. spec 13.3.32 Interrupt Mask Clear Register | ||
set_flags(IMC_OFFSET, 0xFFFFFFFF); | ||
|
||
print_log("[init_dev] Disable interrupts"); | ||
usleep(10000); | ||
print_log("wait 10ms"); | ||
|
||
// Global reset | ||
// see spec chapter 14.5(p490) | ||
// CHECK: are these really Global reset? | ||
set_flags(CTRL_OFFSET, CTRL_LRST | CTRL_RST | CTRL_PHY_RST); | ||
print_log("[init_dev] Global rest(Link reset & Device reset & PHY reset)"); | ||
|
||
// Disable Interrupts again; | ||
// see spec 14.4 Interrupts Duraing Initialization | ||
set_flags(IMC_OFFSET, 0xFFFFFFFF); | ||
print_log("[init_dev] Disable interrupt(again)"); | ||
|
||
// General Configuration | ||
// see spec 14.5 Global Reset and General Configuration | ||
// there seems to be device specific setting (ignore them here) | ||
// No use of XOFF flow control write 0 to FCAL, FCAH, FCT | ||
write_reg(FCAL_OFFSET, 0); | ||
write_reg(FCAH_OFFSET, 0); | ||
write_reg(FCT_OFFSET, 0); | ||
print_log("[init_dev] Configure XOFF Flow control(no use)"); | ||
|
||
// Setup PHY and Link | ||
// see spec 14.8 Link Setup Mechanisms and Control/Status Bit Summary | ||
|
||
// PHY Initialization | ||
// see spec 14.8.1 PHY Initialization | ||
// see spec 13.3.8 MDI Control Register | ||
buf16 = read_mdic(MDIC_PCTRL_POFFSET); | ||
buf16 |= MDIC_PCTRL_PHYRST; | ||
write_mdic(MDIC_PCTRL_POFFSET, buf16); | ||
print_log("[init_dev] PHY RESET from MDI"); | ||
|
||
// MAC/PHY Link Setup | ||
// see spec 14.8.2 MAC/PHY Link Setup | ||
clear_flags(CTRL_OFFSET, CTRL_FRCSPD | CTRL_FRCDPLX); | ||
set_flags(CTRL_OFFSET, CTRL_SLU | CTRL_RFCE); | ||
print_log("[init_dev] MAC/PHY Link Setup"); | ||
|
||
// Initialize all statistical counters | ||
// see spec 13.9 Statistics Registers | ||
// dee spec 14.10 Initialization of Statistics | ||
usleep(1000); | ||
for (int offset = 0x04000; offset <= 0x04124; offset += 0x04) { | ||
read_reg(offset); | ||
} | ||
print_log("[init_dev] reset statistical registers"); | ||
} | ||
|
||
void init_receive(void) { | ||
// see spec 14.6 Receive Initialization | ||
|
||
// MTA | ||
// see spec 13.4.1 Multicast Table Array | ||
for (int i = 0; i < MTA_LEN; i++) { | ||
write_reg(MTA_OFFSET + i * 4, 0); | ||
} | ||
print_log("[Receive] Reset Multicast Table Array"); | ||
|
||
// RCTL | ||
// see spec 13.3.34 Receive Control Register | ||
// set receive buffer size to 2KB & disable VFE | ||
clear_flags(RCTL_OFFSET, RCTL_BSIZE_MASK | RCTL_BSEX | RCTL_VFE); | ||
set_flags(RCTL_OFFSET, RCTL_BSIZE_2K | RCTL_UPE | RCTL_MPE |RCTL_LPE); | ||
print_log("[Receive] program RCTL"); | ||
} | ||
|
||
void init_transmit(void) { | ||
// TXDCTL values GRAN=1 WTHRESH=1(TXDCTL[21:16]) othes=0 | ||
write_reg(TXDCTL_OFFSET, TXDCTL_GRAN | (1 << 16)); | ||
print_log("[Transmit] program TXDCTL"); | ||
|
||
// TCTL CT=0x0F(TCTL[11:4]) COLD=0x03F(TCTL[21:12]) PSP=1b EN =1b others = 0 | ||
write_reg(TCTL_OFFSET, (0x0F << 4) | (0x03F << 12) | TCTL_PSP); | ||
print_log("[Transmit] program TCTL"); | ||
|
||
// Program TARC if use multi Txqueues | ||
// TODO: | ||
|
||
// Program TIPG | ||
// TODO: | ||
} | ||
|
||
void disable_interrupts(uint32_t flags) { set_flags(IMC_OFFSET, flags); } | ||
void enable_interrupts(uint32_t flags) { set_flags(IMS_OFFSET, flags); } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#pragma once | ||
// pciを初期化 | ||
void init_pci(void); | ||
void init_dev(void); | ||
void init_receive(void); | ||
void init_transmit(void); | ||
void enable_interrupts(uint32_t); | ||
void disable_interrupts(uint32_t); |
Oops, something went wrong.