blob: 2e01bc7fdd3faa6da4d271e88cbb541fe538e491 [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);
Craig Lutgen88a22ad2018-10-04 12:30:46 -050065
66static 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,
87 openolt::SchedulingPolicy sched_policy);
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
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400115Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500116 device_info->set_vendor(VENDOR_ID);
117 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400118 device_info->set_hardware_version("");
119 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500120 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500121 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500122
123 // Legacy, device-wide ranges. To be deprecated when adapter
124 // is upgraded to support per-interface ranges
125 if (board_technology == "xgspon") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500126 device_info->set_onu_id_start(1);
127 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600128 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500129 device_info->set_alloc_id_end(16383);
130 device_info->set_gemport_id_start(1024);
131 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500132 device_info->set_flow_id_start(1);
133 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500134 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500135 else if (board_technology == "gpon") {
136 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500137 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600138 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500139 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500140 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500141 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500142 device_info->set_flow_id_start(1);
143 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500144 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500145
146 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
147 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
148 std::string intf_technology = intf_technologies[intf_id];
149 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
150 if(range == nullptr) {
151 range = device_info->add_ranges();
152 ranges[intf_technology] = range;
153 range->set_technology(intf_technology);
154
155 if (intf_technology == "xgspon") {
156 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
157
158 pool = range->add_pools();
159 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
160 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
161 pool->set_start(1);
162 pool->set_end(255);
163
164 pool = range->add_pools();
165 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
166 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
167 pool->set_start(1024);
168 pool->set_end(16383);
169
170 pool = range->add_pools();
171 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
172 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
173 pool->set_start(1024);
174 pool->set_end(65535);
175
176 pool = range->add_pools();
177 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
178 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
179 pool->set_start(1);
180 pool->set_end(16383);
181 }
182 else if (intf_technology == "gpon") {
183 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
184
185 pool = range->add_pools();
186 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
187 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
188 pool->set_start(1);
189 pool->set_end(127);
190
191 pool = range->add_pools();
192 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
193 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
194 pool->set_start(256);
195 pool->set_end(757);
196
197 pool = range->add_pools();
198 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
199 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
200 pool->set_start(256);
201 pool->set_end(4095);
202
203 pool = range->add_pools();
204 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
205 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
206 pool->set_start(1);
207 pool->set_end(16383);
208 }
209 }
210
211 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500212 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400213
214 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500215 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400216 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
217 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500218 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400219 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500220 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
221 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400222
223 return Status::OK;
224}
225
Shad Ansari627b5782018-08-13 22:49:32 +0000226Status Enable_(int argc, char *argv[]) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000227 bcmbal_access_terminal_cfg acc_term_obj;
228 bcmbal_access_terminal_key key = { };
229
Shad Ansariedef2132018-08-10 22:14:50 +0000230 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000231
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500232 vendor_init();
Shad Ansari627b5782018-08-13 22:49:32 +0000233 bcmbal_init(argc, argv, NULL);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600234 bcmos_fastlock_init(&flow_lock, 0);
235
Shad Ansari627b5782018-08-13 22:49:32 +0000236
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500237 BCM_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
238
Shad Ansari627b5782018-08-13 22:49:32 +0000239 Status status = SubscribeIndication();
240 if (!status.ok()) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400241 BCM_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
242 grpc_status_code_to_string(status.error_code()).c_str(),
243 status.error_message().c_str());
244
Shad Ansari627b5782018-08-13 22:49:32 +0000245 return status;
246 }
247
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000248 key.access_term_id = DEFAULT_ATERM_ID;
249 BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
250 BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_UP);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400251 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
252 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400253 BCM_LOG(ERROR, openolt_log_id, "Failed to enable OLT\n");
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400254 return bcm_to_grpc_err(err, "Failed to enable OLT");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000255 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500256
Shad Ansariedef2132018-08-10 22:14:50 +0000257 init_stats();
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000258 }
Shad Ansariedef2132018-08-10 22:14:50 +0000259
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400260 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000261 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400262}
263
264Status Disable_() {
265 // bcmbal_access_terminal_cfg acc_term_obj;
266 // bcmbal_access_terminal_key key = { };
267 //
268 // if (state::is_activated) {
269 // std::cout << "Disable OLT" << std::endl;
270 // key.access_term_id = DEFAULT_ATERM_ID;
271 // BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
272 // BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
273 // bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
274 // if (err) {
275 // std::cout << "ERROR: Failed to disable OLT" << std::endl;
276 // return bcm_to_grpc_err(err, "Failed to disable OLT");
277 // }
278 // }
279 // //If already disabled, generate an extra indication ????
280 // return Status::OK;
281 //This fails with Operation Not Supported, bug ???
282
283 //TEMPORARY WORK AROUND
284 Status status = DisableUplinkIf_(0);
285 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000286 state.deactivate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400287 openolt::Indication ind;
288 openolt::OltIndication* olt_ind = new openolt::OltIndication;
289 olt_ind->set_oper_state("down");
290 ind.set_allocated_olt_ind(olt_ind);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400291 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400292 oltIndQ.push(ind);
293 }
294 return status;
295
296}
297
298Status Reenable_() {
299 Status status = EnableUplinkIf_(0);
300 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000301 state.activate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400302 openolt::Indication ind;
303 openolt::OltIndication* olt_ind = new openolt::OltIndication;
304 olt_ind->set_oper_state("up");
305 ind.set_allocated_olt_ind(olt_ind);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400306 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400307 oltIndQ.push(ind);
308 }
309 return status;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000310}
311
312Status EnablePonIf_(uint32_t intf_id) {
313 bcmbal_interface_cfg interface_obj;
314 bcmbal_interface_key interface_key;
315
316 interface_key.intf_id = intf_id;
317 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
318
319 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500320
321 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
322 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
323 if (err == BCM_ERR_OK && interface_obj.data.admin_state == BCMBAL_STATE_UP) {
324 BCM_LOG(DEBUG, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
325 return Status::OK;
326 }
327
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000328 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
329
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500330 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400331 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400332 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400333 return bcm_to_grpc_err(err, "Failed to enable PON interface");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000334 }
335
336 return Status::OK;
337}
338
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400339Status DisableUplinkIf_(uint32_t intf_id) {
340 bcmbal_interface_cfg interface_obj;
341 bcmbal_interface_key interface_key;
342
343 interface_key.intf_id = intf_id;
344 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
345
346 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
347 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
348
349 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
350 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400351 BCM_LOG(ERROR, openolt_log_id, "Failed to disable Uplink interface: %d\n", intf_id);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400352 return bcm_to_grpc_err(err, "Failed to disable Uplink interface");
353 }
354
355 return Status::OK;
356}
357
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500358Status ProbeDeviceCapabilities_() {
359 bcmbal_access_terminal_cfg acc_term_obj;
360 bcmbal_access_terminal_key key = { };
361
362 key.access_term_id = DEFAULT_ATERM_ID;
363 BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
364 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, admin_state);
365 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, oper_status);
366 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, topology);
367 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, sw_version);
368 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, conn_id);
369 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
370 if (err) {
371 BCM_LOG(ERROR, openolt_log_id, "Failed to query OLT\n");
372 return bcm_to_grpc_err(err, "Failed to query OLT");
373 }
374
375 BCM_LOG(INFO, openolt_log_id, "OLT capabilitites, admin_state: %s oper_state: %s\n",
376 acc_term_obj.data.admin_state == BCMBAL_STATE_UP ? "up" : "down",
377 acc_term_obj.data.oper_status == BCMBAL_STATUS_UP ? "up" : "down");
378
379 std::string bal_version;
380 bal_version += std::to_string(acc_term_obj.data.sw_version.major_rev)
381 + "." + std::to_string(acc_term_obj.data.sw_version.minor_rev)
382 + "." + std::to_string(acc_term_obj.data.sw_version.release_rev);
383 firmware_version = "BAL." + bal_version + "__" + firmware_version;
384
385 BCM_LOG(INFO, openolt_log_id, "--------------- version %s object model: %d\n", bal_version.c_str(),
386 acc_term_obj.data.sw_version.om_version);
387
388 BCM_LOG(INFO, openolt_log_id, "--------------- topology nni:%d pon:%d dev:%d ppd:%d family: %d:%d\n",
389 acc_term_obj.data.topology.num_of_nni_ports,
390 acc_term_obj.data.topology.num_of_pon_ports,
391 acc_term_obj.data.topology.num_of_mac_devs,
392 acc_term_obj.data.topology.num_of_pons_per_mac_dev,
393 acc_term_obj.data.topology.pon_family,
394 acc_term_obj.data.topology.pon_sub_family
395 );
396
397 switch(acc_term_obj.data.topology.pon_sub_family)
398 {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500399 case BCMBAL_PON_SUB_FAMILY_GPON: board_technology = "gpon"; break;
400 case BCMBAL_PON_SUB_FAMILY_XGS: board_technology = "xgspon"; break;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500401 }
402
403 num_of_nni_ports = acc_term_obj.data.topology.num_of_nni_ports;
404 num_of_pon_ports = acc_term_obj.data.topology.num_of_pon_ports;
405
Craig Lutgenb2601f02018-10-23 13:04:31 -0500406 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 -0500407
408 return Status::OK;
409}
410
411Status ProbePonIfTechnology_() {
412 // Probe maximum extent possible as configured into BAL driver to determine
413 // which are active in the current BAL topology. And for those
414 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
415 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
416 bcmbal_interface_cfg interface_obj;
417 bcmbal_interface_key interface_key;
418
419 interface_key.intf_id = intf_id;
420 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
421
422 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
423 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
424 BCMBAL_CFG_PROP_GET(&interface_obj, interface, transceiver_type);
425
426 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
427 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500428 intf_technologies[intf_id] = UNKNOWN_TECH;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500429 if(err != BCM_ERR_RANGE) BCM_LOG(ERROR, openolt_log_id, "Failed to get PON config: %d\n", intf_id);
430 }
431 else {
432 switch(interface_obj.data.transceiver_type) {
433 case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
434 case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
435 case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
436 case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
437 case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
Craig Lutgenb2601f02018-10-23 13:04:31 -0500438 intf_technologies[intf_id] = "gpon";
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500439 break;
440 default:
Craig Lutgenb2601f02018-10-23 13:04:31 -0500441 intf_technologies[intf_id] = "xgspon";
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500442 break;
443 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500444 BCM_LOG(INFO, openolt_log_id, "PON intf_id: %d intf_technologies: %d:%s\n", intf_id,
445 interface_obj.data.transceiver_type, intf_technologies[intf_id].c_str());
446
447 if (board_technology != UNKNOWN_TECH) {
448 board_technology = intf_technologies[intf_id];
449 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
450 intf_technologies[intf_id] = MIXED_TECH;
451 }
452
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500453 }
454 }
455
456 return Status::OK;
457}
458
459unsigned NumNniIf_() {return num_of_nni_ports;}
460unsigned NumPonIf_() {return num_of_pon_ports;}
461
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400462Status EnableUplinkIf_(uint32_t intf_id) {
463 bcmbal_interface_cfg interface_obj;
464 bcmbal_interface_key interface_key;
465
466 interface_key.intf_id = intf_id;
467 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
468
469 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500470
471 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
472 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
473 if (err == BCM_ERR_OK && interface_obj.data.admin_state == BCMBAL_STATE_UP) {
474 BCM_LOG(DEBUG, openolt_log_id, "Uplink interface: %d already enabled\n", intf_id);
475 return Status::OK;
476 }
477
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400478 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
479
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500480 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400481 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400482 BCM_LOG(ERROR, openolt_log_id, "Failed to enable Uplink interface: %d\n", intf_id);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400483 return bcm_to_grpc_err(err, "Failed to enable Uplink interface");
484 }
485
486 return Status::OK;
487}
488
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400489Status DisablePonIf_(uint32_t intf_id) {
490 bcmbal_interface_cfg interface_obj;
491 bcmbal_interface_key interface_key;
492
493 interface_key.intf_id = intf_id;
494 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
495
496 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
497 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
498
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400499 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
500 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400501 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400502 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400503 }
504
505 return Status::OK;
506}
507
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000508Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700509 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000510
511 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
512 bcmbal_subscriber_terminal_key subs_terminal_key;
513 bcmbal_serial_number serial_num = {};
514 bcmbal_registration_id registration_id = {};
515
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700516 BCM_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, vendor specific %s, pir %d\n",
517 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str(), pir);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000518
519 subs_terminal_key.sub_term_id = onu_id;
520 subs_terminal_key.intf_id = intf_id;
521 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
522
523 memcpy(serial_num.vendor_id, vendor_id, 4);
524 memcpy(serial_num.vendor_specific, vendor_specific, 4);
525 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, serial_number, serial_num);
526
Shad Ansaricb004c52018-05-30 18:07:23 +0000527#if 0
528 // Commenting out as this is causing issues with onu activation
529 // with BAL 2.6 (Broadcom CS5248819).
530
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000531 // FIXME - Use a default (all zeros) registration id.
532 memset(registration_id.arr, 0, sizeof(registration_id.arr));
533 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, registration_id, registration_id);
Shad Ansaricb004c52018-05-30 18:07:23 +0000534#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000535
536 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_UP);
537
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400538 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr));
539 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400540 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 -0400541 return bcm_to_grpc_err(err, "Failed to enable ONU");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000542 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700543 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000544}
545
Jonathan Davis70c21812018-07-19 15:32:10 -0400546Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
547 const char *vendor_id, const char *vendor_specific) {
548
Jonathan Davis70c21812018-07-19 15:32:10 -0400549 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
550 bcmbal_subscriber_terminal_key subs_terminal_key;
551
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400552 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 -0500553 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
Jonathan Davis70c21812018-07-19 15:32:10 -0400554
555 subs_terminal_key.sub_term_id = onu_id;
556 subs_terminal_key.intf_id = intf_id;
557 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
558
559 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_DOWN);
560
561 if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr))) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400562 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 -0400563 return Status(grpc::StatusCode::INTERNAL, "Failed to deactivate ONU");
564 }
565
566 return Status::OK;
567}
568
569Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700570 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400571
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500572 BCM_LOG(INFO, openolt_log_id, "DeleteOnu ONU %d on PON %d : vendor id %s, vendor specific %s\n",
573 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
574
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400575 // Need to deactivate before removing it (BAL rules)
576
577 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
578 // Sleep to allow the state to propagate
579 // We need the subscriber terminal object to be admin down before removal
580 // Without sleep the race condition is lost by ~ 20 ms
581 std::this_thread::sleep_for(std::chrono::milliseconds(100));
582
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700583 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400584
Jonathan Davis70c21812018-07-19 15:32:10 -0400585 bcmos_errno err = BCM_ERR_OK;
586 bcmbal_subscriber_terminal_cfg cfg;
587 bcmbal_subscriber_terminal_key key = { };
588
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400589 BCM_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
590 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400591
592 key.sub_term_id = onu_id ;
593 key.intf_id = intf_id ;
594
595 if (0 == key.sub_term_id)
596 {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400597 BCM_LOG(INFO, openolt_log_id,"Invalid Key to handle subscriber terminal clear subscriber_terminal_id %d, Interface ID %d\n",
598 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400599 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
600 }
601
602 BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);
603
604 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
605 if (err != BCM_ERR_OK)
606 {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400607 BCM_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d\n",
608 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400609 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
610 }
611
612 return Status::OK;;
613}
614
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000615#define MAX_CHAR_LENGTH 20
616#define MAX_OMCI_MSG_LENGTH 44
617Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
618 bcmbal_u8_list_u32_max_2048 buf; /* A structure with a msg pointer and length value */
619 bcmos_errno err = BCM_ERR_OK;
620
621 /* The destination of the OMCI packet is a registered ONU on the OLT PON interface */
622 bcmbal_dest proxy_pkt_dest;
623
624 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_ITU_OMCI_CHANNEL;
625 proxy_pkt_dest.u.itu_omci_channel.sub_term_id = onu_id;
626 proxy_pkt_dest.u.itu_omci_channel.intf_id = intf_id;
627
628 // ???
629 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
630 buf.len = MAX_OMCI_MSG_LENGTH;
631 } else {
632 buf.len = pkt.size()/2;
633 }
634
635 /* Send the OMCI packet using the BAL remote proxy API */
636 uint16_t idx1 = 0;
637 uint16_t idx2 = 0;
638 uint8_t arraySend[buf.len];
639 char str1[MAX_CHAR_LENGTH];
640 char str2[MAX_CHAR_LENGTH];
641 memset(&arraySend, 0, buf.len);
642
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000643 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
644 sprintf(str1,"%c", pkt[idx1]);
645 sprintf(str2,"%c", pkt[++idx1]);
646 strcat(str1,str2);
647 arraySend[idx2] = strtol(str1, NULL, 16);
648 }
649
650 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
651 memcpy(buf.val, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000652
653 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
654
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400655 if (err) {
656 BCM_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
657 } else {
658 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 -0500659 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400660 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000661
662 free(buf.val);
663
664 return Status::OK;
665}
666
Craig Lutgen967a1d02018-11-27 10:41:51 -0600667Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, uint32_t port_no, const std::string pkt) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000668 bcmos_errno err = BCM_ERR_OK;
669 bcmbal_dest proxy_pkt_dest;
670 bcmbal_u8_list_u32_max_2048 buf;
671
Craig Lutgen967a1d02018-11-27 10:41:51 -0600672 if (port_no > 0) {
673 bool found = false;
674 uint32_t gemport_id;
675
676 bcmos_fastlock_lock(&flow_lock);
677 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
678 // Pick any flow that is mapped with the same port_no.
679 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
680 if (it != port_to_flows.end() && !it->second.empty()) {
681 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
682 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
683 if (fit != flowid_to_gemport.end()) {
684 found = true;
685 gemport_id = fit->second;
686 }
687 }
688 bcmos_fastlock_unlock(&flow_lock, 0);
689
690 if (!found) {
691 BCM_LOG(ERROR, openolt_log_id, "Packet out failed to find destination for ONU %d port_no %u on PON %d\n",
692 onu_id, port_no, intf_id);
693 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
694 }
695
696 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_SVC_PORT;
697 proxy_pkt_dest.u.svc_port.svc_port_id = gemport_id;
698 proxy_pkt_dest.u.svc_port.intf_id = intf_id;
699 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
700 pkt.size(), gemport_id, intf_id, port_no);
701 }
702 else {
703 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_SUB_TERM,
704 proxy_pkt_dest.u.sub_term.sub_term_id = onu_id;
705 proxy_pkt_dest.u.sub_term.intf_id = intf_id;
706 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent to onu %d on pon %d\n",
707 pkt.size(), onu_id, intf_id);
708 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000709
710 buf.len = pkt.size();
711 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
712 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
713
714 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
715
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000716 free(buf.val);
717
718 return Status::OK;
719}
720
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400721Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
722 bcmos_errno err = BCM_ERR_OK;
723 bcmbal_dest proxy_pkt_dest;
724 bcmbal_u8_list_u32_max_2048 buf;
725
726 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_NNI,
727 proxy_pkt_dest.u.nni.intf_id = intf_id;
728
729 buf.len = pkt.size();
730 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
731 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
732
733 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
734
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400735 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent through uplink port %d\n",
736 buf.len, intf_id);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400737
738 free(buf.val);
739
740 return Status::OK;
741}
742
Craig Lutgen967a1d02018-11-27 10:41:51 -0600743uint32_t GetPortNum_(uint32_t flow_id)
744{
745 bcmos_fastlock_lock(&flow_lock);
746 uint32_t port_no = 0;
747 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
748 if (it != flowid_to_port.end()) {
749 port_no = it->second;
750 }
751 bcmos_fastlock_unlock(&flow_lock, 0);
752 return port_no;
753}
754
755Status 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 +0000756 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700757 int32_t alloc_id, int32_t network_intf_id,
758 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -0600759 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000760 bcmos_errno err;
761 bcmbal_flow_cfg cfg;
762 bcmbal_flow_key key = { };
763
Craig Lutgen967a1d02018-11-27 10:41:51 -0600764 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 %u\n",
765 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 +0000766
767 key.flow_id = flow_id;
768 if (flow_type.compare("upstream") == 0 ) {
769 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
770 } else if (flow_type.compare("downstream") == 0) {
771 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
772 } else {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400773 BCM_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400774 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000775 }
776
777 BCMBAL_CFG_INIT(&cfg, flow, key);
778
779 BCMBAL_CFG_PROP_SET(&cfg, flow, admin_state, BCMBAL_STATE_UP);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600780 BCMBAL_CFG_PROP_SET(&cfg, flow, cookie, cookie);
781
Shad Ansari39739bc2018-09-13 21:38:37 +0000782 if (access_intf_id >= 0) {
783 BCMBAL_CFG_PROP_SET(&cfg, flow, access_int_id, access_intf_id);
784 }
785 if (network_intf_id >= 0) {
786 BCMBAL_CFG_PROP_SET(&cfg, flow, network_int_id, network_intf_id);
787 }
788 if (onu_id >= 0) {
789 BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_id, onu_id);
790 }
791 if (gemport_id >= 0) {
792 BCMBAL_CFG_PROP_SET(&cfg, flow, svc_port_id, gemport_id);
793 }
Craig Lutgen967a1d02018-11-27 10:41:51 -0600794 if (gemport_id >= 0 && port_no != 0) {
795 bcmos_fastlock_lock(&flow_lock);
796 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
797 port_to_flows[port_no].insert(key.flow_id);
798 flowid_to_gemport[key.flow_id] = gemport_id;
799 }
800 else
801 {
802 flowid_to_port[key.flow_id] = port_no;
803 }
804 bcmos_fastlock_unlock(&flow_lock, 0);
805 }
Shad Ansari39739bc2018-09-13 21:38:37 +0000806 if (priority_value >= 0) {
807 BCMBAL_CFG_PROP_SET(&cfg, flow, priority, priority_value);
808 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000809
810 {
811 bcmbal_classifier val = { };
812
813 if (classifier.o_tpid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500814 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000815 }
816
817 if (classifier.o_vid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500818 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_vid, classifier.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000819 }
820
821 if (classifier.i_tpid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500822 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000823 }
824
825 if (classifier.i_vid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500826 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_vid, classifier.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000827 }
828
829 if (classifier.o_pbits()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500830 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000831 }
832
833 if (classifier.i_pbits()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500834 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_pbits, classifier.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000835 }
836
837 if (classifier.eth_type()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500838 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000839 }
840
841 /*
842 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500843 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000844 }
845
846 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500847 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000848 }
849 */
850
851 if (classifier.ip_proto()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500852 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000853 }
854
855 /*
856 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500857 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000858 }
859
860 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500861 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000862 }
863 */
864
865 if (classifier.src_port()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500866 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000867 }
868
869 if (classifier.dst_port()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500870 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000871 }
872
873 if (!classifier.pkt_tag_type().empty()) {
874 if (classifier.pkt_tag_type().compare("untagged") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500875 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_UNTAGGED);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000876 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500877 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_SINGLE_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000878 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500879 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000880 }
881 }
882
883 BCMBAL_CFG_PROP_SET(&cfg, flow, classifier, val);
884 }
885
886 {
887 bcmbal_action val = { };
888
889 const ::openolt::ActionCmd& cmd = action.cmd();
890
891 if (cmd.add_outer_tag()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500892 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000893 }
894
895 if (cmd.remove_outer_tag()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500896 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000897 }
898
899 if (cmd.trap_to_host()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500900 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000901 }
902
903 if (action.o_vid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500904 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000905 }
906
907 if (action.o_pbits()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500908 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000909 }
910
911 if (action.o_tpid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500912 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000913 }
914
915 if (action.i_vid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500916 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000917 }
918
919 if (action.i_pbits()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500920 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000921 }
922
923 if (action.i_tpid()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500924 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000925 }
926
927 BCMBAL_CFG_PROP_SET(&cfg, flow, action, val);
928 }
929
Shad Ansari39739bc2018-09-13 21:38:37 +0000930 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000931
Shad Ansari39739bc2018-09-13 21:38:37 +0000932 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
933 bcmbal_tm_queue_ref val = { };
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700934 val.sched_id = mk_sched_id(access_intf_id, onu_id, "downstream");
Craig Lutgen967a1d02018-11-27 10:41:51 -0600935 uint32_t alloc_id;
936 bcmos_fastlock_lock(&flow_lock);
937 alloc_id = port_to_alloc[port_no];
938 bcmos_fastlock_unlock(&flow_lock, 0);
939 val.queue_id = mk_queue_id(access_intf_id, onu_id, uni_id, port_no, alloc_id);
Shad Ansari39739bc2018-09-13 21:38:37 +0000940 BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700941 } else if (key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM) {
942 bcmbal_tm_sched_id val1;
943 if (alloc_id != 0) {
944 val1 = alloc_id;
945 } else {
946 BCM_LOG(ERROR, openolt_log_id, "alloc_id not present");
947 }
948 BCMBAL_CFG_PROP_SET(&cfg, flow, dba_tm_sched_id, val1);
949
950 bcmbal_tm_queue_ref val2 = { };
951 val2.sched_id = mk_sched_id(network_intf_id, onu_id, "upstream");
952 BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val2);
Shad Ansari39739bc2018-09-13 21:38:37 +0000953 }
Shad Ansari06101952018-07-25 00:22:09 +0000954 }
955
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400956 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
957 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400958 BCM_LOG(ERROR, openolt_log_id, "Flow add failed\n");
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400959 return bcm_to_grpc_err(err, "flow add failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000960 }
961
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400962 // register_new_flow(key);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400963
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000964 return Status::OK;
965}
966
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400967Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
968
969 bcmbal_flow_cfg cfg;
970 bcmbal_flow_key key = { };
971
972 key.flow_id = (bcmbal_flow_id) flow_id;
973 key.flow_id = flow_id;
974 if (flow_type.compare("upstream") == 0 ) {
975 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
976 } else if (flow_type.compare("downstream") == 0) {
977 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
978 } else {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400979 BCM_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400980 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
981 }
982
Craig Lutgen967a1d02018-11-27 10:41:51 -0600983 bcmos_fastlock_lock(&flow_lock);
984 uint32_t port_no = flowid_to_port[key.flow_id];
985 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
986 flowid_to_gemport.erase(key.flow_id);
987 port_to_flows[port_no].erase(key.flow_id);
988 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
989 }
990 else
991 {
992 flowid_to_port.erase(key.flow_id);
993 }
994 bcmos_fastlock_unlock(&flow_lock, 0);
995
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400996 BCMBAL_CFG_INIT(&cfg, flow, key);
997
998
999 bcmos_errno err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
1000 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001001 BCM_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
1002 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001003 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1004 }
1005
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001006 BCM_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001007 return Status::OK;
1008}
1009
Craig Lutgen967a1d02018-11-27 10:41:51 -06001010Status 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 -07001011 uint32_t alloc_id, openolt::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
1012 openolt::SchedulingPolicy sched_policy) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001013
1014 bcmos_errno err;
1015
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001016 if (direction == "downstream") {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001017 bcmbal_tm_queue_cfg cfg;
1018 bcmbal_tm_queue_key key = { };
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001019 // Note: We use the default scheduler available in the DL.
1020 key.sched_id = mk_sched_id(intf_id, onu_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001021 key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
Craig Lutgen967a1d02018-11-27 10:41:51 -06001022 key.id = mk_queue_id(intf_id, onu_id, uni_id, port_no, alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001023
1024 BCMBAL_CFG_INIT(&cfg, tm_queue, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001025 //Queue must be set with either weight or priority, not both,
1026 // as its scheduler' sched_type is sp_wfq
1027 BCMBAL_CFG_PROP_SET(&cfg, tm_queue, priority, priority);
1028 //BCMBAL_CFG_PROP_SET(&cfg, tm_queue, weight, weight);
1029 //BCMBAL_CFG_PROP_SET(&cfg, tm_queue, creation_mode, BCMBAL_TM_CREATION_MODE_MANUAL);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001030 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &cfg.hdr);
1031
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001032 // TODO: Shaping parameters will be available after meter bands are supported.
1033 // TODO: The shaping parameters will be applied on the downstream queue on the PON default scheduler.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001034 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001035 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",
1036 key.id, key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001037 return bcm_to_grpc_err(err, "Failed to create subscriber downstream tm queue");
1038 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001039
1040 bcmos_fastlock_lock(&flow_lock);
1041 port_to_alloc[port_no] = alloc_id;
1042 bcmos_fastlock_unlock(&flow_lock, 0);
1043
1044 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",
1045 key.id,intf_id,onu_id,uni_id,port_no,alloc_id);
1046
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001047 } else { //"upstream"
1048 bcmbal_tm_sched_cfg cfg;
1049 bcmbal_tm_sched_key key = { };
1050 bcmbal_tm_sched_type sched_type;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001051
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001052 key.id = alloc_id;
1053 key.dir = BCMBAL_TM_SCHED_DIR_US;
1054
1055 BCMBAL_CFG_INIT(&cfg, tm_sched, key);
1056
1057 {
1058 bcmbal_tm_sched_owner val = { };
1059
1060 val.type = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT;
1061 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, intf_id, (bcmbal_intf_id) intf_id);
1062 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, sub_term_id, (bcmbal_sub_id) onu_id);
1063 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, agg_port_id, (bcmbal_aggregation_port_id) alloc_id);
1064
1065 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, val);
1066
1067 }
1068 // TODO: Shaping parameters will be available after meter bands are supported.
1069 // TODO: The shaping parameters will be applied on the upstream DBA scheduler.
1070
1071 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
1072 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001073 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",
1074 key.id, intf_id, onu_id,uni_id,port_no,alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001075 return bcm_to_grpc_err(err, "Failed to create upstream DBA sched");
1076 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001077 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",
1078 key.id,intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001079 }
1080
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001081 return Status::OK;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001082
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001083}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001084
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001085Status CreateTconts_(const openolt::Tconts *tconts) {
1086 uint32_t intf_id = tconts->intf_id();
1087 uint32_t onu_id = tconts->onu_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001088 uint32_t uni_id = tconts->uni_id();
1089 uint32_t port_no = tconts->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001090 std::string direction;
1091 unsigned int alloc_id;
1092 openolt::Scheduler scheduler;
1093 openolt::AdditionalBW additional_bw;
1094 uint32_t priority;
1095 uint32_t weight;
1096 openolt::SchedulingPolicy sched_policy;
1097
1098 for (int i = 0; i < tconts->tconts_size(); i++) {
1099 openolt::Tcont tcont = tconts->tconts(i);
1100 if (tcont.direction() == openolt::Direction::UPSTREAM) {
1101 direction = "upstream";
1102 } else if (tcont.direction() == openolt::Direction::DOWNSTREAM) {
1103 direction = "downstream";
1104 }
1105 else {
1106 BCM_LOG(ERROR, openolt_log_id, "direction-not-supported %d", tcont.direction());
1107 return Status::CANCELLED;
1108 }
1109 alloc_id = tcont.alloc_id();
1110 scheduler = tcont.scheduler();
1111 additional_bw = scheduler.additional_bw();
1112 priority = scheduler.priority();
1113 weight = scheduler.weight();
1114 sched_policy = scheduler.sched_policy();
1115 // TODO: TrafficShapingInfo is not supported for now as meter band support is not there
Craig Lutgen967a1d02018-11-27 10:41:51 -06001116 SchedAdd_(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority, sched_policy);
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07001117 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001118 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001119}
Jonathan Davis70c21812018-07-19 15:32:10 -04001120
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001121Status RemoveTconts_(const openolt::Tconts *tconts) {
1122 uint32_t intf_id = tconts->intf_id();
1123 uint32_t onu_id = tconts->onu_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001124 uint32_t uni_id = tconts->uni_id();
1125 uint32_t port_no = tconts->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001126 std::string direction;
1127 unsigned int alloc_id;
1128
1129 for (int i = 0; i < tconts->tconts_size(); i++) {
1130 openolt::Tcont tcont = tconts->tconts(i);
1131 if (tcont.direction() == openolt::Direction::UPSTREAM) {
1132 direction = "upstream";
1133 } else if (tcont.direction() == openolt::Direction::DOWNSTREAM) {
1134 direction = "downstream";
1135 }
1136 else {
1137 BCM_LOG(ERROR, openolt_log_id, "direction-not-supported %d", tcont.direction());
1138 return Status::CANCELLED;
1139 }
1140 alloc_id = tcont.alloc_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001141 SchedRemove_(direction, intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001142 }
1143 return Status::OK;
1144}
1145
Craig Lutgen967a1d02018-11-27 10:41:51 -06001146Status 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 -04001147
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001148 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04001149
Jonathan Davis70c21812018-07-19 15:32:10 -04001150
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001151 if (direction == "upstream") {
1152 // DBA sched
1153 bcmbal_tm_sched_cfg tm_cfg_us;
1154 bcmbal_tm_sched_key tm_key_us = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001155
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001156 tm_key_us.id = alloc_id;
1157 tm_key_us.dir = BCMBAL_TM_SCHED_DIR_US;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001158
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001159 BCMBAL_CFG_INIT(&tm_cfg_us, tm_sched, tm_key_us);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001160
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001161 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(tm_cfg_us.hdr));
1162 if (err) {
1163 BCM_LOG(ERROR, openolt_log_id, "Failed to remove upstream DBA sched, id %d, intf_id %d, onu_id %d\n",
1164 tm_key_us.id, intf_id, onu_id);
1165 return Status(grpc::StatusCode::INTERNAL, "Failed to remove upstream DBA sched");
1166 }
1167
1168 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 -04001169 tm_key_us.id, intf_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001170
1171 } else if (direction == "downstream") {
1172 // Queue
1173
1174 bcmbal_tm_queue_cfg queue_cfg;
1175 bcmbal_tm_queue_key queue_key = { };
1176 queue_key.sched_id = mk_sched_id(intf_id, onu_id, "downstream");
1177 queue_key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
Craig Lutgen967a1d02018-11-27 10:41:51 -06001178 queue_key.id = mk_queue_id(intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001179
1180 BCMBAL_CFG_INIT(&queue_cfg, tm_queue, queue_key);
1181
1182 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(queue_cfg.hdr));
1183 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001184 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",
1185 queue_key.id, queue_key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001186 return Status(grpc::StatusCode::INTERNAL, "Failed to remove downstream tm queue");
1187 }
1188
Craig Lutgen967a1d02018-11-27 10:41:51 -06001189 bcmos_fastlock_lock(&flow_lock);
1190 port_to_alloc.erase(port_no);
1191 bcmos_fastlock_unlock(&flow_lock, 0);
1192
1193 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",
1194 queue_key.id, queue_key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001195 }
1196
Jonathan Davis70c21812018-07-19 15:32:10 -04001197 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001198}