summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0051-Fix-Set-LAN-Config-to-work-without-SetInProgress.patch
blob: 3990c6b5c4d4827ee004217e3f50b53af25ed02a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
From cae9e21f88e6f12c80c89402473a17a10258c843 Mon Sep 17 00:00:00 2001
From: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
Date: Thu, 17 Jan 2019 21:22:30 +0530
Subject: [PATCH] Fix: Set LAN Config to work without SetInProgress

Set LAN Configuration parameters in up-stream code works
with SetInProgress (parameter selector 0), to be marked
as SET_IN_PROGRESS before fields update, and SET_COMPLETE to
make the changes effective. This is not mandatory as per
IPMI Spec, and we must support individual fields update.
Fix:
1. After SET_COMPLETE for parameter selector, changes has
to be applied immediately, and doesn't require to rely on
network timer, as purpose of this logic itself is to stage
and commit.
2. Allow individual parameter changes to take effect based
on timer. For the time being reduced the timer to 5 sec
to have quicker turn-around and group things together.

TODO:
Still need to introduce lock between ChannelConfig variable
between Timer & Get / Set LAN Configuration command to avoid
race condition

Unit-Test:
1. Verified the BIOS Setup page, able to set the IPV4 to static
IP, afte disabling IPV6, and configuring IPV4 to static, after
save and reset, the changes of IPV4 static is preserved.

Change-Id: I7c2edad2861b5dba5ad1ca97cc5e39ac02871746
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
---
 transporthandler.cpp | 54 ++++++++++++++++++++++++++++++++++++----------------
 transporthandler.hpp |  2 ++
 2 files changed, 40 insertions(+), 16 deletions(-)

Index: phosphor-host-ipmid.clean/transporthandler.cpp
===================================================================
--- phosphor-host-ipmid.clean.orig/transporthandler.cpp
+++ phosphor-host-ipmid.clean/transporthandler.cpp
@@ -399,6 +399,41 @@ struct set_lan_t
     uint8_t data[8]; // Per IPMI spec, not expecting more than this size
 } __attribute__((packed));
 
+ipmi_ret_t checkAndUpdateNetwork(int channel)
+{
+    auto channelConf = getChannelConfig(channel);
+    using namespace std::chrono_literals;
+    // time to wait before applying the network changes.
+    constexpr auto networkTimeout = 5000000us; // 5 sec
+
+    if (channelConf->lan_set_in_progress == SET_COMPLETE &&
+        ((channelConf->flush == false) ||
+         (channelConf->updateInProgress == true)))
+    {
+        channelConf->flush = true;
+        // used to indicate that network timer update is in progress.
+        channelConf->updateInProgress = true;
+        if (!networkTimer)
+        {
+            log<level::ERR>("Network timer is not instantiated");
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        // start/restart the timer
+        // TODO: Need to implement locking mechansim between networkTimer &
+        // get/set to avoid race condition.
+        networkTimer->start(networkTimeout);
+    }
+    else if (channelConf->lan_set_in_progress == SET_COMPLETE &&
+             channelConf->flush == true &&
+             channelConf->updateInProgress == false)
+    {
+        // Apply the network changes immediately, if proper SET_IN_PROGRESS,
+        // followed by SET_COMPLETE is issued.
+        applyChanges(channel);
+    }
+    return IPMI_CC_OK;
+}
+
 ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                                   ipmi_request_t request,
                                   ipmi_response_t response,
@@ -406,12 +441,6 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n
                                   ipmi_context_t context)
 {
     ipmi_ret_t rc = IPMI_CC_OK;
-
-    using namespace std::chrono_literals;
-
-    // time to wait before applying the network changes.
-    constexpr auto networkTimeout = 10000000us; // 10 sec
-
     char ipaddr[INET_ADDRSTRLEN];
     char netmask[INET_ADDRSTRLEN];
     char gateway[INET_ADDRSTRLEN];
@@ -543,15 +572,6 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n
                     entry("ADDRESS=%s", channelConf->ipaddr.c_str()),
                     entry("GATEWAY=%s", channelConf->gateway.c_str()),
                     entry("VLAN=%d", channelConf->vlanID));
-
-                if (!networkTimer)
-                {
-                    log<level::ERR>("Network timer is not instantiated");
-                    return IPMI_CC_UNSPECIFIED_ERROR;
-                }
-
-                // start/restart the timer
-                networkTimer->start(networkTimeout);
             }
             else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
             {
@@ -680,8 +700,10 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n
         default:
         {
             rc = IPMI_CC_PARM_NOT_SUPPORTED;
+            return rc;
         }
     }
+    rc = checkAndUpdateNetwork(channel);
 
     return rc;
 }
Index: phosphor-host-ipmid.clean/transporthandler.hpp
===================================================================
--- phosphor-host-ipmid.clean.orig/transporthandler.hpp
+++ phosphor-host-ipmid.clean/transporthandler.hpp
@@ -140,6 +140,7 @@ struct ChannelConfig_t
     // vlan id is in 12 bits and the 16th bit is for enable mask.
     uint32_t vlanID = ipmi::network::VLAN_ID_MASK;
     uint8_t lan_set_in_progress = SET_COMPLETE;
+    uint8_t updateInProgress = false;
     bool flush = false;
 
     // IPV6 parameters
@@ -165,6 +166,7 @@ struct ChannelConfig_t
         vlanID = ipmi::network::VLAN_ID_MASK;
         ipsrc = ipmi::network::IPOrigin::UNSPECIFIED;
         lan_set_in_progress = SET_COMPLETE;
+        updateInProgress = false;
         flush = false;
 
         // IPv6