1 //-----------------------------------用户态 芯片驱动层----------------------------// 2 #include <stdio.h> 3 #include <unistd.h> 4 #include <fcntl.h> 5 #include <sys/stat.h> 6 #include <sys/types.h> 7 #include <sys/mman.h> 8 #include <pthread.h> 9 #include <sys/socket.h> 10 #include <netinet/in.h> 11 #include <arpa/inet.h> 12 13 #include <stdlib.h> 14 #include <sys/ioctl.h> 15 #include <net/if.h> 16 #include <errno.h> 17 #include <sys/wait.h> 18 #include <ctype.h> 19 #include <net/if_arp.h> 20 21 uint8 g_port_smi_addr_list[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16}; 22 uint8 g_port_smi_serdes_addr_list[] = {0, 0, 0, 0, 0xc, 0xd, 0xe}; 23 24 typedef struct shm_info{ 25 uint8 flag; 26 27 uint8 port[SCC_DIP_2_DPORT_NUM]; 28 29 }shm_info_t; 30 31 shm_info_t *g_shm_mem_addr; 32 33 34 //在用户态初始化时定义Linux内核映射文件, 35 //将初始值传递到内核态,后续可动态更新 36 uint8 sccSysMemMapInit(void) 37 { 38 int fd; 39 uint8 i = 0; 40 41 if( (fd = open("/proc/shmfile", O_RDWR)) < 0){ 42 printf("open /proc/shmfile error!\n"); 43 return ERROR; 44 } 45 46 g_shm_mem_addr = (shm_info_t *)mmap(NULL, SCC_MEM_MAP_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); // ignored, because we don't use "vm->pgoff" in driver. 47 if( MAP_FAILED == g_shm_mem_addr){ 48 printf("mmap() error:[%d]\n", errno); 49 return ERROR; 50 } 51 52 memset(g_shm_mem_addr, 0, sizeof(shm_info_t)); 53 54 for (i = 0; i < SCC_DIP_2_DPORT_NUM; i++){ 55 g_shm_mem_addr->port[i] = 0; 56 } 57 58 return OK; 59 } 60 61 62 uint8 sccSysMemMapFlagSet(uint8 enable) 63 { 64 if (TRUE != enable && FALSE != enable){ 65 return ERROR; 66 } 67 68 g_shm_mem_addr->flag = enable; 69 70 return OK; 71 } 72 73 74 uint8 sccSysMemMapFlagGet(uint8 *enable) 75 { 76 if (NULL == enable){ 77 return ERROR; 78 } 79 80 *enable = g_shm_mem_addr->flag; 81 82 return OK; 83 } 84 85 86 uint8 sccCtrlDevInit() 87 { 88 uint8 rc = OK; 89 90 rc = sccSysMemMapInit(); 91 92 return rc; 93 } 94 95 96 97 98 //--------------------------------------------------Linux内核 gianfar.c----------------// 99 100 #define PROC_SHM_FILE "shmfile" 101 102 struct proc_dir_entry *g_proc_file = NULL; 103 unsigned long g_shm_addr = 0; 104 105 #define DIP_2_DPORT_NUM 3 106 107 108 typedef struct mem_shm_info{ 109 unsigned char flag; 110 111 unsigned char port[DIP_2_DPORT_NUM]; 112 113 }mem_shm_info_t; 114 115 116 117 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) 118 { 119 int ret = 0; 120 unsigned char *ptr_data = NULL; 121 unsigned char port = 0; 122 mem_shm_info_t *info = NULL; 123 unsigned char port_num = 0; 124 unsigned char port_list[4] = {0}; 125 126 info = (mem_shm_info_t *)g_shm_addr; 127 if ( 0 == info->flag ){ 128 ret = gfar_start_xmit_real(skb, dev); 129 return ret; 130 } 131 132 ...... 133 } 134 135 136 static int gfar_recv_port_check(unsigned char *skbdata, unsigned char port) 137 { 138 139 mem_shm_info_t *info = NULL; 140 141 info = (mem_shm_info_t *)g_shm_addr; 142 143 /* ipv4 packet , dest ip */ 144 145 if (0 != info->port[port-1]){ 146 ... 147 } 148 149 return 0; 150 } 151 152 153 /* gfar_process_frame() -- handle one incoming packet if skb 154 * isn't NULL. */ 155 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, 156 int amount_pull) 157 { 158 ... 159 160 gfar_recv_port_check(); 161 162 ... 163 } 164 165 166 167 //Linux内核从用户态定义的文件名中,获取设置的值 168 int shm_mmap(struct file *filp, struct vm_area_struct *vma) 169 { 170 unsigned long page; 171 172 page = virt_to_phys((void *)g_shm_addr) >> PAGE_SHIFT; 173 174 if(remap_pfn_range(vma, vma->vm_start, page, (vma->vm_end - vma->vm_start), vma->vm_page_prot)) { 175 return -1; 176 } 177 vma->vm_flags |= VM_RESERVED; 178 printk("remap_pfn_rang page:[%lu] ok.\n", page); 179 180 return 0; 181 } 182 183 static const struct file_operations g_shm_fops ={ 184 .owner = THIS_MODULE, 185 .mmap = shm_mmap, 186 }; 187 188 189 static int shm_init(void) 190 { 191 g_proc_file = proc_create(PROC_SHM_FILE, 0, NULL, &g_shm_fops); 192 if (NULL == g_proc_file) { 193 printk("proc create failed\n"); 194 return -1; 195 } 196 197 g_shm_addr = __get_free_page(GFP_KERNEL); 198 if(!g_shm_addr) { 199 printk("Allocate memory failure!/n"); 200 return -1; 201 } else { 202 SetPageReserved(virt_to_page(g_shm_addr)); 203 printk("Allocate memory success!. The phy mem addr=%lx\n", __pa(g_shm_addr)); 204 } 205 206 return 0; 207 } 208 209 210 static void shm_fini(void) 211 { 212 ClearPageReserved(virt_to_page(g_shm_addr)); 213 free_page(g_shm_addr); 214 remove_proc_entry(PROC_SHM_FILE, NULL); 215 216 return; 217 } 218 219 static int __init gfar_init(void) 220 { 221 #ifdef CONFIG_GFAR_SW_PKT_STEERING 222 gfar_cpu_dev_init(); 223 #endif 224 gfar_1588_proc_init(gfar_match, sizeof(gfar_match)); 225 shm_init(); 226 227 return of_register_platform_driver(&gfar_driver); 228 } 229 230 static void __exit gfar_exit(void) 231 { 232 shm_fini(); 233 #ifdef CONFIG_GFAR_SW_PKT_STEERING 234 gfar_cpu_dev_exit(); 235 #endif 236 gfar_1588_proc_exit(); 237 of_unregister_platform_driver(&gfar_driver); 238 } 239 240 module_init(gfar_init); 241 module_exit(gfar_exit);