blob: babd9cec867d859ea9c00dfacea57f67c2b860bb [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, \
Girish Gowdra252f4972020-09-07 21:24:01 -070068 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,
70 ::tech_profile::TrafficShapingInfo traffic_shaping_info, uint32_t tech_profile_id);
Burak Gurdag2f2618c2020-04-23 13:20:30 +000071static 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);
Orhan Kupusogluec57af02021-05-12 12:38:17 +000078static const std::chrono::milliseconds ONU_RSSI_COMPLETE_WAIT_TIMEOUT = std::chrono::seconds(10);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000080inline const char *get_flow_acton_command(uint32_t command) {
81 char actions[200] = { };
82 char *s_actions_ptr = actions;
83 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
90 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
91 return s_actions_ptr;
92}
93
kesavandc1f2db92020-08-31 15:32:06 +053094bcmolt_stat_alarm_config set_stat_alarm_config(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +080095 bcmolt_stat_alarm_config alarm_cfg = {};
96 bcmolt_stat_alarm_trigger_config trigger_obj = {};
97 bcmolt_stat_alarm_soak_config soak_obj = {};
98
99 switch (request->alarm_reporting_condition()) {
kesavandc1f2db92020-08-31 15:32:06 +0530100 case config::OnuItuPonAlarm::RATE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800101 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD;
102 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
103 rising, request->rate_threshold_config().rate_threshold_rising());
104 BCMOLT_FIELD_SET(&trigger_obj.u.rate_threshold, stat_alarm_trigger_config_rate_threshold,
105 falling, request->rate_threshold_config().rate_threshold_falling());
106 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
107 request->rate_threshold_config().soak_time().active_soak_time());
108 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
109 request->rate_threshold_config().soak_time().clear_soak_time());
110 break;
kesavandc1f2db92020-08-31 15:32:06 +0530111 case config::OnuItuPonAlarm::RATE_RANGE:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800112 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE;
113 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, upper,
114 request->rate_range_config().rate_range_upper());
115 BCMOLT_FIELD_SET(&trigger_obj.u.rate_range, stat_alarm_trigger_config_rate_range, lower,
116 request->rate_range_config().rate_range_lower());
117 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
118 request->rate_range_config().soak_time().active_soak_time());
119 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
120 request->rate_range_config().soak_time().clear_soak_time());
121 break;
kesavandc1f2db92020-08-31 15:32:06 +0530122 case config::OnuItuPonAlarm::VALUE_THRESHOLD:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800123 trigger_obj.type = BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD;
124 BCMOLT_FIELD_SET(&trigger_obj.u.value_threshold, stat_alarm_trigger_config_value_threshold,
125 limit, request->value_threshold_config().threshold_limit());
126 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, active_soak_time,
127 request->value_threshold_config().soak_time().active_soak_time());
128 BCMOLT_FIELD_SET(&soak_obj, stat_alarm_soak_config, clear_soak_time,
129 request->value_threshold_config().soak_time().clear_soak_time());
130 break;
131 default:
132 OPENOLT_LOG(ERROR, openolt_log_id, "unsupported alarm reporting condition = %u\n", request->alarm_reporting_condition());
133 // For now just log the error and not return error. We can handle this scenario in the future.
134 break;
135 }
136
137 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, trigger, trigger_obj);
138 BCMOLT_FIELD_SET(&alarm_cfg, stat_alarm_config, soak, soak_obj);
139
140 return alarm_cfg;
141}
142
kesavandc1f2db92020-08-31 15:32:06 +0530143Status OnuItuPonAlarmSet_(const config::OnuItuPonAlarm* request) {
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800144 bcmos_errno err;
145 bcmolt_onu_itu_pon_stats_cfg stat_cfg; /* declare main API struct */
146 bcmolt_onu_key key = {}; /* declare key */
147 bcmolt_stat_alarm_config errors_cfg = {};
148
149 key.pon_ni = request->pon_ni();
150 key.onu_id = request->onu_id();
151
152 /* Initialize the API struct. */
153 BCMOLT_STAT_CFG_INIT(&stat_cfg, onu, itu_pon_stats, key);
154
155 /*
156 1. BCMOLT_STAT_CONDITION_TYPE_NONE = 0, The alarm is disabled.
157 2. BCMOLT_STAT_CONDITION_TYPE_RATE_THRESHOLD = 1, The alarm is triggered if the stats delta value between samples
158 crosses the configured threshold boundary.
159 rising: The alarm is raised if the stats delta value per second becomes greater than this threshold level.
160 falling: The alarm is cleared if the stats delta value per second becomes less than this threshold level.
161 3. BCMOLT_STAT_CONDITION_TYPE_RATE_RANGE = 2, The alarm is triggered if the stats delta value between samples
162 deviates from the configured range.
163 upper: The alarm is raised if the stats delta value per second becomes greater than this upper level.
164 lower: The alarm is raised if the stats delta value per second becomes less than this lower level.
165 4. BCMOLT_STAT_CONDITION_TYPE_VALUE_THRESHOLD = 3, The alarm is raised if the stats sample value becomes greater
166 than this level. The alarm is cleared when the host read the stats.
167 limit: The alarm is raised if the stats sample value becomes greater than this level.
168 The alarm is cleared when the host clears the stats.
169
170 active_soak_time: If the alarm condition is raised and stays in the raised state for at least this amount
171 of time (unit=seconds), the alarm indication is sent to the host.
172 The OLT delays the alarm indication no less than this delay period.
173 It can be delayed more than this period because of the statistics sampling interval.
174 clear_soak_time: After the alarm is raised, if it is cleared and stays in the cleared state for at least
175 this amount of time (unit=seconds), the alarm indication is sent to the host.
176 The OLT delays the alarm indication no less than this delay period. It can be delayed more
177 than this period because of the statistics sampling interval.
178 */
179
180 errors_cfg = set_stat_alarm_config(request);
181
182 switch (request->alarm_id()) {
kesavandc1f2db92020-08-31 15:32:06 +0530183 case config::OnuItuPonAlarm_AlarmID::OnuItuPonAlarm_AlarmID_RDI_ERRORS:
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800184 //set the rdi_errors alarm
185 BCMOLT_FIELD_SET(&stat_cfg.data, onu_itu_pon_stats_cfg_data, rdi_errors, errors_cfg);
186 break;
187 default:
188 OPENOLT_LOG(ERROR, openolt_log_id, "could not find the alarm id %d\n", request->alarm_id());
189 return bcm_to_grpc_err(BCM_ERR_PARM, "the alarm id is wrong");
190 }
191
192 err = bcmolt_stat_cfg_set(dev_id, &stat_cfg.hdr);
193 if (err != BCM_ERR_OK) {
194 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",
195 request->alarm_id(), key.pon_ni, key.onu_id, bcmos_strerror(err));
196 return bcm_to_grpc_err(err, "set Onu ITU PON stats alarm faild");
197 } else {
198 OPENOLT_LOG(INFO, openolt_log_id, "set onu itu pon stats alarm %d successfully, pon_ni %d, onu_id %d\n",
199 request->alarm_id(), key.pon_ni, key.onu_id);
200 }
201
202 return Status::OK;
203}
204
Girish Gowdra252f4972020-09-07 21:24:01 -0700205Status GetDeviceInfo_(::openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500206 device_info->set_vendor(VENDOR_ID);
207 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400208 device_info->set_hardware_version("");
209 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500210 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500211 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500212
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800213 char serial_number[OPENOLT_FIELD_LEN];
214 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
215 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000216 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800217 device_info->set_device_serial_number(serial_number);
Burak Gurdag30db4822021-03-10 21:30:01 +0000218 device_info->set_previously_connected(state.previously_connected());
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800219
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700220 char device_id[OPENOLT_FIELD_LEN];
221 memset(device_id, '\0', OPENOLT_FIELD_LEN);
Humera Kouser6143c9e2020-06-17 22:37:31 +0530222
223 if (grpc_server_interface_name != NULL) {
224 if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
225 {
226 OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
227 }
228 else
229 {
230 OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
231 }
232 }
233 else
234 {
235 openolt_read_sysinfo("MAC", device_id);
236 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
237 }
238
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700239 device_info->set_device_id(device_id);
240
Craig Lutgenb2601f02018-10-23 13:04:31 -0500241 // Legacy, device-wide ranges. To be deprecated when adapter
242 // is upgraded to support per-interface ranges
Girish Gowdra252f4972020-09-07 21:24:01 -0700243 device_info->set_onu_id_start(ONU_ID_START);
244 device_info->set_onu_id_end(ONU_ID_END);
245 device_info->set_alloc_id_start(ALLOC_ID_START);
246 device_info->set_alloc_id_end(ALLOC_ID_END);
247 device_info->set_gemport_id_start(GEM_PORT_ID_START);
248 device_info->set_gemport_id_end(GEM_PORT_ID_END);
249 device_info->set_flow_id_start(FLOW_ID_START);
250 device_info->set_flow_id_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500251
Girish Gowdra252f4972020-09-07 21:24:01 -0700252 std::map<std::string, ::openolt::DeviceInfo::DeviceResourceRanges*> ranges;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500253 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
254 std::string intf_technology = intf_technologies[intf_id];
Girish Gowdra252f4972020-09-07 21:24:01 -0700255 ::openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
Craig Lutgenb2601f02018-10-23 13:04:31 -0500256 if(range == nullptr) {
257 range = device_info->add_ranges();
258 ranges[intf_technology] = range;
259 range->set_technology(intf_technology);
260
Girish Gowdra252f4972020-09-07 21:24:01 -0700261 ::openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
Craig Lutgenb2601f02018-10-23 13:04:31 -0500262
Girish Gowdra252f4972020-09-07 21:24:01 -0700263 pool = range->add_pools();
264 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
265 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
266 pool->set_start(ONU_ID_START);
267 pool->set_end(ONU_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500268
Girish Gowdra252f4972020-09-07 21:24:01 -0700269 pool = range->add_pools();
270 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
271 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
272 pool->set_start(ALLOC_ID_START);
273 pool->set_end(ALLOC_ID_START);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500274
Girish Gowdra252f4972020-09-07 21:24:01 -0700275 pool = range->add_pools();
276 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
277 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
278 pool->set_start(GEM_PORT_ID_START);
279 pool->set_end(GEM_PORT_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500280
Girish Gowdra252f4972020-09-07 21:24:01 -0700281 pool = range->add_pools();
282 pool->set_type(::openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
283 pool->set_sharing(::openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
284 pool->set_start(FLOW_ID_START);
285 pool->set_end(FLOW_ID_END);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500286 }
287
288 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500289 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400290
291 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500292 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400293 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
294 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500295 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400296 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500297 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
298 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400299
300 return Status::OK;
301}
302
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530303void reset_pon_device(bcmolt_odid dev)
304{
305 bcmos_errno err;
306 bcmolt_device_reset oper;
307 bcmolt_device_key key = {.device_id = dev};
308
309 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device: %d\n", dev);
310
311 BCMOLT_OPER_INIT(&oper, device, reset, key);
312 err = bcmolt_oper_submit(dev_id, &oper.hdr);
313 if (err)
314 {
315 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to reset PON device(%d) failed, err = %s\n", dev, bcmos_strerror(err));
316 }else
317 {
318 OPENOLT_LOG(INFO, openolt_log_id, "Reset PON device(%d) success\n", dev);
319 }
320}
321
Shad Ansari627b5782018-08-13 22:49:32 +0000322Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000323 bcmos_errno err;
324 bcmolt_host_init_parms init_parms = {};
325 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
326 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000327
Shad Ansariedef2132018-08-10 22:14:50 +0000328 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000329
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500330 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000331 /* Initialize host subsystem */
332 err = bcmolt_host_init(&init_parms);
333 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500334 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000335 return bcm_to_grpc_err(err, "Failed to init OLT");
336 }
337
338 bcmcli_session_parm mon_session_parm;
339 /* Create CLI session */
340 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
341 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
342 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
343 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
344 BUG_ON(rc != BCM_ERR_OK);
345
346 /* API CLI */
347 bcm_openolt_api_cli_init(NULL, current_session);
348
349 /* Add quit command */
350 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
351
352 err = bcmolt_apiend_cli_init();
353 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500354 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000355 return bcm_to_grpc_err(err, "Failed to add apiend init");
356 }
357
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800358 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -0700359 bcmos_fastlock_init(&acl_id_bitset_lock, 0);
360 bcmos_fastlock_init(&tm_sched_bitset_lock, 0);
361 bcmos_fastlock_init(&tm_qmp_bitset_lock, 0);
362 bcmos_fastlock_init(&flow_id_bitset_lock, 0);
363 bcmos_fastlock_init(&voltha_flow_to_device_flow_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);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700366 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
367
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000368 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600369
Jason Huangbf45ffb2019-10-30 17:29:02 +0800370 //check BCM daemon is connected or not
371 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000372 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800373 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000374 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800375 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000376 Status status = SubscribeIndication();
377 if (!status.ok()) {
378 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
379 grpc_status_code_to_string(status.error_code()).c_str(),
380 status.error_message().c_str());
381 return status;
382 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800383
384 //check BAL state in initial stage
385 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000386 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800387 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000388 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800389 }
390
391 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000392 bcmos_errno err;
393 bcmolt_odid dev;
394 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
395 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400396 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000397 bcmolt_device_key dev_key = { };
398 dev_key.device_id = dev;
399 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
400 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
401 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800402 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000403 bcmolt_device_key key = {.device_id = dev};
404 bcmolt_device_connect oper;
405 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530406
407 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
408 * it retains config from soc file. If openolt agent try to connect device without
409 * device reset device initialization fails hence doing device reset here. */
410 reset_pon_device(dev);
411
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000412 if (MODEL_ID == "asfvolt16") {
413 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
414 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
415 } else if (MODEL_ID == "asgvolt64") {
416 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
417 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
418 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530419 } else if (MODEL_ID == "phoenix") {
420 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
421 if(dev == 1) {
422 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
423 }
424 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
425 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
426 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000427 }
428 err = bcmolt_oper_submit(dev_id, &oper.hdr);
429 if (err) {
430 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500431 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 +0000432 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500433 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 +0000434 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
435 }
436 }
437 bcmos_usleep(200000);
438 }
439 else {
440 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
441 state.activate();
442 }
443 }
444 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000445 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000446 }
Shad Ansariedef2132018-08-10 22:14:50 +0000447
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000448 /* Start CLI */
449 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400450 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000451 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400452}
453
454Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400455 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
456 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
457 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
458 //To overcome this disable is implemented by disabling all the PON ports
459 //associated with the device so as to support both in-band
460 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400461
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400462 Status status;
463 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700464 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400465 for (int i = 0; i < NumPonIf_(); i++) {
466 status = DisablePonIf_(i);
467 if (!status.ok()) {
468 failedCount+=1;
469 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
470 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400471 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400472 if (failedCount == 0) {
473 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700474 ::openolt::Indication ind;
475 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400476 olt_ind->set_oper_state("down");
477 ind.set_allocated_olt_ind(olt_ind);
478 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
479 oltIndQ.push(ind);
480 return Status::OK;
481 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000482 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400483 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
484 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400485
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400486 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 -0400487}
488
489Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400490 Status status;
491 int failedCount = 0;
492 for (int i = 0; i < NumPonIf_(); i++) {
493 status = EnablePonIf_(i);
494 if (!status.ok()) {
495 failedCount+=1;
496 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
497 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400498 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000499 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400500 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700501 ::openolt::Indication ind;
502 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400503 olt_ind->set_oper_state("up");
504 ind.set_allocated_olt_ind(olt_ind);
505 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
506 oltIndQ.push(ind);
507 return Status::OK;
508 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000509 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400510 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
511 }
512 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 +0000513}
514
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000515inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
516 bcmos_errno err;
517 bcmolt_flow_key flow_key;
518 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400519
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000520 flow_key.flow_id = flow_id;
521 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400522
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000523 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400524
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000525 switch (data_id) {
526 case ONU_ID: //onu_id
527 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500528 #ifdef TEST_MODE
529 // It is impossible to mock the setting of flow_cfg.data.state because
530 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
531 // set the flow_cfg.data. So a new stub function is created and address
532 // of flow_cfg is passed. This is one-of case where we need to add test specific
533 // code in production code.
534 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
535 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000536 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500537 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000538 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500539 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000540 return err;
541 }
542 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400543 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500544 #ifdef TEST_MODE
545 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
546 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000547 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000549 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500550 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000551 return err;
552 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400553 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000554 case SVC_PORT_ID: //svc_port_id
555 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500556 #ifdef TEST_MODE
557 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
558 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000559 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500560 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000561 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500562 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 +0000563 return err;
564 }
565 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400566 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000567 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500568 #ifdef TEST_MODE
569 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
570 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500572 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000573 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500574 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000575 return err;
576 }
577 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400578 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000579 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500580 #ifdef TEST_MODE
581 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
582 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000583 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500584 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000585 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500586 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 return err;
588 }
589 return flow_cfg.data.cookie;
590 case INGRESS_INTF_TYPE: //ingress intf_type
591 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500592 #ifdef TEST_MODE
593 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
594 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500596 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000597 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500598 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 +0000599 return err;
600 }
601 return flow_cfg.data.ingress_intf.intf_type;
602 case EGRESS_INTF_TYPE: //egress intf_type
603 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500604 #ifdef TEST_MODE
605 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
606 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500608 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000609 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500610 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 +0000611 return err;
612 }
613 return flow_cfg.data.egress_intf.intf_type;
614 case INGRESS_INTF_ID: //ingress intf_id
615 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500616 #ifdef TEST_MODE
617 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
618 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000619 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500620 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000621 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500622 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 +0000623 return err;
624 }
625 return flow_cfg.data.ingress_intf.intf_id;
626 case EGRESS_INTF_ID: //egress intf_id
627 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500628 #ifdef TEST_MODE
629 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
630 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000631 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500632 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000633 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500634 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 +0000635 return err;
636 }
637 return flow_cfg.data.egress_intf.intf_id;
638 case CLASSIFIER_O_VID:
639 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500640 #ifdef TEST_MODE
641 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
642 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000643 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500644 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000645 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500646 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 +0000647 return err;
648 }
649 return flow_cfg.data.classifier.o_vid;
650 case CLASSIFIER_O_PBITS:
651 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500652 #ifdef TEST_MODE
653 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
654 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000655 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500656 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000657 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500658 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 +0000659 return err;
660 }
661 return flow_cfg.data.classifier.o_pbits;
662 case CLASSIFIER_I_VID:
663 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500664 #ifdef TEST_MODE
665 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
666 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000667 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500668 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000669 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500670 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 +0000671 return err;
672 }
673 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400674 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000675 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500676 #ifdef TEST_MODE
677 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
678 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000679 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500680 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000681 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500682 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 +0000683 return err;
684 }
685 return flow_cfg.data.classifier.i_pbits;
686 case CLASSIFIER_ETHER_TYPE:
687 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500688 #ifdef TEST_MODE
689 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
690 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000691 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500692 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000693 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500694 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 +0000695 return err;
696 }
697 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400698 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500700 #ifdef TEST_MODE
701 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
702 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000703 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500704 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000705 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500706 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 +0000707 return err;
708 }
709 return flow_cfg.data.classifier.ip_proto;
710 case CLASSIFIER_SRC_PORT:
711 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500712 #ifdef TEST_MODE
713 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
714 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000715 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500716 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000717 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500718 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 +0000719 return err;
720 }
721 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400722 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000723 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500724 #ifdef TEST_MODE
725 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
726 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000727 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500728 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000729 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500730 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 +0000731 return err;
732 }
733 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400734 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000735 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500736 #ifdef TEST_MODE
737 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
738 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000739 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500740 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000741 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500742 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 +0000743 return err;
744 }
745 return flow_cfg.data.classifier.pkt_tag_type;
746 case EGRESS_QOS_TYPE:
747 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500748 #ifdef TEST_MODE
749 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
750 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000751 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500752 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000753 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500754 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 +0000755 return err;
756 }
757 return flow_cfg.data.egress_qos.type;
758 case EGRESS_QOS_QUEUE_ID:
759 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500760 #ifdef TEST_MODE
761 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
762 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000763 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500764 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000765 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500766 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 +0000767 return err;
768 }
769 switch (flow_cfg.data.egress_qos.type) {
770 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
771 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
772 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
773 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
774 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
775 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
776 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
777 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
778 case BCMOLT_EGRESS_QOS_TYPE_NONE:
779 default:
780 return -1;
781 }
782 case EGRESS_QOS_TM_SCHED_ID:
783 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500784 #ifdef TEST_MODE
785 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
786 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000787 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500788 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000789 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500790 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 +0000791 return err;
792 }
793 return flow_cfg.data.egress_qos.tm_sched.id;
794 case ACTION_CMDS_BITMASK:
795 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500796 #ifdef TEST_MODE
797 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
798 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000799 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500800 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000801 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500802 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 +0000803 return err;
804 }
805 return flow_cfg.data.action.cmds_bitmask;
806 case ACTION_O_VID:
807 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500808 #ifdef TEST_MODE
809 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
810 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000811 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500812 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000813 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500814 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 +0000815 return err;
816 }
817 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400818 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000819 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500820 #ifdef TEST_MODE
821 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
822 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000823 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500824 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000825 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500826 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 +0000827 return err;
828 }
829 return flow_cfg.data.action.o_pbits;
830 case ACTION_I_VID:
831 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500832 #ifdef TEST_MODE
833 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
834 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000835 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500836 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000837 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500838 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 +0000839 return err;
840 }
841 return flow_cfg.data.action.i_vid;
842 case ACTION_I_PBITS:
843 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500844 #ifdef TEST_MODE
845 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
846 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000847 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500848 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000849 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500850 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 +0000851 return err;
852 }
853 return flow_cfg.data.action.i_pbits;
854 case STATE:
855 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500856 #ifdef TEST_MODE
857 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
858 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000859 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500860 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000861 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500862 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000863 return err;
864 }
865 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000866 case GROUP_ID:
867 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
868 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
869 if (err) {
870 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
871 return err;
872 }
873 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000874 default:
875 return BCM_ERR_INTERNAL;
876 }
877
878 return err;
879}
880
881Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400882 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000883 bcmolt_pon_interface_cfg interface_obj;
884 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
885 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
886 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530887 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000888
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530889 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000890 if (err == BCM_ERR_OK) {
891 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800892 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000893 return Status::OK;
894 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400895 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000896 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
897 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
898 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
899 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
900 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700901 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000902 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
903 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
904 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
905 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
906 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
907 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000908
909 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
910 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
911 if (board_technology == "GPON") {
912 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
913 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
914 }
915
kesavandc1f2db92020-08-31 15:32:06 +0530916 //Enable AES Encryption
917 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
918 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
919 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
920
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000921 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
922 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
923
924 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
925 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500926 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 +0000927 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
928 }
929 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
930 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500931 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 +0000932 return bcm_to_grpc_err(err, "Failed to enable PON interface");
933 }
934 else {
935 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
936 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
937 CreateDefaultSched(intf_id, downstream);
938 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400939 }
940
941 return Status::OK;
942}
943
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500944Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000945 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400946 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000947 bcmolt_device_key dev_key = { };
948 bcmolt_olt_cfg olt_cfg = { };
949 bcmolt_olt_key olt_key = { };
950 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
951 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500952
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000953 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
954 topo.topology_maps.arr = &topo_map[0];
955 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
956 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
957 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400958 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000959 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400960 #ifdef TEST_MODE
961 // It is impossible to mock the setting of olt_cfg.data.bal_state because
962 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
963 // set the olt_cfg.data.topology. So a new stub function is created and address
964 // of olt_cfg is passed. This is one-of case where we need to test add specific
965 // code in production code.
966 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
967 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000968 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400969 #endif
970 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500971 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 +0000972 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500973 }
974
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000975 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
976 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500977
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400978 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
979 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000980 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500981
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000982 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
983 num_of_nni_ports,
984 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400985 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500986
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000987 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800988 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000989 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
990 dev_key.device_id = devid;
991 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
992 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
993 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
994 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000995 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400996 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500997 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 +0000998 num_failed_cfg_gets++;
999 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001000 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001001
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001002 std::string bal_version;
1003 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1004 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1005 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001006 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001007
1008 switch(dev_cfg.data.system_mode) {
1009 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1010 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1011 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1012 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1013 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1014 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1015 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1016 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1017 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1018 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1019 }
1020
1021 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001022 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1023 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001024 }
1025
Jason Huang09b73ea2020-01-08 17:52:05 +08001026 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1027 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 +00001028
1029 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001030 }
1031
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001032 /* 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 +00001033 only the devices that retured success*/
1034 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1035 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1036 return bcm_to_grpc_err(err, "device: All devices failed query");
1037 }
1038
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001039 return Status::OK;
1040}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001041
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001042Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001043 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001044 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1045 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1046 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001047
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001048 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001049 if (err == BCM_ERR_OK) {
1050 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001051 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001052 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1053 CreateDefaultSched(intf_id, upstream);
1054 CreateDefaultQueue(intf_id, upstream);
1055 return Status::OK;
1056 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1057 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1058 return Status::OK;
1059 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001060 }
1061
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001062 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1063 if (set_state) {
1064 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1065 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1066 } else {
1067 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1068 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1069 }
1070 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1071 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001072 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1073 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001074 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1075 }
1076 else {
1077 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1078 if (set_state) {
1079 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1080 CreateDefaultSched(intf_id, upstream);
1081 CreateDefaultQueue(intf_id, upstream);
1082 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001083 }
1084
1085 return Status::OK;
1086}
1087
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001088Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001089 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001090 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001091 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1092 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001093
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001094 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001095 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1096
1097 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1098 if (err != BCM_ERR_OK) {
1099 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch pon port status, PON interface %d, err %d err_text=%s \n", intf_id, err, interface_obj.hdr.hdr.err_text);
1100 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1101 }
1102 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1103 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1104 return Status::OK;
1105 }
1106
1107 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001108 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1109 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1110
1111 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1112 if (err != BCM_ERR_OK) {
1113 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1114 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1115 }
1116
1117 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1118 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1119
1120 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1121 if (err != BCM_ERR_OK) {
1122 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 -04001123 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001124 }
1125
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001126 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001127 return Status::OK;
1128}
1129
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001130Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301131 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001132 bcmos_errno err = BCM_ERR_OK;
1133 bcmolt_onu_cfg onu_cfg;
1134 bcmolt_onu_key onu_key;
1135 bcmolt_serial_number serial_number; /**< ONU serial number */
1136 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001137
Girish Gowdra24297032020-03-23 12:32:37 -07001138 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1139 bcmolt_onu_state onu_state;
1140
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001141 onu_key.onu_id = onu_id;
1142 onu_key.pon_ni = intf_id;
1143 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1144 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001145#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001146 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1147 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1148 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1149 // of onu_cfg is passed. This is one-of case where we need to add test specific
1150 // code in production code.
1151 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001152#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001153 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001154#endif
1155 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1156 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001157 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001158 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1159 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1160not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001161 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001162 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1163 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1164 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1165 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1166state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1167 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1168 }
1169 } else {
1170 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1171 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1172 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001173 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001174
Girish Gowdra24297032020-03-23 12:32:37 -07001175 // If the ONU is not configured at all we need to first configure it
1176 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1177 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001178vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001179 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001180
Girish Gowdra24297032020-03-23 12:32:37 -07001181 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1182 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1183 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1184 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1185 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1186 /*set burst and data profiles to fec disabled*/
1187 if (board_technology == "XGS-PON") {
1188 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1189 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1190 } else if (board_technology == "GPON") {
1191 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1192 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1193 }
1194 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1195 if (err != BCM_ERR_OK) {
1196 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1197 return bcm_to_grpc_err(err, "Failed to configure ONU");
1198 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001199 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001200
Burak Gurdaga0523592021-02-24 15:17:47 +00001201// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301202 if (omcc_encryption_mode == true) {
1203 // set the encryption mode for omci port id
1204 bcmolt_itupon_gem_cfg gem_cfg;
1205 bcmolt_itupon_gem_key key = {};
1206 bcmolt_gem_port_configuration configuration = {};
1207 key.pon_ni = intf_id;
1208 key.gem_port_id = onu_id;
1209 bcmolt_control_state encryption_mode;
1210 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1211 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1212 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1213 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1214 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001215 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301216 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1217 }
1218 }
Girish Gowdra24297032020-03-23 12:32:37 -07001219 // Now that the ONU is configured, move the ONU to ACTIVE state
1220 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1221 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1222 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1223 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1224 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1225 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1226 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001227 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001228 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 +00001229 return bcm_to_grpc_err(err, "Failed to activate ONU");
1230 }
Girish Gowdra24297032020-03-23 12:32:37 -07001231 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1232 // ONU_ACTIVATION_COMPLETED_INDICATION
1233
1234 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 +00001235
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001236 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001237}
1238
Jonathan Davis70c21812018-07-19 15:32:10 -04001239Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1240 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001241 bcmos_errno err = BCM_ERR_OK;
1242 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1243 bcmolt_onu_cfg onu_cfg;
1244 bcmolt_onu_key onu_key; /**< Object key. */
1245 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001246
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001247 onu_key.onu_id = onu_id;
1248 onu_key.pon_ni = intf_id;
1249 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1250 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001251 #ifdef TEST_MODE
1252 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1253 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1254 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1255 // of onu_cfg is passed. This is one-of case where we need to add test specific
1256 // code in production code.
1257 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001258 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001259 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001260 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301261 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001262 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001263 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001264 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001265 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001266 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001267 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1268 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1269 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001270 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 +00001271 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1272 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301273 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 +00001274 break;
1275 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001276 }
1277
1278 return Status::OK;
1279}
1280
1281Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001282 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301283 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301284 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001285
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001286 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 -05001287 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1288
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001289 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001290 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301291
1292 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1293 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001294 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1295 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1296 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301297 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1298 if (err) {
1299 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1300 intf_id, onu_id);
1301 return bcm_to_grpc_err(err, "Failed to delete ONU");
1302 }
1303 }
Girish Gowdra24297032020-03-23 12:32:37 -07001304 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301305 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1306 intf_id);
1307 }
1308 }
1309 else {
1310 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1311 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301312 return bcm_to_grpc_err(err, "Failed to delete ONU");
1313 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001314
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001315 bcmolt_onu_cfg cfg_obj;
1316 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001317
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001318 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 -04001319 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001321 key.onu_id = onu_id;
1322 key.pon_ni = intf_id;
1323 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001324
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301325 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001326 if (err != BCM_ERR_OK)
1327 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001328 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 -04001329 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1330 }
1331
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301332 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 +00001333 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001334}
1335
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001336#define MAX_CHAR_LENGTH 20
1337#define MAX_OMCI_MSG_LENGTH 44
1338Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001339 bcmolt_bin_str buf = {};
1340 bcmolt_onu_cpu_packets omci_cpu_packets;
1341 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001342
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001343 key.pon_ni = intf_id;
1344 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001345
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001346 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1347 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1348 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001349
1350 // ???
1351 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1352 buf.len = MAX_OMCI_MSG_LENGTH;
1353 } else {
1354 buf.len = pkt.size()/2;
1355 }
1356
1357 /* Send the OMCI packet using the BAL remote proxy API */
1358 uint16_t idx1 = 0;
1359 uint16_t idx2 = 0;
1360 uint8_t arraySend[buf.len];
1361 char str1[MAX_CHAR_LENGTH];
1362 char str2[MAX_CHAR_LENGTH];
1363 memset(&arraySend, 0, buf.len);
1364
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001365 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1366 sprintf(str1,"%c", pkt[idx1]);
1367 sprintf(str2,"%c", pkt[++idx1]);
1368 strcat(str1,str2);
1369 arraySend[idx2] = strtol(str1, NULL, 16);
1370 }
1371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001372 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1373 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001374
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001375 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1376 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1377 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001378
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001379 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001380 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001381 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 +00001382 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001383 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001384 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 -05001385 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001386 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001387 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001388
1389 return Status::OK;
1390}
1391
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001392Status 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 +00001393 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1394 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1395 bcmolt_bin_str buf = {};
1396 bcmolt_gem_port_id gem_port_id_array[1];
1397 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001398
Craig Lutgen967a1d02018-11-27 10:41:51 -06001399 if (port_no > 0) {
1400 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001401 if (gemport_id == 0) {
1402 bcmos_fastlock_lock(&data_lock);
1403 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1404 // Pick any flow that is mapped with the same port_no.
1405 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1406 if (it != port_to_flows.end() && !it->second.empty()) {
1407 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1408 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1409 if (fit != flowid_to_gemport.end()) {
1410 found = true;
1411 gemport_id = fit->second;
1412 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001413 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001414 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001415
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001416 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001417 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 -08001418 onu_id, port_no, intf_id);
1419 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1420 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001421 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 -08001422 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001423 }
1424
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001425 gem_port_id_array[0] = gemport_id;
1426 gem_port_list.len = 1;
1427 gem_port_list.arr = gem_port_id_array;
1428 buf.len = pkt.size();
1429 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1430 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1431
1432 /* init the API struct */
1433 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1434 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1435 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1436 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1437 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1438
1439 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1440 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1441
1442 /* call API */
1443 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001444 }
1445 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001446 //TODO: Port No is 0, it is coming sender requirement.
1447 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1448 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001449 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001450 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001451
1452 return Status::OK;
1453}
1454
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001455Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001456 bcmolt_flow_key key = {}; /* declare key */
1457 bcmolt_bin_str buffer = {};
1458 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001459
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001460 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001461 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001462
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001463 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1464 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1465 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1466 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1467 key.flow_id = flow_id;
1468 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001469 if (flow_id_counters) {
1470 std::map<flow_pair, int>::iterator it;
1471 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1472 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001473 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1474 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1475 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1476 key.flow_id = flow_index;
1477 break;
1478 }
1479 }
1480 }
1481 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001482 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001483 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1484 }
1485 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001486
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001487 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001488
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001489 /* Initialize the API struct. */
1490 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001491
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001492 buffer.len = pkt.size();
1493 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1494 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1495 if (buffer.arr == NULL) {
1496 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1497 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1498 }
1499 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1500
1501 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1502 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001503 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 -05001504 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001505 } else {
1506 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1507 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001508
1509 return Status::OK;
1510}
Girish Gowdra252f4972020-09-07 21:24:01 -07001511
Burak Gurdaga0523592021-02-24 15:17:47 +00001512bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1513 bool aes_flag = false;
1514 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1515 if (it->first == gemport_id) {
1516 aes_flag = it->second;
1517 break;
1518 }
1519 }
1520 return aes_flag;
1521}
1522
Girish Gowdra252f4972020-09-07 21:24:01 -07001523Status FlowAddWrapper_(const ::openolt::Flow* request) {
1524
1525 int32_t access_intf_id = request->access_intf_id();
1526 int32_t onu_id = request->onu_id();
1527 int32_t uni_id = request->uni_id();
1528 uint32_t port_no = request->port_no();
1529 uint64_t voltha_flow_id = request->flow_id();
1530 uint64_t symmetric_voltha_flow_id = request->symmetric_flow_id();
1531 const std::string flow_type = request->flow_type();
1532 int32_t alloc_id = request->alloc_id();
1533 int32_t network_intf_id = request->network_intf_id();
1534 int32_t gemport_id = request->gemport_id();
1535 const ::openolt::Classifier& classifier = request->classifier();
1536 const ::openolt::Action& action = request->action();
1537 int32_t priority = request->priority();
1538 uint64_t cookie = request->cookie();
1539 int32_t group_id = request->group_id();
1540 uint32_t tech_profile_id = request->tech_profile_id();
1541 bool replicate_flow = request->replicate_flow();
1542 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001543 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001544 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001545 bool enable_encryption;
Girish Gowdra252f4972020-09-07 21:24:01 -07001546
1547 // The intf_id variable defaults to access(PON) interface ID.
1548 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1549 // This intf_id identifies the pool from which we get the flow_id
1550 uint32_t intf_id = access_intf_id;
1551 if (onu_id < 1) {
1552 onu_id = 1;
1553 }
1554 if (access_intf_id < 0) {
1555 intf_id = network_intf_id;
1556 }
1557
1558 OPENOLT_LOG(INFO, openolt_log_id, "received flow add. voltha_flow_id=%lu, symmetric_voltha_flow_id=%lu, replication=%d\n", voltha_flow_id, symmetric_voltha_flow_id, replicate_flow)
1559 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1560 if (is_voltha_flow_installed(voltha_flow_id)) {
1561 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1562 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1563 }
1564
Girish Gowdra252f4972020-09-07 21:24:01 -07001565 // This is the case of symmetric_voltha_flow_id
1566 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1567 // check if it is installed, and use the corresponding device_flow_id
1568 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1569 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1570 const device_flow_params *dev_fl_symm_params;
1571 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1572 if (dev_fl_symm_params == NULL) {
1573 OPENOLT_LOG(ERROR, openolt_log_id, "symmetric flow device params not found symm-voltha-flow=%lu voltha-flow=%lu\n", symmetric_voltha_flow_id, voltha_flow_id)
1574 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1575 }
1576
1577 if (!replicate_flow) { // No flow replication
1578 flow_id = dev_fl_symm_params[0].flow_id;
1579 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1580 // Should be same as what is coming in this request.
Burak Gurdaga0523592021-02-24 15:17:47 +00001581 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001582 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1583 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1584 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1585 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001586 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001587 if (st.error_code() == grpc::StatusCode::OK) {
1588 device_flow dev_fl;
1589 dev_fl.is_flow_replicated = false;
1590 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1591 dev_fl.voltha_flow_id = voltha_flow_id;
1592 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1593 // update voltha flow to cache
1594 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1595 }
1596 return st;
1597 } else { // Flow to be replicated
1598 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1599 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1600 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1601 flow_id = dev_fl_symm_params[i].flow_id;
1602 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001603 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001604 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
1605 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001606 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001607 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001608 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1609 OPENOLT_LOG(ERROR, openolt_log_id, "failed to install device flow=%u for voltha flow=%lu. Undoing any device flows installed.", flow_id, voltha_flow_id);
1610 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1611 if (i > 0) {
1612 for (int8_t j = i-1; j >= 0; j--) {
1613 flow_id = dev_fl_symm_params[j].flow_id;
1614 FlowRemove_(flow_id, flow_type);
1615 }
1616 }
1617 return st;
1618 }
1619 }
1620 device_flow dev_fl;
1621 dev_fl.is_flow_replicated = true;
1622 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1623 dev_fl.voltha_flow_id = voltha_flow_id;
1624 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1625 // update voltha flow to cache
1626 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1627 }
1628 } else { // No symmetric flow found
1629 if (!replicate_flow) { // No flow replication
1630 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1631 flow_id = get_flow_id();
1632 if (flow_id == INVALID_FLOW_ID) {
1633 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1634 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1635 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001636 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001637 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1638 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001639 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001640 if (st.error_code() == grpc::StatusCode::OK) {
1641 device_flow dev_fl;
1642 dev_fl.is_flow_replicated = false;
1643 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1644 dev_fl.voltha_flow_id = voltha_flow_id;
1645 dev_fl.params[0].flow_id = flow_id;
1646 dev_fl.params[0].gemport_id = gemport_id;
1647 dev_fl.params[0].pbit = classifier.o_pbits();
1648 // update voltha flow to cache
1649 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1650 } else {
1651 // Free the flow id on failure
1652 free_flow_id(flow_id);
1653 }
1654 return st;
1655 } else { // Flow to be replicated
1656 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1657 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1658 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1659 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1660 }
1661 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1662 device_flow dev_fl;
1663 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1664 uint8_t cnt = 0;
1665 dev_fl.is_flow_replicated = true;
1666 dev_fl.voltha_flow_id = voltha_flow_id;
1667 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1668 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1669 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1670 dev_fl.params[cnt].pbit = it->first;
1671 dev_fl.params[cnt].gemport_id = it->second;
1672
1673 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1674 flow_id = dev_fl.params[cnt].flow_id;
1675 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001676 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001677 cl.set_o_pbits(dev_fl.params[cnt].pbit);
1678 Status st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1679 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001680 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001681 if (st.error_code() != grpc::StatusCode::OK) {
1682 OPENOLT_LOG(ERROR, openolt_log_id, "failed to install device flow=%u for voltha flow=%lu. Undoing any device flows installed.", flow_id, voltha_flow_id);
1683 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1684 if (cnt > 0) {
1685 for (int8_t j = cnt-1; j >= 0; j--) {
1686 flow_id = dev_fl.params[j].flow_id;
1687 FlowRemove_(flow_id, flow_type);
1688 }
1689 }
1690 // Free up all the flow IDs on failure
1691 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1692 return st;
1693 }
1694 cnt++;
1695 }
1696 // On successful flow replication update voltha-flow-id to device-flow map to cache
1697 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1698 } else {
1699 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1700 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1701 }
1702 }
1703 }
1704
1705 return Status::OK;
1706}
1707
1708
Craig Lutgen967a1d02018-11-27 10:41:51 -06001709Status 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 +00001710 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001711 int32_t alloc_id, int32_t network_intf_id,
1712 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001713 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001714 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001715 bcmolt_flow_cfg cfg;
1716 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001717 int32_t o_vid = -1;
1718 bool single_tag = false;
1719 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001720 bcmolt_classifier c_val = { };
1721 bcmolt_action a_val = { };
1722 bcmolt_tm_queue_ref tm_val = { };
1723 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001724 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001725
Jason Huang09b73ea2020-01-08 17:52:05 +08001726 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1727
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001728 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001729 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001730 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001731 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001732 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001733 } else if (flow_type.compare(multicast) == 0) {
1734 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001735 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001736 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001737 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001738 }
1739
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001740 BCMOLT_CFG_INIT(&cfg, flow, key);
1741 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001742
Jason Huang09b73ea2020-01-08 17:52:05 +08001743 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001744 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001745 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001746 return resp;
1747 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001748
1749 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1750
1751 if (access_intf_id >= 0 && network_intf_id >= 0) {
1752 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1753 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1754 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001755 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1756 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001757 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1758 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1759 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1760 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1761 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001762 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001763 } else {
1764 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1765 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001766 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001767
Burak Gurdaga0523592021-02-24 15:17:47 +00001768 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001769 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1770 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001771 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001772 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1773 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001774 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001775 bcmos_fastlock_lock(&data_lock);
1776 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1777 port_to_flows[port_no].insert(key.flow_id);
1778 flowid_to_gemport[key.flow_id] = gemport_id;
1779 }
1780 else
1781 {
1782 flowid_to_port[key.flow_id] = port_no;
1783 }
1784 bcmos_fastlock_unlock(&data_lock, 0);
1785 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001786
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001787 if (priority_value >= 0) {
1788 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1789 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301790
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001791 } else { // MULTICAST FLOW
1792 if (group_id >= 0) {
1793 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001794 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001795 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1796 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001797 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001798
1799 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001800 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001801 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001802 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1803 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001804 }
1805
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001806 if (classifier.dst_mac().size() > 0) {
1807 bcmos_mac_address d_mac = {};
1808 bcmos_mac_address_init(&d_mac);
1809 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1810 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1811 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1812 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001813 }
1814
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001815 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001816 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001817 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001818 }
1819 */
1820
1821 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001822 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1823 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001824 }
1825
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001826 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001827 bcmos_ipv4_address d_ip = {};
1828 bcmos_ipv4_address_init(&d_ip);
1829 d_ip.u32 = classifier.dst_ip();
1830 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1831 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001832 }
1833
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001834 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001835 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001836 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001837 }
1838 */
1839
1840 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001841 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1842 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001843 }
1844
1845 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001846 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1847 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001848 }
1849
1850 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001851 if (classifier.o_vid()) {
1852 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1853 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1854 }
1855
1856 if (classifier.i_vid()) {
1857 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1858 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1859 }
1860
1861 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1862 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1863 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1864 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1865 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1866 single_tag = true;
1867
1868 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301869 // OpenOlt adapter will send 0xFF in case of no pbit classification
1870 // If it is any other value (0 to 7), it is for outer pbit classification.
1871 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1872 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1873 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1874 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001875 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301876 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001877 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1878 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001879
Jason Huang09b73ea2020-01-08 17:52:05 +08001880 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301881 // Same comments as in case of "single_tag" packets.
1882 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1883 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001884 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301885 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001886 }
1887 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001888 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001889 }
1890
Jason Huang09b73ea2020-01-08 17:52:05 +08001891 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001892
Jason Huang09b73ea2020-01-08 17:52:05 +08001893 if (cmd.add_outer_tag()) {
1894 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1895 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001896 }
1897
Jason Huang09b73ea2020-01-08 17:52:05 +08001898 if (cmd.remove_outer_tag()) {
1899 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1900 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1901 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301902
Jason Huang09b73ea2020-01-08 17:52:05 +08001903 if (action.o_vid()) {
1904 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1905 o_vid = action.o_vid();
1906 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1907 }
1908
1909 if (action.o_pbits()) {
1910 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1911 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1912 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301913
Jason Huang09b73ea2020-01-08 17:52:05 +08001914 if (action.i_vid()) {
1915 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1916 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1917 }
1918
1919 if (action.i_pbits()) {
1920 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1921 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1922 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301923
Jason Huang09b73ea2020-01-08 17:52:05 +08001924 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1925
Burak Gurdaga0523592021-02-24 15:17:47 +00001926 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001927 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1928 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001929 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 +00001930
Jason Huang09b73ea2020-01-08 17:52:05 +08001931 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1932 // Queue 0 on DS subscriber scheduler
1933 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001934
Jason Huang09b73ea2020-01-08 17:52:05 +08001935 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1936 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1937 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001938
Jason Huang09b73ea2020-01-08 17:52:05 +08001939 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1940 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1941 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001942
Jason Huang09b73ea2020-01-08 17:52:05 +08001943 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1944 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1945 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 +00001946
Jason Huang09b73ea2020-01-08 17:52:05 +08001947 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1948 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1949 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1950 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 +00001951
Jason Huang09b73ea2020-01-08 17:52:05 +08001952 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1953 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1954 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1955 }
1956 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1957 // NNI Scheduler ID
1958 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1959 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1960 // Queue 0 on NNI scheduler
1961 tm_val.queue_id = 0;
1962 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1963 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1964 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001965
Jason Huang09b73ea2020-01-08 17:52:05 +08001966 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 +00001967 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1968 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1969
Jason Huang09b73ea2020-01-08 17:52:05 +08001970 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1971 /* Fetch TM QMP ID mapped to US NNI scheduler */
1972 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1973 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1974 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1975 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1976 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 +00001977
Jason Huang09b73ea2020-01-08 17:52:05 +08001978 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 +00001979 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1980 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001981 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001982 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301983 } else {
1984 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1985 tm_val.queue_id = 0;
1986
1987 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1988 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1989 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1990
1991 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1992 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1993 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001994 }
1995
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001996 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001997
Girish Gowdra252f4972020-09-07 21:24:01 -07001998#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001999 // BAL 3.1 supports statistics only for unicast flows.
2000 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2001 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2002 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002003#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002004
Girish Gowdra252f4972020-09-07 21:24:01 -07002005#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002006#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002007 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002008 if (flow_id_counters != 0) {
2009 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002010 std::map<flow_pair, int>::iterator it;
2011
2012 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2013 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2014 (key.flow_type == it->first.second) && \
2015 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2016 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2017 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2018 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2019 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2020 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2021 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2022 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2023 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2024 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2025 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2026 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2027 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2028 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2029 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2030 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2031 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2032 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2033 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2034 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2035 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2036 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2037 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2038 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2039 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2040 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002041#ifdef SHOW_FLOW_PARAM
2042 // Flow Parameter
2043 FLOW_PARAM_LOG();
2044#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045 if (b_duplicate_flow) {
2046 FLOW_LOG(WARNING, "Flow duplicate", 0);
2047 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2048 }
2049 }
2050 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002051#endif // FLOW_CHECKER
2052#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002053
2054 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2055 if (err) {
2056 FLOW_LOG(ERROR, "Flow add failed", err);
2057 return bcm_to_grpc_err(err, "flow add failed");
2058 } else {
2059 FLOW_LOG(INFO, "Flow add ok", err);
2060 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002061 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2062 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002063 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002064
2065 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002066
2067 /*
2068 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2069 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2070 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2071 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2072 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2073 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2074 */
2075 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2076 OPENOLT_LOG(INFO, openolt_log_id, "Setting encryption on pon = %d gem_port = %d through flow_id = %d\n", access_intf_id, gemport_id, flow_id);
2077 enable_encryption_for_gem_port(access_intf_id, gemport_id);
2078 } else {
2079 OPENOLT_LOG(WARNING, openolt_log_id, "Flow config for flow_id = %d is not suitable for setting downstream encryption on pon = %d gem_port = %d. No action taken.\n", flow_id, access_intf_id, gemport_id);
2080 }
2081
Girish Gowdra252f4972020-09-07 21:24:01 -07002082 return Status::OK;
2083}
2084
2085Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
2086 const std::string flow_type = request->flow_type();
2087 uint64_t voltha_flow_id = request->flow_id();
2088 Status st;
2089
2090 // If Voltha flow is not installed, return fail
2091 if (! is_voltha_flow_installed(voltha_flow_id)) {
2092 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2093 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002094 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002095
Girish Gowdra252f4972020-09-07 21:24:01 -07002096 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2097 if (dev_fl == NULL) {
2098 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2099 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2100 }
2101 if (dev_fl->is_flow_replicated) {
2102 // Note: Here we are ignoring FlowRemove failures
2103 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2104 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2105 if (st.error_code() == grpc::StatusCode::OK) {
2106 free_flow_id(dev_fl->params[i].flow_id);
2107 }
2108 }
2109 } else {
2110 // Note: Here we are ignoring FlowRemove failures
2111 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2112 if (st.error_code() == grpc::StatusCode::OK) {
2113 free_flow_id(dev_fl->params[0].flow_id);
2114 }
2115 }
2116 // remove the flow from cache on voltha flow removal
2117 remove_voltha_flow_from_cache(voltha_flow_id);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002118 return Status::OK;
2119}
2120
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002121Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2122
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002123 bcmolt_flow_cfg cfg;
2124 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002125
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002126 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002127 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002128 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002129 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002130 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002131 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002132 } else if(flow_type.compare(multicast) == 0) {
2133 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002134 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002135 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002136 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2137 }
2138
Jason Huang09b73ea2020-01-08 17:52:05 +08002139 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2140 flow_id, flow_type.c_str());
2141
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002142 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002143 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2144 int32_t gemport_id = -1;
2145 int32_t intf_id = -1;
2146 int16_t acl_id = -1;
2147 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002148
2149 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2150 acl_id = std::get<0>(ac_id_if_id);
2151 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002152 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2153 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002154 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002155 if (resp.ok()) {
2156 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2157 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002158
2159 // When flow is being removed, extract the value corresponding to flow_id from trap_to_host_pkt_info_with_vlan_for_flow_id if it exists
2160 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2161 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2162 // Formulate the trap_to_host_pkt_info tuple key
2163 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2164 std::get<1>(pkt_info_with_vlan),
2165 std::get<2>(pkt_info_with_vlan),
2166 std::get<3>(pkt_info_with_vlan));
2167 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2168 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2169 // Remove the vlan_id from the list that corresponded to the flow being removed.
2170 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2171 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2172 } else {
2173 OPENOLT_LOG(ERROR, openolt_log_id, "trap-to-host with intf_type = %d, intf_id = %d, pkt_type = %d gemport_id = %d not found in trap_to_host_vlan_ids_for_trap_to_host_pkt_info map",
2174 std::get<0>(pkt_info_with_vlan), std::get<1>(pkt_info_with_vlan), std::get<2>(pkt_info_with_vlan), std::get<3>(pkt_info_with_vlan));
2175 }
2176
2177 } else {
2178 OPENOLT_LOG(ERROR, openolt_log_id, "flow id = %u not found in trap_to_host_pkt_info_with_vlan_for_flow_id map", flow_id);
2179 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002180 } else {
2181 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2182 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002183 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002184 return resp;
2185 }
2186 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002187 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002188
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002189 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002190 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002191 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002192 flowid_to_gemport.erase(key.flow_id);
2193 port_to_flows[port_no].erase(key.flow_id);
2194 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2195 }
2196 else
2197 {
2198 flowid_to_port.erase(key.flow_id);
2199 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002200 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002201
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002202 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002203
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002204 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002205 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002206 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 -04002207 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2208 }
2209
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002210 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002211 if (flow_id_counters != 0) {
2212 std::map<flow_pair, int>::iterator it;
2213 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2214 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2215 flow_id_counters -= 1;
2216 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002217 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002218 }
2219 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002220 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2221
Jason Huang09b73ea2020-01-08 17:52:05 +08002222 flow_to_acl_map.erase(fl_id_fl_dir);
2223
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002224 bcmos_fastlock_unlock(&data_lock, 0);
2225
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002226 return Status::OK;
2227}
2228
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002229bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2230 bcmos_errno err;
2231 bcmolt_tm_sched_cfg tm_sched_cfg;
2232 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2233 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2234
Jason Huangbf45ffb2019-10-30 17:29:02 +08002235 //check TM scheduler has configured or not
2236 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2237 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002238 #ifdef TEST_MODE
2239 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2240 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2241 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2242 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2243 // code in production code.
2244 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2245 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002246 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002247 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002248 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002249 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 +08002250 return err;
2251 }
2252 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2253 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2254 return BCM_ERR_OK;
2255 }
2256
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002257 // bcmbal_tm_sched_owner
2258 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2259
2260 /**< The output of the tm_sched object instance */
2261 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2262
2263 if (direction.compare(upstream) == 0) {
2264 // In upstream it is NNI scheduler
2265 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2266 } else if (direction.compare(downstream) == 0) {
2267 // In downstream it is PON scheduler
2268 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2269 }
2270
2271 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2272
2273 // bcmbal_tm_sched_type
2274 // set the deafult policy to strict priority
2275 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2276
2277 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002278 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002279
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002280 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2281 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002282 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2283 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002284 return err;
2285 }
2286
2287 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2288 direction.c_str(), tm_sched_key.id, intf_id);
2289 return BCM_ERR_OK;
2290}
2291
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002292bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
Girish Gowdra252f4972020-09-07 21:24:01 -07002293 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2294 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002295 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002296
2297 bcmos_errno err;
2298
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002299 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002300 bcmolt_tm_sched_cfg tm_sched_cfg;
2301 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002302 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 -04002303
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002304 // bcmbal_tm_sched_owner
2305 // In downstream it is sub_term scheduler
2306 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002307
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002308 /**< The output of the tm_sched object instance */
2309 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002310
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002311 // bcmbal_tm_sched_parent
2312 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2313 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2314 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 +00002315 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316 be achieved using the' virtual' type of attachment.
2317 tm_sched_owner.u.sub_term.intf_id = intf_id;
2318 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2319 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002320
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002321 // bcmbal_tm_sched_type
2322 // set the deafult policy to strict priority
2323 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002324
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002325 // num_priorities: Max number of strict priority scheduling elements
2326 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002327
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002328 // bcmbal_tm_shaping
2329 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2330 uint32_t cir = tf_sh_info.cir();
2331 uint32_t pir = tf_sh_info.pir();
2332 uint32_t burst = tf_sh_info.pbs();
2333 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2334 cir, pir, burst);
2335 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2336 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2337 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2338 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2339 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2340 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002341 }
2342
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002343 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002344 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002345 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002346intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2347port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002348 return err;
2349 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002350 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2351uni_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 -08002352
2353 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002354 bcmolt_itupon_alloc_cfg cfg;
2355 bcmolt_itupon_alloc_key key = { };
2356 key.pon_ni = intf_id;
2357 key.alloc_id = alloc_id;
2358 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002359 /*
2360 PIR: Maximum Bandwidth
2361 CIR: Assured Bandwidth
2362 GIR: Fixed Bandwidth
2363 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002364 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2365 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002366 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2367 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002368 //offset to match bandwidth granularity
2369 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002370 int offset_gir_bw = gir_bw%bw_granularity;
2371 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002372
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002373 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002374 gir_bw = gir_bw - offset_gir_bw;
2375 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002376
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002377 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002378
Burak Gurdag623fada2021-04-20 22:02:36 +00002379 OPENOLT_LOG(INFO, openolt_log_id, "Creating alloc_id %d with pir = %d bytes/sec, cir = %d bytes/sec, gir = %d bytes/sec, additional_bw = %d.\n", alloc_id, pir_bw, cir_bw, gir_bw, additional_bw);
2380
2381 if (pir_bw == 0) {
2382 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2383 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2384 return BCM_ERR_PARM;
2385 } else if (pir_bw < guaranteed_bw) {
2386 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2387 pir_bw, guaranteed_bw);
2388 return BCM_ERR_PARM;
2389 }
2390
2391 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002392 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002393
2394 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2395 if (pir_bw == guaranteed_bw) {
2396 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2397bandwidth for additional bandwidth eligibility of type Best Effort\n");
2398 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002399 }
2400 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2401 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002402
2403 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2404 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002405 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2406additional bandwidth eligibility of type Non-Assured (NA)\n");
2407 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002408 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002409 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002410bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411 return BCM_ERR_PARM;
2412 }
2413 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2414 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002415
2416 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2417 if (guaranteed_bw != pir_bw) {
2418 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002419for additional bandwidth eligibility of type None\n");
2420 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002421 }
2422 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2423 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002424
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002425 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002426 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002427 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002428 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002429
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002430 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2431 in a fine granularity. */
2432 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002433 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2434 gir_bw to cbr_nrt_bw to allow smaller amounts.
2435 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002436 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002437 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002438 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002439 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002440 /* Maximum allocated bandwidth allowed for this alloc ID */
2441 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002442
2443 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2444 // the condition cir_bw == 0 is implicitly satistied
2445 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2446 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2447 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2448 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2449 }
2450
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002451 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002452 for skipped allocations during quiet window */
2453 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2454 /**< Allocation Profile index for CBR non-RT Bandwidth */
2455 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2456 /**< Allocation Profile index for CBR RT Bandwidth */
2457 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2458 /**< Alloc ID Weight used in case of Extended DBA mode */
2459 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2460 /**< Alloc ID Priority used in case of Extended DBA mode */
2461 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2462 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002463
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002464 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002465 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002466 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Burak Gurdag623fada2021-04-20 22:02:36 +00002467port_no %u, alloc_id %d, err = %s (%s)\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err), cfg.hdr.hdr.err_text);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002468 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002469 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002470#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302471 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2472 if (err) {
2473 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2474port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2475 return err;
2476 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002477#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302478
2479 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2480port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2481
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002482 }
2483
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002484 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002485}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002486
Girish Gowdra252f4972020-09-07 21:24:01 -07002487Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002488 uint32_t intf_id = traffic_scheds->intf_id();
2489 uint32_t onu_id = traffic_scheds->onu_id();
2490 uint32_t uni_id = traffic_scheds->uni_id();
2491 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002492 std::string direction;
2493 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002494 ::tech_profile::SchedulerConfig sched_config;
2495 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002496 uint32_t priority;
2497 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002498 ::tech_profile::SchedulingPolicy sched_policy;
2499 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002500 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002501 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002502
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002503 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002504 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002505
2506 direction = GetDirection(traffic_sched.direction());
2507 if (direction.compare("direction-not-supported") == 0)
2508 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2509
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002510 alloc_id = traffic_sched.alloc_id();
2511 sched_config = traffic_sched.scheduler();
2512 additional_bw = sched_config.additional_bw();
2513 priority = sched_config.priority();
2514 weight = sched_config.weight();
2515 sched_policy = sched_config.sched_policy();
2516 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002517 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002518 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002519 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002520 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002521 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002522 return bcm_to_grpc_err(err, "Failed to create scheduler");
2523 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002524 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002525 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002526}
Jonathan Davis70c21812018-07-19 15:32:10 -04002527
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002528bcmos_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 -04002529
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002530 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302531 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302532 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302533 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002534
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002535 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002536 bcmolt_itupon_alloc_cfg cfg;
2537 bcmolt_itupon_alloc_key key = { };
2538 key.pon_ni = intf_id;
2539 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302540 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002541
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002542 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002543 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2544 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002545 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2546 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002547 return err;
2548 }
Girish Gowdra96461052019-11-22 20:13:59 +05302549
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302550 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302551 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302552 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002553#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302554 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 +05302555 intf_id);
2556 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2557 if (err) {
2558 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2559 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2560 return err;
2561 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002562#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302563 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302564 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2565 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2566 intf_id);
2567 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302568 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2569 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2570 intf_id);
2571 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302572 } else {
2573 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 +05302574 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302575 return err;
2576 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002577 } else if (direction == downstream) {
2578 bcmolt_tm_sched_cfg cfg;
2579 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002580
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002581 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2582 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302583 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002584 } else {
2585 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2586 return BCM_ERR_OK;
2587 }
Girish Gowdra96461052019-11-22 20:13:59 +05302588
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002589 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2590 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2591 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002592 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002593intf_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 +00002594 return err;
2595 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002596 }
2597
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002598 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2599 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2600 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002601 return BCM_ERR_OK;
2602}
2603
Girish Gowdra252f4972020-09-07 21:24:01 -07002604Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002605 uint32_t intf_id = traffic_scheds->intf_id();
2606 uint32_t onu_id = traffic_scheds->onu_id();
2607 uint32_t uni_id = traffic_scheds->uni_id();
2608 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002609 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002610 bcmos_errno err;
2611
2612 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002613 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002614
2615 direction = GetDirection(traffic_sched.direction());
2616 if (direction.compare("direction-not-supported") == 0)
2617 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2618
2619 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002620 int tech_profile_id = traffic_sched.tech_profile_id();
2621 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002622 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002623 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002624 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2625 }
2626 }
2627 return Status::OK;
2628}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002629
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002630bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2631 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002632 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002633 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2634 bcmolt_tm_qmp_key tm_qmp_key;
2635 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002636
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002637 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2638 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002639 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2640 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002641 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002642
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002643 tm_qmp_key.id = tm_qmp_id;
2644 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2645 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2646 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002647
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002648 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2649 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2650 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002651 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2652 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002653
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002654 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002655 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002656 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2657 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002658 return err;
2659 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002660
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002661 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2662 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002663 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002664}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002665
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002666bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2667 bcmos_errno err;
2668 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2669 bcmolt_tm_qmp_key tm_qmp_key;
2670 tm_qmp_key.id = tm_qmp_id;
2671
2672 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2673 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2674 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002675 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2676 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002677 return err;
2678 }
2679
2680 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2681 tm_qmp_key.id);
2682 return BCM_ERR_OK;
2683}
2684
2685bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2686 bcmos_errno err;
2687
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002688 /* Create default queues on the given PON/NNI scheduler */
2689 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002690 bcmolt_tm_queue_cfg tm_queue_cfg;
2691 bcmolt_tm_queue_key tm_queue_key = {};
2692 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2693 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002694 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2695 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2696 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002697
2698 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2699 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2700 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2701
2702 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2703 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002704 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", \
2705 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 +00002706 return err;
2707 }
2708
2709 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2710 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2711 }
2712 return BCM_ERR_OK;
2713}
2714
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002715bcmos_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 +00002716 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 +00002717 bcmos_errno err;
2718 bcmolt_tm_queue_cfg cfg;
2719 bcmolt_tm_queue_key key = { };
2720 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 +00002721gemport_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 +00002722
2723 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002724 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002725
2726 if (priority > 7) {
2727 return BCM_ERR_RANGE;
2728 }
2729
2730 /* FIXME: The upstream queues have to be created once only.
2731 The upstream queues on the NNI scheduler are shared by all subscribers.
2732 When the first scheduler comes in, the queues get created, and are re-used by all others.
2733 Also, these queues should be present until the last subscriber exits the system.
2734 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2735
2736 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2737 for each GEM in TECH PROFILE */
2738 key.id = queue_id_list[priority];
2739
2740 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2741 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2742 key.id = 0;
2743 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2744 }
2745 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2746 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2747 }
2748 else {
2749 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2750 }
2751
2752 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2753
2754 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2755 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2756
2757 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2758 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002759 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002760sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2761 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 +00002762 return err;
2763 }
2764
Girish Gowdra252f4972020-09-07 21:24:01 -07002765 if (direction.compare(upstream) == 0) {
2766 Status st = install_gem_port(access_intf_id, onu_id, gemport_id);
2767 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2768 OPENOLT_LOG(ERROR, openolt_log_id, "failed to created gemport=%d, access_intf=%d, onu_id=%d\n", gemport_id, access_intf_id, onu_id);
2769 return BCM_ERR_INTERNAL;
2770 }
2771 }
2772
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002773 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 +00002774intf_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 +00002775 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002776}
2777
Girish Gowdra252f4972020-09-07 21:24:01 -07002778Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002779 uint32_t intf_id = traffic_queues->intf_id();
2780 uint32_t onu_id = traffic_queues->onu_id();
2781 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002782 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002783 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002784 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002785 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002786 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 +00002787
2788 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2789 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2790 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2791 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002792 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002793
2794 direction = GetDirection(traffic_queue.direction());
2795 if (direction.compare("direction-not-supported") == 0)
2796 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2797
2798 queues_priority_q[i] = traffic_queue.priority();
2799 queues_pbit_map[i] = traffic_queue.pbit_map();
2800 }
2801
2802 std::vector<uint32_t> tmq_map_profile(8, 0);
2803 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2804 queues_priority_q, COUNT_OF(queues_priority_q));
2805 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002806 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002807
2808 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2809 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002810 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2811 if (err != BCM_ERR_OK) {
2812 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2813 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2814 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002815 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2816 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2817 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2818 }
2819 }
2820
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002821 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002822 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002823
2824 direction = GetDirection(traffic_queue.direction());
2825 if (direction.compare("direction-not-supported") == 0)
2826 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2827
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002828 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 +00002829
Girish Gowdruf26cf882019-05-01 23:47:58 -07002830 // If the queue exists already, lets not return failure and break the loop.
2831 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002832 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002833 return bcm_to_grpc_err(err, "Failed to create queue");
2834 }
2835 }
2836 return Status::OK;
2837}
2838
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002839bcmos_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 +00002840 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 +00002841 bcmolt_tm_queue_cfg cfg;
2842 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002843 bcmos_errno err;
2844
2845 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002846 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2847 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 +00002848 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002849 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002850 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 -08002851 return BCM_ERR_OK;
2852 }
2853 } else {
Girish Gowdra4fd30672020-11-09 17:23:06 -08002854 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2855 // upstream queue (see CreateQueue function) and it makes sense to delete them when remove the upstream queues.
2856 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2857 // Moreover it also makes sense to remove when upstream queue is getting removed because the upstream queue MUST exist always.
2858 // It is possible that the downstream queues are not created for a subscriber (for ex: upstream EAPoL trap flow only exists
2859 // but no other flow, and in this case only upstream scheduler and queues exist. We do not have a scenario where only downstream
2860 // subscriber flows exist but no upstream )
2861 remove_gem_port(access_intf_id, gemport_id);
2862
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002863 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2864 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002865 return BCM_ERR_OK;
2866 }
2867
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002868 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2869 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2870 // Reset the queue id to 0 when using fixed queue.
2871 key.id = 0;
2872 }
2873 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2874 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2875 }
2876 else {
2877 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2878 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002879
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002880 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2881 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002882 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002883 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2884tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2885 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 -08002886 return err;
2887 }
2888
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002889 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2890intf_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 -08002891
2892 return BCM_ERR_OK;
2893}
2894
Girish Gowdra252f4972020-09-07 21:24:01 -07002895Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002896 uint32_t intf_id = traffic_queues->intf_id();
2897 uint32_t onu_id = traffic_queues->onu_id();
2898 uint32_t uni_id = traffic_queues->uni_id();
2899 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002900 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002901 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002902 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002903 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002904 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 +00002905
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002906 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002907 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002908
2909 direction = GetDirection(traffic_queue.direction());
2910 if (direction.compare("direction-not-supported") == 0)
2911 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2912
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002913 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 -08002914 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002915 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002916 return bcm_to_grpc_err(err, "Failed to remove queue");
2917 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002918 }
2919
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002920 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 +00002921 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002922 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002923
2924 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2925 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002926 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2927 if (err != BCM_ERR_OK) {
2928 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2929 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2930 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002931 }
2932 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002933 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002934 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002935}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002936
Girish Gowdra252f4972020-09-07 21:24:01 -07002937Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002938
2939 bcmos_errno err;
2940 bcmolt_group_key key = {};
2941 bcmolt_group_cfg grp_cfg_obj;
2942 bcmolt_group_members_update grp_mem_upd;
2943 bcmolt_members_update_command grp_mem_upd_cmd;
2944 bcmolt_group_member_info member_info = {};
2945 bcmolt_group_member_info_list_u8 members = {};
2946 bcmolt_intf_ref interface_ref = {};
2947 bcmolt_egress_qos egress_qos = {};
2948 bcmolt_tm_sched_ref tm_sched_ref = {};
2949 bcmolt_action a_val = {};
2950
2951 uint32_t group_id = group_cfg->group_id();
2952
2953 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2954
2955 if (group_id >= 0) {
2956 key.id = group_id;
2957 }
2958 else {
2959 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2960 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2961 }
2962
2963 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2964 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2965
2966 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2967
2968 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2969 if (err != BCM_ERR_OK) {
2970 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2971 return bcm_to_grpc_err(err, "Error in querying group");
2972 }
2973
2974 members.len = group_cfg->members_size();
2975
2976 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2977 // Group type is determined after a flow is assigned to it.
2978 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2979 // Only then we can add members to the group.
2980
2981 // if group does not exist, create it and return.
2982 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2983
2984 if (members.len != 0) {
2985 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);
2986 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2987 } else {
2988
2989 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2990 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2991
2992 /* Setting group actions and action parameters, if any.
2993 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2994 are supported for multicast groups in BAL 3.1.
2995 */
2996 const ::openolt::Action& action = group_cfg->action();
2997 const ::openolt::ActionCmd &cmd = action.cmd();
2998
2999 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3000 if (cmd.remove_outer_tag()) {
3001 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3002 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3003 }
3004
3005 if (cmd.translate_inner_tag()) {
3006 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3007 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3008 }
3009
3010 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3011
3012 if (action.i_vid()) {
3013 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3014 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3015 }
3016
3017 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3018
3019 // Create group
3020 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3021
3022 if (BCM_ERR_OK != err) {
3023 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3024 return bcm_to_grpc_err(err, "Error in creating group");
3025 }
3026
3027 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3028 return Status::OK;
3029 }
3030 }
3031
3032 // The group already exists. Continue configuring it according to the update member command.
3033
3034 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3035
3036 // MEMBER LIST CONSTRUCTION
3037 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3038 // empty list to the group is a legit operation and this actually empties the member list.
3039 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3040
3041 if (!members.arr) {
3042 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3043 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3044 }
3045
3046 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003047 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003048 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003049 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003050 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3051 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3052 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003053 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003054 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3055 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3056 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003057 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003058 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3059 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3060 break;
3061 default :
3062 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3063 bcmos_free(members.arr);
3064 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3065 }
3066
3067 // SET MEMBERS LIST
3068 for (int i = 0; i < members.len; i++) {
3069
Girish Gowdra252f4972020-09-07 21:24:01 -07003070 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003071 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3072 } else {
3073 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3074 }
3075
Girish Gowdra252f4972020-09-07 21:24:01 -07003076 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003077
3078 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003079 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003080 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003081 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003082 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3083 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3084 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003085 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003086 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3087 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3088 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003089 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003090 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3091 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3092 break;
3093 default :
3094 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3095 bcmos_free(members.arr);
3096 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3097 }
3098
3099 // Set member interface id
3100 if (member->interface_id() >= 0) {
3101 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3102 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3103 } else {
3104 bcmos_free(members.arr);
3105 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3106 }
3107
3108 // Set member interface_ref
3109 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3110
3111 // Set member gem_port_id. This must be a multicast gemport.
3112 if (member->gem_port_id() >= 0) {
3113 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3114 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3115 } else {
3116 bcmos_free(members.arr);
3117 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3118 }
3119
3120 // Set member scheduler id and queue_id
3121 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3122 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3123 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3124 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3125
3126 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3127 uint32_t tm_queue_id;
3128 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3129 tm_queue_id = queue_id_list[member->priority()];
3130 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3131 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3132 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3133 } else {
3134 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3135 bcmos_free(members.arr);
3136 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3137 }
3138
3139 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3140 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3141 }
3142
3143 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3144 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3145 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3146
3147 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3148 bcmos_free(members.arr);
3149
3150 if (BCM_ERR_OK != err) {
3151 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);
3152 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3153 }
3154
3155 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3156
3157 return Status::OK;
3158}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003159
3160Status DeleteGroup_(uint32_t group_id) {
3161
3162 bcmos_errno err = BCM_ERR_OK;
3163 bcmolt_group_cfg grp_cfg_obj;
3164 bcmolt_group_key key = {};
3165
3166
3167 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3168
3169 if (group_id >= 0) {
3170 key.id = group_id;
3171 } else {
3172 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3173 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3174 }
3175
3176 /* init the BAL INIT API */
3177 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3178
3179 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3180
3181 // CONFIGURE GROUP MEMBERS
3182 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3183 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3184
3185 if (err != BCM_ERR_OK) {
3186 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3187 return bcm_to_grpc_err(err, "Error in querying group");
3188 }
3189
3190 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3191 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3192 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3193 if (err != BCM_ERR_OK) {
3194 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3195 return bcm_to_grpc_err(err, "Failed to delete group");;
3196 }
3197 } else {
3198 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3199 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3200 }
3201
3202 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3203 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003204}
3205
Girish Gowdra252f4972020-09-07 21:24:01 -07003206Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003207 bcmos_errno err = BCM_ERR_OK;
3208 uint32_t mld = 0;
3209 double LD0;
3210
3211 err = getOnuMaxLogicalDistance(intf_id, &mld);
3212 if (err != BCM_ERR_OK) {
3213 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3214 }
3215
3216 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3217 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3218 response->set_intf_id(intf_id);
3219 response->set_logical_onu_distance_zero(LD0);
3220
3221 return Status::OK;
3222}
3223
Girish Gowdra252f4972020-09-07 21:24:01 -07003224Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003225 bcmos_errno err = BCM_ERR_OK;
3226 bcmolt_itu_onu_params itu = {};
3227 bcmolt_onu_cfg onu_cfg;
3228 bcmolt_onu_key onu_key = {};
3229 uint32_t mld = 0;
3230 double LDi;
3231
3232 onu_key.pon_ni = intf_id;
3233 onu_key.onu_id = onu_id;
3234
3235 err = getOnuMaxLogicalDistance(intf_id, &mld);
3236 if (err != BCM_ERR_OK) {
3237 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3238 }
3239
3240 /* Initialize the API struct. */
3241 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3242 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3243 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3244 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3245 #ifdef TEST_MODE
3246 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3247 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3248 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3249 // of onu_cfg is passed. This is one-of case where we need to add test specific
3250 // code in production code.
3251 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3252 #else
3253 /* Call API function. */
3254 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3255 #endif
3256 if (err != BCM_ERR_OK) {
3257 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to retrieve ONU ranging time for PON %d/ONU id %d, err = %s (%d)\n", intf_id, onu_id, bcmos_strerror(err), err);
3258 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3259 }
3260
3261 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3262 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3263 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3264 }
3265
3266 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3267 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3268 response->set_intf_id(intf_id);
3269 response->set_onu_id(onu_id);
3270 response->set_logical_onu_distance(LDi);
3271
3272 return Status::OK;
3273}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003274
3275Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3276 bcmos_errno err;
3277
3278 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3279
3280 if (err != BCM_ERR_OK) {
3281 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of ONU statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, onu_id, err, bcmos_strerror(err));
3282 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3283 }
3284
3285 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3286 return Status::OK;
3287}
3288
3289Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3290 bcmos_errno err;
3291
3292 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3293
3294 if (err != BCM_ERR_OK) {
3295 OPENOLT_LOG(ERROR, openolt_log_id, "retrieval of GEMPORT statistics failed - PON ID = %u, ONU ID = %u, err = %d - %s", intf_id, gemport_id, err, bcmos_strerror(err));
3296 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3297 }
3298
3299 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3300 return Status::OK;
3301}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003302
3303Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3304 bcmos_errno err = BCM_ERR_OK;
3305
3306 // check the PON intf id
3307 if (intf_id >= MAX_SUPPORTED_PON) {
3308 err = BCM_ERR_PARM;
3309 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3310 intf_id, onu_id);
3311 return bcm_to_grpc_err(err, "invalid pon intf_id");
3312 }
3313
3314 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3315 bcmolt_onu_key onu_key; /**< Object key. */
3316 onu_rssi_compltd_key key(intf_id, onu_id);
3317 Queue<onu_rssi_complete_result> queue;
3318
3319 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3320
3321 onu_key.onu_id = onu_id;
3322 onu_key.pon_ni = intf_id;
3323 /* Initialize the API struct. */
3324 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3325 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3326 if (err == BCM_ERR_OK) {
3327 // initialize map
3328 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3329 onu_rssi_compltd_map.insert({key, &queue});
3330 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3331 } else {
3332 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3333 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3334 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3335 }
3336
3337 onu_rssi_complete_result completed{};
3338 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3339 // invalidate the queue pointer
3340 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3341 onu_rssi_compltd_map[key] = NULL;
3342 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3343 err = BCM_ERR_TIMEOUT;
3344 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3345 intf_id, onu_id);
3346 } else {
3347 OPENOLT_LOG(INFO, openolt_log_id, "RSSI Rx power - intf_id: %d, onu_id: %d, status: %s, fail_reason: %d, rx_power_mean_dbm: %f\n",
3348 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3349
3350 response->set_intf_id(completed.pon_intf_id);
3351 response->set_onu_id(completed.onu_id);
3352 response->set_status(completed.status);
3353 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3354 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3355 }
3356
3357 // Remove entry from map
3358 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3359 onu_rssi_compltd_map.erase(key);
3360 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3361
3362 if (err == BCM_ERR_OK) {
3363 return Status::OK;
3364 } else {
3365 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3366 }
3367}