blob: a3653f3a876d2b08d6e47e1f011009da4492cdb5 [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
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800145std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000146std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800147
148static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600149
150#define MIN_ALLOC_ID_GPON 256
151#define MIN_ALLOC_ID_XGSPON 1024
152
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800153static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
154 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
155 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
156 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000157static 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 -0800158static 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 -0500159 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
160static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
161 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000162static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
163static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
164
165uint16_t get_dev_id(void) {
166 return dev_id;
167}
Shad Ansari627b5782018-08-13 22:49:32 +0000168
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400169// Stubbed defntions of bcmolt_cfg_get required for unit-test
170#ifdef TEST_MODE
171extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
172extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
173#endif
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800174/**
175* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
176* Every NNI port and PON port have default scheduler.
177* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
178* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
179*
180* @param intf_id NNI or PON interface ID
181* @param direction "upstream" or "downstream"
182*
183* @return default scheduler ID for the given interface.
184*/
185static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700186 if (direction.compare(upstream) == 0) {
187 return tm_upstream_sched_id_start + intf_id;
188 } else if (direction.compare(downstream) == 0) {
189 return tm_downstream_sched_id_start + intf_id;
190 }
191 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000192 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700193 return 0;
194 }
195}
196
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800197/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800198* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
199* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
200* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
201*
202* @param intf_id NNI or PON intf ID
203* @param onu_id ONU ID
204* @param uni_id UNI ID
205* @param gemport_id GEM Port ID
206* @param direction Upstream or downstream
207*
208* @return tm_sched_id
209*/
210uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
211 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
212 int sched_id = -1;
213
214 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
215 if (it != sched_map.end()) {
216 sched_id = it->second;
217 }
218 if (sched_id != -1) {
219 return sched_id;
220 }
221
222 bcmos_fastlock_lock(&data_lock);
223 // Complexity of O(n). Is there better way that can avoid linear search?
224 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
225 if (tm_sched_bitset[sched_id] == 0) {
226 tm_sched_bitset[sched_id] = 1;
227 break;
228 }
229 }
230 bcmos_fastlock_unlock(&data_lock, 0);
231
232 if (sched_id < MAX_TM_SCHED_ID) {
233 bcmos_fastlock_lock(&data_lock);
234 sched_map[key] = sched_id;
235 bcmos_fastlock_unlock(&data_lock, 0);
236 return sched_id;
237 } else {
238 return -1;
239 }
240}
241
242/**
243* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
244*
245* @param intf_id NNI or PON intf ID
246* @param onu_id ONU ID
247* @param uni_id UNI ID
248* @param gemport_id GEM Port ID
249* @param direction Upstream or downstream
250*/
251void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
252 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
253 std::map<sched_map_key_tuple, int>::const_iterator it;
254 bcmos_fastlock_lock(&data_lock);
255 it = sched_map.find(key);
256 if (it != sched_map.end()) {
257 tm_sched_bitset[it->second] = 0;
258 sched_map.erase(it);
259 }
260 bcmos_fastlock_unlock(&data_lock, 0);
261}
262
263bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
264 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000265 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
266 if (it != sched_map.end()) {
267 return true;
268 }
269 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800270}
271
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000272/**
273* Check whether given two tm qmp profiles are equal or not
274*
275* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
276* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
277*
278* @return boolean, true if given tmq_map_profiles are equal else false
279*/
280
281bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
282 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
283 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
284 return false;
285 }
286 }
287 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000288}
289
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000290/**
291* Modifies given queues_pbit_map to parsable format
292* e.g: Modifes "0b00000101" to "10100000"
293*
294* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
295* @param size Queue count
296*
297* @return string queues_pbit_map
298*/
299std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
300 for(uint32_t i=0; i < size; i++) {
301 /* Deletes 2 characters from index number 0 */
302 queues_pbit_map[i].erase(0, 2);
303 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
304 }
305 return queues_pbit_map;
306}
307
308/**
309* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
310*
311* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
312* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
313* @param size Queue count
314*
315* @return <vector> TM QUEUE MAPPING PROFILE
316*/
317std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
318 std::vector<uint32_t> tmq_map_profile(8,0);
319
320 for(uint32_t i=0; i < size; i++) {
321 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
322 if (queues_pbit_map[i][j]=='1') {
323 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
324 }
325 }
326 }
327 return tmq_map_profile;
328}
329
330/**
331* Gets corresponding tm_qmp_id for a given tmq_map_profile
332*
333* @param <vector> TM QUEUE MAPPING PROFILE
334*
335* @return tm_qmp_id
336*/
337int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
338 int tm_qmp_id = -1;
339
340 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
341 while(it != qmp_id_to_qmp_map.end()) {
342 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
343 tm_qmp_id = it->first;
344 break;
345 }
346 it++;
347 }
348 return tm_qmp_id;
349}
350
351/**
352* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
353*
354* @param upstream/downstream sched_id
355* @param PON intf ID
356* @param onu_id ONU ID
357* @param uni_id UNI ID
358* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
359*/
360void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
361 uint32_t uni_id, int tm_qmp_id) {
362 bcmos_fastlock_lock(&data_lock);
363 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
364 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
365 bcmos_fastlock_unlock(&data_lock, 0);
366}
367
368/**
369* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
370*
371* @param upstream/downstream sched_id
372* @param PON intf ID
373* @param onu_id ONU ID
374* @param uni_id UNI ID
375*
376* @return tm_qmp_id
377*/
378int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
379 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
380 int tm_qmp_id = -1;
381
382 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
383 if (it != sched_qmp_id_map.end()) {
384 tm_qmp_id = it->second;
385 }
386 return tm_qmp_id;
387}
388
389/**
390* Gets a unique tm_qmp_id for a given tmq_map_profile
391* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
392* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
393*
394* @param upstream/downstream sched_id
395* @param PON intf ID
396* @param onu_id ONU ID
397* @param uni_id UNI ID
398* @param <vector> TM QUEUE MAPPING PROFILE
399*
400* @return tm_qmp_id
401*/
402int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
403 std::vector<uint32_t> tmq_map_profile) {
404 int tm_qmp_id;
405
406 bcmos_fastlock_lock(&data_lock);
407 /* Complexity of O(n). Is there better way that can avoid linear search? */
408 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
409 if (tm_qmp_bitset[tm_qmp_id] == 0) {
410 tm_qmp_bitset[tm_qmp_id] = 1;
411 break;
412 }
413 }
414 bcmos_fastlock_unlock(&data_lock, 0);
415
416 if (tm_qmp_id < MAX_TM_QMP_ID) {
417 bcmos_fastlock_lock(&data_lock);
418 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
419 bcmos_fastlock_unlock(&data_lock, 0);
420 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
421 return tm_qmp_id;
422 } else {
423 return -1;
424 }
425}
426
427/**
428* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
429*
430* @param upstream/downstream sched_id
431* @param PON intf ID
432* @param onu_id ONU ID
433* @param uni_id UNI ID
434* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
435*
436* @return boolean, true if no more reference for TM QMP else false
437*/
438bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
439 uint32_t uni_id, int tm_qmp_id) {
440 bool result;
441 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
442 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
443 bcmos_fastlock_lock(&data_lock);
444 if (it != sched_qmp_id_map.end()) {
445 sched_qmp_id_map.erase(it);
446 }
447 bcmos_fastlock_unlock(&data_lock, 0);
448
449 uint32_t tm_qmp_ref_count = 0;
450 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
451 while(it2 != sched_qmp_id_map.end()) {
452 if(it2->second == tm_qmp_id) {
453 tm_qmp_ref_count++;
454 }
455 it2++;
456 }
457
458 if (tm_qmp_ref_count == 0) {
459 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
460 if (it3 != qmp_id_to_qmp_map.end()) {
461 bcmos_fastlock_lock(&data_lock);
462 tm_qmp_bitset[tm_qmp_id] = 0;
463 qmp_id_to_qmp_map.erase(it3);
464 bcmos_fastlock_unlock(&data_lock, 0);
465 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
466 tm_qmp_id, tm_qmp_ref_count);
467 result = true;
468 }
469 } else {
470 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
471 tm_qmp_id, tm_qmp_ref_count);
472 result = false;
473 }
474 return result;
475}
476
477/**
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500478* Returns qos type as string
479*
480* @param qos_type bcmolt_egress_qos_type enum
481*/
482std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type) {
483 switch (qos_type)
484 {
485 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE: return "FIXED_QUEUE";
486 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE: return "TC_TO_QUEUE";
487 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC: return "PBIT_TO_TC";
488 case BCMOLT_EGRESS_QOS_TYPE_NONE: return "NONE";
489 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE: return "PRIORITY_TO_QUEUE";
490 default: OPENOLT_LOG(ERROR, openolt_log_id, "qos-type-not-supported %d\n", qos_type);
491 return "qos-type-not-supported";
492 }
493}
494
495/**
496* Gets/Updates qos type for given pon_intf_id, onu_id, uni_id
497*
498* @param PON intf ID
499* @param onu_id ONU ID
500* @param uni_id UNI ID
501* @param queue_size TrafficQueues Size
502*
503* @return qos_type
504*/
505bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size = 0) {
506 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
507 bcmolt_egress_qos_type egress_qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
508 std::string qos_string;
509
510 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
511 if (it != qos_type_map.end()) {
512 egress_qos_type = it->second;
513 qos_string = get_qos_type_as_string(egress_qos_type);
514 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", \
515 pon_intf_id, onu_id, uni_id, qos_string.c_str());
516 }
517 else {
518 /* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
519 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
520 else Priority to Queue */
521 egress_qos_type = (queue_size > 1) ? \
522 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
523 bcmos_fastlock_lock(&data_lock);
524 qos_type_map.insert(make_pair(key, egress_qos_type));
525 bcmos_fastlock_unlock(&data_lock, 0);
526 qos_string = get_qos_type_as_string(egress_qos_type);
527 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", \
528 pon_intf_id, onu_id, uni_id, qos_string.c_str());
529 }
530 return egress_qos_type;
531}
532
533/**
534* Clears qos type for given pon_intf_id, onu_id, uni_id
535*
536* @param PON intf ID
537* @param onu_id ONU ID
538* @param uni_id UNI ID
539*/
540void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
541 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
542 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
543 bcmos_fastlock_lock(&data_lock);
544 if (it != qos_type_map.end()) {
545 qos_type_map.erase(it);
546 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", \
547 pon_intf_id, onu_id, uni_id);
548 }
549 bcmos_fastlock_unlock(&data_lock, 0);
550}
551
552/**
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000553* Returns Scheduler/Queue direction as string
554*
555* @param direction as specified in tech_profile.proto
556*/
557std::string GetDirection(int direction) {
558 switch (direction)
559 {
560 case tech_profile::Direction::UPSTREAM: return upstream;
561 case tech_profile::Direction::DOWNSTREAM: return downstream;
562 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
563 return "direction-not-supported";
564 }
565}
566
567inline const char *get_flow_acton_command(uint32_t command) {
568 char actions[200] = { };
569 char *s_actions_ptr = actions;
570 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
571 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
572 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
573 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
574 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
575 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
576 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
577 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
578 return s_actions_ptr;
579}
580
581char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800582{
583 FILE *fp;
584 /* Prepare the command*/
585 char command[150];
586
587 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
588 /* Open the command for reading. */
589 fp = popen(command, "r");
590 if (fp == NULL) {
591 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000592 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800593 return field_val;
594 }
595
596 /*Read the field value*/
597 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000598 uint8_t ret;
599 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
600 if (ret >= OPENOLT_FIELD_LEN)
601 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800602 pclose(fp);
603 }
604 return field_val;
605}
606
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400607Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500608 device_info->set_vendor(VENDOR_ID);
609 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400610 device_info->set_hardware_version("");
611 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500612 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500613 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500614
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800615 char serial_number[OPENOLT_FIELD_LEN];
616 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
617 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000618 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800619 device_info->set_device_serial_number(serial_number);
620
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700621 char device_id[OPENOLT_FIELD_LEN];
622 memset(device_id, '\0', OPENOLT_FIELD_LEN);
623 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000624 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700625 device_info->set_device_id(device_id);
626
Craig Lutgenb2601f02018-10-23 13:04:31 -0500627 // Legacy, device-wide ranges. To be deprecated when adapter
628 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000629 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500630 device_info->set_onu_id_start(1);
631 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600632 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500633 device_info->set_alloc_id_end(16383);
634 device_info->set_gemport_id_start(1024);
635 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500636 device_info->set_flow_id_start(1);
637 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500638 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000639 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500640 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500641 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600642 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500643 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500644 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500645 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500646 device_info->set_flow_id_start(1);
647 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500648 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500649
650 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
651 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
652 std::string intf_technology = intf_technologies[intf_id];
653 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
654 if(range == nullptr) {
655 range = device_info->add_ranges();
656 ranges[intf_technology] = range;
657 range->set_technology(intf_technology);
658
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000659 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500660 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
661
662 pool = range->add_pools();
663 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
664 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
665 pool->set_start(1);
666 pool->set_end(255);
667
668 pool = range->add_pools();
669 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
670 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
671 pool->set_start(1024);
672 pool->set_end(16383);
673
674 pool = range->add_pools();
675 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
676 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
677 pool->set_start(1024);
678 pool->set_end(65535);
679
680 pool = range->add_pools();
681 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
682 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
683 pool->set_start(1);
684 pool->set_end(16383);
685 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000686 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500687 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
688
689 pool = range->add_pools();
690 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
691 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
692 pool->set_start(1);
693 pool->set_end(127);
694
695 pool = range->add_pools();
696 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
697 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
698 pool->set_start(256);
699 pool->set_end(757);
700
701 pool = range->add_pools();
702 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
703 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
704 pool->set_start(256);
705 pool->set_end(4095);
706
707 pool = range->add_pools();
708 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
709 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
710 pool->set_start(1);
711 pool->set_end(16383);
712 }
713 }
714
715 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500716 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400717
718 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500719 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400720 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
721 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500722 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400723 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500724 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
725 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400726
727 return Status::OK;
728}
729
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000730Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
731{
732 openolt::Indication ind;
733 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
734
735 intf_oper_ind->set_type(type);
736 intf_oper_ind->set_intf_id(intf_id);
737 intf_oper_ind->set_oper_state(state);
738 ind.set_allocated_intf_oper_ind(intf_oper_ind);
739 oltIndQ.push(ind);
740 return Status::OK;
741}
742
743#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
744
745/* Build CLI prompt */
746static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
747{
748 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
749}
750
751static int _bal_apiend_cli_thread_handler(long data)
752{
753 char init_string[]="\n";
754 bcmcli_session *sess = current_session;
755 bcmos_task_parm bal_cli_task_p_dummy;
756
757 /* Switch to interactive mode if not stopped in the init script */
758 if (!bcmcli_is_stopped(sess))
759 {
760 /* Force a CLI command prompt
761 * The string passed into the parse function
762 * must be modifiable, so a string constant like
763 * bcmcli_parse(current_session, "\n") will not
764 * work.
765 */
766 bcmcli_parse(sess, init_string);
767
768 /* Process user input until EOF or quit command */
769 bcmcli_driver(sess);
770 };
771 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
772
773 /* Cleanup */
774 bcmcli_session_close(current_session);
775 bcmcli_token_destroy(NULL);
776 return 0;
777}
778
779/* Init API CLI commands for the current device */
780bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
781{
782 bcmos_errno rc;
783
784 api_parent_dir = parent_dir;
785
786 rc = bcm_api_cli_set_commands(session);
787
788#ifdef BCM_SUBSYSTEM_HOST
789 /* Subscribe for device change indication */
790 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
791#endif
792
793 return rc;
794}
795
796static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
797{
798 bcmcli_stop(session);
799 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
800 status_bcm_cli_quit = BCMOS_TRUE;
801
802 return BCM_ERR_OK;
803}
804
805int get_status_bcm_cli_quit(void) {
806 return status_bcm_cli_quit;
807}
808
809bcmos_errno bcmolt_apiend_cli_init() {
810 bcmos_errno ret;
811 bcmos_task_parm bal_cli_task_p = {};
812 bcmos_task_parm bal_cli_task_p_dummy;
813
814 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
815 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
816 {
817 /* Create BAL CLI thread */
818 bal_cli_task_p.name = bal_cli_thread_name;
819 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
820 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
821
822 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
823 if (BCM_ERR_OK != ret)
824 {
825 bcmos_printf("Couldn't create BAL API end CLI thread\n");
826 return ret;
827 }
828 }
829}
830
Shad Ansari627b5782018-08-13 22:49:32 +0000831Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000832 bcmos_errno err;
833 bcmolt_host_init_parms init_parms = {};
834 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
835 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000836
Shad Ansariedef2132018-08-10 22:14:50 +0000837 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000838
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500839 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000840 /* Initialize host subsystem */
841 err = bcmolt_host_init(&init_parms);
842 if (BCM_ERR_OK != err) {
843 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT\n");
844 return bcm_to_grpc_err(err, "Failed to init OLT");
845 }
846
847 bcmcli_session_parm mon_session_parm;
848 /* Create CLI session */
849 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
850 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
851 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
852 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
853 BUG_ON(rc != BCM_ERR_OK);
854
855 /* API CLI */
856 bcm_openolt_api_cli_init(NULL, current_session);
857
858 /* Add quit command */
859 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
860
861 err = bcmolt_apiend_cli_init();
862 if (BCM_ERR_OK != err) {
863 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init\n");
864 return bcm_to_grpc_err(err, "Failed to add apiend init");
865 }
866
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800867 bcmos_fastlock_init(&data_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000868 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600869
Jason Huangbf45ffb2019-10-30 17:29:02 +0800870 //check BCM daemon is connected or not
871 Status status = check_connection();
872 if (!status.ok())
873 return status;
874 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000875 Status status = SubscribeIndication();
876 if (!status.ok()) {
877 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
878 grpc_status_code_to_string(status.error_code()).c_str(),
879 status.error_message().c_str());
880 return status;
881 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800882
883 //check BAL state in initial stage
884 status = check_bal_ready();
885 if (!status.ok())
886 return status;
887 }
888
889 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000890 bcmos_errno err;
891 bcmolt_odid dev;
892 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
893 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400894 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000895 bcmolt_device_key dev_key = { };
896 dev_key.device_id = dev;
897 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
898 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
899 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800900 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000901 bcmolt_device_key key = {.device_id = dev};
902 bcmolt_device_connect oper;
903 BCMOLT_OPER_INIT(&oper, device, connect, key);
904 if (MODEL_ID == "asfvolt16") {
905 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
906 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
907 } else if (MODEL_ID == "asgvolt64") {
908 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
909 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
910 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
911 }
912 err = bcmolt_oper_submit(dev_id, &oper.hdr);
913 if (err) {
914 failed_enable_device_cnt ++;
915 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err %d\n", dev, err);
916 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
917 OPENOLT_LOG(ERROR, openolt_log_id, "failed to enable all the pon ports\n");
918 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
919 }
920 }
921 bcmos_usleep(200000);
922 }
923 else {
924 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
925 state.activate();
926 }
927 }
928 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +0000929 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000930 }
Shad Ansariedef2132018-08-10 22:14:50 +0000931
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000932 /* Start CLI */
933 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400934 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000935 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400936}
937
938Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400939 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
940 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
941 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
942 //To overcome this disable is implemented by disabling all the PON ports
943 //associated with the device so as to support both in-band
944 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400945
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400946 Status status;
947 int failedCount = 0;
948 for (int i = 0; i < NumPonIf_(); i++) {
949 status = DisablePonIf_(i);
950 if (!status.ok()) {
951 failedCount+=1;
952 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
953 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400954 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400955 if (failedCount == 0) {
956 state.deactivate();
957 openolt::Indication ind;
958 openolt::OltIndication* olt_ind = new openolt::OltIndication;
959 olt_ind->set_oper_state("down");
960 ind.set_allocated_olt_ind(olt_ind);
961 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
962 oltIndQ.push(ind);
963 return Status::OK;
964 }
965 if (failedCount ==NumPonIf_()){
966 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
967 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400968
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400969 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 -0400970}
971
972Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400973 Status status;
974 int failedCount = 0;
975 for (int i = 0; i < NumPonIf_(); i++) {
976 status = EnablePonIf_(i);
977 if (!status.ok()) {
978 failedCount+=1;
979 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
980 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400981 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400982 if (failedCount == 0){
983 state.activate();
984 openolt::Indication ind;
985 openolt::OltIndication* olt_ind = new openolt::OltIndication;
986 olt_ind->set_oper_state("up");
987 ind.set_allocated_olt_ind(olt_ind);
988 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
989 oltIndQ.push(ind);
990 return Status::OK;
991 }
992 if (failedCount ==NumPonIf_()){
993 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
994 }
995 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 +0000996}
997
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000998bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
999 bcmos_errno err;
1000 bcmolt_pon_interface_key pon_key;
1001 bcmolt_pon_interface_cfg pon_cfg;
1002 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001003
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001004 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
1005 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
1006 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
1007 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
1008 *state = pon_cfg.data.state;
1009 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001010}
1011
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001012inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
1013 bcmos_errno err;
1014 bcmolt_flow_key flow_key;
1015 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001016
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001017 flow_key.flow_id = flow_id;
1018 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001019
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001020 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001021
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001022 switch (data_id) {
1023 case ONU_ID: //onu_id
1024 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
1025 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1026 if (err) {
1027 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id\n");
1028 return err;
1029 }
1030 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001031 case FLOW_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001032 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1033 if (err) {
1034 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type\n");
1035 return err;
1036 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001037 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001038 case SVC_PORT_ID: //svc_port_id
1039 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
1040 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1041 if (err) {
1042 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id\n");
1043 return err;
1044 }
1045 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001046 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001047 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
1048 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1049 if (err) {
1050 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority\n");
1051 return err;
1052 }
1053 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001054 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001055 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
1056 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1057 if (err) {
1058 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie\n");
1059 return err;
1060 }
1061 return flow_cfg.data.cookie;
1062 case INGRESS_INTF_TYPE: //ingress intf_type
1063 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1064 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1065 if (err) {
1066 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type\n");
1067 return err;
1068 }
1069 return flow_cfg.data.ingress_intf.intf_type;
1070 case EGRESS_INTF_TYPE: //egress intf_type
1071 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1072 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1073 if (err) {
1074 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type\n");
1075 return err;
1076 }
1077 return flow_cfg.data.egress_intf.intf_type;
1078 case INGRESS_INTF_ID: //ingress intf_id
1079 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
1080 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1081 if (err) {
1082 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id\n");
1083 return err;
1084 }
1085 return flow_cfg.data.ingress_intf.intf_id;
1086 case EGRESS_INTF_ID: //egress intf_id
1087 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
1088 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1089 if (err) {
1090 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id\n");
1091 return err;
1092 }
1093 return flow_cfg.data.egress_intf.intf_id;
1094 case CLASSIFIER_O_VID:
1095 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1096 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1097 if (err) {
1098 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid\n");
1099 return err;
1100 }
1101 return flow_cfg.data.classifier.o_vid;
1102 case CLASSIFIER_O_PBITS:
1103 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1104 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1105 if (err) {
1106 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits\n");
1107 return err;
1108 }
1109 return flow_cfg.data.classifier.o_pbits;
1110 case CLASSIFIER_I_VID:
1111 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1112 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1113 if (err) {
1114 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid\n");
1115 return err;
1116 }
1117 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001118 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001119 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1120 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1121 if (err) {
1122 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits\n");
1123 return err;
1124 }
1125 return flow_cfg.data.classifier.i_pbits;
1126 case CLASSIFIER_ETHER_TYPE:
1127 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1128 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1129 if (err) {
1130 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type\n");
1131 return err;
1132 }
1133 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001134 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001135 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1136 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1137 if (err) {
1138 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto\n");
1139 return err;
1140 }
1141 return flow_cfg.data.classifier.ip_proto;
1142 case CLASSIFIER_SRC_PORT:
1143 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1144 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1145 if (err) {
1146 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port\n");
1147 return err;
1148 }
1149 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001150 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001151 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1152 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1153 if (err) {
1154 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port\n");
1155 return err;
1156 }
1157 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001158 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001159 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
1160 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1161 if (err) {
1162 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type\n");
1163 return err;
1164 }
1165 return flow_cfg.data.classifier.pkt_tag_type;
1166 case EGRESS_QOS_TYPE:
1167 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1168 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1169 if (err) {
1170 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type\n");
1171 return err;
1172 }
1173 return flow_cfg.data.egress_qos.type;
1174 case EGRESS_QOS_QUEUE_ID:
1175 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1176 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1177 if (err) {
1178 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id\n");
1179 return err;
1180 }
1181 switch (flow_cfg.data.egress_qos.type) {
1182 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1183 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1184 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1185 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1186 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1187 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1188 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1189 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1190 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1191 default:
1192 return -1;
1193 }
1194 case EGRESS_QOS_TM_SCHED_ID:
1195 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
1196 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1197 if (err) {
1198 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id\n");
1199 return err;
1200 }
1201 return flow_cfg.data.egress_qos.tm_sched.id;
1202 case ACTION_CMDS_BITMASK:
1203 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1204 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1205 if (err) {
1206 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask\n");
1207 return err;
1208 }
1209 return flow_cfg.data.action.cmds_bitmask;
1210 case ACTION_O_VID:
1211 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1212 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1213 if (err) {
1214 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid\n");
1215 return err;
1216 }
1217 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001218 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001219 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1220 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1221 if (err) {
1222 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits\n");
1223 return err;
1224 }
1225 return flow_cfg.data.action.o_pbits;
1226 case ACTION_I_VID:
1227 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1228 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1229 if (err) {
1230 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid\n");
1231 return err;
1232 }
1233 return flow_cfg.data.action.i_vid;
1234 case ACTION_I_PBITS:
1235 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
1236 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1237 if (err) {
1238 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits\n");
1239 return err;
1240 }
1241 return flow_cfg.data.action.i_pbits;
1242 case STATE:
1243 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
1244 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1245 if (err) {
1246 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state\n");
1247 return err;
1248 }
1249 return flow_cfg.data.state;
1250 default:
1251 return BCM_ERR_INTERNAL;
1252 }
1253
1254 return err;
1255}
1256
1257Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001258 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001259 bcmolt_pon_interface_cfg interface_obj;
1260 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1261 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1262 bcmolt_interface_state state;
1263
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001264 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001265 if (err == BCM_ERR_OK) {
1266 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001267 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001268 return Status::OK;
1269 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001270 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001271 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1272 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1273 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1274 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1275 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1276 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1277 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1278 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1279 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1280 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1281 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1282 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1283 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1284 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1285
1286 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1287 if (err != BCM_ERR_OK) {
1288 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err %d\n", intf_id, err);
1289 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1290 }
1291 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1292 if (err != BCM_ERR_OK) {
1293 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", intf_id);
1294 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1295 }
1296 else {
1297 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1298 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1299 CreateDefaultSched(intf_id, downstream);
1300 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001301 }
1302
1303 return Status::OK;
1304}
1305
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001306/* Same as bcmolt_cfg_get but with added logic of retrying the API
1307 in case of some specific failures like timeout or object not yet ready
1308*/
1309bcmos_errno bcmolt_cfg_get_mult_retry(bcmolt_oltid olt, bcmolt_cfg *cfg) {
1310 bcmos_errno err;
1311 uint32_t current_try = 0;
1312
1313 while (current_try < MAX_BAL_API_RETRY_COUNT) {
1314 err = bcmolt_cfg_get(olt, cfg);
1315 current_try++;
1316
1317 if (err == BCM_ERR_STATE || err == BCM_ERR_TIMEOUT) {
1318 OPENOLT_LOG(WARNING, openolt_log_id, "bcmolt_cfg_get: err = %s(%d)\n",bcmos_strerror(err), err);
1319 bcmos_usleep(BAL_API_RETRY_TIME_IN_USECS);
1320 continue;
1321 }
1322 else {
1323 break;
1324 }
1325 }
1326
1327 if (err != BCM_ERR_OK) {
1328 OPENOLT_LOG(ERROR, openolt_log_id, "bcmolt_cfg_get tried (%d) times with retry time(%d usecs) err=%d\n",
1329 current_try,
1330 BAL_API_RETRY_TIME_IN_USECS,
1331 err);
1332 }
1333 return err;
1334}
1335
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001336Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001337 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001338 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001339 bcmolt_device_key dev_key = { };
1340 bcmolt_olt_cfg olt_cfg = { };
1341 bcmolt_olt_key olt_key = { };
1342 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1343 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001344
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001345 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1346 topo.topology_maps.arr = &topo_map[0];
1347 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1348 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1349 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001350 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001351 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001352 #ifdef TEST_MODE
1353 // It is impossible to mock the setting of olt_cfg.data.bal_state because
1354 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
1355 // set the olt_cfg.data.topology. So a new stub function is created and address
1356 // of olt_cfg is passed. This is one-of case where we need to test add specific
1357 // code in production code.
1358 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1359 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001360 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001361 #endif
1362 if (err) {
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001363 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT topology\n");
1364 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001365 }
1366
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001367 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1368 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001369
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001370 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1371 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001372 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001373
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001374 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1375 num_of_nni_ports,
1376 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001377 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001378
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001379 uint32_t num_failed_cfg_gets = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001380 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1381 dev_key.device_id = devid;
1382 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1383 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1384 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1385 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001386 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001387 if (err) {
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001388 OPENOLT_LOG(WARNING, openolt_log_id,"Failed to query PON MAC Device %d (errno = %d). Skipping the device.\n", devid, err);
1389 num_failed_cfg_gets++;
1390 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001391 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001392
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001393 std::string bal_version;
1394 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1395 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1396 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1397 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1398
1399 switch(dev_cfg.data.system_mode) {
1400 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1401 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1402 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1403 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1404 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1405 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1406 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1407 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1408 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1409 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1410 }
1411
1412 switch(dev_cfg.data.chip_family) {
1413 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1414 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1415 }
1416
1417 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1418 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1419
1420 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001421 }
1422
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001423 /* If all the devices returned errors then we tell the caller that this is an error else we work with
1424 only the devices that retured success*/
1425 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1426 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1427 return bcm_to_grpc_err(err, "device: All devices failed query");
1428 }
1429
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001430 return Status::OK;
1431}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001432#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001433Status ProbePonIfTechnology_() {
1434 // Probe maximum extent possible as configured into BAL driver to determine
1435 // which are active in the current BAL topology. And for those
1436 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1437 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001438 bcmolt_pon_interface_cfg interface_obj;
1439 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001440
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001441 interface_key.pon_ni = intf_id;
1442 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001443 if (board_technology == "XGS-PON"
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001444 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1445 else if (board_technology == "GPON")
1446 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001447
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001448 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001449 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001450 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001451 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 -05001452 }
1453 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001454 if (board_technology == "XGS-PON") {
1455 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1456 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1457 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1458 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1459 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1460 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1461 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1462 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1463 intf_technologies[intf_id] = "XGS-PON";
1464 break;
1465 }
1466 } else if (board_technology == "GPON") {
1467 switch(interface_obj.data.gpon_trx.transceiver_type) {
1468 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1469 case BCMOLT_TRX_TYPE_LTE_3680_M:
1470 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1471 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1472 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1473 intf_technologies[intf_id] = "GPON";
1474 break;
1475 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001476 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001477
1478 if (board_technology != UNKNOWN_TECH) {
1479 board_technology = intf_technologies[intf_id];
1480 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1481 intf_technologies[intf_id] = MIXED_TECH;
1482 }
1483
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001484 }
1485 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001486 return Status::OK;
1487}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001488#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001489unsigned NumNniIf_() {return num_of_nni_ports;}
1490unsigned NumPonIf_() {return num_of_pon_ports;}
1491
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001492bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1493 bcmos_errno err;
1494 bcmolt_nni_interface_key nni_key;
1495 bcmolt_nni_interface_cfg nni_cfg;
1496 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001497
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001498 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1499 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
1500 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
1501 *state = nni_cfg.data.state;
1502 return err;
1503}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001504
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001505Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1506 bcmos_errno err = BCM_ERR_OK;
1507 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1508 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1509 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001510
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001511 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001512 if (err == BCM_ERR_OK) {
1513 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001514 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001515 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1516 CreateDefaultSched(intf_id, upstream);
1517 CreateDefaultQueue(intf_id, upstream);
1518 return Status::OK;
1519 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1520 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1521 return Status::OK;
1522 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001523 }
1524
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001525 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1526 if (set_state) {
1527 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1528 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1529 } else {
1530 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1531 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1532 }
1533 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1534 if (err != BCM_ERR_OK) {
1535 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err %d\n",
1536 (set_state)?"enable":"disable", intf_id, err);
1537 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1538 }
1539 else {
1540 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1541 if (set_state) {
1542 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1543 CreateDefaultSched(intf_id, upstream);
1544 CreateDefaultQueue(intf_id, upstream);
1545 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001546 }
1547
1548 return Status::OK;
1549}
1550
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001551Status DisablePonIf_(uint32_t intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001552 bcmolt_pon_interface_cfg interface_obj;
1553 bcmolt_pon_interface_key interface_key;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001554
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001555 interface_key.pon_ni = intf_id;
1556 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
1557 BCMOLT_MSG_FIELD_GET(&interface_obj, state);
1558 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001559 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001560 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", intf_id);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001561 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001562 }
1563
1564 return Status::OK;
1565}
1566
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001567Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001568 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001569 bcmos_errno err = BCM_ERR_OK;
1570 bcmolt_onu_cfg onu_cfg;
1571 bcmolt_onu_key onu_key;
1572 bcmolt_serial_number serial_number; /**< ONU serial number */
1573 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001574
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001575 onu_key.onu_id = onu_id;
1576 onu_key.pon_ni = intf_id;
1577 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1578 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1579 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001580 if (err == BCM_ERR_OK) {
1581 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001582 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1583 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1584 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1585 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001586 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001587
1588 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001589vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001590 vendor_specific_to_str(vendor_specific).c_str(), pir);
1591
1592 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1593 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1594 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1595 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1596 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1597 /*set burst and data profiles to fec disabled*/
1598 if (board_technology == "XGS-PON") {
1599 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1600 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1601 } else if (board_technology == "GPON") {
1602 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1603 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1604 }
1605 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1606 if (err != BCM_ERR_OK) {
1607 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1608 return bcm_to_grpc_err(err, "Failed to activate ONU");
1609 }
1610
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001611 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001612}
1613
Jonathan Davis70c21812018-07-19 15:32:10 -04001614Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1615 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001616 bcmos_errno err = BCM_ERR_OK;
1617 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1618 bcmolt_onu_cfg onu_cfg;
1619 bcmolt_onu_key onu_key; /**< Object key. */
1620 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001621
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001622 onu_key.onu_id = onu_id;
1623 onu_key.pon_ni = intf_id;
1624 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1625 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
1626 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001627 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001628 switch (onu_state) {
1629 case BCMOLT_ONU_OPERATION_ACTIVE:
1630 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001631 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001632 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1633 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1634 if (err != BCM_ERR_OK) {
1635 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to \
1636deactivate ONU %d on PON %d, err %d\n", onu_id, intf_id, err);
1637 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1638 }
1639 break;
1640 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001641 }
1642
1643 return Status::OK;
1644}
1645
1646Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001647 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001648
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001649 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 -05001650 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1651
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001652 // Need to deactivate before removing it (BAL rules)
1653
1654 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1655 // Sleep to allow the state to propagate
1656 // We need the subscriber terminal object to be admin down before removal
1657 // Without sleep the race condition is lost by ~ 20 ms
1658 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1659
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001660 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001661
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001662 bcmolt_onu_cfg cfg_obj;
1663 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001664
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001665 OPENOLT_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001666 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001667
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001668 key.onu_id = onu_id;
1669 key.pon_ni = intf_id;
1670 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001671
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001672 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001673 if (err != BCM_ERR_OK)
1674 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001675 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001676 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001677 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1678 }
1679
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001680 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001681}
1682
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001683#define MAX_CHAR_LENGTH 20
1684#define MAX_OMCI_MSG_LENGTH 44
1685Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001686 bcmolt_bin_str buf = {};
1687 bcmolt_onu_cpu_packets omci_cpu_packets;
1688 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001689
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001690 key.pon_ni = intf_id;
1691 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001692
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001693 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1694 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1695 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001696
1697 // ???
1698 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1699 buf.len = MAX_OMCI_MSG_LENGTH;
1700 } else {
1701 buf.len = pkt.size()/2;
1702 }
1703
1704 /* Send the OMCI packet using the BAL remote proxy API */
1705 uint16_t idx1 = 0;
1706 uint16_t idx2 = 0;
1707 uint8_t arraySend[buf.len];
1708 char str1[MAX_CHAR_LENGTH];
1709 char str2[MAX_CHAR_LENGTH];
1710 memset(&arraySend, 0, buf.len);
1711
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001712 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1713 sprintf(str1,"%c", pkt[idx1]);
1714 sprintf(str2,"%c", pkt[++idx1]);
1715 strcat(str1,str2);
1716 arraySend[idx2] = strtol(str1, NULL, 16);
1717 }
1718
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001719 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1720 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001721
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001722 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1723 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1724 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001725
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001726 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001727 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001728 OPENOLT_LOG(ERROR, omci_log_id, "Error sending OMCI message to ONU %d on PON %d\n", onu_id, intf_id);
1729 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001730 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001731 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 -05001732 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001733 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001734 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001735
1736 return Status::OK;
1737}
1738
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001739Status 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 +00001740 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1741 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1742 bcmolt_bin_str buf = {};
1743 bcmolt_gem_port_id gem_port_id_array[1];
1744 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001745
Craig Lutgen967a1d02018-11-27 10:41:51 -06001746 if (port_no > 0) {
1747 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001748 if (gemport_id == 0) {
1749 bcmos_fastlock_lock(&data_lock);
1750 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1751 // Pick any flow that is mapped with the same port_no.
1752 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
1753 if (it != port_to_flows.end() && !it->second.empty()) {
1754 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
1755 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
1756 if (fit != flowid_to_gemport.end()) {
1757 found = true;
1758 gemport_id = fit->second;
1759 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06001760 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001761 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001762
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001763 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001764 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 -08001765 onu_id, port_no, intf_id);
1766 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
1767 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001768 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 -08001769 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001770 }
1771
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001772 gem_port_id_array[0] = gemport_id;
1773 gem_port_list.len = 1;
1774 gem_port_list.arr = gem_port_id_array;
1775 buf.len = pkt.size();
1776 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1777 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
1778
1779 /* init the API struct */
1780 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
1781 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
1782 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
1783 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
1784 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
1785
1786 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
1787 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
1788
1789 /* call API */
1790 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001791 }
1792 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001793 //TODO: Port No is 0, it is coming sender requirement.
1794 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
1795 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001796 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001797 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001798
1799 return Status::OK;
1800}
1801
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001802Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001803 bcmolt_flow_key key = {}; /* declare key */
1804 bcmolt_bin_str buffer = {};
1805 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001806
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001807 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
1808 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001809
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001810 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
1811 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1812 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1813 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
1814 key.flow_id = flow_id;
1815 else {
1816 if (flow_id_counters != 0) {
1817 for (int flowid=0; flowid < flow_id_counters; flowid++) {
1818 int flow_index = flow_id_data[flowid][0];
1819 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
1820 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
1821 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
1822 key.flow_id = flow_index;
1823 break;
1824 }
1825 }
1826 }
1827 else {
1828 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
1829 }
1830 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001831
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001832 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001833
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001834 /* Initialize the API struct. */
1835 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001836
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001837 buffer.len = pkt.size();
1838 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
1839 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
1840 if (buffer.arr == NULL) {
1841 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
1842 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
1843 }
1844 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
1845
1846 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
1847 if (err) {
1848 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d err %d\n", intf_id, key.flow_id, err);
1849 } else {
1850 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
1851 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04001852
1853 return Status::OK;
1854}
1855
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001856uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001857 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001858 uint32_t port_no = 0;
1859 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
1860 if (it != flowid_to_port.end()) {
1861 port_no = it->second;
1862 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001863 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06001864 return port_no;
1865}
1866
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001867#define FLOW_LOG(level,msg,err) \
1868 do { \
1869 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
1870 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
1871 access_intf_id, onu_id, uni_id, port_no, cookie); \
1872 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
1873 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
1874 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
1875 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
1876 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
1877 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
1878 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
1879 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", \
1880 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
1881 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
1882 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 -04001883 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001884
1885#define FLOW_PARAM_LOG() \
1886 do { \
1887 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
1888 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
1889 key.flow_id, flow_index); \
1890 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
1891 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
1892 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
1893 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
1894 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
1895 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
1896 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
1897 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
1898 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
1899 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
1900 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
1901 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
1902 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
1903 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
1904 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
1905 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
1906 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
1907 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
1908 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
1909 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
1910 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
1911 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
1912 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
1913 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
1914 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
1915 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
1916 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
1917 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
1918 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
1919 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
1920 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
1921 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
1922 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
1923 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
1924 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
1925 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
1926 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
1927 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
1928 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
1929 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
1930 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
1931 cfg.data.egress_qos.u.fixed_queue.queue_id, \
1932 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
1933 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
1934 cfg.data.egress_qos.tm_sched.id, \
1935 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
1936 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
1937 get_flow_acton_command(a_val.cmds_bitmask), \
1938 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
1939 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
1940 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
1941 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
1942 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
1943 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
1944 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
1945 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
1946 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
1947 } while(0)
1948
1949#define FLOW_CHECKER
1950//#define SHOW_FLOW_PARAM
1951
Craig Lutgen967a1d02018-11-27 10:41:51 -06001952Status 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 +00001953 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001954 int32_t alloc_id, int32_t network_intf_id,
1955 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06001956 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001957 bcmolt_flow_cfg cfg;
1958 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001959 int32_t o_vid = -1;
1960 bool single_tag = false;
1961 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001962 bcmolt_classifier c_val = { };
1963 bcmolt_action a_val = { };
1964 bcmolt_tm_queue_ref tm_val = { };
1965 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05001966 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001967
1968 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001969 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001970 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001971 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001972 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001973 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001975 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001976 }
1977
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001978 BCMOLT_CFG_INIT(&cfg, flow, key);
1979 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001980
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001981 if (access_intf_id >= 0 && network_intf_id >= 0) {
1982 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
1983 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1984 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
1985 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
1986 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
1987 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
1988 } else {
1989 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1990 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
1991 }
1992 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
1993 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
1994 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
1995 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
1996 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
1997 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05301998 } else if (access_intf_id < 0 ) {
1999 // This is the case for packet trap from NNI flow.
2000 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2001 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2002 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002003 } else {
2004 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2005 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
2006 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002007
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302008
Shad Ansari39739bc2018-09-13 21:38:37 +00002009 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002010 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002011 }
2012 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002013 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002014 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002015 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002016 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002017 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002018 port_to_flows[port_no].insert(key.flow_id);
2019 flowid_to_gemport[key.flow_id] = gemport_id;
2020 }
2021 else
2022 {
2023 flowid_to_port[key.flow_id] = port_no;
2024 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002025 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002026 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002027 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002028 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00002029 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002030
2031 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002032 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002033 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002034 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002035 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002036 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002037 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002038 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002039 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002040 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002041 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002042 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002043 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002044
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002045 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002046 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002047 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2048 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002049 }
2050
2051 /*
2052 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002053 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002054 }
2055
2056 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002057 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002058 }
2059 */
2060
2061 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002062 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2063 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002064 }
2065
2066 /*
2067 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002068 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002069 }
2070
2071 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002072 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002073 }
2074 */
2075
2076 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002077 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2078 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002079 }
2080
2081 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002082 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2083 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002084 }
2085
2086 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302087 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2088 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2089 // This is case where packet traps from NNI port. As per Broadcom workaround
2090 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2091 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2092 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2093 } else {
2094 if (classifier.o_vid()) {
2095 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2096 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2097 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002098
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302099 if (classifier.i_vid()) {
2100 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2101 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2102 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002103
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302104 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2105 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2106 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2107 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2108 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2109 single_tag = true;
2110
2111 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
2112 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2113 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2114 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2115
2116 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
2117 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2118 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002119 }
2120 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002121 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002122 }
2123
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002124 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002125 const ::openolt::ActionCmd& cmd = action.cmd();
2126
2127 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002128 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2129 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002130 }
2131
2132 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002133 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2134 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002135 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002136 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002137 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002138 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002139 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002140 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002141 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002142 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002143 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002144 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002145 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002146 }
2147
2148 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002149 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2150 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002151 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002152 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002153 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002154 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002155 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002156 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002157 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002158 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002159 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2160 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002161 }
2162
2163 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002164 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2165 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002166 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002167 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002168 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002169 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002170 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002171 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002172 */
2173 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002174 }
2175
Shad Ansari39739bc2018-09-13 21:38:37 +00002176 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002177 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2178 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2179 get_default_tm_sched_id(network_intf_id, upstream) : \
2180 get_default_tm_sched_id(access_intf_id, downstream);
2181 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002182
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002183 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2184 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2185 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002186
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002187 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2188 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2189 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2190 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002191 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002192 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2193 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2194
2195 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2196 // Queue 0 on DS subscriber scheduler
2197 tm_val.queue_id = 0;
2198
2199 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2200 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2201 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2202
2203 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2204 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2205 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2206
2207 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2208 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2209 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2210
2211 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2212 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2213 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2214 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2215
2216 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2217 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2218 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2219 }
2220 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2221 // NNI Scheduler ID
2222 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2223 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2224 // Queue 0 on NNI scheduler
2225 tm_val.queue_id = 0;
2226 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2227 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2228 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2229
2230 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2231 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2232 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2233
2234 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2235 /* Fetch TM QMP ID mapped to US NNI scheduler */
2236 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2237 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2238 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2239 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2240 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2241
2242 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2243 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2244 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2245 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002246 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002247 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302248 } else {
2249 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2250 tm_val.queue_id = 0;
2251
2252 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2253 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2254 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2255
2256 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2257 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2258 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002259 }
2260
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002261 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2262 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2263#ifdef FLOW_CHECKER
2264 //Flow Checker, To avoid duplicate flow.
2265 if (flow_id_counters != 0) {
2266 bool b_duplicate_flow = false;
2267 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2268 int flow_index = flow_id_data[flowid][0];
2269 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2270 (key.flow_type == flow_id_data[flowid][1]) && \
2271 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2272 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2273 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2274 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2275 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2276 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2277 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2278 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2279 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2280 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2281 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2282 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2283 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2284 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2285 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2286 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2287 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2288 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2289 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2290 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2291 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2292 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2293 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2294 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2295 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2296#ifdef SHOW_FLOW_PARAM
2297 // Flow Parameter
2298 FLOW_PARAM_LOG();
2299#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002300
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002301 if (b_duplicate_flow) {
2302 FLOW_LOG(WARNING, "Flow duplicate", 0);
2303 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2304 }
2305 }
2306 }
2307#endif
2308
2309 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2310 if (err) {
2311 FLOW_LOG(ERROR, "Flow add failed", err);
2312 return bcm_to_grpc_err(err, "flow add failed");
2313 } else {
2314 FLOW_LOG(INFO, "Flow add ok", err);
2315 bcmos_fastlock_lock(&data_lock);
2316 flow_id_data[flow_id_counters][0] = key.flow_id;
2317 flow_id_data[flow_id_counters][1] = key.flow_type;
2318 flow_id_counters += 1;
2319 bcmos_fastlock_unlock(&data_lock, 0);
2320 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002321
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002322 return Status::OK;
2323}
2324
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002325Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2326
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002327 bcmolt_flow_cfg cfg;
2328 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002329
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002330 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002331 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002332 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002333 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002334 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002335 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002336 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002337 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002338 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2339 }
2340
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002341 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002342 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002343 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002344 flowid_to_gemport.erase(key.flow_id);
2345 port_to_flows[port_no].erase(key.flow_id);
2346 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2347 }
2348 else
2349 {
2350 flowid_to_port.erase(key.flow_id);
2351 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002352 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002353
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002354 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002355
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002356 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002357 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002358 OPENOLT_LOG(ERROR, openolt_log_id, "Error %d while removing flow %d, %s\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04002359 err, flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002360 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2361 }
2362
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002363 bcmos_fastlock_lock(&data_lock);
2364 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2365 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2366 flow_id_counters -= 1;
2367 for (int i=flowid; i < flow_id_counters; i++) {
2368 flow_id_data[i][0] = flow_id_data[i + 1][0];
2369 flow_id_data[i][1] = flow_id_data[i + 1][1];
2370 }
2371 break;
2372 }
2373 }
2374 bcmos_fastlock_unlock(&data_lock, 0);
2375
2376 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002377 return Status::OK;
2378}
2379
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002380bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2381 bcmos_errno err;
2382 bcmolt_tm_sched_cfg tm_sched_cfg;
2383 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2384 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2385
Jason Huangbf45ffb2019-10-30 17:29:02 +08002386 //check TM scheduler has configured or not
2387 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2388 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
2389 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
2390 if (err) {
2391 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler\n");
2392 return err;
2393 }
2394 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2395 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2396 return BCM_ERR_OK;
2397 }
2398
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002399 // bcmbal_tm_sched_owner
2400 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2401
2402 /**< The output of the tm_sched object instance */
2403 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2404
2405 if (direction.compare(upstream) == 0) {
2406 // In upstream it is NNI scheduler
2407 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2408 } else if (direction.compare(downstream) == 0) {
2409 // In downstream it is PON scheduler
2410 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2411 }
2412
2413 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2414
2415 // bcmbal_tm_sched_type
2416 // set the deafult policy to strict priority
2417 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2418
2419 // num_priorities: Max number of strict priority scheduling elements
2420 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2421
2422 // bcmbal_tm_shaping
2423 uint32_t cir = 1000000;
2424 uint32_t pir = 1000000;
2425 uint32_t burst = 65536;
2426 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2427 direction.c_str(), pir, burst);
2428 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2429 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2430 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2431 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2432 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2433 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2434
2435 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2436 if (err) {
2437 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err %d\n", \
2438 direction.c_str(), tm_sched_key.id, intf_id, err);
2439 return err;
2440 }
2441
2442 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2443 direction.c_str(), tm_sched_key.id, intf_id);
2444 return BCM_ERR_OK;
2445}
2446
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002447bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2448 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2449 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002450
2451 bcmos_errno err;
2452
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002453 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002454 bcmolt_tm_sched_cfg tm_sched_cfg;
2455 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2456 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002457
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002458 // bcmbal_tm_sched_owner
2459 // In downstream it is sub_term scheduler
2460 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002461
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002462 /**< The output of the tm_sched object instance */
2463 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002464
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002465 // bcmbal_tm_sched_parent
2466 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2467 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2468 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2469 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2470 be achieved using the' virtual' type of attachment.
2471 tm_sched_owner.u.sub_term.intf_id = intf_id;
2472 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2473 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002474
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002475 // bcmbal_tm_sched_type
2476 // set the deafult policy to strict priority
2477 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002478
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002479 // num_priorities: Max number of strict priority scheduling elements
2480 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002481
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002482 // bcmbal_tm_shaping
2483 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2484 uint32_t cir = tf_sh_info.cir();
2485 uint32_t pir = tf_sh_info.pir();
2486 uint32_t burst = tf_sh_info.pbs();
2487 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2488 cir, pir, burst);
2489 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2490 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2491 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2492 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2493 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2494 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002495 }
2496
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002497 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002498 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002499 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
2500intf_id %d, onu_id %d, uni_id %d, port_no %u\n", tm_sched_key.id, intf_id, onu_id, \
2501 uni_id, port_no);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002502 return err;
2503 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002504 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2505uni_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 -08002506
2507 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002508 bcmolt_itupon_alloc_cfg cfg;
2509 bcmolt_itupon_alloc_key key = { };
2510 key.pon_ni = intf_id;
2511 key.alloc_id = alloc_id;
2512 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2513 int pir_bw = tf_sh_info.pir();
2514 int cir_bw = tf_sh_info.cir();
2515 //offset to match bandwidth granularity
2516 int offset_pir_bw = pir_bw%bw_granularity;
2517 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002518
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002519 pir_bw = pir_bw - offset_pir_bw;
2520 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002521
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002522 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002523
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002524 switch (additional_bw) {
2525 case 2: //AdditionalBW_BestEffort
2526 if (pir_bw == 0) {
2527 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2528%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2529 } else if (pir_bw < cir_bw) {
2530 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2531bandwidth (%d)\n", pir_bw, cir_bw);
2532 return BCM_ERR_PARM;
2533 } else if (pir_bw == cir_bw) {
2534 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2535bandwidth for additional bandwidth eligibility of type best_effort\n");
2536 return BCM_ERR_PARM;
2537 }
2538 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2539 break;
2540 case 1: //AdditionalBW_NA
2541 if (pir_bw == 0) {
2542 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2543%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2544 return BCM_ERR_PARM;
2545 } else if (cir_bw == 0) {
2546 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2547additional bandwidth eligibility of type Non-Assured (NA)\n");
2548 return BCM_ERR_PARM;
2549 } else if (pir_bw < cir_bw) {
2550 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2551bandwidth (%d)\n", pir_bw, cir_bw);
2552 return BCM_ERR_PARM;
2553 } else if (pir_bw == cir_bw) {
2554 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2555bandwidth for additional bandwidth eligibility of type non_assured\n");
2556 return BCM_ERR_PARM;
2557 }
2558 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2559 break;
2560 case 0: //AdditionalBW_None
2561 if (pir_bw == 0) {
2562 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
256316000 bytes/sec\n");
2564 return BCM_ERR_PARM;
2565 } else if (cir_bw == 0) {
2566 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2567for additional bandwidth eligibility of type None\n");
2568 return BCM_ERR_PARM;
2569 } else if (pir_bw > cir_bw) {
2570 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2571for additional bandwidth eligibility of type None\n");
2572 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2573bandwidth in None eligibility\n", pir_bw);
2574 cir_bw = pir_bw;
2575 } else if (pir_bw < cir_bw) {
2576 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2577bandwidth (%d)\n", pir_bw, cir_bw);
2578 OPENOLT_LOG(ERROR, openolt_log_id, "set Maximum bandwidth (%d) to Guaranteed \
2579bandwidth in None eligibility\n", pir_bw);
2580 cir_bw = pir_bw;
2581 }
2582 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2583 break;
2584 default:
2585 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002586 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002587 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2588 in a fine granularity. */
2589 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2590 /* Fixed Bandwidth with no critical requirement of shaping */
2591 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2592 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2593 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2594 /* Maximum allocated bandwidth allowed for this alloc ID */
2595 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2596 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2597 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2598 for skipped allocations during quiet window */
2599 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2600 /**< Allocation Profile index for CBR non-RT Bandwidth */
2601 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2602 /**< Allocation Profile index for CBR RT Bandwidth */
2603 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2604 /**< Alloc ID Weight used in case of Extended DBA mode */
2605 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2606 /**< Alloc ID Priority used in case of Extended DBA mode */
2607 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2608 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002609
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002610 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002611 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002612 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2613port_no %u, alloc_id %d, err %d\n", intf_id, onu_id,uni_id,port_no,alloc_id, err);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002614 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002615 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002616 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d, port_no %u, \
2617alloc_id %d\n", intf_id,onu_id,uni_id,port_no,alloc_id);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002618 }
2619
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002620 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002621}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002622
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002623Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2624 uint32_t intf_id = traffic_scheds->intf_id();
2625 uint32_t onu_id = traffic_scheds->onu_id();
2626 uint32_t uni_id = traffic_scheds->uni_id();
2627 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002628 std::string direction;
2629 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002630 tech_profile::SchedulerConfig sched_config;
2631 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002632 uint32_t priority;
2633 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002634 tech_profile::SchedulingPolicy sched_policy;
2635 tech_profile::TrafficShapingInfo traffic_shaping_info;
2636 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002637
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002638 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2639 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002640
2641 direction = GetDirection(traffic_sched.direction());
2642 if (direction.compare("direction-not-supported") == 0)
2643 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2644
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002645 alloc_id = traffic_sched.alloc_id();
2646 sched_config = traffic_sched.scheduler();
2647 additional_bw = sched_config.additional_bw();
2648 priority = sched_config.priority();
2649 weight = sched_config.weight();
2650 sched_policy = sched_config.sched_policy();
2651 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2652 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2653 sched_policy, traffic_shaping_info);
2654 if (err) {
2655 return bcm_to_grpc_err(err, "Failed to create scheduler");
2656 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002657 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002658 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002659}
Jonathan Davis70c21812018-07-19 15:32:10 -04002660
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002661bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002662
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002663 bcmos_errno err;
Jonathan Davis70c21812018-07-19 15:32:10 -04002664
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002665 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002666 bcmolt_itupon_alloc_cfg cfg;
2667 bcmolt_itupon_alloc_key key = { };
2668 key.pon_ni = intf_id;
2669 key.alloc_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002670
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002671 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2672 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2673 if (err) {
2674 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler sched, direction = %s, intf_id %d, alloc_id %d, err %d\n", \
2675 direction.c_str(), intf_id, alloc_id, err);
2676 return err;
2677 }
2678 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, intf_id %d, alloc_id %d\n", \
2679 direction.c_str(), intf_id, alloc_id);
2680 } else if (direction == downstream) {
2681 bcmolt_tm_sched_cfg cfg;
2682 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002683
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002684 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2685 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2686 } else {
2687 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2688 return BCM_ERR_OK;
2689 }
2690 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2691 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2692 if (err) {
2693 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2694 direction.c_str(), key.id, intf_id, onu_id);
2695 return err;
2696 }
2697 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n", \
2698 direction.c_str(), key.id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002699 }
2700
2701 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002702 return BCM_ERR_OK;
2703}
2704
2705Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2706 uint32_t intf_id = traffic_scheds->intf_id();
2707 uint32_t onu_id = traffic_scheds->onu_id();
2708 uint32_t uni_id = traffic_scheds->uni_id();
2709 std::string direction;
2710 bcmos_errno err;
2711
2712 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2713 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002714
2715 direction = GetDirection(traffic_sched.direction());
2716 if (direction.compare("direction-not-supported") == 0)
2717 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2718
2719 int alloc_id = traffic_sched.alloc_id();
2720 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002721 if (err) {
2722 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
2723 }
2724 }
2725 return Status::OK;
2726}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002727
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002728bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
2729 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002730 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002731 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2732 bcmolt_tm_qmp_key tm_qmp_key;
2733 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002734
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002735 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
2736 if (tm_qmp_id == -1) {
2737 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed profile count is 16.\n");
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002738 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07002739
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002740 tm_qmp_key.id = tm_qmp_id;
2741 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
2742 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
2743 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002744
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002745 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2746 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
2747 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
2748 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
2749 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002750
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002751 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002752 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002753 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, id %d\n", \
2754 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002755 return err;
2756 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002757
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002758 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
2759 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002760 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002761}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002762
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002763bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
2764 bcmos_errno err;
2765 bcmolt_tm_qmp_cfg tm_qmp_cfg;
2766 bcmolt_tm_qmp_key tm_qmp_key;
2767 tm_qmp_key.id = tm_qmp_id;
2768
2769 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
2770 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
2771 if (err) {
2772 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, id %d\n", \
2773 tm_qmp_key.id);
2774 return err;
2775 }
2776
2777 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
2778 tm_qmp_key.id);
2779 return BCM_ERR_OK;
2780}
2781
2782bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
2783 bcmos_errno err;
2784
2785 /* Create 4 Queues on given PON/NNI scheduler */
2786 for (int queue_id = 0; queue_id < 4; queue_id++) {
2787 bcmolt_tm_queue_cfg tm_queue_cfg;
2788 bcmolt_tm_queue_key tm_queue_key = {};
2789 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
2790 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002791 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
2792 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
2793 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002794
2795 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
2796 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
2797 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
2798
2799 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
2800 if (err) {
2801 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d\n", \
2802 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2803 return err;
2804 }
2805
2806 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
2807 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
2808 }
2809 return BCM_ERR_OK;
2810}
2811
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002812bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2813 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002814 bcmos_errno err;
2815 bcmolt_tm_queue_cfg cfg;
2816 bcmolt_tm_queue_key key = { };
2817 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
2818gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
2819
2820 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2821 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2822
2823 if (priority > 7) {
2824 return BCM_ERR_RANGE;
2825 }
2826
2827 /* FIXME: The upstream queues have to be created once only.
2828 The upstream queues on the NNI scheduler are shared by all subscribers.
2829 When the first scheduler comes in, the queues get created, and are re-used by all others.
2830 Also, these queues should be present until the last subscriber exits the system.
2831 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
2832
2833 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
2834 for each GEM in TECH PROFILE */
2835 key.id = queue_id_list[priority];
2836
2837 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2838 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
2839 key.id = 0;
2840 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2841 }
2842 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2843 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2844 }
2845 else {
2846 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2847 }
2848
2849 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
2850
2851 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2852 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
2853
2854 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2855 if (err) {
2856 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, id %d, \
2857sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err %d\n", \
2858 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, err);
2859 return err;
2860 }
2861
2862 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2863intf_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);
2864 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002865}
2866
2867Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2868 uint32_t intf_id = traffic_queues->intf_id();
2869 uint32_t onu_id = traffic_queues->onu_id();
2870 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002871 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002872 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002873 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002874 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 +00002875
2876 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2877 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
2878 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
2879 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2880 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
2881
2882 direction = GetDirection(traffic_queue.direction());
2883 if (direction.compare("direction-not-supported") == 0)
2884 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2885
2886 queues_priority_q[i] = traffic_queue.priority();
2887 queues_pbit_map[i] = traffic_queue.pbit_map();
2888 }
2889
2890 std::vector<uint32_t> tmq_map_profile(8, 0);
2891 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
2892 queues_priority_q, COUNT_OF(queues_priority_q));
2893 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2894 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2895
2896 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
2897 if (tm_qmp_id == -1) {
2898 CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
2899 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
2900 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
2901 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
2902 }
2903 }
2904
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002905 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2906 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002907
2908 direction = GetDirection(traffic_queue.direction());
2909 if (direction.compare("direction-not-supported") == 0)
2910 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2911
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002912 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 +00002913
Girish Gowdruf26cf882019-05-01 23:47:58 -07002914 // If the queue exists already, lets not return failure and break the loop.
2915 if (err && err != BCM_ERR_ALREADY) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002916 return bcm_to_grpc_err(err, "Failed to create queue");
2917 }
2918 }
2919 return Status::OK;
2920}
2921
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002922bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
2923 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002924 bcmolt_tm_queue_cfg cfg;
2925 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002926 bcmos_errno err;
2927
2928 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002929 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
2930 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
2931 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002932 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002933 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 -08002934 return BCM_ERR_OK;
2935 }
2936 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002937 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
2938 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002939 return BCM_ERR_OK;
2940 }
2941
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002942 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2943 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
2944 // Reset the queue id to 0 when using fixed queue.
2945 key.id = 0;
2946 }
2947 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2948 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
2949 }
2950 else {
2951 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
2952 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002953
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002954 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
2955 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002956 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002957 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, id %d, sched_id %d, \
2958tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d\n",
2959 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 -08002960 return err;
2961 }
2962
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002963 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
2964intf_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 -08002965
2966 return BCM_ERR_OK;
2967}
2968
2969Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
2970 uint32_t intf_id = traffic_queues->intf_id();
2971 uint32_t onu_id = traffic_queues->onu_id();
2972 uint32_t uni_id = traffic_queues->uni_id();
2973 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002974 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002975 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002976 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002977 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 +00002978
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002979 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
2980 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002981
2982 direction = GetDirection(traffic_queue.direction());
2983 if (direction.compare("direction-not-supported") == 0)
2984 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2985
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002986 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 -08002987 if (err) {
2988 return bcm_to_grpc_err(err, "Failed to remove queue");
2989 }
Jonathan Davis70c21812018-07-19 15:32:10 -04002990 }
2991
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002992 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))) {
2993 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
2994 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
2995
2996 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
2997 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
2998 RemoveTrafficQueueMappingProfile(tm_qmp_id);
2999 }
3000 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003001 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003002 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003003}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003004
3005Status check_connection() {
3006 int maxTrials = 60;
3007 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3008 sleep(1);
3009 if (--maxTrials == 0)
3010 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3011 else
3012 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3013 }
3014 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3015 return Status::OK;
3016}
3017
3018Status check_bal_ready() {
3019 bcmos_errno err;
3020 int maxTrials = 30;
3021 bcmolt_olt_cfg olt_cfg = { };
3022 bcmolt_olt_key olt_key = { };
3023
3024 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3025 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3026
3027 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3028 if (--maxTrials == 0)
3029 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3030 sleep(5);
3031 #ifdef TEST_MODE
3032 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3033 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3034 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003035 // of olt_cfg is passed. This is one-of case where we need to add test specific
3036 // code in production code.
3037 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003038 #else
3039 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3040 #endif
3041 continue;
3042 }
3043 else
3044 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3045 }
3046
3047 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3048 return Status::OK;
3049}