blob: 3267c6c9a701af08c6909ae634736169cde4512f [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Jason Huang09b73ea2020-01-08 17:52:05 +080028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000031
Craig Lutgen88a22ad2018-10-04 12:30:46 -050032#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000033#include "core.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053034#include "core_data.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000035#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040036#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040037#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040038#include "state.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053039#include "core_utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000040
41extern "C"
42{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000043#include <bcmolt_api.h>
44#include <bcmolt_host_api.h>
45#include <bcmolt_api_model_supporting_enums.h>
46
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000047#include <bcmolt_api_conn_mgr.h>
48//CLI header files
49#include <bcmcli_session.h>
50#include <bcmcli.h>
51#include <bcm_api_cli.h>
52
53#include <bcmos_common.h>
54#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040055// FIXME : dependency problem
56// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040057// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000058}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000059
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000060static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050062static const std::string MIXED_TECH("mixed");
63static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000064static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000065static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040066
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
68 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
69 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
Burak Gurdag2f2618c2020-04-23 13:20:30 +000070 tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
71static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080072static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050074static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +000075 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000076static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
77static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
78
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079inline const char *get_flow_acton_command(uint32_t command) {
80 char actions[200] = { };
81 char *s_actions_ptr = actions;
82 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
83 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
90 return s_actions_ptr;
91}
92
Jason Huang5d9ab1a2020-04-15 16:53:49 +080093bcmolt_stat_alarm_config set_stat_alarm_config(const openolt::OnuItuPonAlarm* request) {
94 bcmolt_stat_alarm_config alarm_cfg = {};
95 bcmolt_stat_alarm_trigger_config trigger_obj = {};
96 bcmolt_stat_alarm_soak_config soak_obj = {};
97
98 switch (request->alarm_reporting_condition()) {
99 case openolt::OnuItuPonAlarm::RATE_THRESHOLD:
100 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
101 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
102 rising, request->rate_threshold_config().rate_threshold_rising());
103 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
104 falling, request->rate_threshold_config().rate_threshold_falling());
105 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
106 request->rate_threshold_config().soak_time().active_soak_time());
107 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
108 request->rate_threshold_config().soak_time().clear_soak_time());
109 break;
110 case openolt::OnuItuPonAlarm::RATE_RANGE:
111 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
112 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
113 request->rate_range_config().rate_range_upper());
114 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
115 request->rate_range_config().rate_range_lower());
116 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
117 request->rate_range_config().soak_time().active_soak_time());
118 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
119 request->rate_range_config().soak_time().clear_soak_time());
120 break;
121 case openolt::OnuItuPonAlarm::VALUE_THRESHOLD:
122 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
123 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
124 limit, request->value_threshold_config().threshold_limit());
125 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
126 request->value_threshold_config().soak_time().active_soak_time());
127 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
128 request->value_threshold_config().soak_time().clear_soak_time());
129 break;
130 default:
131 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
132 // For now just log the error and not return error. We can handle this scenario in the future.
133 break;
134 }
135
136 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
138
139 return alarm_cfg;
140}
141
142Status OnuItuPonAlarmSet_(const openolt::OnuItuPonAlarm* request) {
143 bcmos_errno err;
144 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
145 bcmolt_onu_key key = {}; /* declare key */
146 bcmolt_stat_alarm_config errors_cfg = {};
147
148 key.pon_ni = request->pon_ni();
149 key.onu_id = request->onu_id();
150
151 /* Initialize the API struct. */
152 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
153
154 /*
155 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
156 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
157 crosses the configured threshold boundary.
158 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
159 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
160 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
161 deviates from the configured range.
162 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
163 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
164 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
165 than this level. The alarm is cleared when the host read the stats.
166 limit: The alarm is raised if the stats sample value becomes greater than this level.
167 The alarm is cleared when the host clears the stats.
168
169 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
170 of time (unit=seconds), the alarm indication is sent to the host.
171 The OLT delays the alarm indication no less than this delay period.
172 It can be delayed more than this period because of the statistics sampling interval.
173 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
174 this amount of time (unit=seconds), the alarm indication is sent to the host.
175 The OLT delays the alarm indication no less than this delay period. It can be delayed more
176 than this period because of the statistics sampling interval.
177 */
178
179 errors_cfg = set_stat_alarm_config(request);
180
181 switch (request->alarm_id()) {
182 case openolt::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
183 //set the rdi_errors alarm
184 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
185 break;
186 default:
187 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
188 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
189 }
190
191 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
192 if (err != BCM_ERR_OK) {
193 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set onu itu pon stats, alarm id %d, pon_ni %d, onu_id %d, err = %s\n",
194 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
195 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
196 } else {
197 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
198 request->alarm_id(), key.pon_ni, key.onu_id);
199 }
200
201 return Status::OK;
202}
203
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400204Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 device_info->set_vendor(VENDOR_ID);
206 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400207 device_info->set_hardware_version("");
208 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500209 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500211
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800212 char serial_number[OPENOLT_FIELD_LEN];
213 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
214 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000215 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800216 device_info->set_device_serial_number(serial_number);
217
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700218 char device_id[OPENOLT_FIELD_LEN];
219 memset(device_id, '\0', OPENOLT_FIELD_LEN);
220 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000221 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700222 device_info->set_device_id(device_id);
223
Craig Lutgenb2601f02018-10-23 13:04:31 -0500224 // Legacy, device-wide ranges. To be deprecated when adapter
225 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000226 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500227 device_info->set_onu_id_start(1);
228 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600229 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500230 device_info->set_alloc_id_end(16383);
231 device_info->set_gemport_id_start(1024);
232 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500233 device_info->set_flow_id_start(1);
234 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500235 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000236 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500237 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500238 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600239 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500240 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500241 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500242 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500243 device_info->set_flow_id_start(1);
244 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500245 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500246
247 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
248 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
249 std::string intf_technology = intf_technologies[intf_id];
250 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
251 if(range == nullptr) {
252 range = device_info->add_ranges();
253 ranges[intf_technology] = range;
254 range->set_technology(intf_technology);
255
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000256 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500257 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
258
259 pool = range->add_pools();
260 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
261 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
262 pool->set_start(1);
263 pool->set_end(255);
264
265 pool = range->add_pools();
266 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800267 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500268 pool->set_start(1024);
269 pool->set_end(16383);
270
271 pool = range->add_pools();
272 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800273 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500274 pool->set_start(1024);
275 pool->set_end(65535);
276
277 pool = range->add_pools();
278 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
279 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
280 pool->set_start(1);
281 pool->set_end(16383);
282 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000283 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500284 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
285
286 pool = range->add_pools();
287 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
288 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
289 pool->set_start(1);
290 pool->set_end(127);
291
292 pool = range->add_pools();
293 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800294 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500295 pool->set_start(256);
296 pool->set_end(757);
297
298 pool = range->add_pools();
299 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
Girish Gowdra1d018a52020-03-05 14:38:20 -0800300 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500301 pool->set_start(256);
302 pool->set_end(4095);
303
304 pool = range->add_pools();
305 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
306 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
307 pool->set_start(1);
308 pool->set_end(16383);
309 }
310 }
311
312 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500313 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400314
315 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500316 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400317 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
318 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500319 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400320 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500321 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
322 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400323
324 return Status::OK;
325}
326
Shad Ansari627b5782018-08-13 22:49:32 +0000327Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000328 bcmos_errno err;
329 bcmolt_host_init_parms init_parms = {};
330 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
331 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000332
Shad Ansariedef2132018-08-10 22:14:50 +0000333 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000334
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500335 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000336 /* Initialize host subsystem */
337 err = bcmolt_host_init(&init_parms);
338 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500339 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000340 return bcm_to_grpc_err(err, "Failed to init OLT");
341 }
342
343 bcmcli_session_parm mon_session_parm;
344 /* Create CLI session */
345 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
346 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
347 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
348 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
349 BUG_ON(rc != BCM_ERR_OK);
350
351 /* API CLI */
352 bcm_openolt_api_cli_init(NULL, current_session);
353
354 /* Add quit command */
355 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
356
357 err = bcmolt_apiend_cli_init();
358 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500359 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000360 return bcm_to_grpc_err(err, "Failed to add apiend init");
361 }
362
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800363 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530364 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530365 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000366 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600367
Jason Huangbf45ffb2019-10-30 17:29:02 +0800368 //check BCM daemon is connected or not
369 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000370 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800371 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000372 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800373 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000374 Status status = SubscribeIndication();
375 if (!status.ok()) {
376 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
377 grpc_status_code_to_string(status.error_code()).c_str(),
378 status.error_message().c_str());
379 return status;
380 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800381
382 //check BAL state in initial stage
383 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000384 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800385 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000386 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800387 }
388
389 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000390 bcmos_errno err;
391 bcmolt_odid dev;
392 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
393 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400394 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000395 bcmolt_device_key dev_key = { };
396 dev_key.device_id = dev;
397 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
398 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
399 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800400 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000401 bcmolt_device_key key = {.device_id = dev};
402 bcmolt_device_connect oper;
403 BCMOLT_OPER_INIT(&oper, device, connect, key);
404 if (MODEL_ID == "asfvolt16") {
405 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
406 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
407 } else if (MODEL_ID == "asgvolt64") {
408 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
409 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
410 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
411 }
412 err = bcmolt_oper_submit(dev_id, &oper.hdr);
413 if (err) {
414 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500415 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err = %s\n", dev, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000416 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500417 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable all the pon ports, err = %s\n", bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000418 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
419 }
420 }
421 bcmos_usleep(200000);
422 }
423 else {
424 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
425 state.activate();
426 }
427 }
428 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000429 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000430 }
Shad Ansariedef2132018-08-10 22:14:50 +0000431
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000432 /* Start CLI */
433 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400434 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000435 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400436}
437
438Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400439 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
440 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
441 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
442 //To overcome this disable is implemented by disabling all the PON ports
443 //associated with the device so as to support both in-band
444 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400445
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400446 Status status;
447 int failedCount = 0;
448 for (int i = 0; i < NumPonIf_(); i++) {
449 status = DisablePonIf_(i);
450 if (!status.ok()) {
451 failedCount+=1;
452 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
453 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400454 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400455 if (failedCount == 0) {
456 state.deactivate();
457 openolt::Indication ind;
458 openolt::OltIndication* olt_ind = new openolt::OltIndication;
459 olt_ind->set_oper_state("down");
460 ind.set_allocated_olt_ind(olt_ind);
461 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
462 oltIndQ.push(ind);
463 return Status::OK;
464 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000465 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400466 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
467 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400468
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400469 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to disable olt ,few PON ports are still in enabled state");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400470}
471
472Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400473 Status status;
474 int failedCount = 0;
475 for (int i = 0; i < NumPonIf_(); i++) {
476 status = EnablePonIf_(i);
477 if (!status.ok()) {
478 failedCount+=1;
479 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
480 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400481 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000482 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400483 state.activate();
484 openolt::Indication ind;
485 openolt::OltIndication* olt_ind = new openolt::OltIndication;
486 olt_ind->set_oper_state("up");
487 ind.set_allocated_olt_ind(olt_ind);
488 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
489 oltIndQ.push(ind);
490 return Status::OK;
491 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000492 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400493 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
494 }
495 return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to re-enable olt ,few PON ports are still in disabled state");
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000496}
497
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000498inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
499 bcmos_errno err;
500 bcmolt_flow_key flow_key;
501 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400502
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000503 flow_key.flow_id = flow_id;
504 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400505
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000506 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400507
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000508 switch (data_id) {
509 case ONU_ID: //onu_id
510 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500511 #ifdef TEST_MODE
512 // It is impossible to mock the setting of flow_cfg.data.state because
513 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
514 // set the flow_cfg.data. So a new stub function is created and address
515 // of flow_cfg is passed. This is one-of case where we need to add test specific
516 // code in production code.
517 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
518 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000519 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500520 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000521 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500522 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000523 return err;
524 }
525 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400526 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500527 #ifdef TEST_MODE
528 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
529 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000530 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500531 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000532 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500533 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000534 return err;
535 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400536 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000537 case SVC_PORT_ID: //svc_port_id
538 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500539 #ifdef TEST_MODE
540 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
541 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000542 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500543 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000544 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500545 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000546 return err;
547 }
548 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400549 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000550 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500551 #ifdef TEST_MODE
552 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
553 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000554 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500555 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000556 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500557 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000558 return err;
559 }
560 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400561 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000562 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500563 #ifdef TEST_MODE
564 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
565 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000566 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500567 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000568 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500569 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000570 return err;
571 }
572 return flow_cfg.data.cookie;
573 case INGRESS_INTF_TYPE: //ingress intf_type
574 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500575 #ifdef TEST_MODE
576 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
577 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000578 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500579 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000580 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500581 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000582 return err;
583 }
584 return flow_cfg.data.ingress_intf.intf_type;
585 case EGRESS_INTF_TYPE: //egress intf_type
586 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500587 #ifdef TEST_MODE
588 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
589 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000590 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500591 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000592 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500593 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000594 return err;
595 }
596 return flow_cfg.data.egress_intf.intf_type;
597 case INGRESS_INTF_ID: //ingress intf_id
598 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500599 #ifdef TEST_MODE
600 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
601 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000602 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500603 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000604 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500605 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000606 return err;
607 }
608 return flow_cfg.data.ingress_intf.intf_id;
609 case EGRESS_INTF_ID: //egress intf_id
610 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500611 #ifdef TEST_MODE
612 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
613 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000614 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500615 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000616 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500617 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000618 return err;
619 }
620 return flow_cfg.data.egress_intf.intf_id;
621 case CLASSIFIER_O_VID:
622 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500623 #ifdef TEST_MODE
624 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
625 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000626 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500627 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000628 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500629 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000630 return err;
631 }
632 return flow_cfg.data.classifier.o_vid;
633 case CLASSIFIER_O_PBITS:
634 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500635 #ifdef TEST_MODE
636 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
637 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000638 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500639 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000640 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500641 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000642 return err;
643 }
644 return flow_cfg.data.classifier.o_pbits;
645 case CLASSIFIER_I_VID:
646 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500647 #ifdef TEST_MODE
648 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
649 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000650 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500651 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000652 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500653 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000654 return err;
655 }
656 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400657 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000658 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500659 #ifdef TEST_MODE
660 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
661 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000662 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500663 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000664 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500665 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000666 return err;
667 }
668 return flow_cfg.data.classifier.i_pbits;
669 case CLASSIFIER_ETHER_TYPE:
670 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500671 #ifdef TEST_MODE
672 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
673 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000674 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500675 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000676 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500677 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000678 return err;
679 }
680 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400681 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000682 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500683 #ifdef TEST_MODE
684 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
685 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000686 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500687 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000688 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500689 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000690 return err;
691 }
692 return flow_cfg.data.classifier.ip_proto;
693 case CLASSIFIER_SRC_PORT:
694 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500695 #ifdef TEST_MODE
696 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
697 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000698 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500699 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000700 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500701 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000702 return err;
703 }
704 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400705 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000706 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500707 #ifdef TEST_MODE
708 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
709 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000710 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500711 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000712 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500713 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000714 return err;
715 }
716 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400717 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000718 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500719 #ifdef TEST_MODE
720 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
721 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000722 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500723 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000724 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500725 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000726 return err;
727 }
728 return flow_cfg.data.classifier.pkt_tag_type;
729 case EGRESS_QOS_TYPE:
730 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500731 #ifdef TEST_MODE
732 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
733 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000734 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500735 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000736 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500737 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000738 return err;
739 }
740 return flow_cfg.data.egress_qos.type;
741 case EGRESS_QOS_QUEUE_ID:
742 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500743 #ifdef TEST_MODE
744 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
745 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000746 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500747 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000748 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500749 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000750 return err;
751 }
752 switch (flow_cfg.data.egress_qos.type) {
753 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
754 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
755 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
756 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
757 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
758 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
759 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
760 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
761 case BCMOLT_EGRESS_QOS_TYPE_NONE:
762 default:
763 return -1;
764 }
765 case EGRESS_QOS_TM_SCHED_ID:
766 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500767 #ifdef TEST_MODE
768 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
769 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000770 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500771 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000772 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500773 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000774 return err;
775 }
776 return flow_cfg.data.egress_qos.tm_sched.id;
777 case ACTION_CMDS_BITMASK:
778 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500779 #ifdef TEST_MODE
780 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
781 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000782 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500783 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000784 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500785 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000786 return err;
787 }
788 return flow_cfg.data.action.cmds_bitmask;
789 case ACTION_O_VID:
790 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500791 #ifdef TEST_MODE
792 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
793 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000794 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500795 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000796 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500797 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000798 return err;
799 }
800 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400801 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000802 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500803 #ifdef TEST_MODE
804 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
805 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000806 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500807 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000808 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500809 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000810 return err;
811 }
812 return flow_cfg.data.action.o_pbits;
813 case ACTION_I_VID:
814 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500815 #ifdef TEST_MODE
816 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
817 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000818 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500819 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000820 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500821 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000822 return err;
823 }
824 return flow_cfg.data.action.i_vid;
825 case ACTION_I_PBITS:
826 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500827 #ifdef TEST_MODE
828 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
829 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000830 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500831 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000832 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500833 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000834 return err;
835 }
836 return flow_cfg.data.action.i_pbits;
837 case STATE:
838 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500839 #ifdef TEST_MODE
840 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
841 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000842 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500843 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000844 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500845 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000846 return err;
847 }
848 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000849 case GROUP_ID:
850 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
851 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
852 if (err) {
853 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
854 return err;
855 }
856 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000857 default:
858 return BCM_ERR_INTERNAL;
859 }
860
861 return err;
862}
863
864Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400865 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000866 bcmolt_pon_interface_cfg interface_obj;
867 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
868 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
869 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530870 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000871
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530872 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000873 if (err == BCM_ERR_OK) {
874 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800875 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000876 return Status::OK;
877 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400878 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000879 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
880 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
881 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
882 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
883 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700884 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000885 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
886 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
887 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
888 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
889 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
890 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000891
892 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
893 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
894 if (board_technology == "GPON") {
895 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
896 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
897 }
898
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000899 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
900 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
901
902 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
903 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500904 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000905 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
906 }
907 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
908 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500909 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000910 return bcm_to_grpc_err(err, "Failed to enable PON interface");
911 }
912 else {
913 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
914 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
915 CreateDefaultSched(intf_id, downstream);
916 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400917 }
918
919 return Status::OK;
920}
921
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500922Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000923 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400924 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000925 bcmolt_device_key dev_key = { };
926 bcmolt_olt_cfg olt_cfg = { };
927 bcmolt_olt_key olt_key = { };
928 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
929 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500930
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000931 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
932 topo.topology_maps.arr = &topo_map[0];
933 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
934 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
935 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400936 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000937 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400938 #ifdef TEST_MODE
939 // It is impossible to mock the setting of olt_cfg.data.bal_state because
940 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
941 // set the olt_cfg.data.topology. So a new stub function is created and address
942 // of olt_cfg is passed. This is one-of case where we need to test add specific
943 // code in production code.
944 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
945 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000946 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400947 #endif
948 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500949 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT topology, err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000950 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500951 }
952
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000953 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
954 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500955
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400956 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
957 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000958 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500959
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000960 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
961 num_of_nni_ports,
962 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400963 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500964
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000965 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800966 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000967 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
968 dev_key.device_id = devid;
969 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
970 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
971 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
972 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000973 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400974 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500975 OPENOLT_LOG(WARNING, openolt_log_id,"Failed to query PON MAC Device %d (errno = %s). Skipping the device.\n", devid, bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000976 num_failed_cfg_gets++;
977 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000978 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500979
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000980 std::string bal_version;
981 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
982 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
983 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800984 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000985
986 switch(dev_cfg.data.system_mode) {
987 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
988 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
989 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
990 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
991 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
992 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
993 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
994 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
995 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
996 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
997 }
998
999 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001000 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1001 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001002 }
1003
Jason Huang09b73ea2020-01-08 17:52:05 +08001004 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1005 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), chip_family.c_str(), board_technology.c_str());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001006
1007 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001008 }
1009
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001010 /* If all the devices returned errors then we tell the caller that this is an error else we work with
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001011 only the devices that retured success*/
1012 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1013 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1014 return bcm_to_grpc_err(err, "device: All devices failed query");
1015 }
1016
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001017 return Status::OK;
1018}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001019
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001020Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001021 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001022 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1023 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1024 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001025
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001026 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001027 if (err == BCM_ERR_OK) {
1028 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001029 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001030 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1031 CreateDefaultSched(intf_id, upstream);
1032 CreateDefaultQueue(intf_id, upstream);
1033 return Status::OK;
1034 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1035 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1036 return Status::OK;
1037 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001038 }
1039
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001040 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1041 if (set_state) {
1042 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1043 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1044 } else {
1045 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1046 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1047 }
1048 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1049 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001050 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1051 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001052 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1053 }
1054 else {
1055 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1056 if (set_state) {
1057 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1058 CreateDefaultSched(intf_id, upstream);
1059 CreateDefaultQueue(intf_id, upstream);
1060 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001061 }
1062
1063 return Status::OK;
1064}
1065
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001066Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001067 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001068 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001069 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1070 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001071
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001072 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1073 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1074 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1075
1076 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1077 if (err != BCM_ERR_OK) {
1078 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1079 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1080 }
1081
1082 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1083 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1084
1085 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1086 if (err != BCM_ERR_OK) {
1087 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n , err %d\n", intf_id, err);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001088 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001089 }
1090
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001091 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001092 return Status::OK;
1093}
1094
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001095Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001096 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001097 bcmos_errno err = BCM_ERR_OK;
1098 bcmolt_onu_cfg onu_cfg;
1099 bcmolt_onu_key onu_key;
1100 bcmolt_serial_number serial_number; /**< ONU serial number */
1101 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001102
Girish Gowdra24297032020-03-23 12:32:37 -07001103 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1104 bcmolt_onu_state onu_state;
1105
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001106 onu_key.onu_id = onu_id;
1107 onu_key.pon_ni = intf_id;
1108 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1109 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001110#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001111 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1112 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1113 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1114 // of onu_cfg is passed. This is one-of case where we need to add test specific
1115 // code in production code.
1116 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001117#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001118 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001119#endif
1120 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1121 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001122 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001123 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1124 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1125not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001126 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001127 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1128 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1129 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1130 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1131state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1132 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1133 }
1134 } else {
1135 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1136 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1137 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001138 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001139
Girish Gowdra24297032020-03-23 12:32:37 -07001140 // If the ONU is not configured at all we need to first configure it
1141 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1142 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001143vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001144 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001145
Girish Gowdra24297032020-03-23 12:32:37 -07001146 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1147 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1148 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1149 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1150 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1151 /*set burst and data profiles to fec disabled*/
1152 if (board_technology == "XGS-PON") {
1153 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1154 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1155 } else if (board_technology == "GPON") {
1156 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1157 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1158 }
1159 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1160 if (err != BCM_ERR_OK) {
1161 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1162 return bcm_to_grpc_err(err, "Failed to configure ONU");
1163 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001164 }
Girish Gowdra24297032020-03-23 12:32:37 -07001165
1166 // Now that the ONU is configured, move the ONU to ACTIVE state
1167 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1168 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1169 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1170 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1171 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1172 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1173 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001174 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001175 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to activate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001176 return bcm_to_grpc_err(err, "Failed to activate ONU");
1177 }
Girish Gowdra24297032020-03-23 12:32:37 -07001178 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1179 // ONU_ACTIVATION_COMPLETED_INDICATION
1180
1181 OPENOLT_LOG(INFO, openolt_log_id, "Activated ONU, onu_id %d on PON %d\n", onu_id, intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001182
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001183 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001184}
1185
Jonathan Davis70c21812018-07-19 15:32:10 -04001186Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1187 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001188 bcmos_errno err = BCM_ERR_OK;
1189 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1190 bcmolt_onu_cfg onu_cfg;
1191 bcmolt_onu_key onu_key; /**< Object key. */
1192 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001193
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001194 onu_key.onu_id = onu_id;
1195 onu_key.pon_ni = intf_id;
1196 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1197 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001198 #ifdef TEST_MODE
1199 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1200 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1201 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1202 // of onu_cfg is passed. This is one-of case where we need to add test specific
1203 // code in production code.
1204 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001205 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001206 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001207 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301208 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001209 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001210 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001211 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001212 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001213 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001214 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1215 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1216 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001217 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001218 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1219 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301220 OPENOLT_LOG(INFO, openolt_log_id, "Deactivated ONU, onu_id %d on PON %d\n", onu_id, intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001221 break;
1222 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001223 }
1224
1225 return Status::OK;
1226}
1227
1228Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001229 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301230 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301231 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001232
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001233 OPENOLT_LOG(INFO, openolt_log_id, "DeleteOnu ONU %d on PON %d : vendor id %s, vendor specific %s\n",
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001234 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1235
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001236 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001237 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301238
1239 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1240 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001241 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1242 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1243 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301244 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1245 if (err) {
1246 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1247 intf_id, onu_id);
1248 return bcm_to_grpc_err(err, "Failed to delete ONU");
1249 }
1250 }
Girish Gowdra24297032020-03-23 12:32:37 -07001251 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301252 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1253 intf_id);
1254 }
1255 }
1256 else {
1257 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1258 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301259 return bcm_to_grpc_err(err, "Failed to delete ONU");
1260 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001261
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001262 bcmolt_onu_cfg cfg_obj;
1263 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001264
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001265 OPENOLT_LOG(INFO, openolt_log_id, "Processing onu cfg clear for onu_id %d and intf_id %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001266 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001267
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001268 key.onu_id = onu_id;
1269 key.pon_ni = intf_id;
1270 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001271
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301272 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001273 if (err != BCM_ERR_OK)
1274 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001275 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL onu_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Jonathan Davis70c21812018-07-19 15:32:10 -04001276 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1277 }
1278
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301279 OPENOLT_LOG(INFO, openolt_log_id, "Deleted ONU, onu_id %d on PON %d\n", onu_id, intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001280 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001281}
1282
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001283#define MAX_CHAR_LENGTH 20
1284#define MAX_OMCI_MSG_LENGTH 44
1285Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001286 bcmolt_bin_str buf = {};
1287 bcmolt_onu_cpu_packets omci_cpu_packets;
1288 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001289
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001290 key.pon_ni = intf_id;
1291 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001292
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001293 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1294 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1295 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001296
1297 // ???
1298 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1299 buf.len = MAX_OMCI_MSG_LENGTH;
1300 } else {
1301 buf.len = pkt.size()/2;
1302 }
1303
1304 /* Send the OMCI packet using the BAL remote proxy API */
1305 uint16_t idx1 = 0;
1306 uint16_t idx2 = 0;
1307 uint8_t arraySend[buf.len];
1308 char str1[MAX_CHAR_LENGTH];
1309 char str2[MAX_CHAR_LENGTH];
1310 memset(&arraySend, 0, buf.len);
1311
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001312 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1313 sprintf(str1,"%c", pkt[idx1]);
1314 sprintf(str2,"%c", pkt[++idx1]);
1315 strcat(str1,str2);
1316 arraySend[idx2] = strtol(str1, NULL, 16);
1317 }
1318
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001319 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1320 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001321
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001322 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1323 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1324 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001325
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001326 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001327 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001328 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending OMCI message to ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001329 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001330 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001331 OPENOLT_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 -05001332 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001333 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001334 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001335
1336 return Status::OK;
1337}
1338
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001339Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, uint32_t port_no, uint32_t gemport_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001340 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1341 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1342 bcmolt_bin_str buf = {};
1343 bcmolt_gem_port_id gem_port_id_array[1];
1344 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001345
Craig Lutgen967a1d02018-11-27 10:41:51 -06001346 if (port_no > 0) {
1347 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001348 if (gemport_id == 0) {
1349 bcmos_fastlock_lock(&data_lock);
1350 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1351 // Pick any flow that is mapped with the same port_no.
1352 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1353 if (it != port_to_flows.end() && !it->second.empty()) {
1354 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1355 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1356 if (fit != flowid_to_gemport.end()) {
1357 found = true;
1358 gemport_id = fit->second;
1359 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001360 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001361 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001362
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001363 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001364 OPENOLT_LOG(ERROR, openolt_log_id, "Packet out failed to find destination for ONU %d port_no %u on PON %d\n",
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001365 onu_id, port_no, intf_id);
1366 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1367 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001368 OPENOLT_LOG(INFO, openolt_log_id, "Gem port %u found for ONU %d port_no %u on PON %d\n",
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001369 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001370 }
1371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001372 gem_port_id_array[0] = gemport_id;
1373 gem_port_list.len = 1;
1374 gem_port_list.arr = gem_port_id_array;
1375 buf.len = pkt.size();
1376 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1377 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1378
1379 /* init the API struct */
1380 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1381 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1382 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1383 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1384 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1385
1386 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1387 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1388
1389 /* call API */
1390 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001391 }
1392 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001393 //TODO: Port No is 0, it is coming sender requirement.
1394 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1395 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001396 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001397 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001398
1399 return Status::OK;
1400}
1401
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001402Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001403 bcmolt_flow_key key = {}; /* declare key */
1404 bcmolt_bin_str buffer = {};
1405 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001406
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001407 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1408 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001410 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1411 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1412 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1413 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1414 key.flow_id = flow_id;
1415 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001416 if (flow_id_counters) {
1417 std::map<flow_pair, int>::iterator it;
1418 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1419 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001420 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1421 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1422 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1423 key.flow_id = flow_index;
1424 break;
1425 }
1426 }
1427 }
1428 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001429 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001430 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1431 }
1432 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001433
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001434 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001435
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001436 /* Initialize the API struct. */
1437 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001438
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001439 buffer.len = pkt.size();
1440 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1441 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1442 if (buffer.arr == NULL) {
1443 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1444 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1445 }
1446 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1447
1448 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1449 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001450 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d, err = %s\n", intf_id, key.flow_id, bcmos_strerror(err));
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001451 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001452 } else {
1453 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1454 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001455
1456 return Status::OK;
1457}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001458Status 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 +00001459 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001460 int32_t alloc_id, int32_t network_intf_id,
1461 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001462 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001463 int32_t group_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001464 bcmolt_flow_cfg cfg;
1465 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001466 int32_t o_vid = -1;
1467 bool single_tag = false;
1468 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001469 bcmolt_classifier c_val = { };
1470 bcmolt_action a_val = { };
1471 bcmolt_tm_queue_ref tm_val = { };
1472 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001473 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001474
Jason Huang09b73ea2020-01-08 17:52:05 +08001475 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1476
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001477 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001478 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001479 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001480 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001481 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001482 } else if (flow_type.compare(multicast) == 0) {
1483 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001484 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001485 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001486 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001487 }
1488
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001489 BCMOLT_CFG_INIT(&cfg, flow, key);
1490 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001491
Jason Huang09b73ea2020-01-08 17:52:05 +08001492 if (action.cmd().trap_to_host()) {
1493 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1494 network_intf_id, gemport_id, classifier);
1495 return resp;
1496 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001497
1498 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1499
1500 if (access_intf_id >= 0 && network_intf_id >= 0) {
1501 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1502 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1503 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001504 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1505 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001506 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1507 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1508 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1509 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1510 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001511 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001512 } else {
1513 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1514 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001515 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001516
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001517 if (onu_id >= 0) {
1518 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1519 }
1520 if (gemport_id >= 0) {
1521 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1522 }
1523 if (gemport_id >= 0 && port_no != 0) {
1524 bcmos_fastlock_lock(&data_lock);
1525 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1526 port_to_flows[port_no].insert(key.flow_id);
1527 flowid_to_gemport[key.flow_id] = gemport_id;
1528 }
1529 else
1530 {
1531 flowid_to_port[key.flow_id] = port_no;
1532 }
1533 bcmos_fastlock_unlock(&data_lock, 0);
1534 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001535 if (gemport_id >= 0 && access_intf_id >= 0) {
1536 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1537 // This info is needed during flow remove where we need to retrieve the gemport_id
1538 // and access_intf id for the given flow id and flow direction.
1539 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1540 // reference counters for those ACL ID and GEMPORT ID.
1541 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1542 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1543 bcmos_fastlock_lock(&data_lock);
1544 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1545 bcmos_fastlock_unlock(&data_lock, 0);
1546 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001547 if (priority_value >= 0) {
1548 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1549 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301550
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001551 } else { // MULTICAST FLOW
1552 if (group_id >= 0) {
1553 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001554 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001555 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1556 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001557 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001558
1559 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001560 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001561 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001562 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1563 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001564 }
1565
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001566 if (classifier.dst_mac().size() > 0) {
1567 bcmos_mac_address d_mac = {};
1568 bcmos_mac_address_init(&d_mac);
1569 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1570 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1571 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1572 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001573 }
1574
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001575 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001576 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001577 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001578 }
1579 */
1580
1581 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001582 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1583 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001584 }
1585
1586 /*
1587 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001588 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001589 }
1590
1591 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001592 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001593 }
1594 */
1595
1596 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001597 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1598 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001599 }
1600
1601 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001602 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1603 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001604 }
1605
1606 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001607 if (classifier.o_vid()) {
1608 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1609 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1610 }
1611
1612 if (classifier.i_vid()) {
1613 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1614 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1615 }
1616
1617 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1618 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1619 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1620 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1621 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1622 single_tag = true;
1623
1624 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301625 // OpenOlt adapter will send 0xFF in case of no pbit classification
1626 // If it is any other value (0 to 7), it is for outer pbit classification.
1627 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1628 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1629 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1630 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001631 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301632 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001633 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1634 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001635
Jason Huang09b73ea2020-01-08 17:52:05 +08001636 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301637 // Same comments as in case of "single_tag" packets.
1638 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1639 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001640 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301641 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001642 }
1643 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001644 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001645 }
1646
Jason Huang09b73ea2020-01-08 17:52:05 +08001647 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001648
Jason Huang09b73ea2020-01-08 17:52:05 +08001649 if (cmd.add_outer_tag()) {
1650 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1651 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001652 }
1653
Jason Huang09b73ea2020-01-08 17:52:05 +08001654 if (cmd.remove_outer_tag()) {
1655 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1656 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1657 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301658
Jason Huang09b73ea2020-01-08 17:52:05 +08001659 if (action.o_vid()) {
1660 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1661 o_vid = action.o_vid();
1662 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1663 }
1664
1665 if (action.o_pbits()) {
1666 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1667 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1668 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301669
Jason Huang09b73ea2020-01-08 17:52:05 +08001670 if (action.i_vid()) {
1671 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1672 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1673 }
1674
1675 if (action.i_pbits()) {
1676 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1677 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1678 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301679
Jason Huang09b73ea2020-01-08 17:52:05 +08001680 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1681
Shad Ansari39739bc2018-09-13 21:38:37 +00001682 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001683 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1684 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001685 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream, tech_profile_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001686
Jason Huang09b73ea2020-01-08 17:52:05 +08001687 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1688 // Queue 0 on DS subscriber scheduler
1689 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001690
Jason Huang09b73ea2020-01-08 17:52:05 +08001691 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1692 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1693 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001694
Jason Huang09b73ea2020-01-08 17:52:05 +08001695 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1696 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1697 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001698
Jason Huang09b73ea2020-01-08 17:52:05 +08001699 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1700 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1701 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001702
Jason Huang09b73ea2020-01-08 17:52:05 +08001703 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1704 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1705 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1706 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001707
Jason Huang09b73ea2020-01-08 17:52:05 +08001708 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1709 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1710 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1711 }
1712 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1713 // NNI Scheduler ID
1714 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1715 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1716 // Queue 0 on NNI scheduler
1717 tm_val.queue_id = 0;
1718 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1719 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1720 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001721
Jason Huang09b73ea2020-01-08 17:52:05 +08001722 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001723 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1724 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1725
Jason Huang09b73ea2020-01-08 17:52:05 +08001726 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1727 /* Fetch TM QMP ID mapped to US NNI scheduler */
1728 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1729 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1730 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1731 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1732 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001733
Jason Huang09b73ea2020-01-08 17:52:05 +08001734 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001735 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1736 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001737 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001738 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301739 } else {
1740 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1741 tm_val.queue_id = 0;
1742
1743 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1744 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1745 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1746
1747 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1748 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1749 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001750 }
1751
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001752 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001753
1754 // BAL 3.1 supports statistics only for unicast flows.
1755 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1756 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1757 }
1758
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001759#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001760 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001761 if (flow_id_counters != 0) {
1762 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001763 std::map<flow_pair, int>::iterator it;
1764
1765 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1766 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1767 (key.flow_type == it->first.second) && \
1768 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1769 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1770 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1771 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1772 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1773 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1774 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1775 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1776 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1777 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1778 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1779 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1780 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1781 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1782 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1783 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1784 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1785 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1786 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1787 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1788 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1789 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1790 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1791 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1792 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1793 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001794#ifdef SHOW_FLOW_PARAM
1795 // Flow Parameter
1796 FLOW_PARAM_LOG();
1797#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001798 if (b_duplicate_flow) {
1799 FLOW_LOG(WARNING, "Flow duplicate", 0);
1800 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1801 }
1802 }
1803 }
1804#endif
1805
1806 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1807 if (err) {
1808 FLOW_LOG(ERROR, "Flow add failed", err);
1809 return bcm_to_grpc_err(err, "flow add failed");
1810 } else {
1811 FLOW_LOG(INFO, "Flow add ok", err);
1812 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001813 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1814 flow_id_counters = flow_map.size();
1815 if (gemport_id > 0 && access_intf_id >= 0) {
1816 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1817 if (gem_ref_cnt.count(gem_intf) > 0) {
1818 // The gem port is already installed
1819 // Increment the ref counter indicating number of flows referencing this gem port
1820 gem_ref_cnt[gem_intf]++;
1821 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1822 } else {
1823 // Initialize the refence count for the gemport.
1824 gem_ref_cnt[gem_intf] = 1;
1825 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1826 }
1827 } else {
1828 OPENOLT_LOG(DEBUG, openolt_log_id, "not incrementing gem_ref_cnt flow_id=%d gemport_id=%d access_intf_id=%d\n", flow_id, gemport_id, access_intf_id);
1829 }
1830
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001831 bcmos_fastlock_unlock(&data_lock, 0);
1832 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001833
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001834 return Status::OK;
1835}
1836
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001837Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1838
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001839 bcmolt_flow_cfg cfg;
1840 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001841
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001842 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001843 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001844 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001845 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001846 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001847 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001848 } else if(flow_type.compare(multicast) == 0) {
1849 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001850 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001851 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001852 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1853 }
1854
Jason Huang09b73ea2020-01-08 17:52:05 +08001855 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1856 flow_id, flow_type.c_str());
1857
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001858 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001859 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1860 int32_t gemport_id = -1;
1861 int32_t intf_id = -1;
1862 int16_t acl_id = -1;
1863 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1864 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1865 acl_id = std::get<0>(ac_id_gm_id_if_id);
1866 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1867 intf_id = std::get<2>(ac_id_gm_id_if_id);
1868 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1869 if (acl_id >= 0) {
1870 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1871 bcmos_fastlock_unlock(&data_lock, 0);
1872 if (resp.ok()) {
1873 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1874 flow_to_acl_map.erase(fl_id_fl_dir);
1875 } else {
1876 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1877 }
1878 return resp;
1879 }
1880 }
1881
Craig Lutgen967a1d02018-11-27 10:41:51 -06001882 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001883 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001884 flowid_to_gemport.erase(key.flow_id);
1885 port_to_flows[port_no].erase(key.flow_id);
1886 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1887 }
1888 else
1889 {
1890 flowid_to_port.erase(key.flow_id);
1891 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001892 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001893
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001894 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001895
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001896 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001897 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001898 OPENOLT_LOG(ERROR, openolt_log_id, "Error while removing %s flow, flow_id=%d, err = %s\n", flow_type.c_str(), flow_id, bcmos_strerror(err));
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001899 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1900 }
1901
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001902 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001903 if (flow_id_counters != 0) {
1904 std::map<flow_pair, int>::iterator it;
1905 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1906 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1907 flow_id_counters -= 1;
1908 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001909 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001910 }
1911 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001912 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1913
1914 clear_gem_port(gemport_id, intf_id);
1915
1916 flow_to_acl_map.erase(fl_id_fl_dir);
1917
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001918 bcmos_fastlock_unlock(&data_lock, 0);
1919
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001920 return Status::OK;
1921}
1922
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001923bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1924 bcmos_errno err;
1925 bcmolt_tm_sched_cfg tm_sched_cfg;
1926 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1927 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1928
Jason Huangbf45ffb2019-10-30 17:29:02 +08001929 //check TM scheduler has configured or not
1930 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1931 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001932 #ifdef TEST_MODE
1933 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1934 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1935 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1936 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1937 // code in production code.
1938 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1939 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001940 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001941 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001942 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001943 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler, err = %s\n",bcmos_strerror(err));
Jason Huangbf45ffb2019-10-30 17:29:02 +08001944 return err;
1945 }
1946 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1947 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1948 return BCM_ERR_OK;
1949 }
1950
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001951 // bcmbal_tm_sched_owner
1952 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1953
1954 /**< The output of the tm_sched object instance */
1955 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1956
1957 if (direction.compare(upstream) == 0) {
1958 // In upstream it is NNI scheduler
1959 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1960 } else if (direction.compare(downstream) == 0) {
1961 // In downstream it is PON scheduler
1962 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1963 }
1964
1965 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1966
1967 // bcmbal_tm_sched_type
1968 // set the deafult policy to strict priority
1969 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1970
1971 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001972 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001973
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1975 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001976 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1977 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001978 return err;
1979 }
1980
1981 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1982 direction.c_str(), tm_sched_key.id, intf_id);
1983 return BCM_ERR_OK;
1984}
1985
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001986bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
1987 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001988 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info,
1989 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001990
1991 bcmos_errno err;
1992
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001993 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001994 bcmolt_tm_sched_cfg tm_sched_cfg;
1995 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001996 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001997
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001998 // bcmbal_tm_sched_owner
1999 // In downstream it is sub_term scheduler
2000 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002001
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002002 /**< The output of the tm_sched object instance */
2003 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002004
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002005 // bcmbal_tm_sched_parent
2006 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2007 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2008 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002009 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002010 be achieved using the' virtual' type of attachment.
2011 tm_sched_owner.u.sub_term.intf_id = intf_id;
2012 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2013 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002014
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002015 // bcmbal_tm_sched_type
2016 // set the deafult policy to strict priority
2017 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002018
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002019 // num_priorities: Max number of strict priority scheduling elements
2020 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002021
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002022 // bcmbal_tm_shaping
2023 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2024 uint32_t cir = tf_sh_info.cir();
2025 uint32_t pir = tf_sh_info.pir();
2026 uint32_t burst = tf_sh_info.pbs();
2027 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2028 cir, pir, burst);
2029 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2030 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2031 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2032 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2033 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2034 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002035 }
2036
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002037 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002038 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002039 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002040intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2041port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002042 return err;
2043 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002044 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2045uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002046
2047 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002048 bcmolt_itupon_alloc_cfg cfg;
2049 bcmolt_itupon_alloc_key key = { };
2050 key.pon_ni = intf_id;
2051 key.alloc_id = alloc_id;
2052 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002053 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2054 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002055 //offset to match bandwidth granularity
2056 int offset_pir_bw = pir_bw%bw_granularity;
2057 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002058
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002059 pir_bw = pir_bw - offset_pir_bw;
2060 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002061
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002062 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002063
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002064 switch (additional_bw) {
2065 case 2: //AdditionalBW_BestEffort
2066 if (pir_bw == 0) {
2067 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2068%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002069 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002070 } else if (pir_bw < cir_bw) {
2071 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2072bandwidth (%d)\n", pir_bw, cir_bw);
2073 return BCM_ERR_PARM;
2074 } else if (pir_bw == cir_bw) {
2075 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2076bandwidth for additional bandwidth eligibility of type best_effort\n");
2077 return BCM_ERR_PARM;
2078 }
2079 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2080 break;
2081 case 1: //AdditionalBW_NA
2082 if (pir_bw == 0) {
2083 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2084%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2085 return BCM_ERR_PARM;
2086 } else if (cir_bw == 0) {
2087 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2088additional bandwidth eligibility of type Non-Assured (NA)\n");
2089 return BCM_ERR_PARM;
2090 } else if (pir_bw < cir_bw) {
2091 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2092bandwidth (%d)\n", pir_bw, cir_bw);
2093 return BCM_ERR_PARM;
2094 } else if (pir_bw == cir_bw) {
2095 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2096bandwidth for additional bandwidth eligibility of type non_assured\n");
2097 return BCM_ERR_PARM;
2098 }
2099 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2100 break;
2101 case 0: //AdditionalBW_None
2102 if (pir_bw == 0) {
2103 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
210416000 bytes/sec\n");
2105 return BCM_ERR_PARM;
2106 } else if (cir_bw == 0) {
2107 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2108for additional bandwidth eligibility of type None\n");
2109 return BCM_ERR_PARM;
2110 } else if (pir_bw > cir_bw) {
2111 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2112for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002113 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002114bandwidth in None eligibility\n", pir_bw);
2115 cir_bw = pir_bw;
2116 } else if (pir_bw < cir_bw) {
2117 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2118bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002119 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002120bandwidth in None eligibility\n", pir_bw);
2121 cir_bw = pir_bw;
2122 }
2123 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2124 break;
2125 default:
2126 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002127 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002128 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2129 in a fine granularity. */
2130 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2131 /* Fixed Bandwidth with no critical requirement of shaping */
2132 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2133 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2134 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2135 /* Maximum allocated bandwidth allowed for this alloc ID */
2136 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2137 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002138 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002139 for skipped allocations during quiet window */
2140 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2141 /**< Allocation Profile index for CBR non-RT Bandwidth */
2142 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2143 /**< Allocation Profile index for CBR RT Bandwidth */
2144 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2145 /**< Alloc ID Weight used in case of Extended DBA mode */
2146 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2147 /**< Alloc ID Priority used in case of Extended DBA mode */
2148 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2149 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002150
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002151 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002152 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002153 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002154port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002155 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002156 }
Girish Gowdra96461052019-11-22 20:13:59 +05302157
2158 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2159 if (err) {
2160 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2161port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2162 return err;
2163 }
2164
2165 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2166port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2167
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002168 }
2169
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002170 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002171}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002172
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002173Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2174 uint32_t intf_id = traffic_scheds->intf_id();
2175 uint32_t onu_id = traffic_scheds->onu_id();
2176 uint32_t uni_id = traffic_scheds->uni_id();
2177 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002178 std::string direction;
2179 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002180 tech_profile::SchedulerConfig sched_config;
2181 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002182 uint32_t priority;
2183 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002184 tech_profile::SchedulingPolicy sched_policy;
2185 tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002186 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002187 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002188
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002189 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2190 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002191
2192 direction = GetDirection(traffic_sched.direction());
2193 if (direction.compare("direction-not-supported") == 0)
2194 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2195
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002196 alloc_id = traffic_sched.alloc_id();
2197 sched_config = traffic_sched.scheduler();
2198 additional_bw = sched_config.additional_bw();
2199 priority = sched_config.priority();
2200 weight = sched_config.weight();
2201 sched_policy = sched_config.sched_policy();
2202 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002203 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002204 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002205 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002206 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002207 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002208 return bcm_to_grpc_err(err, "Failed to create scheduler");
2209 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002210 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002211 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002212}
Jonathan Davis70c21812018-07-19 15:32:10 -04002213
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002214bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction, int tech_profile_id) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002215
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002216 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302217 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302218 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302219 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002220
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002221 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002222 bcmolt_itupon_alloc_cfg cfg;
2223 bcmolt_itupon_alloc_key key = { };
2224 key.pon_ni = intf_id;
2225 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302226 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002227
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002228 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002229 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2230 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002231 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2232 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002233 return err;
2234 }
Girish Gowdra96461052019-11-22 20:13:59 +05302235
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302236 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302237 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302238 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
2239 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled and LoS status is OFF, waiting for alloc cfg clear response\n",
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302240 intf_id);
2241 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2242 if (err) {
2243 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2244 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2245 return err;
2246 }
2247 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302248 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2249 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2250 intf_id);
2251 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302252 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2253 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2254 intf_id);
2255 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302256 } else {
2257 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface status, intf_id = %d, err = %s\n",
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302258 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302259 return err;
2260 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002261 } else if (direction == downstream) {
2262 bcmolt_tm_sched_cfg cfg;
2263 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002264
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002265 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2266 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302267 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002268 } else {
2269 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2270 return BCM_ERR_OK;
2271 }
Girish Gowdra96461052019-11-22 20:13:59 +05302272
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002273 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2274 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2275 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002276 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002277intf_id %d, onu_id %d, tech_profile_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, tech_profile_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002278 return err;
2279 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002280 }
2281
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002282 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2283 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2284 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002285 return BCM_ERR_OK;
2286}
2287
2288Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2289 uint32_t intf_id = traffic_scheds->intf_id();
2290 uint32_t onu_id = traffic_scheds->onu_id();
2291 uint32_t uni_id = traffic_scheds->uni_id();
2292 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002293 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002294 bcmos_errno err;
2295
2296 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2297 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002298
2299 direction = GetDirection(traffic_sched.direction());
2300 if (direction.compare("direction-not-supported") == 0)
2301 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2302
2303 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002304 int tech_profile_id = traffic_sched.tech_profile_id();
2305 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002306 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002307 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002308 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2309 }
2310 }
2311 return Status::OK;
2312}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002313
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002314bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2315 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002316 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002317 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2318 bcmolt_tm_qmp_key tm_qmp_key;
2319 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002321 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2322 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002323 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2324 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002325 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002326
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002327 tm_qmp_key.id = tm_qmp_id;
2328 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2329 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2330 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002331
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002332 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2333 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2334 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002335 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2336 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002337
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002338 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002339 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002340 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2341 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002342 return err;
2343 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002344
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002345 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2346 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002347 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002348}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002349
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002350bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2351 bcmos_errno err;
2352 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2353 bcmolt_tm_qmp_key tm_qmp_key;
2354 tm_qmp_key.id = tm_qmp_id;
2355
2356 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2357 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2358 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002359 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2360 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002361 return err;
2362 }
2363
2364 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2365 tm_qmp_key.id);
2366 return BCM_ERR_OK;
2367}
2368
2369bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2370 bcmos_errno err;
2371
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002372 /* Create default queues on the given PON/NNI scheduler */
2373 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002374 bcmolt_tm_queue_cfg tm_queue_cfg;
2375 bcmolt_tm_queue_key tm_queue_key = {};
2376 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2377 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002378 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2379 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2380 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002381
2382 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2383 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2384 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2385
2386 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2387 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002388 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d, err = %s\n", \
2389 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002390 return err;
2391 }
2392
2393 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2394 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2395 }
2396 return BCM_ERR_OK;
2397}
2398
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002399bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002400 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002401 bcmos_errno err;
2402 bcmolt_tm_queue_cfg cfg;
2403 bcmolt_tm_queue_key key = { };
2404 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002405gemport_id = %d, tech_profile_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406
2407 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002408 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002409
2410 if (priority > 7) {
2411 return BCM_ERR_RANGE;
2412 }
2413
2414 /* FIXME: The upstream queues have to be created once only.
2415 The upstream queues on the NNI scheduler are shared by all subscribers.
2416 When the first scheduler comes in, the queues get created, and are re-used by all others.
2417 Also, these queues should be present until the last subscriber exits the system.
2418 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2419
2420 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2421 for each GEM in TECH PROFILE */
2422 key.id = queue_id_list[priority];
2423
2424 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2425 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2426 key.id = 0;
2427 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2428 }
2429 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2430 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2431 }
2432 else {
2433 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2434 }
2435
2436 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2437
2438 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2439 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2440
2441 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2442 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002443 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002444sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2445 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, tech_profile_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002446 return err;
2447 }
2448
2449 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002450intf_id %d, onu_id %d, uni_id %d, tech_profiled_id %d\n", direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002451 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002452}
2453
2454Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2455 uint32_t intf_id = traffic_queues->intf_id();
2456 uint32_t onu_id = traffic_queues->onu_id();
2457 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002458 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002459 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002460 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002461 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002462 bcmolt_egress_qos_type qos_type = get_qos_type(intf_id, onu_id, uni_id, traffic_queues->traffic_queues_size());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002463
2464 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2465 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2466 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2467 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2468 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2469
2470 direction = GetDirection(traffic_queue.direction());
2471 if (direction.compare("direction-not-supported") == 0)
2472 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2473
2474 queues_priority_q[i] = traffic_queue.priority();
2475 queues_pbit_map[i] = traffic_queue.pbit_map();
2476 }
2477
2478 std::vector<uint32_t> tmq_map_profile(8, 0);
2479 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2480 queues_priority_q, COUNT_OF(queues_priority_q));
2481 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002482 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002483
2484 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2485 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002486 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2487 if (err != BCM_ERR_OK) {
2488 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2489 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2490 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002491 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2492 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2493 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2494 }
2495 }
2496
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002497 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2498 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002499
2500 direction = GetDirection(traffic_queue.direction());
2501 if (direction.compare("direction-not-supported") == 0)
2502 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2503
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002504 err = CreateQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id(), tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002505
Girish Gowdruf26cf882019-05-01 23:47:58 -07002506 // If the queue exists already, lets not return failure and break the loop.
2507 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002508 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002509 return bcm_to_grpc_err(err, "Failed to create queue");
2510 }
2511 }
2512 return Status::OK;
2513}
2514
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002515bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002516 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002517 bcmolt_tm_queue_cfg cfg;
2518 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002519 bcmos_errno err;
2520
2521 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002522 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2523 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002524 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002525 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002526 OPENOLT_LOG(INFO, openolt_log_id, "queue not present in DS. Not clearing, access_intf_id %d, onu_id %d, uni_id %d, gemport_id %d, direction %s\n", access_intf_id, onu_id, uni_id, gemport_id, direction.c_str());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002527 return BCM_ERR_OK;
2528 }
2529 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002530 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2531 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002532 return BCM_ERR_OK;
2533 }
2534
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002535 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2536 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2537 // Reset the queue id to 0 when using fixed queue.
2538 key.id = 0;
2539 }
2540 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2541 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2542 }
2543 else {
2544 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2545 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002546
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002547 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2548 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002549 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002550 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2551tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2552 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002553 return err;
2554 }
2555
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002556 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2557intf_id %d, onu_id %d, uni_id %d\n", direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002558
2559 return BCM_ERR_OK;
2560}
2561
2562Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2563 uint32_t intf_id = traffic_queues->intf_id();
2564 uint32_t onu_id = traffic_queues->onu_id();
2565 uint32_t uni_id = traffic_queues->uni_id();
2566 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002567 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002568 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002569 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002570 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002571 bcmolt_egress_qos_type qos_type = get_qos_type(intf_id, onu_id, uni_id, traffic_queues->traffic_queues_size());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002572
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002573 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2574 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002575
2576 direction = GetDirection(traffic_queue.direction());
2577 if (direction.compare("direction-not-supported") == 0)
2578 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2579
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002580 err = RemoveQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id(), tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002581 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002582 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002583 return bcm_to_grpc_err(err, "Failed to remove queue");
2584 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002585 }
2586
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002587 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE && (direction.compare(upstream) == 0 || direction.compare(downstream) == 0 && is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id))) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002588 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002589 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002590
2591 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2592 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002593 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2594 if (err != BCM_ERR_OK) {
2595 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2596 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2597 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002598 }
2599 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002600 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002601 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002602}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002603
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002604Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2605
2606 bcmos_errno err;
2607 bcmolt_group_key key = {};
2608 bcmolt_group_cfg grp_cfg_obj;
2609 bcmolt_group_members_update grp_mem_upd;
2610 bcmolt_members_update_command grp_mem_upd_cmd;
2611 bcmolt_group_member_info member_info = {};
2612 bcmolt_group_member_info_list_u8 members = {};
2613 bcmolt_intf_ref interface_ref = {};
2614 bcmolt_egress_qos egress_qos = {};
2615 bcmolt_tm_sched_ref tm_sched_ref = {};
2616 bcmolt_action a_val = {};
2617
2618 uint32_t group_id = group_cfg->group_id();
2619
2620 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2621
2622 if (group_id >= 0) {
2623 key.id = group_id;
2624 }
2625 else {
2626 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2627 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2628 }
2629
2630 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2631 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2632
2633 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2634
2635 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2636 if (err != BCM_ERR_OK) {
2637 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2638 return bcm_to_grpc_err(err, "Error in querying group");
2639 }
2640
2641 members.len = group_cfg->members_size();
2642
2643 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2644 // Group type is determined after a flow is assigned to it.
2645 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2646 // Only then we can add members to the group.
2647
2648 // if group does not exist, create it and return.
2649 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2650
2651 if (members.len != 0) {
2652 OPENOLT_LOG(ERROR, openolt_log_id, "Member list is not empty for non-existent Group %d. Members can be added only after a flow is assigned to this newly-created group.\n", group_id);
2653 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2654 } else {
2655
2656 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2657 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2658
2659 /* Setting group actions and action parameters, if any.
2660 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2661 are supported for multicast groups in BAL 3.1.
2662 */
2663 const ::openolt::Action& action = group_cfg->action();
2664 const ::openolt::ActionCmd &cmd = action.cmd();
2665
2666 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2667 if (cmd.remove_outer_tag()) {
2668 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2669 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2670 }
2671
2672 if (cmd.translate_inner_tag()) {
2673 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2674 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2675 }
2676
2677 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2678
2679 if (action.i_vid()) {
2680 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2681 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2682 }
2683
2684 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2685
2686 // Create group
2687 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2688
2689 if (BCM_ERR_OK != err) {
2690 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2691 return bcm_to_grpc_err(err, "Error in creating group");
2692 }
2693
2694 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2695 return Status::OK;
2696 }
2697 }
2698
2699 // The group already exists. Continue configuring it according to the update member command.
2700
2701 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2702
2703 // MEMBER LIST CONSTRUCTION
2704 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2705 // empty list to the group is a legit operation and this actually empties the member list.
2706 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2707
2708 if (!members.arr) {
2709 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2710 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2711 }
2712
2713 /* SET GROUP MEMBERS UPDATE COMMAND */
2714 openolt::Group::GroupMembersCommand command = group_cfg->command();
2715 switch(command) {
2716 case openolt::Group::SET_MEMBERS :
2717 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2718 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2719 break;
2720 case openolt::Group::ADD_MEMBERS :
2721 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2722 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2723 break;
2724 case openolt::Group::REMOVE_MEMBERS :
2725 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2726 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2727 break;
2728 default :
2729 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2730 bcmos_free(members.arr);
2731 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2732 }
2733
2734 // SET MEMBERS LIST
2735 for (int i = 0; i < members.len; i++) {
2736
2737 if (command == openolt::Group::REMOVE_MEMBERS) {
2738 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2739 } else {
2740 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2741 }
2742
2743 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2744
2745 // Set member interface type
2746 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2747 switch(if_type){
2748 case openolt::GroupMember::PON :
2749 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2750 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2751 break;
2752 case openolt::GroupMember::EPON_1G_PATH :
2753 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2754 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2755 break;
2756 case openolt::GroupMember::EPON_10G_PATH :
2757 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2758 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2759 break;
2760 default :
2761 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2762 bcmos_free(members.arr);
2763 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2764 }
2765
2766 // Set member interface id
2767 if (member->interface_id() >= 0) {
2768 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2769 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2770 } else {
2771 bcmos_free(members.arr);
2772 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2773 }
2774
2775 // Set member interface_ref
2776 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2777
2778 // Set member gem_port_id. This must be a multicast gemport.
2779 if (member->gem_port_id() >= 0) {
2780 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2781 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2782 } else {
2783 bcmos_free(members.arr);
2784 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2785 }
2786
2787 // Set member scheduler id and queue_id
2788 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2789 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2790 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2791 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2792
2793 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2794 uint32_t tm_queue_id;
2795 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2796 tm_queue_id = queue_id_list[member->priority()];
2797 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2798 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2799 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2800 } else {
2801 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2802 bcmos_free(members.arr);
2803 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2804 }
2805
2806 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2807 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2808 }
2809
2810 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2811 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2812 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2813
2814 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2815 bcmos_free(members.arr);
2816
2817 if (BCM_ERR_OK != err) {
2818 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to submit members update operation for Group %d err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2819 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2820 }
2821
2822 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2823
2824 return Status::OK;
2825}