blob: a6411077317cd631a9201a6270cab406381238db [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
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500236 BCM_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
237
Shad Ansari627b5782018-08-13 22:49:32 +0000238 Status status = SubscribeIndication();
239 if (!status.ok()) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400240 BCM_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
241 grpc_status_code_to_string(status.error_code()).c_str(),
242 status.error_message().c_str());
243
Shad Ansari627b5782018-08-13 22:49:32 +0000244 return status;
245 }
246
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000247 key.access_term_id = DEFAULT_ATERM_ID;
248 BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
249 BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_UP);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400250 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
251 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400252 BCM_LOG(ERROR, openolt_log_id, "Failed to enable OLT\n");
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400253 return bcm_to_grpc_err(err, "Failed to enable OLT");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000254 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500255
Shad Ansariedef2132018-08-10 22:14:50 +0000256 init_stats();
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000257 }
Shad Ansariedef2132018-08-10 22:14:50 +0000258
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400259 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000260 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400261}
262
263Status Disable_() {
264 // bcmbal_access_terminal_cfg acc_term_obj;
265 // bcmbal_access_terminal_key key = { };
266 //
267 // if (state::is_activated) {
268 // std::cout << "Disable OLT" << std::endl;
269 // key.access_term_id = DEFAULT_ATERM_ID;
270 // BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
271 // BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
272 // bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
273 // if (err) {
274 // std::cout << "ERROR: Failed to disable OLT" << std::endl;
275 // return bcm_to_grpc_err(err, "Failed to disable OLT");
276 // }
277 // }
278 // //If already disabled, generate an extra indication ????
279 // return Status::OK;
280 //This fails with Operation Not Supported, bug ???
281
282 //TEMPORARY WORK AROUND
283 Status status = DisableUplinkIf_(0);
284 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000285 state.deactivate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400286 openolt::Indication ind;
287 openolt::OltIndication* olt_ind = new openolt::OltIndication;
288 olt_ind->set_oper_state("down");
289 ind.set_allocated_olt_ind(olt_ind);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400290 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400291 oltIndQ.push(ind);
292 }
293 return status;
294
295}
296
297Status Reenable_() {
298 Status status = EnableUplinkIf_(0);
299 if (status.ok()) {
Shad Ansariedef2132018-08-10 22:14:50 +0000300 state.activate();
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400301 openolt::Indication ind;
302 openolt::OltIndication* olt_ind = new openolt::OltIndication;
303 olt_ind->set_oper_state("up");
304 ind.set_allocated_olt_ind(olt_ind);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400305 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400306 oltIndQ.push(ind);
307 }
308 return status;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000309}
310
311Status EnablePonIf_(uint32_t intf_id) {
312 bcmbal_interface_cfg interface_obj;
313 bcmbal_interface_key interface_key;
314
315 interface_key.intf_id = intf_id;
316 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
317
318 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500319
320 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
321 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
322 if (err == BCM_ERR_OK && interface_obj.data.admin_state == BCMBAL_STATE_UP) {
323 BCM_LOG(DEBUG, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
324 return Status::OK;
325 }
326
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000327 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
328
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500329 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400330 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400331 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400332 return bcm_to_grpc_err(err, "Failed to enable PON interface");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000333 }
334
335 return Status::OK;
336}
337
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400338Status DisableUplinkIf_(uint32_t intf_id) {
339 bcmbal_interface_cfg interface_obj;
340 bcmbal_interface_key interface_key;
341
342 interface_key.intf_id = intf_id;
343 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
344
345 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
346 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
347
348 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
349 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400350 BCM_LOG(ERROR, openolt_log_id, "Failed to disable Uplink interface: %d\n", intf_id);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400351 return bcm_to_grpc_err(err, "Failed to disable Uplink interface");
352 }
353
354 return Status::OK;
355}
356
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500357Status ProbeDeviceCapabilities_() {
358 bcmbal_access_terminal_cfg acc_term_obj;
359 bcmbal_access_terminal_key key = { };
360
361 key.access_term_id = DEFAULT_ATERM_ID;
362 BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
363 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, admin_state);
364 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, oper_status);
365 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, topology);
366 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, sw_version);
367 BCMBAL_CFG_PROP_GET(&acc_term_obj, access_terminal, conn_id);
368 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
369 if (err) {
370 BCM_LOG(ERROR, openolt_log_id, "Failed to query OLT\n");
371 return bcm_to_grpc_err(err, "Failed to query OLT");
372 }
373
374 BCM_LOG(INFO, openolt_log_id, "OLT capabilitites, admin_state: %s oper_state: %s\n",
375 acc_term_obj.data.admin_state == BCMBAL_STATE_UP ? "up" : "down",
376 acc_term_obj.data.oper_status == BCMBAL_STATUS_UP ? "up" : "down");
377
378 std::string bal_version;
379 bal_version += std::to_string(acc_term_obj.data.sw_version.major_rev)
380 + "." + std::to_string(acc_term_obj.data.sw_version.minor_rev)
381 + "." + std::to_string(acc_term_obj.data.sw_version.release_rev);
382 firmware_version = "BAL." + bal_version + "__" + firmware_version;
383
384 BCM_LOG(INFO, openolt_log_id, "--------------- version %s object model: %d\n", bal_version.c_str(),
385 acc_term_obj.data.sw_version.om_version);
386
387 BCM_LOG(INFO, openolt_log_id, "--------------- topology nni:%d pon:%d dev:%d ppd:%d family: %d:%d\n",
388 acc_term_obj.data.topology.num_of_nni_ports,
389 acc_term_obj.data.topology.num_of_pon_ports,
390 acc_term_obj.data.topology.num_of_mac_devs,
391 acc_term_obj.data.topology.num_of_pons_per_mac_dev,
392 acc_term_obj.data.topology.pon_family,
393 acc_term_obj.data.topology.pon_sub_family
394 );
395
396 switch(acc_term_obj.data.topology.pon_sub_family)
397 {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500398 case BCMBAL_PON_SUB_FAMILY_GPON: board_technology = "gpon"; break;
399 case BCMBAL_PON_SUB_FAMILY_XGS: board_technology = "xgspon"; break;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500400 }
401
402 num_of_nni_ports = acc_term_obj.data.topology.num_of_nni_ports;
403 num_of_pon_ports = acc_term_obj.data.topology.num_of_pon_ports;
404
Craig Lutgenb2601f02018-10-23 13:04:31 -0500405 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 -0500406
407 return Status::OK;
408}
409
410Status ProbePonIfTechnology_() {
411 // Probe maximum extent possible as configured into BAL driver to determine
412 // which are active in the current BAL topology. And for those
413 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
414 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
415 bcmbal_interface_cfg interface_obj;
416 bcmbal_interface_key interface_key;
417
418 interface_key.intf_id = intf_id;
419 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
420
421 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
422 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
423 BCMBAL_CFG_PROP_GET(&interface_obj, interface, transceiver_type);
424
425 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
426 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500427 intf_technologies[intf_id] = UNKNOWN_TECH;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500428 if(err != BCM_ERR_RANGE) BCM_LOG(ERROR, openolt_log_id, "Failed to get PON config: %d\n", intf_id);
429 }
430 else {
431 switch(interface_obj.data.transceiver_type) {
432 case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
433 case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
434 case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
435 case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
436 case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
Craig Lutgenb2601f02018-10-23 13:04:31 -0500437 intf_technologies[intf_id] = "gpon";
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500438 break;
439 default:
Craig Lutgenb2601f02018-10-23 13:04:31 -0500440 intf_technologies[intf_id] = "xgspon";
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500441 break;
442 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500443 BCM_LOG(INFO, openolt_log_id, "PON intf_id: %d intf_technologies: %d:%s\n", intf_id,
444 interface_obj.data.transceiver_type, intf_technologies[intf_id].c_str());
445
446 if (board_technology != UNKNOWN_TECH) {
447 board_technology = intf_technologies[intf_id];
448 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
449 intf_technologies[intf_id] = MIXED_TECH;
450 }
451
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500452 }
453 }
454
455 return Status::OK;
456}
457
458unsigned NumNniIf_() {return num_of_nni_ports;}
459unsigned NumPonIf_() {return num_of_pon_ports;}
460
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400461Status EnableUplinkIf_(uint32_t intf_id) {
462 bcmbal_interface_cfg interface_obj;
463 bcmbal_interface_key interface_key;
464
465 interface_key.intf_id = intf_id;
466 interface_key.intf_type = BCMBAL_INTF_TYPE_NNI;
467
468 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500469
470 BCMBAL_CFG_PROP_GET(&interface_obj, interface, admin_state);
471 bcmos_errno err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &(interface_obj.hdr));
472 if (err == BCM_ERR_OK && interface_obj.data.admin_state == BCMBAL_STATE_UP) {
473 BCM_LOG(DEBUG, openolt_log_id, "Uplink interface: %d already enabled\n", intf_id);
474 return Status::OK;
475 }
476
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400477 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
478
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500479 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400480 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400481 BCM_LOG(ERROR, openolt_log_id, "Failed to enable Uplink interface: %d\n", intf_id);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400482 return bcm_to_grpc_err(err, "Failed to enable Uplink interface");
483 }
484
485 return Status::OK;
486}
487
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400488Status DisablePonIf_(uint32_t intf_id) {
489 bcmbal_interface_cfg interface_obj;
490 bcmbal_interface_key interface_key;
491
492 interface_key.intf_id = intf_id;
493 interface_key.intf_type = BCMBAL_INTF_TYPE_PON;
494
495 BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
496 BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
497
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400498 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
499 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400500 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400501 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400502 }
503
504 return Status::OK;
505}
506
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000507Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700508 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000509
510 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
511 bcmbal_subscriber_terminal_key subs_terminal_key;
512 bcmbal_serial_number serial_num = {};
513 bcmbal_registration_id registration_id = {};
514
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700515 BCM_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, vendor specific %s, pir %d\n",
516 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str(), pir);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000517
518 subs_terminal_key.sub_term_id = onu_id;
519 subs_terminal_key.intf_id = intf_id;
520 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
521
522 memcpy(serial_num.vendor_id, vendor_id, 4);
523 memcpy(serial_num.vendor_specific, vendor_specific, 4);
524 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, serial_number, serial_num);
525
Shad Ansaricb004c52018-05-30 18:07:23 +0000526#if 0
527 // Commenting out as this is causing issues with onu activation
528 // with BAL 2.6 (Broadcom CS5248819).
529
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000530 // FIXME - Use a default (all zeros) registration id.
531 memset(registration_id.arr, 0, sizeof(registration_id.arr));
532 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, registration_id, registration_id);
Shad Ansaricb004c52018-05-30 18:07:23 +0000533#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000534
535 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_UP);
536
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400537 bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr));
538 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400539 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 -0400540 return bcm_to_grpc_err(err, "Failed to enable ONU");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000541 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700542 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000543}
544
Jonathan Davis70c21812018-07-19 15:32:10 -0400545Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
546 const char *vendor_id, const char *vendor_specific) {
547
Jonathan Davis70c21812018-07-19 15:32:10 -0400548 bcmbal_subscriber_terminal_cfg sub_term_obj = {};
549 bcmbal_subscriber_terminal_key subs_terminal_key;
550
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400551 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 -0500552 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
Jonathan Davis70c21812018-07-19 15:32:10 -0400553
554 subs_terminal_key.sub_term_id = onu_id;
555 subs_terminal_key.intf_id = intf_id;
556 BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);
557
558 BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_DOWN);
559
560 if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr))) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400561 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 -0400562 return Status(grpc::StatusCode::INTERNAL, "Failed to deactivate ONU");
563 }
564
565 return Status::OK;
566}
567
568Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700569 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400570
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500571 BCM_LOG(INFO, openolt_log_id, "DeleteOnu ONU %d on PON %d : vendor id %s, vendor specific %s\n",
572 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
573
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400574 // Need to deactivate before removing it (BAL rules)
575
576 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
577 // Sleep to allow the state to propagate
578 // We need the subscriber terminal object to be admin down before removal
579 // Without sleep the race condition is lost by ~ 20 ms
580 std::this_thread::sleep_for(std::chrono::milliseconds(100));
581
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700582 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -0400583
Jonathan Davis70c21812018-07-19 15:32:10 -0400584 bcmos_errno err = BCM_ERR_OK;
585 bcmbal_subscriber_terminal_cfg cfg;
586 bcmbal_subscriber_terminal_key key = { };
587
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400588 BCM_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
589 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400590
591 key.sub_term_id = onu_id ;
592 key.intf_id = intf_id ;
593
594 if (0 == key.sub_term_id)
595 {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400596 BCM_LOG(INFO, openolt_log_id,"Invalid Key to handle subscriber terminal clear subscriber_terminal_id %d, Interface ID %d\n",
597 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400598 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
599 }
600
601 BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);
602
603 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
604 if (err != BCM_ERR_OK)
605 {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400606 BCM_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d\n",
607 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -0400608 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
609 }
610
611 return Status::OK;;
612}
613
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000614#define MAX_CHAR_LENGTH 20
615#define MAX_OMCI_MSG_LENGTH 44
616Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
617 bcmbal_u8_list_u32_max_2048 buf; /* A structure with a msg pointer and length value */
618 bcmos_errno err = BCM_ERR_OK;
619
620 /* The destination of the OMCI packet is a registered ONU on the OLT PON interface */
621 bcmbal_dest proxy_pkt_dest;
622
623 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_ITU_OMCI_CHANNEL;
624 proxy_pkt_dest.u.itu_omci_channel.sub_term_id = onu_id;
625 proxy_pkt_dest.u.itu_omci_channel.intf_id = intf_id;
626
627 // ???
628 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
629 buf.len = MAX_OMCI_MSG_LENGTH;
630 } else {
631 buf.len = pkt.size()/2;
632 }
633
634 /* Send the OMCI packet using the BAL remote proxy API */
635 uint16_t idx1 = 0;
636 uint16_t idx2 = 0;
637 uint8_t arraySend[buf.len];
638 char str1[MAX_CHAR_LENGTH];
639 char str2[MAX_CHAR_LENGTH];
640 memset(&arraySend, 0, buf.len);
641
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000642 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
643 sprintf(str1,"%c", pkt[idx1]);
644 sprintf(str2,"%c", pkt[++idx1]);
645 strcat(str1,str2);
646 arraySend[idx2] = strtol(str1, NULL, 16);
647 }
648
649 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
650 memcpy(buf.val, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000651
652 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
653
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400654 if (err) {
655 BCM_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
656 } else {
657 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 -0500658 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400659 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000660
661 free(buf.val);
662
663 return Status::OK;
664}
665
Craig Lutgen967a1d02018-11-27 10:41:51 -0600666Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, uint32_t port_no, const std::string pkt) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000667 bcmos_errno err = BCM_ERR_OK;
668 bcmbal_dest proxy_pkt_dest;
669 bcmbal_u8_list_u32_max_2048 buf;
670
Craig Lutgen967a1d02018-11-27 10:41:51 -0600671 if (port_no > 0) {
672 bool found = false;
673 uint32_t gemport_id;
674
675 bcmos_fastlock_lock(&flow_lock);
676 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
677 // Pick any flow that is mapped with the same port_no.
678 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
679 if (it != port_to_flows.end() && !it->second.empty()) {
680 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
681 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
682 if (fit != flowid_to_gemport.end()) {
683 found = true;
684 gemport_id = fit->second;
685 }
686 }
687 bcmos_fastlock_unlock(&flow_lock, 0);
688
689 if (!found) {
690 BCM_LOG(ERROR, openolt_log_id, "Packet out failed to find destination for ONU %d port_no %u on PON %d\n",
691 onu_id, port_no, intf_id);
692 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
693 }
694
695 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_SVC_PORT;
696 proxy_pkt_dest.u.svc_port.svc_port_id = gemport_id;
697 proxy_pkt_dest.u.svc_port.intf_id = intf_id;
698 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
699 pkt.size(), gemport_id, intf_id, port_no);
700 }
701 else {
702 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_SUB_TERM,
703 proxy_pkt_dest.u.sub_term.sub_term_id = onu_id;
704 proxy_pkt_dest.u.sub_term.intf_id = intf_id;
705 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent to onu %d on pon %d\n",
706 pkt.size(), onu_id, intf_id);
707 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000708
709 buf.len = pkt.size();
710 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
711 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
712
713 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
714
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000715 free(buf.val);
716
717 return Status::OK;
718}
719
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400720Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
721 bcmos_errno err = BCM_ERR_OK;
722 bcmbal_dest proxy_pkt_dest;
723 bcmbal_u8_list_u32_max_2048 buf;
724
725 proxy_pkt_dest.type = BCMBAL_DEST_TYPE_NNI,
726 proxy_pkt_dest.u.nni.intf_id = intf_id;
727
728 buf.len = pkt.size();
729 buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
730 memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
731
732 err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
733
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400734 BCM_LOG(INFO, openolt_log_id, "Packet out of length %d sent through uplink port %d\n",
735 buf.len, intf_id);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400736
737 free(buf.val);
738
739 return Status::OK;
740}
741
Craig Lutgen967a1d02018-11-27 10:41:51 -0600742uint32_t GetPortNum_(uint32_t flow_id)
743{
744 bcmos_fastlock_lock(&flow_lock);
745 uint32_t port_no = 0;
746 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
747 if (it != flowid_to_port.end()) {
748 port_no = it->second;
749 }
750 bcmos_fastlock_unlock(&flow_lock, 0);
751 return port_no;
752}
753
754Status 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 +0000755 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700756 int32_t alloc_id, int32_t network_intf_id,
757 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -0600758 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000759 bcmos_errno err;
760 bcmbal_flow_cfg cfg;
761 bcmbal_flow_key key = { };
762
Craig Lutgenecd353a2018-12-12 22:33:17 -0600763 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 -0600764 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 +0000765
766 key.flow_id = flow_id;
767 if (flow_type.compare("upstream") == 0 ) {
768 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
769 } else if (flow_type.compare("downstream") == 0) {
770 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
771 } else {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400772 BCM_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400773 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000774 }
775
776 BCMBAL_CFG_INIT(&cfg, flow, key);
777
778 BCMBAL_CFG_PROP_SET(&cfg, flow, admin_state, BCMBAL_STATE_UP);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600779 BCMBAL_CFG_PROP_SET(&cfg, flow, cookie, cookie);
780
Shad Ansari39739bc2018-09-13 21:38:37 +0000781 if (access_intf_id >= 0) {
782 BCMBAL_CFG_PROP_SET(&cfg, flow, access_int_id, access_intf_id);
783 }
784 if (network_intf_id >= 0) {
785 BCMBAL_CFG_PROP_SET(&cfg, flow, network_int_id, network_intf_id);
786 }
787 if (onu_id >= 0) {
788 BCMBAL_CFG_PROP_SET(&cfg, flow, sub_term_id, onu_id);
789 }
790 if (gemport_id >= 0) {
791 BCMBAL_CFG_PROP_SET(&cfg, flow, svc_port_id, gemport_id);
792 }
Craig Lutgen967a1d02018-11-27 10:41:51 -0600793 if (gemport_id >= 0 && port_no != 0) {
794 bcmos_fastlock_lock(&flow_lock);
795 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
796 port_to_flows[port_no].insert(key.flow_id);
797 flowid_to_gemport[key.flow_id] = gemport_id;
798 }
799 else
800 {
801 flowid_to_port[key.flow_id] = port_no;
802 }
803 bcmos_fastlock_unlock(&flow_lock, 0);
804 }
Shad Ansari39739bc2018-09-13 21:38:37 +0000805 if (priority_value >= 0) {
806 BCMBAL_CFG_PROP_SET(&cfg, flow, priority, priority_value);
807 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000808
809 {
810 bcmbal_classifier val = { };
811
812 if (classifier.o_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600813 BCM_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", 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 Lutgenecd353a2018-12-12 22:33:17 -0600818 BCM_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500819 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_vid, classifier.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000820 }
821
822 if (classifier.i_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600823 BCM_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -0500824 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000825 }
826
827 if (classifier.i_vid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600828 BCM_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500829 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_vid, classifier.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000830 }
831
832 if (classifier.o_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600833 BCM_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500834 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_pbits, classifier.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000835 }
836
837 if (classifier.i_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600838 BCM_LOG(DEBUG, openolt_log_id, "classify i_pbits 0x%x\n", classifier.i_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500839 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_pbits, classifier.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000840 }
841
842 if (classifier.eth_type()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600843 BCM_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
Craig Lutgen19512312018-11-02 10:14:46 -0500844 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000845 }
846
847 /*
848 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500849 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000850 }
851
852 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500853 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000854 }
855 */
856
857 if (classifier.ip_proto()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600858 BCM_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
Craig Lutgen19512312018-11-02 10:14:46 -0500859 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000860 }
861
862 /*
863 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500864 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000865 }
866
867 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -0500868 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000869 }
870 */
871
872 if (classifier.src_port()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600873 BCM_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
Craig Lutgen19512312018-11-02 10:14:46 -0500874 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000875 }
876
877 if (classifier.dst_port()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600878 BCM_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
Craig Lutgen19512312018-11-02 10:14:46 -0500879 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000880 }
881
882 if (!classifier.pkt_tag_type().empty()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600883 BCM_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000884 if (classifier.pkt_tag_type().compare("untagged") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500885 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_UNTAGGED);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000886 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500887 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_SINGLE_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000888 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
Craig Lutgen19512312018-11-02 10:14:46 -0500889 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000890 }
891 }
892
893 BCMBAL_CFG_PROP_SET(&cfg, flow, classifier, val);
894 }
895
896 {
897 bcmbal_action val = { };
898
899 const ::openolt::ActionCmd& cmd = action.cmd();
900
901 if (cmd.add_outer_tag()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600902 BCM_LOG(INFO, openolt_log_id, "action add o_tag\n");
Craig Lutgen19512312018-11-02 10:14:46 -0500903 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000904 }
905
906 if (cmd.remove_outer_tag()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600907 BCM_LOG(INFO, openolt_log_id, "action pop o_tag\n");
Craig Lutgen19512312018-11-02 10:14:46 -0500908 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000909 }
910
911 if (cmd.trap_to_host()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600912 BCM_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -0500913 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000914 }
915
916 if (action.o_vid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600917 BCM_LOG(INFO, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500918 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000919 }
920
921 if (action.o_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600922 BCM_LOG(INFO, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500923 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000924 }
925
926 if (action.o_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600927 BCM_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -0500928 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000929 }
930
931 if (action.i_vid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600932 BCM_LOG(INFO, openolt_log_id, "action i_vid=%d\n", action.i_vid());
Craig Lutgen19512312018-11-02 10:14:46 -0500933 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000934 }
935
936 if (action.i_pbits()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600937 BCM_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
Craig Lutgen19512312018-11-02 10:14:46 -0500938 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000939 }
940
941 if (action.i_tpid()) {
Craig Lutgenecd353a2018-12-12 22:33:17 -0600942 BCM_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -0500943 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000944 }
945
946 BCMBAL_CFG_PROP_SET(&cfg, flow, action, val);
947 }
948
Shad Ansari39739bc2018-09-13 21:38:37 +0000949 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000950
Shad Ansari39739bc2018-09-13 21:38:37 +0000951 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
952 bcmbal_tm_queue_ref val = { };
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700953 val.sched_id = mk_sched_id(access_intf_id, onu_id, "downstream");
Craig Lutgen967a1d02018-11-27 10:41:51 -0600954 uint32_t alloc_id;
955 bcmos_fastlock_lock(&flow_lock);
956 alloc_id = port_to_alloc[port_no];
957 bcmos_fastlock_unlock(&flow_lock, 0);
958 val.queue_id = mk_queue_id(access_intf_id, onu_id, uni_id, port_no, alloc_id);
Shad Ansari39739bc2018-09-13 21:38:37 +0000959 BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700960 } else if (key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM) {
961 bcmbal_tm_sched_id val1;
962 if (alloc_id != 0) {
963 val1 = alloc_id;
964 } else {
965 BCM_LOG(ERROR, openolt_log_id, "alloc_id not present");
966 }
967 BCMBAL_CFG_PROP_SET(&cfg, flow, dba_tm_sched_id, val1);
968
969 bcmbal_tm_queue_ref val2 = { };
970 val2.sched_id = mk_sched_id(network_intf_id, onu_id, "upstream");
971 BCMBAL_CFG_PROP_SET(&cfg, flow, queue, val2);
Shad Ansari39739bc2018-09-13 21:38:37 +0000972 }
Shad Ansari06101952018-07-25 00:22:09 +0000973 }
974
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400975 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
976 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400977 BCM_LOG(ERROR, openolt_log_id, "Flow add failed\n");
Nicolas Palpacuer73222e02018-07-16 12:20:26 -0400978 return bcm_to_grpc_err(err, "flow add failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000979 }
980
Nicolas Palpacuer6a63ea92018-09-05 17:21:37 -0400981 // register_new_flow(key);
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400982
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000983 return Status::OK;
984}
985
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400986Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
987
988 bcmbal_flow_cfg cfg;
989 bcmbal_flow_key key = { };
990
991 key.flow_id = (bcmbal_flow_id) flow_id;
992 key.flow_id = flow_id;
993 if (flow_type.compare("upstream") == 0 ) {
994 key.flow_type = BCMBAL_FLOW_TYPE_UPSTREAM;
995 } else if (flow_type.compare("downstream") == 0) {
996 key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
997 } else {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -0400998 BCM_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400999 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1000 }
1001
Craig Lutgen967a1d02018-11-27 10:41:51 -06001002 bcmos_fastlock_lock(&flow_lock);
1003 uint32_t port_no = flowid_to_port[key.flow_id];
1004 if (key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) {
1005 flowid_to_gemport.erase(key.flow_id);
1006 port_to_flows[port_no].erase(key.flow_id);
1007 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1008 }
1009 else
1010 {
1011 flowid_to_port.erase(key.flow_id);
1012 }
1013 bcmos_fastlock_unlock(&flow_lock, 0);
1014
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001015 BCMBAL_CFG_INIT(&cfg, flow, key);
1016
1017
1018 bcmos_errno err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
1019 if (err) {
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001020 BCM_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
1021 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001022 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1023 }
1024
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001025 BCM_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001026 return Status::OK;
1027}
1028
Craig Lutgen967a1d02018-11-27 10:41:51 -06001029Status 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 -07001030 uint32_t alloc_id, openolt::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
1031 openolt::SchedulingPolicy sched_policy) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001032
1033 bcmos_errno err;
1034
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001035 if (direction == "downstream") {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001036 bcmbal_tm_queue_cfg cfg;
1037 bcmbal_tm_queue_key key = { };
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001038 // Note: We use the default scheduler available in the DL.
1039 key.sched_id = mk_sched_id(intf_id, onu_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001040 key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
Craig Lutgen967a1d02018-11-27 10:41:51 -06001041 key.id = mk_queue_id(intf_id, onu_id, uni_id, port_no, alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001042
1043 BCMBAL_CFG_INIT(&cfg, tm_queue, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001044 //Queue must be set with either weight or priority, not both,
1045 // as its scheduler' sched_type is sp_wfq
1046 BCMBAL_CFG_PROP_SET(&cfg, tm_queue, priority, priority);
1047 //BCMBAL_CFG_PROP_SET(&cfg, tm_queue, weight, weight);
1048 //BCMBAL_CFG_PROP_SET(&cfg, tm_queue, creation_mode, BCMBAL_TM_CREATION_MODE_MANUAL);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001049 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &cfg.hdr);
1050
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001051 // TODO: Shaping parameters will be available after meter bands are supported.
1052 // TODO: The shaping parameters will be applied on the downstream queue on the PON default scheduler.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001053 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001054 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",
1055 key.id, key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001056 return bcm_to_grpc_err(err, "Failed to create subscriber downstream tm queue");
1057 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001058
1059 bcmos_fastlock_lock(&flow_lock);
1060 port_to_alloc[port_no] = alloc_id;
1061 bcmos_fastlock_unlock(&flow_lock, 0);
1062
1063 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",
1064 key.id,intf_id,onu_id,uni_id,port_no,alloc_id);
1065
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001066 } else { //"upstream"
1067 bcmbal_tm_sched_cfg cfg;
1068 bcmbal_tm_sched_key key = { };
1069 bcmbal_tm_sched_type sched_type;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001070
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001071 key.id = alloc_id;
1072 key.dir = BCMBAL_TM_SCHED_DIR_US;
1073
1074 BCMBAL_CFG_INIT(&cfg, tm_sched, key);
1075
1076 {
1077 bcmbal_tm_sched_owner val = { };
1078
1079 val.type = BCMBAL_TM_SCHED_OWNER_TYPE_AGG_PORT;
1080 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, intf_id, (bcmbal_intf_id) intf_id);
1081 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, sub_term_id, (bcmbal_sub_id) onu_id);
1082 BCMBAL_ATTRIBUTE_PROP_SET(&val.u.agg_port, tm_sched_owner_agg_port, agg_port_id, (bcmbal_aggregation_port_id) alloc_id);
1083
1084 BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, val);
1085
1086 }
1087 // TODO: Shaping parameters will be available after meter bands are supported.
1088 // TODO: The shaping parameters will be applied on the upstream DBA scheduler.
1089
1090 err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
1091 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001092 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",
1093 key.id, intf_id, onu_id,uni_id,port_no,alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001094 return bcm_to_grpc_err(err, "Failed to create upstream DBA sched");
1095 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001096 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",
1097 key.id,intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001098 }
1099
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001100 return Status::OK;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001101
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001102}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001103
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001104Status CreateTconts_(const openolt::Tconts *tconts) {
1105 uint32_t intf_id = tconts->intf_id();
1106 uint32_t onu_id = tconts->onu_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001107 uint32_t uni_id = tconts->uni_id();
1108 uint32_t port_no = tconts->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001109 std::string direction;
1110 unsigned int alloc_id;
1111 openolt::Scheduler scheduler;
1112 openolt::AdditionalBW additional_bw;
1113 uint32_t priority;
1114 uint32_t weight;
1115 openolt::SchedulingPolicy sched_policy;
1116
1117 for (int i = 0; i < tconts->tconts_size(); i++) {
1118 openolt::Tcont tcont = tconts->tconts(i);
1119 if (tcont.direction() == openolt::Direction::UPSTREAM) {
1120 direction = "upstream";
1121 } else if (tcont.direction() == openolt::Direction::DOWNSTREAM) {
1122 direction = "downstream";
1123 }
1124 else {
1125 BCM_LOG(ERROR, openolt_log_id, "direction-not-supported %d", tcont.direction());
1126 return Status::CANCELLED;
1127 }
1128 alloc_id = tcont.alloc_id();
1129 scheduler = tcont.scheduler();
1130 additional_bw = scheduler.additional_bw();
1131 priority = scheduler.priority();
1132 weight = scheduler.weight();
1133 sched_policy = scheduler.sched_policy();
1134 // TODO: TrafficShapingInfo is not supported for now as meter band support is not there
Craig Lutgen967a1d02018-11-27 10:41:51 -06001135 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 -07001136 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001137 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001138}
Jonathan Davis70c21812018-07-19 15:32:10 -04001139
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001140Status RemoveTconts_(const openolt::Tconts *tconts) {
1141 uint32_t intf_id = tconts->intf_id();
1142 uint32_t onu_id = tconts->onu_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001143 uint32_t uni_id = tconts->uni_id();
1144 uint32_t port_no = tconts->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001145 std::string direction;
1146 unsigned int alloc_id;
1147
1148 for (int i = 0; i < tconts->tconts_size(); i++) {
1149 openolt::Tcont tcont = tconts->tconts(i);
1150 if (tcont.direction() == openolt::Direction::UPSTREAM) {
1151 direction = "upstream";
1152 } else if (tcont.direction() == openolt::Direction::DOWNSTREAM) {
1153 direction = "downstream";
1154 }
1155 else {
1156 BCM_LOG(ERROR, openolt_log_id, "direction-not-supported %d", tcont.direction());
1157 return Status::CANCELLED;
1158 }
1159 alloc_id = tcont.alloc_id();
Craig Lutgen967a1d02018-11-27 10:41:51 -06001160 SchedRemove_(direction, intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001161 }
1162 return Status::OK;
1163}
1164
Craig Lutgen967a1d02018-11-27 10:41:51 -06001165Status 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 -04001166
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001167 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04001168
Jonathan Davis70c21812018-07-19 15:32:10 -04001169
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001170 if (direction == "upstream") {
1171 // DBA sched
1172 bcmbal_tm_sched_cfg tm_cfg_us;
1173 bcmbal_tm_sched_key tm_key_us = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001174
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001175 tm_key_us.id = alloc_id;
1176 tm_key_us.dir = BCMBAL_TM_SCHED_DIR_US;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001177
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001178 BCMBAL_CFG_INIT(&tm_cfg_us, tm_sched, tm_key_us);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001179
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001180 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(tm_cfg_us.hdr));
1181 if (err) {
1182 BCM_LOG(ERROR, openolt_log_id, "Failed to remove upstream DBA sched, id %d, intf_id %d, onu_id %d\n",
1183 tm_key_us.id, intf_id, onu_id);
1184 return Status(grpc::StatusCode::INTERNAL, "Failed to remove upstream DBA sched");
1185 }
1186
1187 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 -04001188 tm_key_us.id, intf_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001189
1190 } else if (direction == "downstream") {
1191 // Queue
1192
1193 bcmbal_tm_queue_cfg queue_cfg;
1194 bcmbal_tm_queue_key queue_key = { };
1195 queue_key.sched_id = mk_sched_id(intf_id, onu_id, "downstream");
1196 queue_key.sched_dir = BCMBAL_TM_SCHED_DIR_DS;
Craig Lutgen967a1d02018-11-27 10:41:51 -06001197 queue_key.id = mk_queue_id(intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001198
1199 BCMBAL_CFG_INIT(&queue_cfg, tm_queue, queue_key);
1200
1201 err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &(queue_cfg.hdr));
1202 if (err) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001203 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",
1204 queue_key.id, queue_key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001205 return Status(grpc::StatusCode::INTERNAL, "Failed to remove downstream tm queue");
1206 }
1207
Craig Lutgen967a1d02018-11-27 10:41:51 -06001208 bcmos_fastlock_lock(&flow_lock);
1209 port_to_alloc.erase(port_no);
1210 bcmos_fastlock_unlock(&flow_lock, 0);
1211
1212 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",
1213 queue_key.id, queue_key.sched_id, intf_id, onu_id, uni_id, port_no, alloc_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001214 }
1215
Jonathan Davis70c21812018-07-19 15:32:10 -04001216 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001217}