blob: 54f7e0deeacd1b3f5595d452e2eec258a8d37eb6 [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);
891 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
892 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
893
894 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
895 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500896 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 +0000897 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
898 }
899 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
900 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500901 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 +0000902 return bcm_to_grpc_err(err, "Failed to enable PON interface");
903 }
904 else {
905 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
906 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
907 CreateDefaultSched(intf_id, downstream);
908 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400909 }
910
911 return Status::OK;
912}
913
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500914Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000915 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400916 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000917 bcmolt_device_key dev_key = { };
918 bcmolt_olt_cfg olt_cfg = { };
919 bcmolt_olt_key olt_key = { };
920 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
921 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500922
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000923 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
924 topo.topology_maps.arr = &topo_map[0];
925 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
926 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
927 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400928 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000929 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400930 #ifdef TEST_MODE
931 // It is impossible to mock the setting of olt_cfg.data.bal_state because
932 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
933 // set the olt_cfg.data.topology. So a new stub function is created and address
934 // of olt_cfg is passed. This is one-of case where we need to test add specific
935 // code in production code.
936 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
937 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000938 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400939 #endif
940 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500941 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 +0000942 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500943 }
944
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000945 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
946 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500947
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400948 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
949 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000950 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500951
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000952 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
953 num_of_nni_ports,
954 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400955 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500956
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000957 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800958 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000959 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
960 dev_key.device_id = devid;
961 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
962 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
963 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
964 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000965 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400966 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500967 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 +0000968 num_failed_cfg_gets++;
969 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000970 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500971
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000972 std::string bal_version;
973 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
974 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
975 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800976 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000977
978 switch(dev_cfg.data.system_mode) {
979 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
980 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
981 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
982 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
983 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
984 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
985 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
986 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
987 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
988 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
989 }
990
991 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800992 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
993 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000994 }
995
Jason Huang09b73ea2020-01-08 17:52:05 +0800996 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
997 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 +0000998
999 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001000 }
1001
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001002 /* 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 +00001003 only the devices that retured success*/
1004 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1005 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1006 return bcm_to_grpc_err(err, "device: All devices failed query");
1007 }
1008
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001009 return Status::OK;
1010}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001011
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001012Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001013 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001014 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1015 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1016 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001017
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001018 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001019 if (err == BCM_ERR_OK) {
1020 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001021 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001022 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1023 CreateDefaultSched(intf_id, upstream);
1024 CreateDefaultQueue(intf_id, upstream);
1025 return Status::OK;
1026 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1027 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1028 return Status::OK;
1029 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001030 }
1031
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001032 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1033 if (set_state) {
1034 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1035 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1036 } else {
1037 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1038 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1039 }
1040 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1041 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001042 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1043 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001044 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1045 }
1046 else {
1047 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1048 if (set_state) {
1049 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1050 CreateDefaultSched(intf_id, upstream);
1051 CreateDefaultQueue(intf_id, upstream);
1052 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001053 }
1054
1055 return Status::OK;
1056}
1057
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001058Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001059 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001060 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001061 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1062 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001063
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001064 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1065 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1066 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1067
1068 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1069 if (err != BCM_ERR_OK) {
1070 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1071 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1072 }
1073
1074 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1075 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1076
1077 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1078 if (err != BCM_ERR_OK) {
1079 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 -04001080 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001081 }
1082
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001083 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001084 return Status::OK;
1085}
1086
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001087Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001088 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001089 bcmos_errno err = BCM_ERR_OK;
1090 bcmolt_onu_cfg onu_cfg;
1091 bcmolt_onu_key onu_key;
1092 bcmolt_serial_number serial_number; /**< ONU serial number */
1093 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001094
Girish Gowdra24297032020-03-23 12:32:37 -07001095 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1096 bcmolt_onu_state onu_state;
1097
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001098 onu_key.onu_id = onu_id;
1099 onu_key.pon_ni = intf_id;
1100 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1101 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001102#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001103 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1104 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1105 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1106 // of onu_cfg is passed. This is one-of case where we need to add test specific
1107 // code in production code.
1108 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001109#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001110 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001111#endif
1112 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1113 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001114 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001115 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1116 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1117not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001118 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001119 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1120 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1121 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1122 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1123state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1124 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1125 }
1126 } else {
1127 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1128 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1129 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001130 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001131
Girish Gowdra24297032020-03-23 12:32:37 -07001132 // If the ONU is not configured at all we need to first configure it
1133 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1134 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001135vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001136 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001137
Girish Gowdra24297032020-03-23 12:32:37 -07001138 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1139 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1140 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1141 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1142 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1143 /*set burst and data profiles to fec disabled*/
1144 if (board_technology == "XGS-PON") {
1145 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1146 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1147 } else if (board_technology == "GPON") {
1148 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1149 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1150 }
1151 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1152 if (err != BCM_ERR_OK) {
1153 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1154 return bcm_to_grpc_err(err, "Failed to configure ONU");
1155 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001156 }
Girish Gowdra24297032020-03-23 12:32:37 -07001157
1158 // Now that the ONU is configured, move the ONU to ACTIVE state
1159 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1160 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1161 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1162 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1163 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1164 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1165 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001166 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001167 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 +00001168 return bcm_to_grpc_err(err, "Failed to activate ONU");
1169 }
Girish Gowdra24297032020-03-23 12:32:37 -07001170 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1171 // ONU_ACTIVATION_COMPLETED_INDICATION
1172
1173 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 +00001174
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001175 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001176}
1177
Jonathan Davis70c21812018-07-19 15:32:10 -04001178Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1179 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001180 bcmos_errno err = BCM_ERR_OK;
1181 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1182 bcmolt_onu_cfg onu_cfg;
1183 bcmolt_onu_key onu_key; /**< Object key. */
1184 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001185
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001186 onu_key.onu_id = onu_id;
1187 onu_key.pon_ni = intf_id;
1188 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1189 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001190 #ifdef TEST_MODE
1191 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1192 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1193 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1194 // of onu_cfg is passed. This is one-of case where we need to add test specific
1195 // code in production code.
1196 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001197 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001198 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001199 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301200 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001201 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001202 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001203 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001204 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001205 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001206 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1207 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1208 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001209 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 +00001210 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1211 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301212 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 +00001213 break;
1214 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001215 }
1216
1217 return Status::OK;
1218}
1219
1220Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001221 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301222 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301223 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001224
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001225 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 -05001226 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1227
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001228 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001229 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301230
1231 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1232 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001233 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1234 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1235 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301236 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1237 if (err) {
1238 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1239 intf_id, onu_id);
1240 return bcm_to_grpc_err(err, "Failed to delete ONU");
1241 }
1242 }
Girish Gowdra24297032020-03-23 12:32:37 -07001243 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301244 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1245 intf_id);
1246 }
1247 }
1248 else {
1249 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1250 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301251 return bcm_to_grpc_err(err, "Failed to delete ONU");
1252 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001253
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001254 bcmolt_onu_cfg cfg_obj;
1255 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001256
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001257 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 -04001258 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001259
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001260 key.onu_id = onu_id;
1261 key.pon_ni = intf_id;
1262 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001263
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301264 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001265 if (err != BCM_ERR_OK)
1266 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001267 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 -04001268 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1269 }
1270
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301271 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 +00001272 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001273}
1274
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001275#define MAX_CHAR_LENGTH 20
1276#define MAX_OMCI_MSG_LENGTH 44
1277Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001278 bcmolt_bin_str buf = {};
1279 bcmolt_onu_cpu_packets omci_cpu_packets;
1280 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001281
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001282 key.pon_ni = intf_id;
1283 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001284
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001285 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1286 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1287 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001288
1289 // ???
1290 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1291 buf.len = MAX_OMCI_MSG_LENGTH;
1292 } else {
1293 buf.len = pkt.size()/2;
1294 }
1295
1296 /* Send the OMCI packet using the BAL remote proxy API */
1297 uint16_t idx1 = 0;
1298 uint16_t idx2 = 0;
1299 uint8_t arraySend[buf.len];
1300 char str1[MAX_CHAR_LENGTH];
1301 char str2[MAX_CHAR_LENGTH];
1302 memset(&arraySend, 0, buf.len);
1303
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001304 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1305 sprintf(str1,"%c", pkt[idx1]);
1306 sprintf(str2,"%c", pkt[++idx1]);
1307 strcat(str1,str2);
1308 arraySend[idx2] = strtol(str1, NULL, 16);
1309 }
1310
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001311 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1312 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001313
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001314 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1315 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1316 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001317
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001318 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001319 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001320 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 +00001321 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001322 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001323 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 -05001324 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001325 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001326 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001327
1328 return Status::OK;
1329}
1330
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001331Status 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 +00001332 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1333 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1334 bcmolt_bin_str buf = {};
1335 bcmolt_gem_port_id gem_port_id_array[1];
1336 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001337
Craig Lutgen967a1d02018-11-27 10:41:51 -06001338 if (port_no > 0) {
1339 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001340 if (gemport_id == 0) {
1341 bcmos_fastlock_lock(&data_lock);
1342 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1343 // Pick any flow that is mapped with the same port_no.
1344 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1345 if (it != port_to_flows.end() && !it->second.empty()) {
1346 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1347 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1348 if (fit != flowid_to_gemport.end()) {
1349 found = true;
1350 gemport_id = fit->second;
1351 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001352 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001353 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001354
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001355 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001356 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 -08001357 onu_id, port_no, intf_id);
1358 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1359 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001360 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 -08001361 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001362 }
1363
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001364 gem_port_id_array[0] = gemport_id;
1365 gem_port_list.len = 1;
1366 gem_port_list.arr = gem_port_id_array;
1367 buf.len = pkt.size();
1368 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1369 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1370
1371 /* init the API struct */
1372 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1373 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1374 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1375 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1376 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1377
1378 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1379 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1380
1381 /* call API */
1382 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001383 }
1384 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001385 //TODO: Port No is 0, it is coming sender requirement.
1386 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1387 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001388 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001389 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001390
1391 return Status::OK;
1392}
1393
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001394Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001395 bcmolt_flow_key key = {}; /* declare key */
1396 bcmolt_bin_str buffer = {};
1397 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001398
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001399 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1400 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001401
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001402 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1403 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1404 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1405 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1406 key.flow_id = flow_id;
1407 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001408 if (flow_id_counters) {
1409 std::map<flow_pair, int>::iterator it;
1410 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1411 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001412 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1413 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1414 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1415 key.flow_id = flow_index;
1416 break;
1417 }
1418 }
1419 }
1420 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001421 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001422 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1423 }
1424 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001425
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001426 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001427
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001428 /* Initialize the API struct. */
1429 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001430
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001431 buffer.len = pkt.size();
1432 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1433 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1434 if (buffer.arr == NULL) {
1435 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1436 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1437 }
1438 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1439
1440 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1441 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001442 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 -05001443 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001444 } else {
1445 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1446 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001447
1448 return Status::OK;
1449}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001450Status 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 +00001451 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001452 int32_t alloc_id, int32_t network_intf_id,
1453 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001454 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001455 int32_t group_id, uint32_t tech_profile_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001456 bcmolt_flow_cfg cfg;
1457 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001458 int32_t o_vid = -1;
1459 bool single_tag = false;
1460 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001461 bcmolt_classifier c_val = { };
1462 bcmolt_action a_val = { };
1463 bcmolt_tm_queue_ref tm_val = { };
1464 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001465 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001466
Jason Huang09b73ea2020-01-08 17:52:05 +08001467 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1468
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001469 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001470 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001471 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001472 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001473 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001474 } else if (flow_type.compare(multicast) == 0) {
1475 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001476 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001477 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001478 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001479 }
1480
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001481 BCMOLT_CFG_INIT(&cfg, flow, key);
1482 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001483
Jason Huang09b73ea2020-01-08 17:52:05 +08001484 if (action.cmd().trap_to_host()) {
1485 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1486 network_intf_id, gemport_id, classifier);
1487 return resp;
1488 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001489
1490 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1491
1492 if (access_intf_id >= 0 && network_intf_id >= 0) {
1493 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1494 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1495 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001496 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1497 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001498 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1499 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1500 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1501 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1502 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001503 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001504 } else {
1505 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1506 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001507 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001508
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001509 if (onu_id >= 0) {
1510 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1511 }
1512 if (gemport_id >= 0) {
1513 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1514 }
1515 if (gemport_id >= 0 && port_no != 0) {
1516 bcmos_fastlock_lock(&data_lock);
1517 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1518 port_to_flows[port_no].insert(key.flow_id);
1519 flowid_to_gemport[key.flow_id] = gemport_id;
1520 }
1521 else
1522 {
1523 flowid_to_port[key.flow_id] = port_no;
1524 }
1525 bcmos_fastlock_unlock(&data_lock, 0);
1526 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001527 if (gemport_id >= 0 && access_intf_id >= 0) {
1528 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1529 // This info is needed during flow remove where we need to retrieve the gemport_id
1530 // and access_intf id for the given flow id and flow direction.
1531 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1532 // reference counters for those ACL ID and GEMPORT ID.
1533 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1534 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1535 bcmos_fastlock_lock(&data_lock);
1536 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1537 bcmos_fastlock_unlock(&data_lock, 0);
1538 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001539 if (priority_value >= 0) {
1540 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1541 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301542
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001543 } else { // MULTICAST FLOW
1544 if (group_id >= 0) {
1545 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001546 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001547 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1548 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001549 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001550
1551 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001552 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001553 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001554 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1555 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001556 }
1557
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001558 if (classifier.dst_mac().size() > 0) {
1559 bcmos_mac_address d_mac = {};
1560 bcmos_mac_address_init(&d_mac);
1561 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1562 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1563 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1564 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001565 }
1566
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001567 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001568 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001569 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001570 }
1571 */
1572
1573 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001574 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1575 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001576 }
1577
1578 /*
1579 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001580 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001581 }
1582
1583 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001584 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001585 }
1586 */
1587
1588 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001589 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1590 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001591 }
1592
1593 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001594 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1595 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001596 }
1597
1598 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001599 if (classifier.o_vid()) {
1600 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1601 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1602 }
1603
1604 if (classifier.i_vid()) {
1605 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1606 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1607 }
1608
1609 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1610 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1611 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1612 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1613 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1614 single_tag = true;
1615
1616 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301617 // OpenOlt adapter will send 0xFF in case of no pbit classification
1618 // If it is any other value (0 to 7), it is for outer pbit classification.
1619 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1620 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1621 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1622 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001623 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301624 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001625 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1626 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001627
Jason Huang09b73ea2020-01-08 17:52:05 +08001628 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301629 // Same comments as in case of "single_tag" packets.
1630 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1631 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001632 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301633 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001634 }
1635 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001636 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001637 }
1638
Jason Huang09b73ea2020-01-08 17:52:05 +08001639 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001640
Jason Huang09b73ea2020-01-08 17:52:05 +08001641 if (cmd.add_outer_tag()) {
1642 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1643 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001644 }
1645
Jason Huang09b73ea2020-01-08 17:52:05 +08001646 if (cmd.remove_outer_tag()) {
1647 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1648 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1649 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301650
Jason Huang09b73ea2020-01-08 17:52:05 +08001651 if (action.o_vid()) {
1652 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1653 o_vid = action.o_vid();
1654 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1655 }
1656
1657 if (action.o_pbits()) {
1658 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1659 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1660 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301661
Jason Huang09b73ea2020-01-08 17:52:05 +08001662 if (action.i_vid()) {
1663 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1664 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1665 }
1666
1667 if (action.i_pbits()) {
1668 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1669 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1670 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301671
Jason Huang09b73ea2020-01-08 17:52:05 +08001672 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1673
Shad Ansari39739bc2018-09-13 21:38:37 +00001674 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001675 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1676 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001677 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 +00001678
Jason Huang09b73ea2020-01-08 17:52:05 +08001679 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1680 // Queue 0 on DS subscriber scheduler
1681 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001682
Jason Huang09b73ea2020-01-08 17:52:05 +08001683 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1684 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1685 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001686
Jason Huang09b73ea2020-01-08 17:52:05 +08001687 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1688 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1689 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001690
Jason Huang09b73ea2020-01-08 17:52:05 +08001691 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1692 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1693 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 +00001694
Jason Huang09b73ea2020-01-08 17:52:05 +08001695 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1696 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1697 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1698 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 +00001699
Jason Huang09b73ea2020-01-08 17:52:05 +08001700 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1701 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1702 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1703 }
1704 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1705 // NNI Scheduler ID
1706 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1707 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1708 // Queue 0 on NNI scheduler
1709 tm_val.queue_id = 0;
1710 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1711 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1712 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001713
Jason Huang09b73ea2020-01-08 17:52:05 +08001714 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 +00001715 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1716 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1717
Jason Huang09b73ea2020-01-08 17:52:05 +08001718 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1719 /* Fetch TM QMP ID mapped to US NNI scheduler */
1720 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1721 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1722 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1723 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1724 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 +00001725
Jason Huang09b73ea2020-01-08 17:52:05 +08001726 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 +00001727 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1728 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001729 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001730 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301731 } else {
1732 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1733 tm_val.queue_id = 0;
1734
1735 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1736 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1737 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1738
1739 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1740 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1741 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001742 }
1743
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001744 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001745
1746 // BAL 3.1 supports statistics only for unicast flows.
1747 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1748 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1749 }
1750
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001751#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001752 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001753 if (flow_id_counters != 0) {
1754 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001755 std::map<flow_pair, int>::iterator it;
1756
1757 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1758 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1759 (key.flow_type == it->first.second) && \
1760 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1761 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1762 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1763 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1764 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1765 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1766 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1767 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1768 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1769 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1770 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1771 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1772 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1773 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1774 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1775 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1776 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1777 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1778 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1779 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1780 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1781 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1782 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1783 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1784 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1785 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001786#ifdef SHOW_FLOW_PARAM
1787 // Flow Parameter
1788 FLOW_PARAM_LOG();
1789#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001790 if (b_duplicate_flow) {
1791 FLOW_LOG(WARNING, "Flow duplicate", 0);
1792 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1793 }
1794 }
1795 }
1796#endif
1797
1798 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1799 if (err) {
1800 FLOW_LOG(ERROR, "Flow add failed", err);
1801 return bcm_to_grpc_err(err, "flow add failed");
1802 } else {
1803 FLOW_LOG(INFO, "Flow add ok", err);
1804 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001805 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1806 flow_id_counters = flow_map.size();
1807 if (gemport_id > 0 && access_intf_id >= 0) {
1808 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1809 if (gem_ref_cnt.count(gem_intf) > 0) {
1810 // The gem port is already installed
1811 // Increment the ref counter indicating number of flows referencing this gem port
1812 gem_ref_cnt[gem_intf]++;
1813 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1814 } else {
1815 // Initialize the refence count for the gemport.
1816 gem_ref_cnt[gem_intf] = 1;
1817 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1818 }
1819 } else {
1820 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);
1821 }
1822
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001823 bcmos_fastlock_unlock(&data_lock, 0);
1824 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001825
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001826 return Status::OK;
1827}
1828
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001829Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1830
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001831 bcmolt_flow_cfg cfg;
1832 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001833
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001834 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001835 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001836 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001837 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001838 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001839 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001840 } else if(flow_type.compare(multicast) == 0) {
1841 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001842 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001843 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001844 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1845 }
1846
Jason Huang09b73ea2020-01-08 17:52:05 +08001847 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1848 flow_id, flow_type.c_str());
1849
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001850 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001851 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1852 int32_t gemport_id = -1;
1853 int32_t intf_id = -1;
1854 int16_t acl_id = -1;
1855 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1856 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1857 acl_id = std::get<0>(ac_id_gm_id_if_id);
1858 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1859 intf_id = std::get<2>(ac_id_gm_id_if_id);
1860 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1861 if (acl_id >= 0) {
1862 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1863 bcmos_fastlock_unlock(&data_lock, 0);
1864 if (resp.ok()) {
1865 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1866 flow_to_acl_map.erase(fl_id_fl_dir);
1867 } else {
1868 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1869 }
1870 return resp;
1871 }
1872 }
1873
Craig Lutgen967a1d02018-11-27 10:41:51 -06001874 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001875 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001876 flowid_to_gemport.erase(key.flow_id);
1877 port_to_flows[port_no].erase(key.flow_id);
1878 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1879 }
1880 else
1881 {
1882 flowid_to_port.erase(key.flow_id);
1883 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001884 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001885
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001886 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001887
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001888 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001889 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001890 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 -04001891 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1892 }
1893
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001894 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001895 if (flow_id_counters != 0) {
1896 std::map<flow_pair, int>::iterator it;
1897 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1898 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1899 flow_id_counters -= 1;
1900 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001901 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001902 }
1903 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001904 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1905
1906 clear_gem_port(gemport_id, intf_id);
1907
1908 flow_to_acl_map.erase(fl_id_fl_dir);
1909
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001910 bcmos_fastlock_unlock(&data_lock, 0);
1911
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001912 return Status::OK;
1913}
1914
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001915bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1916 bcmos_errno err;
1917 bcmolt_tm_sched_cfg tm_sched_cfg;
1918 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1919 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1920
Jason Huangbf45ffb2019-10-30 17:29:02 +08001921 //check TM scheduler has configured or not
1922 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1923 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001924 #ifdef TEST_MODE
1925 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1926 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1927 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1928 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1929 // code in production code.
1930 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1931 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001932 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001933 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001934 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001935 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 +08001936 return err;
1937 }
1938 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1939 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1940 return BCM_ERR_OK;
1941 }
1942
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001943 // bcmbal_tm_sched_owner
1944 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1945
1946 /**< The output of the tm_sched object instance */
1947 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1948
1949 if (direction.compare(upstream) == 0) {
1950 // In upstream it is NNI scheduler
1951 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1952 } else if (direction.compare(downstream) == 0) {
1953 // In downstream it is PON scheduler
1954 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1955 }
1956
1957 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1958
1959 // bcmbal_tm_sched_type
1960 // set the deafult policy to strict priority
1961 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1962
1963 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001964 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001965
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001966 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1967 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001968 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1969 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001970 return err;
1971 }
1972
1973 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1974 direction.c_str(), tm_sched_key.id, intf_id);
1975 return BCM_ERR_OK;
1976}
1977
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001978bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
1979 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001980 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info,
1981 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001982
1983 bcmos_errno err;
1984
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001985 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001986 bcmolt_tm_sched_cfg tm_sched_cfg;
1987 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001988 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 -04001989
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001990 // bcmbal_tm_sched_owner
1991 // In downstream it is sub_term scheduler
1992 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001993
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001994 /**< The output of the tm_sched object instance */
1995 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001996
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001997 // bcmbal_tm_sched_parent
1998 // The parent for the sub_term scheduler is the PON scheduler in the downstream
1999 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2000 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 +00002001 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002002 be achieved using the' virtual' type of attachment.
2003 tm_sched_owner.u.sub_term.intf_id = intf_id;
2004 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2005 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002006
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002007 // bcmbal_tm_sched_type
2008 // set the deafult policy to strict priority
2009 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002010
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002011 // num_priorities: Max number of strict priority scheduling elements
2012 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002013
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002014 // bcmbal_tm_shaping
2015 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2016 uint32_t cir = tf_sh_info.cir();
2017 uint32_t pir = tf_sh_info.pir();
2018 uint32_t burst = tf_sh_info.pbs();
2019 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2020 cir, pir, burst);
2021 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2022 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2023 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2024 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2025 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2026 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002027 }
2028
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002029 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002030 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002031 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002032intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2033port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002034 return err;
2035 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002036 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2037uni_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 -08002038
2039 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002040 bcmolt_itupon_alloc_cfg cfg;
2041 bcmolt_itupon_alloc_key key = { };
2042 key.pon_ni = intf_id;
2043 key.alloc_id = alloc_id;
2044 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00002045 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2046 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002047 //offset to match bandwidth granularity
2048 int offset_pir_bw = pir_bw%bw_granularity;
2049 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002050
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002051 pir_bw = pir_bw - offset_pir_bw;
2052 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002053
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002054 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002055
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002056 switch (additional_bw) {
2057 case 2: //AdditionalBW_BestEffort
2058 if (pir_bw == 0) {
2059 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2060%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002061 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002062 } else if (pir_bw < cir_bw) {
2063 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2064bandwidth (%d)\n", pir_bw, cir_bw);
2065 return BCM_ERR_PARM;
2066 } else if (pir_bw == cir_bw) {
2067 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2068bandwidth for additional bandwidth eligibility of type best_effort\n");
2069 return BCM_ERR_PARM;
2070 }
2071 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2072 break;
2073 case 1: //AdditionalBW_NA
2074 if (pir_bw == 0) {
2075 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2076%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2077 return BCM_ERR_PARM;
2078 } else if (cir_bw == 0) {
2079 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2080additional bandwidth eligibility of type Non-Assured (NA)\n");
2081 return BCM_ERR_PARM;
2082 } else if (pir_bw < cir_bw) {
2083 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2084bandwidth (%d)\n", pir_bw, cir_bw);
2085 return BCM_ERR_PARM;
2086 } else if (pir_bw == cir_bw) {
2087 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2088bandwidth for additional bandwidth eligibility of type non_assured\n");
2089 return BCM_ERR_PARM;
2090 }
2091 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2092 break;
2093 case 0: //AdditionalBW_None
2094 if (pir_bw == 0) {
2095 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
209616000 bytes/sec\n");
2097 return BCM_ERR_PARM;
2098 } else if (cir_bw == 0) {
2099 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2100for additional bandwidth eligibility of type None\n");
2101 return BCM_ERR_PARM;
2102 } else if (pir_bw > cir_bw) {
2103 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2104for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002105 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002106bandwidth in None eligibility\n", pir_bw);
2107 cir_bw = pir_bw;
2108 } else if (pir_bw < cir_bw) {
2109 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2110bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002111 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002112bandwidth in None eligibility\n", pir_bw);
2113 cir_bw = pir_bw;
2114 }
2115 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2116 break;
2117 default:
2118 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002119 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002120 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2121 in a fine granularity. */
2122 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2123 /* Fixed Bandwidth with no critical requirement of shaping */
2124 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2125 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2126 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2127 /* Maximum allocated bandwidth allowed for this alloc ID */
2128 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2129 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002130 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002131 for skipped allocations during quiet window */
2132 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2133 /**< Allocation Profile index for CBR non-RT Bandwidth */
2134 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2135 /**< Allocation Profile index for CBR RT Bandwidth */
2136 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2137 /**< Alloc ID Weight used in case of Extended DBA mode */
2138 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2139 /**< Alloc ID Priority used in case of Extended DBA mode */
2140 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2141 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002142
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002144 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002145 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 -05002146port_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 -08002147 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002148 }
Girish Gowdra96461052019-11-22 20:13:59 +05302149
2150 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2151 if (err) {
2152 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2153port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2154 return err;
2155 }
2156
2157 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2158port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2159
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002160 }
2161
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002162 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002163}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002164
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002165Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2166 uint32_t intf_id = traffic_scheds->intf_id();
2167 uint32_t onu_id = traffic_scheds->onu_id();
2168 uint32_t uni_id = traffic_scheds->uni_id();
2169 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002170 std::string direction;
2171 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002172 tech_profile::SchedulerConfig sched_config;
2173 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002174 uint32_t priority;
2175 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002176 tech_profile::SchedulingPolicy sched_policy;
2177 tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002178 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002179 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002180
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002181 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2182 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002183
2184 direction = GetDirection(traffic_sched.direction());
2185 if (direction.compare("direction-not-supported") == 0)
2186 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2187
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002188 alloc_id = traffic_sched.alloc_id();
2189 sched_config = traffic_sched.scheduler();
2190 additional_bw = sched_config.additional_bw();
2191 priority = sched_config.priority();
2192 weight = sched_config.weight();
2193 sched_policy = sched_config.sched_policy();
2194 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002195 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002196 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002197 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002198 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002199 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002200 return bcm_to_grpc_err(err, "Failed to create scheduler");
2201 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002202 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002203 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002204}
Jonathan Davis70c21812018-07-19 15:32:10 -04002205
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002206bcmos_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 -04002207
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002208 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302209 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302210 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302211 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002212
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002213 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002214 bcmolt_itupon_alloc_cfg cfg;
2215 bcmolt_itupon_alloc_key key = { };
2216 key.pon_ni = intf_id;
2217 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302218 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002219
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002220 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002221 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2222 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002223 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2224 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002225 return err;
2226 }
Girish Gowdra96461052019-11-22 20:13:59 +05302227
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302228 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302229 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302230 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
2231 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 +05302232 intf_id);
2233 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2234 if (err) {
2235 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2236 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2237 return err;
2238 }
2239 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302240 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2241 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2242 intf_id);
2243 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302244 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2245 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2246 intf_id);
2247 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302248 } else {
2249 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 +05302250 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302251 return err;
2252 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002253 } else if (direction == downstream) {
2254 bcmolt_tm_sched_cfg cfg;
2255 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002256
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002257 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2258 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302259 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002260 } else {
2261 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2262 return BCM_ERR_OK;
2263 }
Girish Gowdra96461052019-11-22 20:13:59 +05302264
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002265 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2266 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2267 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002268 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002269intf_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 +00002270 return err;
2271 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002272 }
2273
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002274 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2275 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2276 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002277 return BCM_ERR_OK;
2278}
2279
2280Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2281 uint32_t intf_id = traffic_scheds->intf_id();
2282 uint32_t onu_id = traffic_scheds->onu_id();
2283 uint32_t uni_id = traffic_scheds->uni_id();
2284 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002285 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002286 bcmos_errno err;
2287
2288 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2289 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002290
2291 direction = GetDirection(traffic_sched.direction());
2292 if (direction.compare("direction-not-supported") == 0)
2293 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2294
2295 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002296 int tech_profile_id = traffic_sched.tech_profile_id();
2297 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002298 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002299 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002300 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2301 }
2302 }
2303 return Status::OK;
2304}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002305
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002306bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2307 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002308 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002309 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2310 bcmolt_tm_qmp_key tm_qmp_key;
2311 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002312
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002313 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2314 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002315 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2316 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002317 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002318
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002319 tm_qmp_key.id = tm_qmp_id;
2320 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2321 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2322 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002323
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002324 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2325 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2326 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002327 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2328 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002329
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002330 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002331 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002332 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2333 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002334 return err;
2335 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002336
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002337 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2338 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002339 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002340}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002341
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002342bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2343 bcmos_errno err;
2344 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2345 bcmolt_tm_qmp_key tm_qmp_key;
2346 tm_qmp_key.id = tm_qmp_id;
2347
2348 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2349 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2350 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002351 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2352 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002353 return err;
2354 }
2355
2356 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2357 tm_qmp_key.id);
2358 return BCM_ERR_OK;
2359}
2360
2361bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2362 bcmos_errno err;
2363
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002364 /* Create default queues on the given PON/NNI scheduler */
2365 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002366 bcmolt_tm_queue_cfg tm_queue_cfg;
2367 bcmolt_tm_queue_key tm_queue_key = {};
2368 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2369 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002370 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2371 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2372 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002373
2374 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2375 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2376 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2377
2378 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2379 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002380 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", \
2381 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 +00002382 return err;
2383 }
2384
2385 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2386 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2387 }
2388 return BCM_ERR_OK;
2389}
2390
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002391bcmos_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 +00002392 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 +00002393 bcmos_errno err;
2394 bcmolt_tm_queue_cfg cfg;
2395 bcmolt_tm_queue_key key = { };
2396 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 +00002397gemport_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 +00002398
2399 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002400 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002401
2402 if (priority > 7) {
2403 return BCM_ERR_RANGE;
2404 }
2405
2406 /* FIXME: The upstream queues have to be created once only.
2407 The upstream queues on the NNI scheduler are shared by all subscribers.
2408 When the first scheduler comes in, the queues get created, and are re-used by all others.
2409 Also, these queues should be present until the last subscriber exits the system.
2410 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2411
2412 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2413 for each GEM in TECH PROFILE */
2414 key.id = queue_id_list[priority];
2415
2416 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2417 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2418 key.id = 0;
2419 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2420 }
2421 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2422 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2423 }
2424 else {
2425 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2426 }
2427
2428 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2429
2430 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2431 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2432
2433 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2434 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002435 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002436sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2437 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 +00002438 return err;
2439 }
2440
2441 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 +00002442intf_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 +00002443 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002444}
2445
2446Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2447 uint32_t intf_id = traffic_queues->intf_id();
2448 uint32_t onu_id = traffic_queues->onu_id();
2449 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002450 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002451 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002452 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002453 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002454 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 +00002455
2456 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2457 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2458 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2459 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2460 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2461
2462 direction = GetDirection(traffic_queue.direction());
2463 if (direction.compare("direction-not-supported") == 0)
2464 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2465
2466 queues_priority_q[i] = traffic_queue.priority();
2467 queues_pbit_map[i] = traffic_queue.pbit_map();
2468 }
2469
2470 std::vector<uint32_t> tmq_map_profile(8, 0);
2471 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2472 queues_priority_q, COUNT_OF(queues_priority_q));
2473 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002474 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002475
2476 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2477 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002478 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2479 if (err != BCM_ERR_OK) {
2480 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2481 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2482 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002483 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2484 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2485 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2486 }
2487 }
2488
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002489 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2490 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002491
2492 direction = GetDirection(traffic_queue.direction());
2493 if (direction.compare("direction-not-supported") == 0)
2494 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2495
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002496 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 +00002497
Girish Gowdruf26cf882019-05-01 23:47:58 -07002498 // If the queue exists already, lets not return failure and break the loop.
2499 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002500 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002501 return bcm_to_grpc_err(err, "Failed to create queue");
2502 }
2503 }
2504 return Status::OK;
2505}
2506
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002507bcmos_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 +00002508 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 +00002509 bcmolt_tm_queue_cfg cfg;
2510 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002511 bcmos_errno err;
2512
2513 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002514 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2515 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 +00002516 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002517 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002518 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 -08002519 return BCM_ERR_OK;
2520 }
2521 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002522 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2523 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002524 return BCM_ERR_OK;
2525 }
2526
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002527 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2528 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2529 // Reset the queue id to 0 when using fixed queue.
2530 key.id = 0;
2531 }
2532 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2533 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2534 }
2535 else {
2536 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2537 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002538
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002539 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2540 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002541 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002542 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2543tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2544 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 -08002545 return err;
2546 }
2547
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002548 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2549intf_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 -08002550
2551 return BCM_ERR_OK;
2552}
2553
2554Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2555 uint32_t intf_id = traffic_queues->intf_id();
2556 uint32_t onu_id = traffic_queues->onu_id();
2557 uint32_t uni_id = traffic_queues->uni_id();
2558 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002559 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002560 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002561 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002562 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002563 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 +00002564
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002565 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2566 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002567
2568 direction = GetDirection(traffic_queue.direction());
2569 if (direction.compare("direction-not-supported") == 0)
2570 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2571
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002572 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 -08002573 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002574 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002575 return bcm_to_grpc_err(err, "Failed to remove queue");
2576 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002577 }
2578
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002579 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 +00002580 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002581 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002582
2583 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2584 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002585 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2586 if (err != BCM_ERR_OK) {
2587 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2588 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2589 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002590 }
2591 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002592 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002593 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002594}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002595
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002596Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2597
2598 bcmos_errno err;
2599 bcmolt_group_key key = {};
2600 bcmolt_group_cfg grp_cfg_obj;
2601 bcmolt_group_members_update grp_mem_upd;
2602 bcmolt_members_update_command grp_mem_upd_cmd;
2603 bcmolt_group_member_info member_info = {};
2604 bcmolt_group_member_info_list_u8 members = {};
2605 bcmolt_intf_ref interface_ref = {};
2606 bcmolt_egress_qos egress_qos = {};
2607 bcmolt_tm_sched_ref tm_sched_ref = {};
2608 bcmolt_action a_val = {};
2609
2610 uint32_t group_id = group_cfg->group_id();
2611
2612 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2613
2614 if (group_id >= 0) {
2615 key.id = group_id;
2616 }
2617 else {
2618 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2619 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2620 }
2621
2622 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2623 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2624
2625 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2626
2627 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2628 if (err != BCM_ERR_OK) {
2629 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2630 return bcm_to_grpc_err(err, "Error in querying group");
2631 }
2632
2633 members.len = group_cfg->members_size();
2634
2635 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2636 // Group type is determined after a flow is assigned to it.
2637 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2638 // Only then we can add members to the group.
2639
2640 // if group does not exist, create it and return.
2641 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2642
2643 if (members.len != 0) {
2644 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);
2645 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2646 } else {
2647
2648 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2649 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2650
2651 /* Setting group actions and action parameters, if any.
2652 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2653 are supported for multicast groups in BAL 3.1.
2654 */
2655 const ::openolt::Action& action = group_cfg->action();
2656 const ::openolt::ActionCmd &cmd = action.cmd();
2657
2658 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2659 if (cmd.remove_outer_tag()) {
2660 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2661 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2662 }
2663
2664 if (cmd.translate_inner_tag()) {
2665 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2666 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2667 }
2668
2669 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2670
2671 if (action.i_vid()) {
2672 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2673 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2674 }
2675
2676 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2677
2678 // Create group
2679 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2680
2681 if (BCM_ERR_OK != err) {
2682 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2683 return bcm_to_grpc_err(err, "Error in creating group");
2684 }
2685
2686 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2687 return Status::OK;
2688 }
2689 }
2690
2691 // The group already exists. Continue configuring it according to the update member command.
2692
2693 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2694
2695 // MEMBER LIST CONSTRUCTION
2696 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2697 // empty list to the group is a legit operation and this actually empties the member list.
2698 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2699
2700 if (!members.arr) {
2701 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2702 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2703 }
2704
2705 /* SET GROUP MEMBERS UPDATE COMMAND */
2706 openolt::Group::GroupMembersCommand command = group_cfg->command();
2707 switch(command) {
2708 case openolt::Group::SET_MEMBERS :
2709 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2710 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2711 break;
2712 case openolt::Group::ADD_MEMBERS :
2713 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2714 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2715 break;
2716 case openolt::Group::REMOVE_MEMBERS :
2717 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2718 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2719 break;
2720 default :
2721 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2722 bcmos_free(members.arr);
2723 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2724 }
2725
2726 // SET MEMBERS LIST
2727 for (int i = 0; i < members.len; i++) {
2728
2729 if (command == openolt::Group::REMOVE_MEMBERS) {
2730 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2731 } else {
2732 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2733 }
2734
2735 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2736
2737 // Set member interface type
2738 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2739 switch(if_type){
2740 case openolt::GroupMember::PON :
2741 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2742 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2743 break;
2744 case openolt::GroupMember::EPON_1G_PATH :
2745 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2746 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2747 break;
2748 case openolt::GroupMember::EPON_10G_PATH :
2749 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2750 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2751 break;
2752 default :
2753 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2754 bcmos_free(members.arr);
2755 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2756 }
2757
2758 // Set member interface id
2759 if (member->interface_id() >= 0) {
2760 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2761 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2762 } else {
2763 bcmos_free(members.arr);
2764 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2765 }
2766
2767 // Set member interface_ref
2768 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2769
2770 // Set member gem_port_id. This must be a multicast gemport.
2771 if (member->gem_port_id() >= 0) {
2772 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2773 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2774 } else {
2775 bcmos_free(members.arr);
2776 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2777 }
2778
2779 // Set member scheduler id and queue_id
2780 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2781 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2782 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2783 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2784
2785 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2786 uint32_t tm_queue_id;
2787 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2788 tm_queue_id = queue_id_list[member->priority()];
2789 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2790 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2791 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2792 } else {
2793 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2794 bcmos_free(members.arr);
2795 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2796 }
2797
2798 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2799 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2800 }
2801
2802 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2803 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2804 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2805
2806 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2807 bcmos_free(members.arr);
2808
2809 if (BCM_ERR_OK != err) {
2810 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);
2811 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2812 }
2813
2814 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2815
2816 return Status::OK;
2817}