blob: 7f4e6daf2ff651011a6060fcf68b9cd51efd9daf [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002 Copyright (C) 2018 Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <iostream>
19#include <memory>
20#include <string>
21
22#include "Queue.h"
23#include <iostream>
24#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040025#include <chrono>
26#include <thread>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000027
28#include "core.h"
29#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040030#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040031#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040032#include "state.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000033
34extern "C"
35{
36#include <bcmos_system.h>
37#include <bal_api.h>
38#include <bal_api_end.h>
39}
40
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040041#define NUM_OF_PON_PORTS 16
42const std::string technology = "xgspon";
43const std::string firmware_version = "BAL.2.6.0.1__Openolt.2018.09.05";
44
Shad Ansariedef2132018-08-10 22:14:50 +000045State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040046
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -070047static Status SchedAdd_(int intf_id, int onu_id, int agg_port_id, int sched_id, int pir);
48static Status SchedRemove_(int intf_id, int onu_id, int agg_port_id, int sched_id);
Shad Ansari627b5782018-08-13 22:49:32 +000049
Nicolas Palpacuer8ebaa262018-08-16 14:56:47 -040050static inline int mk_sched_id(int intf_id, int onu_id) {
51 return 1023 + intf_id * 112 + onu_id;
Shad Ansari627b5782018-08-13 22:49:32 +000052}
53
Nicolas Palpacuer8ebaa262018-08-16 14:56:47 -040054static inline int mk_agg_port_id(int intf_id, int onu_id) {
55 return 1023 + intf_id * 112 + onu_id;
Shad Ansari627b5782018-08-13 22:49:32 +000056}
57
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040058
59Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
60
61 device_info->set_vendor("EdgeCore");
62 device_info->set_model("asfvolt16");
63 device_info->set_hardware_version("");
64 device_info->set_firmware_version(firmware_version);
65 device_info->set_technology(technology);
66 device_info->set_onu_id_start(1);
67 device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
68 device_info->set_alloc_id_start(1024);
69 device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * NUM_OF_PON_PORTS - 1);
70 device_info->set_gemport_id_start(RSC_MGR_XGPON_MIN_BASE_SERVICE_PORT_ID);
71 device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * NUM_OF_PON_PORTS - 1);
72 device_info->set_pon_ports(NUM_OF_PON_PORTS);
73
74 return Status::OK;
75}
76
Shad Ansari627b5782018-08-13 22:49:32 +000077Status Enable_(int argc, char *argv[]) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +000078 bcmbal_access_terminal_cfg acc_term_obj;
79 bcmbal_access_terminal_key key = { };
80
Shad Ansariedef2132018-08-10 22:14:50 +000081 if (!state.is_activated()) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +000082 std::cout << "Enable OLT" << std::endl;
Shad Ansari627b5782018-08-13 22:49:32 +000083
84 bcmbal_init(argc, argv, NULL);
85
86 Status status = SubscribeIndication();
87 if (!status.ok()) {
88 std::cout << "ERROR: SubscribeIndication failed - "
89 << status.error_code() << ": " << status.error_message()
90 << std::endl;
91 return status;
92 }
93
Shad Ansarib7b0ced2018-05-11 21:53:32 +000094 key.access_term_id = DEFAULT_ATERM_ID;
95 BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
96 BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_UP);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040097 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
98 if (err) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +000099 std::cout << "ERROR: Failed to enable OLT" << std::endl;
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400100 return bcm_to_grpc_err(err, "Failed to enable OLT");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000101 }
Shad Ansariedef2132018-08-10 22:14:50 +0000102 init_stats();
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000103 }
Shad Ansariedef2132018-08-10 22:14:50 +0000104
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400105 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000106 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400107}
108
109Status Disable_() {
110 // bcmbal_access_terminal_cfg acc_term_obj;
111 // bcmbal_access_terminal_key key = { };
112 //
113 // if (state::is_activated) {
114 // std::cout << "Disable OLT" << std::endl;
115 // key.access_term_id = DEFAULT_ATERM_ID;
116 // BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
117 // BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
118 // bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
119 // if (err) {
120 // std::cout << "ERROR: Failed to disable OLT" << std::endl;
121 // return bcm_to_grpc_err(err, "Failed to disable OLT");
122 // }
123 // }
124 // //If already disabled, generate an extra indication ????
125 // return Status::OK;
126 //This fails with Operation Not Supported, bug ???
127
128 //TEMPORARY WORK AROUND
129 Status status = DisableUplinkIf_(0);
130 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000131 state.deactivate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400132 openolt::Indication ind;
133 openolt::OltIndication* olt_ind = new openolt::OltIndication;
134 olt_ind->set_oper_state("down");
135 ind.set_allocated_olt_ind(olt_ind);
136 std::cout << "Disable OLT, add an extra indication" << std::endl;
137 oltIndQ.push(ind);
138 }
139 return status;
140
141}
142
143Status Reenable_() {
144 Status status = EnableUplinkIf_(0);
145 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000146 state.activate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400147 openolt::Indication ind;
148 openolt::OltIndication* olt_ind = new openolt::OltIndication;
149 olt_ind->set_oper_state("up");
150 ind.set_allocated_olt_ind(olt_ind);
151 std::cout << "Reenable OLT, add an extra indication" << std::endl;
152 oltIndQ.push(ind);
153 }
154 return status;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000155}
156
157Status EnablePonIf_(uint32_t intf_id) {
158 bcmbal_interface_cfg interface_obj;
159 bcmbal_interface_key interface_key;
160
161 interface_key.intf_id = intf_id;
162 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
163
164 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
165 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
166
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400167 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
168 if (err) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000169 std::cout << "ERROR: Failed to enable PON interface: " << intf_id << std::endl;
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400170 return bcm_to_grpc_err(err, "Failed to enable PON interface");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000171 }
172
173 return Status::OK;
174}
175
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400176Status DisableUplinkIf_(uint32_t intf_id) {
177 bcmbal_interface_cfg interface_obj;
178 bcmbal_interface_key interface_key;
179
180 interface_key.intf_id = intf_id;
181 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
182
183 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
184 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
185
186 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
187 if (err) {
188 std::cout << "ERROR: Failed to disable Uplink interface: " << intf_id << std::endl;
189 return bcm_to_grpc_err(err, "Failed to disable Uplink interface");
190 }
191
192 return Status::OK;
193}
194
195Status EnableUplinkIf_(uint32_t intf_id) {
196 bcmbal_interface_cfg interface_obj;
197 bcmbal_interface_key interface_key;
198
199 interface_key.intf_id = intf_id;
200 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
201
202 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
203 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
204
205 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
206 if (err) {
207 std::cout << "ERROR: Failed to enable Uplink interface: " << intf_id << std::endl;
208 return bcm_to_grpc_err(err, "Failed to enable Uplink interface");
209 }
210
211 return Status::OK;
212}
213
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400214Status DisablePonIf_(uint32_t intf_id) {
215 bcmbal_interface_cfg interface_obj;
216 bcmbal_interface_key interface_key;
217
218 interface_key.intf_id = intf_id;
219 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
220
221 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
222 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
223
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400224 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
225 if (err) {
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400226 std::cout << "ERROR: Failed to disable PON interface: " << intf_id << std::endl;
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400227 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400228 }
229
230 return Status::OK;
231}
232
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000233Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700234 const char *vendor_id, const char *vendor_specific, uint32_t pir,
235 uint32_t agg_port_id, uint32_t sched_id) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000236
237 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
238 bcmbal_subscriber_terminal_key subs_terminal_key;
239 bcmbal_serial_number serial_num = {};
240 bcmbal_registration_id registration_id = {};
241
242 std::cout << "Enabling ONU " << onu_id << " on PON " << intf_id << std::endl;
243 std::cout << "Vendor Id " << vendor_id
244 << "Vendor Specific Id " << vendor_specific
Shad Ansari06101952018-07-25 00:22:09 +0000245 << "pir " << pir
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000246 << std::endl;
247
248 subs_terminal_key.sub_term_id = onu_id;
249 subs_terminal_key.intf_id = intf_id;
250 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
251
252 memcpy(serial_num.vendor_id, vendor_id, 4);
253 memcpy(serial_num.vendor_specific, vendor_specific, 4);
254 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, serial_number, serial_num);
255
Shad Ansaricb004c52018-05-30 18:07:23 +0000256#if 0
257 // Commenting out as this is causing issues with onu activation
258 // with BAL 2.6 (Broadcom CS5248819).
259
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000260 // FIXME - Use a default (all zeros) registration id.
261 memset(registration_id.arr, 0, sizeof(registration_id.arr));
262 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, registration_id, registration_id);
Shad Ansaricb004c52018-05-30 18:07:23 +0000263#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000264
265 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_UP);
266
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400267 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr));
268 if (err) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000269 std::cout << "ERROR: Failed to enable ONU: " << std::endl;
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400270 return bcm_to_grpc_err(err, "Failed to enable ONU");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000271 }
272
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700273 if (agg_port_id != 0) {
274 return SchedAdd_(intf_id, onu_id, agg_port_id, sched_id, pir);
275 } else {
276 return SchedAdd_(intf_id, onu_id, mk_agg_port_id(intf_id, onu_id), sched_id, pir);
277 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000278
279 //return Status::OK;
280}
281
Jonathan Davis70c21812018-07-19 15:32:10 -0400282Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
283 const char *vendor_id, const char *vendor_specific) {
284
Jonathan Davis70c21812018-07-19 15:32:10 -0400285 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
286 bcmbal_subscriber_terminal_key subs_terminal_key;
287
288 std::cout << "Deactivating ONU " << onu_id << " on PON " << intf_id << std::endl;
289 std::cout << "Vendor Id " << vendor_id
290 << "Vendor Specific Id " << vendor_specific
291 << std::endl;
292
293 subs_terminal_key.sub_term_id = onu_id;
294 subs_terminal_key.intf_id = intf_id;
295 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
296
297 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_DOWN);
298
299 if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr))) {
300 std::cout << "ERROR: Failed to deactivate ONU: " << std::endl;
301 return Status(grpc::StatusCode::INTERNAL, "Failed to deactivate ONU");
302 }
303
304 return Status::OK;
305}
306
307Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700308 const char *vendor_id, const char *vendor_specific,
309 uint32_t agg_port_id, uint32_t sched_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400310
311 // Need to deactivate before removing it (BAL rules)
312
313 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
314 // Sleep to allow the state to propagate
315 // We need the subscriber terminal object to be admin down before removal
316 // Without sleep the race condition is lost by ~ 20 ms
317 std::this_thread::sleep_for(std::chrono::milliseconds(100));
318
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700319 if (agg_port_id != 0) {
320 SchedRemove_(intf_id, onu_id, agg_port_id, sched_id);
321 } else {
322 SchedRemove_(intf_id, onu_id, mk_agg_port_id(intf_id, onu_id), sched_id);
323 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400324
Jonathan Davis70c21812018-07-19 15:32:10 -0400325 bcmos_errno err = BCM_ERR_OK;
326 bcmbal_subscriber_terminal_cfg cfg;
327 bcmbal_subscriber_terminal_key key = { };
328
329 std::cout << "Processing subscriber terminal cfg clear for sub_term_id = "
330 << onu_id << " and intf_id = " << intf_id << std::endl;
331
332 key.sub_term_id = onu_id ;
333 key.intf_id = intf_id ;
334
335 if (0 == key.sub_term_id)
336 {
337 std::cout << "Invalid Key to handle subscriber terminal clear subscriber_terminal_id = "
338 << onu_id << " Interface ID = " << intf_id << std::endl;
339 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
340 }
341
342 BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);
343
344 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
345 if (err != BCM_ERR_OK)
346 {
347 std::cout << "Failed to clear information for BAL subscriber_terminal_id = "
348 << onu_id << " Interface ID = " << intf_id << std::endl;
349 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
350 }
351
352 return Status::OK;;
353}
354
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000355#define MAX_CHAR_LENGTH 20
356#define MAX_OMCI_MSG_LENGTH 44
357Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
358 bcmbal_u8_list_u32_max_2048 buf; /* A structure with a msg pointer and length value */
359 bcmos_errno err = BCM_ERR_OK;
360
361 /* The destination of the OMCI packet is a registered ONU on the OLT PON interface */
362 bcmbal_dest proxy_pkt_dest;
363
364 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_ITU_OMCI_CHANNEL;
365 proxy_pkt_dest.u.itu_omci_channel.sub_term_id = onu_id;
366 proxy_pkt_dest.u.itu_omci_channel.intf_id = intf_id;
367
368 // ???
369 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
370 buf.len = MAX_OMCI_MSG_LENGTH;
371 } else {
372 buf.len = pkt.size()/2;
373 }
374
375 /* Send the OMCI packet using the BAL remote proxy API */
376 uint16_t idx1 = 0;
377 uint16_t idx2 = 0;
378 uint8_t arraySend[buf.len];
379 char str1[MAX_CHAR_LENGTH];
380 char str2[MAX_CHAR_LENGTH];
381 memset(&arraySend, 0, buf.len);
382
Nicolas Palpacuer135ce812018-08-30 09:04:34 -0400383 // std::cout << "Sending omci msg to ONU of length is "
384 // << buf.len
385 // << std::endl;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000386
387 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
388 sprintf(str1,"%c", pkt[idx1]);
389 sprintf(str2,"%c", pkt[++idx1]);
390 strcat(str1,str2);
391 arraySend[idx2] = strtol(str1, NULL, 16);
392 }
393
394 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
395 memcpy(buf.val, (uint8_t *)arraySend, buf.len);
Nicolas Palpacuer135ce812018-08-30 09:04:34 -0400396 //
397 // std::cout << "After converting bytes to hex "
398 // << buf.val << buf.len << std::endl;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000399
400 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
401
Nicolas Palpacuer135ce812018-08-30 09:04:34 -0400402 // std::cout << "OMCI request msg of length " << buf.len
403 // << " sent to ONU" << onu_id
404 // << " through PON " << intf_id << std::endl;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000405
406 free(buf.val);
407
408 return Status::OK;
409}
410
411Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
412 bcmos_errno err = BCM_ERR_OK;
413 bcmbal_dest proxy_pkt_dest;
414 bcmbal_u8_list_u32_max_2048 buf;
415
416 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_SUB_TERM,
417 proxy_pkt_dest.u.sub_term.sub_term_id = onu_id;
418 proxy_pkt_dest.u.sub_term.intf_id = intf_id;
419
420 buf.len = pkt.size();
421 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
422 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
423
424 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
425
426 std::cout << "Packet out of length " << buf.len
427 << " sent to ONU" << onu_id
428 << " through PON " << intf_id << std::endl;
429
430 free(buf.val);
431
432 return Status::OK;
433}
434
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400435Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
436 bcmos_errno err = BCM_ERR_OK;
437 bcmbal_dest proxy_pkt_dest;
438 bcmbal_u8_list_u32_max_2048 buf;
439
440 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_NNI,
441 proxy_pkt_dest.u.nni.intf_id = intf_id;
442
443 buf.len = pkt.size();
444 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
445 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
446
447 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
448
449 std::cout << "Packet out of length " << buf.len
450 << " sent through uplink port " << intf_id << std::endl;
451
452 free(buf.val);
453
454 return Status::OK;
455}
456
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000457Status FlowAdd_(uint32_t onu_id,
458 uint32_t flow_id, const std::string flow_type,
459 uint32_t access_intf_id, uint32_t network_intf_id,
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700460 uint32_t gemport_id, uint32_t sched_id,
461 uint32_t priority_value,
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000462 const ::openolt::Classifier& classifier,
463 const ::openolt::Action& action) {
464 bcmos_errno err;
465 bcmbal_flow_cfg cfg;
466 bcmbal_flow_key key = { };
467
468 std::cout << "flow add -"
469 << " intf_id:" << access_intf_id
470 << " onu_id:" << onu_id
471 << " flow_id:" << flow_id
472 << " flow_type:" << flow_type
473 << " gemport_id:" << gemport_id
474 << " network_intf_id:" << network_intf_id
475 << std::endl;
476
477 key.flow_id = flow_id;
478 if (flow_type.compare("upstream") == 0 ) {
479 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
480 } else if (flow_type.compare("downstream") == 0) {
481 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
482 } else {
483 std::cout << "Invalid flow type " << flow_type << std::endl;
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400484 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000485 }
486
487 BCMBAL_CFG_INIT(&cfg, flow, key);
488
489 BCMBAL_CFG_PROP_SET(&cfg, flow, admin_state, BCMBAL_STATE_UP);
490 BCMBAL_CFG_PROP_SET(&cfg, flow, access_int_id, access_intf_id);
491 BCMBAL_CFG_PROP_SET(&cfg, flow, network_int_id, network_intf_id);
492 BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_id, onu_id);
493 BCMBAL_CFG_PROP_SET(&cfg, flow, svc_port_id, gemport_id);
Nicolas Palpacuerd6cf5aa2018-07-16 15:14:39 -0400494 BCMBAL_CFG_PROP_SET(&cfg, flow, priority, priority_value);
495
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000496
497 {
498 bcmbal_classifier val = { };
499
500 if (classifier.o_tpid()) {
501 val.o_tpid = classifier.o_tpid();
502 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_O_TPID;
503 }
504
505 if (classifier.o_vid()) {
506 val.o_vid = classifier.o_vid();
507 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_O_VID;
508 }
509
510 if (classifier.i_tpid()) {
511 val.i_tpid = classifier.i_tpid();
512 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_I_TPID;
513 }
514
515 if (classifier.i_vid()) {
516 val.i_vid = classifier.i_vid();
517 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_I_VID;
518 }
519
520 if (classifier.o_pbits()) {
521 val.o_pbits = classifier.o_pbits();
522 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_O_PBITS;
523 }
524
525 if (classifier.i_pbits()) {
526 val.i_pbits = classifier.i_pbits();
527 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_I_PBITS;
528 }
529
530 if (classifier.eth_type()) {
531 val.ether_type = classifier.eth_type();
532 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_ETHER_TYPE;
533 }
534
535 /*
536 if (classifier.dst_mac()) {
537 val.dst_mac = classifier.dst_mac();
538 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_DST_MAC;
539 }
540
541 if (classifier.src_mac()) {
542 val.src_mac = classifier.src_mac();
543 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_SRC_MAC;
544 }
545 */
546
547 if (classifier.ip_proto()) {
548 val.ip_proto = classifier.ip_proto();
549 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_IP_PROTO;
550 }
551
552 /*
553 if (classifier.dst_ip()) {
554 val.dst_ip = classifier.dst_ip();
555 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_DST_IP;
556 }
557
558 if (classifier.src_ip()) {
559 val.src_ip = classifier.src_ip();
560 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_SRC_IP;
561 }
562 */
563
564 if (classifier.src_port()) {
565 val.src_port = classifier.src_port();
566 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_SRC_PORT;
567 }
568
569 if (classifier.dst_port()) {
570 val.dst_port = classifier.dst_port();
571 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_DST_PORT;
572 }
573
574 if (!classifier.pkt_tag_type().empty()) {
575 if (classifier.pkt_tag_type().compare("untagged") == 0) {
576 val.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_UNTAGGED;
577 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_PKT_TAG_TYPE;
578 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
579 val.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_SINGLE_TAG;
580 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_PKT_TAG_TYPE;
581 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
582 val.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG;
583 val.presence_mask = val.presence_mask | BCMBAL_CLASSIFIER_ID_PKT_TAG_TYPE;
584 }
585 }
586
587 BCMBAL_CFG_PROP_SET(&cfg, flow, classifier, val);
588 }
589
590 {
591 bcmbal_action val = { };
592
593 const ::openolt::ActionCmd& cmd = action.cmd();
594
595 if (cmd.add_outer_tag()) {
596 val.cmds_bitmask |= BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG;
597 val.presence_mask |= BCMBAL_ACTION_ID_CMDS_BITMASK;
598 }
599
600 if (cmd.remove_outer_tag()) {
601 val.cmds_bitmask |= BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG;
602 val.presence_mask |= BCMBAL_ACTION_ID_CMDS_BITMASK;
603 }
604
605 if (cmd.trap_to_host()) {
606 val.cmds_bitmask |= BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST;
607 val.presence_mask |= BCMBAL_ACTION_ID_CMDS_BITMASK;
608 }
609
610 if (action.o_vid()) {
611 val.o_vid = action.o_vid();
612 val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_O_VID;
613 }
614
615 if (action.o_pbits()) {
616 val.o_pbits = action.o_pbits();
617 val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_O_PBITS;
618 }
619
620 if (action.o_tpid()) {
621 val.o_tpid = action.o_tpid();
622 val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_O_TPID;
623 }
624
625 if (action.i_vid()) {
626 val.i_vid = action.i_vid();
627 val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_I_VID;
628 }
629
630 if (action.i_pbits()) {
631 val.i_pbits = action.i_pbits();
632 val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_I_PBITS;
633 }
634
635 if (action.i_tpid()) {
636 val.i_tpid = action.i_tpid();
637 val.presence_mask = val.presence_mask | BCMBAL_ACTION_ID_I_TPID;
638 }
639
640 BCMBAL_CFG_PROP_SET(&cfg, flow, action, val);
641 }
642
643 {
644 bcmbal_tm_sched_id val;
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700645 if (sched_id != 0) {
646 val = sched_id;
647 } else {
Nicolas Palpacuer8ebaa262018-08-16 14:56:47 -0400648 val = (bcmbal_tm_sched_id) mk_sched_id(access_intf_id, onu_id);
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700649 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000650 BCMBAL_CFG_PROP_SET(&cfg, flow, dba_tm_sched_id, val);
651 }
652
Shad Ansari06101952018-07-25 00:22:09 +0000653 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
654 bcmbal_tm_queue_ref val = { };
655 val.sched_id = access_intf_id << 7 | onu_id;
656 val.queue_id = 0;
657 BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val);
658 }
659
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400660 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
661 if (err) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000662 std::cout << "ERROR: flow add failed" << std::endl;
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400663 return bcm_to_grpc_err(err, "flow add failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000664 }
665
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400666 // register_new_flow(key);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400667
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000668 return Status::OK;
669}
670
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400671Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
672
673 bcmbal_flow_cfg cfg;
674 bcmbal_flow_key key = { };
675
676 key.flow_id = (bcmbal_flow_id) flow_id;
677 key.flow_id = flow_id;
678 if (flow_type.compare("upstream") == 0 ) {
679 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
680 } else if (flow_type.compare("downstream") == 0) {
681 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
682 } else {
683 std::cout << "Invalid flow type " << flow_type << std::endl;
684 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
685 }
686
687 BCMBAL_CFG_INIT(&cfg, flow, key);
688
689
690 bcmos_errno err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
691 if (err) {
692 std::cout << "Error " << err << " while removing flow "
693 << flow_id << ", " << flow_type << std::endl;
694 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
695 }
696
697 std::cout << "Flow " << flow_id << ", " << flow_type << " removed";
698 return Status::OK;
699}
700
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700701Status SchedAdd_(int intf_id, int onu_id, int agg_port_id, int sched_id, int pir) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400702
703 bcmos_errno err;
704
705 /* Downstream */
706
707 /* Create subscriber's tm_sched */
708 {
709 bcmbal_tm_sched_cfg cfg;
710 bcmbal_tm_sched_key key = { };
711 key.dir = BCMBAL_TM_SCHED_DIR_DS;
712 key.id = intf_id << 7 | onu_id;
713 BCMBAL_CFG_INIT(&cfg, tm_sched, key);
714
715 bcmbal_tm_sched_owner owner = { };
716 owner.type = BCMBAL_TM_SCHED_OWNER_TYPE_SUB_TERM;
717 owner.u.sub_term.intf_id = intf_id;
718 owner.u.sub_term.sub_term_id = onu_id;
719 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, owner);
720
721 bcmbal_tm_sched_parent parent = { };
722 parent.sched_id = intf_id + 16384;
723 parent.presence_mask = parent.presence_mask | BCMBAL_TM_SCHED_PARENT_ID_SCHED_ID;
724 parent.weight = 1;
725 parent.presence_mask = parent.presence_mask | BCMBAL_TM_SCHED_PARENT_ID_WEIGHT;
726 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_parent, parent);
727
728 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, sched_type, BCMBAL_TM_SCHED_TYPE_WFQ);
729
730 bcmbal_tm_shaping shaping = { };
731 shaping.pir = pir;
732 shaping.presence_mask = shaping.presence_mask | BCMBAL_TM_SHAPING_ID_PIR;
733 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, rate, shaping);
734
735 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &cfg.hdr);
736 if (err) {
737 std::cout << "ERROR: Failed to create subscriber downstream sched"
738 << " id:" << key.id
739 << " intf_id:" << intf_id
740 << " onu_id:" << onu_id << std::endl;
741 return bcm_to_grpc_err(err, "Failed to create subscriber downstream sched");
742 }
743 }
744
745 /* Create tm_queue */
746 {
747 bcmbal_tm_queue_cfg cfg;
748 bcmbal_tm_queue_key key = { };
749 key.sched_id = intf_id << 7 | onu_id;
750 key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
751 key.id = 0;
752
753 BCMBAL_CFG_INIT(&cfg, tm_queue, key);
754 BCMBAL_CFG_PROP_SET(&cfg, tm_queue, weight, 1);
755 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &cfg.hdr);
756
757 if (err) {
758 std::cout << "ERROR: Failed to create subscriber downstream tm queue"
759 << " id: " << key.id
760 << " sched_id: " << key.sched_id
761 << " intf_id: " << intf_id
762 << " onu_id: " << onu_id << std::endl;
763 return bcm_to_grpc_err(err, "Failed to create subscriber downstream tm queue");
764 }
765
766 }
767
768 /* Upstream */
769
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000770 bcmbal_tm_sched_cfg cfg;
771 bcmbal_tm_sched_key key = { };
772 bcmbal_tm_sched_type sched_type;
773
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700774 if (sched_id != 0) {
775 key.id = sched_id;
776 } else {
Nicolas Palpacuer8ebaa262018-08-16 14:56:47 -0400777 key.id = mk_sched_id(intf_id, onu_id);
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700778 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000779 key.dir = BCMBAL_TM_SCHED_DIR_US;
780
781 BCMBAL_CFG_INIT(&cfg, tm_sched, key);
782
783 {
784 bcmbal_tm_sched_owner val = { };
785
786 val.type = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT;
787 val.u.agg_port.intf_id = (bcmbal_intf_id) intf_id;
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400788 val.u.agg_port.presence_mask = val.u.agg_port.presence_mask | BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_INTF_ID;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000789 val.u.agg_port.sub_term_id = (bcmbal_sub_id) onu_id;
790 val.u.agg_port.presence_mask = val.u.agg_port.presence_mask | BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_SUB_TERM_ID;
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400791 val.u.agg_port.agg_port_id = (bcmbal_aggregation_port_id) agg_port_id;
792 val.u.agg_port.presence_mask = val.u.agg_port.presence_mask | BCMBAL_TM_SCHED_OWNER_AGG_PORT_ID_AGG_PORT_ID;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000793
794 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, val);
795 }
796
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400797 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400798 if (err) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000799 std::cout << "ERROR: Failed to create upstream DBA sched"
800 << " id:" << key.id
801 << " intf_id:" << intf_id
802 << " onu_id:" << onu_id << std::endl;
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400803 return bcm_to_grpc_err(err, "Failed to create upstream DBA sched");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000804 }
805 std::cout << "create upstream DBA sched"
806 << " id:" << key.id
807 << " intf_id:" << intf_id
808 << " onu_id:" << onu_id << std::endl;
809
810 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000811}
Jonathan Davis70c21812018-07-19 15:32:10 -0400812
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700813Status SchedRemove_(int intf_id, int onu_id, int agg_port_id, int sched_id) {
Jonathan Davis70c21812018-07-19 15:32:10 -0400814
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400815 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -0400816
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400817 /* Upstream */
Jonathan Davis70c21812018-07-19 15:32:10 -0400818
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400819 bcmbal_tm_sched_cfg tm_cfg_us;
820 bcmbal_tm_sched_key tm_key_us = { };
821
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700822 if (sched_id != 0) {
823 tm_key_us.id = sched_id;
824 } else {
Nicolas Palpacuer8ebaa262018-08-16 14:56:47 -0400825 tm_key_us.id = mk_sched_id(intf_id, onu_id);
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -0700826 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400827 tm_key_us.dir = BCMBAL_TM_SCHED_DIR_US;
828
829 BCMBAL_CFG_INIT(&tm_cfg_us, tm_sched, tm_key_us);
830
831 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(tm_cfg_us.hdr));
832 if (err) {
833 std::cout << "ERROR: Failed to remove upstream DBA sched"
834 << " id:" << tm_key_us.id
Jonathan Davis70c21812018-07-19 15:32:10 -0400835 << " intf_id:" << intf_id
836 << " onu_id:" << onu_id << std::endl;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400837 return Status(grpc::StatusCode::INTERNAL, "Failed to remove upstream DBA sched");
Jonathan Davis70c21812018-07-19 15:32:10 -0400838 }
839
840 std::cout << "remove upstream DBA sched"
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400841 << " id:" << tm_key_us.id
842 << " intf_id:" << intf_id
843 << " onu_id:" << onu_id << std::endl;
844
845 /* Downstream */
846
847 // Queue
848
849 bcmbal_tm_queue_cfg queue_cfg;
850 bcmbal_tm_queue_key queue_key = { };
851 queue_key.sched_id = intf_id << 7 | onu_id;
852 queue_key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
853 queue_key.id = 0;
854
855 BCMBAL_CFG_INIT(&queue_cfg, tm_queue, queue_key);
856
857 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(queue_cfg.hdr));
858 if (err) {
859 std::cout << "ERROR: Failed to remove downstream tm queue"
860 << " id:" << queue_key.id
861 << " sched_id:" << queue_key.sched_id
862 << " intf_id:" << intf_id
863 << " onu_id:" << onu_id << std::endl;
864 return Status(grpc::StatusCode::INTERNAL, "Failed to remove downstream tm queue");
865 }
866
867 std::cout << "remove upstream DBA sched"
868 << " id:" << queue_key.id
869 << " sched_id:" << queue_key.sched_id
870 << " intf_id:" << intf_id
871 << " onu_id:" << onu_id << std::endl;
872
873 // Sheduler
874
875 bcmbal_tm_sched_cfg tm_cfg_ds;
876 bcmbal_tm_sched_key tm_key_ds = { };
877 tm_key_ds.dir = BCMBAL_TM_SCHED_DIR_DS;
878 tm_key_ds.id = intf_id << 7 | onu_id;
879 BCMBAL_CFG_INIT(&tm_cfg_ds, tm_sched, tm_key_ds);
880
881 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(tm_cfg_ds.hdr));
882 if (err) {
883 std::cout << "ERROR: Failed to remove sub downstream sched"
884 << " id:" << tm_key_us.id
885 << " intf_id:" << intf_id
886 << " onu_id:" << onu_id << std::endl;
887 return Status(grpc::StatusCode::INTERNAL, "Failed to remove sub downstream sched");
888 }
889
890 std::cout << "remove sub downstream sched"
891 << " id:" << tm_key_us.id
Jonathan Davis70c21812018-07-19 15:32:10 -0400892 << " intf_id:" << intf_id
893 << " onu_id:" << onu_id << std::endl;
894
895 return Status::OK;
896 //return 0;
897}