blob: 582373ebd780285ec3025c4d84e566264fadbbf5 [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>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000028
Craig Lutgen88a22ad2018-10-04 12:30:46 -050029#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000030#include "core.h"
31#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040032#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040033#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040034#include "state.h"
Craig Lutgen88a22ad2018-10-04 12:30:46 -050035#include "utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000036
37extern "C"
38{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000039#include <bcmolt_api.h>
40#include <bcmolt_host_api.h>
41#include <bcmolt_api_model_supporting_enums.h>
42
43#include <bal_version.h>
44#include <bcmolt_api_conn_mgr.h>
45//CLI header files
46#include <bcmcli_session.h>
47#include <bcmcli.h>
48#include <bcm_api_cli.h>
49
50#include <bcmos_common.h>
51#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040052// FIXME : dependency problem
53// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040054// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000055}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000056
Shad Ansarib7b0ced2018-05-11 21:53:32 +000057
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040058dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
59dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
60
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080062#define MAX_TM_QUEUE_ID 8192
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000063#define MAX_TM_QMP_ID 16
64#define TMQ_MAP_PROFILE_SIZE 8
65#define MAX_TM_SCHED_ID 1023
66#define MAX_SUBS_TM_SCHED_ID (MAX_SUPPORTED_PON == 16 ? MAX_TM_SCHED_ID-4-16 : MAX_TM_SCHED_ID-10-64)
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067#define EAP_ETHER_TYPE 34958
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000068#define XGS_BANDWIDTH_GRANULARITY 16000
69#define GPON_BANDWIDTH_GRANULARITY 32000
70#define FILL_ARRAY(ARRAY,START,END,VALUE) for(int i=START;i<END;ARRAY[i++]=VALUE);
71#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
72
73#define GET_FLOW_INTERFACE_TYPE(type) \
74 (type == BCMOLT_FLOW_INTERFACE_TYPE_PON) ? "PON" : \
75 (type == BCMOLT_FLOW_INTERFACE_TYPE_NNI) ? "NNI" : \
76 (type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) ? "HOST" : "unknown"
77#define GET_PKT_TAG_TYPE(type) \
78 (type == BCMOLT_PKT_TAG_TYPE_UNTAGGED) ? "UNTAG" : \
79 (type == BCMOLT_PKT_TAG_TYPE_SINGLE_TAG) ? "SINGLE_TAG" : \
80 (type == BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG) ? "DOUBLE_TAG" : "unknown"
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040081
Craig Lutgen88a22ad2018-10-04 12:30:46 -050082static unsigned int num_of_nni_ports = 0;
83static unsigned int num_of_pon_ports = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000084static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050085static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050086static const std::string MIXED_TECH("mixed");
87static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000088static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -080089static unsigned int OPENOLT_FIELD_LEN = 200;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000090static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000092const uint32_t tm_upstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
93 MAX_TM_SCHED_ID-3 : MAX_TM_SCHED_ID-9);
94const uint32_t tm_downstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
95 tm_upstream_sched_id_start-16 : tm_upstream_sched_id_start-64);
96
97/* Max Queue ID supported is 7 so based on priority_q configured for GEMPORTS
98in TECH PROFILE respective Queue ID from this list will be used for both
99US and DS Queues*/
100const uint32_t queue_id_list[8] = {0, 1, 2, 3, 4, 5, 6, 7};
101
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700102const std::string upstream = "upstream";
103const std::string downstream = "downstream";
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000104bcmolt_oltid dev_id = 0;
105
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000106/* Constants used for retrying some BAL APIs */
107const uint32_t BAL_API_RETRY_TIME_IN_USECS = 1000000;
108const uint32_t MAX_BAL_API_RETRY_COUNT = 5;
109
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000110/* Current session */
111static bcmcli_session *current_session;
112static bcmcli_entry *api_parent_dir;
113bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
114bcmos_task bal_cli_thread;
115const char *bal_cli_thread_name = "bal_cli_thread";
116uint16_t flow_id_counters = 0;
117int flow_id_data[16384][2];
Shad Ansariedef2132018-08-10 22:14:50 +0000118State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400119
Craig Lutgen967a1d02018-11-27 10:41:51 -0600120static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
121static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
122static std::map<uint32_t, std::set<uint32_t> > port_to_flows; // For mapping logical ports to downstream flows
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800123
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000124/* This represents the Key to 'sched_map' map.
125 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800126typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000127/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
128 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800129static std::map<sched_map_key_tuple, int> sched_map;
130
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500131/* This represents the Key to 'qos_type_map' map.
132 Represents (pon_intf_id, onu_id, uni_id) */
133typedef std::tuple<uint32_t, uint32_t, uint32_t> qos_type_map_key_tuple;
134/* 'qos_type_map' maps qos_type_map_key_tuple to qos_type*/
135static std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type> qos_type_map;
136
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000137/* This represents the Key to 'sched_qmp_id_map' map.
138Represents (sched_id, pon_intf_id, onu_id, uni_id) */
139typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
140/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
141static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
142/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
143static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800144
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500145// Flag used to watch whether mocked alloc_cfg_compltd_key is added to alloc_cfg_compltd_map
146#ifdef TEST_MODE
147bool ALLOC_CFG_FLAG = false;
148#endif
149
Girish Gowdra96461052019-11-22 20:13:59 +0530150#define ALLOC_CFG_COMPLETE_WAIT_TIMEOUT 1000 // in milli-seconds
151// Map used to track response from BAL for ITU PON Alloc Configuration.
152// The key is alloc_cfg_compltd_key and value is a concurrent thread-safe queue which is
153// used for pushing (from BAL) and popping (at application) the results.
154std::map<alloc_cfg_compltd_key, Queue<alloc_cfg_complete_result> *> alloc_cfg_compltd_map;
155// Lock to protect critical section data structure used for handling AllocObject configuration response.
156bcmos_fastlock alloc_cfg_wait_lock;
157
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800158std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000159std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800160
161static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600162
Girish Gowdra96461052019-11-22 20:13:59 +0530163
Craig Lutgen967a1d02018-11-27 10:41:51 -0600164#define MIN_ALLOC_ID_GPON 256
165#define MIN_ALLOC_ID_XGSPON 1024
166
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800167static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
168 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
169 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
170 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000171static 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 -0800172static 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 -0500173 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
174static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
175 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000176static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
177static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
178
179uint16_t get_dev_id(void) {
180 return dev_id;
181}
Shad Ansari627b5782018-08-13 22:49:32 +0000182
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400183// Stubbed defntions of bcmolt_cfg_get required for unit-test
184#ifdef TEST_MODE
185extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500186extern bcmos_errno bcmolt_cfg_get__onu_state_stub(bcmolt_oltid olt_id, void* ptr);
187extern bcmos_errno bcmolt_cfg_get__tm_sched_stub(bcmolt_oltid olt_id, void* ptr);
188extern bcmos_errno bcmolt_cfg_get__pon_intf_stub(bcmolt_oltid olt_id, void* ptr);
189extern bcmos_errno bcmolt_cfg_get__nni_intf_stub(bcmolt_oltid olt_id, void* ptr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400190extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
191#endif
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800192/**
193* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
194* Every NNI port and PON port have default scheduler.
195* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
196* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
197*
198* @param intf_id NNI or PON interface ID
199* @param direction "upstream" or "downstream"
200*
201* @return default scheduler ID for the given interface.
202*/
203static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700204 if (direction.compare(upstream) == 0) {
205 return tm_upstream_sched_id_start + intf_id;
206 } else if (direction.compare(downstream) == 0) {
207 return tm_downstream_sched_id_start + intf_id;
208 }
209 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000210 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700211 return 0;
212 }
213}
214
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800215/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800216* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
217* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
218* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
219*
220* @param intf_id NNI or PON intf ID
221* @param onu_id ONU ID
222* @param uni_id UNI ID
223* @param gemport_id GEM Port ID
224* @param direction Upstream or downstream
225*
226* @return tm_sched_id
227*/
228uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
229 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
230 int sched_id = -1;
231
232 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
233 if (it != sched_map.end()) {
234 sched_id = it->second;
235 }
236 if (sched_id != -1) {
237 return sched_id;
238 }
239
240 bcmos_fastlock_lock(&data_lock);
241 // Complexity of O(n). Is there better way that can avoid linear search?
242 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
243 if (tm_sched_bitset[sched_id] == 0) {
244 tm_sched_bitset[sched_id] = 1;
245 break;
246 }
247 }
248 bcmos_fastlock_unlock(&data_lock, 0);
249
250 if (sched_id < MAX_TM_SCHED_ID) {
251 bcmos_fastlock_lock(&data_lock);
252 sched_map[key] = sched_id;
253 bcmos_fastlock_unlock(&data_lock, 0);
254 return sched_id;
255 } else {
256 return -1;
257 }
258}
259
260/**
261* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
262*
263* @param intf_id NNI or PON intf ID
264* @param onu_id ONU ID
265* @param uni_id UNI ID
266* @param gemport_id GEM Port ID
267* @param direction Upstream or downstream
268*/
269void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
270 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
271 std::map<sched_map_key_tuple, int>::const_iterator it;
272 bcmos_fastlock_lock(&data_lock);
273 it = sched_map.find(key);
274 if (it != sched_map.end()) {
275 tm_sched_bitset[it->second] = 0;
276 sched_map.erase(it);
277 }
278 bcmos_fastlock_unlock(&data_lock, 0);
279}
280
281bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
282 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000283 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
284 if (it != sched_map.end()) {
285 return true;
286 }
287 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800288}
289
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000290/**
291* Check whether given two tm qmp profiles are equal or not
292*
293* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
294* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
295*
296* @return boolean, true if given tmq_map_profiles are equal else false
297*/
298
299bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
300 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
301 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
302 return false;
303 }
304 }
305 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000306}
307
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000308/**
309* Modifies given queues_pbit_map to parsable format
310* e.g: Modifes "0b00000101" to "10100000"
311*
312* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
313* @param size Queue count
314*
315* @return string queues_pbit_map
316*/
317std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
318 for(uint32_t i=0; i < size; i++) {
319 /* Deletes 2 characters from index number 0 */
320 queues_pbit_map[i].erase(0, 2);
321 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
322 }
323 return queues_pbit_map;
324}
325
326/**
327* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
328*
329* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
330* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
331* @param size Queue count
332*
333* @return <vector> TM QUEUE MAPPING PROFILE
334*/
335std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
336 std::vector<uint32_t> tmq_map_profile(8,0);
337
338 for(uint32_t i=0; i < size; i++) {
339 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
340 if (queues_pbit_map[i][j]=='1') {
341 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
342 }
343 }
344 }
345 return tmq_map_profile;
346}
347
348/**
349* Gets corresponding tm_qmp_id for a given tmq_map_profile
350*
351* @param <vector> TM QUEUE MAPPING PROFILE
352*
353* @return tm_qmp_id
354*/
355int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
356 int tm_qmp_id = -1;
357
358 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
359 while(it != qmp_id_to_qmp_map.end()) {
360 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
361 tm_qmp_id = it->first;
362 break;
363 }
364 it++;
365 }
366 return tm_qmp_id;
367}
368
369/**
370* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
371*
372* @param upstream/downstream sched_id
373* @param PON intf ID
374* @param onu_id ONU ID
375* @param uni_id UNI ID
376* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
377*/
378void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
379 uint32_t uni_id, int tm_qmp_id) {
380 bcmos_fastlock_lock(&data_lock);
381 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
382 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
383 bcmos_fastlock_unlock(&data_lock, 0);
384}
385
386/**
387* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
388*
389* @param upstream/downstream sched_id
390* @param PON intf ID
391* @param onu_id ONU ID
392* @param uni_id UNI ID
393*
394* @return tm_qmp_id
395*/
396int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
397 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
398 int tm_qmp_id = -1;
399
400 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
401 if (it != sched_qmp_id_map.end()) {
402 tm_qmp_id = it->second;
403 }
404 return tm_qmp_id;
405}
406
407/**
408* Gets a unique tm_qmp_id for a given tmq_map_profile
409* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
410* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
411*
412* @param upstream/downstream sched_id
413* @param PON intf ID
414* @param onu_id ONU ID
415* @param uni_id UNI ID
416* @param <vector> TM QUEUE MAPPING PROFILE
417*
418* @return tm_qmp_id
419*/
420int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
421 std::vector<uint32_t> tmq_map_profile) {
422 int tm_qmp_id;
423
424 bcmos_fastlock_lock(&data_lock);
425 /* Complexity of O(n). Is there better way that can avoid linear search? */
426 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
427 if (tm_qmp_bitset[tm_qmp_id] == 0) {
428 tm_qmp_bitset[tm_qmp_id] = 1;
429 break;
430 }
431 }
432 bcmos_fastlock_unlock(&data_lock, 0);
433
434 if (tm_qmp_id < MAX_TM_QMP_ID) {
435 bcmos_fastlock_lock(&data_lock);
436 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
437 bcmos_fastlock_unlock(&data_lock, 0);
438 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
439 return tm_qmp_id;
440 } else {
441 return -1;
442 }
443}
444
445/**
446* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
447*
448* @param upstream/downstream sched_id
449* @param PON intf ID
450* @param onu_id ONU ID
451* @param uni_id UNI ID
452* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
453*
454* @return boolean, true if no more reference for TM QMP else false
455*/
456bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
457 uint32_t uni_id, int tm_qmp_id) {
458 bool result;
459 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
460 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
461 bcmos_fastlock_lock(&data_lock);
462 if (it != sched_qmp_id_map.end()) {
463 sched_qmp_id_map.erase(it);
464 }
465 bcmos_fastlock_unlock(&data_lock, 0);
466
467 uint32_t tm_qmp_ref_count = 0;
468 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
469 while(it2 != sched_qmp_id_map.end()) {
470 if(it2->second == tm_qmp_id) {
471 tm_qmp_ref_count++;
472 }
473 it2++;
474 }
475
476 if (tm_qmp_ref_count == 0) {
477 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
478 if (it3 != qmp_id_to_qmp_map.end()) {
479 bcmos_fastlock_lock(&data_lock);
480 tm_qmp_bitset[tm_qmp_id] = 0;
481 qmp_id_to_qmp_map.erase(it3);
482 bcmos_fastlock_unlock(&data_lock, 0);
483 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
484 tm_qmp_id, tm_qmp_ref_count);
485 result = true;
486 }
487 } else {
488 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
489 tm_qmp_id, tm_qmp_ref_count);
490 result = false;
491 }
492 return result;
493}
494
495/**
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500496* Returns qos type as string
497*
498* @param qos_type bcmolt_egress_qos_type enum
499*/
500std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type) {
501 switch (qos_type)
502 {
503 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE: return "FIXED_QUEUE";
504 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE: return "TC_TO_QUEUE";
505 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC: return "PBIT_TO_TC";
506 case BCMOLT_EGRESS_QOS_TYPE_NONE: return "NONE";
507 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE: return "PRIORITY_TO_QUEUE";
508 default: OPENOLT_LOG(ERROR, openolt_log_id, "qos-type-not-supported %d\n", qos_type);
509 return "qos-type-not-supported";
510 }
511}
512
513/**
514* Gets/Updates qos type for given pon_intf_id, onu_id, uni_id
515*
516* @param PON intf ID
517* @param onu_id ONU ID
518* @param uni_id UNI ID
519* @param queue_size TrafficQueues Size
520*
521* @return qos_type
522*/
523bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size = 0) {
524 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
525 bcmolt_egress_qos_type egress_qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
526 std::string qos_string;
527
528 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
529 if (it != qos_type_map.end()) {
530 egress_qos_type = it->second;
531 qos_string = get_qos_type_as_string(egress_qos_type);
532 OPENOLT_LOG(INFO, openolt_log_id, "Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d is %s\n", \
533 pon_intf_id, onu_id, uni_id, qos_string.c_str());
534 }
535 else {
536 /* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
537 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
538 else Priority to Queue */
539 egress_qos_type = (queue_size > 1) ? \
540 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
541 bcmos_fastlock_lock(&data_lock);
542 qos_type_map.insert(make_pair(key, egress_qos_type));
543 bcmos_fastlock_unlock(&data_lock, 0);
544 qos_string = get_qos_type_as_string(egress_qos_type);
545 OPENOLT_LOG(INFO, openolt_log_id, "Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d is %s\n", \
546 pon_intf_id, onu_id, uni_id, qos_string.c_str());
547 }
548 return egress_qos_type;
549}
550
551/**
552* Clears qos type for given pon_intf_id, onu_id, uni_id
553*
554* @param PON intf ID
555* @param onu_id ONU ID
556* @param uni_id UNI ID
557*/
558void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
559 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
560 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
561 bcmos_fastlock_lock(&data_lock);
562 if (it != qos_type_map.end()) {
563 qos_type_map.erase(it);
564 OPENOLT_LOG(INFO, openolt_log_id, "Cleared Qos-type for subscriber connected to pon_intf_id %d, onu_id %d and uni_id %d\n", \
565 pon_intf_id, onu_id, uni_id);
566 }
567 bcmos_fastlock_unlock(&data_lock, 0);
568}
569
570/**
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000571* Returns Scheduler/Queue direction as string
572*
573* @param direction as specified in tech_profile.proto
574*/
575std::string GetDirection(int direction) {
576 switch (direction)
577 {
578 case tech_profile::Direction::UPSTREAM: return upstream;
579 case tech_profile::Direction::DOWNSTREAM: return downstream;
580 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
581 return "direction-not-supported";
582 }
583}
584
585inline const char *get_flow_acton_command(uint32_t command) {
586 char actions[200] = { };
587 char *s_actions_ptr = actions;
588 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
589 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
590 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
591 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
592 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
593 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
594 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
595 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
596 return s_actions_ptr;
597}
598
Girish Gowdra96461052019-11-22 20:13:59 +0530599// This method handles waiting for AllocObject configuration.
600// Returns error if the AllocObject is not in the appropriate state based on action requested.
601bcmos_errno wait_for_alloc_action(uint32_t intf_id, uint32_t alloc_id, AllocCfgAction action) {
602 Queue<alloc_cfg_complete_result> cfg_result;
603 alloc_cfg_compltd_key k(intf_id, alloc_id);
604 alloc_cfg_compltd_map[k] = &cfg_result;
605 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500606 #ifdef TEST_MODE
607 ALLOC_CFG_FLAG = true;
608 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530609
610 // Try to pop the result from BAL with a timeout of ALLOC_CFG_COMPLETE_WAIT_TIMEOUT ms
611 std::pair<alloc_cfg_complete_result, bool> result = cfg_result.pop(ALLOC_CFG_COMPLETE_WAIT_TIMEOUT);
612 if (result.second == false) {
613 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for alloc cfg complete indication intf_id %d, alloc_id %d\n",
614 intf_id, alloc_id);
615 // Invalidate the queue pointer.
616 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
617 alloc_cfg_compltd_map[k] = NULL;
618 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
619 err = BCM_ERR_INTERNAL;
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500620 #ifdef TEST_MODE
621 ALLOC_CFG_FLAG = false;
622 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530623 }
624 else if (result.first.status == ALLOC_CFG_STATUS_FAIL) {
625 OPENOLT_LOG(ERROR, openolt_log_id, "error processing alloc cfg request intf_id %d, alloc_id %d\n",
626 intf_id, alloc_id);
627 err = BCM_ERR_INTERNAL;
628 }
629
630 if (err == BCM_ERR_OK) {
631 if (action == ALLOC_OBJECT_CREATE) {
632 if (result.first.state != ALLOC_OBJECT_STATE_ACTIVE) {
633 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object not in active state intf_id %d, alloc_id %d alloc_obj_state %d\n",
634 intf_id, alloc_id, result.first.state);
635 err = BCM_ERR_INTERNAL;
636 } else {
637 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation success, intf_id %d, alloc_id %d\n",
638 intf_id, alloc_id);
639 }
640 } else { // ALLOC_OBJECT_DELETE
641 if (result.first.state != ALLOC_OBJECT_STATE_NOT_CONFIGURED) {
642 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object is not reset intf_id %d, alloc_id %d alloc_obj_state %d\n",
643 intf_id, alloc_id, result.first.state);
644 err = BCM_ERR_INTERNAL;
645 } else {
646 OPENOLT_LOG(INFO, openolt_log_id, "Remove alloc object success, intf_id %d, alloc_id %d\n",
647 intf_id, alloc_id);
648 }
649 }
650 }
651
652 // Remove entry from map
653 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
654 alloc_cfg_compltd_map.erase(k);
655 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500656 #ifdef TEST_MODE
657 ALLOC_CFG_FLAG = false;
658 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530659 return err;
660}
661
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000662char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800663{
664 FILE *fp;
665 /* Prepare the command*/
666 char command[150];
667
668 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
669 /* Open the command for reading. */
670 fp = popen(command, "r");
671 if (fp == NULL) {
672 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000673 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800674 return field_val;
675 }
676
677 /*Read the field value*/
678 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000679 uint8_t ret;
680 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
681 if (ret >= OPENOLT_FIELD_LEN)
682 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800683 pclose(fp);
684 }
685 return field_val;
686}
687
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400688Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500689 device_info->set_vendor(VENDOR_ID);
690 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400691 device_info->set_hardware_version("");
692 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500693 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500694 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500695
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800696 char serial_number[OPENOLT_FIELD_LEN];
697 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
698 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000699 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800700 device_info->set_device_serial_number(serial_number);
701
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700702 char device_id[OPENOLT_FIELD_LEN];
703 memset(device_id, '\0', OPENOLT_FIELD_LEN);
704 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000705 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700706 device_info->set_device_id(device_id);
707
Craig Lutgenb2601f02018-10-23 13:04:31 -0500708 // Legacy, device-wide ranges. To be deprecated when adapter
709 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000710 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500711 device_info->set_onu_id_start(1);
712 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600713 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500714 device_info->set_alloc_id_end(16383);
715 device_info->set_gemport_id_start(1024);
716 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500717 device_info->set_flow_id_start(1);
718 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500719 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000720 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500721 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500722 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600723 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500724 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500725 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500726 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500727 device_info->set_flow_id_start(1);
728 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500729 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500730
731 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
732 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
733 std::string intf_technology = intf_technologies[intf_id];
734 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
735 if(range == nullptr) {
736 range = device_info->add_ranges();
737 ranges[intf_technology] = range;
738 range->set_technology(intf_technology);
739
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000740 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500741 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
742
743 pool = range->add_pools();
744 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
745 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
746 pool->set_start(1);
747 pool->set_end(255);
748
749 pool = range->add_pools();
750 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
751 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
752 pool->set_start(1024);
753 pool->set_end(16383);
754
755 pool = range->add_pools();
756 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
757 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
758 pool->set_start(1024);
759 pool->set_end(65535);
760
761 pool = range->add_pools();
762 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
763 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
764 pool->set_start(1);
765 pool->set_end(16383);
766 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000767 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500768 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
769
770 pool = range->add_pools();
771 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
772 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
773 pool->set_start(1);
774 pool->set_end(127);
775
776 pool = range->add_pools();
777 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
778 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
779 pool->set_start(256);
780 pool->set_end(757);
781
782 pool = range->add_pools();
783 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
784 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
785 pool->set_start(256);
786 pool->set_end(4095);
787
788 pool = range->add_pools();
789 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
790 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
791 pool->set_start(1);
792 pool->set_end(16383);
793 }
794 }
795
796 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500797 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400798
799 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500800 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400801 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
802 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500803 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400804 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500805 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
806 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400807
808 return Status::OK;
809}
810
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000811Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
812{
813 openolt::Indication ind;
814 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
815
816 intf_oper_ind->set_type(type);
817 intf_oper_ind->set_intf_id(intf_id);
818 intf_oper_ind->set_oper_state(state);
819 ind.set_allocated_intf_oper_ind(intf_oper_ind);
820 oltIndQ.push(ind);
821 return Status::OK;
822}
823
824#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
825
826/* Build CLI prompt */
827static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
828{
829 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
830}
831
832static int _bal_apiend_cli_thread_handler(long data)
833{
834 char init_string[]="\n";
835 bcmcli_session *sess = current_session;
836 bcmos_task_parm bal_cli_task_p_dummy;
837
838 /* Switch to interactive mode if not stopped in the init script */
839 if (!bcmcli_is_stopped(sess))
840 {
841 /* Force a CLI command prompt
842 * The string passed into the parse function
843 * must be modifiable, so a string constant like
844 * bcmcli_parse(current_session, "\n") will not
845 * work.
846 */
847 bcmcli_parse(sess, init_string);
848
849 /* Process user input until EOF or quit command */
850 bcmcli_driver(sess);
851 };
852 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
853
854 /* Cleanup */
855 bcmcli_session_close(current_session);
856 bcmcli_token_destroy(NULL);
857 return 0;
858}
859
860/* Init API CLI commands for the current device */
861bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
862{
863 bcmos_errno rc;
864
865 api_parent_dir = parent_dir;
866
867 rc = bcm_api_cli_set_commands(session);
868
869#ifdef BCM_SUBSYSTEM_HOST
870 /* Subscribe for device change indication */
871 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
872#endif
873
874 return rc;
875}
876
877static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
878{
879 bcmcli_stop(session);
880 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
881 status_bcm_cli_quit = BCMOS_TRUE;
882
883 return BCM_ERR_OK;
884}
885
886int get_status_bcm_cli_quit(void) {
887 return status_bcm_cli_quit;
888}
889
890bcmos_errno bcmolt_apiend_cli_init() {
891 bcmos_errno ret;
892 bcmos_task_parm bal_cli_task_p = {};
893 bcmos_task_parm bal_cli_task_p_dummy;
894
895 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
896 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
897 {
898 /* Create BAL CLI thread */
899 bal_cli_task_p.name = bal_cli_thread_name;
900 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
901 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
902
903 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
904 if (BCM_ERR_OK != ret)
905 {
906 bcmos_printf("Couldn't create BAL API end CLI thread\n");
907 return ret;
908 }
909 }
910}
911
Shad Ansari627b5782018-08-13 22:49:32 +0000912Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000913 bcmos_errno err;
914 bcmolt_host_init_parms init_parms = {};
915 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
916 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000917
Shad Ansariedef2132018-08-10 22:14:50 +0000918 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000919
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500920 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000921 /* Initialize host subsystem */
922 err = bcmolt_host_init(&init_parms);
923 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500924 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000925 return bcm_to_grpc_err(err, "Failed to init OLT");
926 }
927
928 bcmcli_session_parm mon_session_parm;
929 /* Create CLI session */
930 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
931 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
932 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
933 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
934 BUG_ON(rc != BCM_ERR_OK);
935
936 /* API CLI */
937 bcm_openolt_api_cli_init(NULL, current_session);
938
939 /* Add quit command */
940 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
941
942 err = bcmolt_apiend_cli_init();
943 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500944 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000945 return bcm_to_grpc_err(err, "Failed to add apiend init");
946 }
947
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800948 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530949 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000950 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600951
Jason Huangbf45ffb2019-10-30 17:29:02 +0800952 //check BCM daemon is connected or not
953 Status status = check_connection();
954 if (!status.ok())
955 return status;
956 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000957 Status status = SubscribeIndication();
958 if (!status.ok()) {
959 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
960 grpc_status_code_to_string(status.error_code()).c_str(),
961 status.error_message().c_str());
962 return status;
963 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800964
965 //check BAL state in initial stage
966 status = check_bal_ready();
967 if (!status.ok())
968 return status;
969 }
970
971 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000972 bcmos_errno err;
973 bcmolt_odid dev;
974 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
975 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400976 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000977 bcmolt_device_key dev_key = { };
978 dev_key.device_id = dev;
979 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
980 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
981 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800982 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000983 bcmolt_device_key key = {.device_id = dev};
984 bcmolt_device_connect oper;
985 BCMOLT_OPER_INIT(&oper, device, connect, key);
986 if (MODEL_ID == "asfvolt16") {
987 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
988 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
989 } else if (MODEL_ID == "asgvolt64") {
990 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
991 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
992 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
993 }
994 err = bcmolt_oper_submit(dev_id, &oper.hdr);
995 if (err) {
996 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500997 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 +0000998 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500999 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 +00001000 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
1001 }
1002 }
1003 bcmos_usleep(200000);
1004 }
1005 else {
1006 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
1007 state.activate();
1008 }
1009 }
1010 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +00001011 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001012 }
Shad Ansariedef2132018-08-10 22:14:50 +00001013
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001014 /* Start CLI */
1015 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001016 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001017 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001018}
1019
1020Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001021 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
1022 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
1023 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
1024 //To overcome this disable is implemented by disabling all the PON ports
1025 //associated with the device so as to support both in-band
1026 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001027
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001028 Status status;
1029 int failedCount = 0;
1030 for (int i = 0; i < NumPonIf_(); i++) {
1031 status = DisablePonIf_(i);
1032 if (!status.ok()) {
1033 failedCount+=1;
1034 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
1035 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001036 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001037 if (failedCount == 0) {
1038 state.deactivate();
1039 openolt::Indication ind;
1040 openolt::OltIndication* olt_ind = new openolt::OltIndication;
1041 olt_ind->set_oper_state("down");
1042 ind.set_allocated_olt_ind(olt_ind);
1043 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
1044 oltIndQ.push(ind);
1045 return Status::OK;
1046 }
1047 if (failedCount ==NumPonIf_()){
1048 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
1049 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001050
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001051 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 -04001052}
1053
1054Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001055 Status status;
1056 int failedCount = 0;
1057 for (int i = 0; i < NumPonIf_(); i++) {
1058 status = EnablePonIf_(i);
1059 if (!status.ok()) {
1060 failedCount+=1;
1061 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
1062 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001063 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001064 if (failedCount == 0){
1065 state.activate();
1066 openolt::Indication ind;
1067 openolt::OltIndication* olt_ind = new openolt::OltIndication;
1068 olt_ind->set_oper_state("up");
1069 ind.set_allocated_olt_ind(olt_ind);
1070 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
1071 oltIndQ.push(ind);
1072 return Status::OK;
1073 }
1074 if (failedCount ==NumPonIf_()){
1075 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
1076 }
1077 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 +00001078}
1079
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001080bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
1081 bcmos_errno err;
1082 bcmolt_pon_interface_key pon_key;
1083 bcmolt_pon_interface_cfg pon_cfg;
1084 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001085
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001086 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
1087 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
1088 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001089 #ifdef TEST_MODE
1090 // It is impossible to mock the setting of pon_cfg.data.state because
1091 // the actual bcmolt_cfg_get passes the address of pon_cfg.hdr and we cannot
1092 // set the pon_cfg.data.state. So a new stub function is created and address
1093 // of pon_cfg is passed. This is one-of case where we need to add test specific
1094 // code in production code.
1095 err = bcmolt_cfg_get__pon_intf_stub(dev_id, &pon_cfg);
1096 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001097 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001098 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001099 *state = pon_cfg.data.state;
1100 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001101}
1102
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001103inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
1104 bcmos_errno err;
1105 bcmolt_flow_key flow_key;
1106 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001107
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001108 flow_key.flow_id = flow_id;
1109 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001110
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001111 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001112
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001113 switch (data_id) {
1114 case ONU_ID: //onu_id
1115 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
1116 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1117 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001118 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001119 return err;
1120 }
1121 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001122 case FLOW_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001123 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1124 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001125 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001126 return err;
1127 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001128 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001129 case SVC_PORT_ID: //svc_port_id
1130 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
1131 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1132 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001133 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 +00001134 return err;
1135 }
1136 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001137 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001138 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
1139 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1140 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001141 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001142 return err;
1143 }
1144 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001145 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001146 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
1147 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1148 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001149 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001150 return err;
1151 }
1152 return flow_cfg.data.cookie;
1153 case INGRESS_INTF_TYPE: //ingress intf_type
1154 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1155 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1156 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001157 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 +00001158 return err;
1159 }
1160 return flow_cfg.data.ingress_intf.intf_type;
1161 case EGRESS_INTF_TYPE: //egress intf_type
1162 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1163 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1164 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001165 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 +00001166 return err;
1167 }
1168 return flow_cfg.data.egress_intf.intf_type;
1169 case INGRESS_INTF_ID: //ingress intf_id
1170 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1171 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1172 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001173 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 +00001174 return err;
1175 }
1176 return flow_cfg.data.ingress_intf.intf_id;
1177 case EGRESS_INTF_ID: //egress intf_id
1178 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1179 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1180 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001181 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 +00001182 return err;
1183 }
1184 return flow_cfg.data.egress_intf.intf_id;
1185 case CLASSIFIER_O_VID:
1186 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1187 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1188 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001189 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 +00001190 return err;
1191 }
1192 return flow_cfg.data.classifier.o_vid;
1193 case CLASSIFIER_O_PBITS:
1194 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1195 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1196 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001197 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 +00001198 return err;
1199 }
1200 return flow_cfg.data.classifier.o_pbits;
1201 case CLASSIFIER_I_VID:
1202 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1203 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1204 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001205 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 +00001206 return err;
1207 }
1208 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001209 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001210 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1211 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1212 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001213 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 +00001214 return err;
1215 }
1216 return flow_cfg.data.classifier.i_pbits;
1217 case CLASSIFIER_ETHER_TYPE:
1218 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1219 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1220 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001221 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 +00001222 return err;
1223 }
1224 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001225 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001226 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1227 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1228 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001229 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 +00001230 return err;
1231 }
1232 return flow_cfg.data.classifier.ip_proto;
1233 case CLASSIFIER_SRC_PORT:
1234 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1235 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1236 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001237 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 +00001238 return err;
1239 }
1240 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001241 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001242 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1243 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1244 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001245 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 +00001246 return err;
1247 }
1248 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001249 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001250 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1251 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1252 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001253 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 +00001254 return err;
1255 }
1256 return flow_cfg.data.classifier.pkt_tag_type;
1257 case EGRESS_QOS_TYPE:
1258 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1259 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1260 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001261 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 +00001262 return err;
1263 }
1264 return flow_cfg.data.egress_qos.type;
1265 case EGRESS_QOS_QUEUE_ID:
1266 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1267 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1268 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001269 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 +00001270 return err;
1271 }
1272 switch (flow_cfg.data.egress_qos.type) {
1273 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1274 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1275 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1276 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1277 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1278 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1279 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1280 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1281 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1282 default:
1283 return -1;
1284 }
1285 case EGRESS_QOS_TM_SCHED_ID:
1286 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1287 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1288 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001289 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 +00001290 return err;
1291 }
1292 return flow_cfg.data.egress_qos.tm_sched.id;
1293 case ACTION_CMDS_BITMASK:
1294 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1295 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1296 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001297 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 +00001298 return err;
1299 }
1300 return flow_cfg.data.action.cmds_bitmask;
1301 case ACTION_O_VID:
1302 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1303 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1304 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001305 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 +00001306 return err;
1307 }
1308 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001309 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001310 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1311 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1312 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001313 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 +00001314 return err;
1315 }
1316 return flow_cfg.data.action.o_pbits;
1317 case ACTION_I_VID:
1318 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1319 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1320 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001321 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 +00001322 return err;
1323 }
1324 return flow_cfg.data.action.i_vid;
1325 case ACTION_I_PBITS:
1326 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1327 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1328 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001329 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 +00001330 return err;
1331 }
1332 return flow_cfg.data.action.i_pbits;
1333 case STATE:
1334 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1335 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1336 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001337 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001338 return err;
1339 }
1340 return flow_cfg.data.state;
1341 default:
1342 return BCM_ERR_INTERNAL;
1343 }
1344
1345 return err;
1346}
1347
1348Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001349 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001350 bcmolt_pon_interface_cfg interface_obj;
1351 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1352 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1353 bcmolt_interface_state state;
1354
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001355 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001356 if (err == BCM_ERR_OK) {
1357 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001358 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001359 return Status::OK;
1360 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001361 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001362 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1363 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1364 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1365 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1366 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1367 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1368 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1369 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1370 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1371 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1372 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1373 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1374 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1375 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1376
1377 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1378 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001379 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 +00001380 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1381 }
1382 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1383 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001384 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 +00001385 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1386 }
1387 else {
1388 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1389 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1390 CreateDefaultSched(intf_id, downstream);
1391 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001392 }
1393
1394 return Status::OK;
1395}
1396
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001397/* Same as bcmolt_cfg_get but with added logic of retrying the API
1398 in case of some specific failures like timeout or object not yet ready
1399*/
1400bcmos_errno bcmolt_cfg_get_mult_retry(bcmolt_oltid olt, bcmolt_cfg *cfg) {
1401 bcmos_errno err;
1402 uint32_t current_try = 0;
1403
1404 while (current_try < MAX_BAL_API_RETRY_COUNT) {
1405 err = bcmolt_cfg_get(olt, cfg);
1406 current_try++;
1407
1408 if (err == BCM_ERR_STATE || err == BCM_ERR_TIMEOUT) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001409 OPENOLT_LOG(WARNING, openolt_log_id, "bcmolt_cfg_get: err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001410 bcmos_usleep(BAL_API_RETRY_TIME_IN_USECS);
1411 continue;
1412 }
1413 else {
1414 break;
1415 }
1416 }
1417
1418 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001419 OPENOLT_LOG(ERROR, openolt_log_id, "bcmolt_cfg_get tried (%d) times with retry time(%d usecs) err = %s\n",
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001420 current_try,
1421 BAL_API_RETRY_TIME_IN_USECS,
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001422 bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001423 }
1424 return err;
1425}
1426
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001427Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001428 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001429 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001430 bcmolt_device_key dev_key = { };
1431 bcmolt_olt_cfg olt_cfg = { };
1432 bcmolt_olt_key olt_key = { };
1433 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1434 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001435
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001436 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1437 topo.topology_maps.arr = &topo_map[0];
1438 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1439 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1440 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001441 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001442 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001443 #ifdef TEST_MODE
1444 // It is impossible to mock the setting of olt_cfg.data.bal_state because
1445 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
1446 // set the olt_cfg.data.topology. So a new stub function is created and address
1447 // of olt_cfg is passed. This is one-of case where we need to test add specific
1448 // code in production code.
1449 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1450 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001451 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001452 #endif
1453 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001454 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 +00001455 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001456 }
1457
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001458 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1459 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001460
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001461 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1462 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001463 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001464
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001465 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1466 num_of_nni_ports,
1467 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001468 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001469
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001470 uint32_t num_failed_cfg_gets = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001471 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1472 dev_key.device_id = devid;
1473 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1474 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1475 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1476 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001477 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001478 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001479 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 +00001480 num_failed_cfg_gets++;
1481 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001482 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001483
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001484 std::string bal_version;
1485 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1486 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1487 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1488 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1489
1490 switch(dev_cfg.data.system_mode) {
1491 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1492 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1493 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1494 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1495 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1496 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1497 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1498 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1499 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1500 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1501 }
1502
1503 switch(dev_cfg.data.chip_family) {
1504 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1505 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1506 }
1507
1508 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1509 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1510
1511 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001512 }
1513
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001514 /* If all the devices returned errors then we tell the caller that this is an error else we work with
1515 only the devices that retured success*/
1516 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1517 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1518 return bcm_to_grpc_err(err, "device: All devices failed query");
1519 }
1520
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001521 return Status::OK;
1522}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001523#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001524Status ProbePonIfTechnology_() {
1525 // Probe maximum extent possible as configured into BAL driver to determine
1526 // which are active in the current BAL topology. And for those
1527 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1528 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001529 bcmolt_pon_interface_cfg interface_obj;
1530 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001531
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001532 interface_key.pon_ni = intf_id;
1533 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001534 if (board_technology == "XGS-PON"
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001535 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1536 else if (board_technology == "GPON")
1537 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001538
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001539 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001540 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001541 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001542 if(err != BCM_ERR_RANGE) OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get PON config: %d err %d\n", intf_id, err);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001543 }
1544 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001545 if (board_technology == "XGS-PON") {
1546 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1547 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1548 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1549 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1550 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1551 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1552 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1553 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1554 intf_technologies[intf_id] = "XGS-PON";
1555 break;
1556 }
1557 } else if (board_technology == "GPON") {
1558 switch(interface_obj.data.gpon_trx.transceiver_type) {
1559 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1560 case BCMOLT_TRX_TYPE_LTE_3680_M:
1561 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1562 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1563 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1564 intf_technologies[intf_id] = "GPON";
1565 break;
1566 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001567 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001568
1569 if (board_technology != UNKNOWN_TECH) {
1570 board_technology = intf_technologies[intf_id];
1571 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1572 intf_technologies[intf_id] = MIXED_TECH;
1573 }
1574
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001575 }
1576 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001577 return Status::OK;
1578}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001580unsigned NumNniIf_() {return num_of_nni_ports;}
1581unsigned NumPonIf_() {return num_of_pon_ports;}
1582
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001583bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1584 bcmos_errno err;
1585 bcmolt_nni_interface_key nni_key;
1586 bcmolt_nni_interface_cfg nni_cfg;
1587 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001588
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001589 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1590 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001591 #ifdef TEST_MODE
1592 // It is impossible to mock the setting of nni_cfg.data.state because
1593 // the actual bcmolt_cfg_get passes the address of nni_cfg.hdr and we cannot
1594 // set the nni_cfg.data.state. So a new stub function is created and address
1595 // of nni_cfg is passed. This is one-of case where we need to add test specific
1596 // code in production code.
1597 err = bcmolt_cfg_get__nni_intf_stub(dev_id, &nni_cfg);
1598 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001599 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001600 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001601 *state = nni_cfg.data.state;
1602 return err;
1603}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001604
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001605Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1606 bcmos_errno err = BCM_ERR_OK;
1607 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1608 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1609 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001610
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001611 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001612 if (err == BCM_ERR_OK) {
1613 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001614 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001615 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1616 CreateDefaultSched(intf_id, upstream);
1617 CreateDefaultQueue(intf_id, upstream);
1618 return Status::OK;
1619 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1620 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1621 return Status::OK;
1622 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001623 }
1624
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001625 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1626 if (set_state) {
1627 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1628 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1629 } else {
1630 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1631 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1632 }
1633 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1634 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001635 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1636 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001637 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1638 }
1639 else {
1640 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1641 if (set_state) {
1642 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1643 CreateDefaultSched(intf_id, upstream);
1644 CreateDefaultQueue(intf_id, upstream);
1645 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001646 }
1647
1648 return Status::OK;
1649}
1650
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001651Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001652 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001653 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001654 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1655 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001656
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001657 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1658 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1659 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1660
1661 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1662 if (err != BCM_ERR_OK) {
1663 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1664 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1665 }
1666
1667 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1668 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1669
1670 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1671 if (err != BCM_ERR_OK) {
1672 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 -04001673 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001674 }
1675
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001676 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001677 return Status::OK;
1678}
1679
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001680Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001681 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001682 bcmos_errno err = BCM_ERR_OK;
1683 bcmolt_onu_cfg onu_cfg;
1684 bcmolt_onu_key onu_key;
1685 bcmolt_serial_number serial_number; /**< ONU serial number */
1686 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001687
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001688 onu_key.onu_id = onu_id;
1689 onu_key.pon_ni = intf_id;
1690 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1691 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001692 #ifdef TEST_MODE
1693 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1694 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1695 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1696 // of onu_cfg is passed. This is one-of case where we need to add test specific
1697 // code in production code.
1698 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
1699 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001700 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001701 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001702 if (err == BCM_ERR_OK) {
1703 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001704 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1705 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1706 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1707 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001708 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001709
1710 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001711vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001712 vendor_specific_to_str(vendor_specific).c_str(), pir);
1713
1714 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1715 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1716 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1717 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1718 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1719 /*set burst and data profiles to fec disabled*/
1720 if (board_technology == "XGS-PON") {
1721 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1722 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1723 } else if (board_technology == "GPON") {
1724 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1725 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1726 }
1727 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1728 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001729 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 +00001730 return bcm_to_grpc_err(err, "Failed to activate ONU");
1731 }
1732
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001733 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001734}
1735
Jonathan Davis70c21812018-07-19 15:32:10 -04001736Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1737 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001738 bcmos_errno err = BCM_ERR_OK;
1739 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1740 bcmolt_onu_cfg onu_cfg;
1741 bcmolt_onu_key onu_key; /**< Object key. */
1742 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001743
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001744 onu_key.onu_id = onu_id;
1745 onu_key.pon_ni = intf_id;
1746 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1747 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001748 #ifdef TEST_MODE
1749 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1750 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1751 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1752 // of onu_cfg is passed. This is one-of case where we need to add test specific
1753 // code in production code.
1754 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
1755 onu_state = onu_cfg.data.onu_state;
1756 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001757 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001758 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001759 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001760 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001761 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001762 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001763 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001764 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1765 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1766 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001767 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 +00001768 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1769 }
1770 break;
1771 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001772 }
1773
1774 return Status::OK;
1775}
1776
1777Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001778 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001779
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001780 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 -05001781 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1782
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001783 // Need to deactivate before removing it (BAL rules)
1784
1785 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1786 // Sleep to allow the state to propagate
1787 // We need the subscriber terminal object to be admin down before removal
1788 // Without sleep the race condition is lost by ~ 20 ms
1789 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1790
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001791 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001792
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001793 bcmolt_onu_cfg cfg_obj;
1794 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001795
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001796 //OPENOLT_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
1797 // onu_id, intf_id);
1798 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 -04001799 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001800
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001801 key.onu_id = onu_id;
1802 key.pon_ni = intf_id;
1803 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001804
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001805 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001806 if (err != BCM_ERR_OK)
1807 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001808 //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));
1809 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 -04001810 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1811 }
1812
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001813 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001814}
1815
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001816#define MAX_CHAR_LENGTH 20
1817#define MAX_OMCI_MSG_LENGTH 44
1818Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001819 bcmolt_bin_str buf = {};
1820 bcmolt_onu_cpu_packets omci_cpu_packets;
1821 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001822
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001823 key.pon_ni = intf_id;
1824 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001825
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001826 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1827 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1828 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001829
1830 // ???
1831 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1832 buf.len = MAX_OMCI_MSG_LENGTH;
1833 } else {
1834 buf.len = pkt.size()/2;
1835 }
1836
1837 /* Send the OMCI packet using the BAL remote proxy API */
1838 uint16_t idx1 = 0;
1839 uint16_t idx2 = 0;
1840 uint8_t arraySend[buf.len];
1841 char str1[MAX_CHAR_LENGTH];
1842 char str2[MAX_CHAR_LENGTH];
1843 memset(&arraySend, 0, buf.len);
1844
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001845 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1846 sprintf(str1,"%c", pkt[idx1]);
1847 sprintf(str2,"%c", pkt[++idx1]);
1848 strcat(str1,str2);
1849 arraySend[idx2] = strtol(str1, NULL, 16);
1850 }
1851
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001852 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1853 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001854
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001855 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1856 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1857 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001858
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001859 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001860 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001861 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 +00001862 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001863 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001864 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 -05001865 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001866 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001867 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001868
1869 return Status::OK;
1870}
1871
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001872Status 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 +00001873 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1874 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1875 bcmolt_bin_str buf = {};
1876 bcmolt_gem_port_id gem_port_id_array[1];
1877 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001878
Craig Lutgen967a1d02018-11-27 10:41:51 -06001879 if (port_no > 0) {
1880 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001881 if (gemport_id == 0) {
1882 bcmos_fastlock_lock(&data_lock);
1883 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1884 // Pick any flow that is mapped with the same port_no.
1885 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1886 if (it != port_to_flows.end() && !it->second.empty()) {
1887 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1888 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1889 if (fit != flowid_to_gemport.end()) {
1890 found = true;
1891 gemport_id = fit->second;
1892 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001893 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001894 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001895
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001896 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001897 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 -08001898 onu_id, port_no, intf_id);
1899 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1900 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001901 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 -08001902 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001903 }
1904
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001905 gem_port_id_array[0] = gemport_id;
1906 gem_port_list.len = 1;
1907 gem_port_list.arr = gem_port_id_array;
1908 buf.len = pkt.size();
1909 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1910 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1911
1912 /* init the API struct */
1913 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1914 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1915 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1916 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1917 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1918
1919 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1920 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1921
1922 /* call API */
1923 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001924 }
1925 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001926 //TODO: Port No is 0, it is coming sender requirement.
1927 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1928 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001929 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001930 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001931
1932 return Status::OK;
1933}
1934
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001935Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001936 bcmolt_flow_key key = {}; /* declare key */
1937 bcmolt_bin_str buffer = {};
1938 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001939
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001940 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1941 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001942
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001943 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1944 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1945 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1946 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1947 key.flow_id = flow_id;
1948 else {
1949 if (flow_id_counters != 0) {
1950 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1951 int flow_index = flow_id_data[flowid][0];
1952 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1953 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1954 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1955 key.flow_id = flow_index;
1956 break;
1957 }
1958 }
1959 }
1960 else {
1961 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1962 }
1963 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001964
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001965 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001966
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001967 /* Initialize the API struct. */
1968 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001969
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001970 buffer.len = pkt.size();
1971 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1972 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1973 if (buffer.arr == NULL) {
1974 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1975 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1976 }
1977 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1978
1979 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1980 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001981 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 Subramani89fffc02019-05-13 21:33:20 +00001982 } else {
1983 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1984 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001985
1986 return Status::OK;
1987}
1988
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001989uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001990 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001991 uint32_t port_no = 0;
1992 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1993 if (it != flowid_to_port.end()) {
1994 port_no = it->second;
1995 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001996 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001997 return port_no;
1998}
1999
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002000#define FLOW_LOG(level,msg,err) \
2001 do { \
2002 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
2003 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
2004 access_intf_id, onu_id, uni_id, port_no, cookie); \
2005 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
2006 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
2007 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
2008 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
2009 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
2010 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
2011 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
2012 OPENOLT_LOG(level, openolt_log_id, "classifier(ip_proto 0x%x, gemport_id %d, src_port %d, dst_port %d, pkt_tag_type %s)\n", \
2013 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
2014 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
2015 get_flow_acton_command(a_val.cmds_bitmask), a_val.o_vid, a_val.o_pbits, a_val.i_vid, a_val.i_pbits); \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04002016 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002017
2018#define FLOW_PARAM_LOG() \
2019 do { \
2020 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
2021 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
2022 key.flow_id, flow_index); \
2023 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
2024 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
2025 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
2026 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
2027 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
2028 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
2029 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
2030 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
2031 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
2032 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
2033 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
2034 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
2035 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
2036 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
2037 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
2038 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
2039 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
2040 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
2041 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
2042 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
2043 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
2044 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
2045 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
2046 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
2047 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
2048 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
2049 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
2050 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
2051 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
2052 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
2053 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
2054 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
2055 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
2056 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
2057 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
2058 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
2059 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
2060 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
2061 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
2062 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
2063 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
2064 cfg.data.egress_qos.u.fixed_queue.queue_id, \
2065 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
2066 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
2067 cfg.data.egress_qos.tm_sched.id, \
2068 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
2069 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
2070 get_flow_acton_command(a_val.cmds_bitmask), \
2071 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
2072 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
2073 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
2074 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
2075 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
2076 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
2077 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
2078 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
2079 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
2080 } while(0)
2081
2082#define FLOW_CHECKER
2083//#define SHOW_FLOW_PARAM
2084
Craig Lutgen967a1d02018-11-27 10:41:51 -06002085Status 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 +00002086 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002087 int32_t alloc_id, int32_t network_intf_id,
2088 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06002089 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002090 bcmolt_flow_cfg cfg;
2091 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002092 int32_t o_vid = -1;
2093 bool single_tag = false;
2094 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002095 bcmolt_classifier c_val = { };
2096 bcmolt_action a_val = { };
2097 bcmolt_tm_queue_ref tm_val = { };
2098 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002099 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002100
2101 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002102 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002103 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002104 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002105 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002106 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002107 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04002108 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002109 }
2110
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002111 BCMOLT_CFG_INIT(&cfg, flow, key);
2112 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002113
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002114 if (access_intf_id >= 0 && network_intf_id >= 0) {
2115 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
2116 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2117 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
2118 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
2119 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
2120 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
2121 } else {
2122 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2123 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
2124 }
2125 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
2126 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2127 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2128 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2129 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
2130 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302131 } else if (access_intf_id < 0 ) {
2132 // This is the case for packet trap from NNI flow.
2133 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2134 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2135 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002136 } else {
2137 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2138 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
2139 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002140
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302141
Shad Ansari39739bc2018-09-13 21:38:37 +00002142 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002144 }
2145 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002146 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002147 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002148 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002149 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002150 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002151 port_to_flows[port_no].insert(key.flow_id);
2152 flowid_to_gemport[key.flow_id] = gemport_id;
2153 }
2154 else
2155 {
2156 flowid_to_port[key.flow_id] = port_no;
2157 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002158 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002159 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002160 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002161 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00002162 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002163
2164 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002165 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002166 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002167 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002168 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002169 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002170 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002171 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002172 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002173 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002174 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002175 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002176 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002177
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002178 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002179 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002180 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2181 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002182 }
2183
2184 /*
2185 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002186 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002187 }
2188
2189 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002190 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002191 }
2192 */
2193
2194 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002195 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2196 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002197 }
2198
2199 /*
2200 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002201 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002202 }
2203
2204 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002205 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002206 }
2207 */
2208
2209 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002210 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2211 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002212 }
2213
2214 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002215 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2216 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002217 }
2218
2219 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302220 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2221 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2222 // This is case where packet traps from NNI port. As per Broadcom workaround
2223 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2224 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2225 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2226 } else {
2227 if (classifier.o_vid()) {
2228 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2229 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2230 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002231
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302232 if (classifier.i_vid()) {
2233 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2234 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2235 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002236
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302237 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2238 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2239 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2240 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2241 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2242 single_tag = true;
2243
2244 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002245 if(classifier.o_pbits()){
2246 //According to makeOpenOltClassifierField in voltha-openolt-adapter, o_pbits 0xFF means PCP value 0.
2247 //0 vlaue of o_pbits means o_pbits is not available
2248 if(0xFF == classifier.o_pbits()){
2249 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2250 }
2251 else{
2252 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2253 }
2254 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302255 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2256 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2257
2258 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002259 if(classifier.o_pbits()){
2260 if(0xFF == classifier.o_pbits()){
2261 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2262 }
2263 else{
2264 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2265 }
2266 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302267 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002268 }
2269 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002270 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002271 }
2272
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002273 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002274 const ::openolt::ActionCmd& cmd = action.cmd();
2275
2276 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002277 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2278 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002279 }
2280
2281 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002282 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2283 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002284 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002285 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002286 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002287 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002288 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002289 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002290 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002291 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002292 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002293 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002294 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002295 }
2296
2297 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002298 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2299 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002300 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002301 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002302 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002303 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002304 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002305 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002306 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002307 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002308 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2309 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002310 }
2311
2312 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002313 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2314 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002315 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002317 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002318 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002319 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002320 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002321 */
2322 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002323 }
2324
Shad Ansari39739bc2018-09-13 21:38:37 +00002325 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002326 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2327 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2328 get_default_tm_sched_id(network_intf_id, upstream) : \
2329 get_default_tm_sched_id(access_intf_id, downstream);
2330 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002331
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002332 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2333 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2334 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002335
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002336 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2337 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2338 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2339 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002340 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002341 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2342 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2343
2344 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2345 // Queue 0 on DS subscriber scheduler
2346 tm_val.queue_id = 0;
2347
2348 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2349 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2350 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2351
2352 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2353 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2354 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2355
2356 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2357 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2358 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2359
2360 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2361 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2362 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2363 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2364
2365 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2366 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2367 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2368 }
2369 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2370 // NNI Scheduler ID
2371 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2372 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2373 // Queue 0 on NNI scheduler
2374 tm_val.queue_id = 0;
2375 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2376 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2377 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2378
2379 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2380 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2381 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2382
2383 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2384 /* Fetch TM QMP ID mapped to US NNI scheduler */
2385 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2386 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2387 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2388 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2389 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2390
2391 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2392 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2393 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2394 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002395 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002396 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302397 } else {
2398 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2399 tm_val.queue_id = 0;
2400
2401 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2402 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2403 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2404
2405 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2406 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2407 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002408 }
2409
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2411 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2412#ifdef FLOW_CHECKER
2413 //Flow Checker, To avoid duplicate flow.
2414 if (flow_id_counters != 0) {
2415 bool b_duplicate_flow = false;
2416 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2417 int flow_index = flow_id_data[flowid][0];
2418 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2419 (key.flow_type == flow_id_data[flowid][1]) && \
2420 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2421 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2422 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2423 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2424 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2425 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2426 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2427 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2428 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2429 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2430 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2431 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2432 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2433 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2434 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2435 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2436 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2437 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2438 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2439 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2440 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2441 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2442 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2443 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2444 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2445#ifdef SHOW_FLOW_PARAM
2446 // Flow Parameter
2447 FLOW_PARAM_LOG();
2448#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002449
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002450 if (b_duplicate_flow) {
2451 FLOW_LOG(WARNING, "Flow duplicate", 0);
2452 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2453 }
2454 }
2455 }
2456#endif
2457
2458 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2459 if (err) {
2460 FLOW_LOG(ERROR, "Flow add failed", err);
2461 return bcm_to_grpc_err(err, "flow add failed");
2462 } else {
2463 FLOW_LOG(INFO, "Flow add ok", err);
2464 bcmos_fastlock_lock(&data_lock);
2465 flow_id_data[flow_id_counters][0] = key.flow_id;
2466 flow_id_data[flow_id_counters][1] = key.flow_type;
2467 flow_id_counters += 1;
2468 bcmos_fastlock_unlock(&data_lock, 0);
2469 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002470
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002471 return Status::OK;
2472}
2473
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002474Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2475
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002476 bcmolt_flow_cfg cfg;
2477 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002478
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002479 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002480 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002481 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002482 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002483 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002484 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002485 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002486 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002487 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2488 }
2489
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002490 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002491 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002492 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002493 flowid_to_gemport.erase(key.flow_id);
2494 port_to_flows[port_no].erase(key.flow_id);
2495 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2496 }
2497 else
2498 {
2499 flowid_to_port.erase(key.flow_id);
2500 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002501 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002502
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002503 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002504
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002505 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002506 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002507 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 -04002508 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2509 }
2510
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002511 bcmos_fastlock_lock(&data_lock);
2512 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2513 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2514 flow_id_counters -= 1;
2515 for (int i=flowid; i < flow_id_counters; i++) {
2516 flow_id_data[i][0] = flow_id_data[i + 1][0];
2517 flow_id_data[i][1] = flow_id_data[i + 1][1];
2518 }
2519 break;
2520 }
2521 }
2522 bcmos_fastlock_unlock(&data_lock, 0);
2523
2524 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002525 return Status::OK;
2526}
2527
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002528bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2529 bcmos_errno err;
2530 bcmolt_tm_sched_cfg tm_sched_cfg;
2531 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2532 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2533
Jason Huangbf45ffb2019-10-30 17:29:02 +08002534 //check TM scheduler has configured or not
2535 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2536 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002537 #ifdef TEST_MODE
2538 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2539 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2540 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2541 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2542 // code in production code.
2543 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2544 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002545 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002546 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002547 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002548 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 +08002549 return err;
2550 }
2551 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2552 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2553 return BCM_ERR_OK;
2554 }
2555
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002556 // bcmbal_tm_sched_owner
2557 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2558
2559 /**< The output of the tm_sched object instance */
2560 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2561
2562 if (direction.compare(upstream) == 0) {
2563 // In upstream it is NNI scheduler
2564 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2565 } else if (direction.compare(downstream) == 0) {
2566 // In downstream it is PON scheduler
2567 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2568 }
2569
2570 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2571
2572 // bcmbal_tm_sched_type
2573 // set the deafult policy to strict priority
2574 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2575
2576 // num_priorities: Max number of strict priority scheduling elements
2577 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2578
2579 // bcmbal_tm_shaping
2580 uint32_t cir = 1000000;
2581 uint32_t pir = 1000000;
2582 uint32_t burst = 65536;
2583 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2584 direction.c_str(), pir, burst);
2585 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2586 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2587 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2588 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2589 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2590 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2591
2592 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2593 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002594 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2595 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002596 return err;
2597 }
2598
2599 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2600 direction.c_str(), tm_sched_key.id, intf_id);
2601 return BCM_ERR_OK;
2602}
2603
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002604bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2605 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2606 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002607
2608 bcmos_errno err;
2609
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002610 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002611 bcmolt_tm_sched_cfg tm_sched_cfg;
2612 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2613 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002614
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002615 // bcmbal_tm_sched_owner
2616 // In downstream it is sub_term scheduler
2617 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002618
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002619 /**< The output of the tm_sched object instance */
2620 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002621
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002622 // bcmbal_tm_sched_parent
2623 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2624 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2625 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2626 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2627 be achieved using the' virtual' type of attachment.
2628 tm_sched_owner.u.sub_term.intf_id = intf_id;
2629 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2630 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002631
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002632 // bcmbal_tm_sched_type
2633 // set the deafult policy to strict priority
2634 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002635
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002636 // num_priorities: Max number of strict priority scheduling elements
2637 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002638
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002639 // bcmbal_tm_shaping
2640 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2641 uint32_t cir = tf_sh_info.cir();
2642 uint32_t pir = tf_sh_info.pir();
2643 uint32_t burst = tf_sh_info.pbs();
2644 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2645 cir, pir, burst);
2646 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2647 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2648 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2649 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2650 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2651 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002652 }
2653
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002654 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002655 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002656 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002657intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2658port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002659 return err;
2660 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002661 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2662uni_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 -08002663
2664 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002665 bcmolt_itupon_alloc_cfg cfg;
2666 bcmolt_itupon_alloc_key key = { };
2667 key.pon_ni = intf_id;
2668 key.alloc_id = alloc_id;
2669 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2670 int pir_bw = tf_sh_info.pir();
2671 int cir_bw = tf_sh_info.cir();
2672 //offset to match bandwidth granularity
2673 int offset_pir_bw = pir_bw%bw_granularity;
2674 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002675
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002676 pir_bw = pir_bw - offset_pir_bw;
2677 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002678
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002679 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002680
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002681 switch (additional_bw) {
2682 case 2: //AdditionalBW_BestEffort
2683 if (pir_bw == 0) {
2684 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2685%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002686 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002687 } else if (pir_bw < cir_bw) {
2688 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2689bandwidth (%d)\n", pir_bw, cir_bw);
2690 return BCM_ERR_PARM;
2691 } else if (pir_bw == cir_bw) {
2692 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2693bandwidth for additional bandwidth eligibility of type best_effort\n");
2694 return BCM_ERR_PARM;
2695 }
2696 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2697 break;
2698 case 1: //AdditionalBW_NA
2699 if (pir_bw == 0) {
2700 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2701%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2702 return BCM_ERR_PARM;
2703 } else if (cir_bw == 0) {
2704 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2705additional bandwidth eligibility of type Non-Assured (NA)\n");
2706 return BCM_ERR_PARM;
2707 } else if (pir_bw < cir_bw) {
2708 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2709bandwidth (%d)\n", pir_bw, cir_bw);
2710 return BCM_ERR_PARM;
2711 } else if (pir_bw == cir_bw) {
2712 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2713bandwidth for additional bandwidth eligibility of type non_assured\n");
2714 return BCM_ERR_PARM;
2715 }
2716 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2717 break;
2718 case 0: //AdditionalBW_None
2719 if (pir_bw == 0) {
2720 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
272116000 bytes/sec\n");
2722 return BCM_ERR_PARM;
2723 } else if (cir_bw == 0) {
2724 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2725for additional bandwidth eligibility of type None\n");
2726 return BCM_ERR_PARM;
2727 } else if (pir_bw > cir_bw) {
2728 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2729for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002730 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002731bandwidth in None eligibility\n", pir_bw);
2732 cir_bw = pir_bw;
2733 } else if (pir_bw < cir_bw) {
2734 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2735bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002736 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002737bandwidth in None eligibility\n", pir_bw);
2738 cir_bw = pir_bw;
2739 }
2740 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2741 break;
2742 default:
2743 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002744 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002745 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2746 in a fine granularity. */
2747 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2748 /* Fixed Bandwidth with no critical requirement of shaping */
2749 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2750 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2751 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2752 /* Maximum allocated bandwidth allowed for this alloc ID */
2753 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2754 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2755 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2756 for skipped allocations during quiet window */
2757 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2758 /**< Allocation Profile index for CBR non-RT Bandwidth */
2759 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2760 /**< Allocation Profile index for CBR RT Bandwidth */
2761 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2762 /**< Alloc ID Weight used in case of Extended DBA mode */
2763 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2764 /**< Alloc ID Priority used in case of Extended DBA mode */
2765 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2766 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002767
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002768 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002769 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002770 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 -05002771port_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 -08002772 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002773 }
Girish Gowdra96461052019-11-22 20:13:59 +05302774
2775 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2776 if (err) {
2777 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2778port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2779 return err;
2780 }
2781
2782 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2783port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2784
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002785 }
2786
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002787 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002788}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002789
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002790Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2791 uint32_t intf_id = traffic_scheds->intf_id();
2792 uint32_t onu_id = traffic_scheds->onu_id();
2793 uint32_t uni_id = traffic_scheds->uni_id();
2794 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002795 std::string direction;
2796 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002797 tech_profile::SchedulerConfig sched_config;
2798 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002799 uint32_t priority;
2800 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002801 tech_profile::SchedulingPolicy sched_policy;
2802 tech_profile::TrafficShapingInfo traffic_shaping_info;
2803 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002804
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002805 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2806 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002807
2808 direction = GetDirection(traffic_sched.direction());
2809 if (direction.compare("direction-not-supported") == 0)
2810 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2811
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002812 alloc_id = traffic_sched.alloc_id();
2813 sched_config = traffic_sched.scheduler();
2814 additional_bw = sched_config.additional_bw();
2815 priority = sched_config.priority();
2816 weight = sched_config.weight();
2817 sched_policy = sched_config.sched_policy();
2818 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2819 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2820 sched_policy, traffic_shaping_info);
2821 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002822 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002823 return bcm_to_grpc_err(err, "Failed to create scheduler");
2824 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002825 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002826 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002827}
Jonathan Davis70c21812018-07-19 15:32:10 -04002828
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002829bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002830
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002831 bcmos_errno err;
Girish Gowdra96461052019-11-22 20:13:59 +05302832 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002833
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002834 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002835 bcmolt_itupon_alloc_cfg cfg;
2836 bcmolt_itupon_alloc_key key = { };
2837 key.pon_ni = intf_id;
2838 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302839 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002840
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002841 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2842 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2843 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002844 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2845 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002846 return err;
2847 }
Girish Gowdra96461052019-11-22 20:13:59 +05302848
2849 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2850 if (err) {
2851 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2852 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2853 return err;
2854 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002855 } else if (direction == downstream) {
2856 bcmolt_tm_sched_cfg cfg;
2857 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002858
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002859 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2860 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05302861 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002862 } else {
2863 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2864 return BCM_ERR_OK;
2865 }
Girish Gowdra96461052019-11-22 20:13:59 +05302866
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002867 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2868 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2869 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002870 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2871intf_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 +00002872 return err;
2873 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002874 }
2875
Girish Gowdra96461052019-11-22 20:13:59 +05302876 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
2877 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002878 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002879 return BCM_ERR_OK;
2880}
2881
2882Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2883 uint32_t intf_id = traffic_scheds->intf_id();
2884 uint32_t onu_id = traffic_scheds->onu_id();
2885 uint32_t uni_id = traffic_scheds->uni_id();
2886 std::string direction;
2887 bcmos_errno err;
2888
2889 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2890 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002891
2892 direction = GetDirection(traffic_sched.direction());
2893 if (direction.compare("direction-not-supported") == 0)
2894 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2895
2896 int alloc_id = traffic_sched.alloc_id();
2897 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002898 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002899 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002900 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2901 }
2902 }
2903 return Status::OK;
2904}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002905
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002906bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2907 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002908 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002909 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2910 bcmolt_tm_qmp_key tm_qmp_key;
2911 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002912
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002913 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2914 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002915 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
2916 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002917 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002918
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002919 tm_qmp_key.id = tm_qmp_id;
2920 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2921 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2922 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002923
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002924 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2925 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2926 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2927 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2928 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002929
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002930 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002931 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002932 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2933 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002934 return err;
2935 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002936
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002937 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2938 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002939 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002940}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002941
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002942bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2943 bcmos_errno err;
2944 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2945 bcmolt_tm_qmp_key tm_qmp_key;
2946 tm_qmp_key.id = tm_qmp_id;
2947
2948 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2949 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2950 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002951 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
2952 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002953 return err;
2954 }
2955
2956 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2957 tm_qmp_key.id);
2958 return BCM_ERR_OK;
2959}
2960
2961bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2962 bcmos_errno err;
2963
2964 /* Create 4 Queues on given PON/NNI scheduler */
2965 for (int queue_id = 0; queue_id < 4; queue_id++) {
2966 bcmolt_tm_queue_cfg tm_queue_cfg;
2967 bcmolt_tm_queue_key tm_queue_key = {};
2968 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2969 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002970 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2971 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2972 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002973
2974 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2975 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2976 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2977
2978 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2979 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002980 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", \
2981 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 +00002982 return err;
2983 }
2984
2985 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2986 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2987 }
2988 return BCM_ERR_OK;
2989}
2990
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002991bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2992 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002993 bcmos_errno err;
2994 bcmolt_tm_queue_cfg cfg;
2995 bcmolt_tm_queue_key key = { };
2996 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2997gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2998
2999 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3000 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
3001
3002 if (priority > 7) {
3003 return BCM_ERR_RANGE;
3004 }
3005
3006 /* FIXME: The upstream queues have to be created once only.
3007 The upstream queues on the NNI scheduler are shared by all subscribers.
3008 When the first scheduler comes in, the queues get created, and are re-used by all others.
3009 Also, these queues should be present until the last subscriber exits the system.
3010 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
3011
3012 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
3013 for each GEM in TECH PROFILE */
3014 key.id = queue_id_list[priority];
3015
3016 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3017 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
3018 key.id = 0;
3019 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3020 }
3021 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3022 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3023 }
3024 else {
3025 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3026 }
3027
3028 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
3029
3030 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3031 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
3032
3033 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
3034 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003035 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
3036sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
3037 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 +00003038 return err;
3039 }
3040
3041 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3042intf_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);
3043 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003044}
3045
3046Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
3047 uint32_t intf_id = traffic_queues->intf_id();
3048 uint32_t onu_id = traffic_queues->onu_id();
3049 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003050 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003051 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003052 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003053 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 +00003054
3055 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3056 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
3057 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
3058 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3059 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
3060
3061 direction = GetDirection(traffic_queue.direction());
3062 if (direction.compare("direction-not-supported") == 0)
3063 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3064
3065 queues_priority_q[i] = traffic_queue.priority();
3066 queues_pbit_map[i] = traffic_queue.pbit_map();
3067 }
3068
3069 std::vector<uint32_t> tmq_map_profile(8, 0);
3070 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
3071 queues_priority_q, COUNT_OF(queues_priority_q));
3072 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3073 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3074
3075 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
3076 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003077 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
3078 if (err != BCM_ERR_OK) {
3079 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3080 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
3081 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003082 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
3083 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
3084 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
3085 }
3086 }
3087
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003088 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3089 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003090
3091 direction = GetDirection(traffic_queue.direction());
3092 if (direction.compare("direction-not-supported") == 0)
3093 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3094
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003095 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 +00003096
Girish Gowdruf26cf882019-05-01 23:47:58 -07003097 // If the queue exists already, lets not return failure and break the loop.
3098 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003099 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003100 return bcm_to_grpc_err(err, "Failed to create queue");
3101 }
3102 }
3103 return Status::OK;
3104}
3105
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003106bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
3107 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003108 bcmolt_tm_queue_cfg cfg;
3109 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003110 bcmos_errno err;
3111
3112 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003113 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
3114 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
3115 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003116 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003117 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 -08003118 return BCM_ERR_OK;
3119 }
3120 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003121 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3122 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003123 return BCM_ERR_OK;
3124 }
3125
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003126 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3127 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3128 // Reset the queue id to 0 when using fixed queue.
3129 key.id = 0;
3130 }
3131 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3132 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3133 }
3134 else {
3135 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3136 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003137
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003138 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3139 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003140 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003141 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
3142tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
3143 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 -08003144 return err;
3145 }
3146
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003147 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3148intf_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 -08003149
3150 return BCM_ERR_OK;
3151}
3152
3153Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
3154 uint32_t intf_id = traffic_queues->intf_id();
3155 uint32_t onu_id = traffic_queues->onu_id();
3156 uint32_t uni_id = traffic_queues->uni_id();
3157 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003158 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003159 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003160 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003161 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 +00003162
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003163 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3164 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003165
3166 direction = GetDirection(traffic_queue.direction());
3167 if (direction.compare("direction-not-supported") == 0)
3168 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3169
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003170 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 -08003171 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003172 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003173 return bcm_to_grpc_err(err, "Failed to remove queue");
3174 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003175 }
3176
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003177 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))) {
3178 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3179 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3180
3181 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3182 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003183 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3184 if (err != BCM_ERR_OK) {
3185 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3186 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3187 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003188 }
3189 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003190 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003191 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003192}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003193
3194Status check_connection() {
3195 int maxTrials = 60;
3196 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3197 sleep(1);
3198 if (--maxTrials == 0)
3199 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3200 else
3201 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3202 }
3203 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3204 return Status::OK;
3205}
3206
3207Status check_bal_ready() {
3208 bcmos_errno err;
3209 int maxTrials = 30;
3210 bcmolt_olt_cfg olt_cfg = { };
3211 bcmolt_olt_key olt_key = { };
3212
3213 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3214 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3215
3216 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3217 if (--maxTrials == 0)
3218 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3219 sleep(5);
3220 #ifdef TEST_MODE
3221 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3222 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3223 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003224 // of olt_cfg is passed. This is one-of case where we need to add test specific
3225 // code in production code.
3226 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003227 #else
3228 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3229 #endif
3230 continue;
3231 }
3232 else
3233 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3234 }
3235
3236 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3237 return Status::OK;
3238}