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);