blob: 053c82c2576d20b95547aa1dc0dd0c12c088a774 [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Jason Huang09b73ea2020-01-08 17:52:05 +080028#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000031
Craig Lutgen88a22ad2018-10-04 12:30:46 -050032#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000033#include "core.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053034#include "core_data.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000035#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040036#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040037#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040038#include "state.h"
Girish Gowdraddf9a162020-01-27 12:56:27 +053039#include "core_utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000040
41extern "C"
42{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000043#include <bcmolt_api.h>
44#include <bcmolt_host_api.h>
45#include <bcmolt_api_model_supporting_enums.h>
46
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000047#include <bcmolt_api_conn_mgr.h>
48//CLI header files
49#include <bcmcli_session.h>
50#include <bcmcli.h>
51#include <bcm_api_cli.h>
52
53#include <bcmos_common.h>
54#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040055// FIXME : dependency problem
56// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040057// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000058}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000059
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000060static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050062static const std::string MIXED_TECH("mixed");
63static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000064static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000065static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040066
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
68 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
69 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
70 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000071static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction);
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, \
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -050073 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
74static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
75 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000076static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
77static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
78
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000079inline const char *get_flow_acton_command(uint32_t command) {
80 char actions[200] = { };
81 char *s_actions_ptr = actions;
82 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
83 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
84 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
85 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
86 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
87 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
88 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
89 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
90 return s_actions_ptr;
91}
92
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040093Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -050094 device_info->set_vendor(VENDOR_ID);
95 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040096 device_info->set_hardware_version("");
97 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -050098 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -050099 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500100
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800101 char serial_number[OPENOLT_FIELD_LEN];
102 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
103 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000104 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800105 device_info->set_device_serial_number(serial_number);
106
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700107 char device_id[OPENOLT_FIELD_LEN];
108 memset(device_id, '\0', OPENOLT_FIELD_LEN);
109 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000110 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700111 device_info->set_device_id(device_id);
112
Craig Lutgenb2601f02018-10-23 13:04:31 -0500113 // Legacy, device-wide ranges. To be deprecated when adapter
114 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000115 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500116 device_info->set_onu_id_start(1);
117 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600118 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500119 device_info->set_alloc_id_end(16383);
120 device_info->set_gemport_id_start(1024);
121 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500122 device_info->set_flow_id_start(1);
123 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500124 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000125 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500126 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500127 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600128 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500129 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500130 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500131 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500132 device_info->set_flow_id_start(1);
133 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500134 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500135
136 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
137 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
138 std::string intf_technology = intf_technologies[intf_id];
139 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
140 if(range == nullptr) {
141 range = device_info->add_ranges();
142 ranges[intf_technology] = range;
143 range->set_technology(intf_technology);
144
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000145 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500146 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
147
148 pool = range->add_pools();
149 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
150 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
151 pool->set_start(1);
152 pool->set_end(255);
153
154 pool = range->add_pools();
155 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
156 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
157 pool->set_start(1024);
158 pool->set_end(16383);
159
160 pool = range->add_pools();
161 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
162 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
163 pool->set_start(1024);
164 pool->set_end(65535);
165
166 pool = range->add_pools();
167 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
168 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
169 pool->set_start(1);
170 pool->set_end(16383);
171 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000172 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500173 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
174
175 pool = range->add_pools();
176 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
177 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
178 pool->set_start(1);
179 pool->set_end(127);
180
181 pool = range->add_pools();
182 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
183 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
184 pool->set_start(256);
185 pool->set_end(757);
186
187 pool = range->add_pools();
188 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
189 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
190 pool->set_start(256);
191 pool->set_end(4095);
192
193 pool = range->add_pools();
194 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
195 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
196 pool->set_start(1);
197 pool->set_end(16383);
198 }
199 }
200
201 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500202 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400203
204 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500205 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400206 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
207 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500208 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400209 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500210 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
211 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400212
213 return Status::OK;
214}
215
Shad Ansari627b5782018-08-13 22:49:32 +0000216Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000217 bcmos_errno err;
218 bcmolt_host_init_parms init_parms = {};
219 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
220 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000221
Shad Ansariedef2132018-08-10 22:14:50 +0000222 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000223
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500224 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000225 /* Initialize host subsystem */
226 err = bcmolt_host_init(&init_parms);
227 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500228 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000229 return bcm_to_grpc_err(err, "Failed to init OLT");
230 }
231
232 bcmcli_session_parm mon_session_parm;
233 /* Create CLI session */
234 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
235 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
236 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
237 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
238 BUG_ON(rc != BCM_ERR_OK);
239
240 /* API CLI */
241 bcm_openolt_api_cli_init(NULL, current_session);
242
243 /* Add quit command */
244 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
245
246 err = bcmolt_apiend_cli_init();
247 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500248 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000249 return bcm_to_grpc_err(err, "Failed to add apiend init");
250 }
251
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800252 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530253 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000254 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600255
Jason Huangbf45ffb2019-10-30 17:29:02 +0800256 //check BCM daemon is connected or not
257 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000258 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800259 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000260 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800261 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000262 Status status = SubscribeIndication();
263 if (!status.ok()) {
264 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
265 grpc_status_code_to_string(status.error_code()).c_str(),
266 status.error_message().c_str());
267 return status;
268 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800269
270 //check BAL state in initial stage
271 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000272 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800273 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000274 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800275 }
276
277 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000278 bcmos_errno err;
279 bcmolt_odid dev;
280 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
281 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400282 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000283 bcmolt_device_key dev_key = { };
284 dev_key.device_id = dev;
285 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
286 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
287 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800288 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000289 bcmolt_device_key key = {.device_id = dev};
290 bcmolt_device_connect oper;
291 BCMOLT_OPER_INIT(&oper, device, connect, key);
292 if (MODEL_ID == "asfvolt16") {
293 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
294 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
295 } else if (MODEL_ID == "asgvolt64") {
296 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
297 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
298 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
299 }
300 err = bcmolt_oper_submit(dev_id, &oper.hdr);
301 if (err) {
302 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500303 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 +0000304 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500305 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 +0000306 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
307 }
308 }
309 bcmos_usleep(200000);
310 }
311 else {
312 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
313 state.activate();
314 }
315 }
316 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000317 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000318 }
Shad Ansariedef2132018-08-10 22:14:50 +0000319
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000320 /* Start CLI */
321 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400322 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000323 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400324}
325
326Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400327 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
328 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
329 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
330 //To overcome this disable is implemented by disabling all the PON ports
331 //associated with the device so as to support both in-band
332 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400333
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400334 Status status;
335 int failedCount = 0;
336 for (int i = 0; i < NumPonIf_(); i++) {
337 status = DisablePonIf_(i);
338 if (!status.ok()) {
339 failedCount+=1;
340 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
341 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400342 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400343 if (failedCount == 0) {
344 state.deactivate();
345 openolt::Indication ind;
346 openolt::OltIndication* olt_ind = new openolt::OltIndication;
347 olt_ind->set_oper_state("down");
348 ind.set_allocated_olt_ind(olt_ind);
349 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
350 oltIndQ.push(ind);
351 return Status::OK;
352 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000353 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400354 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
355 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400356
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400357 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 -0400358}
359
360Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400361 Status status;
362 int failedCount = 0;
363 for (int i = 0; i < NumPonIf_(); i++) {
364 status = EnablePonIf_(i);
365 if (!status.ok()) {
366 failedCount+=1;
367 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
368 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400369 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000370 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400371 state.activate();
372 openolt::Indication ind;
373 openolt::OltIndication* olt_ind = new openolt::OltIndication;
374 olt_ind->set_oper_state("up");
375 ind.set_allocated_olt_ind(olt_ind);
376 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
377 oltIndQ.push(ind);
378 return Status::OK;
379 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000380 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400381 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
382 }
383 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 +0000384}
385
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000386inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
387 bcmos_errno err;
388 bcmolt_flow_key flow_key;
389 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400390
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000391 flow_key.flow_id = flow_id;
392 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400393
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000394 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400395
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000396 switch (data_id) {
397 case ONU_ID: //onu_id
398 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500399 #ifdef TEST_MODE
400 // It is impossible to mock the setting of flow_cfg.data.state because
401 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
402 // set the flow_cfg.data. So a new stub function is created and address
403 // of flow_cfg is passed. This is one-of case where we need to add test specific
404 // code in production code.
405 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
406 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000407 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500408 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000409 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500410 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000411 return err;
412 }
413 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400414 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500415 #ifdef TEST_MODE
416 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
417 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000418 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500419 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000420 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500421 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000422 return err;
423 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400424 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000425 case SVC_PORT_ID: //svc_port_id
426 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500427 #ifdef TEST_MODE
428 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
429 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000430 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500431 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000432 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500433 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 +0000434 return err;
435 }
436 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400437 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000438 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500439 #ifdef TEST_MODE
440 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
441 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000442 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500443 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000444 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500445 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000446 return err;
447 }
448 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400449 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000450 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500451 #ifdef TEST_MODE
452 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
453 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000454 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500455 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000456 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500457 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000458 return err;
459 }
460 return flow_cfg.data.cookie;
461 case INGRESS_INTF_TYPE: //ingress intf_type
462 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500463 #ifdef TEST_MODE
464 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
465 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000466 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500467 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000468 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500469 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 +0000470 return err;
471 }
472 return flow_cfg.data.ingress_intf.intf_type;
473 case EGRESS_INTF_TYPE: //egress intf_type
474 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500475 #ifdef TEST_MODE
476 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
477 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000478 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500479 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000480 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500481 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 +0000482 return err;
483 }
484 return flow_cfg.data.egress_intf.intf_type;
485 case INGRESS_INTF_ID: //ingress intf_id
486 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500487 #ifdef TEST_MODE
488 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
489 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000490 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500491 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000492 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500493 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 +0000494 return err;
495 }
496 return flow_cfg.data.ingress_intf.intf_id;
497 case EGRESS_INTF_ID: //egress intf_id
498 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500499 #ifdef TEST_MODE
500 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
501 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000502 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500503 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000504 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500505 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 +0000506 return err;
507 }
508 return flow_cfg.data.egress_intf.intf_id;
509 case CLASSIFIER_O_VID:
510 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500511 #ifdef TEST_MODE
512 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
513 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000514 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500515 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000516 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500517 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 +0000518 return err;
519 }
520 return flow_cfg.data.classifier.o_vid;
521 case CLASSIFIER_O_PBITS:
522 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500523 #ifdef TEST_MODE
524 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
525 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000526 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500527 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000528 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500529 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 +0000530 return err;
531 }
532 return flow_cfg.data.classifier.o_pbits;
533 case CLASSIFIER_I_VID:
534 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500535 #ifdef TEST_MODE
536 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
537 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000538 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500539 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000540 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500541 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 +0000542 return err;
543 }
544 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400545 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000546 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500547 #ifdef TEST_MODE
548 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
549 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000550 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500551 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000552 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500553 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 +0000554 return err;
555 }
556 return flow_cfg.data.classifier.i_pbits;
557 case CLASSIFIER_ETHER_TYPE:
558 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500559 #ifdef TEST_MODE
560 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
561 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000562 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500563 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000564 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500565 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 +0000566 return err;
567 }
568 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400569 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000570 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500571 #ifdef TEST_MODE
572 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
573 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000574 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500575 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000576 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500577 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 +0000578 return err;
579 }
580 return flow_cfg.data.classifier.ip_proto;
581 case CLASSIFIER_SRC_PORT:
582 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500583 #ifdef TEST_MODE
584 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
585 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000586 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500587 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000588 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500589 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 +0000590 return err;
591 }
592 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400593 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000594 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500595 #ifdef TEST_MODE
596 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
597 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000598 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500599 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000600 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500601 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 +0000602 return err;
603 }
604 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400605 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000606 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500607 #ifdef TEST_MODE
608 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
609 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000610 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500611 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000612 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500613 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 +0000614 return err;
615 }
616 return flow_cfg.data.classifier.pkt_tag_type;
617 case EGRESS_QOS_TYPE:
618 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500619 #ifdef TEST_MODE
620 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
621 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000622 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500623 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000624 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500625 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 +0000626 return err;
627 }
628 return flow_cfg.data.egress_qos.type;
629 case EGRESS_QOS_QUEUE_ID:
630 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500631 #ifdef TEST_MODE
632 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
633 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000634 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500635 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000636 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500637 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 +0000638 return err;
639 }
640 switch (flow_cfg.data.egress_qos.type) {
641 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
642 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
643 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
644 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
645 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
646 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
647 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
648 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
649 case BCMOLT_EGRESS_QOS_TYPE_NONE:
650 default:
651 return -1;
652 }
653 case EGRESS_QOS_TM_SCHED_ID:
654 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500655 #ifdef TEST_MODE
656 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
657 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000658 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500659 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000660 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500661 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 +0000662 return err;
663 }
664 return flow_cfg.data.egress_qos.tm_sched.id;
665 case ACTION_CMDS_BITMASK:
666 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500667 #ifdef TEST_MODE
668 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
669 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000670 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500671 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000672 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500673 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 +0000674 return err;
675 }
676 return flow_cfg.data.action.cmds_bitmask;
677 case ACTION_O_VID:
678 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500679 #ifdef TEST_MODE
680 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
681 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000682 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500683 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000684 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500685 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 +0000686 return err;
687 }
688 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400689 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000690 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500691 #ifdef TEST_MODE
692 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
693 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000694 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500695 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000696 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500697 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 +0000698 return err;
699 }
700 return flow_cfg.data.action.o_pbits;
701 case ACTION_I_VID:
702 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500703 #ifdef TEST_MODE
704 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
705 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000706 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500707 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000708 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500709 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 +0000710 return err;
711 }
712 return flow_cfg.data.action.i_vid;
713 case ACTION_I_PBITS:
714 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500715 #ifdef TEST_MODE
716 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
717 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000718 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500719 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000720 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500721 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 +0000722 return err;
723 }
724 return flow_cfg.data.action.i_pbits;
725 case STATE:
726 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500727 #ifdef TEST_MODE
728 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
729 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000730 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500731 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000732 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500733 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000734 return err;
735 }
736 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000737 case GROUP_ID:
738 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
739 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
740 if (err) {
741 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
742 return err;
743 }
744 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000745 default:
746 return BCM_ERR_INTERNAL;
747 }
748
749 return err;
750}
751
752Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400753 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000754 bcmolt_pon_interface_cfg interface_obj;
755 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
756 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
757 bcmolt_interface_state state;
758
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400759 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000760 if (err == BCM_ERR_OK) {
761 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800762 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000763 return Status::OK;
764 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400765 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000766 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
767 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
768 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
769 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
770 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
771 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
772 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
773 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
774 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
775 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
776 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
777 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
778 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
779 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
780
781 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
782 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500783 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 +0000784 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
785 }
786 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
787 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500788 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 +0000789 return bcm_to_grpc_err(err, "Failed to enable PON interface");
790 }
791 else {
792 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
793 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
794 CreateDefaultSched(intf_id, downstream);
795 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400796 }
797
798 return Status::OK;
799}
800
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500801Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000802 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400803 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000804 bcmolt_device_key dev_key = { };
805 bcmolt_olt_cfg olt_cfg = { };
806 bcmolt_olt_key olt_key = { };
807 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
808 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500809
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000810 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
811 topo.topology_maps.arr = &topo_map[0];
812 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
813 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
814 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400815 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000816 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400817 #ifdef TEST_MODE
818 // It is impossible to mock the setting of olt_cfg.data.bal_state because
819 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
820 // set the olt_cfg.data.topology. So a new stub function is created and address
821 // of olt_cfg is passed. This is one-of case where we need to test add specific
822 // code in production code.
823 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
824 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000825 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400826 #endif
827 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500828 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 +0000829 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500830 }
831
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000832 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
833 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500834
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400835 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
836 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000837 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500838
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000839 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
840 num_of_nni_ports,
841 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400842 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500843
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000844 uint32_t num_failed_cfg_gets = 0;
Jason Huang09b73ea2020-01-08 17:52:05 +0800845 static std::string openolt_version = firmware_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000846 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
847 dev_key.device_id = devid;
848 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
849 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
850 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
851 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000852 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400853 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500854 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 +0000855 num_failed_cfg_gets++;
856 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000857 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500858
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000859 std::string bal_version;
860 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
861 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
862 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
Jason Huang09b73ea2020-01-08 17:52:05 +0800863 firmware_version = "BAL." + bal_version + "__" + openolt_version;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000864
865 switch(dev_cfg.data.system_mode) {
866 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
867 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
868 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
869 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
870 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
871 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
872 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
873 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
874 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
875 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
876 }
877
878 switch(dev_cfg.data.chip_family) {
Jason Huang09b73ea2020-01-08 17:52:05 +0800879 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X: chip_family = "Maple"; break;
880 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X: chip_family = "Aspen"; break;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000881 }
882
Jason Huang09b73ea2020-01-08 17:52:05 +0800883 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s, family: %s, board_technology: %s\n",
884 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 +0000885
886 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500887 }
888
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000889 /* 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 +0000890 only the devices that retured success*/
891 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
892 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
893 return bcm_to_grpc_err(err, "device: All devices failed query");
894 }
895
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500896 return Status::OK;
897}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400898
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000899Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000900 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000901 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
902 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
903 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500904
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400905 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000906 if (err == BCM_ERR_OK) {
907 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800908 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000909 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
910 CreateDefaultSched(intf_id, upstream);
911 CreateDefaultQueue(intf_id, upstream);
912 return Status::OK;
913 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
914 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
915 return Status::OK;
916 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -0500917 }
918
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000919 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
920 if (set_state) {
921 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
922 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
923 } else {
924 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
925 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
926 }
927 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
928 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500929 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
930 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000931 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
932 }
933 else {
934 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
935 if (set_state) {
936 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
937 CreateDefaultSched(intf_id, upstream);
938 CreateDefaultQueue(intf_id, upstream);
939 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400940 }
941
942 return Status::OK;
943}
944
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400945Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500946 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000947 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500948 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
949 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400950
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500951 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
952 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
953 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
954
955 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
956 if (err != BCM_ERR_OK) {
957 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
958 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
959 }
960
961 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
962 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
963
964 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
965 if (err != BCM_ERR_OK) {
966 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 -0400967 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400968 }
969
Chaitrashree G S73e084d2019-11-20 16:18:59 -0500970 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400971 return Status::OK;
972}
973
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000974Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700975 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000976 bcmos_errno err = BCM_ERR_OK;
977 bcmolt_onu_cfg onu_cfg;
978 bcmolt_onu_key onu_key;
979 bcmolt_serial_number serial_number; /**< ONU serial number */
980 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000981
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000982 onu_key.onu_id = onu_id;
983 onu_key.pon_ni = intf_id;
984 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
985 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500986 #ifdef TEST_MODE
987 // It is impossible to mock the setting of onu_cfg.data.onu_state because
988 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
989 // set the onu_cfg.data.onu_state. So a new stub function is created and address
990 // of onu_cfg is passed. This is one-of case where we need to add test specific
991 // code in production code.
992 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
993 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000994 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500995 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400996 if (err == BCM_ERR_OK) {
997 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000998 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
999 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1000 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1001 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001002 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001003
1004 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001005vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001006 vendor_specific_to_str(vendor_specific).c_str(), pir);
1007
1008 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1009 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1010 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1011 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1012 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1013 /*set burst and data profiles to fec disabled*/
1014 if (board_technology == "XGS-PON") {
1015 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1016 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1017 } else if (board_technology == "GPON") {
1018 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1019 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1020 }
1021 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1022 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001023 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001024 return bcm_to_grpc_err(err, "Failed to activate ONU");
1025 }
1026
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001027 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001028}
1029
Jonathan Davis70c21812018-07-19 15:32:10 -04001030Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1031 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001032 bcmos_errno err = BCM_ERR_OK;
1033 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1034 bcmolt_onu_cfg onu_cfg;
1035 bcmolt_onu_key onu_key; /**< Object key. */
1036 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001037
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001038 onu_key.onu_id = onu_id;
1039 onu_key.pon_ni = intf_id;
1040 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1041 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001042 #ifdef TEST_MODE
1043 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1044 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1045 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1046 // of onu_cfg is passed. This is one-of case where we need to add test specific
1047 // code in production code.
1048 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
1049 onu_state = onu_cfg.data.onu_state;
1050 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001051 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001052 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001053 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001054 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001055 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001056 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001057 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001058 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1059 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1060 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001061 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 +00001062 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1063 }
1064 break;
1065 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001066 }
1067
1068 return Status::OK;
1069}
1070
1071Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001072 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001073
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001074 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 -05001075 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1076
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001077 // Need to deactivate before removing it (BAL rules)
1078
1079 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1080 // Sleep to allow the state to propagate
1081 // We need the subscriber terminal object to be admin down before removal
1082 // Without sleep the race condition is lost by ~ 20 ms
1083 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1084
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001085 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001086
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001087 bcmolt_onu_cfg cfg_obj;
1088 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001089
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001090 //OPENOLT_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
1091 // onu_id, intf_id);
1092 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 -04001093 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001094
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001095 key.onu_id = onu_id;
1096 key.pon_ni = intf_id;
1097 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001098
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001099 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001100 if (err != BCM_ERR_OK)
1101 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001102 //OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1103 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 -04001104 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1105 }
1106
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001107 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001108}
1109
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001110#define MAX_CHAR_LENGTH 20
1111#define MAX_OMCI_MSG_LENGTH 44
1112Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001113 bcmolt_bin_str buf = {};
1114 bcmolt_onu_cpu_packets omci_cpu_packets;
1115 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001116
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001117 key.pon_ni = intf_id;
1118 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001119
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001120 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1121 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1122 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001123
1124 // ???
1125 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1126 buf.len = MAX_OMCI_MSG_LENGTH;
1127 } else {
1128 buf.len = pkt.size()/2;
1129 }
1130
1131 /* Send the OMCI packet using the BAL remote proxy API */
1132 uint16_t idx1 = 0;
1133 uint16_t idx2 = 0;
1134 uint8_t arraySend[buf.len];
1135 char str1[MAX_CHAR_LENGTH];
1136 char str2[MAX_CHAR_LENGTH];
1137 memset(&arraySend, 0, buf.len);
1138
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001139 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1140 sprintf(str1,"%c", pkt[idx1]);
1141 sprintf(str2,"%c", pkt[++idx1]);
1142 strcat(str1,str2);
1143 arraySend[idx2] = strtol(str1, NULL, 16);
1144 }
1145
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001146 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1147 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001148
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001149 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1150 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1151 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001152
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001153 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001154 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001155 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 +00001156 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001157 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001158 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 -05001159 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001160 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001161 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001162
1163 return Status::OK;
1164}
1165
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001166Status 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 +00001167 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1168 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1169 bcmolt_bin_str buf = {};
1170 bcmolt_gem_port_id gem_port_id_array[1];
1171 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001172
Craig Lutgen967a1d02018-11-27 10:41:51 -06001173 if (port_no > 0) {
1174 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001175 if (gemport_id == 0) {
1176 bcmos_fastlock_lock(&data_lock);
1177 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1178 // Pick any flow that is mapped with the same port_no.
1179 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1180 if (it != port_to_flows.end() && !it->second.empty()) {
1181 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1182 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1183 if (fit != flowid_to_gemport.end()) {
1184 found = true;
1185 gemport_id = fit->second;
1186 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001187 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001188 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001189
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001190 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001191 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 -08001192 onu_id, port_no, intf_id);
1193 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1194 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001195 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 -08001196 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001197 }
1198
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001199 gem_port_id_array[0] = gemport_id;
1200 gem_port_list.len = 1;
1201 gem_port_list.arr = gem_port_id_array;
1202 buf.len = pkt.size();
1203 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1204 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1205
1206 /* init the API struct */
1207 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1208 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1209 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1210 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1211 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1212
1213 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1214 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1215
1216 /* call API */
1217 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001218 }
1219 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001220 //TODO: Port No is 0, it is coming sender requirement.
1221 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1222 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001223 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001224 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001225
1226 return Status::OK;
1227}
1228
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001229Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001230 bcmolt_flow_key key = {}; /* declare key */
1231 bcmolt_bin_str buffer = {};
1232 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001233
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001234 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1235 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001236
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001237 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1238 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1239 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1240 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1241 key.flow_id = flow_id;
1242 else {
Jason Huang09b73ea2020-01-08 17:52:05 +08001243 if (flow_id_counters) {
1244 std::map<flow_pair, int>::iterator it;
1245 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1246 int flow_index = it->first.first;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001247 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1248 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1249 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1250 key.flow_id = flow_index;
1251 break;
1252 }
1253 }
1254 }
1255 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001256 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001257 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1258 }
1259 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001260
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001261 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001262
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001263 /* Initialize the API struct. */
1264 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001265
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001266 buffer.len = pkt.size();
1267 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1268 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1269 if (buffer.arr == NULL) {
1270 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1271 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1272 }
1273 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1274
1275 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1276 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001277 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 -05001278 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001279 } else {
1280 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1281 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001282
1283 return Status::OK;
1284}
Craig Lutgen967a1d02018-11-27 10:41:51 -06001285Status 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 +00001286 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001287 int32_t alloc_id, int32_t network_intf_id,
1288 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001289 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
1290 int32_t group_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001291 bcmolt_flow_cfg cfg;
1292 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001293 int32_t o_vid = -1;
1294 bool single_tag = false;
1295 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001296 bcmolt_classifier c_val = { };
1297 bcmolt_action a_val = { };
1298 bcmolt_tm_queue_ref tm_val = { };
1299 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001300 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001301
Jason Huang09b73ea2020-01-08 17:52:05 +08001302 OPENOLT_LOG(INFO, openolt_log_id, "flow add received for flow_id=%u, flow_type=%s\n", flow_id, flow_type.c_str());
1303
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001304 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001305 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001306 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001307 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001308 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001309 } else if (flow_type.compare(multicast) == 0) {
1310 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001311 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001312 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001313 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001314 }
1315
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001316 BCMOLT_CFG_INIT(&cfg, flow, key);
1317 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001318
Jason Huang09b73ea2020-01-08 17:52:05 +08001319 if (action.cmd().trap_to_host()) {
1320 Status resp = handle_acl_rule_install(onu_id, flow_id, flow_type, access_intf_id,
1321 network_intf_id, gemport_id, classifier);
1322 return resp;
1323 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001324
1325 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1326
1327 if (access_intf_id >= 0 && network_intf_id >= 0) {
1328 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1329 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1330 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08001331 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1332 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001333 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1334 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1335 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1336 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1337 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001338 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001339 } else {
1340 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
1341 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001342 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001343
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001344 if (onu_id >= 0) {
1345 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
1346 }
1347 if (gemport_id >= 0) {
1348 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
1349 }
1350 if (gemport_id >= 0 && port_no != 0) {
1351 bcmos_fastlock_lock(&data_lock);
1352 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1353 port_to_flows[port_no].insert(key.flow_id);
1354 flowid_to_gemport[key.flow_id] = gemport_id;
1355 }
1356 else
1357 {
1358 flowid_to_port[key.flow_id] = port_no;
1359 }
1360 bcmos_fastlock_unlock(&data_lock, 0);
1361 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001362 if (gemport_id >= 0 && access_intf_id >= 0) {
1363 // Update the flow_to_acl_map. Note that since this is a datapath flow, acl_id is -1
1364 // This info is needed during flow remove where we need to retrieve the gemport_id
1365 // and access_intf id for the given flow id and flow direction.
1366 // After retrieving the ACL ID and GEM PORT ID, we decrement the corresponding
1367 // reference counters for those ACL ID and GEMPORT ID.
1368 acl_id_gem_id_intf_id ac_id_gm_id_if_id(-1, gemport_id, access_intf_id);
1369 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1370 bcmos_fastlock_lock(&data_lock);
1371 flow_to_acl_map[fl_id_fl_dir] = ac_id_gm_id_if_id;
1372 bcmos_fastlock_unlock(&data_lock, 0);
1373 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001374 if (priority_value >= 0) {
1375 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
1376 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301377
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001378 } else { // MULTICAST FLOW
1379 if (group_id >= 0) {
1380 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001381 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001382 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1383 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00001384 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001385
1386 {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001387 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001388 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001389 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
1390 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001391 }
1392
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001393 if (classifier.dst_mac().size() > 0) {
1394 bcmos_mac_address d_mac = {};
1395 bcmos_mac_address_init(&d_mac);
1396 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
1397 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
1398 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
1399 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001400 }
1401
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001402 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001403 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001404 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001405 }
1406 */
1407
1408 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001409 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
1410 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001411 }
1412
1413 /*
1414 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001415 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001416 }
1417
1418 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05001419 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001420 }
1421 */
1422
1423 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001424 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
1425 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001426 }
1427
1428 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001429 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
1430 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001431 }
1432
1433 if (!classifier.pkt_tag_type().empty()) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001434 if (classifier.o_vid()) {
1435 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
1436 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
1437 }
1438
1439 if (classifier.i_vid()) {
1440 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
1441 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
1442 }
1443
1444 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
1445 if (classifier.pkt_tag_type().compare("untagged") == 0) {
1446 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
1447 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
1448 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
1449 single_tag = true;
1450
1451 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1452 //According to makeOpenOltClassifierField in voltha-openolt-adapter, o_pbits 0xFF means PCP value 0.
1453 if(0xFF == classifier.o_pbits()){
1454 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301455 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001456 else{
1457 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301458 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001459 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
1460 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001461
Jason Huang09b73ea2020-01-08 17:52:05 +08001462 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
1463 if(0xFF == classifier.o_pbits()){
1464 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
1465 }
1466 else{
1467 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301468 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001469 }
1470 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001471 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001472 }
1473
Jason Huang09b73ea2020-01-08 17:52:05 +08001474 const ::openolt::ActionCmd& cmd = action.cmd();
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001475
Jason Huang09b73ea2020-01-08 17:52:05 +08001476 if (cmd.add_outer_tag()) {
1477 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
1478 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001479 }
1480
Jason Huang09b73ea2020-01-08 17:52:05 +08001481 if (cmd.remove_outer_tag()) {
1482 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
1483 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
1484 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301485
Jason Huang09b73ea2020-01-08 17:52:05 +08001486 if (action.o_vid()) {
1487 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
1488 o_vid = action.o_vid();
1489 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
1490 }
1491
1492 if (action.o_pbits()) {
1493 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
1494 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
1495 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301496
Jason Huang09b73ea2020-01-08 17:52:05 +08001497 if (action.i_vid()) {
1498 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
1499 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
1500 }
1501
1502 if (action.i_pbits()) {
1503 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
1504 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
1505 }
Girish Gowdraddf9a162020-01-27 12:56:27 +05301506
Jason Huang09b73ea2020-01-08 17:52:05 +08001507 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
1508
Shad Ansari39739bc2018-09-13 21:38:37 +00001509 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Jason Huang09b73ea2020-01-08 17:52:05 +08001510 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
1511 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
1512 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001513
Jason Huang09b73ea2020-01-08 17:52:05 +08001514 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1515 // Queue 0 on DS subscriber scheduler
1516 tm_val.queue_id = 0;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001517
Jason Huang09b73ea2020-01-08 17:52:05 +08001518 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1519 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1520 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001521
Jason Huang09b73ea2020-01-08 17:52:05 +08001522 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1523 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1524 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525
Jason Huang09b73ea2020-01-08 17:52:05 +08001526 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1527 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
1528 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 +00001529
Jason Huang09b73ea2020-01-08 17:52:05 +08001530 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1531 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1532 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1533 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 +00001534
Jason Huang09b73ea2020-01-08 17:52:05 +08001535 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
1536 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1537 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1538 }
1539 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
1540 // NNI Scheduler ID
1541 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1542 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
1543 // Queue 0 on NNI scheduler
1544 tm_val.queue_id = 0;
1545 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1546 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1547 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001548
Jason Huang09b73ea2020-01-08 17:52:05 +08001549 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 +00001550 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
1551 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
1552
Jason Huang09b73ea2020-01-08 17:52:05 +08001553 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
1554 /* Fetch TM QMP ID mapped to US NNI scheduler */
1555 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
1556 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
1557 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1558 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
1559 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 +00001560
Jason Huang09b73ea2020-01-08 17:52:05 +08001561 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 +00001562 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
1563 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001564 }
Shad Ansari39739bc2018-09-13 21:38:37 +00001565 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301566 } else {
1567 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
1568 tm_val.queue_id = 0;
1569
1570 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
1571 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
1572 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
1573
1574 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
1575 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
1576 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00001577 }
1578
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001580
1581 // BAL 3.1 supports statistics only for unicast flows.
1582 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
1583 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
1584 }
1585
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001586#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001587 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001588 if (flow_id_counters != 0) {
1589 bool b_duplicate_flow = false;
Jason Huang09b73ea2020-01-08 17:52:05 +08001590 std::map<flow_pair, int>::iterator it;
1591
1592 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1593 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(it->first.first, it->first.second, ONU_ID)) && \
1594 (key.flow_type == it->first.second) && \
1595 (cfg.data.svc_port_id == get_flow_status(it->first.first, it->first.second, SVC_PORT_ID)) && \
1596 (cfg.data.priority == get_flow_status(it->first.first, it->first.second, PRIORITY)) && \
1597 (cfg.data.cookie == get_flow_status(it->first.first, it->first.second, COOKIE)) && \
1598 (cfg.data.ingress_intf.intf_type == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_TYPE)) && \
1599 (cfg.data.ingress_intf.intf_id == get_flow_status(it->first.first, it->first.second, INGRESS_INTF_ID)) && \
1600 (cfg.data.egress_intf.intf_type == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_TYPE)) && \
1601 (cfg.data.egress_intf.intf_id == get_flow_status(it->first.first, it->first.second, EGRESS_INTF_ID)) && \
1602 (c_val.o_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_VID)) && \
1603 (c_val.o_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_O_PBITS)) && \
1604 (c_val.i_vid == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_VID)) && \
1605 (c_val.i_pbits == get_flow_status(it->first.first, it->first.second, CLASSIFIER_I_PBITS)) && \
1606 (c_val.ether_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_ETHER_TYPE)) && \
1607 (c_val.ip_proto == get_flow_status(it->first.first, it->first.second, CLASSIFIER_IP_PROTO)) && \
1608 (c_val.src_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_SRC_PORT)) && \
1609 (c_val.dst_port == get_flow_status(it->first.first, it->first.second, CLASSIFIER_DST_PORT)) && \
1610 (c_val.pkt_tag_type == get_flow_status(it->first.first, it->first.second, CLASSIFIER_PKT_TAG_TYPE)) && \
1611 (cfg.data.egress_qos.type == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TYPE)) && \
1612 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_QUEUE_ID)) && \
1613 (cfg.data.egress_qos.tm_sched.id == get_flow_status(it->first.first, it->first.second, EGRESS_QOS_TM_SCHED_ID)) && \
1614 (a_val.cmds_bitmask == get_flow_status(it->first.first, it->first.second, ACTION_CMDS_BITMASK)) && \
1615 (a_val.o_vid == get_flow_status(it->first.first, it->first.second, ACTION_O_VID)) && \
1616 (a_val.i_vid == get_flow_status(it->first.first, it->first.second, ACTION_I_VID)) && \
1617 (a_val.o_pbits == get_flow_status(it->first.first, it->first.second, ACTION_O_PBITS)) && \
1618 (a_val.i_pbits == get_flow_status(it->first.first, it->first.second, ACTION_I_PBITS)) && \
1619 (cfg.data.state == get_flow_status(it->first.first, it->first.second, STATE)) && \
1620 (cfg.data.group_id == get_flow_status(it->first.first, it->first.second, GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001621#ifdef SHOW_FLOW_PARAM
1622 // Flow Parameter
1623 FLOW_PARAM_LOG();
1624#endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001625 if (b_duplicate_flow) {
1626 FLOW_LOG(WARNING, "Flow duplicate", 0);
1627 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
1628 }
1629 }
1630 }
1631#endif
1632
1633 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
1634 if (err) {
1635 FLOW_LOG(ERROR, "Flow add failed", err);
1636 return bcm_to_grpc_err(err, "flow add failed");
1637 } else {
1638 FLOW_LOG(INFO, "Flow add ok", err);
1639 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001640 flow_map[std::pair<int, int>(key.flow_id,key.flow_type)] = flow_map.size();
1641 flow_id_counters = flow_map.size();
1642 if (gemport_id > 0 && access_intf_id >= 0) {
1643 gem_id_intf_id gem_intf(gemport_id, access_intf_id);
1644 if (gem_ref_cnt.count(gem_intf) > 0) {
1645 // The gem port is already installed
1646 // Increment the ref counter indicating number of flows referencing this gem port
1647 gem_ref_cnt[gem_intf]++;
1648 OPENOLT_LOG(DEBUG, openolt_log_id, "incremented gem_ref_cnt, gem_ref_cnt=%d\n", gem_ref_cnt[gem_intf]);
1649 } else {
1650 // Initialize the refence count for the gemport.
1651 gem_ref_cnt[gem_intf] = 1;
1652 OPENOLT_LOG(DEBUG, openolt_log_id, "initialized gem_ref_cnt\n");
1653 }
1654 } else {
1655 OPENOLT_LOG(DEBUG, openolt_log_id, "not incrementing gem_ref_cnt flow_id=%d gemport_id=%d access_intf_id=%d\n", flow_id, gemport_id, access_intf_id);
1656 }
1657
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001658 bcmos_fastlock_unlock(&data_lock, 0);
1659 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04001660
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001661 return Status::OK;
1662}
1663
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001664Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
1665
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001666 bcmolt_flow_cfg cfg;
1667 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001668
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001669 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001670 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001671 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001672 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001673 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001674 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001675 } else if(flow_type.compare(multicast) == 0) {
1676 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001677 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001678 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001679 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
1680 }
1681
Jason Huang09b73ea2020-01-08 17:52:05 +08001682 OPENOLT_LOG(INFO, openolt_log_id, "flow remove received for flow_id=%u, flow_type=%s\n",
1683 flow_id, flow_type.c_str());
1684
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001685 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001686 flow_id_flow_direction fl_id_fl_dir(flow_id, flow_type);
1687 int32_t gemport_id = -1;
1688 int32_t intf_id = -1;
1689 int16_t acl_id = -1;
1690 if (flow_to_acl_map.count(fl_id_fl_dir) > 0) {
1691 acl_id_gem_id_intf_id ac_id_gm_id_if_id = flow_to_acl_map[fl_id_fl_dir];
1692 acl_id = std::get<0>(ac_id_gm_id_if_id);
1693 gemport_id = std::get<1>(ac_id_gm_id_if_id);
1694 intf_id = std::get<2>(ac_id_gm_id_if_id);
1695 // cleanup acl only if it is a valid acl. If not valid acl, it may be datapath flow.
1696 if (acl_id >= 0) {
1697 Status resp = handle_acl_rule_cleanup(acl_id, gemport_id, intf_id, flow_type);
1698 bcmos_fastlock_unlock(&data_lock, 0);
1699 if (resp.ok()) {
1700 OPENOLT_LOG(INFO, openolt_log_id, "acl removed ok for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1701 flow_to_acl_map.erase(fl_id_fl_dir);
1702 } else {
1703 OPENOLT_LOG(ERROR, openolt_log_id, "acl remove error for flow_id = %u with acl_id = %d\n", flow_id, acl_id);
1704 }
1705 return resp;
1706 }
1707 }
1708
Craig Lutgen967a1d02018-11-27 10:41:51 -06001709 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001710 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06001711 flowid_to_gemport.erase(key.flow_id);
1712 port_to_flows[port_no].erase(key.flow_id);
1713 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
1714 }
1715 else
1716 {
1717 flowid_to_port.erase(key.flow_id);
1718 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001719 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001720
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001721 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001722
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001723 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001724 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001725 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 -04001726 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
1727 }
1728
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001729 bcmos_fastlock_lock(&data_lock);
Jason Huang09b73ea2020-01-08 17:52:05 +08001730 if (flow_id_counters != 0) {
1731 std::map<flow_pair, int>::iterator it;
1732 for(it = flow_map.begin(); it != flow_map.end(); it++) {
1733 if (it->first.first == flow_id && it->first.second == key.flow_type) {
1734 flow_id_counters -= 1;
1735 flow_map.erase(it);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001736 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001737 }
1738 }
Jason Huang09b73ea2020-01-08 17:52:05 +08001739 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
1740
1741 clear_gem_port(gemport_id, intf_id);
1742
1743 flow_to_acl_map.erase(fl_id_fl_dir);
1744
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001745 bcmos_fastlock_unlock(&data_lock, 0);
1746
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04001747 return Status::OK;
1748}
1749
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001750bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
1751 bcmos_errno err;
1752 bcmolt_tm_sched_cfg tm_sched_cfg;
1753 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1754 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
1755
Jason Huangbf45ffb2019-10-30 17:29:02 +08001756 //check TM scheduler has configured or not
1757 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1758 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001759 #ifdef TEST_MODE
1760 // It is impossible to mock the setting of tm_sched_cfg.data.state because
1761 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
1762 // set the tm_sched_cfg.data.state. So a new stub function is created and address
1763 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
1764 // code in production code.
1765 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
1766 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08001767 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001768 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08001769 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001770 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 +08001771 return err;
1772 }
1773 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
1774 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
1775 return BCM_ERR_OK;
1776 }
1777
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001778 // bcmbal_tm_sched_owner
1779 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
1780
1781 /**< The output of the tm_sched object instance */
1782 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
1783
1784 if (direction.compare(upstream) == 0) {
1785 // In upstream it is NNI scheduler
1786 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
1787 } else if (direction.compare(downstream) == 0) {
1788 // In downstream it is PON scheduler
1789 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
1790 }
1791
1792 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
1793
1794 // bcmbal_tm_sched_type
1795 // set the deafult policy to strict priority
1796 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
1797
1798 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001799 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001800
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001801 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
1802 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001803 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
1804 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001805 return err;
1806 }
1807
1808 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
1809 direction.c_str(), tm_sched_key.id, intf_id);
1810 return BCM_ERR_OK;
1811}
1812
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001813bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
1814 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
1815 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001816
1817 bcmos_errno err;
1818
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001819 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001820 bcmolt_tm_sched_cfg tm_sched_cfg;
1821 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
1822 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001823
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001824 // bcmbal_tm_sched_owner
1825 // In downstream it is sub_term scheduler
1826 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001827
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001828 /**< The output of the tm_sched object instance */
1829 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001830
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001831 // bcmbal_tm_sched_parent
1832 // The parent for the sub_term scheduler is the PON scheduler in the downstream
1833 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
1834 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 +00001835 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001836 be achieved using the' virtual' type of attachment.
1837 tm_sched_owner.u.sub_term.intf_id = intf_id;
1838 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
1839 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001840
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001841 // bcmbal_tm_sched_type
1842 // set the deafult policy to strict priority
1843 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001844
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001845 // num_priorities: Max number of strict priority scheduling elements
1846 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001847
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001848 // bcmbal_tm_shaping
1849 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
1850 uint32_t cir = tf_sh_info.cir();
1851 uint32_t pir = tf_sh_info.pir();
1852 uint32_t burst = tf_sh_info.pbs();
1853 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
1854 cir, pir, burst);
1855 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
1856 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
1857 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
1858 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
1859 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
1860 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001861 }
1862
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001863 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001864 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001865 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001866intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
1867port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001868 return err;
1869 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001870 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
1871uni_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 -08001872
1873 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001874 bcmolt_itupon_alloc_cfg cfg;
1875 bcmolt_itupon_alloc_key key = { };
1876 key.pon_ni = intf_id;
1877 key.alloc_id = alloc_id;
1878 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
Burak Gurdag03919c72020-02-04 22:46:57 +00001879 int pir_bw = tf_sh_info.pir()*125; // conversion from kbps to bytes/sec
1880 int cir_bw = tf_sh_info.cir()*125; // conversion from kbps to bytes/sec
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001881 //offset to match bandwidth granularity
1882 int offset_pir_bw = pir_bw%bw_granularity;
1883 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001884
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001885 pir_bw = pir_bw - offset_pir_bw;
1886 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001887
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001888 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001889
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001890 switch (additional_bw) {
1891 case 2: //AdditionalBW_BestEffort
1892 if (pir_bw == 0) {
1893 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1894%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001895 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001896 } else if (pir_bw < cir_bw) {
1897 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1898bandwidth (%d)\n", pir_bw, cir_bw);
1899 return BCM_ERR_PARM;
1900 } else if (pir_bw == cir_bw) {
1901 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1902bandwidth for additional bandwidth eligibility of type best_effort\n");
1903 return BCM_ERR_PARM;
1904 }
1905 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
1906 break;
1907 case 1: //AdditionalBW_NA
1908 if (pir_bw == 0) {
1909 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
1910%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
1911 return BCM_ERR_PARM;
1912 } else if (cir_bw == 0) {
1913 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
1914additional bandwidth eligibility of type Non-Assured (NA)\n");
1915 return BCM_ERR_PARM;
1916 } else if (pir_bw < cir_bw) {
1917 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1918bandwidth (%d)\n", pir_bw, cir_bw);
1919 return BCM_ERR_PARM;
1920 } else if (pir_bw == cir_bw) {
1921 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
1922bandwidth for additional bandwidth eligibility of type non_assured\n");
1923 return BCM_ERR_PARM;
1924 }
1925 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
1926 break;
1927 case 0: //AdditionalBW_None
1928 if (pir_bw == 0) {
1929 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
193016000 bytes/sec\n");
1931 return BCM_ERR_PARM;
1932 } else if (cir_bw == 0) {
1933 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1934for additional bandwidth eligibility of type None\n");
1935 return BCM_ERR_PARM;
1936 } else if (pir_bw > cir_bw) {
1937 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
1938for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001939 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001940bandwidth in None eligibility\n", pir_bw);
1941 cir_bw = pir_bw;
1942 } else if (pir_bw < cir_bw) {
1943 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
1944bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001945 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001946bandwidth in None eligibility\n", pir_bw);
1947 cir_bw = pir_bw;
1948 }
1949 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
1950 break;
1951 default:
1952 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08001953 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001954 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
1955 in a fine granularity. */
1956 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
1957 /* Fixed Bandwidth with no critical requirement of shaping */
1958 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
1959 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
1960 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
1961 /* Maximum allocated bandwidth allowed for this alloc ID */
1962 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
1963 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001964 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001965 for skipped allocations during quiet window */
1966 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
1967 /**< Allocation Profile index for CBR non-RT Bandwidth */
1968 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
1969 /**< Allocation Profile index for CBR RT Bandwidth */
1970 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
1971 /**< Alloc ID Weight used in case of Extended DBA mode */
1972 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
1973 /**< Alloc ID Priority used in case of Extended DBA mode */
1974 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
1975 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001976
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001977 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001978 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001979 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001980port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001981 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001982 }
Girish Gowdra96461052019-11-22 20:13:59 +05301983
1984 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
1985 if (err) {
1986 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
1987port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
1988 return err;
1989 }
1990
1991 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
1992port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
1993
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001994 }
1995
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001996 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001997}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001998
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001999Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2000 uint32_t intf_id = traffic_scheds->intf_id();
2001 uint32_t onu_id = traffic_scheds->onu_id();
2002 uint32_t uni_id = traffic_scheds->uni_id();
2003 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002004 std::string direction;
2005 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002006 tech_profile::SchedulerConfig sched_config;
2007 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002008 uint32_t priority;
2009 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002010 tech_profile::SchedulingPolicy sched_policy;
2011 tech_profile::TrafficShapingInfo traffic_shaping_info;
2012 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002013
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002014 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2015 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002016
2017 direction = GetDirection(traffic_sched.direction());
2018 if (direction.compare("direction-not-supported") == 0)
2019 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2020
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002021 alloc_id = traffic_sched.alloc_id();
2022 sched_config = traffic_sched.scheduler();
2023 additional_bw = sched_config.additional_bw();
2024 priority = sched_config.priority();
2025 weight = sched_config.weight();
2026 sched_policy = sched_config.sched_policy();
2027 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2028 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2029 sched_policy, traffic_shaping_info);
2030 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002031 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002032 return bcm_to_grpc_err(err, "Failed to create scheduler");
2033 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002034 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002035 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002036}
Jonathan Davis70c21812018-07-19 15:32:10 -04002037
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002038bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002039
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002040 bcmos_errno err;
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302041 bcmolt_interface_state state;
Girish Gowdra96461052019-11-22 20:13:59 +05302042 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002043
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002044 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002045 bcmolt_itupon_alloc_cfg cfg;
2046 bcmolt_itupon_alloc_key key = { };
2047 key.pon_ni = intf_id;
2048 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302049 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002050
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002051 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002052 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2053 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002054 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2055 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002056 return err;
2057 }
Girish Gowdra96461052019-11-22 20:13:59 +05302058
Thiyagarajan Subramani8305c282020-02-04 20:07:42 +05302059 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
2060 if (err == BCM_ERR_OK) {
2061 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
2062 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is enabled, waiting for alloc cfg clear response\n",
2063 intf_id);
2064 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2065 if (err) {
2066 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2067 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2068 return err;
2069 }
2070 }
2071 else if (state == BCMOLT_INTERFACE_STATE_INACTIVE) {
2072 OPENOLT_LOG(INFO, openolt_log_id, "PON interface: %d is disabled, not waiting for alloc cfg clear response\n",
2073 intf_id);
2074 }
2075 }
2076 else {
2077 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to fetch PON interface state, intf_id = %d, err = %s\n",
2078 intf_id, bcmos_strerror(err));
Girish Gowdra96461052019-11-22 20:13:59 +05302079 return err;
2080 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002081 } else if (direction == downstream) {
2082 bcmolt_tm_sched_cfg cfg;
2083 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002084
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002085 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2086 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05302087 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002088 } else {
2089 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2090 return BCM_ERR_OK;
2091 }
Girish Gowdra96461052019-11-22 20:13:59 +05302092
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002093 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2094 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2095 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002096 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2097intf_id %d, onu_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002098 return err;
2099 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002100 }
2101
Girish Gowdra96461052019-11-22 20:13:59 +05302102 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
2103 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002104 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002105 return BCM_ERR_OK;
2106}
2107
2108Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2109 uint32_t intf_id = traffic_scheds->intf_id();
2110 uint32_t onu_id = traffic_scheds->onu_id();
2111 uint32_t uni_id = traffic_scheds->uni_id();
2112 std::string direction;
2113 bcmos_errno err;
2114
2115 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2116 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002117
2118 direction = GetDirection(traffic_sched.direction());
2119 if (direction.compare("direction-not-supported") == 0)
2120 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2121
2122 int alloc_id = traffic_sched.alloc_id();
2123 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002124 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002125 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002126 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2127 }
2128 }
2129 return Status::OK;
2130}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002131
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002132bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2133 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002134 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002135 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2136 bcmolt_tm_qmp_key tm_qmp_key;
2137 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002138
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002139 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2140 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002141 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2142 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002143 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002144
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002145 tm_qmp_key.id = tm_qmp_id;
2146 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2147 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2148 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002149
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002150 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2151 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2152 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
Jason Huang09b73ea2020-01-08 17:52:05 +08002153 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2154 //BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002155
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002156 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002157 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002158 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2159 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002160 return err;
2161 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002162
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002163 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2164 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002165 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002166}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002167
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002168bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2169 bcmos_errno err;
2170 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2171 bcmolt_tm_qmp_key tm_qmp_key;
2172 tm_qmp_key.id = tm_qmp_id;
2173
2174 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2175 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2176 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002177 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2178 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002179 return err;
2180 }
2181
2182 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2183 tm_qmp_key.id);
2184 return BCM_ERR_OK;
2185}
2186
2187bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2188 bcmos_errno err;
2189
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002190 /* Create default queues on the given PON/NNI scheduler */
2191 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002192 bcmolt_tm_queue_cfg tm_queue_cfg;
2193 bcmolt_tm_queue_key tm_queue_key = {};
2194 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2195 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002196 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2197 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2198 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002199
2200 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2201 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2202 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2203
2204 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2205 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002206 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", \
2207 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 +00002208 return err;
2209 }
2210
2211 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2212 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2213 }
2214 return BCM_ERR_OK;
2215}
2216
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002217bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2218 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002219 bcmos_errno err;
2220 bcmolt_tm_queue_cfg cfg;
2221 bcmolt_tm_queue_key key = { };
2222 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2223gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2224
2225 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2226 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2227
2228 if (priority > 7) {
2229 return BCM_ERR_RANGE;
2230 }
2231
2232 /* FIXME: The upstream queues have to be created once only.
2233 The upstream queues on the NNI scheduler are shared by all subscribers.
2234 When the first scheduler comes in, the queues get created, and are re-used by all others.
2235 Also, these queues should be present until the last subscriber exits the system.
2236 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2237
2238 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2239 for each GEM in TECH PROFILE */
2240 key.id = queue_id_list[priority];
2241
2242 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2243 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2244 key.id = 0;
2245 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2246 }
2247 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2248 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2249 }
2250 else {
2251 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2252 }
2253
2254 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2255
2256 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2257 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2258
2259 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2260 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002261 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
2262sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
2263 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002264 return err;
2265 }
2266
2267 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2268intf_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);
2269 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002270}
2271
2272Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2273 uint32_t intf_id = traffic_queues->intf_id();
2274 uint32_t onu_id = traffic_queues->onu_id();
2275 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002276 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002277 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002278 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002279 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 +00002280
2281 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2282 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2283 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2284 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2285 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2286
2287 direction = GetDirection(traffic_queue.direction());
2288 if (direction.compare("direction-not-supported") == 0)
2289 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2290
2291 queues_priority_q[i] = traffic_queue.priority();
2292 queues_pbit_map[i] = traffic_queue.pbit_map();
2293 }
2294
2295 std::vector<uint32_t> tmq_map_profile(8, 0);
2296 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2297 queues_priority_q, COUNT_OF(queues_priority_q));
2298 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2299 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2300
2301 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2302 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002303 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2304 if (err != BCM_ERR_OK) {
2305 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2306 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
2307 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002308 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2309 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2310 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2311 }
2312 }
2313
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002314 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2315 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316
2317 direction = GetDirection(traffic_queue.direction());
2318 if (direction.compare("direction-not-supported") == 0)
2319 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2320
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002321 err = CreateQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002322
Girish Gowdruf26cf882019-05-01 23:47:58 -07002323 // If the queue exists already, lets not return failure and break the loop.
2324 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002325 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002326 return bcm_to_grpc_err(err, "Failed to create queue");
2327 }
2328 }
2329 return Status::OK;
2330}
2331
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002332bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2333 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002334 bcmolt_tm_queue_cfg cfg;
2335 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002336 bcmos_errno err;
2337
2338 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002339 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2340 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2341 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002342 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002343 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 -08002344 return BCM_ERR_OK;
2345 }
2346 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002347 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2348 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002349 return BCM_ERR_OK;
2350 }
2351
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002352 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2353 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2354 // Reset the queue id to 0 when using fixed queue.
2355 key.id = 0;
2356 }
2357 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2358 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2359 }
2360 else {
2361 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2362 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002363
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002364 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2365 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002366 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002367 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
2368tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
2369 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 -08002370 return err;
2371 }
2372
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002373 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2374intf_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 -08002375
2376 return BCM_ERR_OK;
2377}
2378
2379Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2380 uint32_t intf_id = traffic_queues->intf_id();
2381 uint32_t onu_id = traffic_queues->onu_id();
2382 uint32_t uni_id = traffic_queues->uni_id();
2383 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002384 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002385 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002386 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002387 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 +00002388
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002389 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2390 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002391
2392 direction = GetDirection(traffic_queue.direction());
2393 if (direction.compare("direction-not-supported") == 0)
2394 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2395
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002396 err = RemoveQueue(direction, intf_id, onu_id, uni_id, qos_type, traffic_queue.priority(), traffic_queue.gemport_id());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002397 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002398 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002399 return bcm_to_grpc_err(err, "Failed to remove queue");
2400 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002401 }
2402
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002403 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))) {
2404 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2405 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2406
2407 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2408 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002409 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
2410 if (err != BCM_ERR_OK) {
2411 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
2412 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
2413 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002414 }
2415 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002416 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04002417 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04002418}
Jason Huangbf45ffb2019-10-30 17:29:02 +08002419
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002420Status PerformGroupOperation_(const openolt::Group *group_cfg) {
2421
2422 bcmos_errno err;
2423 bcmolt_group_key key = {};
2424 bcmolt_group_cfg grp_cfg_obj;
2425 bcmolt_group_members_update grp_mem_upd;
2426 bcmolt_members_update_command grp_mem_upd_cmd;
2427 bcmolt_group_member_info member_info = {};
2428 bcmolt_group_member_info_list_u8 members = {};
2429 bcmolt_intf_ref interface_ref = {};
2430 bcmolt_egress_qos egress_qos = {};
2431 bcmolt_tm_sched_ref tm_sched_ref = {};
2432 bcmolt_action a_val = {};
2433
2434 uint32_t group_id = group_cfg->group_id();
2435
2436 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
2437
2438 if (group_id >= 0) {
2439 key.id = group_id;
2440 }
2441 else {
2442 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
2443 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
2444 }
2445
2446 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2447 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
2448
2449 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
2450
2451 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
2452 if (err != BCM_ERR_OK) {
2453 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
2454 return bcm_to_grpc_err(err, "Error in querying group");
2455 }
2456
2457 members.len = group_cfg->members_size();
2458
2459 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
2460 // Group type is determined after a flow is assigned to it.
2461 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
2462 // Only then we can add members to the group.
2463
2464 // if group does not exist, create it and return.
2465 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
2466
2467 if (members.len != 0) {
2468 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);
2469 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
2470 } else {
2471
2472 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
2473 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
2474
2475 /* Setting group actions and action parameters, if any.
2476 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
2477 are supported for multicast groups in BAL 3.1.
2478 */
2479 const ::openolt::Action& action = group_cfg->action();
2480 const ::openolt::ActionCmd &cmd = action.cmd();
2481
2482 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
2483 if (cmd.remove_outer_tag()) {
2484 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
2485 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
2486 }
2487
2488 if (cmd.translate_inner_tag()) {
2489 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
2490 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
2491 }
2492
2493 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
2494
2495 if (action.i_vid()) {
2496 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
2497 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
2498 }
2499
2500 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
2501
2502 // Create group
2503 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
2504
2505 if (BCM_ERR_OK != err) {
2506 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
2507 return bcm_to_grpc_err(err, "Error in creating group");
2508 }
2509
2510 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
2511 return Status::OK;
2512 }
2513 }
2514
2515 // The group already exists. Continue configuring it according to the update member command.
2516
2517 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
2518
2519 // MEMBER LIST CONSTRUCTION
2520 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
2521 // empty list to the group is a legit operation and this actually empties the member list.
2522 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
2523
2524 if (!members.arr) {
2525 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
2526 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
2527 }
2528
2529 /* SET GROUP MEMBERS UPDATE COMMAND */
2530 openolt::Group::GroupMembersCommand command = group_cfg->command();
2531 switch(command) {
2532 case openolt::Group::SET_MEMBERS :
2533 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
2534 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
2535 break;
2536 case openolt::Group::ADD_MEMBERS :
2537 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
2538 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
2539 break;
2540 case openolt::Group::REMOVE_MEMBERS :
2541 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
2542 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
2543 break;
2544 default :
2545 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
2546 bcmos_free(members.arr);
2547 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
2548 }
2549
2550 // SET MEMBERS LIST
2551 for (int i = 0; i < members.len; i++) {
2552
2553 if (command == openolt::Group::REMOVE_MEMBERS) {
2554 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
2555 } else {
2556 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
2557 }
2558
2559 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
2560
2561 // Set member interface type
2562 openolt::GroupMember::InterfaceType if_type = member->interface_type();
2563 switch(if_type){
2564 case openolt::GroupMember::PON :
2565 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
2566 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
2567 break;
2568 case openolt::GroupMember::EPON_1G_PATH :
2569 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
2570 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
2571 break;
2572 case openolt::GroupMember::EPON_10G_PATH :
2573 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
2574 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
2575 break;
2576 default :
2577 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
2578 bcmos_free(members.arr);
2579 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
2580 }
2581
2582 // Set member interface id
2583 if (member->interface_id() >= 0) {
2584 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
2585 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
2586 } else {
2587 bcmos_free(members.arr);
2588 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
2589 }
2590
2591 // Set member interface_ref
2592 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
2593
2594 // Set member gem_port_id. This must be a multicast gemport.
2595 if (member->gem_port_id() >= 0) {
2596 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
2597 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
2598 } else {
2599 bcmos_free(members.arr);
2600 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
2601 }
2602
2603 // Set member scheduler id and queue_id
2604 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
2605 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
2606 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
2607 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
2608
2609 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
2610 uint32_t tm_queue_id;
2611 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
2612 tm_queue_id = queue_id_list[member->priority()];
2613 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
2614 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2615 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
2616 } else {
2617 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
2618 bcmos_free(members.arr);
2619 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
2620 }
2621
2622 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
2623 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
2624 }
2625
2626 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
2627 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
2628 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
2629
2630 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
2631 bcmos_free(members.arr);
2632
2633 if (BCM_ERR_OK != err) {
2634 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);
2635 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
2636 }
2637
2638 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
2639
2640 return Status::OK;
2641}