How can I pass parameters from a main report plugin to subreport plugin, such as the AfterSQLStatementGenerated method of a ReportEngine plugin?

One way you can do this is to use the CallContext class in System.Runtime.Remote.Messaging. This allows you to save and retrieve information in the current Context, which means that even if the current execution changes threads, that information is still available. Since there could be multiple reports running simultaneously, you'll likely want to use a key that's unique to the subreport and current execution.

You can get the name of the current user from Application.Security.CurrentUser.Name. You can get the ID of the subreport from the main report's linked report collection. Here's an example using this technique in AfterSQLStatementGenerated:

IReport subreport = report.LinkedReports[0];
string uniquename = Application.Security.CurrentUser.Name +
    subreport.ID + "myvalue";
CallContext.LogicalSetData(uniquename, "Data to pass");

Then, in AfterSQLStatementGenerated for the subreport:

string uniquename = Application.Security.CurrentUser.Name +
    report.ID + "myvalue";
string parameter = CallContext.LogicalGetData(uniquename);

The parameter string contains "Data to pass."