mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-30 18:07:52 +00:00
realtek: add feed
This adds the feed holding the realtek target specific packages. Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
29
feeds/realtek/rtl83xx-poe/Makefile
Normal file
29
feeds/realtek/rtl83xx-poe/Makefile
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=rtl83xx-poe
|
||||||
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
|
PKG_LICENSE:=GPL-2.0+
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/rtl83xx-poe
|
||||||
|
SECTION:=utils
|
||||||
|
CATEGORY:=Utilities
|
||||||
|
DEPENDS:=+libubox-lua +libubus-lua +libuci-lua +lua-rs232
|
||||||
|
TITLE:=PoE daemon for realtek switches
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/rtl83xx-poe/description
|
||||||
|
This package contains an utility to allow triggering the PoE state of realtek switch ports.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/rtl83xx-poe/install
|
||||||
|
$(CP) ./files/* $(1)/
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,rtl83xx-poe))
|
||||||
316
feeds/realtek/rtl83xx-poe/files/bin/poe.lua
Executable file
316
feeds/realtek/rtl83xx-poe/files/bin/poe.lua
Executable file
@@ -0,0 +1,316 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
local rs = require "luars232"
|
||||||
|
|
||||||
|
port_name = "/dev/ttyS1"
|
||||||
|
out = io.stderr
|
||||||
|
nseq = 0
|
||||||
|
|
||||||
|
budget = 65.0
|
||||||
|
port_power = {0, 0, 0, 0, 0, 0, 0, 0 }
|
||||||
|
|
||||||
|
if arg[1] ~= nil then
|
||||||
|
budget = tonumber(arg[1])
|
||||||
|
end
|
||||||
|
for i = 1, 8 do
|
||||||
|
port_power[i] = arg[i + 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function initSerial(p)
|
||||||
|
local e, p = rs.open(p)
|
||||||
|
if e ~= rs.RS232_ERR_NOERROR then
|
||||||
|
-- handle error
|
||||||
|
out:write(string.format("can't open serial port '%s', error: '%s'\n",
|
||||||
|
port_name, rs.error_tostring(e)))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(p:set_baud_rate(rs.RS232_BAUD_19200) == rs.RS232_ERR_NOERROR)
|
||||||
|
assert(p:set_data_bits(rs.RS232_DATA_8) == rs.RS232_ERR_NOERROR)
|
||||||
|
assert(p:set_parity(rs.RS232_PARITY_NONE) == rs.RS232_ERR_NOERROR)
|
||||||
|
assert(p:set_stop_bits(rs.RS232_STOP_1) == rs.RS232_ERR_NOERROR)
|
||||||
|
assert(p:set_flow_control(rs.RS232_FLOW_OFF) == rs.RS232_ERR_NOERROR)
|
||||||
|
|
||||||
|
out:write(string.format("OK, port open with values '%s'\n", tostring(p)))
|
||||||
|
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
|
||||||
|
function receive(pCon)
|
||||||
|
local reply = {}
|
||||||
|
local retries = 0
|
||||||
|
|
||||||
|
while table.getn(reply) < 12 and retries < 4 do
|
||||||
|
-- Read up to 12 byte response, timeout 400ms
|
||||||
|
err, data_read, size = pCon:read(12, 400)
|
||||||
|
assert(err == rs.RS232_ERR_NOERROR)
|
||||||
|
-- io.write(string.format("-> [%2d]:", string.len(data_read)))
|
||||||
|
for i = 1, string.len(data_read) do
|
||||||
|
table.insert(reply, string.byte(string.sub(data_read, i, i)))
|
||||||
|
-- io.write(string.format(" %02x", reply[i]))
|
||||||
|
end
|
||||||
|
-- io.write("\n")
|
||||||
|
retries = retries + 1
|
||||||
|
end
|
||||||
|
if table.getn(reply) ~= 12 then
|
||||||
|
print ("Unexpected length!")
|
||||||
|
return(nil)
|
||||||
|
end
|
||||||
|
local sum = 0
|
||||||
|
for i = 1, 11 do
|
||||||
|
sum = sum + reply[i]
|
||||||
|
end
|
||||||
|
if sum % 256 ~= reply[12] then
|
||||||
|
print ("Checksum error!")
|
||||||
|
return(nil)
|
||||||
|
end
|
||||||
|
return(reply)
|
||||||
|
end
|
||||||
|
|
||||||
|
function sendCommand(pCon, cmd)
|
||||||
|
nseq = nseq + 1
|
||||||
|
cmd[2] = nseq % 256
|
||||||
|
|
||||||
|
while table.getn(cmd) < 11 do
|
||||||
|
table.insert(cmd, 0xff)
|
||||||
|
end
|
||||||
|
local c_string = ""
|
||||||
|
local sum = 0
|
||||||
|
-- io.write("send ")
|
||||||
|
for i = 1, 11 do
|
||||||
|
sum = sum + cmd[i]
|
||||||
|
-- io.write(string.format(" %02x", cmd[i]))
|
||||||
|
c_string = c_string .. string.char(cmd[i])
|
||||||
|
end
|
||||||
|
-- io.write(string.format(" %02x\n", sum % 256))
|
||||||
|
c_string = c_string .. string.char(sum % 256)
|
||||||
|
err, len_written = pCon:write(c_string)
|
||||||
|
assert(err == rs.RS232_ERR_NOERROR)
|
||||||
|
|
||||||
|
local reply = receive(pCon)
|
||||||
|
if reply then
|
||||||
|
-- io.write("recv ")
|
||||||
|
-- dumpReply(reply)
|
||||||
|
if (reply[1] == cmd[1] and reply[2] == cmd[2]) then
|
||||||
|
return(reply)
|
||||||
|
else
|
||||||
|
if reply[1] == 0xfd then
|
||||||
|
print ("An incomplete request was received!")
|
||||||
|
elseif reply[1] == 0xfe then
|
||||||
|
print ("Request frame checksum was incorrect!")
|
||||||
|
elseif reply[1] == 0xff then
|
||||||
|
print ("Controller was not ready to respond !")
|
||||||
|
else
|
||||||
|
print ("Sequence number mismatch!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print ("Missing reply!")
|
||||||
|
end
|
||||||
|
return(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
function dumpReply(reply)
|
||||||
|
for i,v in ipairs(reply) do
|
||||||
|
io.write(string.format(" %02x", v))
|
||||||
|
end
|
||||||
|
io.write("\n");
|
||||||
|
end
|
||||||
|
|
||||||
|
function getStatus(pCon)
|
||||||
|
local cmd = {0x20, 0x01}
|
||||||
|
local reply = sendCommand(pCon, cmd)
|
||||||
|
if not reply then return(nil) end
|
||||||
|
-- returns status, PoEExtVersion, PoEVersion, state2
|
||||||
|
return({reply[5], reply[6], reply[7], reply[10]})
|
||||||
|
end
|
||||||
|
|
||||||
|
function disablePort(pCon, port)
|
||||||
|
local cmd = {0x00, port, port, 0x00}
|
||||||
|
-- disable command is always sent twice
|
||||||
|
sendCommand(pCon, cmd)
|
||||||
|
sendCommand(pCon, cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
function enablePort(pCon, port)
|
||||||
|
local cmd = {0x00, port, port, 0x01}
|
||||||
|
sendCommand(pCon, cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
function setPortRelPrio(pCon, port, prio)
|
||||||
|
local cmd = {0x1d, 0x00, port, prio}
|
||||||
|
sendCommand(pCon, cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
function setGlobalPowerBudget(pCon, maxPower, guard)
|
||||||
|
-- maxPower and guard Watts
|
||||||
|
local cmd = {0x18, 0x01, 0x00}
|
||||||
|
table.insert(cmd, math.floor(maxPower * 10 / 256))
|
||||||
|
table.insert(cmd, math.floor(maxPower * 10) % 256)
|
||||||
|
table.insert(cmd, math.floor(guard * 10 / 256))
|
||||||
|
table.insert(cmd, math.floor(guard * 10) % 256)
|
||||||
|
sendCommand(pCon, cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
function setPowerLowAction(pCon, disableNext)
|
||||||
|
local cmd = {0x17, 0x00}
|
||||||
|
if disableNext then
|
||||||
|
table.insert(cmd, 0x04)
|
||||||
|
else
|
||||||
|
table.insert(cmd, 0x02)
|
||||||
|
end
|
||||||
|
sendCommand(pCon, cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
function getPowerStat(pCon)
|
||||||
|
local cmd = {0x23, 0x01}
|
||||||
|
local reply = sendCommand(pCon, cmd)
|
||||||
|
if not reply then return(nil) end
|
||||||
|
local watts = (reply[3] * 256 + reply[4]) / 10.0
|
||||||
|
return watts
|
||||||
|
end
|
||||||
|
|
||||||
|
function getPortPower(pCon, port)
|
||||||
|
local cmd = {0x30, 0x01, port}
|
||||||
|
local reply = sendCommand(pCon, cmd)
|
||||||
|
if not reply then return(nil) end
|
||||||
|
local watts = (reply[10] * 256 + reply[11]) / 10.0
|
||||||
|
local mamps = reply[6] * 256 + reply[7]
|
||||||
|
return({watts, mamps})
|
||||||
|
end
|
||||||
|
|
||||||
|
function getPortOverview(pCon)
|
||||||
|
local cmd = {0x2a, 0x01, 0x00}
|
||||||
|
local reply = sendCommand(pCon, cmd)
|
||||||
|
if not reply then return(nil) end
|
||||||
|
local s = { }
|
||||||
|
for i = 4, 11 do
|
||||||
|
if reply[i] == 0x10 then
|
||||||
|
s[i-3] = "off"
|
||||||
|
elseif reply[i] == 0x11 then
|
||||||
|
s[i-3] = "enabled"
|
||||||
|
elseif reply[i] > 0x11 then
|
||||||
|
s[i-3] = "active"
|
||||||
|
else
|
||||||
|
s[i-3] = "unknown"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Priority for power: 3: High, 2: Normal, 1: Low?
|
||||||
|
function setPortPriority(pCon, port, prio)
|
||||||
|
local cmd = {0x1a, port, port, prio}
|
||||||
|
local reply = sendCommand(pCon, cmd)
|
||||||
|
if not reply then return(nil) end
|
||||||
|
return(unpack(reply, 4, 11))
|
||||||
|
end
|
||||||
|
|
||||||
|
function getPortPowerLimits(pCon, port)
|
||||||
|
local cmd = {0x26, 0x01, port}
|
||||||
|
local reply = sendCommand(pCon, cmd)
|
||||||
|
if not reply then return(nil) end
|
||||||
|
return(reply)
|
||||||
|
end
|
||||||
|
|
||||||
|
function startupPoE(pCon)
|
||||||
|
local reply = nil
|
||||||
|
reply = getStatus(pCon)
|
||||||
|
|
||||||
|
setGlobalPowerBudget(pCon, 0, 0)
|
||||||
|
setPowerLowAction(pCon, nil)
|
||||||
|
-- do something unknown
|
||||||
|
sendCommand(pCon, {0x06, 0x00, 0x01})
|
||||||
|
for i = 0, 7 do
|
||||||
|
if port_power[i + 1] ~= "1" then
|
||||||
|
disablePort(pCon, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- do something unknown
|
||||||
|
sendCommand(pCon, {0x02, 0x00, 0x01})
|
||||||
|
|
||||||
|
for i = 0, 7 do
|
||||||
|
if port_power[i + 1] ~= "1" then
|
||||||
|
disablePort(pCon, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- do something unknown
|
||||||
|
sendCommand(pCon, {0x02, 0x00, 0x01})
|
||||||
|
|
||||||
|
-- use monitor command 25
|
||||||
|
sendCommand(pCon, {0x25, 0x01})
|
||||||
|
|
||||||
|
setGlobalPowerBudget(pCon, 65.0, 7.0)
|
||||||
|
getPowerStat(pCon)
|
||||||
|
-- -> 23 01 00 00 02 44 00 02 ff ff 00 6a
|
||||||
|
|
||||||
|
-- Set 4 unknown port properties:
|
||||||
|
for i = 0, 7 do
|
||||||
|
sendCommand(pCon, {0x11, i, i, 0x01})
|
||||||
|
sendCommand(pCon, {0x13, i, i, 0x02})
|
||||||
|
sendCommand(pCon, {0x15, i, i, 0x01})
|
||||||
|
sendCommand(pCon, {0x10, i, i, 0x03})
|
||||||
|
end
|
||||||
|
for i = 0, 7 do
|
||||||
|
if port_power[i + 1] == "1" then
|
||||||
|
enablePort(pCon, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local p = initSerial(port_name)
|
||||||
|
startupPoE(p)
|
||||||
|
|
||||||
|
require "ubus"
|
||||||
|
require "uloop"
|
||||||
|
|
||||||
|
uloop.init()
|
||||||
|
|
||||||
|
local conn = ubus.connect()
|
||||||
|
if not conn then
|
||||||
|
error("Failed to connect to ubus")
|
||||||
|
end
|
||||||
|
|
||||||
|
local my_method = {
|
||||||
|
poe = {
|
||||||
|
info = {
|
||||||
|
function(req, msg)
|
||||||
|
local reply = {}
|
||||||
|
|
||||||
|
reply.power_consumption = tostring(getPowerStat(p)).."W"
|
||||||
|
reply.power_budget = tostring(budget).."W"
|
||||||
|
|
||||||
|
reply.ports = {}
|
||||||
|
local s = getPortOverview(p)
|
||||||
|
for i = 1, 8 do
|
||||||
|
if s[i] == "active" then
|
||||||
|
local r = getPortPower(p, i - 1)
|
||||||
|
reply.ports[i] = tostring(r[1]).."W"
|
||||||
|
else
|
||||||
|
reply.ports[i] = s[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
conn:reply(req, reply);
|
||||||
|
end, {}
|
||||||
|
},
|
||||||
|
port = {
|
||||||
|
function(req, msg)
|
||||||
|
local reply = {}
|
||||||
|
if msg.port < 1 or msg.port > 8 then
|
||||||
|
conn:reply(req, false);
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
if msg.enable == true then
|
||||||
|
enablePort(p, msg.port - 1)
|
||||||
|
else
|
||||||
|
disablePort(p, msg.port - 1)
|
||||||
|
end
|
||||||
|
conn:reply(req, reply);
|
||||||
|
end, {port = ubus.INT32, enable = ubus.BOOLEAN }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
conn:add(my_method)
|
||||||
|
|
||||||
|
uloop.run()
|
||||||
10
feeds/realtek/rtl83xx-poe/files/etc/config/poe
Normal file
10
feeds/realtek/rtl83xx-poe/files/etc/config/poe
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
config poe poe
|
||||||
|
option budget 65
|
||||||
|
option port1 0
|
||||||
|
option port2 0
|
||||||
|
option port3 0
|
||||||
|
option port4 0
|
||||||
|
option port5 0
|
||||||
|
option port6 0
|
||||||
|
option port7 0
|
||||||
|
option port8 0
|
||||||
24
feeds/realtek/rtl83xx-poe/files/etc/init.d/poe
Executable file
24
feeds/realtek/rtl83xx-poe/files/etc/init.d/poe
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
START=40
|
||||||
|
|
||||||
|
USE_PROCD=1
|
||||||
|
PROG=/bin/poe.lua
|
||||||
|
|
||||||
|
service_triggers() {
|
||||||
|
procd_add_reload_trigger ucentral
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
[ "$(uci get poe.poe.enable)" -eq 1 ] || return 0
|
||||||
|
|
||||||
|
local budget=$(uci get poe.poe.budget)
|
||||||
|
|
||||||
|
procd_open_instance
|
||||||
|
procd_set_param command "$PROG"
|
||||||
|
procd_append_param command ${budget:-65}
|
||||||
|
for p in `seq 1 8`; do
|
||||||
|
local pwr=$(uci get poe.poe.port$p)
|
||||||
|
procd_append_param command ${pwr:-0}
|
||||||
|
done
|
||||||
|
procd_close_instance
|
||||||
|
}
|
||||||
21
feeds/realtek/rtl83xx-poe/files/etc/uci-defaults/30-poe
Normal file
21
feeds/realtek/rtl83xx-poe/files/etc/uci-defaults/30-poe
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
|
||||||
|
board=$(board_name)
|
||||||
|
|
||||||
|
budget=0
|
||||||
|
case "$board" in
|
||||||
|
d-link,dgs-1210-10p)
|
||||||
|
budget=65
|
||||||
|
;;
|
||||||
|
netgear,gs110tpp-v1|\
|
||||||
|
zyxel,gs1900-10hp)
|
||||||
|
budget=130
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
uci set poe.poe.enable=1
|
||||||
|
uci set poe.poe.budget=$budget
|
||||||
Reference in New Issue
Block a user