Ipmbbridge: Add support for multiple sub channel.
Added Multiple sub channels support for ipmb and me
type to communicate with more than one device of same type.
ChannelType supports only two channels ME and ipmb.
Using combination of devIndex and channelType approach,
can support multiple sub channels without affecting the
existing functionalities.
Single host or channel, "devIndex" will be set default index as 0.
For multiple channel under same type need to provide devIndex in
json configurations. This approach uses the sendRequest method's
first parameter values for MSB 6 bits as "devIndex" and
the remaining 2 bits as "channelType".
TESTED : Built Facebook YosemiteV2 & Tiogapass images and loaded on
the target hardware. We are able to see BMC to all
host communications through Ipmb.
Signed-off-by: Kumar Thangavel <thangavel.k@hcl.com>
Change-Id: I20a7231993a0dd1f9d396dde114837380302dc76
diff --git a/ipmbbridged.cpp b/ipmbbridged.cpp
index 6496bb8..3dc1a76 100644
--- a/ipmbbridged.cpp
+++ b/ipmbbridged.cpp
@@ -518,11 +518,11 @@
IpmbChannel::IpmbChannel(boost::asio::io_service &io,
uint8_t ipmbBmcSlaveAddress,
- uint8_t ipmbRqSlaveAddress, ipmbChannelType type,
+ uint8_t ipmbRqSlaveAddress, uint8_t channelIdx,
std::shared_ptr<IpmbCommandFilter> commandFilter) :
i2cSlaveDescriptor(io),
ipmbBmcSlaveAddress(ipmbBmcSlaveAddress),
- ipmbRqSlaveAddress(ipmbRqSlaveAddress), type(type),
+ ipmbRqSlaveAddress(ipmbRqSlaveAddress), channelIdx(channelIdx),
commandFilter(commandFilter)
{
}
@@ -684,9 +684,19 @@
return ipmbRqSlaveAddress;
}
+uint8_t IpmbChannel::getDevIndex()
+{
+ return channelIdx >> 2;
+}
+
+uint8_t IpmbChannel::getChannelIdx()
+{
+ return channelIdx;
+}
+
ipmbChannelType IpmbChannel::getChannelType()
{
- return type;
+ return static_cast<ipmbChannelType>((channelIdx & 3));
}
void IpmbChannel::addFilter(const uint8_t respNetFn, const uint8_t cmd)
@@ -761,12 +771,12 @@
return returnStatus(ipmbResponseStatus::timeout);
}
-static IpmbChannel *getChannel(ipmbChannelType channelType)
+static IpmbChannel *getChannel(uint8_t reqChannel)
{
auto channel =
std::find_if(ipmbChannels.begin(), ipmbChannels.end(),
- [channelType](IpmbChannel &channel) {
- return channel.getChannelType() == channelType;
+ [reqChannel](IpmbChannel &channel) {
+ return channel.getChannelIdx() == reqChannel;
});
if (channel != ipmbChannels.end())
{
@@ -792,6 +802,7 @@
}
try
{
+ uint8_t devIndex = 0;
auto data = nlohmann::json::parse(configFile, nullptr);
for (const auto &channelConfig : data["channels"])
{
@@ -799,10 +810,17 @@
const std::string &slavePath = channelConfig["slave-path"];
uint8_t bmcAddr = channelConfig["bmc-addr"];
uint8_t reqAddr = channelConfig["remote-addr"];
+
ipmbChannelType type = ipmbChannelTypeMap.at(typeConfig);
- auto channel = ipmbChannels.emplace(ipmbChannels.end(), io, bmcAddr,
- reqAddr, type, commandFilter);
+ if (channelConfig.contains("devIndex"))
+ {
+ devIndex = channelConfig["devIndex"];
+ }
+
+ auto channel = ipmbChannels.emplace(
+ ipmbChannels.end(), io, bmcAddr, reqAddr,
+ ((devIndex << 2) | static_cast<uint8_t>(type)), commandFilter);
if (channel->ipmbChannelInit(slavePath.c_str()) < 0)
{
phosphor::logging::log<phosphor::logging::level::ERR>(
@@ -829,7 +847,8 @@
auto ipmbHandleRequest = [](boost::asio::yield_context yield,
uint8_t reqChannel, uint8_t netfn, uint8_t lun,
uint8_t cmd, std::vector<uint8_t> dataReceived) {
- IpmbChannel *channel = getChannel(static_cast<ipmbChannelType>(reqChannel));
+ IpmbChannel *channel = getChannel(reqChannel);
+
if (channel == nullptr)
{
phosphor::logging::log<phosphor::logging::level::ERR>(
@@ -883,10 +902,10 @@
message.read(reqChannel, busId, slaveAddr);
- IpmbChannel *channel =
- getChannel(static_cast<ipmbChannelType>(reqChannel));
+ IpmbChannel *channel = getChannel(reqChannel);
+
if (channel == nullptr ||
- reqChannel != static_cast<uint8_t>(ipmbChannelType::ipmb))
+ channel->getChannelType() != ipmbChannelType::ipmb)
{
phosphor::logging::log<phosphor::logging::level::ERR>(
"addUpdateSlaveAddrHandler: invalid channel");
@@ -923,8 +942,8 @@
std::vector<uint8_t> dataReceived;
message.read(reqChannel, netFn, lun, cmd, dataReceived);
- IpmbChannel *channel =
- getChannel(static_cast<ipmbChannelType>(reqChannel));
+ IpmbChannel *channel = getChannel(reqChannel);
+
if (channel == nullptr)
{
phosphor::logging::log<phosphor::logging::level::ERR>(