blob: a905645c2f6db6f77cec975bfc98922b5f03ba0c [file] [log] [blame]
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansarib7b0ced2018-05-11 21:53:32 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansarib7b0ced2018-05-11 21:53:32 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +000016
17#include <iostream>
18#include <memory>
19#include <string>
20
21#include "Queue.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000022#include <sstream>
Nicolas Palpacuer9c352082018-08-14 16:37:14 -040023#include <chrono>
24#include <thread>
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080025#include <bitset>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000026#include <inttypes.h>
Jason Huangbf45ffb2019-10-30 17:29:02 +080027#include <unistd.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000028
Craig Lutgen88a22ad2018-10-04 12:30:46 -050029#include "device.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000030#include "core.h"
31#include "indications.h"
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040032#include "stats_collection.h"
Nicolas Palpacuer73222e02018-07-16 12:20:26 -040033#include "error_format.h"
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040034#include "state.h"
Craig Lutgen88a22ad2018-10-04 12:30:46 -050035#include "utils.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000036
37extern "C"
38{
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000039#include <bcmolt_api.h>
40#include <bcmolt_host_api.h>
41#include <bcmolt_api_model_supporting_enums.h>
42
43#include <bal_version.h>
44#include <bcmolt_api_conn_mgr.h>
45//CLI header files
46#include <bcmcli_session.h>
47#include <bcmcli.h>
48#include <bcm_api_cli.h>
49
50#include <bcmos_common.h>
51#include <bcm_config.h>
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -040052// FIXME : dependency problem
53// #include <bcm_common_gpon.h>
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040054// #include <bcm_dev_log_task.h>
Shad Ansarib7b0ced2018-05-11 21:53:32 +000055}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000056
Shad Ansarib7b0ced2018-05-11 21:53:32 +000057
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040058dev_log_id openolt_log_id = bcm_dev_log_id_register("OPENOLT", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
59dev_log_id omci_log_id = bcm_dev_log_id_register("OMCI", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
60
Craig Lutgen88a22ad2018-10-04 12:30:46 -050061#define BAL_RSC_MANAGER_BASE_TM_SCHED_ID 16384
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080062#define MAX_TM_QUEUE_ID 8192
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000063#define MAX_TM_QMP_ID 16
64#define TMQ_MAP_PROFILE_SIZE 8
65#define MAX_TM_SCHED_ID 1023
66#define MAX_SUBS_TM_SCHED_ID (MAX_SUPPORTED_PON == 16 ? MAX_TM_SCHED_ID-4-16 : MAX_TM_SCHED_ID-10-64)
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -080067#define EAP_ETHER_TYPE 34958
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000068#define XGS_BANDWIDTH_GRANULARITY 16000
69#define GPON_BANDWIDTH_GRANULARITY 32000
70#define FILL_ARRAY(ARRAY,START,END,VALUE) for(int i=START;i<END;ARRAY[i++]=VALUE);
71#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
72
73#define GET_FLOW_INTERFACE_TYPE(type) \
74 (type == BCMOLT_FLOW_INTERFACE_TYPE_PON) ? "PON" : \
75 (type == BCMOLT_FLOW_INTERFACE_TYPE_NNI) ? "NNI" : \
76 (type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) ? "HOST" : "unknown"
77#define GET_PKT_TAG_TYPE(type) \
78 (type == BCMOLT_PKT_TAG_TYPE_UNTAGGED) ? "UNTAG" : \
79 (type == BCMOLT_PKT_TAG_TYPE_SINGLE_TAG) ? "SINGLE_TAG" : \
80 (type == BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG) ? "DOUBLE_TAG" : "unknown"
Nicolas Palpacuer967438f2018-09-07 14:41:54 -040081
Craig Lutgen88a22ad2018-10-04 12:30:46 -050082static unsigned int num_of_nni_ports = 0;
83static unsigned int num_of_pon_ports = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000084static std::string intf_technologies[MAX_SUPPORTED_PON];
Craig Lutgen88a22ad2018-10-04 12:30:46 -050085static const std::string UNKNOWN_TECH("unknown");
Craig Lutgenb2601f02018-10-23 13:04:31 -050086static const std::string MIXED_TECH("mixed");
87static std::string board_technology(UNKNOWN_TECH);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000088static std::string chip_family(UNKNOWN_TECH);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -080089static unsigned int OPENOLT_FIELD_LEN = 200;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000090static std::string firmware_version = "Openolt.2019.07.01";
Nicolas Palpacuerdff96792018-09-06 14:59:32 -040091
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000092const uint32_t tm_upstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
93 MAX_TM_SCHED_ID-3 : MAX_TM_SCHED_ID-9);
94const uint32_t tm_downstream_sched_id_start = (MAX_SUPPORTED_PON == 16 ? \
95 tm_upstream_sched_id_start-16 : tm_upstream_sched_id_start-64);
96
97/* Max Queue ID supported is 7 so based on priority_q configured for GEMPORTS
98in TECH PROFILE respective Queue ID from this list will be used for both
99US and DS Queues*/
100const uint32_t queue_id_list[8] = {0, 1, 2, 3, 4, 5, 6, 7};
101
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700102const std::string upstream = "upstream";
103const std::string downstream = "downstream";
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000104bcmolt_oltid dev_id = 0;
105
Amit Ghoshfcad4d32019-11-13 10:24:55 +0000106/* Constants used for retrying some BAL APIs */
107const uint32_t BAL_API_RETRY_TIME_IN_USECS = 1000000;
108const uint32_t MAX_BAL_API_RETRY_COUNT = 5;
109
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000110/* Current session */
111static bcmcli_session *current_session;
112static bcmcli_entry *api_parent_dir;
113bcmos_bool status_bcm_cli_quit = BCMOS_FALSE;
114bcmos_task bal_cli_thread;
115const char *bal_cli_thread_name = "bal_cli_thread";
116uint16_t flow_id_counters = 0;
117int flow_id_data[16384][2];
Shad Ansariedef2132018-08-10 22:14:50 +0000118State state;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -0400119
Craig Lutgen967a1d02018-11-27 10:41:51 -0600120static std::map<uint32_t, uint32_t> flowid_to_port; // For mapping upstream flows to logical ports
121static std::map<uint32_t, uint32_t> flowid_to_gemport; // For mapping downstream flows into gemports
122static std::map<uint32_t, std::set<uint32_t> > port_to_flows; // For mapping logical ports to downstream flows
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800123
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000124/* This represents the Key to 'sched_map' map.
125 Represents (pon_intf_id, onu_id, uni_id, direction) */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800126typedef std::tuple<uint32_t, uint32_t, uint32_t, std::string> sched_map_key_tuple;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000127/* 'sched_map' maps sched_map_key_tuple to DBA (Upstream) or
128 Subscriber (Downstream) Scheduler ID */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800129static std::map<sched_map_key_tuple, int> sched_map;
130
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500131/* This represents the Key to 'qos_type_map' map.
132 Represents (pon_intf_id, onu_id, uni_id) */
133typedef std::tuple<uint32_t, uint32_t, uint32_t> qos_type_map_key_tuple;
134/* 'qos_type_map' maps qos_type_map_key_tuple to qos_type*/
135static std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type> qos_type_map;
136
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000137/* This represents the Key to 'sched_qmp_id_map' map.
138Represents (sched_id, pon_intf_id, onu_id, uni_id) */
139typedef std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> sched_qmp_id_map_key_tuple;
140/* 'sched_qmp_id_map' maps sched_qmp_id_map_key_tuple to TM Queue Mapping Profile ID */
141static std::map<sched_qmp_id_map_key_tuple, int> sched_qmp_id_map;
142/* 'qmp_id_to_qmp_map' maps TM Queue Mapping Profile ID to TM Queue Mapping Profile */
143static std::map<int, std::vector < uint32_t > > qmp_id_to_qmp_map;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800144
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500145// Flag used to watch whether mocked alloc_cfg_compltd_key is added to alloc_cfg_compltd_map
146#ifdef TEST_MODE
147bool ALLOC_CFG_FLAG = false;
148#endif
149
Girish Gowdra96461052019-11-22 20:13:59 +0530150#define ALLOC_CFG_COMPLETE_WAIT_TIMEOUT 1000 // in milli-seconds
151// Map used to track response from BAL for ITU PON Alloc Configuration.
152// The key is alloc_cfg_compltd_key and value is a concurrent thread-safe queue which is
153// used for pushing (from BAL) and popping (at application) the results.
154std::map<alloc_cfg_compltd_key, Queue<alloc_cfg_complete_result> *> alloc_cfg_compltd_map;
155// Lock to protect critical section data structure used for handling AllocObject configuration response.
156bcmos_fastlock alloc_cfg_wait_lock;
157
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800158std::bitset<MAX_TM_SCHED_ID> tm_sched_bitset;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000159std::bitset<MAX_TM_QMP_ID> tm_qmp_bitset;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800160
161static bcmos_fastlock data_lock;
Craig Lutgen967a1d02018-11-27 10:41:51 -0600162
Girish Gowdra96461052019-11-22 20:13:59 +0530163
Craig Lutgen967a1d02018-11-27 10:41:51 -0600164#define MIN_ALLOC_ID_GPON 256
165#define MIN_ALLOC_ID_XGSPON 1024
166
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800167static bcmos_errno CreateSched(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
168 uint32_t port_no, uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, \
169 uint32_t priority, tech_profile::SchedulingPolicy sched_policy,
170 tech_profile::TrafficShapingInfo traffic_shaping_info);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000171static bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800172static bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500173 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
174static bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id, \
175 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000176static bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction);
177static bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction);
178
179uint16_t get_dev_id(void) {
180 return dev_id;
181}
Shad Ansari627b5782018-08-13 22:49:32 +0000182
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400183// Stubbed defntions of bcmolt_cfg_get required for unit-test
184#ifdef TEST_MODE
185extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500186extern bcmos_errno bcmolt_cfg_get__onu_state_stub(bcmolt_oltid olt_id, void* ptr);
187extern bcmos_errno bcmolt_cfg_get__tm_sched_stub(bcmolt_oltid olt_id, void* ptr);
188extern bcmos_errno bcmolt_cfg_get__pon_intf_stub(bcmolt_oltid olt_id, void* ptr);
189extern bcmos_errno bcmolt_cfg_get__nni_intf_stub(bcmolt_oltid olt_id, void* ptr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400190extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -0500191extern bcmos_errno bcmolt_cfg_get__flow_stub(bcmolt_oltid olt_id, void* ptr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -0400192#endif
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800193/**
194* Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
195* Every NNI port and PON port have default scheduler.
196* The NNI0 default scheduler ID is 18432, and NNI1 is 18433 and so on.
197* Similarly, PON0 default scheduler ID is 16384. PON1 is 16385 and so on.
198*
199* @param intf_id NNI or PON interface ID
200* @param direction "upstream" or "downstream"
201*
202* @return default scheduler ID for the given interface.
203*/
204static inline int get_default_tm_sched_id(int intf_id, std::string direction) {
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700205 if (direction.compare(upstream) == 0) {
206 return tm_upstream_sched_id_start + intf_id;
207 } else if (direction.compare(downstream) == 0) {
208 return tm_downstream_sched_id_start + intf_id;
209 }
210 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000211 OPENOLT_LOG(ERROR, openolt_log_id, "invalid direction - %s\n", direction.c_str());
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700212 return 0;
213 }
214}
215
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800216/**
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800217* Gets a unique tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
218* The tm_sched_id is locally cached in a map, so that it can rendered when necessary.
219* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
220*
221* @param intf_id NNI or PON intf ID
222* @param onu_id ONU ID
223* @param uni_id UNI ID
224* @param gemport_id GEM Port ID
225* @param direction Upstream or downstream
226*
227* @return tm_sched_id
228*/
229uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
230 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
231 int sched_id = -1;
232
233 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
234 if (it != sched_map.end()) {
235 sched_id = it->second;
236 }
237 if (sched_id != -1) {
238 return sched_id;
239 }
240
241 bcmos_fastlock_lock(&data_lock);
242 // Complexity of O(n). Is there better way that can avoid linear search?
243 for (sched_id = 0; sched_id < MAX_TM_SCHED_ID; sched_id++) {
244 if (tm_sched_bitset[sched_id] == 0) {
245 tm_sched_bitset[sched_id] = 1;
246 break;
247 }
248 }
249 bcmos_fastlock_unlock(&data_lock, 0);
250
251 if (sched_id < MAX_TM_SCHED_ID) {
252 bcmos_fastlock_lock(&data_lock);
253 sched_map[key] = sched_id;
254 bcmos_fastlock_unlock(&data_lock, 0);
255 return sched_id;
256 } else {
257 return -1;
258 }
259}
260
261/**
262* Free tm_sched_id for a given intf_id, onu_id, uni_id, gemport_id, direction
263*
264* @param intf_id NNI or PON intf ID
265* @param onu_id ONU ID
266* @param uni_id UNI ID
267* @param gemport_id GEM Port ID
268* @param direction Upstream or downstream
269*/
270void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
271 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
272 std::map<sched_map_key_tuple, int>::const_iterator it;
273 bcmos_fastlock_lock(&data_lock);
274 it = sched_map.find(key);
275 if (it != sched_map.end()) {
276 tm_sched_bitset[it->second] = 0;
277 sched_map.erase(it);
278 }
279 bcmos_fastlock_unlock(&data_lock, 0);
280}
281
282bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction) {
283 sched_map_key_tuple key(pon_intf_id, onu_id, uni_id, direction);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000284 std::map<sched_map_key_tuple, int>::const_iterator it = sched_map.find(key);
285 if (it != sched_map.end()) {
286 return true;
287 }
288 return false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800289}
290
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000291/**
292* Check whether given two tm qmp profiles are equal or not
293*
294* @param tmq_map_profileA <vector> TM QUEUE MAPPING PROFILE
295* @param tmq_map_profileB <vector> TM QUEUE MAPPING PROFILE
296*
297* @return boolean, true if given tmq_map_profiles are equal else false
298*/
299
300bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB) {
301 for (uint32_t i = 0; i < TMQ_MAP_PROFILE_SIZE; i++) {
302 if (tmq_map_profileA[i] != tmq_map_profileB[i]) {
303 return false;
304 }
305 }
306 return true;
Shad Ansari627b5782018-08-13 22:49:32 +0000307}
308
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000309/**
310* Modifies given queues_pbit_map to parsable format
311* e.g: Modifes "0b00000101" to "10100000"
312*
313* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
314* @param size Queue count
315*
316* @return string queues_pbit_map
317*/
318std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size) {
319 for(uint32_t i=0; i < size; i++) {
320 /* Deletes 2 characters from index number 0 */
321 queues_pbit_map[i].erase(0, 2);
322 std::reverse(queues_pbit_map[i].begin(), queues_pbit_map[i].end());
323 }
324 return queues_pbit_map;
325}
326
327/**
328* Creates TM QUEUE MAPPING PROFILE for given queues_pbit_map and queues_priority_q
329*
330* @param queues_pbit_map PBIT MAP configured for each GEM in TECH PROFILE
331* @param queues_priority_q PRIORITY_Q configured for each GEM in TECH PROFILE
332* @param size Queue count
333*
334* @return <vector> TM QUEUE MAPPING PROFILE
335*/
336std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size) {
337 std::vector<uint32_t> tmq_map_profile(8,0);
338
339 for(uint32_t i=0; i < size; i++) {
340 for (uint32_t j = 0; j < queues_pbit_map[i].size(); j++) {
341 if (queues_pbit_map[i][j]=='1') {
342 tmq_map_profile.at(j) = queue_id_list[queues_priority_q[i]];
343 }
344 }
345 }
346 return tmq_map_profile;
347}
348
349/**
350* Gets corresponding tm_qmp_id for a given tmq_map_profile
351*
352* @param <vector> TM QUEUE MAPPING PROFILE
353*
354* @return tm_qmp_id
355*/
356int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile) {
357 int tm_qmp_id = -1;
358
359 std::map<int, std::vector < uint32_t > >::const_iterator it = qmp_id_to_qmp_map.begin();
360 while(it != qmp_id_to_qmp_map.end()) {
361 if(check_tm_qmp_equality(tmq_map_profile, it->second)) {
362 tm_qmp_id = it->first;
363 break;
364 }
365 it++;
366 }
367 return tm_qmp_id;
368}
369
370/**
371* Updates sched_qmp_id_map with given sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id
372*
373* @param upstream/downstream sched_id
374* @param PON intf ID
375* @param onu_id ONU ID
376* @param uni_id UNI ID
377* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
378*/
379void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
380 uint32_t uni_id, int tm_qmp_id) {
381 bcmos_fastlock_lock(&data_lock);
382 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
383 sched_qmp_id_map.insert(make_pair(key, tm_qmp_id));
384 bcmos_fastlock_unlock(&data_lock, 0);
385}
386
387/**
388* Gets corresponding tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
389*
390* @param upstream/downstream sched_id
391* @param PON intf ID
392* @param onu_id ONU ID
393* @param uni_id UNI ID
394*
395* @return tm_qmp_id
396*/
397int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
398 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
399 int tm_qmp_id = -1;
400
401 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
402 if (it != sched_qmp_id_map.end()) {
403 tm_qmp_id = it->second;
404 }
405 return tm_qmp_id;
406}
407
408/**
409* Gets a unique tm_qmp_id for a given tmq_map_profile
410* The tm_qmp_id is locally cached in a map, so that it can be rendered when necessary.
411* VOLTHA replays whole configuration on OLT reboot, so caching locally is not a problem
412*
413* @param upstream/downstream sched_id
414* @param PON intf ID
415* @param onu_id ONU ID
416* @param uni_id UNI ID
417* @param <vector> TM QUEUE MAPPING PROFILE
418*
419* @return tm_qmp_id
420*/
421int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, \
422 std::vector<uint32_t> tmq_map_profile) {
423 int tm_qmp_id;
424
425 bcmos_fastlock_lock(&data_lock);
426 /* Complexity of O(n). Is there better way that can avoid linear search? */
427 for (tm_qmp_id = 0; tm_qmp_id < MAX_TM_QMP_ID; tm_qmp_id++) {
428 if (tm_qmp_bitset[tm_qmp_id] == 0) {
429 tm_qmp_bitset[tm_qmp_id] = 1;
430 break;
431 }
432 }
433 bcmos_fastlock_unlock(&data_lock, 0);
434
435 if (tm_qmp_id < MAX_TM_QMP_ID) {
436 bcmos_fastlock_lock(&data_lock);
437 qmp_id_to_qmp_map.insert(make_pair(tm_qmp_id, tmq_map_profile));
438 bcmos_fastlock_unlock(&data_lock, 0);
439 update_sched_qmp_id_map(sched_id, pon_intf_id, onu_id, uni_id, tm_qmp_id);
440 return tm_qmp_id;
441 } else {
442 return -1;
443 }
444}
445
446/**
447* Free tm_qmp_id for a given sched_id, pon_intf_id, onu_id, uni_id
448*
449* @param upstream/downstream sched_id
450* @param PON intf ID
451* @param onu_id ONU ID
452* @param uni_id UNI ID
453* @param tm_qmp_id TM QUEUE MAPPING PROFILE ID
454*
455* @return boolean, true if no more reference for TM QMP else false
456*/
457bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, \
458 uint32_t uni_id, int tm_qmp_id) {
459 bool result;
460 sched_qmp_id_map_key_tuple key(sched_id, pon_intf_id, onu_id, uni_id);
461 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it = sched_qmp_id_map.find(key);
462 bcmos_fastlock_lock(&data_lock);
463 if (it != sched_qmp_id_map.end()) {
464 sched_qmp_id_map.erase(it);
465 }
466 bcmos_fastlock_unlock(&data_lock, 0);
467
468 uint32_t tm_qmp_ref_count = 0;
469 std::map<sched_qmp_id_map_key_tuple, int>::const_iterator it2 = sched_qmp_id_map.begin();
470 while(it2 != sched_qmp_id_map.end()) {
471 if(it2->second == tm_qmp_id) {
472 tm_qmp_ref_count++;
473 }
474 it2++;
475 }
476
477 if (tm_qmp_ref_count == 0) {
478 std::map<int, std::vector < uint32_t > >::const_iterator it3 = qmp_id_to_qmp_map.find(tm_qmp_id);
479 if (it3 != qmp_id_to_qmp_map.end()) {
480 bcmos_fastlock_lock(&data_lock);
481 tm_qmp_bitset[tm_qmp_id] = 0;
482 qmp_id_to_qmp_map.erase(it3);
483 bcmos_fastlock_unlock(&data_lock, 0);
484 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So clearing it\n", \
485 tm_qmp_id, tm_qmp_ref_count);
486 result = true;
487 }
488 } else {
489 OPENOLT_LOG(INFO, openolt_log_id, "Reference count for tm qmp profile id %d is : %d. So not clearing it\n", \
490 tm_qmp_id, tm_qmp_ref_count);
491 result = false;
492 }
493 return result;
494}
495
496/**
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -0500497* Returns qos type as string
498*
499* @param qos_type bcmolt_egress_qos_type enum
500*/
501std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type) {
502 switch (qos_type)
503 {
504 case BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE: return "FIXED_QUEUE";
505 case BCMOLT_EGRESS_QOS_TYPE_TC_TO_QUEUE: return "TC_TO_QUEUE";
506 case BCMOLT_EGRESS_QOS_TYPE_PBIT_TO_TC: return "PBIT_TO_TC";
507 case BCMOLT_EGRESS_QOS_TYPE_NONE: return "NONE";
508 case BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE: return "PRIORITY_TO_QUEUE";
509 default: OPENOLT_LOG(ERROR, openolt_log_id, "qos-type-not-supported %d\n", qos_type);
510 return "qos-type-not-supported";
511 }
512}
513
514/**
515* Gets/Updates qos type for given pon_intf_id, onu_id, uni_id
516*
517* @param PON intf ID
518* @param onu_id ONU ID
519* @param uni_id UNI ID
520* @param queue_size TrafficQueues Size
521*
522* @return qos_type
523*/
524bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size = 0) {
525 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
526 bcmolt_egress_qos_type egress_qos_type = BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
527 std::string qos_string;
528
529 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
530 if (it != qos_type_map.end()) {
531 egress_qos_type = it->second;
532 qos_string = get_qos_type_as_string(egress_qos_type);
533 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", \
534 pon_intf_id, onu_id, uni_id, qos_string.c_str());
535 }
536 else {
537 /* QOS Type has been pre-defined as Fixed Queue but it will be updated based on number of GEMPORTS
538 associated for a given subscriber. If GEM count = 1 for a given subscriber, qos_type will be Fixed Queue
539 else Priority to Queue */
540 egress_qos_type = (queue_size > 1) ? \
541 BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE : BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE;
542 bcmos_fastlock_lock(&data_lock);
543 qos_type_map.insert(make_pair(key, egress_qos_type));
544 bcmos_fastlock_unlock(&data_lock, 0);
545 qos_string = get_qos_type_as_string(egress_qos_type);
546 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", \
547 pon_intf_id, onu_id, uni_id, qos_string.c_str());
548 }
549 return egress_qos_type;
550}
551
552/**
553* Clears qos type for given pon_intf_id, onu_id, uni_id
554*
555* @param PON intf ID
556* @param onu_id ONU ID
557* @param uni_id UNI ID
558*/
559void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id) {
560 qos_type_map_key_tuple key(pon_intf_id, onu_id, uni_id);
561 std::map<qos_type_map_key_tuple, bcmolt_egress_qos_type>::const_iterator it = qos_type_map.find(key);
562 bcmos_fastlock_lock(&data_lock);
563 if (it != qos_type_map.end()) {
564 qos_type_map.erase(it);
565 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", \
566 pon_intf_id, onu_id, uni_id);
567 }
568 bcmos_fastlock_unlock(&data_lock, 0);
569}
570
571/**
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000572* Returns Scheduler/Queue direction as string
573*
574* @param direction as specified in tech_profile.proto
575*/
576std::string GetDirection(int direction) {
577 switch (direction)
578 {
579 case tech_profile::Direction::UPSTREAM: return upstream;
580 case tech_profile::Direction::DOWNSTREAM: return downstream;
581 default: OPENOLT_LOG(ERROR, openolt_log_id, "direction-not-supported %d\n", direction);
582 return "direction-not-supported";
583 }
584}
585
586inline const char *get_flow_acton_command(uint32_t command) {
587 char actions[200] = { };
588 char *s_actions_ptr = actions;
589 if (command & BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG) strcat(s_actions_ptr, "ADD_OUTER_TAG|");
590 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG) strcat(s_actions_ptr, "REMOVE_OUTER_TAG|");
591 if (command & BCMOLT_ACTION_CMD_ID_XLATE_OUTER_TAG) strcat(s_actions_ptr, "TRANSLATE_OUTER_TAG|");
592 if (command & BCMOLT_ACTION_CMD_ID_ADD_INNER_TAG) strcat(s_actions_ptr, "ADD_INNTER_TAG|");
593 if (command & BCMOLT_ACTION_CMD_ID_REMOVE_INNER_TAG) strcat(s_actions_ptr, "REMOVE_INNER_TAG|");
594 if (command & BCMOLT_ACTION_CMD_ID_XLATE_INNER_TAG) strcat(s_actions_ptr, "TRANSLATE_INNER_TAG|");
595 if (command & BCMOLT_ACTION_CMD_ID_REMARK_OUTER_PBITS) strcat(s_actions_ptr, "REMOVE_OUTER_PBITS|");
596 if (command & BCMOLT_ACTION_CMD_ID_REMARK_INNER_PBITS) strcat(s_actions_ptr, "REMAKE_INNER_PBITS|");
597 return s_actions_ptr;
598}
599
Girish Gowdra96461052019-11-22 20:13:59 +0530600// This method handles waiting for AllocObject configuration.
601// Returns error if the AllocObject is not in the appropriate state based on action requested.
602bcmos_errno wait_for_alloc_action(uint32_t intf_id, uint32_t alloc_id, AllocCfgAction action) {
603 Queue<alloc_cfg_complete_result> cfg_result;
604 alloc_cfg_compltd_key k(intf_id, alloc_id);
605 alloc_cfg_compltd_map[k] = &cfg_result;
606 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500607 #ifdef TEST_MODE
608 ALLOC_CFG_FLAG = true;
609 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530610
611 // Try to pop the result from BAL with a timeout of ALLOC_CFG_COMPLETE_WAIT_TIMEOUT ms
612 std::pair<alloc_cfg_complete_result, bool> result = cfg_result.pop(ALLOC_CFG_COMPLETE_WAIT_TIMEOUT);
613 if (result.second == false) {
614 OPENOLT_LOG(ERROR, openolt_log_id, "timeout waiting for alloc cfg complete indication intf_id %d, alloc_id %d\n",
615 intf_id, alloc_id);
616 // Invalidate the queue pointer.
617 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
618 alloc_cfg_compltd_map[k] = NULL;
619 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
620 err = BCM_ERR_INTERNAL;
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500621 #ifdef TEST_MODE
622 ALLOC_CFG_FLAG = false;
623 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530624 }
625 else if (result.first.status == ALLOC_CFG_STATUS_FAIL) {
626 OPENOLT_LOG(ERROR, openolt_log_id, "error processing alloc cfg request intf_id %d, alloc_id %d\n",
627 intf_id, alloc_id);
628 err = BCM_ERR_INTERNAL;
629 }
630
631 if (err == BCM_ERR_OK) {
632 if (action == ALLOC_OBJECT_CREATE) {
633 if (result.first.state != ALLOC_OBJECT_STATE_ACTIVE) {
634 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object not in active state intf_id %d, alloc_id %d alloc_obj_state %d\n",
635 intf_id, alloc_id, result.first.state);
636 err = BCM_ERR_INTERNAL;
637 } else {
638 OPENOLT_LOG(INFO, openolt_log_id, "Create upstream bandwidth allocation success, intf_id %d, alloc_id %d\n",
639 intf_id, alloc_id);
640 }
641 } else { // ALLOC_OBJECT_DELETE
642 if (result.first.state != ALLOC_OBJECT_STATE_NOT_CONFIGURED) {
643 OPENOLT_LOG(ERROR, openolt_log_id, "alloc object is not reset intf_id %d, alloc_id %d alloc_obj_state %d\n",
644 intf_id, alloc_id, result.first.state);
645 err = BCM_ERR_INTERNAL;
646 } else {
647 OPENOLT_LOG(INFO, openolt_log_id, "Remove alloc object success, intf_id %d, alloc_id %d\n",
648 intf_id, alloc_id);
649 }
650 }
651 }
652
653 // Remove entry from map
654 bcmos_fastlock_lock(&alloc_cfg_wait_lock);
655 alloc_cfg_compltd_map.erase(k);
656 bcmos_fastlock_unlock(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -0500657 #ifdef TEST_MODE
658 ALLOC_CFG_FLAG = false;
659 #endif
Girish Gowdra96461052019-11-22 20:13:59 +0530660 return err;
661}
662
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000663char* openolt_read_sysinfo(const char* field_name, char* field_val)
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800664{
665 FILE *fp;
666 /* Prepare the command*/
667 char command[150];
668
669 snprintf(command, sizeof command, "bash -l -c \"onlpdump -s\" | perl -ne 'print $1 if /%s: (\\S+)/'", field_name);
670 /* Open the command for reading. */
671 fp = popen(command, "r");
672 if (fp == NULL) {
673 /*The client has to check for a Null field value in this case*/
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000674 OPENOLT_LOG(INFO, openolt_log_id, "Failed to query the %s\n", field_name);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800675 return field_val;
676 }
677
678 /*Read the field value*/
679 if (fp) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000680 uint8_t ret;
681 ret = fread(field_val, OPENOLT_FIELD_LEN, 1, fp);
682 if (ret >= OPENOLT_FIELD_LEN)
683 OPENOLT_LOG(INFO, openolt_log_id, "Read data length %u\n", ret);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800684 pclose(fp);
685 }
686 return field_val;
687}
688
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400689Status GetDeviceInfo_(openolt::DeviceInfo* device_info) {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500690 device_info->set_vendor(VENDOR_ID);
691 device_info->set_model(MODEL_ID);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400692 device_info->set_hardware_version("");
693 device_info->set_firmware_version(firmware_version);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500694 device_info->set_technology(board_technology);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500695 device_info->set_pon_ports(num_of_pon_ports);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500696
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800697 char serial_number[OPENOLT_FIELD_LEN];
698 memset(serial_number, '\0', OPENOLT_FIELD_LEN);
699 openolt_read_sysinfo("Serial Number", serial_number);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000700 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device serial number %s\n", serial_number);
Thiyagarajan Subramani5e973532019-02-02 03:21:43 -0800701 device_info->set_device_serial_number(serial_number);
702
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700703 char device_id[OPENOLT_FIELD_LEN];
704 memset(device_id, '\0', OPENOLT_FIELD_LEN);
705 openolt_read_sysinfo("MAC", device_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000706 OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
Girish Gowdru771f9ff2019-07-24 12:02:10 -0700707 device_info->set_device_id(device_id);
708
Craig Lutgenb2601f02018-10-23 13:04:31 -0500709 // Legacy, device-wide ranges. To be deprecated when adapter
710 // is upgraded to support per-interface ranges
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000711 if (board_technology == "XGS-PON") {
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500712 device_info->set_onu_id_start(1);
713 device_info->set_onu_id_end(255);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600714 device_info->set_alloc_id_start(MIN_ALLOC_ID_XGSPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500715 device_info->set_alloc_id_end(16383);
716 device_info->set_gemport_id_start(1024);
717 device_info->set_gemport_id_end(65535);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500718 device_info->set_flow_id_start(1);
719 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500720 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000721 else if (board_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500722 device_info->set_onu_id_start(1);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500723 device_info->set_onu_id_end(127);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600724 device_info->set_alloc_id_start(MIN_ALLOC_ID_GPON);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500725 device_info->set_alloc_id_end(767);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500726 device_info->set_gemport_id_start(256);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500727 device_info->set_gemport_id_end(4095);
Craig Lutgenb2601f02018-10-23 13:04:31 -0500728 device_info->set_flow_id_start(1);
729 device_info->set_flow_id_end(16383);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500730 }
Craig Lutgenb2601f02018-10-23 13:04:31 -0500731
732 std::map<std::string, openolt::DeviceInfo::DeviceResourceRanges*> ranges;
733 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
734 std::string intf_technology = intf_technologies[intf_id];
735 openolt::DeviceInfo::DeviceResourceRanges *range = ranges[intf_technology];
736 if(range == nullptr) {
737 range = device_info->add_ranges();
738 ranges[intf_technology] = range;
739 range->set_technology(intf_technology);
740
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000741 if (intf_technology == "XGS-PON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500742 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
743
744 pool = range->add_pools();
745 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
746 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
747 pool->set_start(1);
748 pool->set_end(255);
749
750 pool = range->add_pools();
751 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
752 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
753 pool->set_start(1024);
754 pool->set_end(16383);
755
756 pool = range->add_pools();
757 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
758 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
759 pool->set_start(1024);
760 pool->set_end(65535);
761
762 pool = range->add_pools();
763 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
764 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
765 pool->set_start(1);
766 pool->set_end(16383);
767 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000768 else if (intf_technology == "GPON") {
Craig Lutgenb2601f02018-10-23 13:04:31 -0500769 openolt::DeviceInfo::DeviceResourceRanges::Pool* pool;
770
771 pool = range->add_pools();
772 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ONU_ID);
773 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::DEDICATED_PER_INTF);
774 pool->set_start(1);
775 pool->set_end(127);
776
777 pool = range->add_pools();
778 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::ALLOC_ID);
779 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_SAME_TECH);
780 pool->set_start(256);
781 pool->set_end(757);
782
783 pool = range->add_pools();
784 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::GEMPORT_ID);
785 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
786 pool->set_start(256);
787 pool->set_end(4095);
788
789 pool = range->add_pools();
790 pool->set_type(openolt::DeviceInfo::DeviceResourceRanges::Pool::FLOW_ID);
791 pool->set_sharing(openolt::DeviceInfo::DeviceResourceRanges::Pool::SHARED_BY_ALL_INTF_ALL_TECH);
792 pool->set_start(1);
793 pool->set_end(16383);
794 }
795 }
796
797 range->add_intf_ids(intf_id);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500798 }
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400799
800 // FIXME: Once dependency problem is fixed
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500801 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400802 // device_info->set_onu_id_end(XGPON_NUM_OF_ONUS - 1);
803 // device_info->set_alloc_id_start(1024);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500804 // device_info->set_alloc_id_end(XGPON_NUM_OF_ALLOC_IDS * num_of_pon_ports ? - 1);
Nicolas Palpacuerf0b02492018-09-10 10:21:29 -0400805 // device_info->set_gemport_id_start(XGPON_MIN_BASE_SERVICE_PORT_ID);
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500806 // device_info->set_gemport_id_end(XGPON_NUM_OF_GEM_PORT_IDS_PER_PON * num_of_pon_ports ? - 1);
807 // device_info->set_pon_ports(num_of_pon_ports);
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400808
809 return Status::OK;
810}
811
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000812Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state)
813{
814 openolt::Indication ind;
815 openolt::IntfOperIndication* intf_oper_ind = new openolt::IntfOperIndication;
816
817 intf_oper_ind->set_type(type);
818 intf_oper_ind->set_intf_id(intf_id);
819 intf_oper_ind->set_oper_state(state);
820 ind.set_allocated_intf_oper_ind(intf_oper_ind);
821 oltIndQ.push(ind);
822 return Status::OK;
823}
824
825#define CLI_HOST_PROMPT_FORMAT "BCM.%u> "
826
827/* Build CLI prompt */
828static void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len)
829{
830 snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, dev_id);
831}
832
833static int _bal_apiend_cli_thread_handler(long data)
834{
835 char init_string[]="\n";
836 bcmcli_session *sess = current_session;
837 bcmos_task_parm bal_cli_task_p_dummy;
838
839 /* Switch to interactive mode if not stopped in the init script */
840 if (!bcmcli_is_stopped(sess))
841 {
842 /* 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);
852 };
853 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 */
897 if (BCM_ERR_OK != bcmos_task_query(&bal_cli_thread, &bal_cli_task_p_dummy))
898 {
899 /* Create BAL CLI thread */
900 bal_cli_task_p.name = bal_cli_thread_name;
901 bal_cli_task_p.handler = _bal_apiend_cli_thread_handler;
902 bal_cli_task_p.priority = TASK_PRIORITY_CLI;
903
904 ret = bcmos_task_create(&bal_cli_thread, &bal_cli_task_p);
905 if (BCM_ERR_OK != ret)
906 {
907 bcmos_printf("Couldn't create BAL API end CLI thread\n");
908 return ret;
909 }
910 }
911}
912
Shad Ansari627b5782018-08-13 22:49:32 +0000913Status Enable_(int argc, char *argv[]) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000914 bcmos_errno err;
915 bcmolt_host_init_parms init_parms = {};
916 init_parms.transport.type = BCM_HOST_API_CONN_LOCAL;
917 unsigned int failed_enable_device_cnt = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +0000918
Shad Ansariedef2132018-08-10 22:14:50 +0000919 if (!state.is_activated()) {
Shad Ansari627b5782018-08-13 22:49:32 +0000920
Craig Lutgen88a22ad2018-10-04 12:30:46 -0500921 vendor_init();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000922 /* Initialize host subsystem */
923 err = bcmolt_host_init(&init_parms);
924 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500925 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to init OLT, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000926 return bcm_to_grpc_err(err, "Failed to init OLT");
927 }
928
929 bcmcli_session_parm mon_session_parm;
930 /* Create CLI session */
931 memset(&mon_session_parm, 0, sizeof(mon_session_parm));
932 mon_session_parm.get_prompt = openolt_cli_get_prompt_cb;
933 mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN;
934 bcmos_errno rc = bcmcli_session_open(&mon_session_parm, &current_session);
935 BUG_ON(rc != BCM_ERR_OK);
936
937 /* API CLI */
938 bcm_openolt_api_cli_init(NULL, current_session);
939
940 /* Add quit command */
941 BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", bcm_cli_quit);
942
943 err = bcmolt_apiend_cli_init();
944 if (BCM_ERR_OK != err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -0500945 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to add apiend init, err = %s\n",bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000946 return bcm_to_grpc_err(err, "Failed to add apiend init");
947 }
948
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800949 bcmos_fastlock_init(&data_lock, 0);
Girish Gowdra96461052019-11-22 20:13:59 +0530950 bcmos_fastlock_init(&alloc_cfg_wait_lock, 0);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000951 OPENOLT_LOG(INFO, openolt_log_id, "Enable OLT - %s-%s\n", VENDOR_ID, MODEL_ID);
Craig Lutgen967a1d02018-11-27 10:41:51 -0600952
Jason Huangbf45ffb2019-10-30 17:29:02 +0800953 //check BCM daemon is connected or not
954 Status status = check_connection();
955 if (!status.ok())
956 return status;
957 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000958 Status status = SubscribeIndication();
959 if (!status.ok()) {
960 OPENOLT_LOG(ERROR, openolt_log_id, "SubscribeIndication failed - %s : %s\n",
961 grpc_status_code_to_string(status.error_code()).c_str(),
962 status.error_message().c_str());
963 return status;
964 }
Jason Huangbf45ffb2019-10-30 17:29:02 +0800965
966 //check BAL state in initial stage
967 status = check_bal_ready();
968 if (!status.ok())
969 return status;
970 }
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 }
1048 if (failedCount ==NumPonIf_()){
1049 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 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001065 if (failedCount == 0){
1066 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 }
1075 if (failedCount ==NumPonIf_()){
1076 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;
1455 default:
1456 return BCM_ERR_INTERNAL;
1457 }
1458
1459 return err;
1460}
1461
1462Status EnablePonIf_(uint32_t intf_id) {
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001463 bcmos_errno err = BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001464 bcmolt_pon_interface_cfg interface_obj;
1465 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1466 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
1467 bcmolt_interface_state state;
1468
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001469 err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001470 if (err == BCM_ERR_OK) {
1471 if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001472 OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001473 return Status::OK;
1474 }
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001475 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001476 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1477 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1478 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
1479 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.interval, 5000);
1480 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.onu_post_discovery_mode,
1481 BCMOLT_ONU_POST_DISCOVERY_MODE_ACTIVATE);
1482 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.los, true);
1483 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.onu_alarms, true);
1484 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.tiwi, true);
1485 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.ack_timeout, true);
1486 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.sfi, true);
1487 BCMOLT_MSG_FIELD_SET(&interface_obj, itu.automatic_onu_deactivation.loki, true);
1488 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1489 operation, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1490
1491 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1492 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001493 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 +00001494 return bcm_to_grpc_err(err, "Failed to enable discovery onu");
1495 }
1496 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1497 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001498 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 +00001499 return bcm_to_grpc_err(err, "Failed to enable PON interface");
1500 }
1501 else {
1502 OPENOLT_LOG(INFO, openolt_log_id, "Successfully enabled PON interface: %d\n", intf_id);
1503 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for PON interface: %d\n", intf_id);
1504 CreateDefaultSched(intf_id, downstream);
1505 CreateDefaultQueue(intf_id, downstream);
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001506 }
1507
1508 return Status::OK;
1509}
1510
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001511/* Same as bcmolt_cfg_get but with added logic of retrying the API
1512 in case of some specific failures like timeout or object not yet ready
1513*/
1514bcmos_errno bcmolt_cfg_get_mult_retry(bcmolt_oltid olt, bcmolt_cfg *cfg) {
1515 bcmos_errno err;
1516 uint32_t current_try = 0;
1517
1518 while (current_try < MAX_BAL_API_RETRY_COUNT) {
1519 err = bcmolt_cfg_get(olt, cfg);
1520 current_try++;
1521
1522 if (err == BCM_ERR_STATE || err == BCM_ERR_TIMEOUT) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001523 OPENOLT_LOG(WARNING, openolt_log_id, "bcmolt_cfg_get: err = %s\n", bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001524 bcmos_usleep(BAL_API_RETRY_TIME_IN_USECS);
1525 continue;
1526 }
1527 else {
1528 break;
1529 }
1530 }
1531
1532 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001533 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 +00001534 current_try,
1535 BAL_API_RETRY_TIME_IN_USECS,
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001536 bcmos_strerror(err));
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001537 }
1538 return err;
1539}
1540
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001541Status ProbeDeviceCapabilities_() {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001542 bcmos_errno err;
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001543 bcmolt_device_cfg dev_cfg = { };
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001544 bcmolt_device_key dev_key = { };
1545 bcmolt_olt_cfg olt_cfg = { };
1546 bcmolt_olt_key olt_key = { };
1547 bcmolt_topology_map topo_map[BCM_MAX_PONS_PER_OLT] = { };
1548 bcmolt_topology topo = { };
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001549
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001550 topo.topology_maps.len = BCM_MAX_PONS_PER_OLT;
1551 topo.topology_maps.arr = &topo_map[0];
1552 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
1553 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
1554 BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001555 BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001556 sizeof(bcmolt_topology_map) * topo.topology_maps.len);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001557 #ifdef TEST_MODE
1558 // It is impossible to mock the setting of olt_cfg.data.bal_state because
1559 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
1560 // set the olt_cfg.data.topology. So a new stub function is created and address
1561 // of olt_cfg is passed. This is one-of case where we need to test add specific
1562 // code in production code.
1563 err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
1564 #else
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001565 err = bcmolt_cfg_get_mult_retry(dev_id, &olt_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001566 #endif
1567 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001568 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 +00001569 return bcm_to_grpc_err(err, "cfg: Failed to query OLT topology");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001570 }
1571
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001572 num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
1573 num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001574
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001575 OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
1576 olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001577 ? "up" : "down");
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001578
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001579 OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
1580 num_of_nni_ports,
1581 num_of_pon_ports,
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001582 BCM_MAX_DEVS_PER_LINE_CARD);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001583
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001584 uint32_t num_failed_cfg_gets = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001585 for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
1586 dev_key.device_id = devid;
1587 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
1588 BCMOLT_MSG_FIELD_GET(&dev_cfg, firmware_sw_version);
1589 BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
1590 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001591 err = bcmolt_cfg_get_mult_retry(dev_id, &dev_cfg.hdr);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001592 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001593 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 +00001594 num_failed_cfg_gets++;
1595 continue;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001596 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001597
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001598 std::string bal_version;
1599 bal_version += std::to_string(dev_cfg.data.firmware_sw_version.major)
1600 + "." + std::to_string(dev_cfg.data.firmware_sw_version.minor)
1601 + "." + std::to_string(dev_cfg.data.firmware_sw_version.revision);
1602 firmware_version = "BAL." + bal_version + "__" + firmware_version;
1603
1604 switch(dev_cfg.data.system_mode) {
1605 case 10: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"GPON"); break;
1606 case 11: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"GPON"); break;
1607 case 12: board_technology = "GPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"GPON"); break;
1608 case 13: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGPON"); break;
1609 case 14: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*4,(devid+1)*4,"XGPON"); break;
1610 case 15: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*8,(devid+1)*8,"XGPON"); break;
1611 case 16: board_technology = "XGPON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGPON"); break;
1612 case 18: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,"XGS-PON"); break;
1613 case 19: board_technology = "XGS-PON"; FILL_ARRAY(intf_technologies,devid*16,(devid+1)*16,"XGS-PON"); break;
1614 case 20: board_technology = MIXED_TECH; FILL_ARRAY(intf_technologies,devid*2,(devid+1)*2,MIXED_TECH); break;
1615 }
1616
1617 switch(dev_cfg.data.chip_family) {
1618 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6862_X_: chip_family = "Maple"; break;
1619 case BCMOLT_CHIP_FAMILY_CHIP_FAMILY_6865_X_: chip_family = "Aspen"; break;
1620 }
1621
1622 OPENOLT_LOG(INFO, openolt_log_id, "device %d, pon: %d, version %s object model: %d, family: %s, board_technology: %s\n",
1623 devid, BCM_MAX_PONS_PER_DEV, bal_version.c_str(), BAL_API_VERSION, chip_family.c_str(), board_technology.c_str());
1624
1625 bcmos_usleep(500000);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001626 }
1627
Amit Ghoshfcad4d32019-11-13 10:24:55 +00001628 /* If all the devices returned errors then we tell the caller that this is an error else we work with
1629 only the devices that retured success*/
1630 if (num_failed_cfg_gets == BCM_MAX_DEVS_PER_LINE_CARD) {
1631 OPENOLT_LOG(ERROR, openolt_log_id, "device: Query of all the devices failed\n");
1632 return bcm_to_grpc_err(err, "device: All devices failed query");
1633 }
1634
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001635 return Status::OK;
1636}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001637#if 0
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001638Status ProbePonIfTechnology_() {
1639 // Probe maximum extent possible as configured into BAL driver to determine
1640 // which are active in the current BAL topology. And for those
1641 // that are active, determine each port's access technology, i.e. "gpon" or "xgspon".
1642 for (uint32_t intf_id = 0; intf_id < num_of_pon_ports; ++intf_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001643 bcmolt_pon_interface_cfg interface_obj;
1644 bcmolt_pon_interface_key interface_key;
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001645
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001646 interface_key.pon_ni = intf_id;
1647 BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001648 if (board_technology == "XGS-PON"
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001649 BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
1650 else if (board_technology == "GPON")
1651 BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001652
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001653 bcmos_errno err = bcmolt_cfg_get(dev_id, &interface_obj.hdr);
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001654 if (err != BCM_ERR_OK) {
Craig Lutgenb2601f02018-10-23 13:04:31 -05001655 intf_technologies[intf_id] = UNKNOWN_TECH;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001656 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 -05001657 }
1658 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001659 if (board_technology == "XGS-PON") {
1660 switch(interface_obj.data.xgpon_trx.transceiver_type) {
1661 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_PC:
1662 case BCMOLT_XGPON_TRX_TYPE_WTD_RTXM266_702:
1663 case BCMOLT_XGPON_TRX_TYPE_LTH_7222_BC_PLUS:
1664 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_PC:
1665 case BCMOLT_XGPON_TRX_TYPE_LTH_5302_PC:
1666 case BCMOLT_XGPON_TRX_TYPE_LTH_7226_A_PC_PLUS:
1667 case BCMOLT_XGPON_TRX_TYPE_D272RR_SSCB_DM:
1668 intf_technologies[intf_id] = "XGS-PON";
1669 break;
1670 }
1671 } else if (board_technology == "GPON") {
1672 switch(interface_obj.data.gpon_trx.transceiver_type) {
1673 case BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013:
1674 case BCMOLT_TRX_TYPE_LTE_3680_M:
1675 case BCMOLT_TRX_TYPE_SOURCE_PHOTONICS:
1676 case BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS:
1677 case BCMOLT_TRX_TYPE_LTE_3680_P_BC:
1678 intf_technologies[intf_id] = "GPON";
1679 break;
1680 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001681 }
Craig Lutgenb2601f02018-10-23 13:04:31 -05001682
1683 if (board_technology != UNKNOWN_TECH) {
1684 board_technology = intf_technologies[intf_id];
1685 } else if (board_technology != MIXED_TECH && board_technology != intf_technologies[intf_id]) {
1686 intf_technologies[intf_id] = MIXED_TECH;
1687 }
1688
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001689 }
1690 }
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001691 return Status::OK;
1692}
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001693#endif
Craig Lutgen88a22ad2018-10-04 12:30:46 -05001694unsigned NumNniIf_() {return num_of_nni_ports;}
1695unsigned NumPonIf_() {return num_of_pon_ports;}
1696
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001697bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state) {
1698 bcmos_errno err;
1699 bcmolt_nni_interface_key nni_key;
1700 bcmolt_nni_interface_cfg nni_cfg;
1701 nni_key.id = id;
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001702
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001703 BCMOLT_CFG_INIT(&nni_cfg, nni_interface, nni_key);
1704 BCMOLT_FIELD_SET_PRESENT(&nni_cfg.data, nni_interface_cfg_data, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001705 #ifdef TEST_MODE
1706 // It is impossible to mock the setting of nni_cfg.data.state because
1707 // the actual bcmolt_cfg_get passes the address of nni_cfg.hdr and we cannot
1708 // set the nni_cfg.data.state. So a new stub function is created and address
1709 // of nni_cfg is passed. This is one-of case where we need to add test specific
1710 // code in production code.
1711 err = bcmolt_cfg_get__nni_intf_stub(dev_id, &nni_cfg);
1712 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001713 err = bcmolt_cfg_get(dev_id, &nni_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001714 #endif
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001715 *state = nni_cfg.data.state;
1716 return err;
1717}
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001718
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001719Status SetStateUplinkIf_(uint32_t intf_id, bool set_state) {
1720 bcmos_errno err = BCM_ERR_OK;
1721 bcmolt_nni_interface_key intf_key = {.id = (bcmolt_interface)intf_id};
1722 bcmolt_nni_interface_set_nni_state nni_interface_set_state;
1723 bcmolt_interface_state state;
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001724
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001725 err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001726 if (err == BCM_ERR_OK) {
1727 if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08001728 OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001729 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1730 CreateDefaultSched(intf_id, upstream);
1731 CreateDefaultQueue(intf_id, upstream);
1732 return Status::OK;
1733 } else if (!set_state && state == BCMOLT_INTERFACE_STATE_INACTIVE) {
1734 OPENOLT_LOG(INFO, openolt_log_id, "NNI interface: %d already disabled\n", intf_id);
1735 return Status::OK;
1736 }
Craig Lutgend0bae9b2018-10-18 18:02:07 -05001737 }
1738
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001739 BCMOLT_OPER_INIT(&nni_interface_set_state, nni_interface, set_nni_state, intf_key);
1740 if (set_state) {
1741 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1742 nni_state, BCMOLT_INTERFACE_OPERATION_ACTIVE_WORKING);
1743 } else {
1744 BCMOLT_FIELD_SET(&nni_interface_set_state.data, nni_interface_set_nni_state_data,
1745 nni_state, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1746 }
1747 err = bcmolt_oper_submit(dev_id, &nni_interface_set_state.hdr);
1748 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001749 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to %s NNI interface: %d, err = %s\n",
1750 (set_state)?"enable":"disable", intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001751 return bcm_to_grpc_err(err, "Failed to enable NNI interface");
1752 }
1753 else {
1754 OPENOLT_LOG(INFO, openolt_log_id, "Successfully %s NNI interface: %d\n", (set_state)?"enable":"disable", intf_id);
1755 if (set_state) {
1756 OPENOLT_LOG(INFO, openolt_log_id, "Initializing tm sched creation for NNI interface: %d\n", intf_id);
1757 CreateDefaultSched(intf_id, upstream);
1758 CreateDefaultQueue(intf_id, upstream);
1759 }
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -04001760 }
1761
1762 return Status::OK;
1763}
1764
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001765Status DisablePonIf_(uint32_t intf_id) {
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001766 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001767 bcmolt_pon_interface_cfg interface_obj;
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001768 bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
1769 bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001770
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001771 BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
1772 BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
1773 BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_DISABLE);
1774
1775 err = bcmolt_cfg_set(dev_id, &interface_obj.hdr);
1776 if (err != BCM_ERR_OK) {
1777 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to disable discovery of onu, PON interface %d, err %d\n", intf_id, err);
1778 return bcm_to_grpc_err(err, "Failed to disable discovery of onu");
1779 }
1780
1781 BCMOLT_FIELD_SET(&pon_interface_set_state.data, pon_interface_set_pon_interface_state_data,
1782 operation, BCMOLT_INTERFACE_OPERATION_INACTIVE);
1783
1784 err = bcmolt_oper_submit(dev_id, &pon_interface_set_state.hdr);
1785 if (err != BCM_ERR_OK) {
1786 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 -04001787 return bcm_to_grpc_err(err, "Failed to disable PON interface");
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001788 }
1789
Chaitrashree G S73e084d2019-11-20 16:18:59 -05001790 OPENOLT_LOG(INFO, openolt_log_id, "Successfully disabled PON interface: %d\n", intf_id);
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -04001791 return Status::OK;
1792}
1793
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001794Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001795 const char *vendor_id, const char *vendor_specific, uint32_t pir) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001796 bcmos_errno err = BCM_ERR_OK;
1797 bcmolt_onu_cfg onu_cfg;
1798 bcmolt_onu_key onu_key;
1799 bcmolt_serial_number serial_number; /**< ONU serial number */
1800 bcmolt_bin_str_36 registration_id; /**< ONU registration ID */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001801
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001802 onu_key.onu_id = onu_id;
1803 onu_key.pon_ni = intf_id;
1804 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1805 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001806 #ifdef TEST_MODE
1807 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1808 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1809 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1810 // of onu_cfg is passed. This is one-of case where we need to add test specific
1811 // code in production code.
1812 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
1813 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001814 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001815 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001816 if (err == BCM_ERR_OK) {
1817 if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001818 onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
1819 (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
1820 onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
1821 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001822 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001823
1824 OPENOLT_LOG(INFO, openolt_log_id, "Enabling ONU %d on PON %d : vendor id %s, \
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001825vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001826 vendor_specific_to_str(vendor_specific).c_str(), pir);
1827
1828 memcpy(serial_number.vendor_id.arr, vendor_id, 4);
1829 memcpy(serial_number.vendor_specific.arr, vendor_specific, 4);
1830 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1831 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.serial_number, serial_number);
1832 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.auto_learning, BCMOS_TRUE);
1833 /*set burst and data profiles to fec disabled*/
1834 if (board_technology == "XGS-PON") {
1835 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.ranging_burst_profile, 2);
1836 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.xgpon.data_burst_profile, 1);
1837 } else if (board_technology == "GPON") {
1838 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.ds_ber_reporting_interval, 1000000);
1839 BCMOLT_MSG_FIELD_SET(&onu_cfg, itu.gpon.omci_port_id, onu_id);
1840 }
1841 err = bcmolt_cfg_set(dev_id, &onu_cfg.hdr);
1842 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001843 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 +00001844 return bcm_to_grpc_err(err, "Failed to activate ONU");
1845 }
1846
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001847 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001848}
1849
Jonathan Davis70c21812018-07-19 15:32:10 -04001850Status DeactivateOnu_(uint32_t intf_id, uint32_t onu_id,
1851 const char *vendor_id, const char *vendor_specific) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001852 bcmos_errno err = BCM_ERR_OK;
1853 bcmolt_onu_set_onu_state onu_oper; /* declare main API struct */
1854 bcmolt_onu_cfg onu_cfg;
1855 bcmolt_onu_key onu_key; /**< Object key. */
1856 bcmolt_onu_state onu_state;
Jonathan Davis70c21812018-07-19 15:32:10 -04001857
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001858 onu_key.onu_id = onu_id;
1859 onu_key.pon_ni = intf_id;
1860 BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
1861 BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001862 #ifdef TEST_MODE
1863 // It is impossible to mock the setting of onu_cfg.data.onu_state because
1864 // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
1865 // set the onu_cfg.data.onu_state. So a new stub function is created and address
1866 // of onu_cfg is passed. This is one-of case where we need to add test specific
1867 // code in production code.
1868 err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
1869 onu_state = onu_cfg.data.onu_state;
1870 #else
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001871 err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001872 #endif
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001873 if (err == BCM_ERR_OK) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001874 switch (onu_state) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001875 case BCMOLT_ONU_STATE_ACTIVE:
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001876 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04001877 BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001878 onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
1879 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
1880 if (err != BCM_ERR_OK) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001881 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 +00001882 return bcm_to_grpc_err(err, "Failed to deactivate ONU");
1883 }
1884 break;
1885 }
Jonathan Davis70c21812018-07-19 15:32:10 -04001886 }
1887
1888 return Status::OK;
1889}
1890
1891Status DeleteOnu_(uint32_t intf_id, uint32_t onu_id,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001892 const char *vendor_id, const char *vendor_specific) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001893
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001894 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 -05001895 onu_id, intf_id, vendor_id, vendor_specific_to_str(vendor_specific).c_str());
1896
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001897 // Need to deactivate before removing it (BAL rules)
1898
1899 DeactivateOnu_(intf_id, onu_id, vendor_id, vendor_specific);
1900 // Sleep to allow the state to propagate
1901 // We need the subscriber terminal object to be admin down before removal
1902 // Without sleep the race condition is lost by ~ 20 ms
1903 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1904
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07001905 // TODO: Delete the schedulers and queues.
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04001906
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001907 bcmolt_onu_cfg cfg_obj;
1908 bcmolt_onu_key key;
Jonathan Davis70c21812018-07-19 15:32:10 -04001909
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001910 //OPENOLT_LOG(INFO, openolt_log_id, "Processing subscriber terminal cfg clear for sub_term_id %d and intf_id %d\n",
1911 // onu_id, intf_id);
1912 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 -04001913 onu_id, intf_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04001914
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001915 key.onu_id = onu_id;
1916 key.pon_ni = intf_id;
1917 BCMOLT_CFG_INIT(&cfg_obj, onu, key);
Jonathan Davis70c21812018-07-19 15:32:10 -04001918
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001919 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg_obj.hdr);
Jonathan Davis70c21812018-07-19 15:32:10 -04001920 if (err != BCM_ERR_OK)
1921 {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05001922 //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));
1923 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 -04001924 return Status(grpc::StatusCode::INTERNAL, "Failed to delete ONU");
1925 }
1926
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001927 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04001928}
1929
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001930#define MAX_CHAR_LENGTH 20
1931#define MAX_OMCI_MSG_LENGTH 44
1932Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001933 bcmolt_bin_str buf = {};
1934 bcmolt_onu_cpu_packets omci_cpu_packets;
1935 bcmolt_onu_key key;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001936
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001937 key.pon_ni = intf_id;
1938 key.onu_id = onu_id;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001939
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001940 BCMOLT_OPER_INIT(&omci_cpu_packets, onu, cpu_packets, key);
1941 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_OMCI);
1942 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, calc_crc, BCMOS_TRUE);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001943
1944 // ???
1945 if ((pkt.size()/2) > MAX_OMCI_MSG_LENGTH) {
1946 buf.len = MAX_OMCI_MSG_LENGTH;
1947 } else {
1948 buf.len = pkt.size()/2;
1949 }
1950
1951 /* Send the OMCI packet using the BAL remote proxy API */
1952 uint16_t idx1 = 0;
1953 uint16_t idx2 = 0;
1954 uint8_t arraySend[buf.len];
1955 char str1[MAX_CHAR_LENGTH];
1956 char str2[MAX_CHAR_LENGTH];
1957 memset(&arraySend, 0, buf.len);
1958
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001959 for (idx1=0,idx2=0; idx1<((buf.len)*2); idx1++,idx2++) {
1960 sprintf(str1,"%c", pkt[idx1]);
1961 sprintf(str2,"%c", pkt[++idx1]);
1962 strcat(str1,str2);
1963 arraySend[idx2] = strtol(str1, NULL, 16);
1964 }
1965
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001966 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
1967 memcpy(buf.arr, (uint8_t *)arraySend, buf.len);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001968
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001969 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, number_of_packets, 1);
1970 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, packet_size, buf.len);
1971 BCMOLT_MSG_FIELD_SET(&omci_cpu_packets, buffer, buf);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001972
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001973 bcmos_errno err = bcmolt_oper_submit(dev_id, &omci_cpu_packets.hdr);
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001974 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05001975 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 +00001976 return bcm_to_grpc_err(err, "send OMCI failed");
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001977 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001978 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 -05001979 buf.len, onu_id, intf_id, pkt.c_str());
Nicolas Palpacuer967438f2018-09-07 14:41:54 -04001980 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00001981 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001982
1983 return Status::OK;
1984}
1985
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001986Status 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 +00001987 bcmolt_pon_interface_cpu_packets pon_interface_cpu_packets; /**< declare main API struct */
1988 bcmolt_pon_interface_key key = {.pon_ni = (bcmolt_interface)intf_id}; /**< declare key */
1989 bcmolt_bin_str buf = {};
1990 bcmolt_gem_port_id gem_port_id_array[1];
1991 bcmolt_gem_port_id_list_u8_max_16 gem_port_list = {};
Shad Ansarib7b0ced2018-05-11 21:53:32 +00001992
Craig Lutgen967a1d02018-11-27 10:41:51 -06001993 if (port_no > 0) {
1994 bool found = false;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08001995 if (gemport_id == 0) {
1996 bcmos_fastlock_lock(&data_lock);
1997 // Map the port_no to one of the flows that owns it to find a gemport_id for that flow.
1998 // Pick any flow that is mapped with the same port_no.
1999 std::map<uint32_t, std::set<uint32_t> >::const_iterator it = port_to_flows.find(port_no);
2000 if (it != port_to_flows.end() && !it->second.empty()) {
2001 uint32_t flow_id = *(it->second.begin()); // Pick any flow_id out of the bag set
2002 std::map<uint32_t, uint32_t>::const_iterator fit = flowid_to_gemport.find(flow_id);
2003 if (fit != flowid_to_gemport.end()) {
2004 found = true;
2005 gemport_id = fit->second;
2006 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002007 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002008 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002009
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002010 if (!found) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002011 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 -08002012 onu_id, port_no, intf_id);
2013 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow for port_no");
2014 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002015 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 -08002016 gemport_id, onu_id, port_no, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002017 }
2018
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002019 gem_port_id_array[0] = gemport_id;
2020 gem_port_list.len = 1;
2021 gem_port_list.arr = gem_port_id_array;
2022 buf.len = pkt.size();
2023 buf.arr = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
2024 memcpy(buf.arr, (uint8_t *)pkt.data(), buf.len);
2025
2026 /* init the API struct */
2027 BCMOLT_OPER_INIT(&pon_interface_cpu_packets, pon_interface, cpu_packets, key);
2028 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, packet_type, BCMOLT_PACKET_TYPE_ETH);
2029 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, calc_crc, BCMOS_TRUE);
2030 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, gem_port_list, gem_port_list);
2031 BCMOLT_MSG_FIELD_SET(&pon_interface_cpu_packets, buffer, buf);
2032
2033 OPENOLT_LOG(INFO, openolt_log_id, "Packet out of length %d sent to gemport %d on pon %d port_no %u\n",
2034 (uint8_t)pkt.size(), gemport_id, intf_id, port_no);
2035
2036 /* call API */
2037 bcmolt_oper_submit(dev_id, &pon_interface_cpu_packets.hdr);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002038 }
2039 else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002040 //TODO: Port No is 0, it is coming sender requirement.
2041 OPENOLT_LOG(INFO, openolt_log_id, "port_no %d onu %d on pon %d\n",
2042 port_no, onu_id, intf_id);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002043 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002044 free(buf.arr);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002045
2046 return Status::OK;
2047}
2048
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002049Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002050 bcmolt_flow_key key = {}; /* declare key */
2051 bcmolt_bin_str buffer = {};
2052 bcmolt_flow_send_eth_packet oper; /* declare main API struct */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002053
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002054 // TODO: flow_id is currently not passed in UplinkPacket message from voltha.
2055 bcmolt_flow_id flow_id = 0;
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002056
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002057 //validate flow_id and find flow_id/flow type: upstream/ingress type: PON/egress type: NNI
2058 if (get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
2059 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
2060 get_flow_status(flow_id, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI)
2061 key.flow_id = flow_id;
2062 else {
2063 if (flow_id_counters != 0) {
2064 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2065 int flow_index = flow_id_data[flowid][0];
2066 if (get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, FLOW_TYPE) == BCMOLT_FLOW_TYPE_UPSTREAM && \
2067 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, INGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_PON && \
2068 get_flow_status(flow_index, BCMOLT_FLOW_TYPE_UPSTREAM, EGRESS_INTF_TYPE) == BCMOLT_FLOW_INTERFACE_TYPE_NNI) {
2069 key.flow_id = flow_index;
2070 break;
2071 }
2072 }
2073 }
2074 else {
Thiyagarajan Subramani81c56112019-12-19 08:29:55 -05002075 OPENOLT_LOG(ERROR, openolt_log_id, "no flow id found for uplink packetout\n");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002076 return grpc::Status(grpc::StatusCode::NOT_FOUND, "no flow id found");
2077 }
2078 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002079
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002080 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM; /* send from uplink direction */
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002081
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002082 /* Initialize the API struct. */
2083 BCMOLT_OPER_INIT(&oper, flow, send_eth_packet, key);
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002084
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002085 buffer.len = pkt.size();
2086 buffer.arr = (uint8_t *)malloc((buffer.len)*sizeof(uint8_t));
2087 memcpy(buffer.arr, (uint8_t *)pkt.data(), buffer.len);
2088 if (buffer.arr == NULL) {
2089 OPENOLT_LOG(ERROR, openolt_log_id, "allocate packet buffer failed\n");
2090 return bcm_to_grpc_err(BCM_ERR_PARM, "allocate packet buffer failed");
2091 }
2092 BCMOLT_FIELD_SET(&oper.data, flow_send_eth_packet_data, buffer, buffer);
2093
2094 bcmos_errno err = bcmolt_oper_submit(dev_id, &oper.hdr);
2095 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002096 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 -05002097 return bcm_to_grpc_err(BCM_ERR_SYSCALL_ERR, "Error sending packets via nni port");
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002098 } else {
2099 OPENOLT_LOG(INFO, openolt_log_id, "sent packets to port %d in upstream direction, flow_id %d \n", intf_id, key.flow_id);
2100 }
Nicolas Palpacuerb78def42018-06-07 12:55:26 -04002101
2102 return Status::OK;
2103}
2104
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002105uint32_t GetPortNum_(uint32_t flow_id) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002106 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002107 uint32_t port_no = 0;
2108 std::map<uint32_t, uint32_t >::const_iterator it = flowid_to_port.find(flow_id);
2109 if (it != flowid_to_port.end()) {
2110 port_no = it->second;
2111 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002112 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002113 return port_no;
2114}
2115
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002116#define FLOW_LOG(level,msg,err) \
2117 do { \
2118 OPENOLT_LOG(level, openolt_log_id, "--------> %s (flow_id %d) err: %d <--------\n", msg, key.flow_id, err); \
2119 OPENOLT_LOG(level, openolt_log_id, "intf_id %d, onu_id %d, uni_id %d, port_no %u, cookie %"PRIu64"\n", \
2120 access_intf_id, onu_id, uni_id, port_no, cookie); \
2121 OPENOLT_LOG(level, openolt_log_id, "flow_type %s, queue_id %d, sched_id %d\n", flow_type.c_str(), \
2122 cfg.data.egress_qos.u.fixed_queue.queue_id, cfg.data.egress_qos.tm_sched.id); \
2123 OPENOLT_LOG(level, openolt_log_id, "Ingress(intfd_type %s, intf_id %d), Egress(intf_type %s, intf_id %d)\n", \
2124 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), cfg.data.ingress_intf.intf_id, \
2125 GET_FLOW_INTERFACE_TYPE(cfg.data.egress_intf.intf_type), cfg.data.egress_intf.intf_id); \
2126 OPENOLT_LOG(level, openolt_log_id, "classifier(o_vid %d, o_pbits %d, i_vid %d, i_pbits %d, ether type 0x%x)\n", \
2127 c_val.o_vid, c_val.o_pbits, c_val.i_vid, c_val.i_pbits, classifier.eth_type()); \
2128 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", \
2129 c_val.ip_proto, gemport_id, c_val.src_port, c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
2130 OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
2131 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 -04002132 } while(0)
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002133
2134#define FLOW_PARAM_LOG() \
2135 do { \
2136 OPENOLT_LOG(INFO, openolt_log_id, "--------> flow comparison (now before) <--------\n"); \
2137 OPENOLT_LOG(INFO, openolt_log_id, "flow_id (%d %d)\n", \
2138 key.flow_id, flow_index); \
2139 OPENOLT_LOG(INFO, openolt_log_id, "onu_id (%d %lu)\n", \
2140 cfg.data.onu_id , get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)); \
2141 OPENOLT_LOG(INFO, openolt_log_id, "type (%d %lu)\n", \
2142 key.flow_type, get_flow_status(flow_index, flow_id_data[flowid][1], FLOW_TYPE)); \
2143 OPENOLT_LOG(INFO, openolt_log_id, "svc_port_id (%d %lu)\n", \
2144 cfg.data.svc_port_id, get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)); \
2145 OPENOLT_LOG(INFO, openolt_log_id, "priority (%d %lu)\n", \
2146 cfg.data.priority, get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)); \
2147 OPENOLT_LOG(INFO, openolt_log_id, "cookie (%lu %lu)\n", \
2148 cfg.data.cookie, get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)); \
2149 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf_type (%s %s)\n", \
2150 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type), \
2151 GET_FLOW_INTERFACE_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE))); \
2152 OPENOLT_LOG(INFO, openolt_log_id, "ingress intf id (%d %lu)\n", \
2153 cfg.data.ingress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)); \
2154 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_type (%d %lu)\n", \
2155 cfg.data.egress_intf.intf_type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)); \
2156 OPENOLT_LOG(INFO, openolt_log_id, "egress intf_id (%d %lu)\n", \
2157 cfg.data.egress_intf.intf_id , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)); \
2158 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_vid (%d %lu)\n", \
2159 c_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)); \
2160 OPENOLT_LOG(INFO, openolt_log_id, "classifier o_pbits (%d %lu)\n", \
2161 c_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)); \
2162 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_vid (%d %lu)\n", \
2163 c_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)); \
2164 OPENOLT_LOG(INFO, openolt_log_id, "classifier i_pbits (%d %lu)\n", \
2165 c_val.i_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)); \
2166 OPENOLT_LOG(INFO, openolt_log_id, "classifier ether_type (0x%x 0x%lx)\n", \
2167 c_val.ether_type , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)); \
2168 OPENOLT_LOG(INFO, openolt_log_id, "classifier ip_proto (%d %lu)\n", \
2169 c_val.ip_proto , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)); \
2170 OPENOLT_LOG(INFO, openolt_log_id, "classifier src_port (%d %lu)\n", \
2171 c_val.src_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)); \
2172 OPENOLT_LOG(INFO, openolt_log_id, "classifier dst_port (%d %lu)\n", \
2173 c_val.dst_port , get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)); \
2174 OPENOLT_LOG(INFO, openolt_log_id, "classifier pkt_tag_type (%s %s)\n", \
2175 GET_PKT_TAG_TYPE(c_val.pkt_tag_type), \
2176 GET_PKT_TAG_TYPE(get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE))); \
2177 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos type (%d %lu)\n", \
2178 cfg.data.egress_qos.type , get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)); \
2179 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos queue_id (%d %lu)\n", \
2180 cfg.data.egress_qos.u.fixed_queue.queue_id, \
2181 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)); \
2182 OPENOLT_LOG(INFO, openolt_log_id, "classifier egress_qos sched_id (%d %lu)\n", \
2183 cfg.data.egress_qos.tm_sched.id, \
2184 get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)); \
2185 OPENOLT_LOG(INFO, openolt_log_id, "classifier cmds_bitmask (%s %s)\n", \
2186 get_flow_acton_command(a_val.cmds_bitmask), \
2187 get_flow_acton_command(get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_CMDS_BITMASK))); \
2188 OPENOLT_LOG(INFO, openolt_log_id, "action o_vid (%d %lu)\n", \
2189 a_val.o_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)); \
2190 OPENOLT_LOG(INFO, openolt_log_id, "action i_vid (%d %lu)\n", \
2191 a_val.i_vid , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)); \
2192 OPENOLT_LOG(INFO, openolt_log_id, "action o_pbits (%d %lu)\n", \
2193 a_val.o_pbits , get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)); \
2194 OPENOLT_LOG(INFO, openolt_log_id, "action i_pbits (%d %lu)\n\n", \
2195 a_val.i_pbits, get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)); \
2196 } while(0)
2197
2198#define FLOW_CHECKER
2199//#define SHOW_FLOW_PARAM
2200
Craig Lutgen967a1d02018-11-27 10:41:51 -06002201Status 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 +00002202 uint32_t flow_id, const std::string flow_type,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002203 int32_t alloc_id, int32_t network_intf_id,
2204 int32_t gemport_id, const ::openolt::Classifier& classifier,
Craig Lutgen967a1d02018-11-27 10:41:51 -06002205 const ::openolt::Action& action, int32_t priority_value, uint64_t cookie) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002206 bcmolt_flow_cfg cfg;
2207 bcmolt_flow_key key = { }; /**< Object key. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002208 int32_t o_vid = -1;
2209 bool single_tag = false;
2210 uint32_t ether_type = 0;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002211 bcmolt_classifier c_val = { };
2212 bcmolt_action a_val = { };
2213 bcmolt_tm_queue_ref tm_val = { };
2214 int tm_qmp_id, tm_q_set_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002215 bcmolt_egress_qos_type qos_type;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002216
2217 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002218 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002219 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002220 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002221 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002222 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002223 OPENOLT_LOG(ERROR, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacuer73222e02018-07-16 12:20:26 -04002224 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002225 }
2226
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002227 BCMOLT_CFG_INIT(&cfg, flow, key);
2228 BCMOLT_MSG_FIELD_SET(&cfg, cookie, cookie);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002229
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002230 if (access_intf_id >= 0 && network_intf_id >= 0) {
2231 if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) { //upstream
2232 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2233 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, access_intf_id);
2234 if (classifier.eth_type() == EAP_ETHER_TYPE || //EAPOL packet
2235 (classifier.ip_proto() == 17 && classifier.src_port() == 68 && classifier.dst_port() == 67)) { //DHCP packet
2236 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
2237 } else {
2238 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2239 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, network_intf_id);
2240 }
2241 } else if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) { //downstream
2242 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2243 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2244 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_PON);
2245 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_id, access_intf_id);
2246 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302247 } else if (access_intf_id < 0 ) {
2248 // This is the case for packet trap from NNI flow.
2249 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_NNI);
2250 BCMOLT_MSG_FIELD_SET(&cfg, ingress_intf.intf_id, network_intf_id);
2251 BCMOLT_MSG_FIELD_SET(&cfg, egress_intf.intf_type, BCMOLT_FLOW_INTERFACE_TYPE_HOST);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002252 } else {
2253 OPENOLT_LOG(ERROR, openolt_log_id, "flow network setting invalid\n");
2254 return bcm_to_grpc_err(BCM_ERR_PARM, "flow network setting invalid");
2255 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002256
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302257
Shad Ansari39739bc2018-09-13 21:38:37 +00002258 if (onu_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002259 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002260 }
2261 if (gemport_id >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002262 BCMOLT_MSG_FIELD_SET(&cfg, svc_port_id, gemport_id);
Shad Ansari39739bc2018-09-13 21:38:37 +00002263 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06002264 if (gemport_id >= 0 && port_no != 0) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002265 bcmos_fastlock_lock(&data_lock);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002266 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002267 port_to_flows[port_no].insert(key.flow_id);
2268 flowid_to_gemport[key.flow_id] = gemport_id;
2269 }
2270 else
2271 {
2272 flowid_to_port[key.flow_id] = port_no;
2273 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002274 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002275 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002276 if (priority_value >= 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002277 BCMOLT_MSG_FIELD_SET(&cfg, priority, priority_value);
Shad Ansari39739bc2018-09-13 21:38:37 +00002278 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002279
2280 {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002281 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002282 if (classifier.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002283 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_tpid 0x%04x\n", classifier.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002284 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, o_tpid, classifier.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002285 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002286 */
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002287 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002288 if (classifier.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002289 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_tpid 0x%04x\n", classifier.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002290 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, i_tpid, classifier.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002291 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002292 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002293
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002294 if (classifier.eth_type()) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002295 ether_type = classifier.eth_type();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002296 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ether_type 0x%04x\n", classifier.eth_type());
2297 BCMOLT_FIELD_SET(&c_val, classifier, ether_type, classifier.eth_type());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002298 }
2299
2300 /*
2301 if (classifier.dst_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002302 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_mac, classifier.dst_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002303 }
2304
2305 if (classifier.src_mac()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002306 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_mac, classifier.src_mac());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002307 }
2308 */
2309
2310 if (classifier.ip_proto()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002311 OPENOLT_LOG(DEBUG, openolt_log_id, "classify ip_proto %d\n", classifier.ip_proto());
2312 BCMOLT_FIELD_SET(&c_val, classifier, ip_proto, classifier.ip_proto());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002313 }
2314
2315 /*
2316 if (classifier.dst_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002317 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, dst_ip, classifier.dst_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002318 }
2319
2320 if (classifier.src_ip()) {
Craig Lutgen19512312018-11-02 10:14:46 -05002321 BCMBAL_ATTRIBUTE_PROP_SET(&val, classifier, src_ip, classifier.src_ip());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002322 }
2323 */
2324
2325 if (classifier.src_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002326 OPENOLT_LOG(DEBUG, openolt_log_id, "classify src_port %d\n", classifier.src_port());
2327 BCMOLT_FIELD_SET(&c_val, classifier, src_port, classifier.src_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002328 }
2329
2330 if (classifier.dst_port()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002331 OPENOLT_LOG(DEBUG, openolt_log_id, "classify dst_port %d\n", classifier.dst_port());
2332 BCMOLT_FIELD_SET(&c_val, classifier, dst_port, classifier.dst_port());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002333 }
2334
2335 if (!classifier.pkt_tag_type().empty()) {
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302336 if (cfg.data.ingress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_NNI && \
2337 cfg.data.egress_intf.intf_type == BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
2338 // This is case where packet traps from NNI port. As per Broadcom workaround
2339 // suggested in CS8839882, the packet_tag_type has to be 'untagged' irrespective
2340 // of what the actual tag type is. Otherwise, packet trap from NNI wont work.
2341 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2342 } else {
2343 if (classifier.o_vid()) {
2344 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_vid %d\n", classifier.o_vid());
2345 BCMOLT_FIELD_SET(&c_val, classifier, o_vid, classifier.o_vid());
2346 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002347
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302348 if (classifier.i_vid()) {
2349 OPENOLT_LOG(DEBUG, openolt_log_id, "classify i_vid %d\n", classifier.i_vid());
2350 BCMOLT_FIELD_SET(&c_val, classifier, i_vid, classifier.i_vid());
2351 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002352
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302353 OPENOLT_LOG(DEBUG, openolt_log_id, "classify tag_type %s\n", classifier.pkt_tag_type().c_str());
2354 if (classifier.pkt_tag_type().compare("untagged") == 0) {
2355 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_UNTAGGED);
2356 } else if (classifier.pkt_tag_type().compare("single_tag") == 0) {
2357 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_SINGLE_TAG);
2358 single_tag = true;
2359
2360 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002361 if(classifier.o_pbits()){
2362 //According to makeOpenOltClassifierField in voltha-openolt-adapter, o_pbits 0xFF means PCP value 0.
2363 //0 vlaue of o_pbits means o_pbits is not available
2364 if(0xFF == classifier.o_pbits()){
2365 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2366 }
2367 else{
2368 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2369 }
2370 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302371 } else if (classifier.pkt_tag_type().compare("double_tag") == 0) {
2372 BCMOLT_FIELD_SET(&c_val, classifier, pkt_tag_type, BCMOLT_PKT_TAG_TYPE_DOUBLE_TAG);
2373
2374 OPENOLT_LOG(DEBUG, openolt_log_id, "classify o_pbits 0x%x\n", classifier.o_pbits());
YJbbeeff42019-11-21 16:22:50 -05002375 if(classifier.o_pbits()){
2376 if(0xFF == classifier.o_pbits()){
2377 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, 0);
2378 }
2379 else{
2380 BCMOLT_FIELD_SET(&c_val, classifier, o_pbits, classifier.o_pbits());
2381 }
2382 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302383 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002384 }
2385 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002386 BCMOLT_MSG_FIELD_SET(&cfg, classifier, c_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002387 }
2388
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002389 if (cfg.data.egress_intf.intf_type != BCMOLT_FLOW_INTERFACE_TYPE_HOST) {
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002390 const ::openolt::ActionCmd& cmd = action.cmd();
2391
2392 if (cmd.add_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002393 OPENOLT_LOG(DEBUG, openolt_log_id, "action add o_tag\n");
2394 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_ADD_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002395 }
2396
2397 if (cmd.remove_outer_tag()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002398 OPENOLT_LOG(DEBUG, openolt_log_id, "action pop o_tag\n");
2399 BCMOLT_FIELD_SET(&a_val, action, cmds_bitmask, BCMOLT_ACTION_CMD_ID_REMOVE_OUTER_TAG);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002400 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002401 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002402 if (cmd.trap_to_host()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002403 OPENOLT_LOG(INFO, openolt_log_id, "action trap-to-host\n");
Craig Lutgen19512312018-11-02 10:14:46 -05002404 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, cmds_bitmask, BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002405 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002406 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002407 if (action.o_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002408 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_vid=%d\n", action.o_vid());
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002409 o_vid = action.o_vid();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002410 BCMOLT_FIELD_SET(&a_val, action, o_vid, action.o_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002411 }
2412
2413 if (action.o_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002414 OPENOLT_LOG(DEBUG, openolt_log_id, "action o_pbits=0x%x\n", action.o_pbits());
2415 BCMOLT_FIELD_SET(&a_val, action, o_pbits, action.o_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002416 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002417 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002418 if (action.o_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002419 OPENOLT_LOG(INFO, openolt_log_id, "action o_tpid=0x%04x\n", action.o_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002420 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, o_tpid, action.o_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002421 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002422 */
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002423 if (action.i_vid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002424 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_vid=%d\n", action.i_vid());
2425 BCMOLT_FIELD_SET(&a_val, action, i_vid, action.i_vid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002426 }
2427
2428 if (action.i_pbits()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002429 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_pbits=0x%x\n", action.i_pbits());
2430 BCMOLT_FIELD_SET(&a_val, action, i_pbits, action.i_pbits());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002431 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002432 /* removed by BAL v3.0
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002433 if (action.i_tpid()) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002434 OPENOLT_LOG(DEBUG, openolt_log_id, "action i_tpid=0x%04x\n", action.i_tpid());
Craig Lutgen19512312018-11-02 10:14:46 -05002435 BCMBAL_ATTRIBUTE_PROP_SET(&val, action, i_tpid, action.i_tpid());
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002436 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002437 */
2438 BCMOLT_MSG_FIELD_SET(&cfg, action, a_val);
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002439 }
2440
Shad Ansari39739bc2018-09-13 21:38:37 +00002441 if ((access_intf_id >= 0) && (onu_id >= 0)) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002442 if(single_tag && ether_type == EAP_ETHER_TYPE) {
2443 tm_val.sched_id = (flow_type.compare(upstream) == 0) ? \
2444 get_default_tm_sched_id(network_intf_id, upstream) : \
2445 get_default_tm_sched_id(access_intf_id, downstream);
2446 tm_val.queue_id = 0;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002447
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002448 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2449 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2450 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002451
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002452 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2453 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2454 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2455 } else {
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05002456 qos_type = get_qos_type(access_intf_id, onu_id, uni_id);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002457 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
2458 tm_val.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, downstream);
2459
2460 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2461 // Queue 0 on DS subscriber scheduler
2462 tm_val.queue_id = 0;
2463
2464 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2465 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2466 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2467
2468 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2469 downstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2470 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2471
2472 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2473 /* Fetch TM QMP ID mapped to DS subscriber scheduler */
2474 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2475
2476 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2477 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2478 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2479 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2480
2481 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2482 downstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2483 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2484 }
2485 } else if (key.flow_type == BCMOLT_FLOW_TYPE_UPSTREAM) {
2486 // NNI Scheduler ID
2487 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2488 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
2489 // Queue 0 on NNI scheduler
2490 tm_val.queue_id = 0;
2491 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2492 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2493 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2494
2495 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2496 upstream.c_str(), tm_val.queue_id, tm_val.sched_id, \
2497 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2498
2499 } else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
2500 /* Fetch TM QMP ID mapped to US NNI scheduler */
2501 tm_qmp_id = tm_q_set_id = get_tm_qmp_id(tm_val.sched_id, access_intf_id, onu_id, uni_id);
2502 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, qos_type);
2503 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2504 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_qmp_id, tm_qmp_id);
2505 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.priority_to_queue.tm_q_set_id, tm_q_set_id);
2506
2507 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, q_set_id = %d, sched_id = %d, intf_type %s\n", \
2508 upstream.c_str(), tm_q_set_id, tm_val.sched_id, \
2509 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
2510 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002511 }
Shad Ansari39739bc2018-09-13 21:38:37 +00002512 }
Girish Gowdra80b0fb92019-11-15 11:40:39 +05302513 } else {
2514 tm_val.sched_id = get_default_tm_sched_id(network_intf_id, upstream);
2515 tm_val.queue_id = 0;
2516
2517 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.type, BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE);
2518 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.tm_sched.id, tm_val.sched_id);
2519 BCMOLT_MSG_FIELD_SET(&cfg , egress_qos.u.fixed_queue.queue_id, tm_val.queue_id);
2520
2521 OPENOLT_LOG(DEBUG, openolt_log_id, "direction = %s, queue_id = %d, sched_id = %d, intf_type %s\n", \
2522 flow_type.c_str(), tm_val.queue_id, tm_val.sched_id, \
2523 GET_FLOW_INTERFACE_TYPE(cfg.data.ingress_intf.intf_type));
Shad Ansari06101952018-07-25 00:22:09 +00002524 }
2525
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002526 BCMOLT_MSG_FIELD_SET(&cfg, state, BCMOLT_FLOW_STATE_ENABLE);
2527 BCMOLT_MSG_FIELD_SET(&cfg, statistics, BCMOLT_CONTROL_STATE_ENABLE);
2528#ifdef FLOW_CHECKER
2529 //Flow Checker, To avoid duplicate flow.
2530 if (flow_id_counters != 0) {
2531 bool b_duplicate_flow = false;
2532 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2533 int flow_index = flow_id_data[flowid][0];
2534 b_duplicate_flow = (cfg.data.onu_id == get_flow_status(flow_index, flow_id_data[flowid][1], ONU_ID)) && \
2535 (key.flow_type == flow_id_data[flowid][1]) && \
2536 (cfg.data.svc_port_id == get_flow_status(flow_index, flow_id_data[flowid][1], SVC_PORT_ID)) && \
2537 (cfg.data.priority == get_flow_status(flow_index, flow_id_data[flowid][1], PRIORITY)) && \
2538 (cfg.data.cookie == get_flow_status(flow_index, flow_id_data[flowid][1], COOKIE)) && \
2539 (cfg.data.ingress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_TYPE)) && \
2540 (cfg.data.ingress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], INGRESS_INTF_ID)) && \
2541 (cfg.data.egress_intf.intf_type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_TYPE)) && \
2542 (cfg.data.egress_intf.intf_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_INTF_ID)) && \
2543 (c_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_VID)) && \
2544 (c_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_O_PBITS)) && \
2545 (c_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_VID)) && \
2546 (c_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_I_PBITS)) && \
2547 (c_val.ether_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_ETHER_TYPE)) && \
2548 (c_val.ip_proto == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_IP_PROTO)) && \
2549 (c_val.src_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_SRC_PORT)) && \
2550 (c_val.dst_port == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_DST_PORT)) && \
2551 (c_val.pkt_tag_type == get_flow_status(flow_index, flow_id_data[flowid][1], CLASSIFIER_PKT_TAG_TYPE)) && \
2552 (cfg.data.egress_qos.type == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TYPE)) && \
2553 (cfg.data.egress_qos.u.fixed_queue.queue_id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_QUEUE_ID)) && \
2554 (cfg.data.egress_qos.tm_sched.id == get_flow_status(flow_index, flow_id_data[flowid][1], EGRESS_QOS_TM_SCHED_ID)) && \
2555 (a_val.cmds_bitmask == get_flow_status(flowid, flow_id_data[flowid][1], ACTION_CMDS_BITMASK)) && \
2556 (a_val.o_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_VID)) && \
2557 (a_val.i_vid == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_VID)) && \
2558 (a_val.o_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_O_PBITS)) && \
2559 (a_val.i_pbits == get_flow_status(flow_index, flow_id_data[flowid][1], ACTION_I_PBITS)) && \
2560 (cfg.data.state == get_flow_status(flowid, flow_id_data[flowid][1], STATE));
2561#ifdef SHOW_FLOW_PARAM
2562 // Flow Parameter
2563 FLOW_PARAM_LOG();
2564#endif
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002565
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002566 if (b_duplicate_flow) {
2567 FLOW_LOG(WARNING, "Flow duplicate", 0);
2568 return bcm_to_grpc_err(BCM_ERR_ALREADY, "flow exists");
2569 }
2570 }
2571 }
2572#endif
2573
2574 bcmos_errno err = bcmolt_cfg_set(dev_id, &cfg.hdr);
2575 if (err) {
2576 FLOW_LOG(ERROR, "Flow add failed", err);
2577 return bcm_to_grpc_err(err, "flow add failed");
2578 } else {
2579 FLOW_LOG(INFO, "Flow add ok", err);
2580 bcmos_fastlock_lock(&data_lock);
2581 flow_id_data[flow_id_counters][0] = key.flow_id;
2582 flow_id_data[flow_id_counters][1] = key.flow_type;
2583 flow_id_counters += 1;
2584 bcmos_fastlock_unlock(&data_lock, 0);
2585 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -04002586
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002587 return Status::OK;
2588}
2589
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002590Status FlowRemove_(uint32_t flow_id, const std::string flow_type) {
2591
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002592 bcmolt_flow_cfg cfg;
2593 bcmolt_flow_key key = { };
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002594
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002595 key.flow_id = (bcmolt_flow_id) flow_id;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002596 key.flow_id = flow_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002597 if (flow_type.compare(upstream) == 0 ) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002598 key.flow_type = BCMOLT_FLOW_TYPE_UPSTREAM;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002599 } else if (flow_type.compare(downstream) == 0) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002600 key.flow_type = BCMOLT_FLOW_TYPE_DOWNSTREAM;
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002601 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002602 OPENOLT_LOG(WARNING, openolt_log_id, "Invalid flow type %s\n", flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002603 return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
2604 }
2605
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002606 bcmos_fastlock_lock(&data_lock);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002607 uint32_t port_no = flowid_to_port[key.flow_id];
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002608 if (key.flow_type == BCMOLT_FLOW_TYPE_DOWNSTREAM) {
Craig Lutgen967a1d02018-11-27 10:41:51 -06002609 flowid_to_gemport.erase(key.flow_id);
2610 port_to_flows[port_no].erase(key.flow_id);
2611 if (port_to_flows[port_no].empty()) port_to_flows.erase(port_no);
2612 }
2613 else
2614 {
2615 flowid_to_port.erase(key.flow_id);
2616 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002617 bcmos_fastlock_unlock(&data_lock, 0);
Craig Lutgen967a1d02018-11-27 10:41:51 -06002618
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002619 BCMOLT_CFG_INIT(&cfg, flow, key);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002620
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002621 bcmos_errno err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002622 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002623 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 -04002624 return Status(grpc::StatusCode::INTERNAL, "Failed to remove flow");
2625 }
2626
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002627 bcmos_fastlock_lock(&data_lock);
2628 for (int flowid=0; flowid < flow_id_counters; flowid++) {
2629 if (flow_id_data[flowid][0] == flow_id && flow_id_data[flowid][1] == key.flow_type) {
2630 flow_id_counters -= 1;
2631 for (int i=flowid; i < flow_id_counters; i++) {
2632 flow_id_data[i][0] = flow_id_data[i + 1][0];
2633 flow_id_data[i][1] = flow_id_data[i + 1][1];
2634 }
2635 break;
2636 }
2637 }
2638 bcmos_fastlock_unlock(&data_lock, 0);
2639
2640 OPENOLT_LOG(INFO, openolt_log_id, "Flow %d, %s removed\n", flow_id, flow_type.c_str());
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -04002641 return Status::OK;
2642}
2643
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002644bcmos_errno CreateDefaultSched(uint32_t intf_id, const std::string direction) {
2645 bcmos_errno err;
2646 bcmolt_tm_sched_cfg tm_sched_cfg;
2647 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2648 tm_sched_key.id = get_default_tm_sched_id(intf_id, direction);
2649
Jason Huangbf45ffb2019-10-30 17:29:02 +08002650 //check TM scheduler has configured or not
2651 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2652 BCMOLT_MSG_FIELD_GET(&tm_sched_cfg, state);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002653 #ifdef TEST_MODE
2654 // It is impossible to mock the setting of tm_sched_cfg.data.state because
2655 // the actual bcmolt_cfg_get passes the address of tm_sched_cfg.hdr and we cannot
2656 // set the tm_sched_cfg.data.state. So a new stub function is created and address
2657 // of tm_sched_cfg is passed. This is one-of case where we need to add test specific
2658 // code in production code.
2659 err = bcmolt_cfg_get__tm_sched_stub(dev_id, &tm_sched_cfg);
2660 #else
Jason Huangbf45ffb2019-10-30 17:29:02 +08002661 err = bcmolt_cfg_get(dev_id, &tm_sched_cfg.hdr);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002662 #endif
Jason Huangbf45ffb2019-10-30 17:29:02 +08002663 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002664 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 +08002665 return err;
2666 }
2667 else if (tm_sched_cfg.data.state == BCMOLT_CONFIG_STATE_CONFIGURED) {
2668 OPENOLT_LOG(WARNING, openolt_log_id, "tm scheduler default config has already with id %d\n", tm_sched_key.id);
2669 return BCM_ERR_OK;
2670 }
2671
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002672 // bcmbal_tm_sched_owner
2673 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
2674
2675 /**< The output of the tm_sched object instance */
2676 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_INTERFACE);
2677
2678 if (direction.compare(upstream) == 0) {
2679 // In upstream it is NNI scheduler
2680 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_NNI);
2681 } else if (direction.compare(downstream) == 0) {
2682 // In downstream it is PON scheduler
2683 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_type, BCMOLT_INTERFACE_TYPE_PON);
2684 }
2685
2686 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.interface.interface_ref.intf_id, intf_id);
2687
2688 // bcmbal_tm_sched_type
2689 // set the deafult policy to strict priority
2690 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
2691
2692 // num_priorities: Max number of strict priority scheduling elements
2693 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
2694
2695 // bcmbal_tm_shaping
2696 uint32_t cir = 1000000;
2697 uint32_t pir = 1000000;
2698 uint32_t burst = 65536;
2699 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in %s pir=%u, burst=%u\n",
2700 direction.c_str(), pir, burst);
2701 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2702 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2703 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2704 // BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2705 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2706 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
2707
2708 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
2709 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002710 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create %s scheduler, id %d, intf_id %d, err = %s\n",
2711 direction.c_str(), tm_sched_key.id, intf_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002712 return err;
2713 }
2714
2715 OPENOLT_LOG(INFO, openolt_log_id, "Create %s scheduler success, id %d, intf_id %d\n", \
2716 direction.c_str(), tm_sched_key.id, intf_id);
2717 return BCM_ERR_OK;
2718}
2719
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002720bcmos_errno CreateSched(std::string direction, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t port_no,
2721 uint32_t alloc_id, tech_profile::AdditionalBW additional_bw, uint32_t weight, uint32_t priority,
2722 tech_profile::SchedulingPolicy sched_policy, tech_profile::TrafficShapingInfo tf_sh_info) {
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002723
2724 bcmos_errno err;
2725
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002726 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002727 bcmolt_tm_sched_cfg tm_sched_cfg;
2728 bcmolt_tm_sched_key tm_sched_key = {.id = 1};
2729 tm_sched_key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002730
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002731 // bcmbal_tm_sched_owner
2732 // In downstream it is sub_term scheduler
2733 BCMOLT_CFG_INIT(&tm_sched_cfg, tm_sched, tm_sched_key);
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002734
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002735 /**< The output of the tm_sched object instance */
2736 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.type, BCMOLT_TM_SCHED_OUTPUT_TYPE_TM_SCHED);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002737
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002738 // bcmbal_tm_sched_parent
2739 // The parent for the sub_term scheduler is the PON scheduler in the downstream
2740 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_id, get_default_tm_sched_id(intf_id, direction));
2741 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, attachment_point.u.tm_sched.tm_sched_param.u.priority.priority, priority);
2742 /* removed by BAL v3.0, N/A - No direct attachment point of type ONU, same functionality may
2743 be achieved using the' virtual' type of attachment.
2744 tm_sched_owner.u.sub_term.intf_id = intf_id;
2745 tm_sched_owner.u.sub_term.sub_term_id = onu_id;
2746 */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002747
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002748 // bcmbal_tm_sched_type
2749 // set the deafult policy to strict priority
2750 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, sched_type, BCMOLT_TM_SCHED_TYPE_SP);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002751
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002752 // num_priorities: Max number of strict priority scheduling elements
2753 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, num_priorities, 8);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002754
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002755 // bcmbal_tm_shaping
2756 if (tf_sh_info.cir() >= 0 && tf_sh_info.pir() > 0) {
2757 uint32_t cir = tf_sh_info.cir();
2758 uint32_t pir = tf_sh_info.pir();
2759 uint32_t burst = tf_sh_info.pbs();
2760 OPENOLT_LOG(INFO, openolt_log_id, "applying traffic shaping in DL cir=%u, pir=%u, burst=%u\n",
2761 cir, pir, burst);
2762 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, pir);
2763 BCMOLT_FIELD_SET_PRESENT(&tm_sched_cfg.data.rate, tm_shaping, burst);
2764 // FIXME: Setting CIR, results in BAL throwing error 'tm_sched minimum rate is not supported yet'
2765 //BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.cir, cir);
2766 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.pir, pir);
2767 BCMOLT_MSG_FIELD_SET(&tm_sched_cfg, rate.burst, burst);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002768 }
2769
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002770 err = bcmolt_cfg_set(dev_id, &tm_sched_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002771 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002772 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create downstream subscriber scheduler, id %d, \
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002773intf_id %d, onu_id %d, uni_id %d, port_no %u, err = %s\n", tm_sched_key.id, intf_id, onu_id, uni_id, \
2774port_no, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002775 return err;
2776 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002777 OPENOLT_LOG(INFO, openolt_log_id, "Create downstream subscriber sched, id %d, intf_id %d, onu_id %d, \
2778uni_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 -08002779
2780 } else { //upstream
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002781 bcmolt_itupon_alloc_cfg cfg;
2782 bcmolt_itupon_alloc_key key = { };
2783 key.pon_ni = intf_id;
2784 key.alloc_id = alloc_id;
2785 int bw_granularity = (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY;
2786 int pir_bw = tf_sh_info.pir();
2787 int cir_bw = tf_sh_info.cir();
2788 //offset to match bandwidth granularity
2789 int offset_pir_bw = pir_bw%bw_granularity;
2790 int offset_cir_bw = cir_bw%bw_granularity;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002791
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002792 pir_bw = pir_bw - offset_pir_bw;
2793 cir_bw = cir_bw - offset_cir_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002794
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002795 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002796
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002797 switch (additional_bw) {
2798 case 2: //AdditionalBW_BestEffort
2799 if (pir_bw == 0) {
2800 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2801%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002802 return BCM_ERR_PARM;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002803 } else if (pir_bw < cir_bw) {
2804 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2805bandwidth (%d)\n", pir_bw, cir_bw);
2806 return BCM_ERR_PARM;
2807 } else if (pir_bw == cir_bw) {
2808 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2809bandwidth for additional bandwidth eligibility of type best_effort\n");
2810 return BCM_ERR_PARM;
2811 }
2812 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_BEST_EFFORT);
2813 break;
2814 case 1: //AdditionalBW_NA
2815 if (pir_bw == 0) {
2816 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
2817%d bytes/sec\n", (board_technology == "XGS-PON")?XGS_BANDWIDTH_GRANULARITY:GPON_BANDWIDTH_GRANULARITY);
2818 return BCM_ERR_PARM;
2819 } else if (cir_bw == 0) {
2820 OPENOLT_LOG(ERROR, openolt_log_id, "Guaranteed bandwidth must be greater than zero for \
2821additional bandwidth eligibility of type Non-Assured (NA)\n");
2822 return BCM_ERR_PARM;
2823 } else if (pir_bw < cir_bw) {
2824 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2825bandwidth (%d)\n", pir_bw, cir_bw);
2826 return BCM_ERR_PARM;
2827 } else if (pir_bw == cir_bw) {
2828 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be greater than Guaranteed \
2829bandwidth for additional bandwidth eligibility of type non_assured\n");
2830 return BCM_ERR_PARM;
2831 }
2832 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NON_ASSURED);
2833 break;
2834 case 0: //AdditionalBW_None
2835 if (pir_bw == 0) {
2836 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth was set to 0, must be at least \
283716000 bytes/sec\n");
2838 return BCM_ERR_PARM;
2839 } else if (cir_bw == 0) {
2840 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2841for additional bandwidth eligibility of type None\n");
2842 return BCM_ERR_PARM;
2843 } else if (pir_bw > cir_bw) {
2844 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth must be equal to Guaranteed bandwidth \
2845for additional bandwidth eligibility of type None\n");
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002846 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002847bandwidth in None eligibility\n", pir_bw);
2848 cir_bw = pir_bw;
2849 } else if (pir_bw < cir_bw) {
2850 OPENOLT_LOG(ERROR, openolt_log_id, "Maximum bandwidth (%d) can't be less than Guaranteed \
2851bandwidth (%d)\n", pir_bw, cir_bw);
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05002852 OPENOLT_LOG(ERROR, openolt_log_id, "Setting Maximum bandwidth (%d) to Guaranteed \
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002853bandwidth in None eligibility\n", pir_bw);
2854 cir_bw = pir_bw;
2855 }
2856 BCMOLT_MSG_FIELD_SET(&cfg, sla.additional_bw_eligibility, BCMOLT_ADDITIONAL_BW_ELIGIBILITY_NONE);
2857 break;
2858 default:
2859 return BCM_ERR_PARM;
Girish Gowdrue075c642019-01-23 04:05:53 -08002860 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002861 /* CBR Real Time Bandwidth which require shaping of the bandwidth allocations
2862 in a fine granularity. */
2863 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_bw, 0);
2864 /* Fixed Bandwidth with no critical requirement of shaping */
2865 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_bw, 0);
2866 /* Dynamic bandwidth which the OLT is committed to allocate upon demand */
2867 BCMOLT_MSG_FIELD_SET(&cfg, sla.guaranteed_bw, cir_bw);
2868 /* Maximum allocated bandwidth allowed for this alloc ID */
2869 BCMOLT_MSG_FIELD_SET(&cfg, sla.maximum_bw, pir_bw);
2870 BCMOLT_MSG_FIELD_SET(&cfg, sla.alloc_type, BCMOLT_ALLOC_TYPE_NSR);
2871 /* Set to True for AllocID with CBR RT Bandwidth that requires compensation
2872 for skipped allocations during quiet window */
2873 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_compensation, BCMOS_FALSE);
2874 /**< Allocation Profile index for CBR non-RT Bandwidth */
2875 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_nrt_ap_index, 0);
2876 /**< Allocation Profile index for CBR RT Bandwidth */
2877 BCMOLT_MSG_FIELD_SET(&cfg, sla.cbr_rt_ap_index, 0);
2878 /**< Alloc ID Weight used in case of Extended DBA mode */
2879 BCMOLT_MSG_FIELD_SET(&cfg, sla.weight, 0);
2880 /**< Alloc ID Priority used in case of Extended DBA mode */
2881 BCMOLT_MSG_FIELD_SET(&cfg, sla.priority, 0);
2882 BCMOLT_MSG_FIELD_SET(&cfg, onu_id, onu_id);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002883
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002884 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002885 if (err) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002886 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 -05002887port_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 -08002888 return err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002889 }
Girish Gowdra96461052019-11-22 20:13:59 +05302890
2891 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_CREATE);
2892 if (err) {
2893 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create upstream bandwidth allocation, intf_id %d, onu_id %d, uni_id %d,\
2894port_no %u, alloc_id %d, err = %s\n", intf_id, onu_id,uni_id,port_no,alloc_id, bcmos_strerror(err));
2895 return err;
2896 }
2897
2898 OPENOLT_LOG(INFO, openolt_log_id, "create upstream bandwidth allocation success, intf_id %d, onu_id %d, uni_id %d,\
2899port_no %u, alloc_id %d\n", intf_id, onu_id,uni_id,port_no,alloc_id);
2900
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002901 }
2902
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002903 return BCM_ERR_OK;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002904}
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002905
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002906Status CreateTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2907 uint32_t intf_id = traffic_scheds->intf_id();
2908 uint32_t onu_id = traffic_scheds->onu_id();
2909 uint32_t uni_id = traffic_scheds->uni_id();
2910 uint32_t port_no = traffic_scheds->port_no();
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002911 std::string direction;
2912 unsigned int alloc_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002913 tech_profile::SchedulerConfig sched_config;
2914 tech_profile::AdditionalBW additional_bw;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002915 uint32_t priority;
2916 uint32_t weight;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002917 tech_profile::SchedulingPolicy sched_policy;
2918 tech_profile::TrafficShapingInfo traffic_shaping_info;
2919 bcmos_errno err;
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07002920
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002921 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
2922 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002923
2924 direction = GetDirection(traffic_sched.direction());
2925 if (direction.compare("direction-not-supported") == 0)
2926 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
2927
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002928 alloc_id = traffic_sched.alloc_id();
2929 sched_config = traffic_sched.scheduler();
2930 additional_bw = sched_config.additional_bw();
2931 priority = sched_config.priority();
2932 weight = sched_config.weight();
2933 sched_policy = sched_config.sched_policy();
2934 traffic_shaping_info = traffic_sched.traffic_shaping_info();
2935 err = CreateSched(direction, intf_id, onu_id, uni_id, port_no, alloc_id, additional_bw, weight, priority,
2936 sched_policy, traffic_shaping_info);
2937 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002938 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create scheduler, err = %s\n", bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002939 return bcm_to_grpc_err(err, "Failed to create scheduler");
2940 }
Girish Gowdru1cdf6ce2018-08-27 02:43:02 -07002941 }
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002942 return Status::OK;
Shad Ansarib7b0ced2018-05-11 21:53:32 +00002943}
Jonathan Davis70c21812018-07-19 15:32:10 -04002944
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002945bcmos_errno RemoveSched(int intf_id, int onu_id, int uni_id, int alloc_id, std::string direction) {
Jonathan Davis70c21812018-07-19 15:32:10 -04002946
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002947 bcmos_errno err;
Girish Gowdra96461052019-11-22 20:13:59 +05302948 uint16_t sched_id;
Jonathan Davis70c21812018-07-19 15:32:10 -04002949
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002950 if (direction == upstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002951 bcmolt_itupon_alloc_cfg cfg;
2952 bcmolt_itupon_alloc_key key = { };
2953 key.pon_ni = intf_id;
2954 key.alloc_id = alloc_id;
Girish Gowdra96461052019-11-22 20:13:59 +05302955 sched_id = alloc_id;
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002956
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002957 BCMOLT_CFG_INIT(&cfg, itupon_alloc, key);
2958 err = bcmolt_cfg_clear(dev_id, &cfg.hdr);
2959 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002960 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2961 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002962 return err;
2963 }
Girish Gowdra96461052019-11-22 20:13:59 +05302964
2965 err = wait_for_alloc_action(intf_id, alloc_id, ALLOC_OBJECT_DELETE);
2966 if (err) {
2967 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, intf_id %d, alloc_id %d, err = %s\n",
2968 direction.c_str(), intf_id, alloc_id, bcmos_strerror(err));
2969 return err;
2970 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002971 } else if (direction == downstream) {
2972 bcmolt_tm_sched_cfg cfg;
2973 bcmolt_tm_sched_key key = { };
Nicolas Palpacuer9c352082018-08-14 16:37:14 -04002974
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002975 if (is_tm_sched_id_present(intf_id, onu_id, uni_id, direction)) {
2976 key.id = get_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdra96461052019-11-22 20:13:59 +05302977 sched_id = key.id;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002978 } else {
2979 OPENOLT_LOG(INFO, openolt_log_id, "schduler not present in %s, err %d\n", direction.c_str(), err);
2980 return BCM_ERR_OK;
2981 }
Girish Gowdra96461052019-11-22 20:13:59 +05302982
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00002983 BCMOLT_CFG_INIT(&cfg, tm_sched, key);
2984 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
2985 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05002986 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove scheduler, direction = %s, sched_id %d, \
2987intf_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 +00002988 return err;
2989 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002990 }
2991
Girish Gowdra96461052019-11-22 20:13:59 +05302992 OPENOLT_LOG(INFO, openolt_log_id, "Removed sched, direction = %s, id %d, intf_id %d, onu_id %d\n",
2993 direction.c_str(), sched_id, intf_id, onu_id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002994 free_tm_sched_id(intf_id, onu_id, uni_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08002995 return BCM_ERR_OK;
2996}
2997
2998Status RemoveTrafficSchedulers_(const tech_profile::TrafficSchedulers *traffic_scheds) {
2999 uint32_t intf_id = traffic_scheds->intf_id();
3000 uint32_t onu_id = traffic_scheds->onu_id();
3001 uint32_t uni_id = traffic_scheds->uni_id();
3002 std::string direction;
3003 bcmos_errno err;
3004
3005 for (int i = 0; i < traffic_scheds->traffic_scheds_size(); i++) {
3006 tech_profile::TrafficScheduler traffic_sched = traffic_scheds->traffic_scheds(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003007
3008 direction = GetDirection(traffic_sched.direction());
3009 if (direction.compare("direction-not-supported") == 0)
3010 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3011
3012 int alloc_id = traffic_sched.alloc_id();
3013 err = RemoveSched(intf_id, onu_id, uni_id, alloc_id, direction);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003014 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003015 OPENOLT_LOG(ERROR, openolt_log_id, "Error-removing-traffic-scheduler, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003016 return bcm_to_grpc_err(err, "error-removing-traffic-scheduler");
3017 }
3018 }
3019 return Status::OK;
3020}
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003021
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003022bcmos_errno CreateTrafficQueueMappingProfile(uint32_t sched_id, uint32_t intf_id, uint32_t onu_id, uint32_t uni_id, \
3023 std::string direction, std::vector<uint32_t> tmq_map_profile) {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003024 bcmos_errno err;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003025 bcmolt_tm_qmp_cfg tm_qmp_cfg;
3026 bcmolt_tm_qmp_key tm_qmp_key;
3027 bcmolt_arr_u8_8 pbits_to_tmq_id = {0};
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003028
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003029 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tmq_map_profile);
3030 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003031 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile. Max allowed tm queue mapping profile count is 16.\n");
3032 return BCM_ERR_RANGE;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003033 }
Girish Gowdruf26cf882019-05-01 23:47:58 -07003034
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003035 tm_qmp_key.id = tm_qmp_id;
3036 for (uint32_t priority=0; priority<tmq_map_profile.size(); priority++) {
3037 pbits_to_tmq_id.arr[priority] = tmq_map_profile[priority];
3038 }
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003039
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003040 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
3041 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, type, BCMOLT_TM_QMP_TYPE_PBITS);
3042 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, pbits_to_tmq_id, pbits_to_tmq_id);
3043 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, ref_count, 0);
3044 BCMOLT_MSG_FIELD_SET(&tm_qmp_cfg, state, BCMOLT_CONFIG_STATE_CONFIGURED);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -07003045
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003046 err = bcmolt_cfg_set(dev_id, &tm_qmp_cfg.hdr);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003047 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003048 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, tm_qmp_id %d, err = %s\n",
3049 tm_qmp_key.id, bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003050 return err;
3051 }
Craig Lutgen967a1d02018-11-27 10:41:51 -06003052
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003053 OPENOLT_LOG(INFO, openolt_log_id, "Create tm queue mapping profile success, id %d\n", \
3054 tm_qmp_key.id);
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003055 return BCM_ERR_OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003056}
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003057
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003058bcmos_errno RemoveTrafficQueueMappingProfile(uint32_t tm_qmp_id) {
3059 bcmos_errno err;
3060 bcmolt_tm_qmp_cfg tm_qmp_cfg;
3061 bcmolt_tm_qmp_key tm_qmp_key;
3062 tm_qmp_key.id = tm_qmp_id;
3063
3064 BCMOLT_CFG_INIT(&tm_qmp_cfg, tm_qmp, tm_qmp_key);
3065 err = bcmolt_cfg_clear(dev_id, &tm_qmp_cfg.hdr);
3066 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003067 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, tm_qmp_id %d, err = %s\n",
3068 tm_qmp_key.id, bcmos_strerror(err));
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003069 return err;
3070 }
3071
3072 OPENOLT_LOG(INFO, openolt_log_id, "Remove tm queue mapping profile success, id %d\n", \
3073 tm_qmp_key.id);
3074 return BCM_ERR_OK;
3075}
3076
3077bcmos_errno CreateDefaultQueue(uint32_t intf_id, const std::string direction) {
3078 bcmos_errno err;
3079
3080 /* Create 4 Queues on given PON/NNI scheduler */
3081 for (int queue_id = 0; queue_id < 4; queue_id++) {
3082 bcmolt_tm_queue_cfg tm_queue_cfg;
3083 bcmolt_tm_queue_key tm_queue_key = {};
3084 tm_queue_key.sched_id = get_default_tm_sched_id(intf_id, direction);
3085 tm_queue_key.id = queue_id;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003086 /* DefaultQueues on PON/NNI schedulers are created with egress_qos_type as
3087 BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE - with tm_q_set_id 32768 */
3088 tm_queue_key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003089
3090 BCMOLT_CFG_INIT(&tm_queue_cfg, tm_queue, tm_queue_key);
3091 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.type, BCMOLT_TM_SCHED_PARAM_TYPE_PRIORITY);
3092 BCMOLT_MSG_FIELD_SET(&tm_queue_cfg, tm_sched_param.u.priority.priority, queue_id);
3093
3094 err = bcmolt_cfg_set(dev_id, &tm_queue_cfg.hdr);
3095 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003096 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", \
3097 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 +00003098 return err;
3099 }
3100
3101 OPENOLT_LOG(INFO, openolt_log_id, "Create %s tm_queue success, id %d, sched_id %d, tm_q_set_id %d\n", \
3102 direction.c_str(), tm_queue_key.id, tm_queue_key.sched_id, tm_queue_key.tm_q_set_id);
3103 }
3104 return BCM_ERR_OK;
3105}
3106
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003107bcmos_errno CreateQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
3108 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003109 bcmos_errno err;
3110 bcmolt_tm_queue_cfg cfg;
3111 bcmolt_tm_queue_key key = { };
3112 OPENOLT_LOG(INFO, openolt_log_id, "creating %s queue. access_intf_id = %d, onu_id = %d, uni_id = %d \
3113gemport_id = %d\n", direction.c_str(), access_intf_id, onu_id, uni_id, gemport_id);
3114
3115 key.sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3116 get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
3117
3118 if (priority > 7) {
3119 return BCM_ERR_RANGE;
3120 }
3121
3122 /* FIXME: The upstream queues have to be created once only.
3123 The upstream queues on the NNI scheduler are shared by all subscribers.
3124 When the first scheduler comes in, the queues get created, and are re-used by all others.
3125 Also, these queues should be present until the last subscriber exits the system.
3126 One solution is to have these queues always, i.e., create it as soon as OLT is enabled.
3127
3128 There is one queue per gem port and Queue ID is fetched based on priority_q configuration
3129 for each GEM in TECH PROFILE */
3130 key.id = queue_id_list[priority];
3131
3132 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3133 // Reset the Queue ID to 0, if it is fixed queue, i.e., there is only one queue for subscriber.
3134 key.id = 0;
3135 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3136 }
3137 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3138 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3139 }
3140 else {
3141 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3142 }
3143
3144 OPENOLT_LOG(INFO, openolt_log_id, "queue assigned queue_id = %d\n", key.id);
3145
3146 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3147 BCMOLT_MSG_FIELD_SET(&cfg, tm_sched_param.u.priority.priority, priority);
3148
3149 err = bcmolt_cfg_set(dev_id, &cfg.hdr);
3150 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003151 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create subscriber tm queue, direction = %s, queue_id %d, \
3152sched_id %d, tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n", \
3153 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 +00003154 return err;
3155 }
3156
3157 OPENOLT_LOG(INFO, openolt_log_id, "Created tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3158intf_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);
3159 return BCM_ERR_OK;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003160}
3161
3162Status CreateTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
3163 uint32_t intf_id = traffic_queues->intf_id();
3164 uint32_t onu_id = traffic_queues->onu_id();
3165 uint32_t uni_id = traffic_queues->uni_id();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003166 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003167 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003168 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003169 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 +00003170
3171 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3172 uint32_t queues_priority_q[traffic_queues->traffic_queues_size()] = {0};
3173 std::string queues_pbit_map[traffic_queues->traffic_queues_size()];
3174 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3175 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
3176
3177 direction = GetDirection(traffic_queue.direction());
3178 if (direction.compare("direction-not-supported") == 0)
3179 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3180
3181 queues_priority_q[i] = traffic_queue.priority();
3182 queues_pbit_map[i] = traffic_queue.pbit_map();
3183 }
3184
3185 std::vector<uint32_t> tmq_map_profile(8, 0);
3186 tmq_map_profile = get_tmq_map_profile(get_valid_queues_pbit_map(queues_pbit_map, COUNT_OF(queues_pbit_map)), \
3187 queues_priority_q, COUNT_OF(queues_priority_q));
3188 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3189 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3190
3191 int tm_qmp_id = get_tm_qmp_id(tmq_map_profile);
3192 if (tm_qmp_id == -1) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003193 err = CreateTrafficQueueMappingProfile(sched_id, intf_id, onu_id, uni_id, direction, tmq_map_profile);
3194 if (err != BCM_ERR_OK) {
3195 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3196 return bcm_to_grpc_err(err, "Failed to create tm queue mapping profile");
3197 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003198 } else if (tm_qmp_id != -1 && get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id) == -1) {
3199 OPENOLT_LOG(INFO, openolt_log_id, "tm queue mapping profile present already with id %d\n", tm_qmp_id);
3200 update_sched_qmp_id_map(sched_id, intf_id, onu_id, uni_id, tm_qmp_id);
3201 }
3202 }
3203
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003204 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3205 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003206
3207 direction = GetDirection(traffic_queue.direction());
3208 if (direction.compare("direction-not-supported") == 0)
3209 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3210
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003211 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 +00003212
Girish Gowdruf26cf882019-05-01 23:47:58 -07003213 // If the queue exists already, lets not return failure and break the loop.
3214 if (err && err != BCM_ERR_ALREADY) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003215 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to create queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003216 return bcm_to_grpc_err(err, "Failed to create queue");
3217 }
3218 }
3219 return Status::OK;
3220}
3221
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003222bcmos_errno RemoveQueue(std::string direction, uint32_t access_intf_id, uint32_t onu_id, uint32_t uni_id,
3223 bcmolt_egress_qos_type qos_type, uint32_t priority, uint32_t gemport_id) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003224 bcmolt_tm_queue_cfg cfg;
3225 bcmolt_tm_queue_key key = { };
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003226 bcmos_errno err;
3227
3228 if (direction == downstream) {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003229 if (is_tm_sched_id_present(access_intf_id, onu_id, uni_id, direction)) {
3230 key.sched_id = get_tm_sched_id(access_intf_id, onu_id, uni_id, direction);
3231 key.id = queue_id_list[priority];
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003232 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003233 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 -08003234 return BCM_ERR_OK;
3235 }
3236 } else {
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003237 /* In the upstream we use pre-created queues on the NNI scheduler that are used by all subscribers.
3238 They should not be removed. So, lets return OK. */
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003239 return BCM_ERR_OK;
3240 }
3241
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003242 if (qos_type == BCMOLT_EGRESS_QOS_TYPE_FIXED_QUEUE) {
3243 key.tm_q_set_id = BCMOLT_TM_QUEUE_SET_ID_QSET_NOT_USE;
3244 // Reset the queue id to 0 when using fixed queue.
3245 key.id = 0;
3246 }
3247 else if (qos_type == BCMOLT_EGRESS_QOS_TYPE_PRIORITY_TO_QUEUE) {
3248 key.tm_q_set_id = get_tm_qmp_id(key.sched_id, access_intf_id, onu_id, uni_id);
3249 }
3250 else {
3251 key.tm_q_set_id = BCMOLT_TM_QUEUE_KEY_TM_Q_SET_ID_DEFAULT;
3252 }
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003253
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003254 BCMOLT_CFG_INIT(&cfg, tm_queue, key);
3255 err = bcmolt_cfg_clear(dev_id, &(cfg.hdr));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003256 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003257 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, direction = %s, queue_id %d, sched_id %d, \
3258tm_q_set_id %d, intf_id %d, onu_id %d, uni_id %d, err = %s\n",
3259 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 -08003260 return err;
3261 }
3262
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003263 OPENOLT_LOG(INFO, openolt_log_id, "Removed tm_queue, direction %s, id %d, sched_id %d, tm_q_set_id %d, \
3264intf_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 -08003265
3266 return BCM_ERR_OK;
3267}
3268
3269Status RemoveTrafficQueues_(const tech_profile::TrafficQueues *traffic_queues) {
3270 uint32_t intf_id = traffic_queues->intf_id();
3271 uint32_t onu_id = traffic_queues->onu_id();
3272 uint32_t uni_id = traffic_queues->uni_id();
3273 uint32_t port_no = traffic_queues->port_no();
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003274 uint32_t sched_id;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003275 std::string direction;
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003276 bcmos_errno err;
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003277 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 +00003278
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003279 for (int i = 0; i < traffic_queues->traffic_queues_size(); i++) {
3280 tech_profile::TrafficQueue traffic_queue = traffic_queues->traffic_queues(i);
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003281
3282 direction = GetDirection(traffic_queue.direction());
3283 if (direction.compare("direction-not-supported") == 0)
3284 return bcm_to_grpc_err(BCM_ERR_PARM, "direction-not-supported");
3285
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003286 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 -08003287 if (err) {
Thiyagarajan Subramani0890b1f2019-11-22 07:52:47 -05003288 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove queue, err = %s\n",bcmos_strerror(err));
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -08003289 return bcm_to_grpc_err(err, "Failed to remove queue");
3290 }
Jonathan Davis70c21812018-07-19 15:32:10 -04003291 }
3292
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003293 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))) {
3294 sched_id = (direction.compare(upstream) == 0) ? get_default_tm_sched_id(nni_intf_id, direction) : \
3295 get_tm_sched_id(intf_id, onu_id, uni_id, direction);
3296
3297 int tm_qmp_id = get_tm_qmp_id(sched_id, intf_id, onu_id, uni_id);
3298 if (free_tm_qmp_id(sched_id, intf_id, onu_id, uni_id, tm_qmp_id)) {
Thiyagarajan Subramani6dc20052019-12-05 09:06:36 -05003299 err = RemoveTrafficQueueMappingProfile(tm_qmp_id);
3300 if (err != BCM_ERR_OK) {
3301 OPENOLT_LOG(ERROR, openolt_log_id, "Failed to remove tm queue mapping profile, err = %s\n", bcmos_strerror(err));
3302 return bcm_to_grpc_err(err, "Failed to remove tm queue mapping profile");
3303 }
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +00003304 }
3305 }
Thiyagarajan Subramani8154d932019-11-13 05:29:06 -05003306 clear_qos_type(intf_id, onu_id, uni_id);
Jonathan Davis70c21812018-07-19 15:32:10 -04003307 return Status::OK;
Jonathan Davis70c21812018-07-19 15:32:10 -04003308}
Jason Huangbf45ffb2019-10-30 17:29:02 +08003309
3310Status check_connection() {
3311 int maxTrials = 60;
3312 while (!bcmolt_api_conn_mgr_is_connected(dev_id)) {
3313 sleep(1);
3314 if (--maxTrials == 0)
3315 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check connection failed");
3316 else
3317 OPENOLT_LOG(INFO, openolt_log_id, "waiting for daemon connection ...\n");
3318 }
3319 OPENOLT_LOG(INFO, openolt_log_id, "daemon is connected\n");
3320 return Status::OK;
3321}
3322
3323Status check_bal_ready() {
3324 bcmos_errno err;
3325 int maxTrials = 30;
3326 bcmolt_olt_cfg olt_cfg = { };
3327 bcmolt_olt_key olt_key = { };
3328
3329 BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
3330 BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
3331
3332 while (olt_cfg.data.bal_state != BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY) {
3333 if (--maxTrials == 0)
3334 return grpc::Status(grpc::StatusCode::UNAVAILABLE, "check bal ready failed");
3335 sleep(5);
3336 #ifdef TEST_MODE
3337 // It is impossible to mock the setting of olt_cfg.data.bal_state because
3338 // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
3339 // set the olt_cfg.data.bal_state. So a new stub function is created and address
Chaitrashree G Sfd15c8c2019-09-09 18:46:15 -04003340 // of olt_cfg is passed. This is one-of case where we need to add test specific
3341 // code in production code.
3342 if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
Jason Huangbf45ffb2019-10-30 17:29:02 +08003343 #else
3344 if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
3345 #endif
3346 continue;
3347 }
3348 else
3349 OPENOLT_LOG(INFO, openolt_log_id, "waiting for BAL ready ...\n");
3350 }
3351
3352 OPENOLT_LOG(INFO, openolt_log_id, "BAL is ready\n");
3353 return Status::OK;
3354}