blob: e72fc3635a0d27036234ef5d21816a7da4ffe5f4 [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);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700273 pool->set_end(ALLOC_ID_END);
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);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +0530365 bcmos_fastlock_init(&gem_cfg_wait_lock, 0);
Girish Gowdra7a79dae2020-02-10 18:22:11 +0530366 bcmos_fastlock_init(&onu_deactivate_wait_lock, 0);
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700367 bcmos_fastlock_init(&acl_packet_trap_handler_lock, 0);
Girish Gowdraeec0fc92021-05-12 15:37:55 -0700368 bcmos_fastlock_init(&symmetric_datapath_flow_id_lock, 0);
369 bcmos_fastlock_init(&pon_gem_to_onu_uni_map_lock, 0);
370
Girish Gowdra1935e6a2020-10-31 21:48:22 -0700371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000372 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600373
Jason Huangbf45ffb2019-10-30 17:29:02 +0800374 //check BCM daemon is connected or not
375 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000376 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800377 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000378 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800379 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000380 Status status = SubscribeIndication();
381 if (!status.ok()) {
382 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
383 grpc_status_code_to_string(status.error_code()).c_str(),
384 status.error_message().c_str());
385 return status;
386 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800387
388 //check BAL state in initial stage
389 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000390 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800391 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000392 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800393 }
394
395 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000396 bcmos_errno err;
397 bcmolt_odid dev;
398 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
399 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400400 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000401 bcmolt_device_key dev_key = { };
402 dev_key.device_id = dev;
403 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
404 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530405
406 /* FIXME: Single Phoenix BAL patch is prepared for all three variants of Radisys OLT
407 * in which BCM_MAX_DEVS_PER_LINE_CARD macro need to be redefined as 1 incase of
408 * "rlt-1600g-w" and "rlt-1600x-w", till then this workaround is required.*/
409 if (dev == 1 && (MODEL_ID == "rlt-1600g-w" || MODEL_ID == "rlt-1600x-w")) {
410 continue;
411 }
412
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000413 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800414 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000415 bcmolt_device_key key = {.device_id = dev};
416 bcmolt_device_connect oper;
417 BCMOLT_OPER_INIT(&oper, device, connect, key);
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530418
419 /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
420 * it retains config from soc file. If openolt agent try to connect device without
421 * device reset device initialization fails hence doing device reset here. */
422 reset_pon_device(dev);
423
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000424 if (MODEL_ID == "asfvolt16") {
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_XGS__2_X);
427 } else if (MODEL_ID == "asgvolt64") {
428 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
429 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
430 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530431 } else if (MODEL_ID == "rlt-3200g-w" || MODEL_ID == "rlt-1600g-w") {
Thiyagarajan Subramani3e8bfd92021-04-26 15:07:14 +0530432 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
433 if(dev == 1) {
434 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
435 }
436 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
437 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
438 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530439 } else if (MODEL_ID == "rlt-1600x-w") {
440 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
441 BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
442 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
443 /* By default setting device mode to GPON for rlt 1600x.
444 In future device mode can be configured to XGSPON || GPON by reading
445 device mode configuration from a static configuration file*/
446 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000447 }
448 err = bcmolt_oper_submit(dev_id, &oper.hdr);
449 if (err) {
450 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500451 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 +0000452 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500453 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 +0000454 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
455 }
456 }
457 bcmos_usleep(200000);
458 }
459 else {
Thiyagarajan Subramani4e62e172021-06-25 17:31:30 +0530460 OPENOLT_LOG(WARNING, openolt_log_id, "PON device %d already connected\n", dev);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000461 state.activate();
462 }
463 }
464 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000465 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000466 }
Shad Ansariedef2132018-08-10 22:14:50 +0000467
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000468 /* Start CLI */
469 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400470 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000471 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400472}
473
474Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400475 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
476 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
477 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
478 //To overcome this disable is implemented by disabling all the PON ports
479 //associated with the device so as to support both in-band
480 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400481
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400482 Status status;
483 int failedCount = 0;
Girish Gowdrae1db2952021-05-04 00:16:54 -0700484 OPENOLT_LOG(INFO, openolt_log_id, "Received disable OLT\n");
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400485 for (int i = 0; i < NumPonIf_(); i++) {
486 status = DisablePonIf_(i);
487 if (!status.ok()) {
488 failedCount+=1;
489 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
490 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400491 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400492 if (failedCount == 0) {
493 state.deactivate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700494 ::openolt::Indication ind;
495 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400496 olt_ind->set_oper_state("down");
497 ind.set_allocated_olt_ind(olt_ind);
498 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
499 oltIndQ.push(ind);
500 return Status::OK;
501 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000502 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400503 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
504 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400505
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400506 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 -0400507}
508
509Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400510 Status status;
511 int failedCount = 0;
512 for (int i = 0; i < NumPonIf_(); i++) {
513 status = EnablePonIf_(i);
514 if (!status.ok()) {
515 failedCount+=1;
516 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
517 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400518 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000519 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400520 state.activate();
Girish Gowdra252f4972020-09-07 21:24:01 -0700521 ::openolt::Indication ind;
522 ::openolt::OltIndication* olt_ind = new ::openolt::OltIndication;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400523 olt_ind->set_oper_state("up");
524 ind.set_allocated_olt_ind(olt_ind);
525 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
526 oltIndQ.push(ind);
527 return Status::OK;
528 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000529 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400530 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
531 }
532 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 +0000533}
534
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000535inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
536 bcmos_errno err;
537 bcmolt_flow_key flow_key;
538 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400539
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000540 flow_key.flow_id = flow_id;
541 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400542
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000543 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400544
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000545 switch (data_id) {
546 case ONU_ID: //onu_id
547 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500548 #ifdef TEST_MODE
549 // It is impossible to mock the setting of flow_cfg.data.state because
550 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
551 // set the flow_cfg.data. So a new stub function is created and address
552 // of flow_cfg is passed. This is one-of case where we need to add test specific
553 // code in production code.
554 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
555 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000556 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500557 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000558 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500559 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000560 return err;
561 }
562 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400563 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500564 #ifdef TEST_MODE
565 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
566 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000567 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500568 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000569 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500570 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571 return err;
572 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400573 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000574 case SVC_PORT_ID: //svc_port_id
575 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500576 #ifdef TEST_MODE
577 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
578 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000579 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500580 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000581 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500582 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 +0000583 return err;
584 }
585 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400586 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000587 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500588 #ifdef TEST_MODE
589 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
590 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000591 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500592 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000593 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500594 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000595 return err;
596 }
597 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400598 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000599 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500600 #ifdef TEST_MODE
601 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
602 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000603 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500604 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000605 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500606 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000607 return err;
608 }
609 return flow_cfg.data.cookie;
610 case INGRESS_INTF_TYPE: //ingress intf_type
611 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500612 #ifdef TEST_MODE
613 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
614 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000615 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500616 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000617 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500618 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 +0000619 return err;
620 }
621 return flow_cfg.data.ingress_intf.intf_type;
622 case EGRESS_INTF_TYPE: //egress intf_type
623 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500624 #ifdef TEST_MODE
625 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
626 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000627 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500628 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000629 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500630 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 +0000631 return err;
632 }
633 return flow_cfg.data.egress_intf.intf_type;
634 case INGRESS_INTF_ID: //ingress intf_id
635 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500636 #ifdef TEST_MODE
637 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
638 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500640 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000641 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500642 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 +0000643 return err;
644 }
645 return flow_cfg.data.ingress_intf.intf_id;
646 case EGRESS_INTF_ID: //egress intf_id
647 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500648 #ifdef TEST_MODE
649 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
650 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000651 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500652 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000653 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500654 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 +0000655 return err;
656 }
657 return flow_cfg.data.egress_intf.intf_id;
658 case CLASSIFIER_O_VID:
659 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500660 #ifdef TEST_MODE
661 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
662 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500664 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000665 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500666 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 +0000667 return err;
668 }
669 return flow_cfg.data.classifier.o_vid;
670 case CLASSIFIER_O_PBITS:
671 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500672 #ifdef TEST_MODE
673 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
674 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000675 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500676 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000677 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500678 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 +0000679 return err;
680 }
681 return flow_cfg.data.classifier.o_pbits;
682 case CLASSIFIER_I_VID:
683 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500684 #ifdef TEST_MODE
685 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
686 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000687 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500688 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000689 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500690 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 +0000691 return err;
692 }
693 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400694 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000695 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500696 #ifdef TEST_MODE
697 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
698 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500700 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000701 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500702 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 +0000703 return err;
704 }
705 return flow_cfg.data.classifier.i_pbits;
706 case CLASSIFIER_ETHER_TYPE:
707 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500708 #ifdef TEST_MODE
709 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
710 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000711 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500712 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000713 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500714 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 +0000715 return err;
716 }
717 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400718 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000719 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500720 #ifdef TEST_MODE
721 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
722 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000723 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500724 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000725 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500726 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 +0000727 return err;
728 }
729 return flow_cfg.data.classifier.ip_proto;
730 case CLASSIFIER_SRC_PORT:
731 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500732 #ifdef TEST_MODE
733 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
734 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000735 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500736 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000737 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500738 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 +0000739 return err;
740 }
741 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400742 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000743 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500744 #ifdef TEST_MODE
745 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
746 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000747 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500748 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000749 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500750 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 +0000751 return err;
752 }
753 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400754 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000755 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500756 #ifdef TEST_MODE
757 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
758 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000759 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500760 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000761 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500762 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 +0000763 return err;
764 }
765 return flow_cfg.data.classifier.pkt_tag_type;
766 case EGRESS_QOS_TYPE:
767 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500768 #ifdef TEST_MODE
769 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
770 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000771 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500772 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000773 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500774 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 +0000775 return err;
776 }
777 return flow_cfg.data.egress_qos.type;
778 case EGRESS_QOS_QUEUE_ID:
779 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500780 #ifdef TEST_MODE
781 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
782 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000783 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500784 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000785 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500786 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 +0000787 return err;
788 }
789 switch (flow_cfg.data.egress_qos.type) {
790 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
791 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
792 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
793 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
794 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
795 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
796 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
797 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
798 case BCMOLT_EGRESS_QOS_TYPE_NONE:
799 default:
800 return -1;
801 }
802 case EGRESS_QOS_TM_SCHED_ID:
803 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500804 #ifdef TEST_MODE
805 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
806 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000807 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500808 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000809 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500810 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 +0000811 return err;
812 }
813 return flow_cfg.data.egress_qos.tm_sched.id;
814 case ACTION_CMDS_BITMASK:
815 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500816 #ifdef TEST_MODE
817 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
818 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000819 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500820 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000821 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500822 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 +0000823 return err;
824 }
825 return flow_cfg.data.action.cmds_bitmask;
826 case ACTION_O_VID:
827 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500828 #ifdef TEST_MODE
829 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
830 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000831 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500832 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000833 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500834 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 +0000835 return err;
836 }
837 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400838 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500840 #ifdef TEST_MODE
841 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
842 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000843 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500844 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000845 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500846 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 +0000847 return err;
848 }
849 return flow_cfg.data.action.o_pbits;
850 case ACTION_I_VID:
851 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500852 #ifdef TEST_MODE
853 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
854 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000855 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500856 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000857 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500858 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 +0000859 return err;
860 }
861 return flow_cfg.data.action.i_vid;
862 case ACTION_I_PBITS:
863 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500864 #ifdef TEST_MODE
865 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
866 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000867 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500868 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000869 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500870 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 +0000871 return err;
872 }
873 return flow_cfg.data.action.i_pbits;
874 case STATE:
875 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500876 #ifdef TEST_MODE
877 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
878 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000879 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500880 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000881 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500882 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000883 return err;
884 }
885 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000886 case GROUP_ID:
887 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
888 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
889 if (err) {
890 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
891 return err;
892 }
893 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000894 default:
895 return BCM_ERR_INTERNAL;
896 }
897
898 return err;
899}
900
901Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400902 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000903 bcmolt_pon_interface_cfg interface_obj;
904 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
905 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
906 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530907 bcmolt_status los_status;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000908
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +0530909 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000910 if (err == BCM_ERR_OK) {
911 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800912 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000913 return Status::OK;
914 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400915 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000916 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
917 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
918 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
919 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
920 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
Girish Gowdra24297032020-03-23 12:32:37 -0700921 BCMOLT_ONU_POST_DISCOVERY_MODE_NONE);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000922 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
923 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
924 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
925 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
926 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
927 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
Burak Gurdag5e587792020-05-06 14:58:02 +0000928
929 // On GPON, power level mode is not set to its default value (i.e. 0) as documented in Broadcom documentation.
930 // Instead, it is set to 2 which means -6 dbM attenuation. Therefore, we explicitly set it to the default value below.
931 if (board_technology == "GPON") {
932 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.pls_maximum_allocation_size, BCMOLT_PON_POWER_LEVEL_PLS_MAXIMUM_ALLOCATION_SIZE_DEFAULT);
933 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
934 }
935
kesavandc1f2db92020-08-31 15:32:06 +0530936 //Enable AES Encryption
937 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
938 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
939 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.fail_due_to_authentication_failure, BCMOLT_CONTROL_STATE_ENABLE);
940
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000941 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
942 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
943
944 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
945 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500946 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 +0000947 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
948 }
949 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
950 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500951 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 +0000952 return bcm_to_grpc_err(err, "Failed to enable PON interface");
953 }
954 else {
955 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
956 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
957 CreateDefaultSched(intf_id, downstream);
958 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400959 }
960
961 return Status::OK;
962}
963
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500964Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000965 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400966 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000967 bcmolt_device_key dev_key = { };
968 bcmolt_olt_cfg olt_cfg = { };
969 bcmolt_olt_key olt_key = { };
970 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
971 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500972
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000973 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
974 topo.topology_maps.arr = &topo_map[0];
975 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
976 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
977 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400978 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000979 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400980 #ifdef TEST_MODE
981 // It is impossible to mock the setting of olt_cfg.data.bal_state because
982 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
983 // set the olt_cfg.data.topology. So a new stub function is created and address
984 // of olt_cfg is passed. This is one-of case where we need to test add specific
985 // code in production code.
986 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
987 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000988 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400989 #endif
990 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500991 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 +0000992 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500993 }
994
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000995 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
996 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500997
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400998 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
999 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001000 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001001
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001002 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1003 num_of_nni_ports,
1004 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001005 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001006
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001007 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +08001008 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001009 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1010 dev_key.device_id = devid;
1011 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1012 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1013 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1014 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001015 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001016 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001017 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 +00001018 num_failed_cfg_gets++;
1019 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001020 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001021
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001022 std::string bal_version;
1023 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1024 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1025 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +08001026 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001027
1028 switch(dev_cfg.data.system_mode) {
1029 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1030 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1031 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1032 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1033 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1034 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1035 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1036 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1037 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1038 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1039 }
1040
1041 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001042 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
1043 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001044 }
1045
Jason Huang09b73ea2020-01-08 17:52:05 +08001046 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
1047 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 +00001048
1049 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001050 }
1051
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001052 /* 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 +00001053 only the devices that retured success*/
1054 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1055 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1056 return bcm_to_grpc_err(err, "device: All devices failed query");
1057 }
1058
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001059 return Status::OK;
1060}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001061
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001062Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001063 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001064 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1065 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1066 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001067
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001068 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001069 if (err == BCM_ERR_OK) {
1070 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001071 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001072 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1073 CreateDefaultSched(intf_id, upstream);
1074 CreateDefaultQueue(intf_id, upstream);
1075 return Status::OK;
1076 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1077 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1078 return Status::OK;
1079 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001080 }
1081
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001082 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1083 if (set_state) {
1084 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1085 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1086 } else {
1087 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1088 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1089 }
1090 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1091 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001092 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1093 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001094 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1095 }
1096 else {
1097 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1098 if (set_state) {
1099 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1100 CreateDefaultSched(intf_id, upstream);
1101 CreateDefaultQueue(intf_id, upstream);
1102 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001103 }
1104
1105 return Status::OK;
1106}
1107
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001108Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001109 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001110 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001111 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1112 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001113
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001114 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Girish Gowdrae1db2952021-05-04 00:16:54 -07001115 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1116
1117 err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
1118 if (err != BCM_ERR_OK) {
1119 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);
1120 return bcm_to_grpc_err(err, "Failed to fetch pon port state");
1121 }
1122 if (interface_obj.data.state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1123 OPENOLT_LOG(INFO, openolt_log_id, "PON Interface already inactive, PON interface %d\n", intf_id);
1124 return Status::OK;
1125 }
1126
1127 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001128 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1129 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1130
1131 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1132 if (err != BCM_ERR_OK) {
1133 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1134 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1135 }
1136
1137 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1138 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1139
1140 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1141 if (err != BCM_ERR_OK) {
1142 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 -04001143 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001144 }
1145
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001146 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001147 return Status::OK;
1148}
1149
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001150Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
kesavandc1f2db92020-08-31 15:32:06 +05301151 const char *vendor_id, const char *vendor_specific, uint32_t pir, bool omcc_encryption_mode) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001152 bcmos_errno err = BCM_ERR_OK;
1153 bcmolt_onu_cfg onu_cfg;
1154 bcmolt_onu_key onu_key;
1155 bcmolt_serial_number serial_number; /**< ONU serial number */
1156 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001157
Girish Gowdra24297032020-03-23 12:32:37 -07001158 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1159 bcmolt_onu_state onu_state;
1160
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001161 onu_key.onu_id = onu_id;
1162 onu_key.pon_ni = intf_id;
1163 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1164 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Girish Gowdra24297032020-03-23 12:32:37 -07001165#ifdef TEST_MODE
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001166 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1167 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1168 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1169 // of onu_cfg is passed. This is one-of case where we need to add test specific
1170 // code in production code.
1171 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Girish Gowdra24297032020-03-23 12:32:37 -07001172#else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001173 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Girish Gowdra24297032020-03-23 12:32:37 -07001174#endif
1175 OPENOLT_LOG(INFO, openolt_log_id, "Activate ONU : old state = %d, current state = %d\n",
1176 onu_cfg.data.onu_old_state, onu_cfg.data.onu_state);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001177 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001178 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) {
1179 OPENOLT_LOG(INFO, openolt_log_id, "ONU is already in ACTIVE state, \
1180not processing this request for pon_intf=%d onu_id=%d\n", intf_id, onu_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001181 return Status::OK;
Girish Gowdra24297032020-03-23 12:32:37 -07001182 } else if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_NOT_CONFIGURED &&
1183 onu_cfg.data.onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1184 // We need the ONU to be in NOT_CONFIGURED or INACTIVE state to further process the request
1185 OPENOLT_LOG(ERROR, openolt_log_id, "ONU in an invalid state to process the request, \
1186state=%d pon_intf=%d onu_id=%d\n", onu_cfg.data.onu_state, intf_id, onu_id);
1187 return bcm_to_grpc_err(err, "Failed to activate ONU, invalid ONU state");
1188 }
1189 } else {
1190 // This should never happen. BAL GET should succeed for non-existant ONUs too. The state of such ONUs will be NOT_CONFIGURED
1191 OPENOLT_LOG(ERROR, openolt_log_id, "ONU state query failed pon_intf=%d onu_id=%d\n", intf_id, onu_id);
1192 return bcm_to_grpc_err(err, "onu get failed");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001193 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001194
Girish Gowdra24297032020-03-23 12:32:37 -07001195 // If the ONU is not configured at all we need to first configure it
1196 if (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_NOT_CONFIGURED) {
1197 OPENOLT_LOG(INFO, openolt_log_id, "Configuring ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001198vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Girish Gowdra24297032020-03-23 12:32:37 -07001199 vendor_specific_to_str(vendor_specific).c_str(), pir);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001200
Girish Gowdra24297032020-03-23 12:32:37 -07001201 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1202 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1203 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1204 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1205 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1206 /*set burst and data profiles to fec disabled*/
1207 if (board_technology == "XGS-PON") {
1208 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1209 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1210 } else if (board_technology == "GPON") {
1211 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1212 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1213 }
1214 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1215 if (err != BCM_ERR_OK) {
1216 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to configure ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1217 return bcm_to_grpc_err(err, "Failed to configure ONU");
1218 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001219 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001220
Burak Gurdaga0523592021-02-24 15:17:47 +00001221// TODO: MOVE THIS TO A NEW METHOD
kesavandc1f2db92020-08-31 15:32:06 +05301222 if (omcc_encryption_mode == true) {
1223 // set the encryption mode for omci port id
1224 bcmolt_itupon_gem_cfg gem_cfg;
1225 bcmolt_itupon_gem_key key = {};
1226 bcmolt_gem_port_configuration configuration = {};
1227 key.pon_ni = intf_id;
1228 key.gem_port_id = onu_id;
1229 bcmolt_control_state encryption_mode;
1230 encryption_mode = BCMOLT_CONTROL_STATE_ENABLE;
1231 BCMOLT_CFG_INIT(&gem_cfg, itupon_gem, key);
1232 BCMOLT_FIELD_SET(&gem_cfg.data, itupon_gem_cfg_data, encryption_mode, encryption_mode);
1233 err = bcmolt_cfg_set(dev_id, &gem_cfg.hdr);
1234 if(err != BCM_ERR_OK) {
Burak Gurdaga0523592021-02-24 15:17:47 +00001235 OPENOLT_LOG(ERROR, openolt_log_id, "failed to configure omci gem_port encryption mode = %d\n", onu_id);
kesavandc1f2db92020-08-31 15:32:06 +05301236 return bcm_to_grpc_err(err, "Access_Control set ITU PON OMCI Gem port failed");
1237 }
1238 }
Girish Gowdra24297032020-03-23 12:32:37 -07001239 // Now that the ONU is configured, move the ONU to ACTIVE state
1240 memset(&onu_cfg, 0, sizeof(bcmolt_onu_cfg));
1241 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1242 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1243 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
1244 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
1245 onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
1246 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001247 if (err != BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001248 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 +00001249 return bcm_to_grpc_err(err, "Failed to activate ONU");
1250 }
Girish Gowdra24297032020-03-23 12:32:37 -07001251 // ONU will eventually get activated after we have submitted the operation request. The adapter will receive an asynchronous
1252 // ONU_ACTIVATION_COMPLETED_INDICATION
1253
1254 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 +00001255
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001256 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001257}
1258
Jonathan Davis70c21812018-07-19 15:32:10 -04001259Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1260 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001261 bcmos_errno err = BCM_ERR_OK;
1262 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1263 bcmolt_onu_cfg onu_cfg;
1264 bcmolt_onu_key onu_key; /**< Object key. */
1265 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001266
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001267 onu_key.onu_id = onu_id;
1268 onu_key.pon_ni = intf_id;
1269 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1270 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001271 #ifdef TEST_MODE
1272 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1273 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1274 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1275 // of onu_cfg is passed. This is one-of case where we need to add test specific
1276 // code in production code.
1277 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001278 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001279 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001280 #endif
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301281 onu_state = onu_cfg.data.onu_state;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001282 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001283 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001284 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001285 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001286 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001287 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1288 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1289 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001290 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 +00001291 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1292 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301293 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 +00001294 break;
1295 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001296 }
1297
1298 return Status::OK;
1299}
1300
1301Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001302 const char *vendor_id, const char *vendor_specific) {
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301303 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301304 bcmolt_onu_state onu_state;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001305
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001306 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 -05001307 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1308
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001309 // Need to deactivate before removing it (BAL rules)
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001310 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301311
1312 err = get_onu_status((bcmolt_interface)intf_id, onu_id, &onu_state);
1313 if (err == BCM_ERR_OK) {
Girish Gowdra24297032020-03-23 12:32:37 -07001314 if (onu_state != BCMOLT_ONU_STATE_INACTIVE) {
1315 OPENOLT_LOG(INFO, openolt_log_id, "waiting for onu deactivate complete response: intf_id=%d, onu_id=%d\n",
1316 intf_id, onu_id);
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301317 err = wait_for_onu_deactivate_complete(intf_id, onu_id);
1318 if (err) {
1319 OPENOLT_LOG(ERROR, openolt_log_id, "failed to delete onu intf_id %d, onu_id %d\n",
1320 intf_id, onu_id);
1321 return bcm_to_grpc_err(err, "Failed to delete ONU");
1322 }
1323 }
Girish Gowdra24297032020-03-23 12:32:37 -07001324 else {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301325 OPENOLT_LOG(INFO, openolt_log_id, "Onu is Inactive, onu_id: %d, not waiting for onu deactivate complete response\n",
1326 intf_id);
1327 }
1328 }
1329 else {
1330 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch Onu status, onu_id = %d, intf_id = %d, err = %s\n",
1331 onu_id, intf_id, bcmos_strerror(err));
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301332 return bcm_to_grpc_err(err, "Failed to delete ONU");
1333 }
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001334
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001335 bcmolt_onu_cfg cfg_obj;
1336 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001337
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001338 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 -04001339 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001340
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001341 key.onu_id = onu_id;
1342 key.pon_ni = intf_id;
1343 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001344
Girish Gowdra7a79dae2020-02-10 18:22:11 +05301345 err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001346 if (err != BCM_ERR_OK)
1347 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001348 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 -04001349 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1350 }
1351
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05301352 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 +00001353 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001354}
1355
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001356#define MAX_CHAR_LENGTH 20
1357#define MAX_OMCI_MSG_LENGTH 44
1358Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001359 bcmolt_bin_str buf = {};
1360 bcmolt_onu_cpu_packets omci_cpu_packets;
1361 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001362
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001363 key.pon_ni = intf_id;
1364 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001365
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001366 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1367 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1368 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001369
1370 // ???
1371 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1372 buf.len = MAX_OMCI_MSG_LENGTH;
1373 } else {
1374 buf.len = pkt.size()/2;
1375 }
1376
1377 /* Send the OMCI packet using the BAL remote proxy API */
1378 uint16_t idx1 = 0;
1379 uint16_t idx2 = 0;
1380 uint8_t arraySend[buf.len];
1381 char str1[MAX_CHAR_LENGTH];
1382 char str2[MAX_CHAR_LENGTH];
1383 memset(&arraySend, 0, buf.len);
1384
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001385 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1386 sprintf(str1,"%c", pkt[idx1]);
1387 sprintf(str2,"%c", pkt[++idx1]);
1388 strcat(str1,str2);
1389 arraySend[idx2] = strtol(str1, NULL, 16);
1390 }
1391
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001392 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1393 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001394
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001395 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1396 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1397 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001398
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001399 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001400 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001401 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 +00001402 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001403 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001404 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 -05001405 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001406 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001407 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001408
1409 return Status::OK;
1410}
1411
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001412Status 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 +00001413 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1414 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1415 bcmolt_bin_str buf = {};
1416 bcmolt_gem_port_id gem_port_id_array[1];
1417 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001418
Craig Lutgen967a1d02018-11-27 10:41:51 -06001419 if (port_no > 0) {
1420 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001421 if (gemport_id == 0) {
1422 bcmos_fastlock_lock(&data_lock);
1423 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1424 // Pick any flow that is mapped with the same port_no.
1425 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1426 if (it != port_to_flows.end() && !it->second.empty()) {
1427 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1428 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1429 if (fit != flowid_to_gemport.end()) {
1430 found = true;
1431 gemport_id = fit->second;
1432 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001433 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001434 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001435
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001436 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001437 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 -08001438 onu_id, port_no, intf_id);
1439 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1440 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001441 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 -08001442 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001443 }
1444
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001445 gem_port_id_array[0] = gemport_id;
1446 gem_port_list.len = 1;
1447 gem_port_list.arr = gem_port_id_array;
1448 buf.len = pkt.size();
1449 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1450 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1451
1452 /* init the API struct */
1453 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1454 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1455 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1456 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1457 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1458
1459 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1460 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1461
1462 /* call API */
1463 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001464 }
1465 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001466 //TODO: Port No is 0, it is coming sender requirement.
1467 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1468 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001469 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001470 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001471
1472 return Status::OK;
1473}
1474
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001475Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001476 bcmolt_flow_key key = {}; /* declare key */
1477 bcmolt_bin_str buffer = {};
1478 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001479
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001480 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
Girish Gowdra252f4972020-09-07 21:24:01 -07001481 bcmolt_flow_id flow_id = INVALID_FLOW_ID;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001482
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001483 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1484 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1485 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1486 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1487 key.flow_id = flow_id;
1488 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001489 if (flow_id_counters) {
1490 std::map<flow_pair, int>::iterator it;
1491 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1492 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001493 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1494 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1495 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1496 key.flow_id = flow_index;
1497 break;
1498 }
1499 }
1500 }
1501 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001502 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001503 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1504 }
1505 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001506
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001507 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001508
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001509 /* Initialize the API struct. */
1510 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001511
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001512 buffer.len = pkt.size();
1513 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1514 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1515 if (buffer.arr == NULL) {
1516 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1517 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1518 }
1519 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1520
1521 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1522 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001523 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 -05001524 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525 } else {
1526 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1527 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001528
1529 return Status::OK;
1530}
Girish Gowdra252f4972020-09-07 21:24:01 -07001531
Burak Gurdaga0523592021-02-24 15:17:47 +00001532bool get_aes_flag_for_gem_port(const google::protobuf::Map<unsigned int, bool> &gemport_to_aes, uint32_t gemport_id) {
1533 bool aes_flag = false;
1534 for (google::protobuf::Map<unsigned int, bool>::const_iterator it=gemport_to_aes.begin(); it!=gemport_to_aes.end(); it++) {
1535 if (it->first == gemport_id) {
1536 aes_flag = it->second;
1537 break;
1538 }
1539 }
1540 return aes_flag;
1541}
1542
Girish Gowdra252f4972020-09-07 21:24:01 -07001543Status FlowAddWrapper_(const ::openolt::Flow* request) {
1544
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001545 Status st = Status::OK;
Girish Gowdra252f4972020-09-07 21:24:01 -07001546 int32_t access_intf_id = request->access_intf_id();
1547 int32_t onu_id = request->onu_id();
1548 int32_t uni_id = request->uni_id();
1549 uint32_t port_no = request->port_no();
1550 uint64_t voltha_flow_id = request->flow_id();
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001551 uint64_t symmetric_voltha_flow_id = 0;
Girish Gowdra252f4972020-09-07 21:24:01 -07001552 const std::string flow_type = request->flow_type();
1553 int32_t alloc_id = request->alloc_id();
1554 int32_t network_intf_id = request->network_intf_id();
1555 int32_t gemport_id = request->gemport_id();
1556 const ::openolt::Classifier& classifier = request->classifier();
1557 const ::openolt::Action& action = request->action();
1558 int32_t priority = request->priority();
1559 uint64_t cookie = request->cookie();
1560 int32_t group_id = request->group_id();
1561 uint32_t tech_profile_id = request->tech_profile_id();
1562 bool replicate_flow = request->replicate_flow();
1563 const google::protobuf::Map<unsigned int, unsigned int> &pbit_to_gemport = request->pbit_to_gemport();
Burak Gurdaga0523592021-02-24 15:17:47 +00001564 const google::protobuf::Map<unsigned int, bool> &gemport_to_aes = request->gemport_to_aes();
Girish Gowdra252f4972020-09-07 21:24:01 -07001565 uint16_t flow_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001566 bool enable_encryption;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001567 // When following conditions are ALL met, it qualifies as datapath flow.
1568 // 1. valid access_intf_id, onu_id, uni_id
1569 // 2. Valid tech_profile_id
1570 // 3. flow_type that is not MULTICAST
1571 // 4. Not a trap-to-host flow.
1572 bool datapathFlow = access_intf_id >= 0 && onu_id >= 0 && uni_id >= 0 && tech_profile_id > 0
1573 && flow_type != multicast && !action.cmd().trap_to_host();
1574
1575 if (datapathFlow) {
1576 const std::string inverse_flow_type = flow_type.compare(upstream) == 0 ? downstream : upstream;
1577 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, inverse_flow_type);
1578 // Find the onu-uni mapping for the pon-gem key
1579 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1580 auto it = symmetric_datapath_flow_id_map.find(key);
1581 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1582 if (it != symmetric_datapath_flow_id_map.end()) {
1583 symmetric_voltha_flow_id = it->second;
1584 }
1585 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001586
1587 // The intf_id variable defaults to access(PON) interface ID.
1588 // For trap-from-nni flow where access interface ID is not valid , change it to NNI interface ID
1589 // This intf_id identifies the pool from which we get the flow_id
1590 uint32_t intf_id = access_intf_id;
1591 if (onu_id < 1) {
1592 onu_id = 1;
1593 }
1594 if (access_intf_id < 0) {
1595 intf_id = network_intf_id;
1596 }
1597
1598 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)
1599 // This is the case of voltha_flow_id (not symmetric_voltha_flow_id)
1600 if (is_voltha_flow_installed(voltha_flow_id)) {
1601 OPENOLT_LOG(INFO, openolt_log_id, "voltha_flow_id=%lu, already installed\n", voltha_flow_id);
1602 return ::Status(grpc::StatusCode::ALREADY_EXISTS, "voltha-flow-already-installed");
1603 }
1604
Girish Gowdra252f4972020-09-07 21:24:01 -07001605 // This is the case of symmetric_voltha_flow_id
1606 // If symmetric_voltha_flow_id is available and valid in the Flow message,
1607 // check if it is installed, and use the corresponding device_flow_id
1608 if (symmetric_voltha_flow_id > 0 && is_voltha_flow_installed(symmetric_voltha_flow_id)) { // symmetric flow found
1609 OPENOLT_LOG(INFO, openolt_log_id, "symmetric flow and the symmetric flow is installed\n");
1610 const device_flow_params *dev_fl_symm_params;
1611 dev_fl_symm_params = get_device_flow_params(symmetric_voltha_flow_id);
1612 if (dev_fl_symm_params == NULL) {
1613 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)
1614 return ::Status(grpc::StatusCode::INTERNAL, "symmetric-flow-details-not-found");
1615 }
1616
1617 if (!replicate_flow) { // No flow replication
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001618 flow_id = dev_fl_symm_params[0].flow_id;
1619 gemport_id = dev_fl_symm_params[0].gemport_id; // overwrite the gemport with symmetric flow gemport
1620 // Should be same as what is coming in this request.
1621 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
1622 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1623 cl.set_o_pbits(dev_fl_symm_params[0].pbit);
1624 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
1625 flow_type, alloc_id, network_intf_id, gemport_id, cl,
1626 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
1627 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1628 OPENOLT_LOG(ERROR, openolt_log_id, "failed to install device flow=%u for voltha flow=%lu", flow_id, voltha_flow_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001629 return st;
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001630 }
1631
1632 device_flow dev_fl;
1633 dev_fl.is_flow_replicated = false;
1634 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1635 dev_fl.voltha_flow_id = voltha_flow_id;
1636 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params));
1637 // update voltha flow to cache
1638 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
Girish Gowdra252f4972020-09-07 21:24:01 -07001639 } else { // Flow to be replicated
1640 OPENOLT_LOG(INFO, openolt_log_id,"symmetric flow and replication is needed\n");
1641 for (uint8_t i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
1642 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1643 flow_id = dev_fl_symm_params[i].flow_id;
1644 gemport_id = dev_fl_symm_params[i].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001645 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001646 cl.set_o_pbits(dev_fl_symm_params[i].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001647 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdrade65ab42020-12-17 23:08:43 -08001648 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001649 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001650 if (st.error_code() != grpc::StatusCode::OK && st.error_code() != grpc::StatusCode::ALREADY_EXISTS) {
1651 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);
1652 // On failure remove any successfully replicated flows installed so far for the voltha_flow_id
1653 if (i > 0) {
1654 for (int8_t j = i-1; j >= 0; j--) {
1655 flow_id = dev_fl_symm_params[j].flow_id;
1656 FlowRemove_(flow_id, flow_type);
1657 }
1658 }
1659 return st;
1660 }
1661 }
1662 device_flow dev_fl;
1663 dev_fl.is_flow_replicated = true;
1664 dev_fl.symmetric_voltha_flow_id = symmetric_voltha_flow_id;
1665 dev_fl.voltha_flow_id = voltha_flow_id;
1666 memcpy(dev_fl.params, dev_fl_symm_params, sizeof(device_flow_params)*NUMBER_OF_REPLICATED_FLOWS);
1667 // update voltha flow to cache
1668 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1669 }
1670 } else { // No symmetric flow found
1671 if (!replicate_flow) { // No flow replication
1672 OPENOLT_LOG(INFO, openolt_log_id, "not a symmetric flow and replication is not needed\n");
1673 flow_id = get_flow_id();
1674 if (flow_id == INVALID_FLOW_ID) {
1675 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocated flow id for voltha-flow-id=%lu\n", voltha_flow_id);
1676 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1677 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001678 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001679 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001680 flow_type, alloc_id, network_intf_id, gemport_id, classifier,
Burak Gurdaga0523592021-02-24 15:17:47 +00001681 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001682 if (st.error_code() == grpc::StatusCode::OK) {
1683 device_flow dev_fl;
1684 dev_fl.is_flow_replicated = false;
1685 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // Invalid
1686 dev_fl.voltha_flow_id = voltha_flow_id;
1687 dev_fl.params[0].flow_id = flow_id;
1688 dev_fl.params[0].gemport_id = gemport_id;
1689 dev_fl.params[0].pbit = classifier.o_pbits();
1690 // update voltha flow to cache
1691 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1692 } else {
1693 // Free the flow id on failure
1694 free_flow_id(flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001695 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001696 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001697 } else { // Flow to be replicated
1698 OPENOLT_LOG(INFO, openolt_log_id,"not a symmetric flow and replication is needed\n");
1699 if (pbit_to_gemport.size() != NUMBER_OF_PBITS) {
1700 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pbit-to-gemport map size=%lu", pbit_to_gemport.size())
1701 return ::Status(grpc::StatusCode::OUT_OF_RANGE, "pbit-to-gemport-map-len-invalid-for-flow-replication");
1702 }
1703 uint16_t flow_ids[NUMBER_OF_REPLICATED_FLOWS];
1704 device_flow dev_fl;
1705 if (get_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids)) {
1706 uint8_t cnt = 0;
1707 dev_fl.is_flow_replicated = true;
1708 dev_fl.voltha_flow_id = voltha_flow_id;
1709 dev_fl.symmetric_voltha_flow_id = INVALID_FLOW_ID; // invalid
1710 for (google::protobuf::Map<unsigned int, unsigned int>::const_iterator it=pbit_to_gemport.begin(); it!=pbit_to_gemport.end(); it++) {
1711 dev_fl.params[cnt].flow_id = flow_ids[cnt];
1712 dev_fl.params[cnt].pbit = it->first;
1713 dev_fl.params[cnt].gemport_id = it->second;
1714
1715 ::openolt::Classifier cl = ::openolt::Classifier(classifier);
1716 flow_id = dev_fl.params[cnt].flow_id;
1717 gemport_id = dev_fl.params[cnt].gemport_id;
Burak Gurdaga0523592021-02-24 15:17:47 +00001718 enable_encryption = get_aes_flag_for_gem_port(gemport_to_aes, gemport_id);
Girish Gowdra252f4972020-09-07 21:24:01 -07001719 cl.set_o_pbits(dev_fl.params[cnt].pbit);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001720 st = FlowAdd_(access_intf_id, onu_id, uni_id, port_no, flow_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001721 flow_type, alloc_id, network_intf_id, gemport_id, cl,
Burak Gurdaga0523592021-02-24 15:17:47 +00001722 action, priority, cookie, group_id, tech_profile_id, enable_encryption);
Girish Gowdra252f4972020-09-07 21:24:01 -07001723 if (st.error_code() != grpc::StatusCode::OK) {
1724 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);
1725 // Remove any successfully replicated flows installed so far for the voltha_flow_id
1726 if (cnt > 0) {
1727 for (int8_t j = cnt-1; j >= 0; j--) {
1728 flow_id = dev_fl.params[j].flow_id;
1729 FlowRemove_(flow_id, flow_type);
1730 }
1731 }
1732 // Free up all the flow IDs on failure
1733 free_flow_ids(NUMBER_OF_REPLICATED_FLOWS, flow_ids);
1734 return st;
1735 }
1736 cnt++;
1737 }
1738 // On successful flow replication update voltha-flow-id to device-flow map to cache
1739 update_voltha_flow_to_cache(voltha_flow_id, dev_fl);
1740 } else {
1741 OPENOLT_LOG(ERROR, openolt_log_id, "could not allocate flow ids for replication voltha-flow-id=%lu\n", voltha_flow_id);
1742 return ::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "flow-ids-exhausted");
1743 }
1744 }
1745 }
1746
Girish Gowdraeec0fc92021-05-12 15:37:55 -07001747 if (datapathFlow) {
1748 // Create the pon-gem to onu-uni mapping
1749 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
1750 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
1751 symmetric_datapath_flow_id_map[key] = voltha_flow_id;
1752 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
1753 }
1754
1755 return st;
Girish Gowdra252f4972020-09-07 21:24:01 -07001756}
1757
1758
Craig Lutgen967a1d02018-11-27 10:41:51 -06001759Status 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 +00001760 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001761 int32_t alloc_id, int32_t network_intf_id,
1762 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001763 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
Burak Gurdaga0523592021-02-24 15:17:47 +00001764 int32_t group_id, uint32_t tech_profile_id, bool aes_enabled) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001765 bcmolt_flow_cfg cfg;
1766 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001767 int32_t o_vid = -1;
1768 bool single_tag = false;
1769 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001770 bcmolt_classifier c_val = { };
1771 bcmolt_action a_val = { };
1772 bcmolt_tm_queue_ref tm_val = { };
1773 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001774 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001775
Jason Huang09b73ea2020-01-08 17:52:05 +08001776 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1777
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001778 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001779 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001780 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001781 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001782 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001783 } else if (flow_type.compare(multicast) == 0) {
1784 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001785 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001786 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001787 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001788 }
1789
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001790 BCMOLT_CFG_INIT(&cfg, flow, key);
1791 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001792
Jason Huang09b73ea2020-01-08 17:52:05 +08001793 if (action.cmd().trap_to_host()) {
Girish Gowdra1935e6a2020-10-31 21:48:22 -07001794 Status resp = handle_acl_rule_install(onu_id, flow_id, gemport_id, flow_type, access_intf_id,
Girish Gowdra252f4972020-09-07 21:24:01 -07001795 network_intf_id, classifier);
Jason Huang09b73ea2020-01-08 17:52:05 +08001796 return resp;
1797 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001798
1799 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1800
1801 if (access_intf_id >= 0 && network_intf_id >= 0) {
1802 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1803 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1804 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001805 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1806 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001807 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1808 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1809 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1810 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1811 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001812 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001813 } else {
1814 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1815 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001816 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001817
Burak Gurdaga0523592021-02-24 15:17:47 +00001818 if (onu_id >= ONU_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001819 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1820 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001821 if (gemport_id >= GEM_PORT_ID_START) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001822 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1823 }
Burak Gurdaga0523592021-02-24 15:17:47 +00001824 if (gemport_id >= GEM_PORT_ID_START && port_no != 0) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001825 bcmos_fastlock_lock(&data_lock);
1826 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1827 port_to_flows[port_no].insert(key.flow_id);
1828 flowid_to_gemport[key.flow_id] = gemport_id;
1829 }
1830 else
1831 {
1832 flowid_to_port[key.flow_id] = port_no;
1833 }
1834 bcmos_fastlock_unlock(&data_lock, 0);
1835 }
Girish Gowdra252f4972020-09-07 21:24:01 -07001836
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001837 if (priority_value >= 0) {
1838 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1839 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301840
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001841 } else { // MULTICAST FLOW
1842 if (group_id >= 0) {
1843 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001844 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001845 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1846 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001847 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001848
1849 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001850 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001851 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001852 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1853 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001854 }
1855
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001856 if (classifier.dst_mac().size() > 0) {
1857 bcmos_mac_address d_mac = {};
1858 bcmos_mac_address_init(&d_mac);
1859 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1860 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1861 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1862 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001863 }
1864
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001865 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001866 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001867 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001868 }
1869 */
1870
1871 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001872 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1873 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001874 }
1875
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001876 if (classifier.dst_ip()) {
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001877 bcmos_ipv4_address d_ip = {};
1878 bcmos_ipv4_address_init(&d_ip);
1879 d_ip.u32 = classifier.dst_ip();
1880 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_ip %04x\n", d_ip.u32);
1881 BCMOLT_FIELD_SET(&c_val, classifier, dst_ip, d_ip);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001882 }
1883
Girish Gowdraf7feb4b2021-01-08 16:08:52 -08001884 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001885 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001886 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001887 }
1888 */
1889
1890 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001891 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1892 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001893 }
1894
1895 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001896 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1897 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001898 }
1899
1900 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001901 if (classifier.o_vid()) {
1902 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1903 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1904 }
1905
1906 if (classifier.i_vid()) {
1907 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1908 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1909 }
1910
1911 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1912 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1913 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1914 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1915 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1916 single_tag = true;
1917
1918 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301919 // OpenOlt adapter will send 0xFF in case of no pbit classification
1920 // If it is any other value (0 to 7), it is for outer pbit classification.
1921 // OpenFlow protocol does not provide inner pbit classification (in case of double tagged packets),
1922 // and VOLTHA has not used any workaround to solve this problem (for ex: use metadata field).
1923 // Also there exists no use case for i-pbit classification, so we can safely ignore this for now.
1924 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001925 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301926 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001927 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1928 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001929
Jason Huang09b73ea2020-01-08 17:52:05 +08001930 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
Girish Gowdra7bcfaf62020-02-17 19:17:20 +05301931 // Same comments as in case of "single_tag" packets.
1932 // 0xFF means no pbit classification, otherwise a valid PCP (0 to 7).
1933 if(0xFF != classifier.o_pbits()){
Jason Huang09b73ea2020-01-08 17:52:05 +08001934 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301935 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001936 }
1937 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001938 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001939 }
1940
Jason Huang09b73ea2020-01-08 17:52:05 +08001941 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001942
Jason Huang09b73ea2020-01-08 17:52:05 +08001943 if (cmd.add_outer_tag()) {
1944 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1945 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001946 }
1947
Jason Huang09b73ea2020-01-08 17:52:05 +08001948 if (cmd.remove_outer_tag()) {
1949 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1950 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1951 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301952
Jason Huang09b73ea2020-01-08 17:52:05 +08001953 if (action.o_vid()) {
1954 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1955 o_vid = action.o_vid();
1956 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1957 }
1958
1959 if (action.o_pbits()) {
1960 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1961 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1962 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301963
Jason Huang09b73ea2020-01-08 17:52:05 +08001964 if (action.i_vid()) {
1965 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1966 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1967 }
1968
1969 if (action.i_pbits()) {
1970 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1971 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1972 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301973
Jason Huang09b73ea2020-01-08 17:52:05 +08001974 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1975
Burak Gurdaga0523592021-02-24 15:17:47 +00001976 if ((access_intf_id >= 0) && (onu_id >= ONU_ID_START)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001977 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1978 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00001979 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 +00001980
Jason Huang09b73ea2020-01-08 17:52:05 +08001981 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1982 // Queue 0 on DS subscriber scheduler
1983 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001984
Jason Huang09b73ea2020-01-08 17:52:05 +08001985 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1986 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1987 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001988
Jason Huang09b73ea2020-01-08 17:52:05 +08001989 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1990 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1991 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001992
Jason Huang09b73ea2020-01-08 17:52:05 +08001993 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1994 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1995 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 +00001996
Jason Huang09b73ea2020-01-08 17:52:05 +08001997 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1998 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1999 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2000 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 +00002001
Jason Huang09b73ea2020-01-08 17:52:05 +08002002 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2003 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2004 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2005 }
2006 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2007 // NNI Scheduler ID
2008 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2009 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2010 // Queue 0 on NNI scheduler
2011 tm_val.queue_id = 0;
2012 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2013 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2014 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002015
Jason Huang09b73ea2020-01-08 17:52:05 +08002016 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 +00002017 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2018 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2019
Jason Huang09b73ea2020-01-08 17:52:05 +08002020 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2021 /* Fetch TM QMP ID mapped to US NNI scheduler */
2022 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2023 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2024 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2025 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2026 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 +00002027
Jason Huang09b73ea2020-01-08 17:52:05 +08002028 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 +00002029 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2030 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002031 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002032 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302033 } else {
2034 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2035 tm_val.queue_id = 0;
2036
2037 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2038 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2039 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2040
2041 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2042 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2043 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002044 }
2045
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002046 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002047
Girish Gowdra252f4972020-09-07 21:24:01 -07002048#ifndef SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002049 // BAL 3.1 supports statistics only for unicast flows.
2050 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2051 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2052 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002053#endif // SCALE_AND_PERF
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002054
Girish Gowdra252f4972020-09-07 21:24:01 -07002055#ifndef SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002056#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002057 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002058 if (flow_id_counters != 0) {
2059 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08002060 std::map<flow_pair, int>::iterator it;
2061
2062 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2063 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
2064 (key.flow_type == it->first.second) && \
2065 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
2066 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
2067 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
2068 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
2069 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
2070 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
2071 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
2072 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
2073 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
2074 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
2075 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
2076 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
2077 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
2078 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
2079 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
2080 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
2081 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
2082 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
2083 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
2084 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
2085 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
2086 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
2087 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
2088 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
2089 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
2090 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002091#ifdef SHOW_FLOW_PARAM
2092 // Flow Parameter
2093 FLOW_PARAM_LOG();
2094#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002095 if (b_duplicate_flow) {
2096 FLOW_LOG(WARNING, "Flow duplicate", 0);
2097 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2098 }
2099 }
2100 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002101#endif // FLOW_CHECKER
2102#endif // SCALE_AND_PERF
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002103
2104 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2105 if (err) {
2106 FLOW_LOG(ERROR, "Flow add failed", err);
2107 return bcm_to_grpc_err(err, "flow add failed");
2108 } else {
2109 FLOW_LOG(INFO, "Flow add ok", err);
2110 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002111 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
2112 flow_id_counters = flow_map.size();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002113 bcmos_fastlock_unlock(&data_lock, 0);
Girish Gowdra252f4972020-09-07 21:24:01 -07002114
2115 }
Burak Gurdaga0523592021-02-24 15:17:47 +00002116
2117 /*
2118 Enable AES encryption on GEM ports if they are used in downstream unicast flows.
2119 Rationale: We can't do upstream encryption in GPON. This change addresses the common denominator (and also minimum viable)
2120 use case for both technologies which is downstream unicast GEM port encryption. Since the downstream traffic is inherently
2121 broadcast to all the ONUs behind a PON port, encrypting the individual subscriber traffic in this direction is important
2122 and considered good enough in terms of security (See Section 12.1 of G.984.3). For upstream unicast and downstream multicast
2123 GEM encryption, we need to make additional changes specific to XGSPON. This will be done as a future work.
2124 */
2125 if (aes_enabled && (access_intf_id >= 0) && (gemport_id >= GEM_PORT_ID_START) && (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM)) {
2126 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);
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302127 enable_encryption_for_gem_port(access_intf_id, gemport_id, board_technology);
Burak Gurdaga0523592021-02-24 15:17:47 +00002128 } else {
2129 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);
2130 }
2131
Girish Gowdra252f4972020-09-07 21:24:01 -07002132 return Status::OK;
2133}
2134
2135Status FlowRemoveWrapper_(const ::openolt::Flow* request) {
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002136 int32_t access_intf_id = request->access_intf_id();
2137 int32_t onu_id = request->onu_id();
2138 int32_t uni_id = request->uni_id();
2139 uint32_t tech_profile_id = request->tech_profile_id();
Girish Gowdra252f4972020-09-07 21:24:01 -07002140 const std::string flow_type = request->flow_type();
2141 uint64_t voltha_flow_id = request->flow_id();
2142 Status st;
2143
2144 // If Voltha flow is not installed, return fail
2145 if (! is_voltha_flow_installed(voltha_flow_id)) {
2146 OPENOLT_LOG(ERROR, openolt_log_id, "voltha_flow_id=%lu not found\n", voltha_flow_id);
2147 return ::Status(grpc::StatusCode::NOT_FOUND, "voltha-flow-not-found");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002148 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002149
Girish Gowdra252f4972020-09-07 21:24:01 -07002150 const device_flow *dev_fl = get_device_flow(voltha_flow_id);
2151 if (dev_fl == NULL) {
2152 OPENOLT_LOG(ERROR, openolt_log_id, "device flow for voltha_flow_id=%lu in the cache is NULL\n", voltha_flow_id);
2153 return ::Status(grpc::StatusCode::INTERNAL, "device-flow-null-in-cache");
2154 }
2155 if (dev_fl->is_flow_replicated) {
2156 // Note: Here we are ignoring FlowRemove failures
2157 for (int i=0; i<NUMBER_OF_REPLICATED_FLOWS; i++) {
2158 st = FlowRemove_(dev_fl->params[i].flow_id, flow_type);
2159 if (st.error_code() == grpc::StatusCode::OK) {
2160 free_flow_id(dev_fl->params[i].flow_id);
2161 }
2162 }
2163 } else {
2164 // Note: Here we are ignoring FlowRemove failures
2165 st = FlowRemove_(dev_fl->params[0].flow_id, flow_type);
2166 if (st.error_code() == grpc::StatusCode::OK) {
2167 free_flow_id(dev_fl->params[0].flow_id);
2168 }
2169 }
2170 // remove the flow from cache on voltha flow removal
2171 remove_voltha_flow_from_cache(voltha_flow_id);
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002172
2173 symmetric_datapath_flow_id_map_key key(access_intf_id, onu_id, uni_id, tech_profile_id, flow_type);
2174 // Remove onu-uni mapping for the pon-gem key
2175 bcmos_fastlock_lock(&symmetric_datapath_flow_id_lock);
2176 symmetric_datapath_flow_id_map.erase(key);
2177 bcmos_fastlock_unlock(&symmetric_datapath_flow_id_lock, 0);
2178
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002179 return Status::OK;
2180}
2181
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002182Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2183
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002184 bcmolt_flow_cfg cfg;
2185 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002186
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002187 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002188 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002189 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002190 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002191 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002192 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002193 } else if(flow_type.compare(multicast) == 0) {
2194 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002195 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002196 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002197 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2198 }
2199
Jason Huang09b73ea2020-01-08 17:52:05 +08002200 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
2201 flow_id, flow_type.c_str());
2202
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002203 bcmos_fastlock_lock(&acl_packet_trap_handler_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002204 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
2205 int32_t gemport_id = -1;
2206 int32_t intf_id = -1;
2207 int16_t acl_id = -1;
2208 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002209
2210 acl_id_intf_id ac_id_if_id = flow_to_acl_map[fl_id_fl_dir];
2211 acl_id = std::get<0>(ac_id_if_id);
2212 intf_id = std::get<1>(ac_id_if_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002213 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
2214 if (acl_id >= 0) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002215 Status resp = handle_acl_rule_cleanup(acl_id, intf_id, flow_type);
Jason Huang09b73ea2020-01-08 17:52:05 +08002216 if (resp.ok()) {
2217 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2218 flow_to_acl_map.erase(fl_id_fl_dir);
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002219
2220 // 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
2221 if (trap_to_host_pkt_info_with_vlan_for_flow_id.count(flow_id) > 0) {
2222 trap_to_host_pkt_info_with_vlan pkt_info_with_vlan = trap_to_host_pkt_info_with_vlan_for_flow_id[flow_id];
2223 // Formulate the trap_to_host_pkt_info tuple key
2224 trap_to_host_pkt_info pkt_info(std::get<0>(pkt_info_with_vlan),
2225 std::get<1>(pkt_info_with_vlan),
2226 std::get<2>(pkt_info_with_vlan),
2227 std::get<3>(pkt_info_with_vlan));
2228 // Extract the value corresponding to trap_to_host_pkt_info key from trap_to_host_vlan_ids_for_trap_to_host_pkt_info
2229 // The value is a list of vlan_ids for the given trap_to_host_pkt_info key
2230 // Remove the vlan_id from the list that corresponded to the flow being removed.
2231 if (trap_to_host_vlan_ids_for_trap_to_host_pkt_info.count(pkt_info) > 0) {
2232 trap_to_host_vlan_ids_for_trap_to_host_pkt_info[pkt_info].remove(std::get<4>(pkt_info_with_vlan));
2233 } else {
2234 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",
2235 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));
2236 }
2237
2238 } else {
2239 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);
2240 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002241 } else {
2242 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
2243 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002244 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002245 return resp;
2246 }
2247 }
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002248 bcmos_fastlock_unlock(&acl_packet_trap_handler_lock, 0);
Jason Huang09b73ea2020-01-08 17:52:05 +08002249
Girish Gowdra1935e6a2020-10-31 21:48:22 -07002250 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002251 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002252 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002253 flowid_to_gemport.erase(key.flow_id);
2254 port_to_flows[port_no].erase(key.flow_id);
2255 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2256 }
2257 else
2258 {
2259 flowid_to_port.erase(key.flow_id);
2260 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002261 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002262
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002263 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002264
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002265 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002266 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002267 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 -04002268 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2269 }
2270
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002271 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08002272 if (flow_id_counters != 0) {
2273 std::map<flow_pair, int>::iterator it;
2274 for(it = flow_map.begin(); it != flow_map.end(); it++) {
2275 if (it->first.first == flow_id && it->first.second == key.flow_type) {
2276 flow_id_counters -= 1;
2277 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002278 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002279 }
2280 }
Jason Huang09b73ea2020-01-08 17:52:05 +08002281 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
2282
Jason Huang09b73ea2020-01-08 17:52:05 +08002283 flow_to_acl_map.erase(fl_id_fl_dir);
2284
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002285 bcmos_fastlock_unlock(&data_lock, 0);
2286
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002287 return Status::OK;
2288}
2289
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002290bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2291 bcmos_errno err;
2292 bcmolt_tm_sched_cfg tm_sched_cfg;
2293 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2294 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2295
Jason Huangbf45ffb2019-10-30 17:29:02 +08002296 //check TM scheduler has configured or not
2297 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2298 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002299 #ifdef TEST_MODE
2300 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2301 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2302 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2303 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2304 // code in production code.
2305 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2306 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002307 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002308 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002309 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002310 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 +08002311 return err;
2312 }
2313 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2314 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2315 return BCM_ERR_OK;
2316 }
2317
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002318 // bcmbal_tm_sched_owner
2319 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2320
2321 /**< The output of the tm_sched object instance */
2322 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2323
2324 if (direction.compare(upstream) == 0) {
2325 // In upstream it is NNI scheduler
2326 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2327 } else if (direction.compare(downstream) == 0) {
2328 // In downstream it is PON scheduler
2329 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2330 }
2331
2332 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2333
2334 // bcmbal_tm_sched_type
2335 // set the deafult policy to strict priority
2336 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2337
2338 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002339 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002340
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002341 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2342 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002343 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2344 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002345 return err;
2346 }
2347
2348 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2349 direction.c_str(), tm_sched_key.id, intf_id);
2350 return BCM_ERR_OK;
2351}
2352
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002353bcmos_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 -07002354 uint32_t alloc_id, ::tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2355 ::tech_profile::SchedulingPolicy sched_policy, ::tech_profile::TrafficShapingInfo tf_sh_info,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002356 uint32_t tech_profile_id) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002357
2358 bcmos_errno err;
2359
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002360 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002361 bcmolt_tm_sched_cfg tm_sched_cfg;
2362 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002363 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 -04002364
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002365 // bcmbal_tm_sched_owner
2366 // In downstream it is sub_term scheduler
2367 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002368
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002369 /**< The output of the tm_sched object instance */
2370 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002371
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002372 // bcmbal_tm_sched_parent
2373 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2374 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2375 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 +00002376 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002377 be achieved using the' virtual' type of attachment.
2378 tm_sched_owner.u.sub_term.intf_id = intf_id;
2379 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2380 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002381
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002382 // bcmbal_tm_sched_type
2383 // set the deafult policy to strict priority
2384 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002385
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002386 // num_priorities: Max number of strict priority scheduling elements
2387 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002388
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002389 // bcmbal_tm_shaping
2390 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2391 uint32_t cir = tf_sh_info.cir();
2392 uint32_t pir = tf_sh_info.pir();
2393 uint32_t burst = tf_sh_info.pbs();
2394 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2395 cir, pir, burst);
2396 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2397 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2398 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2399 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2400 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2401 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002402 }
2403
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002404 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002405 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002407intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2408port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002409 return err;
2410 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002411 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2412uni_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 -08002413
2414 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002415 bcmolt_itupon_alloc_cfg cfg;
2416 bcmolt_itupon_alloc_key key = { };
2417 key.pon_ni = intf_id;
2418 key.alloc_id = alloc_id;
2419 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag623fada2021-04-20 22:02:36 +00002420 /*
2421 PIR: Maximum Bandwidth
2422 CIR: Assured Bandwidth
2423 GIR: Fixed Bandwidth
2424 */
Burak Gurdag03919c72020-02-04 22:46:57 +00002425 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
2426 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Burak Gurdag623fada2021-04-20 22:02:36 +00002427 int gir_bw = tf_sh_info.gir()*125; // conversion from kbps to bytes/sec
2428 int guaranteed_bw = cir_bw+gir_bw;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002429 //offset to match bandwidth granularity
2430 int offset_pir_bw = pir_bw%bw_granularity;
Burak Gurdag623fada2021-04-20 22:02:36 +00002431 int offset_gir_bw = gir_bw%bw_granularity;
2432 int offset_guaranteed_bw = guaranteed_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002433
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002434 pir_bw = pir_bw - offset_pir_bw;
Burak Gurdag623fada2021-04-20 22:02:36 +00002435 gir_bw = gir_bw - offset_gir_bw;
2436 guaranteed_bw = guaranteed_bw - offset_guaranteed_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002437
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002438 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002439
Burak Gurdag623fada2021-04-20 22:02:36 +00002440 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);
2441
2442 if (pir_bw == 0) {
2443 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be at least %d bytes/sec\n",
2444 (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2445 return BCM_ERR_PARM;
2446 } else if (pir_bw < guaranteed_bw) {
2447 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed bandwidth (%d)\n",
2448 pir_bw, guaranteed_bw);
2449 return BCM_ERR_PARM;
2450 }
2451
2452 // Setting additional bw eligibility and validating bw provisionings
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002453 switch (additional_bw) {
Burak Gurdag623fada2021-04-20 22:02:36 +00002454
2455 case tech_profile::AdditionalBW::AdditionalBW_BestEffort: //AdditionalBW_BestEffort - For T-Cont types 4 & 5
2456 if (pir_bw == guaranteed_bw) {
2457 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2458bandwidth for additional bandwidth eligibility of type Best Effort\n");
2459 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002460 }
2461 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2462 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002463
2464 case tech_profile::AdditionalBW::AdditionalBW_NA: //AdditionalBW_NA - For T-Cont types 3 & 5
2465 if (guaranteed_bw == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002466 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2467additional bandwidth eligibility of type Non-Assured (NA)\n");
2468 return BCM_ERR_PARM;
Burak Gurdag623fada2021-04-20 22:02:36 +00002469 } else if (pir_bw == guaranteed_bw) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002470 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
Burak Gurdag623fada2021-04-20 22:02:36 +00002471bandwidth for additional bandwidth eligibility of type Non-Assured\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002472 return BCM_ERR_PARM;
2473 }
2474 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2475 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002476
2477 case tech_profile::AdditionalBW::AdditionalBW_None: //AdditionalBW_None - For T-Cont types 1 & 2
2478 if (guaranteed_bw != pir_bw) {
2479 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be equal to maximum bandwidth \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002480for additional bandwidth eligibility of type None\n");
2481 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002482 }
2483 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2484 break;
Burak Gurdag623fada2021-04-20 22:02:36 +00002485
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002486 default:
Burak Gurdag623fada2021-04-20 22:02:36 +00002487 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid additional bandwidth eligibility value (%d) supplied.\n", additional_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002488 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002489 }
Burak Gurdag623fada2021-04-20 22:02:36 +00002490
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002491 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2492 in a fine granularity. */
2493 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
Burak Gurdag623fada2021-04-20 22:02:36 +00002494 /* Since we can assign minimum 64000 bytes/sec for cbr_rt_bw, we prefer assigning
2495 gir_bw to cbr_nrt_bw to allow smaller amounts.
2496 TODO: Specify CBR_RT_BW and CBR_NRT_BW separately from VOLTHA */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002497 /* Fixed Bandwidth with no critical requirement of shaping */
Burak Gurdag623fada2021-04-20 22:02:36 +00002498 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, gir_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002499 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
Burak Gurdag623fada2021-04-20 22:02:36 +00002500 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, guaranteed_bw);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002501 /* Maximum allocated bandwidth allowed for this alloc ID */
2502 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
Burak Gurdag623fada2021-04-20 22:02:36 +00002503
2504 if (pir_bw == gir_bw) { // T-Cont Type 1 --> set alloc type to NONE
2505 // the condition cir_bw == 0 is implicitly satistied
2506 OPENOLT_LOG(INFO, openolt_log_id, "Setting alloc type to NONE since maximum bandwidth is equal to fixed bandwidth\n");
2507 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NONE);
2508 } else { // For other T-Cont types, set alloc type to NSR. TODO: read the default from a config file.
2509 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2510 }
2511
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002512 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002513 for skipped allocations during quiet window */
2514 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2515 /**< Allocation Profile index for CBR non-RT Bandwidth */
2516 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2517 /**< Allocation Profile index for CBR RT Bandwidth */
2518 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2519 /**< Alloc ID Weight used in case of Extended DBA mode */
2520 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2521 /**< Alloc ID Priority used in case of Extended DBA mode */
2522 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2523 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002524
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002525 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002526 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002527 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 +00002528port_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 -08002529 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002530 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002531#ifndef SCALE_AND_PERF
Girish Gowdra96461052019-11-22 20:13:59 +05302532 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2533 if (err) {
2534 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2535port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2536 return err;
2537 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002538#endif
Girish Gowdra96461052019-11-22 20:13:59 +05302539
2540 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2541port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2542
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002543 }
2544
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002545 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002546}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002547
Girish Gowdra252f4972020-09-07 21:24:01 -07002548Status CreateTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002549 uint32_t intf_id = traffic_scheds->intf_id();
2550 uint32_t onu_id = traffic_scheds->onu_id();
2551 uint32_t uni_id = traffic_scheds->uni_id();
2552 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002553 std::string direction;
2554 unsigned int alloc_id;
Girish Gowdra252f4972020-09-07 21:24:01 -07002555 ::tech_profile::SchedulerConfig sched_config;
2556 ::tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002557 uint32_t priority;
2558 uint32_t weight;
Girish Gowdra252f4972020-09-07 21:24:01 -07002559 ::tech_profile::SchedulingPolicy sched_policy;
2560 ::tech_profile::TrafficShapingInfo traffic_shaping_info;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002561 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002562 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002563
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002564 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002565 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002566
2567 direction = GetDirection(traffic_sched.direction());
2568 if (direction.compare("direction-not-supported") == 0)
2569 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2570
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002571 alloc_id = traffic_sched.alloc_id();
2572 sched_config = traffic_sched.scheduler();
2573 additional_bw = sched_config.additional_bw();
2574 priority = sched_config.priority();
2575 weight = sched_config.weight();
2576 sched_policy = sched_config.sched_policy();
2577 traffic_shaping_info = traffic_sched.traffic_shaping_info();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002578 tech_profile_id = traffic_sched.tech_profile_id();
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002579 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002580 sched_policy, traffic_shaping_info, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002581 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002582 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002583 return bcm_to_grpc_err(err, "Failed to create scheduler");
2584 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002585 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002586 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002587}
Jonathan Davis70c21812018-07-19 15:32:10 -04002588
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002589bcmos_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 -04002590
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002591 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302592 bcmolt_interface_state state;
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302593 bcmolt_status los_status;
Girish Gowdra96461052019-11-22 20:13:59 +05302594 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002595
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002596 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002597 bcmolt_itupon_alloc_cfg cfg;
2598 bcmolt_itupon_alloc_key key = { };
2599 key.pon_ni = intf_id;
2600 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302601 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002602
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002603 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002604 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2605 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002606 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2607 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002608 return err;
2609 }
Girish Gowdra96461052019-11-22 20:13:59 +05302610
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302611 err = get_pon_interface_status((bcmolt_interface)intf_id, &state, &los_status);
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302612 if (err == BCM_ERR_OK) {
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302613 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_OFF) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002614#ifndef SCALE_AND_PERF
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302615 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 +05302616 intf_id);
2617 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2618 if (err) {
2619 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2620 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2621 return err;
2622 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002623#endif
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302624 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302625 else if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING && los_status == BCMOLT_STATUS_ON) {
2626 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled but LoS status is ON, not waiting for alloc cfg clear response\n",
2627 intf_id);
2628 }
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302629 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2630 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2631 intf_id);
2632 }
Thiyagarajan Subramaniad463232020-02-28 19:10:43 +05302633 } else {
2634 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 +05302635 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302636 return err;
2637 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002638 } else if (direction == downstream) {
2639 bcmolt_tm_sched_cfg cfg;
2640 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002641
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002642 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2643 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdra96461052019-11-22 20:13:59 +05302644 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002645 } else {
2646 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2647 return BCM_ERR_OK;
2648 }
Girish Gowdra96461052019-11-22 20:13:59 +05302649
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002650 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2651 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2652 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002653 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002654intf_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 +00002655 return err;
2656 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002657 }
2658
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002659 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d, tech_profile_id %d\n",
2660 direction.c_str(), sched_id, intf_id, onu_id, tech_profile_id);
2661 free_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002662 return BCM_ERR_OK;
2663}
2664
Girish Gowdra252f4972020-09-07 21:24:01 -07002665Status RemoveTrafficSchedulers_(const ::tech_profile::TrafficSchedulers *traffic_scheds) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002666 uint32_t intf_id = traffic_scheds->intf_id();
2667 uint32_t onu_id = traffic_scheds->onu_id();
2668 uint32_t uni_id = traffic_scheds->uni_id();
2669 std::string direction;
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002670 uint32_t tech_profile_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002671 bcmos_errno err;
2672
2673 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002674 ::tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002675
2676 direction = GetDirection(traffic_sched.direction());
2677 if (direction.compare("direction-not-supported") == 0)
2678 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2679
2680 int alloc_id = traffic_sched.alloc_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002681 int tech_profile_id = traffic_sched.tech_profile_id();
2682 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction, tech_profile_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002683 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002684 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002685 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2686 }
2687 }
2688 return Status::OK;
2689}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002690
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002691bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2692 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002693 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002694 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2695 bcmolt_tm_qmp_key tm_qmp_key;
2696 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002697
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002698 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2699 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002700 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2701 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002702 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002703
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002704 tm_qmp_key.id = tm_qmp_id;
2705 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2706 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2707 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002708
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002709 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2710 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2711 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002712 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2713 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002714
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002715 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002716 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002717 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2718 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002719 return err;
2720 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002721
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002722 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2723 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002724 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002725}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002726
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002727bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2728 bcmos_errno err;
2729 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2730 bcmolt_tm_qmp_key tm_qmp_key;
2731 tm_qmp_key.id = tm_qmp_id;
2732
2733 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2734 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2735 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002736 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2737 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002738 return err;
2739 }
2740
2741 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2742 tm_qmp_key.id);
2743 return BCM_ERR_OK;
2744}
2745
2746bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2747 bcmos_errno err;
2748
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002749 /* Create default queues on the given PON/NNI scheduler */
2750 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002751 bcmolt_tm_queue_cfg tm_queue_cfg;
2752 bcmolt_tm_queue_key tm_queue_key = {};
2753 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2754 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002755 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2756 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2757 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002758
2759 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2760 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2761 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2762
2763 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2764 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002765 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", \
2766 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 +00002767 return err;
2768 }
2769
2770 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2771 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2772 }
2773 return BCM_ERR_OK;
2774}
2775
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002776bcmos_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 +00002777 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 +00002778 bcmos_errno err;
2779 bcmolt_tm_queue_cfg cfg;
2780 bcmolt_tm_queue_key key = { };
2781 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 +00002782gemport_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 +00002783
2784 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002785 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002786
2787 if (priority > 7) {
2788 return BCM_ERR_RANGE;
2789 }
2790
2791 /* FIXME: The upstream queues have to be created once only.
2792 The upstream queues on the NNI scheduler are shared by all subscribers.
2793 When the first scheduler comes in, the queues get created, and are re-used by all others.
2794 Also, these queues should be present until the last subscriber exits the system.
2795 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2796
2797 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2798 for each GEM in TECH PROFILE */
2799 key.id = queue_id_list[priority];
2800
2801 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2802 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2803 key.id = 0;
2804 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2805 }
2806 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2807 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2808 }
2809 else {
2810 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2811 }
2812
2813 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2814
2815 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2816 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2817
2818 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2819 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002820 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002821sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, tech_profile_id %d, err = %s\n", \
2822 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 +00002823 return err;
2824 }
2825
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302826 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302827 Status st = install_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Girish Gowdra252f4972020-09-07 21:24:01 -07002828 if (st.error_code() != grpc::StatusCode::ALREADY_EXISTS && st.error_code() != grpc::StatusCode::OK) {
2829 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);
2830 return BCM_ERR_INTERNAL;
2831 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002832 if (direction == upstream) {
2833 // Create the pon-gem to onu-uni mapping
2834 pon_gem pg(access_intf_id, gemport_id);
2835 onu_uni ou(onu_id, uni_id);
2836 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2837 pon_gem_to_onu_uni_map[pg] = ou;
2838 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2839 }
Girish Gowdra252f4972020-09-07 21:24:01 -07002840 }
2841
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002842 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 +00002843intf_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 +00002844 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002845}
2846
Girish Gowdra252f4972020-09-07 21:24:01 -07002847Status CreateTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002848 uint32_t intf_id = traffic_queues->intf_id();
2849 uint32_t onu_id = traffic_queues->onu_id();
2850 uint32_t uni_id = traffic_queues->uni_id();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002851 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002852 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002853 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002854 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002855 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 +00002856
2857 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2858 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2859 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2860 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002861 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002862
2863 direction = GetDirection(traffic_queue.direction());
2864 if (direction.compare("direction-not-supported") == 0)
2865 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2866
2867 queues_priority_q[i] = traffic_queue.priority();
2868 queues_pbit_map[i] = traffic_queue.pbit_map();
2869 }
2870
2871 std::vector<uint32_t> tmq_map_profile(8, 0);
2872 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2873 queues_priority_q, COUNT_OF(queues_priority_q));
2874 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002875 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002876
2877 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2878 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002879 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2880 if (err != BCM_ERR_OK) {
2881 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2882 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2883 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002884 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2885 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2886 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2887 }
2888 }
2889
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002890 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002891 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002892
2893 direction = GetDirection(traffic_queue.direction());
2894 if (direction.compare("direction-not-supported") == 0)
2895 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2896
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002897 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 +00002898
Girish Gowdruf26cf882019-05-01 23:47:58 -07002899 // If the queue exists already, lets not return failure and break the loop.
2900 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002901 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002902 return bcm_to_grpc_err(err, "Failed to create queue");
2903 }
2904 }
2905 return Status::OK;
2906}
2907
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002908bcmos_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 +00002909 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 +00002910 bcmolt_tm_queue_cfg cfg;
2911 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002912 bcmos_errno err;
2913
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302914 // Gemports are bi-directional (except in multicast case). We create the gem port when we create the
2915 // upstream/downstream queue (see CreateQueue function) and it makes sense to delete them when remove the queues.
2916 // For multicast case we do not manage the install/remove of gem port in agent application. It is managed by BAL.
2917 if (direction == upstream || direction == downstream) {
Thiyagarajan Subramani19168f52021-05-25 23:26:41 +05302918 Status st = remove_gem_port(access_intf_id, onu_id, uni_id, gemport_id, board_technology);
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302919 if (st.error_code() != grpc::StatusCode::OK) {
2920 OPENOLT_LOG(ERROR, openolt_log_id, "failed to remove gemport=%d, access_intf=%d, onu_id=%d\n", gemport_id, access_intf_id, onu_id);
2921 return BCM_ERR_INTERNAL;
2922 }
Girish Gowdraeec0fc92021-05-12 15:37:55 -07002923 if (direction == upstream) {
2924 // Remove the pon-gem to onu-uni mapping
2925 pon_gem pg(access_intf_id, gemport_id);
2926 bcmos_fastlock_lock(&pon_gem_to_onu_uni_map_lock);
2927 pon_gem_to_onu_uni_map.erase(pg);
2928 bcmos_fastlock_unlock(&pon_gem_to_onu_uni_map_lock, 0);
2929 }
Thiyagarajan Subramanie976fcf2021-05-07 22:46:57 +05302930 }
2931
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002932 if (direction == downstream) {
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002933 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction, tech_profile_id)) {
2934 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 +00002935 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002936 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002937 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 -08002938 return BCM_ERR_OK;
2939 }
2940 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002941 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2942 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002943 return BCM_ERR_OK;
2944 }
2945
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002946 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2947 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2948 // Reset the queue id to 0 when using fixed queue.
2949 key.id = 0;
2950 }
2951 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2952 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2953 }
2954 else {
2955 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2956 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002957
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002958 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2959 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002960 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002961 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2962tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2963 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 -08002964 return err;
2965 }
2966
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002967 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2968intf_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 -08002969
2970 return BCM_ERR_OK;
2971}
2972
Girish Gowdra252f4972020-09-07 21:24:01 -07002973Status RemoveTrafficQueues_(const ::tech_profile::TrafficQueues *traffic_queues) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002974 uint32_t intf_id = traffic_queues->intf_id();
2975 uint32_t onu_id = traffic_queues->onu_id();
2976 uint32_t uni_id = traffic_queues->uni_id();
2977 uint32_t port_no = traffic_queues->port_no();
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002978 uint32_t tech_profile_id = traffic_queues->tech_profile_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002979 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002980 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002981 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002982 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 +00002983
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002984 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
Girish Gowdra252f4972020-09-07 21:24:01 -07002985 ::tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002986
2987 direction = GetDirection(traffic_queue.direction());
2988 if (direction.compare("direction-not-supported") == 0)
2989 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2990
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002991 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 -08002992 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002993 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002994 return bcm_to_grpc_err(err, "Failed to remove queue");
2995 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002996 }
2997
Burak Gurdag2f2618c2020-04-23 13:20:30 +00002998 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 +00002999 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
Burak Gurdag2f2618c2020-04-23 13:20:30 +00003000 get_tm_sched_id(intf_id, onu_id, uni_id, direction, tech_profile_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003001
3002 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3003 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003004 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3005 if (err != BCM_ERR_OK) {
3006 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3007 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3008 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003009 }
3010 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003011 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003012 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003013}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003014
Girish Gowdra252f4972020-09-07 21:24:01 -07003015Status PerformGroupOperation_(const ::openolt::Group *group_cfg) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003016
3017 bcmos_errno err;
3018 bcmolt_group_key key = {};
3019 bcmolt_group_cfg grp_cfg_obj;
3020 bcmolt_group_members_update grp_mem_upd;
3021 bcmolt_members_update_command grp_mem_upd_cmd;
3022 bcmolt_group_member_info member_info = {};
3023 bcmolt_group_member_info_list_u8 members = {};
3024 bcmolt_intf_ref interface_ref = {};
3025 bcmolt_egress_qos egress_qos = {};
3026 bcmolt_tm_sched_ref tm_sched_ref = {};
3027 bcmolt_action a_val = {};
3028
3029 uint32_t group_id = group_cfg->group_id();
3030
3031 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3032
3033 if (group_id >= 0) {
3034 key.id = group_id;
3035 }
3036 else {
3037 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3038 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3039 }
3040
3041 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3042 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3043
3044 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3045
3046 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3047 if (err != BCM_ERR_OK) {
3048 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3049 return bcm_to_grpc_err(err, "Error in querying group");
3050 }
3051
3052 members.len = group_cfg->members_size();
3053
3054 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3055 // Group type is determined after a flow is assigned to it.
3056 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3057 // Only then we can add members to the group.
3058
3059 // if group does not exist, create it and return.
3060 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3061
3062 if (members.len != 0) {
3063 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);
3064 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3065 } else {
3066
3067 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3068 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3069
3070 /* Setting group actions and action parameters, if any.
3071 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3072 are supported for multicast groups in BAL 3.1.
3073 */
3074 const ::openolt::Action& action = group_cfg->action();
3075 const ::openolt::ActionCmd &cmd = action.cmd();
3076
3077 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3078 if (cmd.remove_outer_tag()) {
3079 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3080 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3081 }
3082
3083 if (cmd.translate_inner_tag()) {
3084 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3085 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3086 }
3087
3088 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3089
3090 if (action.i_vid()) {
3091 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3092 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3093 }
3094
3095 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3096
3097 // Create group
3098 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3099
3100 if (BCM_ERR_OK != err) {
3101 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3102 return bcm_to_grpc_err(err, "Error in creating group");
3103 }
3104
3105 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3106 return Status::OK;
3107 }
3108 }
3109
3110 // The group already exists. Continue configuring it according to the update member command.
3111
3112 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3113
3114 // MEMBER LIST CONSTRUCTION
3115 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3116 // empty list to the group is a legit operation and this actually empties the member list.
3117 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3118
3119 if (!members.arr) {
3120 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3121 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3122 }
3123
3124 /* SET GROUP MEMBERS UPDATE COMMAND */
Girish Gowdra252f4972020-09-07 21:24:01 -07003125 ::openolt::Group::GroupMembersCommand command = group_cfg->command();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003126 switch(command) {
Girish Gowdra252f4972020-09-07 21:24:01 -07003127 case ::openolt::Group::SET_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003128 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3129 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3130 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003131 case ::openolt::Group::ADD_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003132 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3133 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3134 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003135 case ::openolt::Group::REMOVE_MEMBERS :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003136 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3137 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3138 break;
3139 default :
3140 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3141 bcmos_free(members.arr);
3142 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3143 }
3144
3145 // SET MEMBERS LIST
3146 for (int i = 0; i < members.len; i++) {
3147
Girish Gowdra252f4972020-09-07 21:24:01 -07003148 if (command == ::openolt::Group::REMOVE_MEMBERS) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003149 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3150 } else {
3151 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3152 }
3153
Girish Gowdra252f4972020-09-07 21:24:01 -07003154 ::openolt::GroupMember *member = (::openolt::GroupMember *) &group_cfg->members()[i];
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003155
3156 // Set member interface type
Girish Gowdra252f4972020-09-07 21:24:01 -07003157 ::openolt::GroupMember::InterfaceType if_type = member->interface_type();
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003158 switch(if_type){
Girish Gowdra252f4972020-09-07 21:24:01 -07003159 case ::openolt::GroupMember::PON :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003160 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3161 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3162 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003163 case ::openolt::GroupMember::EPON_1G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003164 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3165 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3166 break;
Girish Gowdra252f4972020-09-07 21:24:01 -07003167 case ::openolt::GroupMember::EPON_10G_PATH :
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003168 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3169 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3170 break;
3171 default :
3172 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3173 bcmos_free(members.arr);
3174 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3175 }
3176
3177 // Set member interface id
3178 if (member->interface_id() >= 0) {
3179 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3180 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3181 } else {
3182 bcmos_free(members.arr);
3183 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3184 }
3185
3186 // Set member interface_ref
3187 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3188
3189 // Set member gem_port_id. This must be a multicast gemport.
3190 if (member->gem_port_id() >= 0) {
3191 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3192 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3193 } else {
3194 bcmos_free(members.arr);
3195 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3196 }
3197
3198 // Set member scheduler id and queue_id
3199 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3200 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3201 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3202 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3203
3204 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3205 uint32_t tm_queue_id;
3206 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3207 tm_queue_id = queue_id_list[member->priority()];
3208 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3209 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3210 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3211 } else {
3212 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3213 bcmos_free(members.arr);
3214 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3215 }
3216
3217 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3218 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3219 }
3220
3221 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3222 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3223 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3224
3225 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3226 bcmos_free(members.arr);
3227
3228 if (BCM_ERR_OK != err) {
3229 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);
3230 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3231 }
3232
3233 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3234
3235 return Status::OK;
3236}
Burak Gurdageb4ca2e2020-06-15 07:48:26 +00003237
3238Status DeleteGroup_(uint32_t group_id) {
3239
3240 bcmos_errno err = BCM_ERR_OK;
3241 bcmolt_group_cfg grp_cfg_obj;
3242 bcmolt_group_key key = {};
3243
3244
3245 OPENOLT_LOG(INFO, openolt_log_id, "Delete request received for group %d\n", group_id);
3246
3247 if (group_id >= 0) {
3248 key.id = group_id;
3249 } else {
3250 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3251 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3252 }
3253
3254 /* init the BAL INIT API */
3255 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3256
3257 OPENOLT_LOG(DEBUG, openolt_log_id, "Checking if group %d exists...\n",group_id);
3258
3259 // CONFIGURE GROUP MEMBERS
3260 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3261 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3262
3263 if (err != BCM_ERR_OK) {
3264 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3265 return bcm_to_grpc_err(err, "Error in querying group");
3266 }
3267
3268 if (grp_cfg_obj.data.state != BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3269 OPENOLT_LOG(DEBUG, openolt_log_id, "Group %d exists. Will be deleted.\n",group_id);
3270 err = bcmolt_cfg_clear(dev_id, &(grp_cfg_obj.hdr));
3271 if (err != BCM_ERR_OK) {
3272 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d cannot be deleted err = %s (%d).\n", group_id, bcmos_strerror(err), err);
3273 return bcm_to_grpc_err(err, "Failed to delete group");;
3274 }
3275 } else {
3276 OPENOLT_LOG(ERROR, openolt_log_id, "Group %d does not exist.\n", group_id);
3277 return Status(grpc::StatusCode::NOT_FOUND, "Group not found");
3278 }
3279
3280 OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
3281 return Status::OK;
Jason Huang1d9cfce2020-05-20 22:58:47 +08003282}
3283
Girish Gowdra252f4972020-09-07 21:24:01 -07003284Status GetLogicalOnuDistanceZero_(uint32_t intf_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003285 bcmos_errno err = BCM_ERR_OK;
3286 uint32_t mld = 0;
3287 double LD0;
3288
3289 err = getOnuMaxLogicalDistance(intf_id, &mld);
3290 if (err != BCM_ERR_OK) {
3291 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3292 }
3293
3294 LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
3295 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
3296 response->set_intf_id(intf_id);
3297 response->set_logical_onu_distance_zero(LD0);
3298
3299 return Status::OK;
3300}
3301
Girish Gowdra252f4972020-09-07 21:24:01 -07003302Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, ::openolt::OnuLogicalDistance* response) {
Jason Huang1d9cfce2020-05-20 22:58:47 +08003303 bcmos_errno err = BCM_ERR_OK;
3304 bcmolt_itu_onu_params itu = {};
3305 bcmolt_onu_cfg onu_cfg;
3306 bcmolt_onu_key onu_key = {};
3307 uint32_t mld = 0;
3308 double LDi;
3309
3310 onu_key.pon_ni = intf_id;
3311 onu_key.onu_id = onu_id;
3312
3313 err = getOnuMaxLogicalDistance(intf_id, &mld);
3314 if (err != BCM_ERR_OK) {
3315 return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
3316 }
3317
3318 /* Initialize the API struct. */
3319 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
3320 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
3321 BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
3322 BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
3323 #ifdef TEST_MODE
3324 // It is impossible to mock the setting of onu_cfg.data.onu_state because
3325 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
3326 // set the onu_cfg.data.onu_state. So a new stub function is created and address
3327 // of onu_cfg is passed. This is one-of case where we need to add test specific
3328 // code in production code.
3329 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
3330 #else
3331 /* Call API function. */
3332 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
3333 #endif
3334 if (err != BCM_ERR_OK) {
3335 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);
3336 return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
3337 }
3338
3339 if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
3340 OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
3341 return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
3342 }
3343
3344 LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
3345 OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
3346 response->set_intf_id(intf_id);
3347 response->set_onu_id(onu_id);
3348 response->set_logical_onu_distance(LDi);
3349
3350 return Status::OK;
3351}
Burak Gurdag74e3ab82020-12-17 13:35:06 +00003352
3353Status GetOnuStatistics_(uint32_t intf_id, uint32_t onu_id, openolt::OnuStatistics* onu_stats) {
3354 bcmos_errno err;
3355
3356 err = get_onu_statistics((bcmolt_interface_id)intf_id, (bcmolt_onu_id)onu_id, onu_stats);
3357
3358 if (err != BCM_ERR_OK) {
3359 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));
3360 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of ONU statistics failed");
3361 }
3362
3363 OPENOLT_LOG(INFO, openolt_log_id, "retrieved ONU statistics for PON ID = %d, ONU ID = %d\n", (int)intf_id, (int)onu_id);
3364 return Status::OK;
3365}
3366
3367Status GetGemPortStatistics_(uint32_t intf_id, uint32_t gemport_id, openolt::GemPortStatistics* gemport_stats) {
3368 bcmos_errno err;
3369
3370 err = get_gemport_statistics((bcmolt_interface_id)intf_id, (bcmolt_gem_port_id)gemport_id, gemport_stats);
3371
3372 if (err != BCM_ERR_OK) {
3373 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));
3374 return grpc::Status(grpc::StatusCode::INTERNAL, "retrieval of GEMPORT statistics failed");
3375 }
3376
3377 OPENOLT_LOG(INFO, openolt_log_id, "retrieved GEMPORT statistics for PON ID = %d, GEMPORT ID = %d\n", (int)intf_id, (int)gemport_id);
3378 return Status::OK;
3379}
Orhan Kupusogluec57af02021-05-12 12:38:17 +00003380
3381Status GetPonRxPower_(uint32_t intf_id, uint32_t onu_id, openolt::PonRxPowerData* response) {
3382 bcmos_errno err = BCM_ERR_OK;
3383
3384 // check the PON intf id
3385 if (intf_id >= MAX_SUPPORTED_PON) {
3386 err = BCM_ERR_PARM;
3387 OPENOLT_LOG(ERROR, openolt_log_id, "invalid pon intf_id - intf_id: %d, onu_id: %d\n",
3388 intf_id, onu_id);
3389 return bcm_to_grpc_err(err, "invalid pon intf_id");
3390 }
3391
3392 bcmolt_onu_rssi_measurement onu_oper; /* declare main API struct */
3393 bcmolt_onu_key onu_key; /**< Object key. */
3394 onu_rssi_compltd_key key(intf_id, onu_id);
3395 Queue<onu_rssi_complete_result> queue;
3396
3397 OPENOLT_LOG(INFO, openolt_log_id, "GetPonRxPower - intf_id %d, onu_id %d\n", intf_id, onu_id);
3398
3399 onu_key.onu_id = onu_id;
3400 onu_key.pon_ni = intf_id;
3401 /* Initialize the API struct. */
3402 BCMOLT_OPER_INIT(&onu_oper, onu, rssi_measurement, onu_key);
3403 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
3404 if (err == BCM_ERR_OK) {
3405 // initialize map
3406 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3407 onu_rssi_compltd_map.insert({key, &queue});
3408 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3409 } else {
3410 OPENOLT_LOG(ERROR, openolt_log_id, "failed to measure rssi rx power - intf_id: %d, onu_id: %d, err = %s (%d): %s\n",
3411 intf_id, onu_id, bcmos_strerror(err), err, onu_oper.hdr.hdr.err_text);
3412 return bcm_to_grpc_err(err, "failed to measure rssi rx power");
3413 }
3414
3415 onu_rssi_complete_result completed{};
3416 if (!queue.pop(completed, ONU_RSSI_COMPLETE_WAIT_TIMEOUT)) {
3417 // invalidate the queue pointer
3418 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3419 onu_rssi_compltd_map[key] = NULL;
3420 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3421 err = BCM_ERR_TIMEOUT;
3422 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for RSSI Measurement Completed indication intf_id %d, onu_id %d\n",
3423 intf_id, onu_id);
3424 } else {
3425 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",
3426 completed.pon_intf_id, completed.onu_id, completed.status.c_str(), completed.reason, completed.rx_power_mean_dbm);
3427
3428 response->set_intf_id(completed.pon_intf_id);
3429 response->set_onu_id(completed.onu_id);
3430 response->set_status(completed.status);
3431 response->set_fail_reason(static_cast<::openolt::PonRxPowerData_RssiMeasurementFailReason>(completed.reason));
3432 response->set_rx_power_mean_dbm(completed.rx_power_mean_dbm);
3433 }
3434
3435 // Remove entry from map
3436 bcmos_fastlock_lock(&onu_rssi_wait_lock);
3437 onu_rssi_compltd_map.erase(key);
3438 bcmos_fastlock_unlock(&onu_rssi_wait_lock, 0);
3439
3440 if (err == BCM_ERR_OK) {
3441 return Status::OK;
3442 } else {
3443 return bcm_to_grpc_err(err, "timeout waiting for pon rssi measurement complete indication");
3444 }
3445}