1#include "defs.h"
2#include <linux/sockios.h>
3#include "switch-api.h"
4#include <unistd.h>
5#include <sys/ioctl.h>
6
7static void
8IpAddrToMacAddr(uint32 group, fal_mac_addr_t *mac)
9{
10    group = ntohl(group);
11
12    mac->addr[0] = 0x01;
13    mac->addr[1] = 0x00;
14    mac->addr[2] = 0x5e;
15    mac->addr[3] = (group >> 16) & 0x7f;
16    mac->addr[4] = (group >> 8) & 0xff;
17    mac->addr[5] = group & 0xff;
18
19}
20
21#if 0
22static void
23error_print(sw_error_t rtn)
24{
25	switch (rtn) {
26    case SW_FAIL:{
27        atlog(LOG_WARNING, 0, "Operation failed\n");
28        break;
29    }
30    case SW_BAD_VALUE:{
31        atlog(LOG_WARNING, 0, "Illegal value\n");
32        break;
33    }
34    case SW_OUT_OF_RANGE:{
35        atlog(LOG_WARNING, 0, "Value is out of range\n");
36        break;
37    }
38    case SW_BAD_PARAM:{
39        atlog(LOG_WARNING, 0, "Illegal parameter(s)\n");
40        break;
41    }
42    case SW_BAD_PTR:{
43        atlog(LOG_WARNING, 0, "Illegal pointer value\n");
44        break;
45    }
46    case SW_BAD_LEN:{
47        atlog(LOG_WARNING, 0, "Wrong length\n");
48        break;
49    }
50    case SW_READ_ERROR:{
51        atlog(LOG_WARNING, 0, "Read operation failed\n");
52        break;
53    }
54    case SW_WRITE_ERROR:{
55        atlog(LOG_WARNING, 0, "Write operation failed\n");
56        break;
57    }
58    case SW_CREATE_ERROR:{
59        atlog(LOG_WARNING, 0, "Fail in creating an entry\n");
60        break;
61    }
62    case SW_DELETE_ERROR:{
63        atlog(LOG_WARNING, 0, "Fail in deleteing an entry\n");
64        break;
65    }
66    case SW_NOT_FOUND:{
67        atlog(LOG_WARNING, 0, "Entry not found\n");
68        break;
69    }
70    case SW_NO_CHANGE:{
71        atlog(LOG_WARNING, 0, "The parameter(s) is the same\n");
72        break;
73    }
74    case SW_NO_MORE:{
75        atlog(LOG_WARNING, 0, "No more entry found \n");
76        break;
77    }
78    case SW_NO_SUCH:{
79        atlog(LOG_WARNING, 0, "No such entry \n");
80        break;
81    }
82    case SW_ALREADY_EXIST:{
83        atlog(LOG_WARNING, 0, "Tried to create existing entry \n");
84        break;
85    }
86    case SW_FULL:{
87        atlog(LOG_WARNING, 0, "Table is full \n");
88        break;
89    }
90    case SW_EMPTY:{
91        atlog(LOG_WARNING, 0, "Table is empty \n");
92        break;
93    }
94    case SW_NOT_SUPPORTED:{
95        atlog(LOG_WARNING, 0, "This request is not support   \n");
96        break;
97    }
98    case SW_NOT_IMPLEMENTED:{
99        atlog(LOG_WARNING, 0, "This request is not implemented \n");
100        break;
101    }
102    case SW_NOT_INITIALIZED:{
103        atlog(LOG_WARNING, 0, "The item is not initialized \n");
104        break;
105    }
106    case SW_BUSY:{
107        atlog(LOG_WARNING, 0, "Operation is still running n");
108        break;
109    }
110    case SW_TIMEOUT:{
111        atlog(LOG_WARNING, 0, "Operation Time Out \n");
112        break;
113    }
114    case SW_DISABLE:{
115        atlog(LOG_WARNING, 0, "Operation is disabled \n");
116        break;
117    }
118    case SW_NO_RESOURCE:{
119        atlog(LOG_WARNING, 0, "Resource not available (memory ...)\n");
120        break;
121    }
122    case SW_INIT_ERROR:{
123        atlog(LOG_WARNING, 0, "Error occured while INIT process\n");
124        break;
125    }
126    case SW_NOT_READY:{
127        atlog(LOG_WARNING, 0, "The other side is not ready yet \n");
128        break;
129    }
130    case SW_OUT_OF_MEM:{
131        atlog(LOG_WARNING, 0, "Cpu memory allocation failed\n");
132        break;
133    }
134    case SW_ABORTED:{
135        atlog(LOG_WARNING, 0, "Operation has been aborted.\n");
136        break;
137    }
138
139    default:
140        atlog(LOG_WARNING, 0, "ioctl error return code <%d>\n", rtn);
141    }
142}
143#endif
144
145int addMFdb(uint32 group, uint32 port){
146
147
148    int s = -1;
149    struct ifreq ifr = {};
150    arl_struct_t arl;
151    fal_mac_addr_t macAddr;
152
153    if(port > 31) return -1;
154
155    if(0 > (s=socket(AF_INET, SOCK_DGRAM, 0))) {
156        return -1;
157    }
158
159    memcpy(ifr.ifr_name, IF_NAME, IFNAMSIZ);
160    IpAddrToMacAddr(group, &macAddr);
161    memcpy(&arl.hwaddr,&macAddr,6);
162
163    arl.port_map = port;
164    arl.sa_drop = 0;
165
166    memcpy(&ifr.ifr_ifru.ifru_mtu,&arl,sizeof(arl_struct_t));
167
168    if (ioctl(s, SIOCDEVPRIVATE|0xd, &ifr) < 0) {
169        close(s);
170        return -1;
171    }
172    atlog(LOG_DEBUG, 0, "addMFdb group %x port %d.\n",group,port);
173    close(s);
174    return 0;
175}
176
177int delMFdb(uint32 group){
178
179    int s = -1;
180    struct ifreq ifr = {};
181    arl_struct_t arl;
182    fal_mac_addr_t macAddr;
183
184    if(0 >= (s=socket(AF_INET, SOCK_DGRAM, 0))) {
185        return -1;
186    }
187
188    memcpy(ifr.ifr_name, IF_NAME, IFNAMSIZ);
189    IpAddrToMacAddr(group, &macAddr);
190    memcpy(&arl.hwaddr,&macAddr,6);
191
192    memcpy(&ifr.ifr_ifru.ifru_mtu,&arl,sizeof(arl_struct_t));
193
194    if (ioctl(s, ATHSIOCDEVPRIVATE|0xe, &ifr) < 0) {
195        close(s);
196        return -1;
197    }
198
199    atlog(LOG_DEBUG, 0, "delMFdb group %x.OK.\n",group);
200    close(s);
201    return 0;
202}
203
204//0: switch off the unkown multicast packets over vlan. 1: allow the unknown multicaset packets over vlans.
205int setMultiOnVlan(int enable)
206{
207    int s = -1;
208    struct ifreq ifr;
209
210    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
211        return -1;
212
213    memcpy(ifr.ifr_name, IF_NAME, IFNAMSIZ);
214
215    ifr.ifr_ifru.ifru_ivalue = enable;
216
217    if (ioctl(s, ATHSIOCDEVPRIVATE|0xf, &ifr) != 0) {
218	   close(s);
219	   return -1;
220    }
221
222    close(s);    atlog(LOG_DEBUG, 0,"setMultiOnVlan %d.\n",enable);
223    return 0;
224}
225
226
227int enableHwIGMPS()
228{
229    int s = -1;
230    struct ifreq ifr;
231    uint32 port_id;
232
233    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
234        return -1;
235
236    memcpy(ifr.ifr_name, IF_NAME, IFNAMSIZ);
237    for(port_id = 1; port_id <= SW_MAX_NR_PORTS; port_id++){
238
239        ifr.ifr_ifru.ifru_ivalue = port_id;
240
241        if (ioctl(s, ATHSIOCDEVPRIVATE|0x8, &ifr) != 0) {
242	   close(s);
243	   return -1;
244        }
245    }
246    close(s);    atlog(LOG_DEBUG, 0,"enableHwIGMPS OK.\n");
247    return 0;
248}
249
250int disableHwIGMPS()
251{
252    int s = -1;
253    struct ifreq ifr;
254    uint32 port_id;
255
256    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
257        return -1;
258
259    memcpy(ifr.ifr_name, IF_NAME, IFNAMSIZ);
260    for(port_id = 1; port_id <= SW_MAX_NR_PORTS; port_id++){
261
262        ifr.ifr_ifru.ifru_ivalue = port_id;
263
264        if (ioctl(s, ATHSIOCDEVPRIVATE|0x9, &ifr) != 0) {
265	   close(s);
266	   return -1;
267        }
268    }
269    close(s);
270    atlog(LOG_DEBUG, 0,"disableHwIGMPS OK.\n");
271    return 0;
272}
273