Skip to content
Snippets Groups Projects
Commit d17c2fe2 authored by Andrew Cooks's avatar Andrew Cooks
Browse files

Merge branch 'master' into cleanup/v0.3.6.17.2

parents 894992c9 fedea83b
No related branches found
No related tags found
No related merge requests found
tn40xx.ko
tn40xx.mod.c
Module.symvers
*~
*.o
*.o.cmd
*.swp
This repo contains the tn40xx Linux driver for 10Gbit NICs based on the TN4010 MAC from [Tehuti Networks](http://www.tehutinetworks.net).
This driver enables the following 10Gb SFP+ NICs:
- D-Link DXE-810S
- Edimax EN-9320SFP+
- StarTech PEX10000SFP
- Synology E10G15-F1
... as well as the following 10GBase-T/NBASE-T NICs:
- D-Link DXE-810T
- Edimax EN-9320TX-E
- EXSYS EX-6061-2
- Intellinet 507950
- StarTech ST10GSPEXNB
An official tn40xx driver is distributed by Tehuti Networks under GPLv2 license, with all the copyright entitlements and restrictions associated with GPLv2 works. OEM vendors (like those listed above) also provide tn40xx drivers from their websites.
This repo does not claim any copyright over the original Tehuti Networks source code. As far as possible, the source code from Tehuti Networks is preserved in unmodified state in the `vendor-drop/` branches.
This repo aims to:
- track the official code drops from the vendor website
- enable comparisons with code drops from OEMs for other NIC implementations that use the same driver
- make the driver easily downloadable for Linux distributions and build systems (with a predictable URL and without web forms and cookies)
- track non-vendor bug fixes and improvements
- track the transformation of the driver into an upstreamable state
The older TN3020-D (Luxor) processor already has a mainline Linux driver, but that driver doesn't support the TN40xx (Bordeaux) devices.
# Install
While upstreaming is the ultimate goal of this project, some systems already rely on this driver. For such systems, DKMS provides a convenient way to install and update the driver, [See DKMS instructions](docs/dkms.md).
# Branches
This repo makes extensive use of branches to organise the changes to the vendor driver. For example,
- `release/tn40xx-001`
- `vendor-drop/v0.3.6.17`
- `cleanup/v0.3.6.17`
- `topic/topic/feature/add-Promise-SANLink3-T1`
The branching strategy is [described in the documentation](docs/branches.md).
# Changes between vendor releases
See [vendor-diffs.md](docs/vendor-diffs.md).
# Thanks
To the following people who have contributed to this project - thank you!
- Jean-Christophe Heger
- Nickolai Zeldovich
- Patrick Heffernan
PROG = ccmtcnvt
CPPFLAGS := -D_POSIX_C_SOURCE=2 $(CPPFLAGS)
CFLAGS := -Wall -std=c99 -pedantic -O2 $(CFLAGS)
.PHONY: all
all: $(PROG) Makefile
%.o: %.c %.h Makefile
$(COMPILE.c) $< -o $@
$(PROG): $(PROG).o
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $<
clean:
rm $(PROG) *.o || true
/*
* Copied from liwc, a collection of tools for manipulating C source code
* Retrieved from https://github.com/ajkaijanaho/liwc
*
* Copyright (c) 2012 Antti-Juhani Kaijanaho
* Copyright (c) 1994-2003 Lars Wirzenius
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
/*
* ccmtcnvt.c -- convert C++ comments to C comments
*
* Usage: ccmtcnvt [-hv] [--help] [--version] <file>
* All output is to the standard output.
*
* This program converts the C++ style comments into traditional C style
* comments.
*
* This is written as a finite state machine (FSM), which reads (presumably
* correct) C code, and when it finds a // that is not inside a comment, or
* string or character literal, it converts it to a C start of comment and
* adds a space and a comment delimiter (unreproducible here :-) before the
* next newline.
*
* Known problems:
*
* a) Include file names are not recognized being special, so that
*
* #include <sys//stat.h>
*
* will be mangled. I've never seen such names used in source code, though,
* so I don't think ignoring them will cause too much harm.
*
* b) Does not understand trigraphs or digraphs.
*
* c) Does not understand line continuation (\ at end of line) outside
* string literals and character constants.
*
* Patches for fixing these are welcome. They're not common enough for me
* to worry about them, at least for now.
*/
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
* Special marks for input characters used in the description of the FSM.
*/
#define DFL (int)UCHAR_MAX+1 /* any character */
#define NONE (int)UCHAR_MAX+2 /* don't print any character */
#define SELF (int)UCHAR_MAX+3 /* print last input character */
/*
* Possible states for the FSM.
*/
enum state {
code, chr_lit, chr_esc, str_lit, str_esc,
slash, cpp_cmt, cpp_ast, c_cmt, star
};
/*
* Rules for describing the state changes and associated actions for the
* FSM.
*/
struct rule {
enum state state;
int c;
enum state new_state;
int print1, print2, print3, print4;
const char *warning;
};
/*
* The FSM itself.
*/
static const struct rule fsm[] = {
{ code, '"', str_lit, SELF, NONE, NONE, NONE, NULL },
{ code, '\'', chr_lit, SELF, NONE, NONE, NONE, NULL },
{ code, '/', slash, NONE, NONE, NONE, NONE, NULL },
{ code, DFL, code, SELF, NONE, NONE, NONE, NULL },
{ str_lit, '\\', str_esc, SELF, NONE, NONE, NONE, NULL },
{ str_lit, '"', code, SELF, NONE, NONE, NONE, NULL },
{ str_lit, DFL, str_lit, SELF, NONE, NONE, NONE, NULL },
{ str_esc, DFL, str_lit, SELF, NONE, NONE, NONE, NULL },
{ chr_lit, '\\', chr_esc, SELF, NONE, NONE, NONE, NULL },
{ chr_lit, '\'', code, SELF, NONE, NONE, NONE, NULL },
{ chr_lit, DFL, chr_lit, SELF, NONE, NONE, NONE, NULL },
{ chr_esc, DFL, chr_lit, SELF, NONE, NONE, NONE, NULL },
{ slash, '/', cpp_cmt, '/', '*', NONE, NONE, NULL },
{ slash, '*', c_cmt, '/', '*', NONE, NONE, NULL },
{ slash, DFL, code, '/', SELF, NONE, NONE, NULL },
{ cpp_cmt, '\n', code, ' ', '*', '/', SELF, NULL },
{ cpp_cmt, '*', cpp_ast, SELF, NONE, NONE, NONE, NULL },
{ cpp_cmt, DFL, cpp_cmt, SELF, NONE, NONE, NONE, NULL },
{ cpp_ast, '\n', code, ' ', '*', '/', SELF, NULL },
{ cpp_ast, '*', cpp_ast, SELF, NONE, NONE, NONE, NULL },
{ cpp_ast, '/', cpp_cmt, ' ', SELF, NONE, NONE,
"converted a '*/' inside a C++ comment to '* /'." },
{ cpp_ast, DFL, cpp_cmt, SELF, NONE, NONE, NONE, NULL },
{ c_cmt, '*', star, SELF, NONE, NONE, NONE, NULL },
{ c_cmt, DFL, c_cmt, SELF, NONE, NONE, NONE, NULL },
{ star, '/', code, SELF, NONE, NONE, NONE, NULL },
{ star, '*', star, SELF, NONE, NONE, NONE, NULL },
{ star, DFL, c_cmt, SELF, NONE, NONE, NONE, NULL },
};
static int convert(char *filename);
static char usage[] = "Usage: %s [-hv] <file>\n";
static char version[] = "version 1.1-without-publib\n";
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "hv")) != EOF) {
switch (opt) {
case 'h':
case '?':
fprintf(stderr, usage, argv[0]);
case 'v':
fprintf(stderr, "%s", version);
}
}
if (optind != argc-1) {
fprintf(stderr, usage, argv[0]);
return EXIT_FAILURE;
}
if (convert(argv[optind]) != 0) {
fprintf(stderr, "conversion incomplete.\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
#define print(x) (void)((x) != NONE && printf("%c", (x) == SELF ? c : (x)))
static int convert(char *filename) {
enum state state;
const struct rule *p;
int c, i;
FILE *f;
f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "couldn't open file %s for reading: %s\n",
filename, strerror(errno));
return -1;
}
state = code;
for (;;) {
c = getc(f);
if (c == EOF) {
if (ferror(f)) {
fprintf(stderr, "error reading %s: %s",
filename, strerror(errno));
return -1;
}
switch (state) {
case cpp_cmt:
/* need to terminate the last // comment */
printf(" */");
break;
case code:
/* do nothing 'cause all's good */
break;
default:
fprintf(stderr, "%s error, %s ends funnily",
__func__, filename);
return -1;
}
if (fflush(stdout) == EOF || ferror(stdout))
return -1;
return 0; /* everything seems to be OK */
}
for (i = 0; i < sizeof(fsm) / sizeof(fsm[0]); ++i) {
p = &fsm[i];
if (p->state == state && (p->c == c || p->c == DFL)) {
state = p->new_state;
print(p->print1);
print(p->print2);
print(p->print3);
print(p->print4);
if (p->warning != NULL)
fprintf(stderr, "%s %s %s", __func__,
filename, p->warning);
break;
}
}
}
/*NOTREACHED*/
}
#!/bin/bash
set -e
# Use the kernel's scripts/Lindent utility
if [ -z "$LINDENT" -o ! -x "$LINDENT" ] ; then
echo " You need to set the LINDENT environment variable to specify where the Lindent script is (Hint: in the kernel sources at scripts/Lindent)"
exit 1
fi
# Run Lindent at the start of cleanup, so that the regexes below are applied to
# a predictable style of code.
# Run Lindent twice, because the operation is unfortunately not idempotent
# after only a single run (but is after two runs).
${LINDENT} *.c *.h ; ${LINDENT} *.c *.h
# Trim trailing whitespace
sed -i 's|\s*$||g' *.c *.h
# build 'ccmtcnvt' for converting C++ comments into C comments.
# (unfortunately it doesn't fix C++ comments inside C comments)
make -C cleanup
for f in *.c *.h ; do
mv $f $f~
cleanup/ccmtcnvt $f~ > $f
done
# remove horizontal line breaks like /* ------ */
sed -i 's|/\*\s*---*---*\s*\*/||g' *.c
# remove comments after the closing function brace, like } /* foo() */
sed -i 's|\s*}\s*/\*.*\*/|}|g' *.c
# remove the use of the ENTER macro
sed -i 's|\s*ENTER\s*;||g' *.c
# remove the definition of the ENTER macro
sed -i 's|.*#define\s\+ENTER.*||' *.h
# remove the use of the EXIT macro
sed -i 's|\s*EXIT\s*;||g' *.c
# remove the definition of the EXIT macro
sed -i 's|.*#define\s\+EXIT.*||' *.h
# remove the use of the RET() macro
sed -i 's|\(\s\+\)RET(\(.*\));|\1return \2;|' *.c
# remove the definition of the RET() macro
sed -i 's|.*#define\s\+RET\(.*\).*||' *.h
# remove dead code disguised as comments
# weed out function calls first
sed -i 's|/\*\s*.*(.*);.*\*/||g' *.c *.h
# weed out assignments involving struct members
sed -i 's|/\*\s*.*\..*=.*;.*\*/||g' *.c *.h
sed -i 's|/\*\s*.*->.*=.*;.*\*/||g' *.c *.h
sed -i 's|/\*\s*.*=.*->.*;.*\*/||g' *.c *.h
# remove unused g_ftrace variable
sed -i 's|\(.*g_ftrace.*\)||g' *.{c,h}
# remove unused DBG1 macro
sed -i 's|\(#define DBG1.*\)||g' tn40.h
# confirm that it really is unsused and gone
(! grep -Iq DBG1 *.{c,h}) || (echo 'unexpected DBG1 macro remaining.' && false)
# remove redundant return at end of void functions
# look for one level of tab indentation to determine function scope, instead of
# early returns from block scope. It's ugly, but semantically-important
# whitespace works for python and Lindent ensures that the indentation is
# consistent here.
sed -i 's|^\treturn\s*;.*||g' *.c
# remove unused FTRACE_ON and FTRACE_OFF macros
sed -i 's|#define FTRACE_ON$||g' *.c *.h
sed -i 's|#define FTRACE_OFF$||g' *.c *.h
# For these multi-line matches, it's much simpler to use perl...
# remove empty TN40_FTRACE block
perl -0777 -i -pe 's|#if defined\(TN40_FTRACE\)\s*\n*\s*#endif||g' *.c *.h
# remove empty FTRACE block
perl -0777 -i -pe 's|#if defined\(FTRACE\)\s*\n*\s*#endif||g' *.c *.h
# remove empty FTRACE with empty else block
perl -0777 -i -pe 's|#if defined\(FTRACE\)\s*\n*\s*#else\s*\n*\s*#endif||g' *.c *.h
# finally, remove the unused FTRACE definition
sed -i 's|#define FTRACE||g' *.c *.h
# remove the comment
sed -i 's|/\*\s*F T R A C E\s*\*/||g' *.c *.h
# remove \r characters.
sed -i 's|\r| |g' *.c *.h
# rename DRB_OBJS to DRV_OBJS as in 0.3.16.15
sed -i 's|DRB_OBJS|DRV_OBJS|g' Makefile
# replace DBG(...) macro with pr_debug(...)
sed -i 's|\(\s\+\)\(DBG(\)|\1pr_debug(|g' *.c
sed -i 's|#define\(.*\)DBG$|#define\1pr_debug|g' *.c *.h
# remove unused DBG macro
sed -i 's|^\(#define\s\+DBG(.*\)||g' tn40.h
# replace MSG(...) macro with pr_info(...)
sed -i 's|\(\s\+\)\(MSG(\)|\1pr_info(|g' *.c
# remove unused MSG macro
sed -i 's|\(#define\s\+MSG(.*\)||g' tn40.h
# remove unused ERR macro
sed -i 's|\(#define\s\+ERR(.*\)||g' tn40.h
# replace ERR(...) macro with pr_err(...)
sed -i 's|\(\s\+\)\(ERR(\)|\1pr_err(|g' *.c *.h
# remove redundant STRING_FMT macro
sed -i 's|\#define\s\+STRING_FMT.*||g' tn40.h
sed -i 's|" STRING_FMT "|%s|g' *.c *.h
sed -i 's|STRING_FMT\s\+"|"%s|g' *.c *.h
perl -0777 -i -pe 's|STRING_FMT\s*\n\s*"|"%s|g' *.c *.h
# remove single line empty comments
perl -0777 -i -pe 's|/\*\s*\*/\n||g' *.c *.h
# remove inline empty comments
sed -i 's|/\*\s*\*/||g' *.c *.h
# Insert new cleanup steps above this comment.
# Keep Lindent as the last step.
# Run Lindent again at the end, because the regexes above affect the format.
# Run Lindent twice, because the operation is unfortunately not idempotent
# after only a single run (but is after two runs).
${LINDENT} *.c *.h ; ${LINDENT} *.c *.h
PACKAGE_NAME=tn40xx
PACKAGE_VERSION=001
BUILT_MODULE_NAME[0]="$PACKAGE_NAME"
MAKE[0]="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build"
CLEAN="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build clean"
DEST_MODULE_LOCATION[0]=/extra
REMAKE_INITRD=no
AUTOINSTALL=yes
# Branches
This repo makes extensive use of branches to organise the changes to the vendor driver. For example,
- `vendor-drop/v0.3.6.14.3`
- `cleanup/v0.3.6.14.3`
- `topic/remove-linux-2.6-support`
A description of the purpose of each type of branch follows.
## Release branches
A release branch is a combination of (vendor release + cleanups + topic work). The release branch name is a simple monotonically increasing counter of the release number.
## Vendor drop branches
Vendor releases are imported from their distributed tarball into `vendor-drop/` branches. These branches are used for easy access to the unmodified driver, as well as reference between vendor branches.
## Cleanup branches
Ignoring the Linux kernel style prevents this driver from being included in the mainline kernel.
The intention of the `cleanup/` branches is to transform the vendor code into a better format that addresses the problems with the code style used by the vendor.
Some specific problems are:
- mixed tabs and spaces look horrible unless tab-width is 4
- trailing whitespace
- mixed C-style and C++ style comments
- single lines of commented code smells
- long lines
The cleanup transformation MUST:
- be logically equivalent to the vendor code
- follow an automatable, repeatable process
- involve low human effort
- make progress towards an 'upstreamable' driver
To apply the cleanup changes, run: `cleanup.sh`
## Topic branches
Features, bugfixes and improvements towards mainline inclusion are contained on these branches. For example, mainline Linux drivers do not have support for different kernel versions than the one that they ship with, so that support has to be removed.
Topic branches are always based on cleanup branches.
introduction
============
Dynamic Kernel Module Support (DKMS) builds Linux kernel modules whose sources reside outside the kernel source tree. It automates rebuilding of such modules when a new kernel is installed.
install
=======
git clone -b release/tn40xx-001 https://github.com/acooks/tn40xx-driver.git /usr/src/tn40xx-001
dkms add -m tn40xx -v 001
build driver for current kernel
===============================
dkms install -m tn40xx -v 001
build driver for specific kernel version
========================================
dkms install -m tn40xx -v 001 -k [kernel_version]
uninstall
=========
This will remove module for all kernel versions
dkms remove -m tn40xx -v 001 --all
# Changes between vendor releases
The vendor provides [release_notes](release_notes), Sometimes additional information comes to light when comparing the cleaned-up branches - that's where these review notes may help.
To generate the diff, use something like this:
```
git diff -D cleanup/v0.3.6.15 cleanup/v0.3.6.16.1
```
## vendor-drop/v0.3.6.17.1
- Fix compilation error under RHEL 8
- Change default installation folder as required by RHEL 8
- Fix kernel 4.20 compilation error (deprecated ethtool_ops.[gs]et_settings)
## vendor-drop/v0.3.6.17
- AQR105 PHY firmware blob updated from v2.b.e-798 to v2.c.7-880
- Add QNAP's TN9710P SVID/SDID (uses MV88X3310 PHY)
- Add LR-Link LREC6860BT SVID/SDID (uses MV88X3310 PHY)
- Add LR-Link LREC6860AF SVID/SDID (uses TLK10232 PHY)
- QNAP LED support to MV88X3310 PHY driver
- Bump expected MV88E2010 and MV88X3310 firmware blob version from `0_3_3_0_9374` to `0_3_4_0_9445`
- PCI IRQ MSI initialisation changed
- Add device shutdown callback
## vendor-drop/v0.3.6.16-startech
- Startech OEM driver contains Marvell firmware files missing from vendor-drop/v0.3.6.16.
## vendor-drop/v0.3.6.16
- AQR105 PHY firmware updated from XXX to 2.b.e2
- Add SVID/SDID for [IOI GE10-PCIE4XG202](http://www.ioi.com.tw/products/prodcat_device.aspx?CatID=106&DeviceID=3035&HostID=2069) OEM products. They're using _Marvell MV88X3310 PHYs_, so Linux support may be a challenge.
## vendor-drop/v0.3.6.15
- The Marvell PHY control that was removed in 0.3.6.14.3 has reappeared (without the required firmware/initialisation data blobs!) and the 'Marvell' name has been replaced with 'Pele' for what could only be trademark lawyer nonsense.
- Added support for "Mustang-200 10GbE Ethernet Adapter"
- More magical _Mike fix_ copy pasta
- Some timer cruft was removed
Plus vendor's release_notes:
- New build method for Marvell PHYs. Please consult the Readme file
- Improved startup procudure for "Phyless" CX4 mode
- Dynamic advertising of MACA for RX flow control
- Support for IEI SVID/SDID added
- Improved memory allocation for memory limited or fragmented applications
## vendor-drop/v0.3.6.14.3
- Removed support for Marvell PHYs, which removes support for the following NICs:
- "TN9210 10GBase-T Ethernet Adapter"
- "TN9710P 10GBase-T/NBASE-T Ethernet Adapter"
- "TN9710Q 5GBase-T/NBASE-T Ethernet Adapter"
- "Edimax 10 Gigabit Ethernet PCI Express Adapter"
- "Buffalo LGY-PCIE-MG Ethernet Adapter"
Plus the following claims from the vendors release_notes:
- Fix RX Flow Control
- Fix ethtool mtu on Ubuntu 17.04
- Improve single PHY build code
- Fix compilation error for CentOS 7.4
- Fix missing PCP bits in VLAN tag
## vendor-drop/v0.3.6.14.1
- First import; see release_notes for history.
# How to add a vendor drop:
- Check for new tarball on http://www.tehutinetworks.net/?t=drivers&L1=8&L2=12&L3=26
- Download and extract tarball
- Create a new empty branch with `git checkout --orphan vendor-drop/v0.3.XYZ`
- Unstage any changes with `git reset --hard`
- CAREFULLY clean out all left-over files: `git clean -fd`
- Copy the extracted sources to the git repo.
- Add all of it: `git add .`
- Commit
# How to run cleanup:
- Start from the vendor-drop: `git checkout vendor-drop/v0.3.XYZ`
- Create and Checkout the cleanup branch: `git checkout -b cleanup/v0.3.XYZ`
- Merge master: `git merge --allow-unrelated-histories master`
- Run cleanup: `LINDENT=~/linux/scripts/Lindent ./cleanup/cleanup.sh`
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment