blob: 7168fcd32a31f64f489da59caa64144d04120e67 [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
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040057dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
58dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
59
Craig Lutgen88a22ad2018-10-04 12:30:46 -050060#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000061#define MAX_TM_QMP_ID 16
62#define TMQ_MAP_PROFILE_SIZE 8
63#define MAX_TM_SCHED_ID 1023
64#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 -080065#define EAP_ETHER_TYPE 34958
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000066#define XGS_BANDWIDTH_GRANULARITY 16000
67#define GPON_BANDWIDTH_GRANULARITY 32000
Burak Gurdagc78b9e12019-11-29 11:14:51 +000068#define NUM_OF_PRIORITIES 8
69#define NUMBER_OF_DEFAULT_INTERFACE_QUEUES 4 // <= NUM_OF_PRIORITIES
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000070#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";
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000104const std::string multicast = "multicast";
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000105bcmolt_oltid dev_id = 0;
106
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000107/* Constants used for retrying some BAL APIs */
108const uint32_t BAL_API_RETRY_TIME_IN_USECS = 1000000;
109const uint32_t MAX_BAL_API_RETRY_COUNT = 5;
110
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000111/* Current session */
112static bcmcli_session *current_session;
113static bcmcli_entry *api_parent_dir;
114bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
115bcmos_task bal_cli_thread;
116const char *bal_cli_thread_name = "bal_cli_thread";
117uint16_t flow_id_counters = 0;
118int flow_id_data[16384][2];
Shad Ansariedef2132018-08-10 22:14:50 +0000119State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400120
Craig Lutgen967a1d02018-11-27 10:41:51 -0600121static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
122static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
123static 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 -0800124
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000125/* This represents the Key to 'sched_map' map.
126 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800127typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000128/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
129 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800130static std::map<sched_map_key_tuple, int> sched_map;
131
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500132/* This represents the Key to 'qos_type_map' map.
133 Represents (pon_intf_id, onu_id, uni_id) */
134typedef std::tuple<uint32_t, uint32_t, uint32_t> qos_type_map_key_tuple;
135/* 'qos_type_map' maps qos_type_map_key_tuple to qos_type*/
136static std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type> qos_type_map;
137
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000138/* This represents the Key to 'sched_qmp_id_map' map.
139Represents (sched_id, pon_intf_id, onu_id, uni_id) */
140typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
141/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
142static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
143/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
144static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800145
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500146// Flag used to watch whether mocked alloc_cfg_compltd_key is added to alloc_cfg_compltd_map
147#ifdef TEST_MODE
148bool ALLOC_CFG_FLAG = false;
149#endif
150
Girish Gowdra96461052019-11-22 20:13:59 +0530151#define ALLOC_CFG_COMPLETE_WAIT_TIMEOUT 1000 // in milli-seconds
152// Map used to track response from BAL for ITU PON Alloc Configuration.
153// The key is alloc_cfg_compltd_key and value is a concurrent thread-safe queue which is
154// used for pushing (from BAL) and popping (at application) the results.
155std::map<alloc_cfg_compltd_key, Queue<alloc_cfg_complete_result> *> alloc_cfg_compltd_map;
156// Lock to protect critical section data structure used for handling AllocObject configuration response.
157bcmos_fastlock alloc_cfg_wait_lock;
158
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800159std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000160std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800161
162static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600163
Girish Gowdra96461052019-11-22 20:13:59 +0530164
Craig Lutgen967a1d02018-11-27 10:41:51 -0600165#define MIN_ALLOC_ID_GPON 256
166#define MIN_ALLOC_ID_XGSPON 1024
167
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800168static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
169 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
170 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
171 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000172static 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 -0800173static 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 -0500174 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
175static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
176 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000177static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
178static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
179
180uint16_t get_dev_id(void) {
181 return dev_id;
182}
Shad Ansari627b5782018-08-13 22:49:32 +0000183
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400184// Stubbed defntions of bcmolt_cfg_get required for unit-test
185#ifdef TEST_MODE
186extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500187extern bcmos_errno bcmolt_cfg_get__onu_state_stub(bcmolt_oltid olt_id, void* ptr);
188extern bcmos_errno bcmolt_cfg_get__tm_sched_stub(bcmolt_oltid olt_id, void* ptr);
189extern bcmos_errno bcmolt_cfg_get__pon_intf_stub(bcmolt_oltid olt_id, void* ptr);
190extern bcmos_errno bcmolt_cfg_get__nni_intf_stub(bcmolt_oltid olt_id, void* ptr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400191extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500192extern bcmos_errno bcmolt_cfg_get__flow_stub(bcmolt_oltid olt_id, void* ptr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400193#endif
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800194/**
195* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
196* Every NNI port and PON port have default scheduler.
197* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
198* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
199*
200* @param intf_id NNI or PON interface ID
201* @param direction "upstream" or "downstream"
202*
203* @return default scheduler ID for the given interface.
204*/
205static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700206 if (direction.compare(upstream) == 0) {
207 return tm_upstream_sched_id_start + intf_id;
208 } else if (direction.compare(downstream) == 0) {
209 return tm_downstream_sched_id_start + intf_id;
210 }
211 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000212 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700213 return 0;
214 }
215}
216
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800217/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800218* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
219* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
220* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
221*
222* @param intf_id NNI or PON intf ID
223* @param onu_id ONU ID
224* @param uni_id UNI ID
225* @param gemport_id GEM Port ID
226* @param direction Upstream or downstream
227*
228* @return tm_sched_id
229*/
230uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
231 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
232 int sched_id = -1;
233
234 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
235 if (it != sched_map.end()) {
236 sched_id = it->second;
237 }
238 if (sched_id != -1) {
239 return sched_id;
240 }
241
242 bcmos_fastlock_lock(&data_lock);
243 // Complexity of O(n). Is there better way that can avoid linear search?
244 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
245 if (tm_sched_bitset[sched_id] == 0) {
246 tm_sched_bitset[sched_id] = 1;
247 break;
248 }
249 }
250 bcmos_fastlock_unlock(&data_lock, 0);
251
252 if (sched_id < MAX_TM_SCHED_ID) {
253 bcmos_fastlock_lock(&data_lock);
254 sched_map[key] = sched_id;
255 bcmos_fastlock_unlock(&data_lock, 0);
256 return sched_id;
257 } else {
258 return -1;
259 }
260}
261
262/**
263* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
264*
265* @param intf_id NNI or PON intf ID
266* @param onu_id ONU ID
267* @param uni_id UNI ID
268* @param gemport_id GEM Port ID
269* @param direction Upstream or downstream
270*/
271void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
272 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
273 std::map<sched_map_key_tuple, int>::const_iterator it;
274 bcmos_fastlock_lock(&data_lock);
275 it = sched_map.find(key);
276 if (it != sched_map.end()) {
277 tm_sched_bitset[it->second] = 0;
278 sched_map.erase(it);
279 }
280 bcmos_fastlock_unlock(&data_lock, 0);
281}
282
283bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
284 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000285 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
286 if (it != sched_map.end()) {
287 return true;
288 }
289 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800290}
291
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000292/**
293* Check whether given two tm qmp profiles are equal or not
294*
295* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
296* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
297*
298* @return boolean, true if given tmq_map_profiles are equal else false
299*/
300
301bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
302 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
303 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
304 return false;
305 }
306 }
307 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000308}
309
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000310/**
311* Modifies given queues_pbit_map to parsable format
312* e.g: Modifes "0b00000101" to "10100000"
313*
314* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
315* @param size Queue count
316*
317* @return string queues_pbit_map
318*/
319std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
320 for(uint32_t i=0; i < size; i++) {
321 /* Deletes 2 characters from index number 0 */
322 queues_pbit_map[i].erase(0, 2);
323 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
324 }
325 return queues_pbit_map;
326}
327
328/**
329* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
330*
331* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
332* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
333* @param size Queue count
334*
335* @return <vector> TM QUEUE MAPPING PROFILE
336*/
337std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
338 std::vector<uint32_t> tmq_map_profile(8,0);
339
340 for(uint32_t i=0; i < size; i++) {
341 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
342 if (queues_pbit_map[i][j]=='1') {
343 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
344 }
345 }
346 }
347 return tmq_map_profile;
348}
349
350/**
351* Gets corresponding tm_qmp_id for a given tmq_map_profile
352*
353* @param <vector> TM QUEUE MAPPING PROFILE
354*
355* @return tm_qmp_id
356*/
357int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
358 int tm_qmp_id = -1;
359
360 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
361 while(it != qmp_id_to_qmp_map.end()) {
362 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
363 tm_qmp_id = it->first;
364 break;
365 }
366 it++;
367 }
368 return tm_qmp_id;
369}
370
371/**
372* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
373*
374* @param upstream/downstream sched_id
375* @param PON intf ID
376* @param onu_id ONU ID
377* @param uni_id UNI ID
378* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
379*/
380void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
381 uint32_t uni_id, int tm_qmp_id) {
382 bcmos_fastlock_lock(&data_lock);
383 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
384 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
385 bcmos_fastlock_unlock(&data_lock, 0);
386}
387
388/**
389* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
390*
391* @param upstream/downstream sched_id
392* @param PON intf ID
393* @param onu_id ONU ID
394* @param uni_id UNI ID
395*
396* @return tm_qmp_id
397*/
398int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
399 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
400 int tm_qmp_id = -1;
401
402 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
403 if (it != sched_qmp_id_map.end()) {
404 tm_qmp_id = it->second;
405 }
406 return tm_qmp_id;
407}
408
409/**
410* Gets a unique tm_qmp_id for a given tmq_map_profile
411* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
412* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
413*
414* @param upstream/downstream sched_id
415* @param PON intf ID
416* @param onu_id ONU ID
417* @param uni_id UNI ID
418* @param <vector> TM QUEUE MAPPING PROFILE
419*
420* @return tm_qmp_id
421*/
422int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
423 std::vector<uint32_t> tmq_map_profile) {
424 int tm_qmp_id;
425
426 bcmos_fastlock_lock(&data_lock);
427 /* Complexity of O(n). Is there better way that can avoid linear search? */
428 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
429 if (tm_qmp_bitset[tm_qmp_id] == 0) {
430 tm_qmp_bitset[tm_qmp_id] = 1;
431 break;
432 }
433 }
434 bcmos_fastlock_unlock(&data_lock, 0);
435
436 if (tm_qmp_id < MAX_TM_QMP_ID) {
437 bcmos_fastlock_lock(&data_lock);
438 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
439 bcmos_fastlock_unlock(&data_lock, 0);
440 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
441 return tm_qmp_id;
442 } else {
443 return -1;
444 }
445}
446
447/**
448* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
449*
450* @param upstream/downstream sched_id
451* @param PON intf ID
452* @param onu_id ONU ID
453* @param uni_id UNI ID
454* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
455*
456* @return boolean, true if no more reference for TM QMP else false
457*/
458bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
459 uint32_t uni_id, int tm_qmp_id) {
460 bool result;
461 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
462 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
463 bcmos_fastlock_lock(&data_lock);
464 if (it != sched_qmp_id_map.end()) {
465 sched_qmp_id_map.erase(it);
466 }
467 bcmos_fastlock_unlock(&data_lock, 0);
468
469 uint32_t tm_qmp_ref_count = 0;
470 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
471 while(it2 != sched_qmp_id_map.end()) {
472 if(it2->second == tm_qmp_id) {
473 tm_qmp_ref_count++;
474 }
475 it2++;
476 }
477
478 if (tm_qmp_ref_count == 0) {
479 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
480 if (it3 != qmp_id_to_qmp_map.end()) {
481 bcmos_fastlock_lock(&data_lock);
482 tm_qmp_bitset[tm_qmp_id] = 0;
483 qmp_id_to_qmp_map.erase(it3);
484 bcmos_fastlock_unlock(&data_lock, 0);
485 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
486 tm_qmp_id, tm_qmp_ref_count);
487 result = true;
488 }
489 } else {
490 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
491 tm_qmp_id, tm_qmp_ref_count);
492 result = false;
493 }
494 return result;
495}
496
497/**
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500498* Returns qos type as string
499*
500* @param qos_type bcmolt_egress_qos_type enum
501*/
502std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type) {
503 switch (qos_type)
504 {
505 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE: return "FIXED_QUEUE";
506 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE: return "TC_TO_QUEUE";
507 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC: return "PBIT_TO_TC";
508 case BCMOLT_EGRESS_QOS_TYPE_NONE: return "NONE";
509 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE: return "PRIORITY_TO_QUEUE";
510 default: OPENOLT_LOG(ERROR, openolt_log_id, "qos-type-not-supported %d\n", qos_type);
511 return "qos-type-not-supported";
512 }
513}
514
515/**
516* Gets/Updates qos type for given pon_intf_id, onu_id, uni_id
517*
518* @param PON intf ID
519* @param onu_id ONU ID
520* @param uni_id UNI ID
521* @param queue_size TrafficQueues Size
522*
523* @return qos_type
524*/
525bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size = 0) {
526 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
527 bcmolt_egress_qos_type egress_qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
528 std::string qos_string;
529
530 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
531 if (it != qos_type_map.end()) {
532 egress_qos_type = it->second;
533 qos_string = get_qos_type_as_string(egress_qos_type);
534 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", \
535 pon_intf_id, onu_id, uni_id, qos_string.c_str());
536 }
537 else {
538 /* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
539 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
540 else Priority to Queue */
541 egress_qos_type = (queue_size > 1) ? \
542 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
543 bcmos_fastlock_lock(&data_lock);
544 qos_type_map.insert(make_pair(key, egress_qos_type));
545 bcmos_fastlock_unlock(&data_lock, 0);
546 qos_string = get_qos_type_as_string(egress_qos_type);
547 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", \
548 pon_intf_id, onu_id, uni_id, qos_string.c_str());
549 }
550 return egress_qos_type;
551}
552
553/**
554* Clears qos type for given pon_intf_id, onu_id, uni_id
555*
556* @param PON intf ID
557* @param onu_id ONU ID
558* @param uni_id UNI ID
559*/
560void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
561 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
562 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
563 bcmos_fastlock_lock(&data_lock);
564 if (it != qos_type_map.end()) {
565 qos_type_map.erase(it);
566 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", \
567 pon_intf_id, onu_id, uni_id);
568 }
569 bcmos_fastlock_unlock(&data_lock, 0);
570}
571
572/**
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000573* Returns Scheduler/Queue direction as string
574*
575* @param direction as specified in tech_profile.proto
576*/
577std::string GetDirection(int direction) {
578 switch (direction)
579 {
580 case tech_profile::Direction::UPSTREAM: return upstream;
581 case tech_profile::Direction::DOWNSTREAM: return downstream;
582 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
583 return "direction-not-supported";
584 }
585}
586
587inline const char *get_flow_acton_command(uint32_t command) {
588 char actions[200] = { };
589 char *s_actions_ptr = actions;
590 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
591 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
592 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
593 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
594 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
595 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
596 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
597 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
598 return s_actions_ptr;
599}
600
Girish Gowdra96461052019-11-22 20:13:59 +0530601// This method handles waiting for AllocObject configuration.
602// Returns error if the AllocObject is not in the appropriate state based on action requested.
603bcmos_errno wait_for_alloc_action(uint32_t intf_id, uint32_t alloc_id, AllocCfgAction action) {
604 Queue<alloc_cfg_complete_result> cfg_result;
605 alloc_cfg_compltd_key k(intf_id, alloc_id);
606 alloc_cfg_compltd_map[k] = &cfg_result;
607 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500608 #ifdef TEST_MODE
609 ALLOC_CFG_FLAG = true;
610 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530611
612 // Try to pop the result from BAL with a timeout of ALLOC_CFG_COMPLETE_WAIT_TIMEOUT ms
613 std::pair<alloc_cfg_complete_result, bool> result = cfg_result.pop(ALLOC_CFG_COMPLETE_WAIT_TIMEOUT);
614 if (result.second == false) {
615 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for alloc cfg complete indication intf_id %d, alloc_id %d\n",
616 intf_id, alloc_id);
617 // Invalidate the queue pointer.
618 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
619 alloc_cfg_compltd_map[k] = NULL;
620 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
621 err = BCM_ERR_INTERNAL;
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500622 #ifdef TEST_MODE
623 ALLOC_CFG_FLAG = false;
624 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530625 }
626 else if (result.first.status == ALLOC_CFG_STATUS_FAIL) {
627 OPENOLT_LOG(ERROR, openolt_log_id, "error processing alloc cfg request intf_id %d, alloc_id %d\n",
628 intf_id, alloc_id);
629 err = BCM_ERR_INTERNAL;
630 }
631
632 if (err == BCM_ERR_OK) {
633 if (action == ALLOC_OBJECT_CREATE) {
634 if (result.first.state != ALLOC_OBJECT_STATE_ACTIVE) {
635 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object not in active state intf_id %d, alloc_id %d alloc_obj_state %d\n",
636 intf_id, alloc_id, result.first.state);
637 err = BCM_ERR_INTERNAL;
638 } else {
639 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation success, intf_id %d, alloc_id %d\n",
640 intf_id, alloc_id);
641 }
642 } else { // ALLOC_OBJECT_DELETE
643 if (result.first.state != ALLOC_OBJECT_STATE_NOT_CONFIGURED) {
644 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object is not reset intf_id %d, alloc_id %d alloc_obj_state %d\n",
645 intf_id, alloc_id, result.first.state);
646 err = BCM_ERR_INTERNAL;
647 } else {
648 OPENOLT_LOG(INFO, openolt_log_id, "Remove alloc object success, intf_id %d, alloc_id %d\n",
649 intf_id, alloc_id);
650 }
651 }
652 }
653
654 // Remove entry from map
655 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
656 alloc_cfg_compltd_map.erase(k);
657 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500658 #ifdef TEST_MODE
659 ALLOC_CFG_FLAG = false;
660 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530661 return err;
662}
663
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000664char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800665{
666 FILE *fp;
667 /* Prepare the command*/
668 char command[150];
669
670 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
671 /* Open the command for reading. */
672 fp = popen(command, "r");
673 if (fp == NULL) {
674 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000675 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800676 return field_val;
677 }
678
679 /*Read the field value*/
680 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000681 uint8_t ret;
682 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
683 if (ret >= OPENOLT_FIELD_LEN)
684 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800685 pclose(fp);
686 }
687 return field_val;
688}
689
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400690Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500691 device_info->set_vendor(VENDOR_ID);
692 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400693 device_info->set_hardware_version("");
694 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500695 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500696 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500697
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800698 char serial_number[OPENOLT_FIELD_LEN];
699 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
700 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000701 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800702 device_info->set_device_serial_number(serial_number);
703
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700704 char device_id[OPENOLT_FIELD_LEN];
705 memset(device_id, '\0', OPENOLT_FIELD_LEN);
706 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000707 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700708 device_info->set_device_id(device_id);
709
Craig Lutgenb2601f02018-10-23 13:04:31 -0500710 // Legacy, device-wide ranges. To be deprecated when adapter
711 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000712 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500713 device_info->set_onu_id_start(1);
714 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600715 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500716 device_info->set_alloc_id_end(16383);
717 device_info->set_gemport_id_start(1024);
718 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500719 device_info->set_flow_id_start(1);
720 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500721 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000722 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500723 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500724 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600725 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500726 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500727 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500728 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500729 device_info->set_flow_id_start(1);
730 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500731 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500732
733 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
734 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
735 std::string intf_technology = intf_technologies[intf_id];
736 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
737 if(range == nullptr) {
738 range = device_info->add_ranges();
739 ranges[intf_technology] = range;
740 range->set_technology(intf_technology);
741
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000742 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500743 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
744
745 pool = range->add_pools();
746 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
747 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
748 pool->set_start(1);
749 pool->set_end(255);
750
751 pool = range->add_pools();
752 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
753 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
754 pool->set_start(1024);
755 pool->set_end(16383);
756
757 pool = range->add_pools();
758 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
759 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
760 pool->set_start(1024);
761 pool->set_end(65535);
762
763 pool = range->add_pools();
764 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
765 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
766 pool->set_start(1);
767 pool->set_end(16383);
768 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000769 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500770 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
771
772 pool = range->add_pools();
773 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
774 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
775 pool->set_start(1);
776 pool->set_end(127);
777
778 pool = range->add_pools();
779 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
780 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
781 pool->set_start(256);
782 pool->set_end(757);
783
784 pool = range->add_pools();
785 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
786 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
787 pool->set_start(256);
788 pool->set_end(4095);
789
790 pool = range->add_pools();
791 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
792 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
793 pool->set_start(1);
794 pool->set_end(16383);
795 }
796 }
797
798 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500799 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400800
801 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500802 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400803 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
804 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500805 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400806 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500807 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
808 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400809
810 return Status::OK;
811}
812
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000813Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
814{
815 openolt::Indication ind;
816 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
817
818 intf_oper_ind->set_type(type);
819 intf_oper_ind->set_intf_id(intf_id);
820 intf_oper_ind->set_oper_state(state);
821 ind.set_allocated_intf_oper_ind(intf_oper_ind);
822 oltIndQ.push(ind);
823 return Status::OK;
824}
825
826#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
827
828/* Build CLI prompt */
829static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
830{
831 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
832}
833
834static int _bal_apiend_cli_thread_handler(long data)
835{
836 char init_string[]="\n";
837 bcmcli_session *sess = current_session;
838 bcmos_task_parm bal_cli_task_p_dummy;
839
840 /* Switch to interactive mode if not stopped in the init script */
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000841 if (!bcmcli_is_stopped(sess)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000842 /* Force a CLI command prompt
843 * The string passed into the parse function
844 * must be modifiable, so a string constant like
845 * bcmcli_parse(current_session, "\n") will not
846 * work.
847 */
848 bcmcli_parse(sess, init_string);
849
850 /* Process user input until EOF or quit command */
851 bcmcli_driver(sess);
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000852 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000853 OPENOLT_LOG(INFO, openolt_log_id, "BAL API End CLI terminated\n");
854
855 /* Cleanup */
856 bcmcli_session_close(current_session);
857 bcmcli_token_destroy(NULL);
858 return 0;
859}
860
861/* Init API CLI commands for the current device */
862bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
863{
864 bcmos_errno rc;
865
866 api_parent_dir = parent_dir;
867
868 rc = bcm_api_cli_set_commands(session);
869
870#ifdef BCM_SUBSYSTEM_HOST
871 /* Subscribe for device change indication */
872 rc = rc ? rc : bcmolt_olt_sel_ind_register(_api_cli_olt_change_ind);
873#endif
874
875 return rc;
876}
877
878static bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
879{
880 bcmcli_stop(session);
881 bcmcli_session_print(session, "CLI terminated by 'Quit' command\n");
882 status_bcm_cli_quit = BCMOS_TRUE;
883
884 return BCM_ERR_OK;
885}
886
887int get_status_bcm_cli_quit(void) {
888 return status_bcm_cli_quit;
889}
890
891bcmos_errno bcmolt_apiend_cli_init() {
892 bcmos_errno ret;
893 bcmos_task_parm bal_cli_task_p = {};
894 bcmos_task_parm bal_cli_task_p_dummy;
895
896 /** before creating the task, check if it is already created by the other half of BAL i.e. Core side */
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000897 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000898 /* Create BAL CLI thread */
899 bal_cli_task_p.name = bal_cli_thread_name;
900 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
901 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
902
903 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000904 if (BCM_ERR_OK != ret) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000905 bcmos_printf("Couldn't create BAL API end CLI thread\n");
906 return ret;
907 }
908 }
909}
910
Shad Ansari627b5782018-08-13 22:49:32 +0000911Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000912 bcmos_errno err;
913 bcmolt_host_init_parms init_parms = {};
914 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
915 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000916
Shad Ansariedef2132018-08-10 22:14:50 +0000917 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000918
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500919 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000920 /* Initialize host subsystem */
921 err = bcmolt_host_init(&init_parms);
922 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500923 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000924 return bcm_to_grpc_err(err, "Failed to init OLT");
925 }
926
927 bcmcli_session_parm mon_session_parm;
928 /* Create CLI session */
929 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
930 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
931 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
932 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
933 BUG_ON(rc != BCM_ERR_OK);
934
935 /* API CLI */
936 bcm_openolt_api_cli_init(NULL, current_session);
937
938 /* Add quit command */
939 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
940
941 err = bcmolt_apiend_cli_init();
942 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500943 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000944 return bcm_to_grpc_err(err, "Failed to add apiend init");
945 }
946
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800947 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530948 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000949 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600950
Jason Huangbf45ffb2019-10-30 17:29:02 +0800951 //check BCM daemon is connected or not
952 Status status = check_connection();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000953 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800954 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000955 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800956 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000957 Status status = SubscribeIndication();
958 if (!status.ok()) {
959 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
960 grpc_status_code_to_string(status.error_code()).c_str(),
961 status.error_message().c_str());
962 return status;
963 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800964
965 //check BAL state in initial stage
966 status = check_bal_ready();
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000967 if (!status.ok()) {
Jason Huangbf45ffb2019-10-30 17:29:02 +0800968 return status;
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000969 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800970 }
971
972 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000973 bcmos_errno err;
974 bcmolt_odid dev;
975 OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
976 for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400977 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000978 bcmolt_device_key dev_key = { };
979 dev_key.device_id = dev;
980 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
981 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
982 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
Jason Huangbf45ffb2019-10-30 17:29:02 +0800983 if (err == BCM_ERR_NOT_CONNECTED) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000984 bcmolt_device_key key = {.device_id = dev};
985 bcmolt_device_connect oper;
986 BCMOLT_OPER_INIT(&oper, device, connect, key);
987 if (MODEL_ID == "asfvolt16") {
988 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
989 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
990 } else if (MODEL_ID == "asgvolt64") {
991 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
992 BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
993 BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
994 }
995 err = bcmolt_oper_submit(dev_id, &oper.hdr);
996 if (err) {
997 failed_enable_device_cnt ++;
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500998 OPENOLT_LOG(ERROR, openolt_log_id, "Enable PON device %d failed, err = %s\n", dev, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000999 if (failed_enable_device_cnt == BCM_MAX_DEVS_PER_LINE_CARD) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001000 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable all the pon ports, err = %s\n", bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001001 return Status(grpc::StatusCode::INTERNAL, "Failed to activate all PON ports");
1002 }
1003 }
1004 bcmos_usleep(200000);
1005 }
1006 else {
1007 OPENOLT_LOG(WARNING, openolt_log_id, "PON deivce %d already connected\n", dev);
1008 state.activate();
1009 }
1010 }
1011 init_stats();
Shad Ansari627b5782018-08-13 22:49:32 +00001012 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001013 }
Shad Ansariedef2132018-08-10 22:14:50 +00001014
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001015 /* Start CLI */
1016 OPENOLT_LOG(INFO, def_log_id, "Starting CLI\n");
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001017 //If already enabled, generate an extra indication ????
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001018 return Status::OK;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001019}
1020
1021Status Disable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001022 //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
1023 //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
1024 //Disabling NNI port on olt disable causes connection loss between adapter and agent.
1025 //To overcome this disable is implemented by disabling all the PON ports
1026 //associated with the device so as to support both in-band
1027 //and out of band scenarios.
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001028
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001029 Status status;
1030 int failedCount = 0;
1031 for (int i = 0; i < NumPonIf_(); i++) {
1032 status = DisablePonIf_(i);
1033 if (!status.ok()) {
1034 failedCount+=1;
1035 BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
1036 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001037 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001038 if (failedCount == 0) {
1039 state.deactivate();
1040 openolt::Indication ind;
1041 openolt::OltIndication* olt_ind = new openolt::OltIndication;
1042 olt_ind->set_oper_state("down");
1043 ind.set_allocated_olt_ind(olt_ind);
1044 BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
1045 oltIndQ.push(ind);
1046 return Status::OK;
1047 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001048 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001049 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
1050 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001051
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001052 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 -04001053}
1054
1055Status Reenable_() {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001056 Status status;
1057 int failedCount = 0;
1058 for (int i = 0; i < NumPonIf_(); i++) {
1059 status = EnablePonIf_(i);
1060 if (!status.ok()) {
1061 failedCount+=1;
1062 BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
1063 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001064 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001065 if (failedCount == 0) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001066 state.activate();
1067 openolt::Indication ind;
1068 openolt::OltIndication* olt_ind = new openolt::OltIndication;
1069 olt_ind->set_oper_state("up");
1070 ind.set_allocated_olt_ind(olt_ind);
1071 BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
1072 oltIndQ.push(ind);
1073 return Status::OK;
1074 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001075 if (failedCount ==NumPonIf_()) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001076 return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
1077 }
1078 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 +00001079}
1080
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001081bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
1082 bcmos_errno err;
1083 bcmolt_pon_interface_key pon_key;
1084 bcmolt_pon_interface_cfg pon_cfg;
1085 pon_key.pon_ni = pon_ni;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001086
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001087 BCMOLT_CFG_INIT(&pon_cfg, pon_interface, pon_key);
1088 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, state);
1089 BCMOLT_FIELD_SET_PRESENT(&pon_cfg.data, pon_interface_cfg_data, itu);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001090 #ifdef TEST_MODE
1091 // It is impossible to mock the setting of pon_cfg.data.state because
1092 // the actual bcmolt_cfg_get passes the address of pon_cfg.hdr and we cannot
1093 // set the pon_cfg.data.state. So a new stub function is created and address
1094 // of pon_cfg is passed. This is one-of case where we need to add test specific
1095 // code in production code.
1096 err = bcmolt_cfg_get__pon_intf_stub(dev_id, &pon_cfg);
1097 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001098 err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001099 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001100 *state = pon_cfg.data.state;
1101 return err;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001102}
1103
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001104inline uint64_t get_flow_status(uint16_t flow_id, uint16_t flow_type, uint16_t data_id) {
1105 bcmos_errno err;
1106 bcmolt_flow_key flow_key;
1107 bcmolt_flow_cfg flow_cfg;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001108
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001109 flow_key.flow_id = flow_id;
1110 flow_key.flow_type = (bcmolt_flow_type)flow_type;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001111
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001112 BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001113
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001114 switch (data_id) {
1115 case ONU_ID: //onu_id
1116 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, onu_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001117 #ifdef TEST_MODE
1118 // It is impossible to mock the setting of flow_cfg.data.state because
1119 // the actual bcmolt_cfg_get passes the address of flow_cfg.hdr and we cannot
1120 // set the flow_cfg.data. So a new stub function is created and address
1121 // of flow_cfg is passed. This is one-of case where we need to add test specific
1122 // code in production code.
1123 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1124 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001125 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001126 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001127 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001128 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get onu_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001129 return err;
1130 }
1131 return flow_cfg.data.onu_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001132 case FLOW_TYPE:
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001133 #ifdef TEST_MODE
1134 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1135 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001136 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001137 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001138 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001139 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get flow_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001140 return err;
1141 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001142 return flow_cfg.key.flow_type;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001143 case SVC_PORT_ID: //svc_port_id
1144 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001145 #ifdef TEST_MODE
1146 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1147 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001148 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001149 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001150 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001151 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get svc_port_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001152 return err;
1153 }
1154 return flow_cfg.data.svc_port_id;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001155 case PRIORITY:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001156 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001157 #ifdef TEST_MODE
1158 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1159 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001160 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001161 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001162 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001163 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get priority, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001164 return err;
1165 }
1166 return flow_cfg.data.priority;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001167 case COOKIE: //cookie
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001168 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001169 #ifdef TEST_MODE
1170 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1171 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001172 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001173 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001174 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001175 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get cookie, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001176 return err;
1177 }
1178 return flow_cfg.data.cookie;
1179 case INGRESS_INTF_TYPE: //ingress intf_type
1180 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001181 #ifdef TEST_MODE
1182 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1183 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001184 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001185 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001186 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001187 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001188 return err;
1189 }
1190 return flow_cfg.data.ingress_intf.intf_type;
1191 case EGRESS_INTF_TYPE: //egress intf_type
1192 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001193 #ifdef TEST_MODE
1194 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1195 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001196 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001197 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001198 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001199 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001200 return err;
1201 }
1202 return flow_cfg.data.egress_intf.intf_type;
1203 case INGRESS_INTF_ID: //ingress intf_id
1204 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001205 #ifdef TEST_MODE
1206 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1207 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001208 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001209 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001210 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001211 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get ingress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001212 return err;
1213 }
1214 return flow_cfg.data.ingress_intf.intf_id;
1215 case EGRESS_INTF_ID: //egress intf_id
1216 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_intf);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001217 #ifdef TEST_MODE
1218 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1219 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001220 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001221 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001222 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001223 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress intf_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001224 return err;
1225 }
1226 return flow_cfg.data.egress_intf.intf_id;
1227 case CLASSIFIER_O_VID:
1228 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001229 #ifdef TEST_MODE
1230 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1231 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001232 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001233 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001234 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001235 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001236 return err;
1237 }
1238 return flow_cfg.data.classifier.o_vid;
1239 case CLASSIFIER_O_PBITS:
1240 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001241 #ifdef TEST_MODE
1242 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1243 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001244 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001245 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001246 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001247 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001248 return err;
1249 }
1250 return flow_cfg.data.classifier.o_pbits;
1251 case CLASSIFIER_I_VID:
1252 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001253 #ifdef TEST_MODE
1254 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1255 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001256 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001257 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001258 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001259 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001260 return err;
1261 }
1262 return flow_cfg.data.classifier.i_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001263 case CLASSIFIER_I_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001264 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001265 #ifdef TEST_MODE
1266 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1267 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001268 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001269 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001270 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001271 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001272 return err;
1273 }
1274 return flow_cfg.data.classifier.i_pbits;
1275 case CLASSIFIER_ETHER_TYPE:
1276 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001277 #ifdef TEST_MODE
1278 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1279 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001280 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001281 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001282 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001283 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ether_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001284 return err;
1285 }
1286 return flow_cfg.data.classifier.ether_type;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001287 case CLASSIFIER_IP_PROTO:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001288 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001289 #ifdef TEST_MODE
1290 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1291 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001292 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001293 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001294 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001295 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier ip_proto, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001296 return err;
1297 }
1298 return flow_cfg.data.classifier.ip_proto;
1299 case CLASSIFIER_SRC_PORT:
1300 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001301 #ifdef TEST_MODE
1302 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1303 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001304 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001305 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001306 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001307 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier src_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001308 return err;
1309 }
1310 return flow_cfg.data.classifier.src_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001311 case CLASSIFIER_DST_PORT:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001312 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001313 #ifdef TEST_MODE
1314 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1315 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001316 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001317 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001318 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001319 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier dst_port, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001320 return err;
1321 }
1322 return flow_cfg.data.classifier.dst_port;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001323 case CLASSIFIER_PKT_TAG_TYPE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001324 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001325 #ifdef TEST_MODE
1326 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1327 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001328 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001329 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001330 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001331 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get classifier pkt_tag_type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001332 return err;
1333 }
1334 return flow_cfg.data.classifier.pkt_tag_type;
1335 case EGRESS_QOS_TYPE:
1336 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001337 #ifdef TEST_MODE
1338 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1339 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001340 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001341 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001342 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001343 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos type, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001344 return err;
1345 }
1346 return flow_cfg.data.egress_qos.type;
1347 case EGRESS_QOS_QUEUE_ID:
1348 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001349 #ifdef TEST_MODE
1350 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1351 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001352 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001353 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001354 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001355 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos queue_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001356 return err;
1357 }
1358 switch (flow_cfg.data.egress_qos.type) {
1359 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE:
1360 return flow_cfg.data.egress_qos.u.fixed_queue.queue_id;
1361 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE:
1362 return flow_cfg.data.egress_qos.u.tc_to_queue.tc_to_queue_id;
1363 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC:
1364 return flow_cfg.data.egress_qos.u.pbit_to_tc.tc_to_queue_id;
1365 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE:
1366 return flow_cfg.data.egress_qos.u.priority_to_queue.tm_q_set_id;
1367 case BCMOLT_EGRESS_QOS_TYPE_NONE:
1368 default:
1369 return -1;
1370 }
1371 case EGRESS_QOS_TM_SCHED_ID:
1372 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, egress_qos);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001373 #ifdef TEST_MODE
1374 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1375 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001376 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001377 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001378 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001379 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get egress_qos tm_sched_id, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001380 return err;
1381 }
1382 return flow_cfg.data.egress_qos.tm_sched.id;
1383 case ACTION_CMDS_BITMASK:
1384 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001385 #ifdef TEST_MODE
1386 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1387 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001388 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001389 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001390 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001391 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action cmds_bitmask, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001392 return err;
1393 }
1394 return flow_cfg.data.action.cmds_bitmask;
1395 case ACTION_O_VID:
1396 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001397 #ifdef TEST_MODE
1398 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1399 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001400 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001401 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001402 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001403 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001404 return err;
1405 }
1406 return flow_cfg.data.action.o_vid;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001407 case ACTION_O_PBITS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001408 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001409 #ifdef TEST_MODE
1410 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1411 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001412 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001413 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001414 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001415 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action o_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001416 return err;
1417 }
1418 return flow_cfg.data.action.o_pbits;
1419 case ACTION_I_VID:
1420 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001421 #ifdef TEST_MODE
1422 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1423 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001424 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001425 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001426 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001427 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_vid, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001428 return err;
1429 }
1430 return flow_cfg.data.action.i_vid;
1431 case ACTION_I_PBITS:
1432 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001433 #ifdef TEST_MODE
1434 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1435 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001436 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001437 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001438 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001439 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get action i_pbits, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001440 return err;
1441 }
1442 return flow_cfg.data.action.i_pbits;
1443 case STATE:
1444 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, state);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001445 #ifdef TEST_MODE
1446 err = bcmolt_cfg_get__flow_stub(dev_id, &flow_cfg);
1447 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001448 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05001449 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001450 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001451 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get state, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001452 return err;
1453 }
1454 return flow_cfg.data.state;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001455 case GROUP_ID:
1456 BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, group_id);
1457 err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
1458 if (err) {
1459 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to get group_id, err = %s\n",bcmos_strerror(err));
1460 return err;
1461 }
1462 return flow_cfg.data.group_id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001463 default:
1464 return BCM_ERR_INTERNAL;
1465 }
1466
1467 return err;
1468}
1469
1470Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001471 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001472 bcmolt_pon_interface_cfg interface_obj;
1473 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1474 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1475 bcmolt_interface_state state;
1476
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001477 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001478 if (err == BCM_ERR_OK) {
1479 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001480 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001481 return Status::OK;
1482 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001483 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001484 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1485 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1486 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1487 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1488 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1489 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1490 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1491 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1492 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1493 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1494 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1495 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1496 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1497 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1498
1499 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1500 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001501 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable discovery onu, PON interface %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001502 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1503 }
1504 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1505 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001506 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d, err = %s\n", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001507 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1508 }
1509 else {
1510 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1511 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1512 CreateDefaultSched(intf_id, downstream);
1513 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001514 }
1515
1516 return Status::OK;
1517}
1518
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001519/* Same as bcmolt_cfg_get but with added logic of retrying the API
1520 in case of some specific failures like timeout or object not yet ready
1521*/
1522bcmos_errno bcmolt_cfg_get_mult_retry(bcmolt_oltid olt, bcmolt_cfg *cfg) {
1523 bcmos_errno err;
1524 uint32_t current_try = 0;
1525
1526 while (current_try < MAX_BAL_API_RETRY_COUNT) {
1527 err = bcmolt_cfg_get(olt, cfg);
1528 current_try++;
1529
1530 if (err == BCM_ERR_STATE || err == BCM_ERR_TIMEOUT) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001531 OPENOLT_LOG(WARNING, openolt_log_id, "bcmolt_cfg_get: err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001532 bcmos_usleep(BAL_API_RETRY_TIME_IN_USECS);
1533 continue;
1534 }
1535 else {
1536 break;
1537 }
1538 }
1539
1540 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001541 OPENOLT_LOG(ERROR, openolt_log_id, "bcmolt_cfg_get tried (%d) times with retry time(%d usecs) err = %s\n",
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001542 current_try,
1543 BAL_API_RETRY_TIME_IN_USECS,
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001544 bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001545 }
1546 return err;
1547}
1548
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001549Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001550 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001551 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001552 bcmolt_device_key dev_key = { };
1553 bcmolt_olt_cfg olt_cfg = { };
1554 bcmolt_olt_key olt_key = { };
1555 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1556 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001557
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001558 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1559 topo.topology_maps.arr = &topo_map[0];
1560 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1561 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1562 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001563 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001564 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001565 #ifdef TEST_MODE
1566 // It is impossible to mock the setting of olt_cfg.data.bal_state because
1567 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
1568 // set the olt_cfg.data.topology. So a new stub function is created and address
1569 // of olt_cfg is passed. This is one-of case where we need to test add specific
1570 // code in production code.
1571 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1572 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001573 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001574 #endif
1575 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001576 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT topology, err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001577 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001578 }
1579
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001580 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1581 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001582
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001583 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1584 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001585 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001586
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001587 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1588 num_of_nni_ports,
1589 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001590 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001591
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001592 uint32_t num_failed_cfg_gets = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001593 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1594 dev_key.device_id = devid;
1595 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1596 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1597 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1598 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001599 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001600 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001601 OPENOLT_LOG(WARNING, openolt_log_id,"Failed to query PON MAC Device %d (errno = %s). Skipping the device.\n", devid, bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001602 num_failed_cfg_gets++;
1603 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001604 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001605
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001606 std::string bal_version;
1607 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1608 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1609 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1610 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1611
1612 switch(dev_cfg.data.system_mode) {
1613 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1614 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1615 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1616 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1617 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1618 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1619 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1620 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1621 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1622 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1623 }
1624
1625 switch(dev_cfg.data.chip_family) {
1626 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1627 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1628 }
1629
1630 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1631 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1632
1633 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001634 }
1635
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001636 /* If all the devices returned errors then we tell the caller that this is an error else we work with
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001637 only the devices that retured success*/
1638 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1639 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1640 return bcm_to_grpc_err(err, "device: All devices failed query");
1641 }
1642
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001643 return Status::OK;
1644}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001645#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001646Status ProbePonIfTechnology_() {
1647 // Probe maximum extent possible as configured into BAL driver to determine
1648 // which are active in the current BAL topology. And for those
1649 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1650 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001651 bcmolt_pon_interface_cfg interface_obj;
1652 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001653
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001654 interface_key.pon_ni = intf_id;
1655 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001656 if (board_technology == "XGS-PON"
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001657 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1658 else if (board_technology == "GPON")
1659 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001660
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001661 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001662 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001663 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001664 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 -05001665 }
1666 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001667 if (board_technology == "XGS-PON") {
1668 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1669 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001670 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1671 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001672 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001673 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1674 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1675 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001676 intf_technologies[intf_id] = "XGS-PON";
1677 break;
1678 }
1679 } else if (board_technology == "GPON") {
1680 switch(interface_obj.data.gpon_trx.transceiver_type) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001681 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001682 case BCMOLT_TRX_TYPE_LTE_3680_M:
1683 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1684 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001685 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001686 intf_technologies[intf_id] = "GPON";
1687 break;
1688 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001689 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001690
1691 if (board_technology != UNKNOWN_TECH) {
1692 board_technology = intf_technologies[intf_id];
1693 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1694 intf_technologies[intf_id] = MIXED_TECH;
1695 }
1696
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001697 }
1698 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001699 return Status::OK;
1700}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001701#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001702unsigned NumNniIf_() {return num_of_nni_ports;}
1703unsigned NumPonIf_() {return num_of_pon_ports;}
1704
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001705bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1706 bcmos_errno err;
1707 bcmolt_nni_interface_key nni_key;
1708 bcmolt_nni_interface_cfg nni_cfg;
1709 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001710
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001711 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1712 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001713 #ifdef TEST_MODE
1714 // It is impossible to mock the setting of nni_cfg.data.state because
1715 // the actual bcmolt_cfg_get passes the address of nni_cfg.hdr and we cannot
1716 // set the nni_cfg.data.state. So a new stub function is created and address
1717 // of nni_cfg is passed. This is one-of case where we need to add test specific
1718 // code in production code.
1719 err = bcmolt_cfg_get__nni_intf_stub(dev_id, &nni_cfg);
1720 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001721 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001722 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001723 *state = nni_cfg.data.state;
1724 return err;
1725}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001726
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001727Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00001728 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001729 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1730 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1731 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001732
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001733 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001734 if (err == BCM_ERR_OK) {
1735 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001736 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001737 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1738 CreateDefaultSched(intf_id, upstream);
1739 CreateDefaultQueue(intf_id, upstream);
1740 return Status::OK;
1741 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1742 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1743 return Status::OK;
1744 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001745 }
1746
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001747 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1748 if (set_state) {
1749 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1750 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1751 } else {
1752 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1753 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1754 }
1755 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1756 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001757 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1758 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001759 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1760 }
1761 else {
1762 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1763 if (set_state) {
1764 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1765 CreateDefaultSched(intf_id, upstream);
1766 CreateDefaultQueue(intf_id, upstream);
1767 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001768 }
1769
1770 return Status::OK;
1771}
1772
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001773Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001774 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001775 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001776 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1777 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001778
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001779 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1780 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1781 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1782
1783 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1784 if (err != BCM_ERR_OK) {
1785 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1786 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1787 }
1788
1789 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1790 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1791
1792 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1793 if (err != BCM_ERR_OK) {
1794 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n , err %d\n", intf_id, err);
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04001795 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001796 }
1797
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001798 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001799 return Status::OK;
1800}
1801
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001802Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001803 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001804 bcmos_errno err = BCM_ERR_OK;
1805 bcmolt_onu_cfg onu_cfg;
1806 bcmolt_onu_key onu_key;
1807 bcmolt_serial_number serial_number; /**< ONU serial number */
1808 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001809
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001810 onu_key.onu_id = onu_id;
1811 onu_key.pon_ni = intf_id;
1812 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1813 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001814 #ifdef TEST_MODE
1815 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1816 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1817 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1818 // of onu_cfg is passed. This is one-of case where we need to add test specific
1819 // code in production code.
1820 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
1821 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001822 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001823 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001824 if (err == BCM_ERR_OK) {
1825 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001826 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1827 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1828 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1829 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001830 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001831
1832 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001833vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001834 vendor_specific_to_str(vendor_specific).c_str(), pir);
1835
1836 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1837 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1838 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1839 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1840 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1841 /*set burst and data profiles to fec disabled*/
1842 if (board_technology == "XGS-PON") {
1843 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1844 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1845 } else if (board_technology == "GPON") {
1846 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1847 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1848 }
1849 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1850 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001851 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to set activate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001852 return bcm_to_grpc_err(err, "Failed to activate ONU");
1853 }
1854
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001855 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001856}
1857
Jonathan Davis70c21812018-07-19 15:32:10 -04001858Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1859 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001860 bcmos_errno err = BCM_ERR_OK;
1861 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1862 bcmolt_onu_cfg onu_cfg;
1863 bcmolt_onu_key onu_key; /**< Object key. */
1864 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001865
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001866 onu_key.onu_id = onu_id;
1867 onu_key.pon_ni = intf_id;
1868 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1869 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001870 #ifdef TEST_MODE
1871 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1872 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1873 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1874 // of onu_cfg is passed. This is one-of case where we need to add test specific
1875 // code in production code.
1876 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
1877 onu_state = onu_cfg.data.onu_state;
1878 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001879 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001880 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001881 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001882 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001883 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001884 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001885 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001886 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1887 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1888 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001889 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to deactivate ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001890 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1891 }
1892 break;
1893 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001894 }
1895
1896 return Status::OK;
1897}
1898
1899Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001900 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001901
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001902 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 -05001903 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1904
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001905 // Need to deactivate before removing it (BAL rules)
1906
1907 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1908 // Sleep to allow the state to propagate
1909 // We need the subscriber terminal object to be admin down before removal
1910 // Without sleep the race condition is lost by ~ 20 ms
1911 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1912
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001913 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001914
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001915 bcmolt_onu_cfg cfg_obj;
1916 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001917
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001918 //OPENOLT_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
1919 // onu_id, intf_id);
1920 OPENOLT_LOG(INFO, openolt_log_id, "Processing onu cfg clear for onu_id %d and intf_id %d\n",
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001921 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001922
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001923 key.onu_id = onu_id;
1924 key.pon_ni = intf_id;
1925 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001926
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001927 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001928 if (err != BCM_ERR_OK)
1929 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001930 //OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL subscriber_terminal_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
1931 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to clear information for BAL onu_id %d, Interface ID %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Jonathan Davis70c21812018-07-19 15:32:10 -04001932 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1933 }
1934
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001935 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001936}
1937
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001938#define MAX_CHAR_LENGTH 20
1939#define MAX_OMCI_MSG_LENGTH 44
1940Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001941 bcmolt_bin_str buf = {};
1942 bcmolt_onu_cpu_packets omci_cpu_packets;
1943 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001944
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001945 key.pon_ni = intf_id;
1946 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001947
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001948 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1949 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1950 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001951
1952 // ???
1953 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1954 buf.len = MAX_OMCI_MSG_LENGTH;
1955 } else {
1956 buf.len = pkt.size()/2;
1957 }
1958
1959 /* Send the OMCI packet using the BAL remote proxy API */
1960 uint16_t idx1 = 0;
1961 uint16_t idx2 = 0;
1962 uint8_t arraySend[buf.len];
1963 char str1[MAX_CHAR_LENGTH];
1964 char str2[MAX_CHAR_LENGTH];
1965 memset(&arraySend, 0, buf.len);
1966
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001967 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1968 sprintf(str1,"%c", pkt[idx1]);
1969 sprintf(str2,"%c", pkt[++idx1]);
1970 strcat(str1,str2);
1971 arraySend[idx2] = strtol(str1, NULL, 16);
1972 }
1973
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001974 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1975 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001976
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001977 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1978 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1979 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001980
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001981 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001982 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001983 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending OMCI message to ONU %d on PON %d, err = %s\n", onu_id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001984 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001985 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001986 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 -05001987 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001988 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001989 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001990
1991 return Status::OK;
1992}
1993
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001994Status 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 +00001995 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1996 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1997 bcmolt_bin_str buf = {};
1998 bcmolt_gem_port_id gem_port_id_array[1];
1999 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002000
Craig Lutgen967a1d02018-11-27 10:41:51 -06002001 if (port_no > 0) {
2002 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002003 if (gemport_id == 0) {
2004 bcmos_fastlock_lock(&data_lock);
2005 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
2006 // Pick any flow that is mapped with the same port_no.
2007 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
2008 if (it != port_to_flows.end() && !it->second.empty()) {
2009 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
2010 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
2011 if (fit != flowid_to_gemport.end()) {
2012 found = true;
2013 gemport_id = fit->second;
2014 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002015 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002016 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002017
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002018 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002019 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 -08002020 onu_id, port_no, intf_id);
2021 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
2022 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002023 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 -08002024 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002025 }
2026
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002027 gem_port_id_array[0] = gemport_id;
2028 gem_port_list.len = 1;
2029 gem_port_list.arr = gem_port_id_array;
2030 buf.len = pkt.size();
2031 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
2032 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
2033
2034 /* init the API struct */
2035 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
2036 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
2037 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
2038 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
2039 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
2040
2041 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
2042 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
2043
2044 /* call API */
2045 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002046 }
2047 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002048 //TODO: Port No is 0, it is coming sender requirement.
2049 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
2050 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002051 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002052 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002053
2054 return Status::OK;
2055}
2056
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002057Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002058 bcmolt_flow_key key = {}; /* declare key */
2059 bcmolt_bin_str buffer = {};
2060 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002061
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002062 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
2063 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002064
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002065 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
2066 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
2067 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
2068 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
2069 key.flow_id = flow_id;
2070 else {
2071 if (flow_id_counters != 0) {
2072 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2073 int flow_index = flow_id_data[flowid][0];
2074 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
2075 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
2076 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
2077 key.flow_id = flow_index;
2078 break;
2079 }
2080 }
2081 }
2082 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05002083 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002084 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
2085 }
2086 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002087
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002088 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002089
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002090 /* Initialize the API struct. */
2091 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002092
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002093 buffer.len = pkt.size();
2094 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
2095 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
2096 if (buffer.arr == NULL) {
2097 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
2098 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
2099 }
2100 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
2101
2102 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
2103 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002104 OPENOLT_LOG(ERROR, openolt_log_id, "Error sending packets via nni port %d, flow_id %d, err = %s\n", intf_id, key.flow_id, bcmos_strerror(err));
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05002105 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002106 } else {
2107 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
2108 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002109
2110 return Status::OK;
2111}
2112
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002113uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002114 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002115 uint32_t port_no = 0;
2116 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
2117 if (it != flowid_to_port.end()) {
2118 port_no = it->second;
2119 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002120 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002121 return port_no;
2122}
2123
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002124#define FLOW_LOG(level,msg,err) \
2125 do { \
2126 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
2127 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
2128 access_intf_id, onu_id, uni_id, port_no, cookie); \
2129 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
2130 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
2131 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
2132 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
2133 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
2134 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
2135 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
2136 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", \
2137 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
2138 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
2139 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 -04002140 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002141
2142#define FLOW_PARAM_LOG() \
2143 do { \
2144 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
2145 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
2146 key.flow_id, flow_index); \
2147 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
2148 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
2149 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
2150 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
2151 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
2152 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
2153 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
2154 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
2155 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
2156 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
2157 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
2158 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
2159 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
2160 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
2161 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
2162 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
2163 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
2164 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
2165 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
2166 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
2167 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
2168 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
2169 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
2170 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
2171 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
2172 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
2173 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
2174 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
2175 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
2176 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
2177 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
2178 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
2179 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
2180 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
2181 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
2182 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
2183 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
2184 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
2185 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
2186 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
2187 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
2188 cfg.data.egress_qos.u.fixed_queue.queue_id, \
2189 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
2190 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
2191 cfg.data.egress_qos.tm_sched.id, \
2192 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
2193 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
2194 get_flow_acton_command(a_val.cmds_bitmask), \
2195 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
2196 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
2197 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
2198 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
2199 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
2200 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
2201 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002202 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n", \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002203 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002204 OPENOLT_LOG(INFO, openolt_log_id, "group_id (%d %lu)\n\n", \
2205 cfg.data.group_id, get_flow_status(flow_index, flow_id_data[flowid][1], GROUP_ID)); \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002206 } while(0)
2207
2208#define FLOW_CHECKER
2209//#define SHOW_FLOW_PARAM
2210
Craig Lutgen967a1d02018-11-27 10:41:51 -06002211Status 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 +00002212 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002213 int32_t alloc_id, int32_t network_intf_id,
2214 int32_t gemport_id, const ::openolt::Classifier& classifier,
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002215 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie,
2216 int32_t group_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002217 bcmolt_flow_cfg cfg;
2218 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002219 int32_t o_vid = -1;
2220 bool single_tag = false;
2221 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002222 bcmolt_classifier c_val = { };
2223 bcmolt_action a_val = { };
2224 bcmolt_tm_queue_ref tm_val = { };
2225 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002226 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002227
2228 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002229 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002230 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002231 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002232 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002233 } else if (flow_type.compare(multicast) == 0) {
2234 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002235 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002236 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04002237 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002238 }
2239
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002240 BCMOLT_CFG_INIT(&cfg, flow, key);
2241 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002242
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002243
2244 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2245
2246 if (access_intf_id >= 0 && network_intf_id >= 0) {
2247 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
2248 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2249 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
2250 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
2251 classifier.ip_proto() == 2 || // IGMP packet
2252 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
2253 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
2254 } else {
2255 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2256 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
2257 }
2258 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
2259 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2260 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2261 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2262 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002263 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002264 } else if (access_intf_id < 0 ) {
2265 // This is the case for packet trap from NNI flow.
2266 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2267 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2268 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
2269 } else {
2270 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2271 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002272 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002273
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002274 if (onu_id >= 0) {
2275 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
2276 }
2277 if (gemport_id >= 0) {
2278 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
2279 }
2280 if (gemport_id >= 0 && port_no != 0) {
2281 bcmos_fastlock_lock(&data_lock);
2282 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2283 port_to_flows[port_no].insert(key.flow_id);
2284 flowid_to_gemport[key.flow_id] = gemport_id;
2285 }
2286 else
2287 {
2288 flowid_to_port[key.flow_id] = port_no;
2289 }
2290 bcmos_fastlock_unlock(&data_lock, 0);
2291 }
2292 if (priority_value >= 0) {
2293 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
2294 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302295
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002296 } else { // MULTICAST FLOW
2297 if (group_id >= 0) {
2298 BCMOLT_MSG_FIELD_SET(&cfg, group_id, group_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002299 }
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002300 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2301 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002302 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002303
2304 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002305 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002306 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002307 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002308 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002309 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002310 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002311 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002312 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002313 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002314 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002315 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002316 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002317
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002318 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002319 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002320 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2321 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002322 }
2323
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002324 if (classifier.dst_mac().size() > 0) {
2325 bcmos_mac_address d_mac = {};
2326 bcmos_mac_address_init(&d_mac);
2327 memcpy(d_mac.u8, classifier.dst_mac().data(), sizeof(d_mac.u8));
2328 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_mac %02x:%02x:%02x:%02x:%02x:%02x\n", d_mac.u8[0],
2329 d_mac.u8[1], d_mac.u8[2], d_mac.u8[3], d_mac.u8[4], d_mac.u8[5]);
2330 BCMOLT_FIELD_SET(&c_val, classifier, dst_mac, d_mac);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002331 }
2332
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002333 /*
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002334 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002335 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002336 }
2337 */
2338
2339 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002340 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2341 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002342 }
2343
2344 /*
2345 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002346 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002347 }
2348
2349 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002350 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002351 }
2352 */
2353
2354 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002355 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2356 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002357 }
2358
2359 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002360 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2361 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002362 }
2363
2364 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302365 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2366 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2367 // This is case where packet traps from NNI port. As per Broadcom workaround
2368 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2369 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2370 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2371 } else {
2372 if (classifier.o_vid()) {
2373 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2374 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2375 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002376
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302377 if (classifier.i_vid()) {
2378 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2379 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2380 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002381
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302382 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2383 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2384 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2385 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2386 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2387 single_tag = true;
2388
2389 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002390 if(classifier.o_pbits()){
2391 //According to makeOpenOltClassifierField in voltha-openolt-adapter, o_pbits 0xFF means PCP value 0.
2392 //0 vlaue of o_pbits means o_pbits is not available
2393 if(0xFF == classifier.o_pbits()){
2394 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2395 }
2396 else{
2397 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2398 }
2399 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302400 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2401 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2402
2403 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002404 if(classifier.o_pbits()){
2405 if(0xFF == classifier.o_pbits()){
2406 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2407 }
2408 else{
2409 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2410 }
2411 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302412 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002413 }
2414 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002415 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002416 }
2417
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002418 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002419 const ::openolt::ActionCmd& cmd = action.cmd();
2420
2421 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002422 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2423 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002424 }
2425
2426 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002427 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2428 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002429 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002430 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002431 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002432 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002433 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002434 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002435 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002436 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002438 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002439 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002440 }
2441
2442 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002443 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2444 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002445 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002446 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002447 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002448 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002449 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002450 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002451 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002452 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002453 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2454 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002455 }
2456
2457 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002458 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2459 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002460 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002461 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002462 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002463 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002464 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002465 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002466 */
2467 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002468 }
2469
Shad Ansari39739bc2018-09-13 21:38:37 +00002470 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002471 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2472 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2473 get_default_tm_sched_id(network_intf_id, upstream) : \
2474 get_default_tm_sched_id(access_intf_id, downstream);
2475 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002476
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002477 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2478 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2479 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002480
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002481 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2482 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2483 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2484 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002485 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002486 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2487 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2488
2489 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2490 // Queue 0 on DS subscriber scheduler
2491 tm_val.queue_id = 0;
2492
2493 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2494 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2495 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2496
2497 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2498 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2499 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2500
2501 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2502 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2503 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2504
2505 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2506 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2507 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2508 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2509
2510 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2511 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2512 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2513 }
2514 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2515 // NNI Scheduler ID
2516 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2517 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2518 // Queue 0 on NNI scheduler
2519 tm_val.queue_id = 0;
2520 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2521 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2522 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2523
2524 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2525 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2526 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2527
2528 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2529 /* Fetch TM QMP ID mapped to US NNI scheduler */
2530 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2531 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2532 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2533 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2534 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2535
2536 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2537 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2538 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2539 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002540 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002541 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302542 } else {
2543 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2544 tm_val.queue_id = 0;
2545
2546 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2547 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2548 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2549
2550 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2551 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2552 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002553 }
2554
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002555 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002556
2557 // BAL 3.1 supports statistics only for unicast flows.
2558 if (key.flow_type != BCMOLT_FLOW_TYPE_MULTICAST) {
2559 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2560 }
2561
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002562#ifdef FLOW_CHECKER
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002563 //Flow Checker, To avoid duplicate flow.
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002564 if (flow_id_counters != 0) {
2565 bool b_duplicate_flow = false;
2566 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2567 int flow_index = flow_id_data[flowid][0];
2568 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2569 (key.flow_type == flow_id_data[flowid][1]) && \
2570 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2571 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2572 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2573 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2574 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2575 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2576 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2577 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2578 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2579 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2580 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2581 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2582 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2583 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2584 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2585 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2586 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2587 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2588 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2589 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2590 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2591 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2592 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2593 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002594 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE)) && \
2595 (cfg.data.group_id == get_flow_status(flowid, flow_id_data[flowid][1], GROUP_ID));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002596#ifdef SHOW_FLOW_PARAM
2597 // Flow Parameter
2598 FLOW_PARAM_LOG();
2599#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002600
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002601 if (b_duplicate_flow) {
2602 FLOW_LOG(WARNING, "Flow duplicate", 0);
2603 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2604 }
2605 }
2606 }
2607#endif
2608
2609 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2610 if (err) {
2611 FLOW_LOG(ERROR, "Flow add failed", err);
2612 return bcm_to_grpc_err(err, "flow add failed");
2613 } else {
2614 FLOW_LOG(INFO, "Flow add ok", err);
2615 bcmos_fastlock_lock(&data_lock);
2616 flow_id_data[flow_id_counters][0] = key.flow_id;
2617 flow_id_data[flow_id_counters][1] = key.flow_type;
2618 flow_id_counters += 1;
2619 bcmos_fastlock_unlock(&data_lock, 0);
2620 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002621
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002622 return Status::OK;
2623}
2624
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002625Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2626
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002627 bcmolt_flow_cfg cfg;
2628 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002629
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002630 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002631 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002632 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002633 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002634 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002635 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002636 } else if(flow_type.compare(multicast) == 0) {
2637 key.flow_type = BCMOLT_FLOW_TYPE_MULTICAST;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002638 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002639 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002640 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2641 }
2642
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002643 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002644 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002645 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002646 flowid_to_gemport.erase(key.flow_id);
2647 port_to_flows[port_no].erase(key.flow_id);
2648 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2649 }
2650 else
2651 {
2652 flowid_to_port.erase(key.flow_id);
2653 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002654 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002655
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002656 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002657
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002658 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002659 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002660 OPENOLT_LOG(ERROR, openolt_log_id, "Error while removing %s flow, flow_id=%d, err = %s\n", flow_type.c_str(), flow_id, bcmos_strerror(err));
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002661 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2662 }
2663
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002664 bcmos_fastlock_lock(&data_lock);
2665 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2666 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2667 flow_id_counters -= 1;
2668 for (int i=flowid; i < flow_id_counters; i++) {
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002669 flow_id_data[i][0] = flow_id_data[i + 1][0];
2670 flow_id_data[i][1] = flow_id_data[i + 1][1];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002671 }
2672 break;
2673 }
2674 }
2675 bcmos_fastlock_unlock(&data_lock, 0);
2676
2677 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002678 return Status::OK;
2679}
2680
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002681bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2682 bcmos_errno err;
2683 bcmolt_tm_sched_cfg tm_sched_cfg;
2684 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2685 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2686
Jason Huangbf45ffb2019-10-30 17:29:02 +08002687 //check TM scheduler has configured or not
2688 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2689 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002690 #ifdef TEST_MODE
2691 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2692 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2693 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2694 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2695 // code in production code.
2696 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2697 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002698 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002699 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002700 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002701 OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query TM scheduler, err = %s\n",bcmos_strerror(err));
Jason Huangbf45ffb2019-10-30 17:29:02 +08002702 return err;
2703 }
2704 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2705 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2706 return BCM_ERR_OK;
2707 }
2708
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002709 // bcmbal_tm_sched_owner
2710 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2711
2712 /**< The output of the tm_sched object instance */
2713 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2714
2715 if (direction.compare(upstream) == 0) {
2716 // In upstream it is NNI scheduler
2717 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2718 } else if (direction.compare(downstream) == 0) {
2719 // In downstream it is PON scheduler
2720 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2721 }
2722
2723 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2724
2725 // bcmbal_tm_sched_type
2726 // set the deafult policy to strict priority
2727 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2728
2729 // num_priorities: Max number of strict priority scheduling elements
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002730 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, NUM_OF_PRIORITIES);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002731
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002732 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2733 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002734 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2735 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002736 return err;
2737 }
2738
2739 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2740 direction.c_str(), tm_sched_key.id, intf_id);
2741 return BCM_ERR_OK;
2742}
2743
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002744bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2745 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2746 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002747
2748 bcmos_errno err;
2749
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002750 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002751 bcmolt_tm_sched_cfg tm_sched_cfg;
2752 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2753 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002754
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002755 // bcmbal_tm_sched_owner
2756 // In downstream it is sub_term scheduler
2757 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002758
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002759 /**< The output of the tm_sched object instance */
2760 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002761
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002762 // bcmbal_tm_sched_parent
2763 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2764 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2765 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002766 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002767 be achieved using the' virtual' type of attachment.
2768 tm_sched_owner.u.sub_term.intf_id = intf_id;
2769 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2770 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002771
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002772 // bcmbal_tm_sched_type
2773 // set the deafult policy to strict priority
2774 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002775
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002776 // num_priorities: Max number of strict priority scheduling elements
2777 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002778
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002779 // bcmbal_tm_shaping
2780 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2781 uint32_t cir = tf_sh_info.cir();
2782 uint32_t pir = tf_sh_info.pir();
2783 uint32_t burst = tf_sh_info.pbs();
2784 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2785 cir, pir, burst);
2786 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2787 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2788 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2789 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2790 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2791 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002792 }
2793
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002794 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002795 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002796 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002797intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2798port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002799 return err;
2800 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002801 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2802uni_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 -08002803
2804 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002805 bcmolt_itupon_alloc_cfg cfg;
2806 bcmolt_itupon_alloc_key key = { };
2807 key.pon_ni = intf_id;
2808 key.alloc_id = alloc_id;
2809 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2810 int pir_bw = tf_sh_info.pir();
2811 int cir_bw = tf_sh_info.cir();
2812 //offset to match bandwidth granularity
2813 int offset_pir_bw = pir_bw%bw_granularity;
2814 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002815
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002816 pir_bw = pir_bw - offset_pir_bw;
2817 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002818
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002819 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002820
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002821 switch (additional_bw) {
2822 case 2: //AdditionalBW_BestEffort
2823 if (pir_bw == 0) {
2824 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2825%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002826 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002827 } else if (pir_bw < cir_bw) {
2828 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2829bandwidth (%d)\n", pir_bw, cir_bw);
2830 return BCM_ERR_PARM;
2831 } else if (pir_bw == cir_bw) {
2832 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2833bandwidth for additional bandwidth eligibility of type best_effort\n");
2834 return BCM_ERR_PARM;
2835 }
2836 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2837 break;
2838 case 1: //AdditionalBW_NA
2839 if (pir_bw == 0) {
2840 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2841%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2842 return BCM_ERR_PARM;
2843 } else if (cir_bw == 0) {
2844 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2845additional bandwidth eligibility of type Non-Assured (NA)\n");
2846 return BCM_ERR_PARM;
2847 } else if (pir_bw < cir_bw) {
2848 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2849bandwidth (%d)\n", pir_bw, cir_bw);
2850 return BCM_ERR_PARM;
2851 } else if (pir_bw == cir_bw) {
2852 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2853bandwidth for additional bandwidth eligibility of type non_assured\n");
2854 return BCM_ERR_PARM;
2855 }
2856 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2857 break;
2858 case 0: //AdditionalBW_None
2859 if (pir_bw == 0) {
2860 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
286116000 bytes/sec\n");
2862 return BCM_ERR_PARM;
2863 } else if (cir_bw == 0) {
2864 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2865for additional bandwidth eligibility of type None\n");
2866 return BCM_ERR_PARM;
2867 } else if (pir_bw > cir_bw) {
2868 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2869for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002870 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002871bandwidth in None eligibility\n", pir_bw);
2872 cir_bw = pir_bw;
2873 } else if (pir_bw < cir_bw) {
2874 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2875bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002876 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002877bandwidth in None eligibility\n", pir_bw);
2878 cir_bw = pir_bw;
2879 }
2880 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2881 break;
2882 default:
2883 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002884 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002885 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2886 in a fine granularity. */
2887 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2888 /* Fixed Bandwidth with no critical requirement of shaping */
2889 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2890 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2891 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2892 /* Maximum allocated bandwidth allowed for this alloc ID */
2893 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2894 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002895 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002896 for skipped allocations during quiet window */
2897 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2898 /**< Allocation Profile index for CBR non-RT Bandwidth */
2899 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2900 /**< Allocation Profile index for CBR RT Bandwidth */
2901 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2902 /**< Alloc ID Weight used in case of Extended DBA mode */
2903 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2904 /**< Alloc ID Priority used in case of Extended DBA mode */
2905 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2906 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002907
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002908 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002909 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002910 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002911port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002912 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002913 }
Girish Gowdra96461052019-11-22 20:13:59 +05302914
2915 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2916 if (err) {
2917 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2918port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2919 return err;
2920 }
2921
2922 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2923port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2924
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002925 }
2926
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002927 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002928}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002929
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002930Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2931 uint32_t intf_id = traffic_scheds->intf_id();
2932 uint32_t onu_id = traffic_scheds->onu_id();
2933 uint32_t uni_id = traffic_scheds->uni_id();
2934 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002935 std::string direction;
2936 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002937 tech_profile::SchedulerConfig sched_config;
2938 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002939 uint32_t priority;
2940 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002941 tech_profile::SchedulingPolicy sched_policy;
2942 tech_profile::TrafficShapingInfo traffic_shaping_info;
2943 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002944
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002945 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2946 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002947
2948 direction = GetDirection(traffic_sched.direction());
2949 if (direction.compare("direction-not-supported") == 0)
2950 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2951
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002952 alloc_id = traffic_sched.alloc_id();
2953 sched_config = traffic_sched.scheduler();
2954 additional_bw = sched_config.additional_bw();
2955 priority = sched_config.priority();
2956 weight = sched_config.weight();
2957 sched_policy = sched_config.sched_policy();
2958 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2959 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2960 sched_policy, traffic_shaping_info);
2961 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002962 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002963 return bcm_to_grpc_err(err, "Failed to create scheduler");
2964 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002965 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002966 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002967}
Jonathan Davis70c21812018-07-19 15:32:10 -04002968
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002969bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002970
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002971 bcmos_errno err;
Girish Gowdra96461052019-11-22 20:13:59 +05302972 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002973
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002974 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002975 bcmolt_itupon_alloc_cfg cfg;
2976 bcmolt_itupon_alloc_key key = { };
2977 key.pon_ni = intf_id;
2978 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302979 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002980
Burak Gurdagc78b9e12019-11-29 11:14:51 +00002981 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002982 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2983 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002984 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2985 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002986 return err;
2987 }
Girish Gowdra96461052019-11-22 20:13:59 +05302988
2989 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2990 if (err) {
2991 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2992 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2993 return err;
2994 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002995 } else if (direction == downstream) {
2996 bcmolt_tm_sched_cfg cfg;
2997 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002998
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002999 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
3000 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05303001 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003002 } else {
3003 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
3004 return BCM_ERR_OK;
3005 }
Girish Gowdra96461052019-11-22 20:13:59 +05303006
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003007 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
3008 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
3009 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003010 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
3011intf_id %d, onu_id %d, err = %s\n", direction.c_str(), key.id, intf_id, onu_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003012 return err;
3013 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003014 }
3015
Girish Gowdra96461052019-11-22 20:13:59 +05303016 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
3017 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003018 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003019 return BCM_ERR_OK;
3020}
3021
3022Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
3023 uint32_t intf_id = traffic_scheds->intf_id();
3024 uint32_t onu_id = traffic_scheds->onu_id();
3025 uint32_t uni_id = traffic_scheds->uni_id();
3026 std::string direction;
3027 bcmos_errno err;
3028
3029 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
3030 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003031
3032 direction = GetDirection(traffic_sched.direction());
3033 if (direction.compare("direction-not-supported") == 0)
3034 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3035
3036 int alloc_id = traffic_sched.alloc_id();
3037 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003038 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003039 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003040 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
3041 }
3042 }
3043 return Status::OK;
3044}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003045
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003046bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
3047 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003048 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003049 bcmolt_tm_qmp_cfg tm_qmp_cfg;
3050 bcmolt_tm_qmp_key tm_qmp_key;
3051 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003052
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003053 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
3054 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003055 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
3056 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003057 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07003058
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003059 tm_qmp_key.id = tm_qmp_id;
3060 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
3061 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
3062 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003063
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003064 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
3065 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
3066 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
3067 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
3068 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003069
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003070 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003071 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003072 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
3073 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003074 return err;
3075 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06003076
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003077 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
3078 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003079 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003080}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003081
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003082bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
3083 bcmos_errno err;
3084 bcmolt_tm_qmp_cfg tm_qmp_cfg;
3085 bcmolt_tm_qmp_key tm_qmp_key;
3086 tm_qmp_key.id = tm_qmp_id;
3087
3088 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
3089 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
3090 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003091 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
3092 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003093 return err;
3094 }
3095
3096 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
3097 tm_qmp_key.id);
3098 return BCM_ERR_OK;
3099}
3100
3101bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
3102 bcmos_errno err;
3103
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003104 /* Create default queues on the given PON/NNI scheduler */
3105 for (int queue_id = 0; queue_id < NUMBER_OF_DEFAULT_INTERFACE_QUEUES; queue_id++) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003106 bcmolt_tm_queue_cfg tm_queue_cfg;
3107 bcmolt_tm_queue_key tm_queue_key = {};
3108 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
3109 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003110 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
3111 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
3112 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003113
3114 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
3115 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
3116 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
3117
3118 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
3119 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003120 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s tm queue, id %d, sched_id %d, tm_q_set_id %d, err = %s\n", \
3121 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003122 return err;
3123 }
3124
3125 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
3126 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
3127 }
3128 return BCM_ERR_OK;
3129}
3130
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003131bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
3132 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003133 bcmos_errno err;
3134 bcmolt_tm_queue_cfg cfg;
3135 bcmolt_tm_queue_key key = { };
3136 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
3137gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
3138
3139 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3140 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
3141
3142 if (priority > 7) {
3143 return BCM_ERR_RANGE;
3144 }
3145
3146 /* FIXME: The upstream queues have to be created once only.
3147 The upstream queues on the NNI scheduler are shared by all subscribers.
3148 When the first scheduler comes in, the queues get created, and are re-used by all others.
3149 Also, these queues should be present until the last subscriber exits the system.
3150 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
3151
3152 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
3153 for each GEM in TECH PROFILE */
3154 key.id = queue_id_list[priority];
3155
3156 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3157 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
3158 key.id = 0;
3159 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3160 }
3161 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3162 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3163 }
3164 else {
3165 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3166 }
3167
3168 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
3169
3170 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3171 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
3172
3173 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
3174 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003175 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
3176sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
3177 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003178 return err;
3179 }
3180
3181 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3182intf_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);
3183 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003184}
3185
3186Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
3187 uint32_t intf_id = traffic_queues->intf_id();
3188 uint32_t onu_id = traffic_queues->onu_id();
3189 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003190 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003191 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003192 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003193 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 +00003194
3195 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3196 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
3197 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
3198 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3199 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
3200
3201 direction = GetDirection(traffic_queue.direction());
3202 if (direction.compare("direction-not-supported") == 0)
3203 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3204
3205 queues_priority_q[i] = traffic_queue.priority();
3206 queues_pbit_map[i] = traffic_queue.pbit_map();
3207 }
3208
3209 std::vector<uint32_t> tmq_map_profile(8, 0);
3210 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
3211 queues_priority_q, COUNT_OF(queues_priority_q));
3212 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3213 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3214
3215 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
3216 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003217 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
3218 if (err != BCM_ERR_OK) {
3219 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3220 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
3221 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003222 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
3223 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
3224 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
3225 }
3226 }
3227
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003228 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3229 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003230
3231 direction = GetDirection(traffic_queue.direction());
3232 if (direction.compare("direction-not-supported") == 0)
3233 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3234
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003235 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 +00003236
Girish Gowdruf26cf882019-05-01 23:47:58 -07003237 // If the queue exists already, lets not return failure and break the loop.
3238 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003239 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003240 return bcm_to_grpc_err(err, "Failed to create queue");
3241 }
3242 }
3243 return Status::OK;
3244}
3245
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003246bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
3247 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003248 bcmolt_tm_queue_cfg cfg;
3249 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003250 bcmos_errno err;
3251
3252 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003253 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
3254 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
3255 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003256 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003257 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 -08003258 return BCM_ERR_OK;
3259 }
3260 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003261 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3262 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003263 return BCM_ERR_OK;
3264 }
3265
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003266 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3267 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3268 // Reset the queue id to 0 when using fixed queue.
3269 key.id = 0;
3270 }
3271 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3272 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3273 }
3274 else {
3275 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3276 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003277
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003278 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3279 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003280 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003281 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
3282tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
3283 direction.c_str(), key.id, key.sched_id, key.tm_q_set_id, access_intf_id, onu_id, uni_id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003284 return err;
3285 }
3286
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003287 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3288intf_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 -08003289
3290 return BCM_ERR_OK;
3291}
3292
3293Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
3294 uint32_t intf_id = traffic_queues->intf_id();
3295 uint32_t onu_id = traffic_queues->onu_id();
3296 uint32_t uni_id = traffic_queues->uni_id();
3297 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003298 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003299 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003300 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003301 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 +00003302
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003303 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3304 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003305
3306 direction = GetDirection(traffic_queue.direction());
3307 if (direction.compare("direction-not-supported") == 0)
3308 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3309
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003310 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 -08003311 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003312 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003313 return bcm_to_grpc_err(err, "Failed to remove queue");
3314 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003315 }
3316
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003317 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))) {
3318 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3319 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3320
3321 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3322 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003323 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3324 if (err != BCM_ERR_OK) {
3325 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3326 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3327 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003328 }
3329 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003330 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003331 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003332}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003333
3334Status check_connection() {
3335 int maxTrials = 60;
3336 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3337 sleep(1);
3338 if (--maxTrials == 0)
3339 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3340 else
3341 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3342 }
3343 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3344 return Status::OK;
3345}
3346
3347Status check_bal_ready() {
3348 bcmos_errno err;
3349 int maxTrials = 30;
3350 bcmolt_olt_cfg olt_cfg = { };
3351 bcmolt_olt_key olt_key = { };
3352
3353 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3354 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3355
3356 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3357 if (--maxTrials == 0)
3358 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3359 sleep(5);
3360 #ifdef TEST_MODE
3361 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3362 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3363 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003364 // of olt_cfg is passed. This is one-of case where we need to add test specific
3365 // code in production code.
3366 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003367 #else
3368 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3369 #endif
3370 continue;
3371 }
3372 else
3373 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3374 }
3375
3376 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3377 return Status::OK;
3378}
Burak Gurdagc78b9e12019-11-29 11:14:51 +00003379
3380Status PerformGroupOperation_(const openolt::Group *group_cfg) {
3381
3382 bcmos_errno err;
3383 bcmolt_group_key key = {};
3384 bcmolt_group_cfg grp_cfg_obj;
3385 bcmolt_group_members_update grp_mem_upd;
3386 bcmolt_members_update_command grp_mem_upd_cmd;
3387 bcmolt_group_member_info member_info = {};
3388 bcmolt_group_member_info_list_u8 members = {};
3389 bcmolt_intf_ref interface_ref = {};
3390 bcmolt_egress_qos egress_qos = {};
3391 bcmolt_tm_sched_ref tm_sched_ref = {};
3392 bcmolt_action a_val = {};
3393
3394 uint32_t group_id = group_cfg->group_id();
3395
3396 OPENOLT_LOG(INFO, openolt_log_id, "PerformGroupOperation request received for Group %d\n", group_id);
3397
3398 if (group_id >= 0) {
3399 key.id = group_id;
3400 }
3401 else {
3402 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid group id %d.\n", group_id);
3403 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group id");
3404 }
3405
3406 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3407 BCMOLT_FIELD_SET_PRESENT(&grp_cfg_obj.data, group_cfg_data, state);
3408
3409 OPENOLT_LOG(INFO, openolt_log_id, "Checking if Group %d exists...\n",group_id);
3410
3411 err = bcmolt_cfg_get(dev_id, &(grp_cfg_obj.hdr));
3412 if (err != BCM_ERR_OK) {
3413 OPENOLT_LOG(ERROR, openolt_log_id, "Error in querying Group %d, err = %s\n", group_id, bcmos_strerror(err));
3414 return bcm_to_grpc_err(err, "Error in querying group");
3415 }
3416
3417 members.len = group_cfg->members_size();
3418
3419 // IMPORTANT: A member cannot be added to a group if the group type is not determined.
3420 // Group type is determined after a flow is assigned to it.
3421 // Therefore, a group must be created first, then a flow (with multicast type) must be assigned to it.
3422 // Only then we can add members to the group.
3423
3424 // if group does not exist, create it and return.
3425 if (grp_cfg_obj.data.state == BCMOLT_GROUP_STATE_NOT_CONFIGURED) {
3426
3427 if (members.len != 0) {
3428 OPENOLT_LOG(ERROR, openolt_log_id, "Member list is not empty for non-existent Group %d. Members can be added only after a flow is assigned to this newly-created group.\n", group_id);
3429 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Non-empty member list given for non-existent group");
3430 } else {
3431
3432 BCMOLT_CFG_INIT(&grp_cfg_obj, group, key);
3433 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, cookie, key.id);
3434
3435 /* Setting group actions and action parameters, if any.
3436 Only remove_outer_tag and translate_inner_tag actions and i_vid action parameter
3437 are supported for multicast groups in BAL 3.1.
3438 */
3439 const ::openolt::Action& action = group_cfg->action();
3440 const ::openolt::ActionCmd &cmd = action.cmd();
3441
3442 bcmolt_action_cmd_id cmd_bmask = BCMOLT_ACTION_CMD_ID_NONE;
3443 if (cmd.remove_outer_tag()) {
3444 OPENOLT_LOG(INFO, openolt_log_id, "Action remove_outer_tag applied to Group %d.\n", group_id);
3445 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
3446 }
3447
3448 if (cmd.translate_inner_tag()) {
3449 OPENOLT_LOG(INFO, openolt_log_id, "Action translate_inner_tag applied to Group %d.\n", group_id);
3450 cmd_bmask = (bcmolt_action_cmd_id) (cmd_bmask | BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG);
3451 }
3452
3453 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, cmd_bmask);
3454
3455 if (action.i_vid()) {
3456 OPENOLT_LOG(INFO, openolt_log_id, "Setting action parameter i_vid=%d for Group %d.\n", action.i_vid(), group_id);
3457 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
3458 }
3459
3460 BCMOLT_MSG_FIELD_SET(&grp_cfg_obj, action, a_val);
3461
3462 // Create group
3463 err = bcmolt_cfg_set(dev_id, &(grp_cfg_obj.hdr));
3464
3465 if (BCM_ERR_OK != err) {
3466 BCM_LOG(ERROR, openolt_log_id, "Failed to create Group %d, err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3467 return bcm_to_grpc_err(err, "Error in creating group");
3468 }
3469
3470 BCM_LOG(INFO, openolt_log_id, "Group %d has been created and configured with empty member list.\n", key.id);
3471 return Status::OK;
3472 }
3473 }
3474
3475 // The group already exists. Continue configuring it according to the update member command.
3476
3477 OPENOLT_LOG(INFO, openolt_log_id, "Configuring existing Group %d.\n",group_id);
3478
3479 // MEMBER LIST CONSTRUCTION
3480 // Note that members.len can be 0 here. if the group already exists and the command is SET then sending
3481 // empty list to the group is a legit operation and this actually empties the member list.
3482 members.arr = (bcmolt_group_member_info*)bcmos_calloc((members.len)*sizeof(bcmolt_group_member_info));
3483
3484 if (!members.arr) {
3485 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to allocate memory for group member list.\n");
3486 return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, "Memory exhausted during member list creation");
3487 }
3488
3489 /* SET GROUP MEMBERS UPDATE COMMAND */
3490 openolt::Group::GroupMembersCommand command = group_cfg->command();
3491 switch(command) {
3492 case openolt::Group::SET_MEMBERS :
3493 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_SET;
3494 OPENOLT_LOG(INFO, openolt_log_id, "Setting %d members for Group %d.\n", members.len, group_id);
3495 break;
3496 case openolt::Group::ADD_MEMBERS :
3497 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_ADD;
3498 OPENOLT_LOG(INFO, openolt_log_id, "Adding %d members to Group %d.\n", members.len, group_id);
3499 break;
3500 case openolt::Group::REMOVE_MEMBERS :
3501 grp_mem_upd_cmd = BCMOLT_MEMBERS_UPDATE_COMMAND_REMOVE;
3502 OPENOLT_LOG(INFO, openolt_log_id, "Removing %d members from Group %d.\n", members.len, group_id);
3503 break;
3504 default :
3505 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid value %d for group member command.\n", command);
3506 bcmos_free(members.arr);
3507 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid group member command");
3508 }
3509
3510 // SET MEMBERS LIST
3511 for (int i = 0; i < members.len; i++) {
3512
3513 if (command == openolt::Group::REMOVE_MEMBERS) {
3514 OPENOLT_LOG(INFO, openolt_log_id, "Removing group member %d from group %d\n",i,key.id);
3515 } else {
3516 OPENOLT_LOG(INFO, openolt_log_id, "Adding group member %d to group %d\n",i,key.id);
3517 }
3518
3519 openolt::GroupMember *member = (openolt::GroupMember *) &group_cfg->members()[i];
3520
3521 // Set member interface type
3522 openolt::GroupMember::InterfaceType if_type = member->interface_type();
3523 switch(if_type){
3524 case openolt::GroupMember::PON :
3525 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_PON);
3526 OPENOLT_LOG(INFO, openolt_log_id, "Interface type PON is assigned to GroupMember %d\n",i);
3527 break;
3528 case openolt::GroupMember::EPON_1G_PATH :
3529 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_1_G);
3530 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_1G is assigned to GroupMember %d\n",i);
3531 break;
3532 case openolt::GroupMember::EPON_10G_PATH :
3533 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_type, BCMOLT_INTERFACE_TYPE_EPON_10_G);
3534 OPENOLT_LOG(INFO, openolt_log_id, "Interface type EPON_10G is assigned to GroupMember %d\n",i);
3535 break;
3536 default :
3537 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid interface type value %d for GroupMember %d.\n",if_type,i);
3538 bcmos_free(members.arr);
3539 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface type for a group member");
3540 }
3541
3542 // Set member interface id
3543 if (member->interface_id() >= 0) {
3544 BCMOLT_FIELD_SET(&interface_ref, intf_ref, intf_id, member->interface_id());
3545 OPENOLT_LOG(INFO, openolt_log_id, "Interface %d is assigned to GroupMember %d\n", member->interface_id(), i);
3546 } else {
3547 bcmos_free(members.arr);
3548 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid interface id for a group member");
3549 }
3550
3551 // Set member interface_ref
3552 BCMOLT_FIELD_SET(&member_info, group_member_info, intf, interface_ref);
3553
3554 // Set member gem_port_id. This must be a multicast gemport.
3555 if (member->gem_port_id() >= 0) {
3556 BCMOLT_FIELD_SET(&member_info, group_member_info, svc_port_id, member->gem_port_id());
3557 OPENOLT_LOG(INFO, openolt_log_id, "GEM Port %d is assigned to GroupMember %d\n", member->gem_port_id(), i);
3558 } else {
3559 bcmos_free(members.arr);
3560 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid gem port id for a group member");
3561 }
3562
3563 // Set member scheduler id and queue_id
3564 uint32_t tm_sched_id = get_default_tm_sched_id(member->interface_id(), downstream);
3565 OPENOLT_LOG(INFO, openolt_log_id, "Scheduler %d is assigned to GroupMember %d\n", tm_sched_id, i);
3566 BCMOLT_FIELD_SET(&tm_sched_ref, tm_sched_ref, id, tm_sched_id);
3567 BCMOLT_FIELD_SET(&egress_qos, egress_qos, tm_sched, tm_sched_ref);
3568
3569 // We assume that all multicast traffic destined to a PON port is using the same fixed queue.
3570 uint32_t tm_queue_id;
3571 if (member->priority() >= 0 && member->priority() < NUMBER_OF_DEFAULT_INTERFACE_QUEUES) {
3572 tm_queue_id = queue_id_list[member->priority()];
3573 OPENOLT_LOG(INFO, openolt_log_id, "Queue %d is assigned to GroupMember %d\n", tm_queue_id, i);
3574 BCMOLT_FIELD_SET(&egress_qos, egress_qos, type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
3575 BCMOLT_FIELD_SET(&egress_qos.u.fixed_queue, egress_qos_fixed_queue, queue_id, tm_queue_id);
3576 } else {
3577 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid fixed queue priority/ID %d for GroupMember %d\n", member->priority(), i);
3578 bcmos_free(members.arr);
3579 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid queue priority for a group member");
3580 }
3581
3582 BCMOLT_FIELD_SET(&member_info, group_member_info, egress_qos, egress_qos);
3583 BCMOLT_ARRAY_ELEM_SET(&(members), i, member_info);
3584 }
3585
3586 BCMOLT_OPER_INIT(&grp_mem_upd, group, members_update, key);
3587 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.members, members);
3588 BCMOLT_MSG_FIELD_SET(&grp_mem_upd, members_cmd.command, grp_mem_upd_cmd);
3589
3590 err = bcmolt_oper_submit(dev_id, &(grp_mem_upd.hdr));
3591 bcmos_free(members.arr);
3592
3593 if (BCM_ERR_OK != err) {
3594 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to submit members update operation for Group %d err = %s (%d)\n", key.id, bcmos_strerror(err), err);
3595 return bcm_to_grpc_err(err, "Failed to submit members update operation for the group");
3596 }
3597
3598 OPENOLT_LOG(INFO, openolt_log_id, "Successfully submitted members update operation for Group %d\n", key.id);
3599
3600 return Status::OK;
3601}