blob: c9781ffd78827c33af2a912c5f32914469a77aa3 [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
Craig Lutgen88a22ad2018-10-04 12:30:46 -050028#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000029#include "core.h"
30#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040031#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040032#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040033#include "state.h"
Craig Lutgen88a22ad2018-10-04 12:30:46 -050034#include "utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000035
36extern "C"
37{
38#include <bcmos_system.h>
39#include <bal_api.h>
40#include <bal_api_end.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040041// FIXME : dependency problem
42// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040043// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000044}
Craig Lutgen19512312018-11-02 10:14:46 -050045// These need patched into bal_model_types.h directly. But, with above extern "C", it cannot be done
46inline bcmbal_action_cmd_id& operator|=(bcmbal_action_cmd_id& a, bcmbal_action_cmd_id b) {return a = static_cast<bcmbal_action_cmd_id>(static_cast<int>(a) | static_cast<int>(b));}
47inline bcmbal_action_id& operator|=(bcmbal_action_id& a, bcmbal_action_id b) {return a = static_cast<bcmbal_action_id>(static_cast<int>(a) | static_cast<int>(b));}
48inline bcmbal_classifier_id& operator|=(bcmbal_classifier_id& a, bcmbal_classifier_id b) {return a = static_cast<bcmbal_classifier_id>(static_cast<int>(a) | static_cast<int>(b));}
49inline bcmbal_tm_sched_owner_agg_port_id& operator|=(bcmbal_tm_sched_owner_agg_port_id& a, bcmbal_tm_sched_owner_agg_port_id b) {return a = static_cast<bcmbal_tm_sched_owner_agg_port_id>(static_cast<int>(a) | static_cast<int>(b));}
50inline bcmbal_tm_sched_parent_id& operator|=(bcmbal_tm_sched_parent_id& a, bcmbal_tm_sched_parent_id b) {return a = static_cast<bcmbal_tm_sched_parent_id>(static_cast<int>(a) | static_cast<int>(b));}
51inline bcmbal_tm_shaping_id& operator|=(bcmbal_tm_shaping_id& a, bcmbal_tm_shaping_id b) {return a = static_cast<bcmbal_tm_shaping_id>(static_cast<int>(a) | static_cast<int>(b));}
Shad Ansarib7b0ced2018-05-11 21:53:32 +000052
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040053dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
54dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
55
Craig Lutgen88a22ad2018-10-04 12:30:46 -050056#define MAX_SUPPORTED_INTF 16
57#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040058
Craig Lutgen88a22ad2018-10-04 12:30:46 -050059static unsigned int num_of_nni_ports = 0;
60static unsigned int num_of_pon_ports = 0;
Craig Lutgenb2601f02018-10-23 13:04:31 -050061static std::string intf_technologies[MAX_SUPPORTED_INTF];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050062static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050063static const std::string MIXED_TECH("mixed");
64static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -080065static unsigned int OPENOLT_FIELD_LEN = 200;
Craig Lutgen88a22ad2018-10-04 12:30:46 -050066static std::string firmware_version = "Openolt.2018.10.04";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040067
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -070068const uint32_t tm_upstream_sched_id_start = 18432;
69const uint32_t tm_downstream_sched_id_start = 16384;
70const uint32_t tm_queue_id_start = 4; //0 to 3 are default queues. Lets not use them.
71const std::string upstream = "upstream";
72const std::string downstream = "downstream";
73
Shad Ansariedef2132018-08-10 22:14:50 +000074State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040075
Craig Lutgen967a1d02018-11-27 10:41:51 -060076static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
77static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
78static std::map<uint32_t, std::set<uint32_t> > port_to_flows; // For mapping logical ports to downstream flows
79static std::map<uint32_t, uint32_t> port_to_alloc;
80static bcmos_fastlock flow_lock;
81
82#define MIN_ALLOC_ID_GPON 256
83#define MIN_ALLOC_ID_XGSPON 1024
84
85Status SchedAdd_(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -070086 uint32_t alloc_id, openolt::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
Girish Gowdrue075c642019-01-23 04:05:53 -080087 openolt::SchedulingPolicy sched_policy, openolt::TrafficShapingInfo traffic_shaping_info);
Craig Lutgen967a1d02018-11-27 10:41:51 -060088static Status SchedRemove_(std::string direction, int intf_id, int onu_id, int uni_id, uint32_t port_no, int alloc_id);
Shad Ansari627b5782018-08-13 22:49:32 +000089
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -070090static inline int mk_sched_id(int intf_id, int onu_id, std::string direction) {
91 if (direction.compare(upstream) == 0) {
92 return tm_upstream_sched_id_start + intf_id;
93 } else if (direction.compare(downstream) == 0) {
94 return tm_downstream_sched_id_start + intf_id;
95 }
96 else {
97 BCM_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
98 return 0;
99 }
100}
101
Craig Lutgen967a1d02018-11-27 10:41:51 -0600102static inline int mk_queue_id(int pon_intf_id, int onu_id, int uni_id, uint32_t port_no, uint32_t alloc_id) {
103 (void) uni_id; // unused
104 if(port_no == 0) return tm_queue_id_start + pon_intf_id * 32 + onu_id; // old style
105
106 int start = intf_technologies[pon_intf_id] == "gpon" ? MIN_ALLOC_ID_GPON : MIN_ALLOC_ID_XGSPON; // offset built into all alloc Ids
107 return tm_queue_id_start + alloc_id - start; // use alloc_id as a unique queue id. It is unique per UNI, and in the range of IDs supported by BAL
Shad Ansari627b5782018-08-13 22:49:32 +0000108}
109
Nicolas Palpacuer8ebaa262018-08-16 14:56:47 -0400110static inline int mk_agg_port_id(int intf_id, int onu_id) {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500111 if (board_technology == "gpon") return 511 + intf_id * 32 + onu_id;
Shad Ansari0c6fa3e2018-09-26 17:43:21 +0000112 return 1023 + intf_id * 32 + onu_id;
Shad Ansari627b5782018-08-13 22:49:32 +0000113}
114
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800115char* openolt_read_sysinfo(char* field_name, char* field_val)
116{
117 FILE *fp;
118 /* Prepare the command*/
119 char command[150];
120
121 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
122 /* Open the command for reading. */
123 fp = popen(command, "r");
124 if (fp == NULL) {
125 /*The client has to check for a Null field value in this case*/
126 BCM_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
127 return field_val;
128 }
129
130 /*Read the field value*/
131 if (fp) {
132 fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
133 pclose(fp);
134 }
135 return field_val;
136}
137
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400138Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500139 device_info->set_vendor(VENDOR_ID);
140 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400141 device_info->set_hardware_version("");
142 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500143 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500144 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500145
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800146 char serial_number[OPENOLT_FIELD_LEN];
147 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
148 openolt_read_sysinfo("Serial Number", serial_number);
149 BCM_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
150 device_info->set_device_serial_number(serial_number);
151
Craig Lutgenb2601f02018-10-23 13:04:31 -0500152 // Legacy, device-wide ranges. To be deprecated when adapter
153 // is upgraded to support per-interface ranges
154 if (board_technology == "xgspon") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500155 device_info->set_onu_id_start(1);
156 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600157 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500158 device_info->set_alloc_id_end(16383);
159 device_info->set_gemport_id_start(1024);
160 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500161 device_info->set_flow_id_start(1);
162 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500163 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500164 else if (board_technology == "gpon") {
165 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500166 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600167 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500168 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500169 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500170 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500171 device_info->set_flow_id_start(1);
172 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500173 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500174
175 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
176 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
177 std::string intf_technology = intf_technologies[intf_id];
178 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
179 if(range == nullptr) {
180 range = device_info->add_ranges();
181 ranges[intf_technology] = range;
182 range->set_technology(intf_technology);
183
184 if (intf_technology == "xgspon") {
185 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
186
187 pool = range->add_pools();
188 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
189 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
190 pool->set_start(1);
191 pool->set_end(255);
192
193 pool = range->add_pools();
194 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
195 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
196 pool->set_start(1024);
197 pool->set_end(16383);
198
199 pool = range->add_pools();
200 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
201 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
202 pool->set_start(1024);
203 pool->set_end(65535);
204
205 pool = range->add_pools();
206 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
207 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
208 pool->set_start(1);
209 pool->set_end(16383);
210 }
211 else if (intf_technology == "gpon") {
212 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
213
214 pool = range->add_pools();
215 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
216 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
217 pool->set_start(1);
218 pool->set_end(127);
219
220 pool = range->add_pools();
221 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
222 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
223 pool->set_start(256);
224 pool->set_end(757);
225
226 pool = range->add_pools();
227 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
228 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
229 pool->set_start(256);
230 pool->set_end(4095);
231
232 pool = range->add_pools();
233 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
234 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
235 pool->set_start(1);
236 pool->set_end(16383);
237 }
238 }
239
240 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500241 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400242
243 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500244 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400245 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
246 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500247 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400248 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500249 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
250 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400251
252 return Status::OK;
253}
254
Shad Ansari627b5782018-08-13 22:49:32 +0000255Status Enable_(int argc, char *argv[]) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000256 bcmbal_access_terminal_cfg acc_term_obj;
257 bcmbal_access_terminal_key key = { };
258
Shad Ansariedef2132018-08-10 22:14:50 +0000259 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000260
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500261 vendor_init();
Shad Ansari627b5782018-08-13 22:49:32 +0000262 bcmbal_init(argc, argv, NULL);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600263 bcmos_fastlock_init(&flow_lock, 0);
264
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500265 BCM_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
266
Shad Ansari627b5782018-08-13 22:49:32 +0000267 Status status = SubscribeIndication();
268 if (!status.ok()) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400269 BCM_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
270 grpc_status_code_to_string(status.error_code()).c_str(),
271 status.error_message().c_str());
272
Shad Ansari627b5782018-08-13 22:49:32 +0000273 return status;
274 }
275
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000276 key.access_term_id = DEFAULT_ATERM_ID;
277 BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
278 BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_UP);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400279 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
280 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400281 BCM_LOG(ERROR, openolt_log_id, "Failed to enable OLT\n");
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400282 return bcm_to_grpc_err(err, "Failed to enable OLT");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000283 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500284
Shad Ansariedef2132018-08-10 22:14:50 +0000285 init_stats();
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000286 }
Shad Ansariedef2132018-08-10 22:14:50 +0000287
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400288 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000289 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400290}
291
292Status Disable_() {
293 // bcmbal_access_terminal_cfg acc_term_obj;
294 // bcmbal_access_terminal_key key = { };
295 //
296 // if (state::is_activated) {
297 // std::cout << "Disable OLT" << std::endl;
298 // key.access_term_id = DEFAULT_ATERM_ID;
299 // BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
300 // BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
301 // bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
302 // if (err) {
303 // std::cout << "ERROR: Failed to disable OLT" << std::endl;
304 // return bcm_to_grpc_err(err, "Failed to disable OLT");
305 // }
306 // }
307 // //If already disabled, generate an extra indication ????
308 // return Status::OK;
309 //This fails with Operation Not Supported, bug ???
310
311 //TEMPORARY WORK AROUND
312 Status status = DisableUplinkIf_(0);
313 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000314 state.deactivate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400315 openolt::Indication ind;
316 openolt::OltIndication* olt_ind = new openolt::OltIndication;
317 olt_ind->set_oper_state("down");
318 ind.set_allocated_olt_ind(olt_ind);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400319 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400320 oltIndQ.push(ind);
321 }
322 return status;
323
324}
325
326Status Reenable_() {
327 Status status = EnableUplinkIf_(0);
328 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000329 state.activate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400330 openolt::Indication ind;
331 openolt::OltIndication* olt_ind = new openolt::OltIndication;
332 olt_ind->set_oper_state("up");
333 ind.set_allocated_olt_ind(olt_ind);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400334 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400335 oltIndQ.push(ind);
336 }
337 return status;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000338}
339
340Status EnablePonIf_(uint32_t intf_id) {
341 bcmbal_interface_cfg interface_obj;
342 bcmbal_interface_key interface_key;
343
344 interface_key.intf_id = intf_id;
345 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
346
347 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500348
349 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
350 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
351 if (err == BCM_ERR_OK && interface_obj.data.admin_state == BCMBAL_STATE_UP) {
352 BCM_LOG(DEBUG, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
353 return Status::OK;
354 }
355
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000356 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
357
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500358 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400359 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400360 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400361 return bcm_to_grpc_err(err, "Failed to enable PON interface");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000362 }
363
364 return Status::OK;
365}
366
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400367Status DisableUplinkIf_(uint32_t intf_id) {
368 bcmbal_interface_cfg interface_obj;
369 bcmbal_interface_key interface_key;
370
371 interface_key.intf_id = intf_id;
372 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
373
374 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
375 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
376
377 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
378 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400379 BCM_LOG(ERROR, openolt_log_id, "Failed to disable Uplink interface: %d\n", intf_id);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400380 return bcm_to_grpc_err(err, "Failed to disable Uplink interface");
381 }
382
383 return Status::OK;
384}
385
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500386Status ProbeDeviceCapabilities_() {
387 bcmbal_access_terminal_cfg acc_term_obj;
388 bcmbal_access_terminal_key key = { };
389
390 key.access_term_id = DEFAULT_ATERM_ID;
391 BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
392 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, admin_state);
393 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, oper_status);
394 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, topology);
395 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, sw_version);
396 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, conn_id);
397 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
398 if (err) {
399 BCM_LOG(ERROR, openolt_log_id, "Failed to query OLT\n");
400 return bcm_to_grpc_err(err, "Failed to query OLT");
401 }
402
403 BCM_LOG(INFO, openolt_log_id, "OLT capabilitites, admin_state: %s oper_state: %s\n",
404 acc_term_obj.data.admin_state == BCMBAL_STATE_UP ? "up" : "down",
405 acc_term_obj.data.oper_status == BCMBAL_STATUS_UP ? "up" : "down");
406
407 std::string bal_version;
408 bal_version += std::to_string(acc_term_obj.data.sw_version.major_rev)
409 + "." + std::to_string(acc_term_obj.data.sw_version.minor_rev)
410 + "." + std::to_string(acc_term_obj.data.sw_version.release_rev);
411 firmware_version = "BAL." + bal_version + "__" + firmware_version;
412
413 BCM_LOG(INFO, openolt_log_id, "--------------- version %s object model: %d\n", bal_version.c_str(),
414 acc_term_obj.data.sw_version.om_version);
415
416 BCM_LOG(INFO, openolt_log_id, "--------------- topology nni:%d pon:%d dev:%d ppd:%d family: %d:%d\n",
417 acc_term_obj.data.topology.num_of_nni_ports,
418 acc_term_obj.data.topology.num_of_pon_ports,
419 acc_term_obj.data.topology.num_of_mac_devs,
420 acc_term_obj.data.topology.num_of_pons_per_mac_dev,
421 acc_term_obj.data.topology.pon_family,
422 acc_term_obj.data.topology.pon_sub_family
423 );
424
425 switch(acc_term_obj.data.topology.pon_sub_family)
426 {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500427 case BCMBAL_PON_SUB_FAMILY_GPON: board_technology = "gpon"; break;
428 case BCMBAL_PON_SUB_FAMILY_XGS: board_technology = "xgspon"; break;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500429 }
430
431 num_of_nni_ports = acc_term_obj.data.topology.num_of_nni_ports;
432 num_of_pon_ports = acc_term_obj.data.topology.num_of_pon_ports;
433
Craig Lutgenb2601f02018-10-23 13:04:31 -0500434 BCM_LOG(INFO, openolt_log_id, "PON num_intfs: %d global board_technology: %s\n", num_of_pon_ports, board_technology.c_str());
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500435
436 return Status::OK;
437}
438
439Status ProbePonIfTechnology_() {
440 // Probe maximum extent possible as configured into BAL driver to determine
441 // which are active in the current BAL topology. And for those
442 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
443 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
444 bcmbal_interface_cfg interface_obj;
445 bcmbal_interface_key interface_key;
446
447 interface_key.intf_id = intf_id;
448 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
449
450 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
451 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
452 BCMBAL_CFG_PROP_GET(&interface_obj, interface, transceiver_type);
453
454 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
455 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500456 intf_technologies[intf_id] = UNKNOWN_TECH;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500457 if(err != BCM_ERR_RANGE) BCM_LOG(ERROR, openolt_log_id, "Failed to get PON config: %d\n", intf_id);
458 }
459 else {
460 switch(interface_obj.data.transceiver_type) {
461 case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
462 case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
463 case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
464 case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
465 case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
Craig Lutgenb2601f02018-10-23 13:04:31 -0500466 intf_technologies[intf_id] = "gpon";
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500467 break;
468 default:
Craig Lutgenb2601f02018-10-23 13:04:31 -0500469 intf_technologies[intf_id] = "xgspon";
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500470 break;
471 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500472 BCM_LOG(INFO, openolt_log_id, "PON intf_id: %d intf_technologies: %d:%s\n", intf_id,
473 interface_obj.data.transceiver_type, intf_technologies[intf_id].c_str());
474
475 if (board_technology != UNKNOWN_TECH) {
476 board_technology = intf_technologies[intf_id];
477 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
478 intf_technologies[intf_id] = MIXED_TECH;
479 }
480
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500481 }
482 }
483
484 return Status::OK;
485}
486
487unsigned NumNniIf_() {return num_of_nni_ports;}
488unsigned NumPonIf_() {return num_of_pon_ports;}
489
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400490Status EnableUplinkIf_(uint32_t intf_id) {
491 bcmbal_interface_cfg interface_obj;
492 bcmbal_interface_key interface_key;
493
494 interface_key.intf_id = intf_id;
495 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
496
497 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500498
499 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
500 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
501 if (err == BCM_ERR_OK && interface_obj.data.admin_state == BCMBAL_STATE_UP) {
502 BCM_LOG(DEBUG, openolt_log_id, "Uplink interface: %d already enabled\n", intf_id);
503 return Status::OK;
504 }
505
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400506 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
507
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500508 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400509 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400510 BCM_LOG(ERROR, openolt_log_id, "Failed to enable Uplink interface: %d\n", intf_id);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400511 return bcm_to_grpc_err(err, "Failed to enable Uplink interface");
512 }
513
514 return Status::OK;
515}
516
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400517Status DisablePonIf_(uint32_t intf_id) {
518 bcmbal_interface_cfg interface_obj;
519 bcmbal_interface_key interface_key;
520
521 interface_key.intf_id = intf_id;
522 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
523
524 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
525 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
526
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400527 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
528 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400529 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400530 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400531 }
532
533 return Status::OK;
534}
535
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000536Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700537 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000538
539 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
540 bcmbal_subscriber_terminal_key subs_terminal_key;
541 bcmbal_serial_number serial_num = {};
542 bcmbal_registration_id registration_id = {};
543
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700544 BCM_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, vendor specific %s, pir %d\n",
545 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str(), pir);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000546
547 subs_terminal_key.sub_term_id = onu_id;
548 subs_terminal_key.intf_id = intf_id;
549 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
550
551 memcpy(serial_num.vendor_id, vendor_id, 4);
552 memcpy(serial_num.vendor_specific, vendor_specific, 4);
553 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, serial_number, serial_num);
554
Shad Ansaricb004c52018-05-30 18:07:23 +0000555#if 0
556 // Commenting out as this is causing issues with onu activation
557 // with BAL 2.6 (Broadcom CS5248819).
558
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000559 // FIXME - Use a default (all zeros) registration id.
560 memset(registration_id.arr, 0, sizeof(registration_id.arr));
561 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, registration_id, registration_id);
Shad Ansaricb004c52018-05-30 18:07:23 +0000562#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000563
564 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_UP);
565
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400566 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr));
567 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400568 BCM_LOG(ERROR, openolt_log_id, "Failed to enable ONU %d on PON %d\n", onu_id, intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400569 return bcm_to_grpc_err(err, "Failed to enable ONU");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000570 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700571 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000572}
573
Jonathan Davis70c21812018-07-19 15:32:10 -0400574Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
575 const char *vendor_id, const char *vendor_specific) {
576
Jonathan Davis70c21812018-07-19 15:32:10 -0400577 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
578 bcmbal_subscriber_terminal_key subs_terminal_key;
579
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400580 BCM_LOG(INFO, openolt_log_id, "Deactivating ONU %d on PON %d : vendor id %s, vendor specific %s\n",
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500581 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
Jonathan Davis70c21812018-07-19 15:32:10 -0400582
583 subs_terminal_key.sub_term_id = onu_id;
584 subs_terminal_key.intf_id = intf_id;
585 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
586
587 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_DOWN);
588
589 if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr))) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400590 BCM_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d\n", onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400591 return Status(grpc::StatusCode::INTERNAL, "Failed to deactivate ONU");
592 }
593
594 return Status::OK;
595}
596
597Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700598 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400599
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500600 BCM_LOG(INFO, openolt_log_id, "DeleteOnu ONU %d on PON %d : vendor id %s, vendor specific %s\n",
601 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
602
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400603 // Need to deactivate before removing it (BAL rules)
604
605 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
606 // Sleep to allow the state to propagate
607 // We need the subscriber terminal object to be admin down before removal
608 // Without sleep the race condition is lost by ~ 20 ms
609 std::this_thread::sleep_for(std::chrono::milliseconds(100));
610
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700611 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400612
Jonathan Davis70c21812018-07-19 15:32:10 -0400613 bcmos_errno err = BCM_ERR_OK;
614 bcmbal_subscriber_terminal_cfg cfg;
615 bcmbal_subscriber_terminal_key key = { };
616
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400617 BCM_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
618 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400619
620 key.sub_term_id = onu_id ;
621 key.intf_id = intf_id ;
622
623 if (0 == key.sub_term_id)
624 {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400625 BCM_LOG(INFO, openolt_log_id,"Invalid Key to handle subscriber terminal clear subscriber_terminal_id %d, Interface ID %d\n",
626 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400627 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
628 }
629
630 BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);
631
632 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
633 if (err != BCM_ERR_OK)
634 {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400635 BCM_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d\n",
636 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400637 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
638 }
639
640 return Status::OK;;
641}
642
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000643#define MAX_CHAR_LENGTH 20
644#define MAX_OMCI_MSG_LENGTH 44
645Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
646 bcmbal_u8_list_u32_max_2048 buf; /* A structure with a msg pointer and length value */
647 bcmos_errno err = BCM_ERR_OK;
648
649 /* The destination of the OMCI packet is a registered ONU on the OLT PON interface */
650 bcmbal_dest proxy_pkt_dest;
651
652 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_ITU_OMCI_CHANNEL;
653 proxy_pkt_dest.u.itu_omci_channel.sub_term_id = onu_id;
654 proxy_pkt_dest.u.itu_omci_channel.intf_id = intf_id;
655
656 // ???
657 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
658 buf.len = MAX_OMCI_MSG_LENGTH;
659 } else {
660 buf.len = pkt.size()/2;
661 }
662
663 /* Send the OMCI packet using the BAL remote proxy API */
664 uint16_t idx1 = 0;
665 uint16_t idx2 = 0;
666 uint8_t arraySend[buf.len];
667 char str1[MAX_CHAR_LENGTH];
668 char str2[MAX_CHAR_LENGTH];
669 memset(&arraySend, 0, buf.len);
670
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000671 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
672 sprintf(str1,"%c", pkt[idx1]);
673 sprintf(str2,"%c", pkt[++idx1]);
674 strcat(str1,str2);
675 arraySend[idx2] = strtol(str1, NULL, 16);
676 }
677
678 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
679 memcpy(buf.val, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000680
681 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
682
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400683 if (err) {
684 BCM_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
685 } else {
686 BCM_LOG(DEBUG, omci_log_id, "OMCI request msg of length %d sent to ONU %d on PON %d : %s\n",
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500687 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400688 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000689
690 free(buf.val);
691
692 return Status::OK;
693}
694
Craig Lutgen967a1d02018-11-27 10:41:51 -0600695Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, uint32_t port_no, const std::string pkt) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000696 bcmos_errno err = BCM_ERR_OK;
697 bcmbal_dest proxy_pkt_dest;
698 bcmbal_u8_list_u32_max_2048 buf;
699
Craig Lutgen967a1d02018-11-27 10:41:51 -0600700 if (port_no > 0) {
701 bool found = false;
702 uint32_t gemport_id;
703
704 bcmos_fastlock_lock(&flow_lock);
705 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
706 // Pick any flow that is mapped with the same port_no.
707 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
708 if (it != port_to_flows.end() && !it->second.empty()) {
709 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
710 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
711 if (fit != flowid_to_gemport.end()) {
712 found = true;
713 gemport_id = fit->second;
714 }
715 }
716 bcmos_fastlock_unlock(&flow_lock, 0);
717
718 if (!found) {
719 BCM_LOG(ERROR, openolt_log_id, "Packet out failed to find destination for ONU %d port_no %u on PON %d\n",
720 onu_id, port_no, intf_id);
721 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
722 }
723
724 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_SVC_PORT;
725 proxy_pkt_dest.u.svc_port.svc_port_id = gemport_id;
726 proxy_pkt_dest.u.svc_port.intf_id = intf_id;
727 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
728 pkt.size(), gemport_id, intf_id, port_no);
729 }
730 else {
731 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_SUB_TERM,
732 proxy_pkt_dest.u.sub_term.sub_term_id = onu_id;
733 proxy_pkt_dest.u.sub_term.intf_id = intf_id;
734 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent to onu %d on pon %d\n",
735 pkt.size(), onu_id, intf_id);
736 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000737
738 buf.len = pkt.size();
739 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
740 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
741
742 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
743
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000744 free(buf.val);
745
746 return Status::OK;
747}
748
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400749Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
750 bcmos_errno err = BCM_ERR_OK;
751 bcmbal_dest proxy_pkt_dest;
752 bcmbal_u8_list_u32_max_2048 buf;
753
754 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_NNI,
755 proxy_pkt_dest.u.nni.intf_id = intf_id;
756
757 buf.len = pkt.size();
758 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
759 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
760
761 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
762
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400763 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent through uplink port %d\n",
764 buf.len, intf_id);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400765
766 free(buf.val);
767
768 return Status::OK;
769}
770
Craig Lutgen967a1d02018-11-27 10:41:51 -0600771uint32_t GetPortNum_(uint32_t flow_id)
772{
773 bcmos_fastlock_lock(&flow_lock);
774 uint32_t port_no = 0;
775 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
776 if (it != flowid_to_port.end()) {
777 port_no = it->second;
778 }
779 bcmos_fastlock_unlock(&flow_lock, 0);
780 return port_no;
781}
782
783Status FlowAdd_(int32_t access_intf_id, int32_t onu_id, int32_t uni_id, uint32_t port_no,
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000784 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700785 int32_t alloc_id, int32_t network_intf_id,
786 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -0600787 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000788 bcmos_errno err;
789 bcmbal_flow_cfg cfg;
790 bcmbal_flow_key key = { };
791
Craig Lutgenecd353a2018-12-12 22:33:17 -0600792 BCM_LOG(INFO, openolt_log_id, "flow add - intf_id %d, onu_id %d, uni_id %d, port_no %u, flow_id %d, flow_type %s, gemport_id %d, network_intf_id %d, cookie %llu\n",
Craig Lutgen967a1d02018-11-27 10:41:51 -0600793 access_intf_id, onu_id, uni_id, port_no, flow_id, flow_type.c_str(), gemport_id, network_intf_id, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000794
795 key.flow_id = flow_id;
796 if (flow_type.compare("upstream") == 0 ) {
797 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
798 } else if (flow_type.compare("downstream") == 0) {
799 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
800 } else {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400801 BCM_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400802 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000803 }
804
805 BCMBAL_CFG_INIT(&cfg, flow, key);
806
807 BCMBAL_CFG_PROP_SET(&cfg, flow, admin_state, BCMBAL_STATE_UP);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600808 BCMBAL_CFG_PROP_SET(&cfg, flow, cookie, cookie);
809
Shad Ansari39739bc2018-09-13 21:38:37 +0000810 if (access_intf_id >= 0) {
811 BCMBAL_CFG_PROP_SET(&cfg, flow, access_int_id, access_intf_id);
812 }
813 if (network_intf_id >= 0) {
814 BCMBAL_CFG_PROP_SET(&cfg, flow, network_int_id, network_intf_id);
815 }
816 if (onu_id >= 0) {
817 BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_id, onu_id);
818 }
819 if (gemport_id >= 0) {
820 BCMBAL_CFG_PROP_SET(&cfg, flow, svc_port_id, gemport_id);
821 }
Craig Lutgen967a1d02018-11-27 10:41:51 -0600822 if (gemport_id >= 0 && port_no != 0) {
823 bcmos_fastlock_lock(&flow_lock);
824 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
825 port_to_flows[port_no].insert(key.flow_id);
826 flowid_to_gemport[key.flow_id] = gemport_id;
827 }
828 else
829 {
830 flowid_to_port[key.flow_id] = port_no;
831 }
832 bcmos_fastlock_unlock(&flow_lock, 0);
833 }
Shad Ansari39739bc2018-09-13 21:38:37 +0000834 if (priority_value >= 0) {
835 BCMBAL_CFG_PROP_SET(&cfg, flow, priority, priority_value);
836 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000837
838 {
839 bcmbal_classifier val = { };
840
841 if (classifier.o_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600842 BCM_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -0500843 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000844 }
845
846 if (classifier.o_vid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600847 BCM_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500848 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_vid, classifier.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000849 }
850
851 if (classifier.i_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600852 BCM_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -0500853 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000854 }
855
856 if (classifier.i_vid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600857 BCM_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500858 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_vid, classifier.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000859 }
860
861 if (classifier.o_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600862 BCM_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500863 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000864 }
865
866 if (classifier.i_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600867 BCM_LOG(DEBUG, openolt_log_id, "classify i_pbits 0x%x\n", classifier.i_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500868 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_pbits, classifier.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000869 }
870
871 if (classifier.eth_type()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600872 BCM_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
Craig Lutgen19512312018-11-02 10:14:46 -0500873 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000874 }
875
876 /*
877 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500878 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000879 }
880
881 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500882 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000883 }
884 */
885
886 if (classifier.ip_proto()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600887 BCM_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
Craig Lutgen19512312018-11-02 10:14:46 -0500888 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000889 }
890
891 /*
892 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500893 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000894 }
895
896 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500897 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000898 }
899 */
900
901 if (classifier.src_port()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600902 BCM_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
Craig Lutgen19512312018-11-02 10:14:46 -0500903 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000904 }
905
906 if (classifier.dst_port()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600907 BCM_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
Craig Lutgen19512312018-11-02 10:14:46 -0500908 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000909 }
910
911 if (!classifier.pkt_tag_type().empty()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600912 BCM_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000913 if (classifier.pkt_tag_type().compare("untagged") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500914 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_UNTAGGED);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000915 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500916 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_SINGLE_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000917 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500918 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000919 }
920 }
921
922 BCMBAL_CFG_PROP_SET(&cfg, flow, classifier, val);
923 }
924
925 {
926 bcmbal_action val = { };
927
928 const ::openolt::ActionCmd& cmd = action.cmd();
929
930 if (cmd.add_outer_tag()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600931 BCM_LOG(INFO, openolt_log_id, "action add o_tag\n");
Craig Lutgen19512312018-11-02 10:14:46 -0500932 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000933 }
934
935 if (cmd.remove_outer_tag()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600936 BCM_LOG(INFO, openolt_log_id, "action pop o_tag\n");
Craig Lutgen19512312018-11-02 10:14:46 -0500937 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000938 }
939
940 if (cmd.trap_to_host()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600941 BCM_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -0500942 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000943 }
944
945 if (action.o_vid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600946 BCM_LOG(INFO, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500947 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000948 }
949
950 if (action.o_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600951 BCM_LOG(INFO, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500952 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000953 }
954
955 if (action.o_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600956 BCM_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -0500957 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000958 }
959
960 if (action.i_vid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600961 BCM_LOG(INFO, openolt_log_id, "action i_vid=%d\n", action.i_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500962 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000963 }
964
965 if (action.i_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600966 BCM_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500967 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000968 }
969
970 if (action.i_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600971 BCM_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -0500972 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000973 }
974
975 BCMBAL_CFG_PROP_SET(&cfg, flow, action, val);
976 }
977
Shad Ansari39739bc2018-09-13 21:38:37 +0000978 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000979
Shad Ansari39739bc2018-09-13 21:38:37 +0000980 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
981 bcmbal_tm_queue_ref val = { };
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700982 val.sched_id = mk_sched_id(access_intf_id, onu_id, "downstream");
Craig Lutgen967a1d02018-11-27 10:41:51 -0600983 uint32_t alloc_id;
984 bcmos_fastlock_lock(&flow_lock);
985 alloc_id = port_to_alloc[port_no];
986 bcmos_fastlock_unlock(&flow_lock, 0);
987 val.queue_id = mk_queue_id(access_intf_id, onu_id, uni_id, port_no, alloc_id);
Shad Ansari39739bc2018-09-13 21:38:37 +0000988 BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700989 } else if (key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM) {
990 bcmbal_tm_sched_id val1;
991 if (alloc_id != 0) {
992 val1 = alloc_id;
993 } else {
994 BCM_LOG(ERROR, openolt_log_id, "alloc_id not present");
995 }
996 BCMBAL_CFG_PROP_SET(&cfg, flow, dba_tm_sched_id, val1);
997
998 bcmbal_tm_queue_ref val2 = { };
999 val2.sched_id = mk_sched_id(network_intf_id, onu_id, "upstream");
1000 BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val2);
Shad Ansari39739bc2018-09-13 21:38:37 +00001001 }
Shad Ansari06101952018-07-25 00:22:09 +00001002 }
1003
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001004 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
1005 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001006 BCM_LOG(ERROR, openolt_log_id, "Flow add failed\n");
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001007 return bcm_to_grpc_err(err, "flow add failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001008 }
1009
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -04001010 // register_new_flow(key);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001011
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001012 return Status::OK;
1013}
1014
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001015Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1016
1017 bcmbal_flow_cfg cfg;
1018 bcmbal_flow_key key = { };
1019
1020 key.flow_id = (bcmbal_flow_id) flow_id;
1021 key.flow_id = flow_id;
1022 if (flow_type.compare("upstream") == 0 ) {
1023 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
1024 } else if (flow_type.compare("downstream") == 0) {
1025 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
1026 } else {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001027 BCM_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001028 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1029 }
1030
Craig Lutgen967a1d02018-11-27 10:41:51 -06001031 bcmos_fastlock_lock(&flow_lock);
1032 uint32_t port_no = flowid_to_port[key.flow_id];
1033 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
1034 flowid_to_gemport.erase(key.flow_id);
1035 port_to_flows[port_no].erase(key.flow_id);
1036 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1037 }
1038 else
1039 {
1040 flowid_to_port.erase(key.flow_id);
1041 }
1042 bcmos_fastlock_unlock(&flow_lock, 0);
1043
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001044 BCMBAL_CFG_INIT(&cfg, flow, key);
1045
1046
1047 bcmos_errno err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
1048 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001049 BCM_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
1050 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001051 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1052 }
1053
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001054 BCM_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001055 return Status::OK;
1056}
1057
Craig Lutgen967a1d02018-11-27 10:41:51 -06001058Status SchedAdd_(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001059 uint32_t alloc_id, openolt::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
Girish Gowdrue075c642019-01-23 04:05:53 -08001060 openolt::SchedulingPolicy sched_policy, openolt::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001061
1062 bcmos_errno err;
1063
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001064 if (direction == "downstream") {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001065 bcmbal_tm_queue_cfg cfg;
1066 bcmbal_tm_queue_key key = { };
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001067 // Note: We use the default scheduler available in the DL.
1068 key.sched_id = mk_sched_id(intf_id, onu_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001069 key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
Craig Lutgen967a1d02018-11-27 10:41:51 -06001070 key.id = mk_queue_id(intf_id, onu_id, uni_id, port_no, alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001071
1072 BCMBAL_CFG_INIT(&cfg, tm_queue, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001073 //Queue must be set with either weight or priority, not both,
1074 // as its scheduler' sched_type is sp_wfq
1075 BCMBAL_CFG_PROP_SET(&cfg, tm_queue, priority, priority);
1076 //BCMBAL_CFG_PROP_SET(&cfg, tm_queue, weight, weight);
1077 //BCMBAL_CFG_PROP_SET(&cfg, tm_queue, creation_mode, BCMBAL_TM_CREATION_MODE_MANUAL);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001078
Girish Gowdrue075c642019-01-23 04:05:53 -08001079 bcmbal_tm_shaping rate = {};
1080 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
1081 uint32_t cir = tf_sh_info.cir();
1082 uint32_t pir = tf_sh_info.pir();
1083 uint32_t burst = tf_sh_info.pbs();
1084 BCM_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
1085 cir, pir, burst);
1086 rate.presence_mask = BCMBAL_TM_SHAPING_ID_ALL;
1087 rate.cir = cir;
1088 rate.pir = pir;
1089 rate.burst = burst;
1090
1091 BCMBAL_CFG_PROP_SET(&cfg, tm_queue, rate, rate);
1092 }
1093
1094 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &cfg.hdr);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001095 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001096 BCM_LOG(ERROR, openolt_log_id, "Failed to create subscriber downstream tm queue, id %d, sched_id %d, intf_id %d, onu_id %d, uni_id %d, port_no %u, alt_id %d\n",
1097 key.id, key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001098 return bcm_to_grpc_err(err, "Failed to create subscriber downstream tm queue");
1099 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001100
1101 bcmos_fastlock_lock(&flow_lock);
1102 port_to_alloc[port_no] = alloc_id;
1103 bcmos_fastlock_unlock(&flow_lock, 0);
1104
1105 BCM_LOG(INFO, openolt_log_id, "Create downstream sched, id %d, intf_id %d, onu_id %d, uni_id %d, port_no %u, alt_id %d\n",
1106 key.id,intf_id,onu_id,uni_id,port_no,alloc_id);
1107
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001108 } else { //"upstream"
1109 bcmbal_tm_sched_cfg cfg;
1110 bcmbal_tm_sched_key key = { };
1111 bcmbal_tm_sched_type sched_type;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001112
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001113 key.id = alloc_id;
1114 key.dir = BCMBAL_TM_SCHED_DIR_US;
1115
1116 BCMBAL_CFG_INIT(&cfg, tm_sched, key);
1117
1118 {
1119 bcmbal_tm_sched_owner val = { };
1120
1121 val.type = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT;
1122 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, intf_id, (bcmbal_intf_id) intf_id);
1123 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, sub_term_id, (bcmbal_sub_id) onu_id);
1124 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, agg_port_id, (bcmbal_aggregation_port_id) alloc_id);
1125
1126 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, val);
1127
1128 }
Girish Gowdrue075c642019-01-23 04:05:53 -08001129 bcmbal_tm_shaping rate = {};
1130 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
1131 uint32_t cir = tf_sh_info.cir();
1132 uint32_t pir = tf_sh_info.pir();
1133 uint32_t burst = tf_sh_info.pbs();
1134 BCM_LOG(INFO, openolt_log_id, "applying traffic shaping in UL cir=%u, pir=%u, burst=%u\n",
1135 cir, pir, burst);
1136 rate.presence_mask = BCMBAL_TM_SHAPING_ID_ALL;
1137 rate.cir = cir;
1138 rate.pir = pir;
1139 rate.burst = burst;
1140
1141 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, rate, rate);
1142 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001143
1144 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
1145 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001146 BCM_LOG(ERROR, openolt_log_id, "Failed to create upstream DBA sched, id %d, intf_id %d, onu_id %d, uni_id %d, port_no %u, alloc_id %d\n",
1147 key.id, intf_id, onu_id,uni_id,port_no,alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001148 return bcm_to_grpc_err(err, "Failed to create upstream DBA sched");
1149 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001150 BCM_LOG(INFO, openolt_log_id, "Create upstream DBA sched, id %d, intf_id %d, onu_id %d, uni_id %d, port_no %u, alloc_id %d\n",
1151 key.id,intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001152 }
1153
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001154 return Status::OK;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001155
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001156}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001157
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001158Status CreateTconts_(const openolt::Tconts *tconts) {
1159 uint32_t intf_id = tconts->intf_id();
1160 uint32_t onu_id = tconts->onu_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001161 uint32_t uni_id = tconts->uni_id();
1162 uint32_t port_no = tconts->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001163 std::string direction;
1164 unsigned int alloc_id;
1165 openolt::Scheduler scheduler;
1166 openolt::AdditionalBW additional_bw;
1167 uint32_t priority;
1168 uint32_t weight;
1169 openolt::SchedulingPolicy sched_policy;
Girish Gowdrue075c642019-01-23 04:05:53 -08001170 openolt::TrafficShapingInfo traffic_shaping_info;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001171
1172 for (int i = 0; i < tconts->tconts_size(); i++) {
1173 openolt::Tcont tcont = tconts->tconts(i);
1174 if (tcont.direction() == openolt::Direction::UPSTREAM) {
1175 direction = "upstream";
1176 } else if (tcont.direction() == openolt::Direction::DOWNSTREAM) {
1177 direction = "downstream";
1178 }
1179 else {
1180 BCM_LOG(ERROR, openolt_log_id, "direction-not-supported %d", tcont.direction());
1181 return Status::CANCELLED;
1182 }
1183 alloc_id = tcont.alloc_id();
1184 scheduler = tcont.scheduler();
1185 additional_bw = scheduler.additional_bw();
1186 priority = scheduler.priority();
1187 weight = scheduler.weight();
1188 sched_policy = scheduler.sched_policy();
Girish Gowdrue075c642019-01-23 04:05:53 -08001189 traffic_shaping_info = tcont.traffic_shaping_info();
1190 SchedAdd_(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority, sched_policy, traffic_shaping_info);
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07001191 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001192 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001193}
Jonathan Davis70c21812018-07-19 15:32:10 -04001194
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001195Status RemoveTconts_(const openolt::Tconts *tconts) {
1196 uint32_t intf_id = tconts->intf_id();
1197 uint32_t onu_id = tconts->onu_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001198 uint32_t uni_id = tconts->uni_id();
1199 uint32_t port_no = tconts->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001200 std::string direction;
1201 unsigned int alloc_id;
1202
1203 for (int i = 0; i < tconts->tconts_size(); i++) {
1204 openolt::Tcont tcont = tconts->tconts(i);
1205 if (tcont.direction() == openolt::Direction::UPSTREAM) {
1206 direction = "upstream";
1207 } else if (tcont.direction() == openolt::Direction::DOWNSTREAM) {
1208 direction = "downstream";
1209 }
1210 else {
1211 BCM_LOG(ERROR, openolt_log_id, "direction-not-supported %d", tcont.direction());
1212 return Status::CANCELLED;
1213 }
1214 alloc_id = tcont.alloc_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001215 SchedRemove_(direction, intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001216 }
1217 return Status::OK;
1218}
1219
Craig Lutgen967a1d02018-11-27 10:41:51 -06001220Status SchedRemove_(std::string direction, int intf_id, int onu_id, int uni_id, uint32_t port_no, int alloc_id) {
Jonathan Davis70c21812018-07-19 15:32:10 -04001221
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001222 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04001223
Jonathan Davis70c21812018-07-19 15:32:10 -04001224
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001225 if (direction == "upstream") {
1226 // DBA sched
1227 bcmbal_tm_sched_cfg tm_cfg_us;
1228 bcmbal_tm_sched_key tm_key_us = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001229
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001230 tm_key_us.id = alloc_id;
1231 tm_key_us.dir = BCMBAL_TM_SCHED_DIR_US;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001232
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001233 BCMBAL_CFG_INIT(&tm_cfg_us, tm_sched, tm_key_us);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001234
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001235 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(tm_cfg_us.hdr));
1236 if (err) {
1237 BCM_LOG(ERROR, openolt_log_id, "Failed to remove upstream DBA sched, id %d, intf_id %d, onu_id %d\n",
1238 tm_key_us.id, intf_id, onu_id);
1239 return Status(grpc::StatusCode::INTERNAL, "Failed to remove upstream DBA sched");
1240 }
1241
1242 BCM_LOG(INFO, openolt_log_id, "Remove upstream DBA sched, id %d, intf_id %d, onu_id %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001243 tm_key_us.id, intf_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001244
1245 } else if (direction == "downstream") {
1246 // Queue
1247
1248 bcmbal_tm_queue_cfg queue_cfg;
1249 bcmbal_tm_queue_key queue_key = { };
1250 queue_key.sched_id = mk_sched_id(intf_id, onu_id, "downstream");
1251 queue_key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
Craig Lutgen967a1d02018-11-27 10:41:51 -06001252 queue_key.id = mk_queue_id(intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001253
1254 BCMBAL_CFG_INIT(&queue_cfg, tm_queue, queue_key);
1255
1256 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(queue_cfg.hdr));
1257 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001258 BCM_LOG(ERROR, openolt_log_id, "Failed to remove downstream tm queue, id %d, sched_id %d, intf_id %d, onu_id %d, uni_id %d, port_no %u, alt_id %d\n",
1259 queue_key.id, queue_key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001260 return Status(grpc::StatusCode::INTERNAL, "Failed to remove downstream tm queue");
1261 }
1262
Craig Lutgen967a1d02018-11-27 10:41:51 -06001263 bcmos_fastlock_lock(&flow_lock);
1264 port_to_alloc.erase(port_no);
1265 bcmos_fastlock_unlock(&flow_lock, 0);
1266
1267 BCM_LOG(INFO, openolt_log_id, "Remove upstream DBA sched, id %d, sched_id %d, intf_id %d, onu_id %d, uni_id %d, port_no %u, alt_id %d\n",
1268 queue_key.id, queue_key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001269 }
1270
Jonathan Davis70c21812018-07-19 15:32:10 -04001271 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001272}